commit 32a360eca660c76c3620317b98e0b542ceaa6eae Author: Mario Fetka Date: Sat May 20 15:26:21 2017 +0200 Imported Upstream version 0.6.24+dfsg1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf28ca2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +autom4te.cache +subst +summary +*Makefile +config.log +config.status +scripts/rc.npcd +scripts/rc.pnp_gearman_worker +scripts/check_pnp_rrds.pl +scripts/process_perfdata.pl +scripts/rrd_modify.pl +src/*.o +src/npcd +include/config.h +*~ + +sample-config/pnp/config.php +sample-config/pnp/pnp4nagios_release +sample-config/pnp/process_perfdata.cfg-sample +sample-config/pnp/npcd.cfg-sample +sample-config/misccommands.cfg-sample +sample-config/nagios.cfg-sample + +share/pnp/application/config/config.php +share/pnp/index.php +share/pnp/install.php +sample-config/httpd.conf +share/pnp/application/logs/* +contrib/ssi/status-header.ssi +helpers/w2h.pl +scripts/verify_pnp_config.pl +sample-config/lighttpd.pnp4nagios.conf +sample-config/nginx.pnp4nagios.conf +share/pnp/media/js/basket.js +scripts/rrd_convert.pl +scripts/rrd_converter.pl + +man/npcd.8 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..56e9fde --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Authors: +Jörg Linge pitchfork@pnp4nagios.org +Hendrik Bäcker andurin@process-zero.de diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..623b625 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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 Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..66dbda2 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,185 @@ +**pnp-0.6.?? ??/??/2013** + +**pnp-0.6.24 07/30/2013** + * Bugfix: Fixed some more XSS issues + * Bugfix: Fixed PHP issue while running on PHP 5.6 ( Reported by Sven Nierlein ) + +**pnp-0.6.22 06/04/2014** + * Bugfix: Fixed livestatus socket parsing ( Pekka Panula ) + * Bugfix: Update check_mssql_health.php ( Miriam Zenk ) + * Feature: Add "version=tiny" to got get a stripped down version of graph ( Ricardo Bartels ) + * feature: Add STDIN Mode to process_perfdata.pl ( Robert Steininger ) + * Bugfix: XSS issue fixed by Mikael Falkvidd. This issue was detected by Peter Österberg at Hexbit AB in a security assessment of op5 Monitor 6.3 on assignment by op5 AB. + +**pnp-0.6.21 03/24/2013** + * Feature: Helper functions rrd::alerter and rrd:alerter_gr both supports treshold detection (Martin Schirrmacher) + * Update: jQuery Mobile update to 1.3.0 ( was broken in 0.6.20 ) + +**pnp-0.6.20 03/03/2013** + * Feature: Support check_mk Multisite Cookie Auth ( Lars Michelsen ) + * Feature: Allow RRD unknown values ( Simon Meggle ) + * feature: Interactive delete mode added to check_rrds.pl ( Simon Meggle ) + * Bugfix: Allow multiple gearman servers ( Craig Barraclough ) + * Bugfix: Fixed Graph Search ( Stefan Triep ) + * Update: jQuery update to 1.8.1 + * Update: jQueryUI update to 1.8.23 + +**pnp-0.6.19 09/01/2012** + * Feature: Parameter "width" added to popup controller ( Andreas Doehler ) + * Fix: simplify/improve apache rules ( Christoph Anton Mitterer ) + * Fix: Check for missing PHP GD functions + * Bugfix: socketDOMAIN changed to AF_INET while using livstatus tcp socket ( Rene Koch ) + +**pnp-0.6.18 06/28/2012** + * Bugfix: Fixed STORAGE_TYPE and CUSTOM_TEMPLATE vars used in custom templates + * Bugfix: Blank screen on PHP 5.4 fixed + * Feature: Allow multiple gearman job servers + * Feature: New helper function rrd::debug() + * Feature: New templates check_jmx4perl_*.php + +**pnp-0.6.17 03/25/2012** + * Bugfix: Fixed rrd_convert.pl while running with --dry-run + * Bugfix: logging.c include missing header files ( Lars Vogdt ) + * Bugfix: Check if pnp4nagios/etc/rra.cfg is readable + * Bugfix: rrd_convert.pl use XML tag TEMPLATE instead of CHECKCOMMAND to selects RRDs ( Sven Velt ) + * Feature: npcdmod.o increase perfdata buffer and log discarded perfdata ( Birger Schmidt ) + * Feature: rrd_modify.pl to change number of data sources of an RRD file + * Feature: New template check_apachestatus_auto.php + * Feature: Implement etc/config.d to place config snippets ( Lars Michelsen ) + +**pnp-0.6.16 11/21/2011** + * Bugfix: Fixed single quoted check_multi labels (Reported by Matthias Flacke) + * Bugfix: Append missing slash to perfdata_spool_dir ( Reported by Juergen-Michael Radtke ) + * Bugfix: Fixed jQuery-ui multisite theme + * Feature: PDF margins are now adjustable via config.php ( Thomas Witzenrath ) + * Feature: Support for PDF size 'letter' added ( Robert Becht ) + +**pnp-0.6.15 09/15/2011** + * Bugfix: Fixed Overview link (reported by Stefan Triep) + * Bugfix: Fixed zoom popup (reported by Rudolf Labuschagne) + * Bugfix: Fixed double urlencode() (reported by Mathias Kettner) + * Feature: "Clear basket" button added (suggested by Stefan Triep) + * Feature: New helper function "rrd::alerter_gr()" ( committed by Stefan Trip ) + +**pnp-0.6.14 08/05/2011** + * Feature: Webinterface for mobile devices based on jQuery Mobile \\ ( http://jquerymobile.com/ ) + * Feature: Zoom based on jQuery plugin imgAreaSelect \\ ( http://odyniec.net/projects/imgareaselect/ ) + * Feature: New template check_mssql_health.php + * Bugfix: Fixed popups to work under nginx ( Joram Agten ) + * Bugfix: Helper rrd::vdef() fixed + * Update: jQuery update to 1.6.2 + * Update: jQuery-ui update to 1.8.14 + +**pnp-0.6.13 05/19/2011** + * Feature: New option --ignore-hosts added to check_pnp_rrds.pl ( by Jochen Bern ) + * Feature: New options zgraph_width and zgraph_height in config.php ( Mike Liebsch ) + * Bugfix: rrd_convert.pl: parse_xml_filename() regex fix + * Info: Version used by OMD-0.48 [[http://omdistro.org|OMD]] + +**pnp-0.6.12 04/22/2011** + * Feature: mod_gearman support added + * Feature: rrd_convert.pl is now able to convert all RRDs from RRD_STORAGE_TYPE=SINGLE to RRD_STORAGE_TYPE=MULTIPLE + * Feature: New template check_gearman.php + * Feature: Install process_perfdata.cfg and npcd.cfg by default + * Bugfix: rrd_convert.pl is now able to parse xml dumps created by rrdtool 1.4.x + * Bugfix: process_perfdata.pl default timeout value set to 15 seconds + +**pnp-0.6.11 01/15/2011** + * Bugfix: urldecoding fixed + * Bugfix: Zoom in/out is working again ( Reported by Thorben Soehl ) + * Featue: npcd.cfg - New option perfdata_file_processing_interval used by npcdmod + * Info: Version used by OMD-0.46 [[http://omdistro.org|OMD]] + +**pnp-0.6.10 12/15/2010** + + * Feature: Add RRDTool Option --only-graph if graph height is below 32px to create thumbnails + * Feature: RRDTool Option --width and --height is now allowed in templates + * Feature: RRDTool DS Type for UOM of "c" changed from COUNTER to DERIVE + * Feature: Pass query string from special controller to image controller ( Matthew Garrett ) + * Feature: Authorisation against [[http://mathias-kettner.de/checkmk_livestatus.html|mk_livestatus]] API added + * Feature: Sample nginx webserver config added ( by evax@users.sourceforge.net ) + * Feature: Kohana backport to support PHP 5.1.6 ( Kudos to Andreas Ericsson ) + * Bugfix: Sort list of special templates + * Bugfix: Urlencode hostname and service description ( Reported by Yannick ) + * Bugfix: corrected warning/critical thresholds in ticker/alerter functions + +**pnp-0.6.7 09/27/2010** + + * Bugfix: Page config parser fix (Beau Gunderson) + * Bugfix: Zoom window size fixed (Report by Rudolf Labuschagne) + * Bugfix: Fixed undefined offset while using 'ds_name' in templates (Reported by Vladimir Bilik) + * Bugfix: Npcdmod respects process_perf_data option used in hosts and services definitions ( Reported by Wolfgang Barth ) + * Template: New Template check_nagiostats.php used with check_nagiostats written by Jochen Bern + +**pnp-0.6.6 08/07/2010** + + * Bugfix: Fixed max amount of graphs per template + * Bugfix: Autodetect PNP base URL + * Bugfix: Too short npcdmod perfdata_template to take perfdata + overhead, increased +1024byte + * Bugfix: Ignore files in var/perfdata and check for empty directories + * Bugfix: Reducing memory usage while parsing page config (Laurent Freval) + +**pnp-0.6.5 07/09/2010** + + * Feature: Special Templates are back [[tpl_special]] + * Feature: New rrdtool helper functions makes template design easier [[tpl_helper]] + * Feature: config.php -> 'recursive_template_search' is enabled by default + * Feature: config.php -> 'template_dirs' is now an array of directorys to search for PNP templates + +**pnp-0.6.4 06/03/2010** + + * Update: jQuery Update to 1.4.2 + * Update: jQuery-ui Update to 1.8 + * Feature: New configure Option --with-base-url + * Template: New template check_ntp_time.php (Mathias Kettner) + * Feature: New i18n files for fr_FR (Yannig Parre) + * Feature: New jQuery Theme 'multisite' + +**pnp-0.6.3 03/16/2010** + + * Feature: New helper script libexec/rrd_convert.pl -> [[rrd_convert]] + * Bugfix: Ignore old XML files while building the service list + * Template: New template check_hpasm.php + * Bugfix: Installer now checks for json_decode() + * Workaround: Allow "trailing unfilled semicolons". Workaround for nsclient++ + * Template: Updates for check_openmanage.php, check_hp_bladecenter.php and check_dell_baldecenter.php ( Trond Hasle Amundsen )" + +**pnp-0.6.2 12/23/2009** + + * Feature: XML_WRITE_DELAY option added to process_perfdata.cfg as suggested by Mathias Kettner + * Feature: New template integer.php + * Update: FPDI update to 1.3.1 + * Feature: PNP will now work with [[http://http://www.lighttpd.net|lighttpd]] and php-cgi + * Template: check_mk-ps.perf.php added ( by Mathias Kettner ) + * Feature: PNP will now work without mod_rewrite -> [[webfe]] + * Bugfix: Wrong pdf link used on site 'pages' and 'basket' + * Bugfix: Incorrect group permissions on spool directory + +**pnp-0.6.1 11/22/2009** + + * Feature: RRD heartbeat per check_command -> [[tpl_custom]] + * Feature: New config.php option pdf_graph_opt + * Feature: Recognize the 'background_pdf' option in page definitions -> [[pages]] + * Feature: Recognize the 'source' option in page definitions -> [[pages]] + * Feature: Array $TIMERANGE now available for templates -> [[timeranges]] + * Bugfix: ./configure --sysconfdir no longer ignored + * Feature: Store internal runtime statistics on a per minute base + * Feature: Added two widgets views/widget_menu.php and views/widget_graph.php + +**pnp-0.6.0 10/30/2009** + + * Webfrontend based on [[http://www.kohanaphp.com|Kohana]] + * Webfrontend based on [[http://jqueryui.com/themeroller/|jQuery Themes]] + * Javascript-functions using [[http://jquery.com/|jQuery]] plugins + * process_perfdata.pl will be able to use one RRD database per datasource + * improved installer. Specification of directory layouts using --with-layout + * RRDtool errors are now displayed as images. no more missing images + * PNP templates cannot overwrite internal variables anymore + * PNP templates of version 0.4.x can still be used + * PDF functions recoded + * Template default.php optimized + * Export from RRD databases into XML, CSV and JSON format using the RRDtool "xport" function + * Page functions recoded + * Error pages links to online FAQ + * Mouseover Popup in Nagios frontend via jQuery.clueTip plugin + * Full support of rrdcached diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..23e5f25 --- /dev/null +++ b/INSTALL @@ -0,0 +1,236 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free +Software Foundation, Inc. + +This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + +These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + +Some systems require unusual options for compilation or linking that the +`configure' script does not know about. Run `./configure --help' for +details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + +You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + +By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + +Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + +There may be some features `configure' cannot figure out automatically, +but needs to determine by the type of machine the package will run on. +Usually, assuming the package is built to be run on the _same_ +architectures, `configure' can figure that out, but if it prints a +message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + +If you want to set default values for `configure' scripts to share, you +can create a site shell script called `config.site' that gives default +values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + +Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). Here is a another example: + + /bin/bash ./configure CONFIG_SHELL=/bin/bash + +Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent +configuration-related scripts to be executed by `/bin/bash'. + +`configure' Invocation +====================== + +`configure' recognizes the following options to control how it operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..5ac4d8e --- /dev/null +++ b/Makefile.in @@ -0,0 +1,183 @@ +############################### +# Makefile for PNP +# +# Last Modified: 12-10-2006 +############################### + + +# Source code directories +SRC_BASE=@srcdir@/src +SRC_SHARE=@srcdir@/share +SRC_LIB=@srcdir@/lib +SRC_SCRIPTS=@srcdir@/scripts +SRC_CONFIG=@srcdir@/sample-config +SRC_MAN=@srcdir@/man +SRC_CONTRIB=@srcdir@/contrib +SRC_HELPERS=@srcdir@/helpers + +CC=@CC@ +CFLAGS=@CFLAGS@ @DEFS@ +LDFLAGS=@LDFLAGS@ @LIBS@ + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +LOGDIR=@localstatedir@ +CFGDIR=@sysconfdir@ +BINDIR=@bindir@ +LIBEXECDIR=@libexecdir@ +LIBDIR=@libdir@ +KOHANA=@KOHANA@ +CGIDIR=@sbindir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +DATAROOTDIR=@datarootdir@ + +CP=@CP@ +PERL=@PERL@ + +none: + @echo "Please supply a command line argument (i.e. 'make all'). Other targets are:" + @echo " clean" + @echo " install install-init install-config install-processperfdata install-html fullinstall" + @echo " install-plugins" + +all: + cd $(SRC_BASE) && $(MAKE) + cd $(SRC_SHARE) && $(MAKE) + cd $(SRC_SCRIPTS) && $(MAKE) + chmod a+r $(SRC_CONTRIB)/ssi/status-header.ssi + + @echo "" + @echo "*** Compile finished ***" + @echo "" + @echo " make install" + @echo " - This installs the main program and HTML files" + @echo "" + @echo " make fullinstall" + @echo " - This installs the main program, runlevel scripts, config and HTML files" + @echo "" + @echo "Enjoy." + @echo "" + +scripts: + cd $(SRC_SCRIPTS) && $(MAKE) + +share: + cd $(SRC_SHARE) && $(MAKE) + +clean: + cd $(SRC_BASE) && $(MAKE) $@ + cd $(SRC_MAN) && $(MAKE) $@ + cd $(SRC_SHARE) && $(MAKE) $@ + cd $(SRC_LIB) && $(MAKE) $@ + cd $(SRC_SCRIPTS) && $(MAKE) $@ + cd $(SRC_CONFIG) && $(MAKE) $@ + -rm -f *.cfg core + -rm -f *~ *.*~ */*~ */*.*~ + -rm -f config.log config.status config.cache + +distclean: + cd $(SRC_BASE) && $(MAKE) $@ + cd $(SRC_MAN) && $(MAKE) $@ + cd $(SRC_SHARE) && $(MAKE) $@ + cd $(SRC_LIB) && $(MAKE) $@ + cd $(SRC_SCRIPTS) && $(MAKE) $@ + cd $(SRC_CONFIG) && $(MAKE) $@ + -rm -f *.cfg core + -rm -f *~ *.*~ */*~ */*.*~ + -rm -f config.log config.status config.cache + rm -f Makefile include/stamp-h1 include/config.h config.status config.log + rm -f subst summary + rm -f $(SRC_CONTRIB)/ssi/status-header.ssi + +devclean: distclean + +install-html: + cd $(SRC_SHARE) && $(MAKE) install + +install-base: + cd $(SRC_BASE) && $(MAKE) install + +install-man: + cd $(SRC_MAN) && $(MAKE) install + +install-processperfdata: + cd $(SRC_SCRIPTS) && $(MAKE) install + +install-init: + cd $(SRC_SCRIPTS) && $(MAKE) $@ + +install-config: + cd $(SRC_CONFIG) && $(MAKE) $@ + + @echo "" + @echo "*** PNP4Nagios sample config files installed ***" + @echo "" + @echo "Please run 'make install-init' if you want to use" + @echo "BULK Mode with NPCD" + @echo "" + @echo "" + @echo "" + +install-webconf: + cd $(SRC_CONFIG) && $(MAKE) $@ + + + @echo "" + @echo "*** Apache config file installed ***" + @echo "" + @echo "Restart your apache webserver to activete your changes." + @echo "" + @echo "Please run 'make install-config' to install sample" + @echo "configuration files" + @echo "" + @echo "Please run 'make install-init' if you want to use" + @echo "BULK Mode with NPCD" + @echo "" + @echo "" + @echo "" + +install-plugins: + cd $(SRC_SCRIPTS) && $(MAKE) $@ + +install: + cd $(SRC_BASE) && $(MAKE) $@ + cd $(SRC_MAN) && $(MAKE) $@ + cd $(SRC_SHARE) && $(MAKE) $@ + if [ x$(KOHANA) = xyes ]; then \ + cd $(SRC_LIB) && $(MAKE) $@; \ + fi + + cd $(SRC_SCRIPTS) && $(MAKE) $@ + cd $(SRC_CONFIG) && $(MAKE) $@ + + @echo "" + @echo "*** Main program, Scripts and HTML files installed ***" + @echo "" + @echo "Please run 'make install-webconf' to install the" + @echo "web configuration file" + @echo "" + @echo "Please run 'make install-config' to install sample" + @echo "configuration files" + @echo "" + @echo "Please run 'make install-init' if you want to use" + @echo "BULK Mode with NPCD" + @echo "" + @echo "" + @echo "" + +install-unstripped: + cd $(SRC_BASE) && $(MAKE) $@ + cd $(SRC_SHARE) && $(MAKE) $@ + cd $(SRC_SCRIPTS) && $(MAKE) $@ + $(MAKE) install-basic + +fullinstall: install install-webconf install-config install-init + + $(PERL) summary fullinstall + @echo "" + @echo "*** Main program, Scripts and HTML files installed ***" + @echo "" + @echo "Enjoy." + @echo "" + diff --git a/README b/README new file mode 100644 index 0000000..72010fd --- /dev/null +++ b/README @@ -0,0 +1,10 @@ +######################### +# # +# README # +# # +######################### + +See our online documentation at: + +http://pnp4nagios.sourceforge.net or: +http://docs.pnp4nagios.org/ diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..94b9a83 --- /dev/null +++ b/THANKS @@ -0,0 +1,85 @@ +########################################### +# PNP Thanks # +########################################### + +Olivier PLATHEY - For providing FPDF +Sven Nierlein - For providing mod_gearman +Michal Wojciechowski - For providing imgAreaSelect + +Hendrik Baecker - Testing, debugging and english Translation +Olaf Reiss - Testing +Andreas Koch - Testing +Christian Mies - check_nwstat Templates, Testing +Sebastian Schubert - Internal Design +Stephan von Gehlen - Testing and Feedback +Geoffrey Walton - Feedback and Translation +Frank J. Heym - process_perfdata.pl Patch for check_nrpe Templates +Rudolf Labuschagne - Testing PNP in distributed setups +Sven Velt - Multigraph Layout +Sonja Scholz - Documentation +Andrea Gabellini - +Matthias Flittener - Bugreport +Ton Kersten - Dutch Language +Matthias Flacke - check_multi development, npcd load patch +Markus Dorfer - +Christian Claus - Debugging 64bit Counter +Herbert Straub +Wolfgang Nieder - English translation, verify-script, nitpicking +Max Schubert - +Wolfgang Barth - +Ethan Galstad - Patches and Feedback +Jan Dreyer - Solaris debugging +Jean-Marie Le Borgne - French Translation +Steffen Waitz - ./configure Patch +Lars Michelsen - +Philipp Deneu - +Thomas Stolle - Debugging and testing +Benjamin Ritcey - Patches +Franky Van Liedekerke - Testing +Simon Meggle - Testing / Patches +Mattias Ryrlén - Patches +Nicolas Graziano - Patches +Joe Precious - Testing +Stefan Priebe - Patches +Carlos de Nova - i18n +Stefan Hoesl - Testing +Trond Hasle Amundsen - Template check_openmanage +Silvan Hunkirchen - Bugreport +Petr Maizner - Bugreport +Steve Finkelstein - Bugreport +Mathias Kettner - xml write delay +Yannig Parre - i18n fr_FR +Laurent Freval - Patches and feedback +Beau Gunderson - Patches and feedback +Thomas Sesselmann - Patches and feedback +Vladimir Bilik - Feedback +Matthew Garrett - +Thomas Charbonnel - nginx webserver config +Richard Allen - Patches and feedback +Falko Koglin - Patches +Jochen Bern - Patches +Mike Liebsch - Patches +Joram Agten - Patches +Juergen-Michael Radtke - Bugreport +Robert Becht - Feedback +Lars Vogdt - Patches +Birger Schmidt - Patches +Andreas Doehler - Patches +Christoph Anton Mitterer - Patches and feedback +Rene Koch - Patches +Craig Barraclough - Patches +Martin Schirrmacher - Patches +Pekka Panula - Bugreport +Dennis Lamers - Bugreport and Patches +Robert Steininger - Patches +Ricardo Bartels - Patches +Miriam Zenk - Patches + +########################################### +# NPCD Thanks # +########################################### + +Joerg Linge - for giving so much ideas what I have to do ;) +Ethan Galstad - for many useful code to learn from +Carsten Schlosser - for all the time I can disturb him to ask silly pointer questions +My Girlfriend Katrin (without 'h') - for spending so much time without me diff --git a/config.guess b/config.guess new file mode 100755 index 0000000..d407b8c --- /dev/null +++ b/config.guess @@ -0,0 +1,1526 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner . +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep __LP64__ >/dev/null + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips + #undef mipsel + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mipsel + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef mips64 + #undef mips64el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=mips64el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=mips64 + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + # Set LC_ALL=C to ensure ld outputs messages in English. + ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ + | sed -ne '/supported targets:/!d + s/[ ][ ]*/ /g + s/.*supported targets: *// + s/ .*// + p'` + case "$ld_supported_targets" in + elf32-i386) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + a.out-i386-linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit ;; + coff-i386) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit ;; + "") + # Either a pre-BFD a.out linker (linux-gnuoldld) or + # one that does not give us useful --help. + echo "${UNAME_MACHINE}-pc-linux-gnuoldld" + exit ;; + esac + # Determine whether the default compiler is a.out or elf + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + #ifdef __ELF__ + # ifdef __GLIBC__ + # if __GLIBC__ >= 2 + LIBC=gnu + # else + LIBC=gnulibc1 + # endif + # else + LIBC=gnulibc1 + # endif + #else + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) + LIBC=gnu + #else + LIBC=gnuaout + #endif + #endif + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" + test x"${LIBC}" != x && { + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit + } + test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.sub b/config.sub new file mode 100755 index 0000000..6759825 --- /dev/null +++ b/config.sub @@ -0,0 +1,1658 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. + +timestamp='2008-01-16' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 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 Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64vr | mips64vrel \ + | mips64orion | mips64orionel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tron-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100755 index 0000000..f0756a8 --- /dev/null +++ b/configure @@ -0,0 +1,7104 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61 for pnp 0.6.24. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='pnp' +PACKAGE_TARNAME='pnp' +PACKAGE_VERSION='0.6.24' +PACKAGE_STRING='pnp 0.6.24' +PACKAGE_BUGREPORT='pnp4nagios-devel@lists.sourceforge.net' + +ac_unique_file="src/" +ac_default_prefix=/usr/local/pnp4nagios +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +PKG_NAME +PKG_VERSION +PKG_HOME_URL +PKG_REL_DATE +ac_configure_args +XML_STRUCTURE_VERSION +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +INSTALL +build +build_cpu +build_vendor +build_os +host +host_cpu +host_vendor +host_os +CC +CFLAGS +LDFLAGS +CPPFLAGS +ac_ct_CC +EXEEXT +OBJEXT +SET_MAKE +STRIP +CP +CPP +GREP +EGREP +LIBOBJS +KOHANA +KOHANA_SYSTEM +nagios_user +nagios_grp +INSTALL_OPTS +PERL +PERL_LIB_PATH +RRDTOOL +PERFDATA_LOG +PERFDATA_DIR +PERFDATA_SPOOL_DIR +DEBUG +HTTPD_CONF +BASE_URL +init_dir +pnpsender_name +npcd_name +pp_pl_name +MOD_CFLAGS +MOD_LDFLAGS +RRDS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures pnp 0.6.24 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/pnp] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of pnp 0.6.24:";; + esac + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-layout=\default,debian\ sets directory layout + --without-kohana does not install the kohana framework + --with-kohana_system= Points to an already installed kohana framework + --with-nagios-user= sets user name to run nagios + --with-nagios-group= sets group name to run nagios + --with-perl_lib_path= sets path to rrdtool RRDs perl modules. + --with-rrdtool= sets path to rrdtool + --with-perfdata-logfile= Tell me where I should store the 'process_perfdata.pl' Logfile + --with-perfdata-dir= Tell me where I should store the RRD Database Files + --with-perfdata-spool-dir= Tell me where I should store perfdata files for bulk mode with npcd + --with-debug Enable debuging for process_perfdata.pl + --with-httpd-conf= sets path to Apache conf.d directory + --with-base-url=/${PKG_NAME} + --with-init-dir= sets directory to place init script into + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +pnp configure 0.6.24 +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by pnp $as_me 0.6.24, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers include/config.h:include/config.h.in" + + + + +cat >>confdefs.h <<\_ACEOF +#define DEFAULT_NAGIOS_USER nagios +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define DEFAULT_NAGIOS_GROUP nagios +_ACEOF + + +PKG_NAME=pnp4nagios +PKG_VERSION="0.6.24" +PKG_HOME_URL="http://www.pnp4nagios.org/pnp/start" +PKG_REL_DATE="30-07-2014" + + + + + +XML_STRUCTURE_VERSION="4" + + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + + +#dnl What OS are we running? +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6; } +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6; } +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO: checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +# +# List of possible output files, starting from the most likely. +# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) +# only as a last resort. b.out is created by i960 compilers. +ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' +# +# The IRIX 6 linker writes into existing files which may not be +# executable, retaining their permissions. Remove them first so a +# subsequent execution test works. +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } +if test -z "$ac_file"; then + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6; } + +{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6; } ;; + xno) + { echo "$as_me:$LINENO: result: unsupported" >&5 +echo "${ECHO_T}unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } +set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + SET_MAKE= +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $STRIP in + [\\/]* | ?:[\\/]*) + ac_cv_path_STRIP="$STRIP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_STRIP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_STRIP" && ac_cv_path_STRIP="true" + ;; +esac +fi +STRIP=$ac_cv_path_STRIP +if test -n "$STRIP"; then + { echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + + + +# Extract the first word of "cp", so it can be a program name with args. +set dummy cp; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_CP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $CP in + [\\/]* | ?:[\\/]*) + ac_cv_path_CP="$CP" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +CP=$ac_cv_path_CP +if test -n "$CP"; then + { echo "$as_me:$LINENO: result: $CP" >&5 +echo "${ECHO_T}$CP" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + +# Checks for libraries. + +# Checks for header files. + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Extract the first word of "grep ggrep" to use in msg output +if test -z "$GREP"; then +set dummy grep ggrep; ac_prog_name=$2 +if test "${ac_cv_path_GREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_GREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_GREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +GREP="$ac_cv_path_GREP" +if test -z "$GREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_GREP=$GREP +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +echo "${ECHO_T}$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + # Extract the first word of "egrep" to use in msg output +if test -z "$EGREP"; then +set dummy egrep; ac_prog_name=$2 +if test "${ac_cv_path_EGREP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_path_EGREP_found=false +# Loop through the user's path and test for each of PROGNAME-LIST +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + + $ac_path_EGREP_found && break 3 + done +done + +done +IFS=$as_save_IFS + + +fi + +EGREP="$ac_cv_path_EGREP" +if test -z "$EGREP"; then + { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } +fi + +else + ac_cv_path_EGREP=$EGREP +fi + + + fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_search_opendir=$ac_res +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_opendir+set}" = set; then + break +fi +done +if test "${ac_cv_search_opendir+set}" = set; then + : +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + +{ echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_sys_wait_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + +#AC_CHECK_HEADERS(netinet/in.h string.h sys/socket.h unistd.h stdio.h stdlib.h getopt.h signal.h) +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + + + + + + + + + + + + + + + +for ac_header in dirent.h stdio.h errno.h unistd.h syslog.h signal.h stdlib.h dirent.h string.h pthread.h getopt.h grp.h pwd.h sys/mman.h sys/types.h sys/wait.h sys/stat.h sys/socket.h sys/loadavg.h netinet/in.h fcntl.h limits.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------------- ## +## Report this to pnp4nagios-devel@lists.sourceforge.net ## +## ----------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +typedef pid_t ac__type_new_; +int +main () +{ +if ((ac__type_new_ *) 0) + return 0; +if (sizeof (ac__type_new_)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_pid_t=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +{ echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + + +# Checks for structure members +#AC_CHECK_MEMBER([struct dirent.d_type], [AC_MSG_RESULT([We successfully have a `dirent_d_type'!])], +# [AC_MSG_ERROR([We need `dirent.d_type'!])], +# [#include ]) + + + + { echo "$as_me:$LINENO: checking for struct dirent.d_type" >&5 +echo $ECHO_N "checking for struct dirent.d_type... $ECHO_C" >&6; } +if test "${ac_cv_member_struct_dirent_d_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#ifdef HAVE_DIRENT_H +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + + +int +main () +{ +static struct dirent ac_aggr; +if (ac_aggr.d_type) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_dirent_d_type=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#ifdef HAVE_DIRENT_H +# include +#else +# define dirent direct +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +#endif + + +int +main () +{ +static struct dirent ac_aggr; +if (sizeof ac_aggr.d_type) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_dirent_d_type=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_member_struct_dirent_d_type=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_dirent_d_type" >&5 +echo "${ECHO_T}$ac_cv_member_struct_dirent_d_type" >&6; } +if test $ac_cv_member_struct_dirent_d_type = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_DIRENT_D_TYPE 1 +_ACEOF + + +fi + + + +# Checks for library functions. + +for ac_header in vfork.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------------- ## +## Report this to pnp4nagios-devel@lists.sourceforge.net ## +## ----------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in fork vfork +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { echo "$as_me:$LINENO: checking for working fork" >&5 +echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } +if test "${ac_cv_func_fork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_fork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 +echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { echo "$as_me:$LINENO: checking for working vfork" >&5 +echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } +if test "${ac_cv_func_vfork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_vfork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include +#ifdef HAVE_VFORK_H +# include +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include , but some compilers + (e.g. gcc -O) don't grok . Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vfork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 +echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_VFORK 1 +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define vfork fork +_ACEOF + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_FORK 1 +_ACEOF + +fi + + + + + + + +for ac_func in bzero socket alarm strerror strspn getloadavg +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + +for ac_header in stdlib.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------------------------- ## +## Report this to pnp4nagios-devel@lists.sourceforge.net ## +## ----------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +{ echo "$as_me:$LINENO: checking for GNU libc compatible malloc" >&5 +echo $ECHO_N "checking for GNU libc compatible malloc... $ECHO_C" >&6; } +if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_malloc_0_nonnull=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#if defined STDC_HEADERS || defined HAVE_STDLIB_H +# include +#else +char *malloc (); +#endif + +int +main () +{ +return ! malloc (0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_malloc_0_nonnull=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_malloc_0_nonnull=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_malloc_0_nonnull" >&5 +echo "${ECHO_T}$ac_cv_func_malloc_0_nonnull" >&6; } +if test $ac_cv_func_malloc_0_nonnull = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 1 +_ACEOF + +else + cat >>confdefs.h <<\_ACEOF +#define HAVE_MALLOC 0 +_ACEOF + + case " $LIBOBJS " in + *" malloc.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS malloc.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<\_ACEOF +#define malloc rpl_malloc +_ACEOF + +fi + + + +{ echo "$as_me:$LINENO: checking whether lstat dereferences a symlink specified with a trailing slash" >&5 +echo $ECHO_N "checking whether lstat dereferences a symlink specified with a trailing slash... $ECHO_C" >&6; } +if test "${ac_cv_func_lstat_dereferences_slashed_symlink+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + rm -f conftest.sym conftest.file +echo >conftest.file +if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then + if test "$cross_compiling" = yes; then + ac_cv_func_lstat_dereferences_slashed_symlink=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + /* Linux will dereference the symlink and fail. + That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_lstat_dereferences_slashed_symlink=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +else + # If the `ln -s' command failed, then we probably don't even + # have an lstat function. + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f conftest.sym conftest.file + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +echo "${ECHO_T}$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } + +test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && + +cat >>confdefs.h <<_ACEOF +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +_ACEOF + + +if test $ac_cv_func_lstat_dereferences_slashed_symlink = no; then + case " $LIBOBJS " in + *" lstat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; +esac + +fi + +{ echo "$as_me:$LINENO: checking whether stat accepts an empty string" >&5 +echo $ECHO_N "checking whether stat accepts an empty string... $ECHO_C" >&6; } +if test "${ac_cv_func_stat_empty_string_bug+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_stat_empty_string_bug=yes +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + return stat ("", &sbuf) == 0; + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_stat_empty_string_bug=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_stat_empty_string_bug=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +{ echo "$as_me:$LINENO: result: $ac_cv_func_stat_empty_string_bug" >&5 +echo "${ECHO_T}$ac_cv_func_stat_empty_string_bug" >&6; } +if test $ac_cv_func_stat_empty_string_bug = yes; then + case " $LIBOBJS " in + *" stat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define HAVE_STAT_EMPTY_STRING_BUG 1 +_ACEOF + +fi + + +{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + + +layout="default" + +# Check whether --with-layout was given. +if test "${with_layout+set}" = set; then + withval=$with_layout; layout=$withval +fi + + +case $layout in + debian) + prefix="/" + sysconfdir="/etc/${PKG_NAME}" + localstatedir="/var/log/${PKG_NAME}" + libexecdir="/usr/lib/${PKG_NAME}/libexec" + libdir="/usr/lib/${PKG_NAME}" + datarootdir="/usr/share/${PKG_NAME}/html" + PERFDATA_LOG="/var/log/${PKG_NAME}/perfdata.log" + PERFDATA_DIR="/var/lib/${PKG_NAME}/perfdata" + PERFDATA_SPOOL_DIR="/var/spool/${PKG_NAME}" + bindir="/usr/bin" + sbindir="/usr/sbin" + ;; + default-0.4) + prefix="/usr/local/nagios" + sysconfdir="\${prefix}/etc/pnp" + localstatedir="\${prefix}/var" + libexecdir="\${prefix}/libexec" + datarootdir="\${prefix}/share/pnp" + libdir="\${prefix}/lib/pnp" + PERFDATA_LOG="\${prefix}/var/perfdata.log" + PERFDATA_DIR="\${prefix}/share/perfdata" + PERFDATA_SPOOL_DIR="\${prefix}/var/spool/perfdata" + ;; + default) + PERFDATA_LOG="${localstatedir}/perfdata.log" + PERFDATA_DIR="${localstatedir}/perfdata" + PERFDATA_SPOOL_DIR="${localstatedir}/spool" + mandir="\${prefix}/man" + ;; +esac + + +# Check whether --with-kohana was given. +if test "${with_kohana+set}" = set; then + withval=$with_kohana; KOHANA=no +else + KOHANA=yes +fi + + + +# Check whether --with-kohana_system was given. +if test "${with_kohana_system+set}" = set; then + withval=$with_kohana_system; KOHANA_SYSTEM=$withval +else + KOHANA_SYSTEM=$libdir/kohana/system +fi + + + +# Check whether --with-nagios_user was given. +if test "${with_nagios_user+set}" = set; then + withval=$with_nagios_user; nagios_user=$withval +else + nagios_user=nagios +fi + + +# Check whether --with-nagios_group was given. +if test "${with_nagios_group+set}" = set; then + withval=$with_nagios_group; nagios_grp=$withval +else + nagios_grp=nagios +fi + + + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_NAGIOS_USER "$nagios_user" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_NAGIOS_GROUP "$nagios_grp" +_ACEOF + +INSTALL_OPTS="-o $nagios_user -g $nagios_grp" + + +# Checks for programs. +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +# Check for Perl lib path +PERL_LIB_PATH=no + +# Check whether --with-perl_lib_path was given. +if test "${with_perl_lib_path+set}" = set; then + withval=$with_perl_lib_path; PERL_LIB_PATH=$withval +else + PERL_LIB_PATH=no +fi + + +# Check for rrdtool +RRDTOOL=no + +# Check whether --with-rrdtool was given. +if test "${with_rrdtool+set}" = set; then + withval=$with_rrdtool; RRDTOOL=$withval +else + RRDTOOL=no +fi + +if test RRDTOOL=no; then + # Extract the first word of "rrdtool", so it can be a program name with args. +set dummy rrdtool; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_RRDTOOL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $RRDTOOL in + [\\/]* | ?:[\\/]*) + ac_cv_path_RRDTOOL="$RRDTOOL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_RRDTOOL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +RRDTOOL=$ac_cv_path_RRDTOOL +if test -n "$RRDTOOL"; then + { echo "$as_me:$LINENO: result: $RRDTOOL" >&5 +echo "${ECHO_T}$RRDTOOL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi + +{ echo "$as_me:$LINENO: checking rrdtool path $RRDTOOL" >&5 +echo $ECHO_N "checking rrdtool path $RRDTOOL... $ECHO_C" >&6; } +if test -d $RRDTOOL ;then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: $RRDTOOL is a directory! PNP needs the Path to the rrdtool binary!" >&5 +echo "$as_me: error: $RRDTOOL is a directory! PNP needs the Path to the rrdtool binary!" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +{ echo "$as_me:$LINENO: checking for executable Bit on $RRDTOOL" >&5 +echo $ECHO_N "checking for executable Bit on $RRDTOOL... $ECHO_C" >&6; } +if ! test -x $RRDTOOL ;then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: $RRDTOOL is not executable!" >&5 +echo "$as_me: error: $RRDTOOL is not executable!" >&2;} + { (exit 1); exit 1; }; } +fi +{ echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + + + + + +# Check whether --with-perfdata-logfile was given. +if test "${with_perfdata_logfile+set}" = set; then + withval=$with_perfdata_logfile; PERFDATA_LOG=$withval + +fi + + + + + +# Check whether --with-perfdata-dir was given. +if test "${with_perfdata_dir+set}" = set; then + withval=$with_perfdata_dir; PERFDATA_DIR=$withval + +fi + + + + +# Check whether --with-perfdata-spool-dir was given. +if test "${with_perfdata_spool_dir+set}" = set; then + withval=$with_perfdata_spool_dir; PERFDATA_SPOOL_DIR=$withval + +fi + + + + +# Check whether --with-debug was given. +if test "${with_debug+set}" = set; then + withval=$with_debug; DEBUG="2" +else + DEBUG="0" + +fi + + + +HTTP_CONF=no + +# Check whether --with-httpd_conf was given. +if test "${with_httpd_conf+set}" = set; then + withval=$with_httpd_conf; HTTPD_CONF=$withval +else + HTTPD_CONF=no +fi + +if test x$HTTPD_CONF = xno; then + if test -d /etc/httpd/conf.d; then + HTTPD_CONF="/etc/httpd/conf.d" + elif test -d /etc/apache2/conf.d; then + HTTPD_CONF="/etc/apache2/conf.d" + elif test -d /etc/apache/conf.d; then + HTTPD_CONF="/etc/apache/conf.d" + else + HTTPD_CONF="/etc/httpd/conf.d" + fi +fi + + +init_dir=/etc/rc.d/init.d +if test -d /etc/rc.d/init.d; then + init_dir="/etc/rc.d/init.d" +elif test -d /usr/local/etc/rc.d; then + init_dir="/usr/local/etc/rc.d" +elif test -d /etc/rc.d; then + init_dir="/etc/rc.d" +elif test -d /etc/init.d; then + init_dir="/etc/init.d" +elif test -d /sbin/init.d; then + init_dir="/sbin/init.d" +fi + +BASE_URL=${PKG_NAME} + +# Check whether --with-base-url was given. +if test "${with_base_url+set}" = set; then + withval=$with_base_url; BASE_URL=$withval +else + BASE_URL=/${PKG_NAME} +fi + + + + +# Check whether --with-init_dir was given. +if test "${with_init_dir+set}" = set; then + withval=$with_init_dir; init_dir=$withval +fi + + + +pnpsender_name=pnpsender + + +npcd_name=npcd + + +pp_pl_name=process_perfdata.pl + + +{ echo "$as_me:$LINENO: checking for linker flags for loadable modules" >&5 +echo $ECHO_N "checking for linker flags for loadable modules... $ECHO_C" >&6; } +case $host_os in + solaris2*|sysv4*) + MOD_LDFLAGS="-G" + ;; + aix4*|aix5*|aix6*|aix7*) + #MOD_LDFLAGS="-G -bnoentry -bexpall" + MOD_LDFLAGS="-shared -Wl,-G -Wl,-bM:SRE -Wl,-bnoentry -Wl,-bexpall" + ;; + freebsd2*) + # Non-ELF GNU linker + MOD_LDFLAGS="-Bshareable" + ;; + darwin*) + # Mach-O linker, a shared lib and a loadable + # object file is not the same thing. + MOD_LDFLAGS="-bundle -flat_namespace -undefined suppress" + MOD_CFLAGS="$MOD_CFLAGS -fno-common" + ;; + linux* | k*bsd*-gnu*) + # assume GNU linker and ELF + MOD_LDFLAGS="-shared" + MOD_CFLAGS="-fPIC" + ;; + *) + # assume GNU linker and ELF + MOD_LDFLAGS="-shared" + ;; +esac +{ echo "$as_me:$LINENO: result: $MOD_LDFLAGS" >&5 +echo "${ECHO_T}$MOD_LDFLAGS" >&6; } + + + +# +# Checking for Perl Modules +# +{ echo "$as_me:$LINENO: checking for Perl Module Time::HiRes" >&5 +echo $ECHO_N "checking for Perl Module Time::HiRes... $ECHO_C" >&6; } +$PERL -MTime::HiRes -e exit >/dev/null 2>&1 +if test $? -ne 0; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Perl Module Time::HiRes not available" >&5 +echo "$as_me: error: Perl Module Time::HiRes not available" >&2;} + { (exit 1); exit 1; }; } +else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +fi + +{ echo "$as_me:$LINENO: checking for Perl Module Getopt::Long" >&5 +echo $ECHO_N "checking for Perl Module Getopt::Long... $ECHO_C" >&6; } +$PERL -MGetopt::Long -e exit >/dev/null 2>&1 +if test $? -ne 0; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Perl Module Getopt::Long not available" >&5 +echo "$as_me: error: Perl Module Getopt::Long not available" >&2;} + { (exit 1); exit 1; }; } +else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } +fi + +RRDS=0 +{ echo "$as_me:$LINENO: checking for optional Perl Module RRDs" >&5 +echo $ECHO_N "checking for optional Perl Module RRDs... $ECHO_C" >&6; } +$PERL -I${PERL_LIB_PATH} -MRRDs -e exit >/dev/null 2>&1 +if test $? -ne 0; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { echo "$as_me:$LINENO: WARNING: Perl Module RRDs not available" >&5 +echo "$as_me: WARNING: Perl Module RRDs not available" >&2;} + RRDS=0 +else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + RRDS=1 +fi + + +ac_config_files="$ac_config_files subst Makefile share/Makefile lib/Makefile scripts/Makefile src/Makefile sample-config/Makefile man/Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by pnp $as_me 0.6.24, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +pnp config.status 0.6.24 +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "include/config.h") CONFIG_HEADERS="$CONFIG_HEADERS include/config.h:include/config.h.in" ;; + "subst") CONFIG_FILES="$CONFIG_FILES subst" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "share/Makefile") CONFIG_FILES="$CONFIG_FILES share/Makefile" ;; + "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; + "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "sample-config/Makefile") CONFIG_FILES="$CONFIG_FILES sample-config/Makefile" ;; + "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +PKG_NAME!$PKG_NAME$ac_delim +PKG_VERSION!$PKG_VERSION$ac_delim +PKG_HOME_URL!$PKG_HOME_URL$ac_delim +PKG_REL_DATE!$PKG_REL_DATE$ac_delim +ac_configure_args!$ac_configure_args$ac_delim +XML_STRUCTURE_VERSION!$XML_STRUCTURE_VERSION$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +INSTALL!$INSTALL$ac_delim +build!$build$ac_delim +build_cpu!$build_cpu$ac_delim +build_vendor!$build_vendor$ac_delim +build_os!$build_os$ac_delim +host!$host$ac_delim +host_cpu!$host_cpu$ac_delim +host_vendor!$host_vendor$ac_delim +host_os!$host_os$ac_delim +CC!$CC$ac_delim +CFLAGS!$CFLAGS$ac_delim +LDFLAGS!$LDFLAGS$ac_delim +CPPFLAGS!$CPPFLAGS$ac_delim +ac_ct_CC!$ac_ct_CC$ac_delim +EXEEXT!$EXEEXT$ac_delim +OBJEXT!$OBJEXT$ac_delim +SET_MAKE!$SET_MAKE$ac_delim +STRIP!$STRIP$ac_delim +CP!$CP$ac_delim +CPP!$CPP$ac_delim +GREP!$GREP$ac_delim +EGREP!$EGREP$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +KOHANA!$KOHANA$ac_delim +KOHANA_SYSTEM!$KOHANA_SYSTEM$ac_delim +nagios_user!$nagios_user$ac_delim +nagios_grp!$nagios_grp$ac_delim +INSTALL_OPTS!$INSTALL_OPTS$ac_delim +PERL!$PERL$ac_delim +PERL_LIB_PATH!$PERL_LIB_PATH$ac_delim +RRDTOOL!$RRDTOOL$ac_delim +PERFDATA_LOG!$PERFDATA_LOG$ac_delim +PERFDATA_DIR!$PERFDATA_DIR$ac_delim +PERFDATA_SPOOL_DIR!$PERFDATA_SPOOL_DIR$ac_delim +DEBUG!$DEBUG$ac_delim +HTTPD_CONF!$HTTPD_CONF$ac_delim +BASE_URL!$BASE_URL$ac_delim +init_dir!$init_dir$ac_delim +pnpsender_name!$pnpsender_name$ac_delim +npcd_name!$npcd_name$ac_delim +pp_pl_name!$pp_pl_name$ac_delim +MOD_CFLAGS!$MOD_CFLAGS$ac_delim +MOD_LDFLAGS!$MOD_LDFLAGS$ac_delim +RRDS!$RRDS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + :H) + # + # CONFIG_HEADER + # +_ACEOF + +# Transform confdefs.h into a sed script `conftest.defines', that +# substitutes the proper values into config.h.in to produce config.h. +rm -f conftest.defines conftest.tail +# First, append a space to every undef/define line, to ease matching. +echo 's/$/ /' >conftest.defines +# Then, protect against being on the right side of a sed subst, or in +# an unquoted here document, in config.status. If some macros were +# called several times there might be several #defines for the same +# symbol, which is useless. But do not sort them, since the last +# AC_DEFINE must be honored. +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where +# NAME is the cpp macro being defined, VALUE is the value it is being given. +# PARAMS is the parameter list in the macro definition--in most cases, it's +# just an empty string. +ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' +ac_dB='\\)[ (].*,\\1define\\2' +ac_dC=' ' +ac_dD=' ,' + +uniq confdefs.h | + sed -n ' + t rset + :rset + s/^[ ]*#[ ]*define[ ][ ]*// + t ok + d + :ok + s/[\\&,]/\\&/g + s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p + s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p + ' >>conftest.defines + +# Remove the space that was appended to ease matching. +# Then replace #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +# (The regexp can be short, since the line contains either #define or #undef.) +echo 's/ $// +s,^[ #]*u.*,/* & */,' >>conftest.defines + +# Break up conftest.defines: +ac_max_sed_lines=50 + +# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" +# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" +# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" +# et cetera. +ac_in='$ac_file_inputs' +ac_out='"$tmp/out1"' +ac_nxt='"$tmp/out2"' + +while : +do + # Write a here document: + cat >>$CONFIG_STATUS <<_ACEOF + # First, check the format of the line: + cat >"\$tmp/defines.sed" <<\\CEOF +/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def +/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def +b +:def +_ACEOF + sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS + ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in + sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail + grep . conftest.tail >/dev/null || break + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines conftest.tail + +echo "ac_result=$ac_in" >>$CONFIG_STATUS +cat >>$CONFIG_STATUS <<\_ACEOF + if test x"$ac_file" != x-; then + echo "/* $configure_input */" >"$tmp/config.h" + cat "$ac_result" >>"$tmp/config.h" + if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f $ac_file + mv "$tmp/config.h" $ac_file + fi + else + echo "/* $configure_input */" + cat "$ac_result" + fi + rm -f "$tmp/out12" + ;; + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + +$PERL subst summary +$PERL subst scripts/process_perfdata.pl +$PERL subst scripts/rrd_convert.pl +$PERL subst scripts/rrd_modify.pl +$PERL subst scripts/rc.npcd +$PERL subst scripts/rc.pnp_gearman_worker +$PERL subst scripts/check_pnp_rrds.pl +$PERL subst share/pnp/index.php +$PERL subst share/pnp/install.php +$PERL subst sample-config/httpd.conf +$PERL subst sample-config/lighttpd.pnp4nagios.conf +$PERL subst sample-config/nginx.pnp4nagios.conf +$PERL subst sample-config/nagios.cfg-sample +$PERL subst sample-config/misccommands.cfg-sample +$PERL subst sample-config/pnp/config.php +$PERL subst sample-config/pnp/npcd.cfg-sample +$PERL subst sample-config/pnp/process_perfdata.cfg-sample +$PERL subst sample-config/pnp/pnp4nagios_release +$PERL subst contrib/ssi/status-header.ssi +$PERL subst man/npcd.8 + +$PERL summary diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..3a4098d --- /dev/null +++ b/configure.ac @@ -0,0 +1,313 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT(pnp, 0.6.24, pnp4nagios-devel@lists.sourceforge.net) +AC_CONFIG_SRCDIR(src/) +AC_CONFIG_HEADERS(include/config.h:include/config.h.in) +AC_PREFIX_DEFAULT(/usr/local/pnp4nagios) + +AC_DEFINE([DEFAULT_NAGIOS_USER], [nagios], [Default Nagios User]) +AC_DEFINE([DEFAULT_NAGIOS_GROUP], [nagios], [Default Nagios Group]) + +PKG_NAME=pnp4nagios +PKG_VERSION="0.6.24" +PKG_HOME_URL="http://www.pnp4nagios.org/pnp/start" +PKG_REL_DATE="30-07-2014" +AC_SUBST(PKG_NAME) +AC_SUBST(PKG_VERSION) +AC_SUBST(PKG_HOME_URL) +AC_SUBST(PKG_REL_DATE) +AC_SUBST(ac_configure_args) +XML_STRUCTURE_VERSION="4" +AC_SUBST(XML_STRUCTURE_VERSION) + +dnl Figure out how to invoke "install" and what install options to use. + +AC_PROG_INSTALL +AC_SUBST(INSTALL) + +#dnl What OS are we running? +AC_CANONICAL_HOST + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET +AC_PATH_PROG([STRIP],[strip],[true]) + + + +AC_PATH_PROG(CP,cp) + +# Checks for libraries. + +# Checks for header files. +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_HEADER_SYS_WAIT +#AC_CHECK_HEADERS(netinet/in.h string.h sys/socket.h unistd.h stdio.h stdlib.h getopt.h signal.h) +AC_CHECK_HEADERS(dirent.h stdio.h errno.h unistd.h syslog.h signal.h stdlib.h dirent.h string.h pthread.h getopt.h grp.h pwd.h sys/mman.h sys/types.h sys/wait.h sys/stat.h sys/socket.h sys/loadavg.h netinet/in.h fcntl.h limits.h) + +# Checks for typedefs, structures, and compiler characteristics. +AC_TYPE_PID_T +AC_TYPE_SIGNAL +AC_TYPE_UID_T + +# Checks for structure members +#AC_CHECK_MEMBER([struct dirent.d_type], [AC_MSG_RESULT([We successfully have a `dirent_d_type'!])], +# [AC_MSG_ERROR([We need `dirent.d_type'!])], +# [#include ]) + +AC_STRUCT_DIRENT_D_TYPE + +# Checks for library functions. +AC_FUNC_FORK +AC_CHECK_FUNCS([bzero socket alarm strerror strspn getloadavg]) + +AC_FUNC_MALLOC +AC_FUNC_STAT + +AC_C_CONST + +dnl Layout Methods +layout="default" +AC_ARG_WITH(layout,[ --with-layout=\[default,debian\] sets directory layout],layout=$withval) + +case $layout in + debian) + prefix="/" + sysconfdir="/etc/${PKG_NAME}" + localstatedir="/var/log/${PKG_NAME}" + libexecdir="/usr/lib/${PKG_NAME}/libexec" + libdir="/usr/lib/${PKG_NAME}" + datarootdir="/usr/share/${PKG_NAME}/html" + PERFDATA_LOG="/var/log/${PKG_NAME}/perfdata.log" + PERFDATA_DIR="/var/lib/${PKG_NAME}/perfdata" + PERFDATA_SPOOL_DIR="/var/spool/${PKG_NAME}" + bindir="/usr/bin" + sbindir="/usr/sbin" + ;; + default-0.4) + prefix="/usr/local/nagios" + sysconfdir="\${prefix}/etc/pnp" + localstatedir="\${prefix}/var" + libexecdir="\${prefix}/libexec" + datarootdir="\${prefix}/share/pnp" + libdir="\${prefix}/lib/pnp" + PERFDATA_LOG="\${prefix}/var/perfdata.log" + PERFDATA_DIR="\${prefix}/share/perfdata" + PERFDATA_SPOOL_DIR="\${prefix}/var/spool/perfdata" + ;; + default) + PERFDATA_LOG="${localstatedir}/perfdata.log" + PERFDATA_DIR="${localstatedir}/perfdata" + PERFDATA_SPOOL_DIR="${localstatedir}/spool" + mandir="\${prefix}/man" + ;; +esac + +AC_ARG_WITH(kohana,[ --without-kohana does not install the kohana framework],KOHANA=no,KOHANA=yes) +AC_SUBST(KOHANA) +AC_ARG_WITH(kohana_system,[ --with-kohana_system= Points to an already installed kohana framework],KOHANA_SYSTEM=$withval,KOHANA_SYSTEM=$libdir/kohana/system) +AC_SUBST(KOHANA_SYSTEM) +AC_ARG_WITH(nagios_user,[ --with-nagios-user= sets user name to run nagios],nagios_user=$withval,nagios_user=nagios) +AC_ARG_WITH(nagios_group,[ --with-nagios-group= sets group name to run nagios],nagios_grp=$withval,nagios_grp=nagios) +AC_SUBST(nagios_user) +AC_SUBST(nagios_grp) +AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_USER,"$nagios_user") +AC_DEFINE_UNQUOTED(DEFAULT_NAGIOS_GROUP,"$nagios_grp") +INSTALL_OPTS="-o $nagios_user -g $nagios_grp" +AC_SUBST(INSTALL_OPTS) + +# Checks for programs. +AC_PATH_PROG(PERL,perl) +# Check for Perl lib path +PERL_LIB_PATH=no +AC_ARG_WITH(perl_lib_path,[ --with-perl_lib_path= sets path to rrdtool RRDs perl modules.],PERL_LIB_PATH=$withval,PERL_LIB_PATH=no) +AC_SUBST(PERL_LIB_PATH) +# Check for rrdtool +RRDTOOL=no +AC_ARG_WITH(rrdtool,[ --with-rrdtool= sets path to rrdtool],RRDTOOL=$withval,RRDTOOL=no) +if test RRDTOOL=no; then + AC_PATH_PROG(RRDTOOL,rrdtool) +fi + +AC_MSG_CHECKING(rrdtool path $RRDTOOL) +if [ test -d $RRDTOOL ];then + AC_MSG_RESULT(no) + AC_MSG_ERROR([$RRDTOOL is a directory! PNP needs the Path to the rrdtool binary!]) +fi +AC_MSG_RESULT(yes) +AC_MSG_CHECKING(for executable Bit on $RRDTOOL) +if [ ! test -x $RRDTOOL] ;then + AC_MSG_RESULT(no) + AC_MSG_ERROR([$RRDTOOL is not executable!]) +fi +AC_MSG_RESULT(yes) + +AC_SUBST(RRDTOOL) + + +AC_ARG_WITH(perfdata-logfile,[ --with-perfdata-logfile= Tell me where I should store the 'process_perfdata.pl' Logfile], + PERFDATA_LOG=$withval + ) +AC_SUBST(PERFDATA_LOG) + + +AC_ARG_WITH(perfdata-dir,[ --with-perfdata-dir= Tell me where I should store the RRD Database Files], + PERFDATA_DIR=$withval + ) +AC_SUBST(PERFDATA_DIR) + +AC_ARG_WITH(perfdata-spool-dir,[ --with-perfdata-spool-dir= Tell me where I should store perfdata files for bulk mode with npcd], + PERFDATA_SPOOL_DIR=$withval + ) +AC_SUBST(PERFDATA_SPOOL_DIR) + +AC_ARG_WITH(debug,[ --with-debug Enable debuging for process_perfdata.pl], + DEBUG="2", + DEBUG="0" + ) +AC_SUBST(DEBUG) + +dnl Check for location of Apache conf.d directory +HTTP_CONF=no +AC_ARG_WITH(httpd_conf,[ --with-httpd-conf= sets path to Apache conf.d directory],HTTPD_CONF=$withval,HTTPD_CONF=no) +if test x$HTTPD_CONF = xno; then + if test -d /etc/httpd/conf.d; then + HTTPD_CONF="/etc/httpd/conf.d" + elif test -d /etc/apache2/conf.d; then + HTTPD_CONF="/etc/apache2/conf.d" + elif test -d /etc/apache/conf.d; then + HTTPD_CONF="/etc/apache/conf.d" + else + HTTPD_CONF="/etc/httpd/conf.d" + fi +fi +AC_SUBST(HTTPD_CONF) + +dnl Check for location of init scripts +init_dir=/etc/rc.d/init.d +if test -d /etc/rc.d/init.d; then + init_dir="/etc/rc.d/init.d" +elif test -d /usr/local/etc/rc.d; then + init_dir="/usr/local/etc/rc.d" +elif test -d /etc/rc.d; then + init_dir="/etc/rc.d" +elif test -d /etc/init.d; then + init_dir="/etc/init.d" +elif test -d /sbin/init.d; then + init_dir="/sbin/init.d" +fi + +BASE_URL=${PKG_NAME} +AC_ARG_WITH(base-url,[ --with-base-url=/${PKG_NAME} ],BASE_URL=$withval,BASE_URL=/${PKG_NAME}) +AC_SUBST(BASE_URL) + +dnl User can override init script location +AC_ARG_WITH(init_dir,[ --with-init-dir= sets directory to place init script into],init_dir=$withval) +AC_SUBST(init_dir) + +pnpsender_name=pnpsender +AC_SUBST(pnpsender_name) + +npcd_name=npcd +AC_SUBST(npcd_name) + +pp_pl_name=process_perfdata.pl +AC_SUBST(pp_pl_name) + +dnl - Modified version from www.erlang.org +dnl - Some 12/15/05 mods made after reading http://xaxxon.slackworks.com/phuku/dl.html +AC_MSG_CHECKING(for linker flags for loadable modules) +case $host_os in + solaris2*|sysv4*) + MOD_LDFLAGS="-G" + ;; + aix4*|aix5*|aix6*|aix7*) + #MOD_LDFLAGS="-G -bnoentry -bexpall" + MOD_LDFLAGS="-shared -Wl,-G -Wl,-bM:SRE -Wl,-bnoentry -Wl,-bexpall" + ;; + freebsd2*) + # Non-ELF GNU linker + MOD_LDFLAGS="-Bshareable" + ;; + darwin*) + # Mach-O linker, a shared lib and a loadable + # object file is not the same thing. + MOD_LDFLAGS="-bundle -flat_namespace -undefined suppress" + MOD_CFLAGS="$MOD_CFLAGS -fno-common" + ;; + linux* | k*bsd*-gnu*) + # assume GNU linker and ELF + MOD_LDFLAGS="-shared" + MOD_CFLAGS="-fPIC" + ;; + *) + # assume GNU linker and ELF + MOD_LDFLAGS="-shared" + ;; +esac +AC_MSG_RESULT([$MOD_LDFLAGS]) +AC_SUBST(MOD_CFLAGS) +AC_SUBST(MOD_LDFLAGS) + +# +# Checking for Perl Modules +# +AC_MSG_CHECKING(for Perl Module Time::HiRes) +$PERL -MTime::HiRes -e exit >/dev/null 2>&1 +if test $? -ne 0; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Perl Module Time::HiRes not available) +else + AC_MSG_RESULT(yes) +fi + +AC_MSG_CHECKING(for Perl Module Getopt::Long) +$PERL -MGetopt::Long -e exit >/dev/null 2>&1 +if test $? -ne 0; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Perl Module Getopt::Long not available) +else + AC_MSG_RESULT(yes) +fi + +RRDS=0 +AC_MSG_CHECKING(for optional Perl Module RRDs) +$PERL -I${PERL_LIB_PATH} -MRRDs -e exit >/dev/null 2>&1 +if test $? -ne 0; then + AC_MSG_RESULT(no) + AC_MSG_WARN(Perl Module RRDs not available) + RRDS=0 +else + AC_MSG_RESULT(yes) + RRDS=1 +fi +AC_SUBST(RRDS) + +AC_CONFIG_FILES( subst Makefile share/Makefile lib/Makefile scripts/Makefile src/Makefile sample-config/Makefile man/Makefile ) +AC_OUTPUT() + +$PERL subst summary +$PERL subst scripts/process_perfdata.pl +$PERL subst scripts/rrd_convert.pl +$PERL subst scripts/rrd_modify.pl +$PERL subst scripts/rc.npcd +$PERL subst scripts/rc.pnp_gearman_worker +$PERL subst scripts/check_pnp_rrds.pl +$PERL subst share/pnp/index.php +$PERL subst share/pnp/install.php +$PERL subst sample-config/httpd.conf +$PERL subst sample-config/lighttpd.pnp4nagios.conf +$PERL subst sample-config/nginx.pnp4nagios.conf +$PERL subst sample-config/nagios.cfg-sample +$PERL subst sample-config/misccommands.cfg-sample +$PERL subst sample-config/pnp/config.php +$PERL subst sample-config/pnp/npcd.cfg-sample +$PERL subst sample-config/pnp/process_perfdata.cfg-sample +$PERL subst sample-config/pnp/pnp4nagios_release +$PERL subst contrib/ssi/status-header.ssi +$PERL subst man/npcd.8 + +$PERL summary diff --git a/contrib/pnp4nagios-gearman.spec b/contrib/pnp4nagios-gearman.spec new file mode 100644 index 0000000..dbcee38 --- /dev/null +++ b/contrib/pnp4nagios-gearman.spec @@ -0,0 +1,62 @@ +Name: pnp4nagios +Version: 0.6.7 +Release: 1 +License: GNU Public License version 2 +Packager: Olivier Raginel +Vendor: PNP4nagios team +URL: http://pnp4nagios.org +Prefix: /opt/pnp4nagios +Source: http://github.com/Babar/pnp4nagios/tarball/%{name}-%{version}.tar.gz +Group: Applications/Monitoring +Requires: perl(Gearman::Worker), perl(Crypt::Rijndael) +BuildRoot: %{_tmppath}/%{name}-%{version}-root-%(%{__id_u} -n) +Summary: Gearman version of pnp4nagios +Provides: pnp4nagios + +%description +From the web page (http://docs.pnp4nagios.org/pnp-0.6/start): + +PNP is an addon to Nagios which analyzes performance data provided by plugins +and stores them automatically into RRD-databases (Round Robin Databases, see +RRD Tool). + +This is the version with support for Gearman, suitable to use with mod_gearman. + +%prep +%setup -q + +%build +./configure --with-nagios-user=nagios \ + --with-nagios-group=nagios \ + --prefix=%{_prefix} \ + --libdir=%{_libdir}/%{name} \ + --sysconfdir=%{_sysconfdir}/%{name} \ + --localstatedir=%{_localstatedir} \ + --with-init-dir=%{_initrddir} \ + --with-layout=debian + +%{__make} all + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/%{_prefix} + +%{__make} install fullinstall DESTDIR=$RPM_BUILD_ROOT INIT_OPTS= INSTALL_OPTS= + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%docdir %{_defaultdocdir} +%{_prefix} +%{_sysconfdir} +%defattr(-,nagios,root) +%{_localstatedir} + +%changelog +* Wed Oct 21 2010 Olivier Raginel +- First build diff --git a/contrib/pnp4nagios.spec b/contrib/pnp4nagios.spec new file mode 100644 index 0000000..1216f9d --- /dev/null +++ b/contrib/pnp4nagios.spec @@ -0,0 +1,128 @@ +# $Id:$ +# Upstream: pnp4nagios-devel@lists.sourceforge.net +Name: pnp4nagios +Version: 0.6.16 +Release: 1 +Summary: PNP is not PerfParse. A Nagios/Icinga perfdata graphing solution + +Group: Applications/System +License: GPLv2 +URL: http://www.pnp4nagios.org/ +Source: http://downloads.sourceforge.net/pnp4nagios/%{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root + +BuildRequires: rrdtool-devel +BuildRequires: perl-rrdtool +Requires: rrdtool +Requires: perl-rrdtool +Obsoletes: pnp + +%description +PNP is an addon to Nagios/Icinga which analyzes performance data provided by plugins and stores them automatically into RRD-databases. + +%prep +%setup + + +%build +sed -i -e 's/INSTALL_OPTS="-o $nagios_user -g $nagios_grp"/INSTALL_OPTS=""/' configure +sed -i -e 's/INIT_OPTS=-o root -g root/INIT_OPTS=/' scripts/Makefile.in +# hardcode that until a proper fix is upstream +sed -i -e 's/MANDIR=@mandir@/MANDIR=\/usr\/share\/man/' man/Makefile.in +%configure --with-perfdata-logfile=%{_localstatedir}/log/nagios/perfdata.log \ + --sysconfdir=%{_sysconfdir}/%{name} \ + --datarootdir=%{_datadir}/%{name} \ + --with-perfdata-dir=%{_datadir}/%{name}/perfdata \ + --with-perfdata-spool-dir=%{_localstatedir}/spool/nagios \ + --mandir=%{_mandir} \ + --libdir=%{_libdir}/%{name} # only kohana is installed there and maybe we have a system wide kohana already +make %{?_smp_mflags} all + + +%install +rm -rf %{buildroot} +%{__mkdir} -p %{buildroot}%{_sysconfdir}/httpd/conf.d/ +make fullinstall DESTDIR=%{buildroot} +mv %{buildroot}%{_sysconfdir}/%{name}/check_commands/check_nwstat.cfg-sample %{buildroot}%{_sysconfdir}/%{name}/check_commands/check_nwstat.cfg +mv %{buildroot}%{_sysconfdir}/%{name}/pages/web_traffic.cfg-sample %{buildroot}%{_sysconfdir}/%{name}/pages/web_traffic.cfg +mv %{buildroot}%{_sysconfdir}/%{name}/rra.cfg-sample %{buildroot}%{_sysconfdir}/%{name}/rra.cfg + +sed -i -e 's*log_file = /var/npcd.log*log_file = /var/log/nagios/npcd.log*' %{buildroot}%{_sysconfdir}/%{name}/npcd.cfg + +# drop local versioning, we already provide our own upgrade safety +rm -f %{buildroot}%{_sysconfdir}/%{name}/config.php.%{version} +rm -f %{buildroot}%{_sysconfdir}/%{name}/config_local.php + + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,nagios,nagios,-) +%doc AUTHORS +%doc ChangeLog +%doc COPYING +%doc INSTALL +%doc README +%doc THANKS +%config(noreplace) %{_sysconfdir}/%{name}/check_commands/check_all_local_disks.cfg-sample +%config(noreplace) %{_sysconfdir}/%{name}/check_commands/check_nrpe.cfg-sample +%config(noreplace) %{_sysconfdir}/%{name}/check_commands/check_nwstat.cfg +%config(noreplace) %{_sysconfdir}/%{name}/npcd.cfg +%config(noreplace) %{_sysconfdir}/%{name}/pages/web_traffic.cfg +%config(noreplace) %{_sysconfdir}/%{name}/process_perfdata.cfg +%config(noreplace) %{_sysconfdir}/%{name}/rra.cfg +%config(noreplace) %{_sysconfdir}/httpd/conf.d/%{name}.conf +%{_sysconfdir}/%{name}/background.pdf +%{_sysconfdir}/%{name}/config.php +%{_sysconfdir}/%{name}/misccommands.cfg-sample +%{_sysconfdir}/%{name}/nagios.cfg-sample +%{_sysconfdir}/%{name}/pnp4nagios_release +%attr(755,root,root) %{_sysconfdir}/rc.d/init.d/npcd +%attr(755,root,root) %{_sysconfdir}/rc.d/init.d/pnp_gearman_worker +%{_bindir}/npcd +%{_libdir}/pnp4nagios/npcdmod.o +%{_libdir}/%{name} +%{_libexecdir}/check_pnp_rrds.pl +%{_libexecdir}/process_perfdata.pl +%{_libexecdir}/rrd_convert.pl +%{_datadir}/%{name} +%{_mandir}/man8/npcd.8.gz + + +%changelog +* Mon Feb 06 2012 Michael Friedrich - 0.6.16-1 +- Updated to version 0.6.16. +- drop (Build)Requires nagios, we can use other core(s) as well +- verify_pnp_config.pl => verify_pnp_config_v2.pl not installed anymore +- npcd.cfg and process_perfdata.cfg get now installed by make install w/o -sample suffix +- recognize new initscript for pnp_gearman_worker +- autoremove versionized config.php, we use config(noreplace) +- drop config_local.php which would override default settings +- fix npcd.8 man page prefix install + +* Tue Feb 15 2011 Christoph Maser - 0.6.11-1 +- Updated to version 0.6.11. + +* Tue Aug 31 2010 Christoph Maser - 0.6.6-1 +- Updated to version 0.6.6. + +* Thu Dec 24 2009 Christoph Maser - 0.6.2 - 2 +- add --with-perfdata-spool-dir and --with-perfdata--dir +- mark httpd-config snippet as config file + +* Thu Dec 24 2009 Christoph Maser - 0.6.2 - 1 +- Update to version 0.6.2 +- Rename to pnp4nagios + +* Mon Mar 23 2009 Christoph Maser - 0.4.14 - 2 +- Update to version 0.4.14 + +* Mon Mar 23 2009 Christoph Maser - 0.4.13 - 2 +- modify log path +- add documentation files + +* Mon Mar 23 2009 Christoph Maser - 0.4.13 - 1 +- Initial package (using brain ;) + diff --git a/contrib/ssi/status-header.ssi.in b/contrib/ssi/status-header.ssi.in new file mode 100644 index 0000000..19a0e0e --- /dev/null +++ b/contrib/ssi/status-header.ssi.in @@ -0,0 +1,9 @@ + + + + diff --git a/helpers/kohana-install.sh b/helpers/kohana-install.sh new file mode 100755 index 0000000..c2b70af --- /dev/null +++ b/helpers/kohana-install.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# +# PNP4Nagios Helper Script +# +DIR=`dirname $0` +cd $DIR/../lib/kohana +for D in `find . -type d -printf "%P\n"`;do + if [ "$D" != "" ];then + echo -e "\t\$(INSTALL) -m 755 \$(INSTALL_OPTS) -d \$(DESTDIR)\$(LIBDIR)/kohana/$D" + fi +done +for F in `find . -type f -printf "%P\n"`;do + if [ "$F" != "" ];then + echo -e "\t\$(INSTALL) -m 644 \$(INSTALL_OPTS) kohana/$F \$(DESTDIR)\$(LIBDIR)/kohana/$F" + fi +done diff --git a/helpers/wiki2html.sh b/helpers/wiki2html.sh new file mode 100755 index 0000000..81e1c4f --- /dev/null +++ b/helpers/wiki2html.sh @@ -0,0 +1,42 @@ +#!/bin/bash +#set -xv +LANG="de en" +LANG_TARGET=(de_DE en_US) +FILES=( about advanced config doc_complete dwnld install modes new-features npcd pages perfdata_format rrdcached rrd_convert start timeranges tpl_helper tpl_helper_pnp tpl_custom tpl upgrade verify verify_pnp_config webfe_cfg webfe wrapper xport mobile ) + + +DESTDIR="../share/pnp/documents" +URL="http://docs.pnp4nagios.org" + +cd $DESTDIR + +lindex=0 +for L in $LANG; do + if [ "$L" == "en" ];then + PART="pnp-0.6" + else + PART="$L/pnp-0.6" + fi + + T=${LANG_TARGET[$lindex]} + mkdir $T + index=0 + documents=${#FILES[@]} + + while [ "$index" -lt "$documents" ];do + F=${FILES[$index]} + echo "$L $F" + wget -nv -O "${T}/${F}.html" "${URL}/${PART}/${F}?do=export_xhtmlbody" + sed -i -e's/ü/\ü/g' "${T}/${F}.html" + sed -i -e's/Ü/\Ü/g' "${T}/${F}.html" + sed -i -e's/ä/\ä/g' "${T}/${F}.html" + sed -i -e's/Ä/\Ä/g' "${T}/${F}.html" + sed -i -e's/ö/\ö/g' "${T}/${F}.html" + sed -i -e's/Ö/\Ö/g' "${T}/${F}.html" + ((index++)) + + done + ((lindex++)) +done +rm de_DE/dwnld.html +ln -s en_US/dwnld.html de_DE/dwnld.html diff --git a/include/broker.h b/include/broker.h new file mode 100644 index 0000000..abc6b52 --- /dev/null +++ b/include/broker.h @@ -0,0 +1,222 @@ +/***************************************************************************** + * + * BROKER.H - Event broker includes for Nagios + * + * Copyright (c) 2002-2006 Ethan Galstad (nagios@nagios.org) + * Last Modified: 12-12-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _BROKER_H +#define _BROKER_H + +#include "config.h" +#include "nagios.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/*************** EVENT BROKER OPTIONS *****************/ + +#define BROKER_NOTHING 0 +#define BROKER_EVERYTHING 1048575 + +#define BROKER_PROGRAM_STATE 1 /* DONE */ +#define BROKER_TIMED_EVENTS 2 /* DONE */ +#define BROKER_SERVICE_CHECKS 4 /* DONE */ +#define BROKER_HOST_CHECKS 8 /* DONE */ +#define BROKER_EVENT_HANDLERS 16 /* DONE */ +#define BROKER_LOGGED_DATA 32 /* DONE */ +#define BROKER_NOTIFICATIONS 64 /* DONE */ +#define BROKER_FLAPPING_DATA 128 /* DONE */ +#define BROKER_COMMENT_DATA 256 /* DONE */ +#define BROKER_DOWNTIME_DATA 512 /* DONE */ +#define BROKER_SYSTEM_COMMANDS 1024 /* DONE */ +#define BROKER_OCP_DATA 2048 /* DONE */ +#define BROKER_STATUS_DATA 4096 /* DONE */ +#define BROKER_ADAPTIVE_DATA 8192 /* DONE */ +#define BROKER_EXTERNALCOMMAND_DATA 16384 /* DONE */ +#define BROKER_RETENTION_DATA 32768 /* DONE */ +#define BROKER_ACKNOWLEDGEMENT_DATA 65536 +#define BROKER_STATECHANGE_DATA 131072 +#define BROKER_RESERVED18 262144 +#define BROKER_RESERVED19 524288 + + +/****** EVENT TYPES ************************/ + +#define NEBTYPE_NONE 0 + +#define NEBTYPE_HELLO 1 +#define NEBTYPE_GOODBYE 2 +#define NEBTYPE_INFO 3 + +#define NEBTYPE_PROCESS_START 100 +#define NEBTYPE_PROCESS_DAEMONIZE 101 +#define NEBTYPE_PROCESS_RESTART 102 +#define NEBTYPE_PROCESS_SHUTDOWN 103 +#define NEBTYPE_PROCESS_PRELAUNCH 104 /* before objects are read or verified */ +#define NEBTYPE_PROCESS_EVENTLOOPSTART 105 +#define NEBTYPE_PROCESS_EVENTLOOPEND 106 + +#define NEBTYPE_TIMEDEVENT_ADD 200 +#define NEBTYPE_TIMEDEVENT_REMOVE 201 +#define NEBTYPE_TIMEDEVENT_EXECUTE 202 +#define NEBTYPE_TIMEDEVENT_DELAY 203 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SKIP 204 /* NOT IMPLEMENTED */ +#define NEBTYPE_TIMEDEVENT_SLEEP 205 + +#define NEBTYPE_LOG_DATA 300 +#define NEBTYPE_LOG_ROTATION 301 + +#define NEBTYPE_SYSTEM_COMMAND_START 400 +#define NEBTYPE_SYSTEM_COMMAND_END 401 + +#define NEBTYPE_EVENTHANDLER_START 500 +#define NEBTYPE_EVENTHANDLER_END 501 + +#define NEBTYPE_NOTIFICATION_START 600 +#define NEBTYPE_NOTIFICATION_END 601 +#define NEBTYPE_CONTACTNOTIFICATION_START 602 +#define NEBTYPE_CONTACTNOTIFICATION_END 603 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_START 604 +#define NEBTYPE_CONTACTNOTIFICATIONMETHOD_END 605 + +#define NEBTYPE_SERVICECHECK_INITIATE 700 +#define NEBTYPE_SERVICECHECK_PROCESSED 701 +#define NEBTYPE_SERVICECHECK_RAW_START 702 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_RAW_END 703 /* NOT IMPLEMENTED */ +#define NEBTYPE_SERVICECHECK_ASYNC_PRECHECK 704 + +#define NEBTYPE_HOSTCHECK_INITIATE 800 /* a check of the route to the host has been initiated */ +#define NEBTYPE_HOSTCHECK_PROCESSED 801 /* the processed/final result of a host check */ +#define NEBTYPE_HOSTCHECK_RAW_START 802 /* the start of a "raw" host check */ +#define NEBTYPE_HOSTCHECK_RAW_END 803 /* a finished "raw" host check */ +#define NEBTYPE_HOSTCHECK_ASYNC_PRECHECK 804 +#define NEBTYPE_HOSTCHECK_SYNC_PRECHECK 805 + +#define NEBTYPE_COMMENT_ADD 900 +#define NEBTYPE_COMMENT_DELETE 901 +#define NEBTYPE_COMMENT_LOAD 902 + +#define NEBTYPE_FLAPPING_START 1000 +#define NEBTYPE_FLAPPING_STOP 1001 + +#define NEBTYPE_DOWNTIME_ADD 1100 +#define NEBTYPE_DOWNTIME_DELETE 1101 +#define NEBTYPE_DOWNTIME_LOAD 1102 +#define NEBTYPE_DOWNTIME_START 1103 +#define NEBTYPE_DOWNTIME_STOP 1104 + +#define NEBTYPE_PROGRAMSTATUS_UPDATE 1200 +#define NEBTYPE_HOSTSTATUS_UPDATE 1201 +#define NEBTYPE_SERVICESTATUS_UPDATE 1202 +#define NEBTYPE_CONTACTSTATUS_UPDATE 1203 + +#define NEBTYPE_ADAPTIVEPROGRAM_UPDATE 1300 +#define NEBTYPE_ADAPTIVEHOST_UPDATE 1301 +#define NEBTYPE_ADAPTIVESERVICE_UPDATE 1302 +#define NEBTYPE_ADAPTIVECONTACT_UPDATE 1303 + +#define NEBTYPE_EXTERNALCOMMAND_START 1400 +#define NEBTYPE_EXTERNALCOMMAND_END 1401 + +#define NEBTYPE_AGGREGATEDSTATUS_STARTDUMP 1500 +#define NEBTYPE_AGGREGATEDSTATUS_ENDDUMP 1501 + +#define NEBTYPE_RETENTIONDATA_STARTLOAD 1600 +#define NEBTYPE_RETENTIONDATA_ENDLOAD 1601 +#define NEBTYPE_RETENTIONDATA_STARTSAVE 1602 +#define NEBTYPE_RETENTIONDATA_ENDSAVE 1603 + +#define NEBTYPE_ACKNOWLEDGEMENT_ADD 1700 +#define NEBTYPE_ACKNOWLEDGEMENT_REMOVE 1701 /* NOT IMPLEMENTED */ +#define NEBTYPE_ACKNOWLEDGEMENT_LOAD 1702 /* NOT IMPLEMENTED */ + +#define NEBTYPE_STATECHANGE_START 1800 /* NOT IMPLEMENTED */ +#define NEBTYPE_STATECHANGE_END 1801 + + + +/****** EVENT FLAGS ************************/ + +#define NEBFLAG_NONE 0 +#define NEBFLAG_PROCESS_INITIATED 1 /* event was initiated by Nagios process */ +#define NEBFLAG_USER_INITIATED 2 /* event was initiated by a user request */ +#define NEBFLAG_MODULE_INITIATED 3 /* event was initiated by an event broker module */ + + + + +/****** EVENT ATTRIBUTES *******************/ + +#define NEBATTR_NONE 0 + +#define NEBATTR_SHUTDOWN_NORMAL 1 +#define NEBATTR_SHUTDOWN_ABNORMAL 2 +#define NEBATTR_RESTART_NORMAL 4 +#define NEBATTR_RESTART_ABNORMAL 8 + +#define NEBATTR_FLAPPING_STOP_NORMAL 1 +#define NEBATTR_FLAPPING_STOP_DISABLED 2 /* flapping stopped because flap detection was disabled */ + +#define NEBATTR_DOWNTIME_STOP_NORMAL 1 +#define NEBATTR_DOWNTIME_STOP_CANCELLED 2 + + + +/****** EVENT BROKER FUNCTIONS *************/ + +#ifdef USE_EVENT_BROKER +struct timeval get_broker_timestamp(struct timeval *); +void broker_program_state(int,int,int,struct timeval *); +void broker_timed_event(int,int,int,timed_event *,struct timeval *); +void broker_log_data(int,int,int,char *,unsigned long,time_t,struct timeval *); +void broker_event_handler(int,int,int,int,void *,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,char *,struct timeval *); +void broker_ocp_data(int,int,int,void *,int,int,double,int,int,struct timeval *); +void broker_system_command(int,int,int,struct timeval,struct timeval,double,int,int,int,char *,char *,struct timeval *); +int broker_host_check(int,int,int,host *,int,int,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,char *,char *,char *,struct timeval *); +int broker_service_check(int,int,int,service *,int,struct timeval,struct timeval,char *,double,double,int,int,int,char *,struct timeval *); +void broker_comment_data(int,int,int,int,int,char *,char *,time_t,char *,char *,int,int,int,time_t,unsigned long,struct timeval *); +void broker_downtime_data(int,int,int,int,char *,char *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long,unsigned long,struct timeval *); +void broker_flapping_data(int,int,int,int,void *,double,double,double,struct timeval *); +void broker_program_status(int,int,int,struct timeval *); +void broker_host_status(int,int,int,host *,struct timeval *); +void broker_service_status(int,int,int,service *,struct timeval *); +void broker_contact_status(int,int,int,contact *,struct timeval *); +void broker_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,char *,char *,int,int,struct timeval *); +void broker_contact_notification_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,int,struct timeval *); +void broker_contact_notification_method_data(int,int,int,int,int,struct timeval,struct timeval,void *,contact *,char *,char *,char *,int,struct timeval *); +void broker_adaptive_program_data(int,int,int,int,unsigned long,unsigned long,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_host_data(int,int,int,host *,int,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_service_data(int,int,int,service *,int,unsigned long,unsigned long,struct timeval *); +void broker_adaptive_contact_data(int,int,int,contact *,int,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long,unsigned long, struct timeval *); +void broker_external_command(int,int,int,int,time_t,char *,char *,struct timeval *); +void broker_aggregated_status_data(int,int,int,struct timeval *); +void broker_retention_data(int,int,int,struct timeval *); +void broker_acknowledgement_data(int,int,int,int,void *,char *,char *,int,int,int,struct timeval *); +void broker_statechange_data(int,int,int,int,void *,int,int,int,int,struct timeval *); +#endif + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/include/common.h b/include/common.h new file mode 100644 index 0000000..1cf7628 --- /dev/null +++ b/include/common.h @@ -0,0 +1,500 @@ +/************************************************************************ + * + * Nagios Common Header File + * Written By: Ethan Galstad (nagios@nagios.org) + * Last Modified: 10-22-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + + +#define PROGRAM_VERSION "3.0" +#define PROGRAM_MODIFICATION_DATE "03-13-2008" + +/*#define DEBUG_CHECK_IPC 1 */ +/*#define DEBUG_CHECK_IPC2 1*/ + + + +/* daemon is thread safe */ +#ifdef NSCORE +#ifndef _REENTRANT +#define _REENTRANT +#endif +#ifndef _THREAD_SAFE +#define _THREAD_SAFE +#endif +#endif + +/* Experimental performance tweaks - use with caution */ +#undef USE_MEMORY_PERFORMANCE_TWEAKS + +/* my_free has been freed from bondage as a function */ +#define my_free(ptr) { if(ptr) { free(ptr); ptr = NULL; } } + + + +/***************************** COMMANDS *********************************/ + +#define CMD_NONE 0 + +#define CMD_ADD_HOST_COMMENT 1 +#define CMD_DEL_HOST_COMMENT 2 + +#define CMD_ADD_SVC_COMMENT 3 +#define CMD_DEL_SVC_COMMENT 4 + +#define CMD_ENABLE_SVC_CHECK 5 +#define CMD_DISABLE_SVC_CHECK 6 + +#define CMD_SCHEDULE_SVC_CHECK 7 + +#define CMD_DELAY_SVC_NOTIFICATION 9 + +#define CMD_DELAY_HOST_NOTIFICATION 10 + +#define CMD_DISABLE_NOTIFICATIONS 11 +#define CMD_ENABLE_NOTIFICATIONS 12 + +#define CMD_RESTART_PROCESS 13 +#define CMD_SHUTDOWN_PROCESS 14 + +#define CMD_ENABLE_HOST_SVC_CHECKS 15 +#define CMD_DISABLE_HOST_SVC_CHECKS 16 + +#define CMD_SCHEDULE_HOST_SVC_CHECKS 17 + +#define CMD_DELAY_HOST_SVC_NOTIFICATIONS 19 /* currently unimplemented */ + +#define CMD_DEL_ALL_HOST_COMMENTS 20 +#define CMD_DEL_ALL_SVC_COMMENTS 21 + +#define CMD_ENABLE_SVC_NOTIFICATIONS 22 +#define CMD_DISABLE_SVC_NOTIFICATIONS 23 +#define CMD_ENABLE_HOST_NOTIFICATIONS 24 +#define CMD_DISABLE_HOST_NOTIFICATIONS 25 +#define CMD_ENABLE_ALL_NOTIFICATIONS_BEYOND_HOST 26 +#define CMD_DISABLE_ALL_NOTIFICATIONS_BEYOND_HOST 27 +#define CMD_ENABLE_HOST_SVC_NOTIFICATIONS 28 +#define CMD_DISABLE_HOST_SVC_NOTIFICATIONS 29 + +#define CMD_PROCESS_SERVICE_CHECK_RESULT 30 + +#define CMD_SAVE_STATE_INFORMATION 31 +#define CMD_READ_STATE_INFORMATION 32 + +#define CMD_ACKNOWLEDGE_HOST_PROBLEM 33 +#define CMD_ACKNOWLEDGE_SVC_PROBLEM 34 + +#define CMD_START_EXECUTING_SVC_CHECKS 35 +#define CMD_STOP_EXECUTING_SVC_CHECKS 36 + +#define CMD_START_ACCEPTING_PASSIVE_SVC_CHECKS 37 +#define CMD_STOP_ACCEPTING_PASSIVE_SVC_CHECKS 38 + +#define CMD_ENABLE_PASSIVE_SVC_CHECKS 39 +#define CMD_DISABLE_PASSIVE_SVC_CHECKS 40 + +#define CMD_ENABLE_EVENT_HANDLERS 41 +#define CMD_DISABLE_EVENT_HANDLERS 42 + +#define CMD_ENABLE_HOST_EVENT_HANDLER 43 +#define CMD_DISABLE_HOST_EVENT_HANDLER 44 + +#define CMD_ENABLE_SVC_EVENT_HANDLER 45 +#define CMD_DISABLE_SVC_EVENT_HANDLER 46 + +#define CMD_ENABLE_HOST_CHECK 47 +#define CMD_DISABLE_HOST_CHECK 48 + +#define CMD_START_OBSESSING_OVER_SVC_CHECKS 49 +#define CMD_STOP_OBSESSING_OVER_SVC_CHECKS 50 + +#define CMD_REMOVE_HOST_ACKNOWLEDGEMENT 51 +#define CMD_REMOVE_SVC_ACKNOWLEDGEMENT 52 + +#define CMD_SCHEDULE_FORCED_HOST_SVC_CHECKS 53 +#define CMD_SCHEDULE_FORCED_SVC_CHECK 54 + +#define CMD_SCHEDULE_HOST_DOWNTIME 55 +#define CMD_SCHEDULE_SVC_DOWNTIME 56 + +#define CMD_ENABLE_HOST_FLAP_DETECTION 57 +#define CMD_DISABLE_HOST_FLAP_DETECTION 58 + +#define CMD_ENABLE_SVC_FLAP_DETECTION 59 +#define CMD_DISABLE_SVC_FLAP_DETECTION 60 + +#define CMD_ENABLE_FLAP_DETECTION 61 +#define CMD_DISABLE_FLAP_DETECTION 62 + +#define CMD_ENABLE_HOSTGROUP_SVC_NOTIFICATIONS 63 +#define CMD_DISABLE_HOSTGROUP_SVC_NOTIFICATIONS 64 + +#define CMD_ENABLE_HOSTGROUP_HOST_NOTIFICATIONS 65 +#define CMD_DISABLE_HOSTGROUP_HOST_NOTIFICATIONS 66 + +#define CMD_ENABLE_HOSTGROUP_SVC_CHECKS 67 +#define CMD_DISABLE_HOSTGROUP_SVC_CHECKS 68 + +#define CMD_CANCEL_HOST_DOWNTIME 69 /* not internally implemented */ +#define CMD_CANCEL_SVC_DOWNTIME 70 /* not internally implemented */ + +#define CMD_CANCEL_ACTIVE_HOST_DOWNTIME 71 /* old - no longer used */ +#define CMD_CANCEL_PENDING_HOST_DOWNTIME 72 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_SVC_DOWNTIME 73 /* old - no longer used */ +#define CMD_CANCEL_PENDING_SVC_DOWNTIME 74 /* old - no longer used */ + +#define CMD_CANCEL_ACTIVE_HOST_SVC_DOWNTIME 75 /* unimplemented */ +#define CMD_CANCEL_PENDING_HOST_SVC_DOWNTIME 76 /* unimplemented */ + +#define CMD_FLUSH_PENDING_COMMANDS 77 + +#define CMD_DEL_HOST_DOWNTIME 78 +#define CMD_DEL_SVC_DOWNTIME 79 + +#define CMD_ENABLE_FAILURE_PREDICTION 80 +#define CMD_DISABLE_FAILURE_PREDICTION 81 + +#define CMD_ENABLE_PERFORMANCE_DATA 82 +#define CMD_DISABLE_PERFORMANCE_DATA 83 + +#define CMD_SCHEDULE_HOSTGROUP_HOST_DOWNTIME 84 +#define CMD_SCHEDULE_HOSTGROUP_SVC_DOWNTIME 85 +#define CMD_SCHEDULE_HOST_SVC_DOWNTIME 86 + +/* new commands in Nagios 2.x found below... */ +#define CMD_PROCESS_HOST_CHECK_RESULT 87 + +#define CMD_START_EXECUTING_HOST_CHECKS 88 +#define CMD_STOP_EXECUTING_HOST_CHECKS 89 + +#define CMD_START_ACCEPTING_PASSIVE_HOST_CHECKS 90 +#define CMD_STOP_ACCEPTING_PASSIVE_HOST_CHECKS 91 + +#define CMD_ENABLE_PASSIVE_HOST_CHECKS 92 +#define CMD_DISABLE_PASSIVE_HOST_CHECKS 93 + +#define CMD_START_OBSESSING_OVER_HOST_CHECKS 94 +#define CMD_STOP_OBSESSING_OVER_HOST_CHECKS 95 + +#define CMD_SCHEDULE_HOST_CHECK 96 +#define CMD_SCHEDULE_FORCED_HOST_CHECK 98 + +#define CMD_START_OBSESSING_OVER_SVC 99 +#define CMD_STOP_OBSESSING_OVER_SVC 100 + +#define CMD_START_OBSESSING_OVER_HOST 101 +#define CMD_STOP_OBSESSING_OVER_HOST 102 + +#define CMD_ENABLE_HOSTGROUP_HOST_CHECKS 103 +#define CMD_DISABLE_HOSTGROUP_HOST_CHECKS 104 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 105 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_SVC_CHECKS 106 + +#define CMD_ENABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 107 +#define CMD_DISABLE_HOSTGROUP_PASSIVE_HOST_CHECKS 108 + +#define CMD_ENABLE_SERVICEGROUP_SVC_NOTIFICATIONS 109 +#define CMD_DISABLE_SERVICEGROUP_SVC_NOTIFICATIONS 110 + +#define CMD_ENABLE_SERVICEGROUP_HOST_NOTIFICATIONS 111 +#define CMD_DISABLE_SERVICEGROUP_HOST_NOTIFICATIONS 112 + +#define CMD_ENABLE_SERVICEGROUP_SVC_CHECKS 113 +#define CMD_DISABLE_SERVICEGROUP_SVC_CHECKS 114 + +#define CMD_ENABLE_SERVICEGROUP_HOST_CHECKS 115 +#define CMD_DISABLE_SERVICEGROUP_HOST_CHECKS 116 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 117 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_SVC_CHECKS 118 + +#define CMD_ENABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 119 +#define CMD_DISABLE_SERVICEGROUP_PASSIVE_HOST_CHECKS 120 + +#define CMD_SCHEDULE_SERVICEGROUP_HOST_DOWNTIME 121 +#define CMD_SCHEDULE_SERVICEGROUP_SVC_DOWNTIME 122 + +#define CMD_CHANGE_GLOBAL_HOST_EVENT_HANDLER 123 +#define CMD_CHANGE_GLOBAL_SVC_EVENT_HANDLER 124 + +#define CMD_CHANGE_HOST_EVENT_HANDLER 125 +#define CMD_CHANGE_SVC_EVENT_HANDLER 126 + +#define CMD_CHANGE_HOST_CHECK_COMMAND 127 +#define CMD_CHANGE_SVC_CHECK_COMMAND 128 + +#define CMD_CHANGE_NORMAL_HOST_CHECK_INTERVAL 129 +#define CMD_CHANGE_NORMAL_SVC_CHECK_INTERVAL 130 +#define CMD_CHANGE_RETRY_SVC_CHECK_INTERVAL 131 + +#define CMD_CHANGE_MAX_HOST_CHECK_ATTEMPTS 132 +#define CMD_CHANGE_MAX_SVC_CHECK_ATTEMPTS 133 + +#define CMD_SCHEDULE_AND_PROPAGATE_TRIGGERED_HOST_DOWNTIME 134 + +#define CMD_ENABLE_HOST_AND_CHILD_NOTIFICATIONS 135 +#define CMD_DISABLE_HOST_AND_CHILD_NOTIFICATIONS 136 + +#define CMD_SCHEDULE_AND_PROPAGATE_HOST_DOWNTIME 137 + +#define CMD_ENABLE_SERVICE_FRESHNESS_CHECKS 138 +#define CMD_DISABLE_SERVICE_FRESHNESS_CHECKS 139 + +#define CMD_ENABLE_HOST_FRESHNESS_CHECKS 140 +#define CMD_DISABLE_HOST_FRESHNESS_CHECKS 141 + +#define CMD_SET_HOST_NOTIFICATION_NUMBER 142 +#define CMD_SET_SVC_NOTIFICATION_NUMBER 143 + +/* new commands in Nagios 3.x found below... */ +#define CMD_CHANGE_HOST_CHECK_TIMEPERIOD 144 +#define CMD_CHANGE_SVC_CHECK_TIMEPERIOD 145 + +#define CMD_PROCESS_FILE 146 + +#define CMD_CHANGE_CUSTOM_HOST_VAR 147 +#define CMD_CHANGE_CUSTOM_SVC_VAR 148 +#define CMD_CHANGE_CUSTOM_CONTACT_VAR 149 + +#define CMD_ENABLE_CONTACT_HOST_NOTIFICATIONS 150 +#define CMD_DISABLE_CONTACT_HOST_NOTIFICATIONS 151 +#define CMD_ENABLE_CONTACT_SVC_NOTIFICATIONS 152 +#define CMD_DISABLE_CONTACT_SVC_NOTIFICATIONS 153 + +#define CMD_ENABLE_CONTACTGROUP_HOST_NOTIFICATIONS 154 +#define CMD_DISABLE_CONTACTGROUP_HOST_NOTIFICATIONS 155 +#define CMD_ENABLE_CONTACTGROUP_SVC_NOTIFICATIONS 156 +#define CMD_DISABLE_CONTACTGROUP_SVC_NOTIFICATIONS 157 + +#define CMD_CHANGE_RETRY_HOST_CHECK_INTERVAL 158 + +#define CMD_SEND_CUSTOM_HOST_NOTIFICATION 159 +#define CMD_SEND_CUSTOM_SVC_NOTIFICATION 160 + +#define CMD_CHANGE_HOST_NOTIFICATION_TIMEPERIOD 161 +#define CMD_CHANGE_SVC_NOTIFICATION_TIMEPERIOD 162 +#define CMD_CHANGE_CONTACT_HOST_NOTIFICATION_TIMEPERIOD 163 +#define CMD_CHANGE_CONTACT_SVC_NOTIFICATION_TIMEPERIOD 164 + +#define CMD_CHANGE_HOST_MODATTR 165 +#define CMD_CHANGE_SVC_MODATTR 166 +#define CMD_CHANGE_CONTACT_MODATTR 167 +#define CMD_CHANGE_CONTACT_MODHATTR 168 +#define CMD_CHANGE_CONTACT_MODSATTR 169 + +/* custom command introduced in Nagios 3.x */ +#define CMD_CUSTOM_COMMAND 999 + + + +/************************ SERVICE CHECK TYPES ****************************/ + +#define SERVICE_CHECK_ACTIVE 0 /* Nagios performed the service check */ +#define SERVICE_CHECK_PASSIVE 1 /* the service check result was submitted by an external source */ + + +/************************** HOST CHECK TYPES *****************************/ + +#define HOST_CHECK_ACTIVE 0 /* Nagios performed the host check */ +#define HOST_CHECK_PASSIVE 1 /* the host check result was submitted by an external source */ + + +/************************ SERVICE STATE TYPES ****************************/ + +#define SOFT_STATE 0 +#define HARD_STATE 1 + + +/************************* SCHEDULED DOWNTIME TYPES **********************/ + +#define SERVICE_DOWNTIME 1 /* service downtime */ +#define HOST_DOWNTIME 2 /* host downtime */ +#define ANY_DOWNTIME 3 /* host or service downtime */ + + +/************************** NOTIFICATION OPTIONS *************************/ + +#define NOTIFICATION_OPTION_NONE 0 +#define NOTIFICATION_OPTION_BROADCAST 1 +#define NOTIFICATION_OPTION_FORCED 2 +#define NOTIFICATION_OPTION_INCREMENT 4 + + +/************************** ACKNOWLEDGEMENT TYPES ************************/ + +#define HOST_ACKNOWLEDGEMENT 0 +#define SERVICE_ACKNOWLEDGEMENT 1 + +#define ACKNOWLEDGEMENT_NONE 0 +#define ACKNOWLEDGEMENT_NORMAL 1 +#define ACKNOWLEDGEMENT_STICKY 2 + + +/**************************** DEPENDENCY TYPES ***************************/ + +#define NOTIFICATION_DEPENDENCY 1 +#define EXECUTION_DEPENDENCY 2 + + + +/********************** HOST/SERVICE CHECK OPTIONS ***********************/ + +#define CHECK_OPTION_NONE 0 /* no check options */ +#define CHECK_OPTION_FORCE_EXECUTION 1 /* force execution of a check (ignores disabled services/hosts, invalid timeperiods) */ +#define CHECK_OPTION_FRESHNESS_CHECK 2 /* this is a freshness check */ +#define CHECK_OPTION_ORPHAN_CHECK 4 /* this is an orphan check */ + + +/**************************** PROGRAM MODES ******************************/ + +#define STANDBY_MODE 0 +#define ACTIVE_MODE 1 + + +/************************** LOG ROTATION MODES ***************************/ + +#define LOG_ROTATION_NONE 0 +#define LOG_ROTATION_HOURLY 1 +#define LOG_ROTATION_DAILY 2 +#define LOG_ROTATION_WEEKLY 3 +#define LOG_ROTATION_MONTHLY 4 + + +/***************************** LOG VERSIONS ******************************/ + +#define LOG_VERSION_1 "1.0" +#define LOG_VERSION_2 "2.0" + + + +/*************************** CHECK STATISTICS ****************************/ + +#define ACTIVE_SCHEDULED_SERVICE_CHECK_STATS 0 +#define ACTIVE_ONDEMAND_SERVICE_CHECK_STATS 1 +#define PASSIVE_SERVICE_CHECK_STATS 2 +#define ACTIVE_SCHEDULED_HOST_CHECK_STATS 3 +#define ACTIVE_ONDEMAND_HOST_CHECK_STATS 4 +#define PASSIVE_HOST_CHECK_STATS 5 +#define ACTIVE_CACHED_HOST_CHECK_STATS 6 +#define ACTIVE_CACHED_SERVICE_CHECK_STATS 7 +#define EXTERNAL_COMMAND_STATS 8 +#define PARALLEL_HOST_CHECK_STATS 9 +#define SERIAL_HOST_CHECK_STATS 10 +#define MAX_CHECK_STATS_TYPES 11 + + +/************************* GENERAL DEFINITIONS **************************/ + +#define OK 0 +#define ERROR -2 /* value was changed from -1 so as to not interfere with STATUS_UNKNOWN plugin result */ + + +#ifndef TRUE +#define TRUE 1 +#elif (TRUE!=1) +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#elif (FALSE!=0) +#define FALSE 0 +#endif + + +/****************** HOST CONFIG FILE READING OPTIONS ********************/ + +#define READ_HOSTS 1 +#define READ_HOSTGROUPS 2 +#define READ_CONTACTS 4 +#define READ_CONTACTGROUPS 8 +#define READ_SERVICES 16 +#define READ_COMMANDS 32 +#define READ_TIMEPERIODS 64 +#define READ_SERVICEESCALATIONS 128 +#define READ_HOSTGROUPESCALATIONS 256 /* no longer implemented */ +#define READ_SERVICEDEPENDENCIES 512 +#define READ_HOSTDEPENDENCIES 1024 +#define READ_HOSTESCALATIONS 2048 +#define READ_HOSTEXTINFO 4096 +#define READ_SERVICEEXTINFO 8192 +#define READ_SERVICEGROUPS 16384 + +#define READ_ALL_OBJECT_DATA READ_HOSTS | READ_HOSTGROUPS | READ_CONTACTS | READ_CONTACTGROUPS | READ_SERVICES | READ_COMMANDS | READ_TIMEPERIODS | READ_SERVICEESCALATIONS | READ_SERVICEDEPENDENCIES | READ_HOSTDEPENDENCIES | READ_HOSTESCALATIONS | READ_HOSTEXTINFO | READ_SERVICEEXTINFO | READ_SERVICEGROUPS + + +/************************** DATE RANGE TYPES ****************************/ + +#define DATERANGE_CALENDAR_DATE 0 /* 2008-12-25 */ +#define DATERANGE_MONTH_DATE 1 /* july 4 (specific month) */ +#define DATERANGE_MONTH_DAY 2 /* day 21 (generic month) */ +#define DATERANGE_MONTH_WEEK_DAY 3 /* 3rd thursday (specific month) */ +#define DATERANGE_WEEK_DAY 4 /* 3rd thursday (generic month) */ +#define DATERANGE_TYPES 5 + + +/************************** DATE/TIME TYPES *****************************/ + +#define LONG_DATE_TIME 0 +#define SHORT_DATE_TIME 1 +#define SHORT_DATE 2 +#define SHORT_TIME 3 +#define HTTP_DATE_TIME 4 /* time formatted for use in HTTP headers */ + + +/**************************** DATE FORMATS ******************************/ + +#define DATE_FORMAT_US 0 /* U.S. (MM-DD-YYYY HH:MM:SS) */ +#define DATE_FORMAT_EURO 1 /* European (DD-MM-YYYY HH:MM:SS) */ +#define DATE_FORMAT_ISO8601 2 /* ISO8601 (YYYY-MM-DD HH:MM:SS) */ +#define DATE_FORMAT_STRICT_ISO8601 3 /* ISO8601 (YYYY-MM-DDTHH:MM:SS) */ + + +/************************** MISC DEFINITIONS ****************************/ + +#define MAX_FILENAME_LENGTH 256 /* max length of path/filename that Nagios will process */ +#define MAX_INPUT_BUFFER 1024 /* size in bytes of max. input buffer (for reading files, misc stuff) */ +#define MAX_COMMAND_BUFFER 8192 /* max length of raw or processed command line */ +#define MAX_EXTERNAL_COMMAND_LENGTH 8192 /* max length of an external command */ + +#define MAX_DATETIME_LENGTH 48 + + +/************************* MODIFIED ATTRIBUTES **************************/ + +#define MODATTR_NONE 0 +#define MODATTR_NOTIFICATIONS_ENABLED 1 +#define MODATTR_ACTIVE_CHECKS_ENABLED 2 +#define MODATTR_PASSIVE_CHECKS_ENABLED 4 +#define MODATTR_EVENT_HANDLER_ENABLED 8 +#define MODATTR_FLAP_DETECTION_ENABLED 16 +#define MODATTR_FAILURE_PREDICTION_ENABLED 32 +#define MODATTR_PERFORMANCE_DATA_ENABLED 64 +#define MODATTR_OBSESSIVE_HANDLER_ENABLED 128 +#define MODATTR_EVENT_HANDLER_COMMAND 256 +#define MODATTR_CHECK_COMMAND 512 +#define MODATTR_NORMAL_CHECK_INTERVAL 1024 +#define MODATTR_RETRY_CHECK_INTERVAL 2048 +#define MODATTR_MAX_CHECK_ATTEMPTS 4096 +#define MODATTR_FRESHNESS_CHECKS_ENABLED 8192 +#define MODATTR_CHECK_TIMEPERIOD 16384 +#define MODATTR_CUSTOM_VARIABLE 32768 +#define MODATTR_NOTIFICATION_TIMEPERIOD 65536 + + diff --git a/include/config.h.in b/include/config.h.in new file mode 100644 index 0000000..1af2340 --- /dev/null +++ b/include/config.h.in @@ -0,0 +1,177 @@ +/* include/config.h.in. Generated from configure.ac by autoheader. */ + +/* Default Nagios Group */ +#undef DEFAULT_NAGIOS_GROUP + +/* Default Nagios User */ +#undef DEFAULT_NAGIOS_USER + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the `bzero' function. */ +#undef HAVE_BZERO + +/* Define to 1 if you have the `getloadavg' function. */ +#undef HAVE_GETLOADAVG + +/* Define to 1 if you have the header file. */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GRP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if your system has a GNU libc compatible `malloc' function, and + to 0 otherwise. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PWD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SIGNAL_H + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strspn' function. */ +#undef HAVE_STRSPN + +/* Define to 1 if `d_type' is member of `struct dirent'. */ +#undef HAVE_STRUCT_DIRENT_D_TYPE + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to rpl_malloc if the replacement function should be used. */ +#undef malloc + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/include/global.h b/include/global.h new file mode 100644 index 0000000..58c8279 --- /dev/null +++ b/include/global.h @@ -0,0 +1,4 @@ +#ifndef GLOBAL_H_ +#define GLOBAL_H_ + +#endif /*GLOBAL_H_*/ diff --git a/include/locations.h b/include/locations.h new file mode 100644 index 0000000..834e6c4 --- /dev/null +++ b/include/locations.h @@ -0,0 +1,43 @@ +/************************************************************************ + * + * Nagios Locations Header File + * Written By: Ethan Galstad (nagios@nagios.org) + * Last Modified: 04-30-2007 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#define DEFAULT_TEMP_FILE "/usr/local/nagios/var/tempfile" +#define DEFAULT_TEMP_PATH "/tmp" +#define DEFAULT_CHECK_RESULT_PATH "/usr/local/nagios/var/spool/checkresults" +#define DEFAULT_STATUS_FILE "/usr/local/nagios/var/status.dat" +#define DEFAULT_LOG_FILE "/usr/local/nagios/var/nagios.log" +#define DEFAULT_LOG_ARCHIVE_PATH "/usr/local/nagios/var/archives/" +#define DEFAULT_DEBUG_FILE "/usr/local/nagios/var/nagios.debug" +#define DEFAULT_COMMENT_FILE "/usr/local/nagios/var/comments.dat" +#define DEFAULT_DOWNTIME_FILE "/usr/local/nagios/var/downtime.dat" +#define DEFAULT_RETENTION_FILE "/usr/local/nagios/var/retention.dat" +#define DEFAULT_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd" +#define DEFAULT_CONFIG_FILE "/usr/local/nagios/etc/nagios.cfg" +#define DEFAULT_PHYSICAL_HTML_PATH "/usr/local/nagios/share" +#define DEFAULT_URL_HTML_PATH "/nagios" +#define DEFAULT_PHYSICAL_CGIBIN_PATH "/usr/local/nagios/sbin" +#define DEFAULT_URL_CGIBIN_PATH "/nagios/cgi-bin" +#define DEFAULT_CGI_CONFIG_FILE "/usr/local/nagios/etc/cgi.cfg" +#define DEFAULT_LOCK_FILE "/usr/local/nagios/var/nagios.lock" +#define DEFAULT_OBJECT_CACHE_FILE "/usr/local/nagios/var/objects.cache" +#define DEFAULT_PRECACHED_OBJECT_FILE "/usr/local/nagios/var/objects.precache" +#define DEFAULT_EVENT_BROKER_FILE "/usr/local/nagios/var/broker.socket" +#define DEFAULT_P1_FILE "/usr/local/nagios/bin/p1.pl" /**** EMBEDDED PERL ****/ +#define DEFAULT_AUTH_FILE "" /**** EMBEDDED PERL - IS THIS USED? ****/ diff --git a/include/nagios.h b/include/nagios.h new file mode 100644 index 0000000..01eae70 --- /dev/null +++ b/include/nagios.h @@ -0,0 +1,812 @@ +/************************************************************************ + * + * Nagios Main Header File + * Written By: Ethan Galstad (nagios@nagios.org) + * Last Modified: 02-23-2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************/ + +#ifndef _NAGIOS_H +#define _NAGIOS_H + +#ifndef __GNUC__ +# define __attribute__(x) /* nothing */ +#endif + +#include "config.h" + +//#include "pnp.h" +#include "common.h" +#include "locations.h" +#include "objects.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/************* MISC LENGTH/SIZE DEFINITIONS ***********/ + +/* + NOTE: Plugin length is artificially capped at 8k to prevent runaway plugins from returning MBs/GBs of data + back to Nagios. If you increase the 8k cap by modifying this value, make sure you also increase the value + of MAX_EXTERNAL_COMMAND_LENGTH in common.h to allow for passive checks results received through the external + command file. EG 10/19/07 +*/ +#define MAX_PLUGIN_OUTPUT_LENGTH 8192 /* max length of plugin output (including perf data) */ + + + +/******************* DEFAULT VALUES *******************/ + +#define DEFAULT_LOG_LEVEL 1 /* log all events to main log file */ +#define DEFAULT_USE_SYSLOG 1 /* log events to syslog? 1=yes, 0=no */ +#define DEFAULT_SYSLOG_LEVEL 2 /* log only severe events to syslog */ + +#define DEFAULT_NOTIFICATION_LOGGING 1 /* log notification events? 1=yes, 0=no */ + +#define DEFAULT_INTER_CHECK_DELAY 5.0 /* seconds between initial service check scheduling */ +#define DEFAULT_INTERLEAVE_FACTOR 1 /* default interleave to use when scheduling checks */ +#define DEFAULT_SLEEP_TIME 0.5 /* seconds between event run checks */ +#define DEFAULT_INTERVAL_LENGTH 60 /* seconds per interval unit for check scheduling */ +#define DEFAULT_RETRY_INTERVAL 30 /* services are retried in 30 seconds if they're not OK */ +#define DEFAULT_COMMAND_CHECK_INTERVAL -1 /* interval to check for external commands (default = as often as possible) */ +#define DEFAULT_CHECK_REAPER_INTERVAL 10 /* interval in seconds to reap host and service check results */ +#define DEFAULT_MAX_REAPER_TIME 30 /* maximum number of seconds to spend reaping service checks before we break out for a while */ +#define DEFAULT_MAX_CHECK_RESULT_AGE 3600 /* maximum number of seconds that a check result file is considered to be valid */ +#define DEFAULT_MAX_PARALLEL_SERVICE_CHECKS 0 /* maximum number of service checks we can have running at any given time (0=unlimited) */ +#define DEFAULT_RETENTION_UPDATE_INTERVAL 60 /* minutes between auto-save of retention data */ +#define DEFAULT_RETENTION_SCHEDULING_HORIZON 900 /* max seconds between program restarts that we will preserve scheduling information */ +#define DEFAULT_STATUS_UPDATE_INTERVAL 60 /* seconds between aggregated status data updates */ +#define DEFAULT_FRESHNESS_CHECK_INTERVAL 60 /* seconds between service result freshness checks */ +#define DEFAULT_AUTO_RESCHEDULING_INTERVAL 30 /* seconds between host and service check rescheduling events */ +#define DEFAULT_AUTO_RESCHEDULING_WINDOW 180 /* window of time (in seconds) for which we should reschedule host and service checks */ +#define DEFAULT_ORPHAN_CHECK_INTERVAL 60 /* seconds between checks for orphaned hosts and services */ + +#define DEFAULT_NOTIFICATION_TIMEOUT 30 /* max time in seconds to wait for notification commands to complete */ +#define DEFAULT_EVENT_HANDLER_TIMEOUT 30 /* max time in seconds to wait for event handler commands to complete */ +#define DEFAULT_HOST_CHECK_TIMEOUT 30 /* max time in seconds to wait for host check commands to complete */ +#define DEFAULT_SERVICE_CHECK_TIMEOUT 60 /* max time in seconds to wait for service check commands to complete */ +#define DEFAULT_OCSP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_OCHP_TIMEOUT 15 /* max time in seconds to wait for obsessive compulsive processing commands to complete */ +#define DEFAULT_PERFDATA_TIMEOUT 5 /* max time in seconds to wait for performance data commands to complete */ +#define DEFAULT_TIME_CHANGE_THRESHOLD 900 /* compensate for time changes of more than 15 minutes */ + +#define DEFAULT_LOG_HOST_RETRIES 0 /* don't log host retries */ +#define DEFAULT_LOG_SERVICE_RETRIES 0 /* don't log service retries */ +#define DEFAULT_LOG_EVENT_HANDLERS 1 /* log event handlers */ +#define DEFAULT_LOG_INITIAL_STATES 0 /* don't log initial service and host states */ +#define DEFAULT_LOG_EXTERNAL_COMMANDS 1 /* log external commands */ +#define DEFAULT_LOG_PASSIVE_CHECKS 1 /* log passive service checks */ + +#define DEFAULT_DEBUG_LEVEL 0 /* don't log any debugging information */ +#define DEFAULT_DEBUG_VERBOSITY 1 +#define DEFAULT_MAX_DEBUG_FILE_SIZE 1000000 /* max size of debug log */ + +#define DEFAULT_AGGRESSIVE_HOST_CHECKING 0 /* don't use "aggressive" host checking */ +#define DEFAULT_CHECK_EXTERNAL_COMMANDS 1 /* check for external commands */ +#define DEFAULT_CHECK_ORPHANED_SERVICES 1 /* check for orphaned services */ +#define DEFAULT_CHECK_ORPHANED_HOSTS 1 /* check for orphaned hosts */ +#define DEFAULT_ENABLE_FLAP_DETECTION 0 /* don't enable flap detection */ +#define DEFAULT_PROCESS_PERFORMANCE_DATA 0 /* don't process performance data */ +#define DEFAULT_CHECK_SERVICE_FRESHNESS 1 /* check service result freshness */ +#define DEFAULT_CHECK_HOST_FRESHNESS 0 /* don't check host result freshness */ +#define DEFAULT_AUTO_RESCHEDULE_CHECKS 0 /* don't auto-reschedule host and service checks */ +#define DEFAULT_TRANSLATE_PASSIVE_HOST_CHECKS 0 /* should we translate DOWN/UNREACHABLE passive host checks? */ +#define DEFAULT_PASSIVE_HOST_CHECKS_SOFT 0 /* passive host checks are treated as HARD by default */ + +#define DEFAULT_LOW_SERVICE_FLAP_THRESHOLD 20.0 /* low threshold for detection of service flapping */ +#define DEFAULT_HIGH_SERVICE_FLAP_THRESHOLD 30.0 /* high threshold for detection of service flapping */ +#define DEFAULT_LOW_HOST_FLAP_THRESHOLD 20.0 /* low threshold for detection of host flapping */ +#define DEFAULT_HIGH_HOST_FLAP_THRESHOLD 30.0 /* high threshold for detection of host flapping */ + +#define DEFAULT_HOST_CHECK_SPREAD 30 /* max minutes to schedule all initial host checks */ +#define DEFAULT_SERVICE_CHECK_SPREAD 30 /* max minutes to schedule all initial service checks */ + +#define DEFAULT_CACHED_HOST_CHECK_HORIZON 15 /* max age in seconds that cached host checks can be used */ +#define DEFAULT_CACHED_SERVICE_CHECK_HORIZON 15 /* max age in seconds that cached service checks can be used */ +#define DEFAULT_ENABLE_PREDICTIVE_HOST_DEPENDENCY_CHECKS 1 /* should we use predictive host dependency checks? */ +#define DEFAULT_ENABLE_PREDICTIVE_SERVICE_DEPENDENCY_CHECKS 1 /* should we use predictive service dependency checks? */ + +#define DEFAULT_USE_LARGE_INSTALLATION_TWEAKS 0 /* don't use tweaks for large Nagios installations */ + +#define DEFAULT_ENABLE_EMBEDDED_PERL 1 /* enable embedded Perl interpreter (if compiled in) */ +#define DEFAULT_USE_EMBEDDED_PERL_IMPLICITLY 1 /* by default, embedded Perl is used for Perl plugins that don't explicitly disable it */ + +#define DEFAULT_ADDITIONAL_FRESHNESS_LATENCY 15 /* seconds to be added to freshness thresholds when automatically calculated by Nagios */ + + + +/******************* LOGGING TYPES ********************/ + +#define NSLOG_RUNTIME_ERROR 1 +#define NSLOG_RUNTIME_WARNING 2 + +#define NSLOG_VERIFICATION_ERROR 4 +#define NSLOG_VERIFICATION_WARNING 8 + +#define NSLOG_CONFIG_ERROR 16 +#define NSLOG_CONFIG_WARNING 32 + +#define NSLOG_PROCESS_INFO 64 +#define NSLOG_EVENT_HANDLER 128 +/*#define NSLOG_NOTIFICATION 256*/ /* NOT USED ANYMORE - CAN BE REUSED */ +#define NSLOG_EXTERNAL_COMMAND 512 + +#define NSLOG_HOST_UP 1024 +#define NSLOG_HOST_DOWN 2048 +#define NSLOG_HOST_UNREACHABLE 4096 + +#define NSLOG_SERVICE_OK 8192 +#define NSLOG_SERVICE_UNKNOWN 16384 +#define NSLOG_SERVICE_WARNING 32768 +#define NSLOG_SERVICE_CRITICAL 65536 + +#define NSLOG_PASSIVE_CHECK 131072 + +#define NSLOG_INFO_MESSAGE 262144 + +#define NSLOG_HOST_NOTIFICATION 524288 +#define NSLOG_SERVICE_NOTIFICATION 1048576 + + +/***************** DEBUGGING LEVELS *******************/ + +#define DEBUGL_ALL -1 +#define DEBUGL_NONE 0 +#define DEBUGL_FUNCTIONS 1 +#define DEBUGL_CONFIG 2 +#define DEBUGL_PROCESS 4 +#define DEBUGL_STATUSDATA 4 +#define DEBUGL_RETENTIONDATA 4 +#define DEBUGL_EVENTS 8 +#define DEBUGL_CHECKS 16 +#define DEBUGL_IPC 16 +#define DEBUGL_FLAPPING 16 +#define DEBUGL_EVENTHANDLERS 16 +#define DEBUGL_PERFDATA 16 +#define DEBUGL_NOTIFICATIONS 32 +#define DEBUGL_EVENTBROKER 64 +#define DEBUGL_EXTERNALCOMMANDS 128 +#define DEBUGL_COMMANDS 256 +#define DEBUGL_DOWNTIME 512 +#define DEBUGL_COMMENTS 1024 +#define DEBUGL_MACROS 2048 + +#define DEBUGV_BASIC 0 +#define DEBUGV_MORE 1 +#define DEBUGV_MOST 2 + + +/******************** HOST STATUS *********************/ + +#define HOST_UP 0 +#define HOST_DOWN 1 +#define HOST_UNREACHABLE 2 + + + +/******************* STATE LOGGING TYPES **************/ + +#define INITIAL_STATES 1 +#define CURRENT_STATES 2 + + + +/************ SERVICE DEPENDENCY VALUES ***************/ + +#define DEPENDENCIES_OK 0 +#define DEPENDENCIES_FAILED 1 + + + +/*********** ROUTE CHECK PROPAGATION TYPES ************/ + +#define PROPAGATE_TO_PARENT_HOSTS 1 +#define PROPAGATE_TO_CHILD_HOSTS 2 + + + +/****************** SERVICE STATES ********************/ + +#define STATE_OK 0 +#define STATE_WARNING 1 +#define STATE_CRITICAL 2 +#define STATE_UNKNOWN 3 /* changed from -1 on 02/24/2001 */ + + + +/****************** FLAPPING TYPES ********************/ + +#define HOST_FLAPPING 0 +#define SERVICE_FLAPPING 1 + + + +/**************** NOTIFICATION TYPES ******************/ + +#define HOST_NOTIFICATION 0 +#define SERVICE_NOTIFICATION 1 + + + +/************* NOTIFICATION REASON TYPES ***************/ + +#define NOTIFICATION_NORMAL 0 +#define NOTIFICATION_ACKNOWLEDGEMENT 1 +#define NOTIFICATION_FLAPPINGSTART 2 +#define NOTIFICATION_FLAPPINGSTOP 3 +#define NOTIFICATION_FLAPPINGDISABLED 4 +#define NOTIFICATION_DOWNTIMESTART 5 +#define NOTIFICATION_DOWNTIMEEND 6 +#define NOTIFICATION_DOWNTIMECANCELLED 7 +#define NOTIFICATION_CUSTOM 99 + + + +/**************** EVENT HANDLER TYPES *****************/ + +#define HOST_EVENTHANDLER 0 +#define SERVICE_EVENTHANDLER 1 +#define GLOBAL_HOST_EVENTHANDLER 2 +#define GLOBAL_SERVICE_EVENTHANDLER 3 + + + +/***************** STATE CHANGE TYPES *****************/ + +#define HOST_STATECHANGE 0 +#define SERVICE_STATECHANGE 1 + + + +/***************** OBJECT CHECK TYPES *****************/ +#define SERVICE_CHECK 0 +#define HOST_CHECK 1 + + + +/******************* EVENT TYPES **********************/ + +#define EVENT_SERVICE_CHECK 0 /* active service check */ +#define EVENT_COMMAND_CHECK 1 /* external command check */ +#define EVENT_LOG_ROTATION 2 /* log file rotation */ +#define EVENT_PROGRAM_SHUTDOWN 3 /* program shutdown */ +#define EVENT_PROGRAM_RESTART 4 /* program restart */ +#define EVENT_CHECK_REAPER 5 /* reaps results from host and service checks */ +#define EVENT_ORPHAN_CHECK 6 /* checks for orphaned hosts and services */ +#define EVENT_RETENTION_SAVE 7 /* save (dump) retention data */ +#define EVENT_STATUS_SAVE 8 /* save (dump) status data */ +#define EVENT_SCHEDULED_DOWNTIME 9 /* scheduled host or service downtime */ +#define EVENT_SFRESHNESS_CHECK 10 /* checks service result "freshness" */ +#define EVENT_EXPIRE_DOWNTIME 11 /* checks for (and removes) expired scheduled downtime */ +#define EVENT_HOST_CHECK 12 /* active host check */ +#define EVENT_HFRESHNESS_CHECK 13 /* checks host result "freshness" */ +#define EVENT_RESCHEDULE_CHECKS 14 /* adjust scheduling of host and service checks */ +#define EVENT_EXPIRE_COMMENT 15 /* removes expired comments */ +#define EVENT_SLEEP 98 /* asynchronous sleep event that occurs when event queues are empty */ +#define EVENT_USER_FUNCTION 99 /* USER-defined function (modules) */ + + + +/******* INTER-CHECK DELAY CALCULATION TYPES **********/ + +#define ICD_NONE 0 /* no inter-check delay */ +#define ICD_DUMB 1 /* dumb delay of 1 second */ +#define ICD_SMART 2 /* smart delay */ +#define ICD_USER 3 /* user-specified delay */ + + + +/******* INTERLEAVE FACTOR CALCULATION TYPES **********/ + +#define ILF_USER 0 /* user-specified interleave factor */ +#define ILF_SMART 1 /* smart interleave */ + + + +/************ SCHEDULED DOWNTIME TYPES ****************/ + +#define ACTIVE_DOWNTIME 0 /* active downtime - currently in effect */ +#define PENDING_DOWNTIME 1 /* pending downtime - scheduled for the future */ + + + +/****************** DATA STRUCTURES *******************/ + +/* TIMED_EVENT structure */ +typedef struct timed_event_struct{ + int event_type; + time_t run_time; + int recurring; + unsigned long event_interval; + int compensate_for_time_change; + void *timing_func; + void *event_data; + void *event_args; + int event_options; + struct timed_event_struct *next; + struct timed_event_struct *prev; + }timed_event; + + +/* NOTIFY_LIST structure */ +typedef struct notify_list_struct{ + contact *contact; + struct notify_list_struct *next; + }notification; + + +/* CHECK_RESULT structure */ +typedef struct check_result_struct{ + int object_check_type; /* is this a service or a host check? */ + char *host_name; /* host name */ + char *service_description; /* service description */ + int check_type; /* was this an active or passive service check? */ + int check_options; + int scheduled_check; /* was this a scheduled or an on-demand check? */ + int reschedule_check; /* should we reschedule the next check */ + char *output_file; /* what file is the output stored in? */ + FILE *output_file_fp; + int output_file_fd; + double latency; + struct timeval start_time; /* time the service check was initiated */ + struct timeval finish_time; /* time the service check was completed */ + int early_timeout; /* did the service check timeout? */ + int exited_ok; /* did the plugin check return okay? */ + int return_code; /* plugin return code */ + char *output; /* plugin output */ + struct check_result_struct *next; + }check_result; + + +/* SCHED_INFO structure */ +typedef struct sched_info_struct{ + int total_services; + int total_scheduled_services; + int total_hosts; + int total_scheduled_hosts; + double average_services_per_host; + double average_scheduled_services_per_host; + unsigned long service_check_interval_total; + unsigned long host_check_interval_total; + double average_service_execution_time; + double average_service_check_interval; + double average_host_check_interval; + double average_service_inter_check_delay; + double average_host_inter_check_delay; + double service_inter_check_delay; + double host_inter_check_delay; + int service_interleave_factor; + int max_service_check_spread; + int max_host_check_spread; + time_t first_service_check; + time_t last_service_check; + time_t first_host_check; + time_t last_host_check; + }sched_info; + + +/* PASSIVE_CHECK_RESULT structure */ +typedef struct passive_check_result_struct{ + int object_check_type; + char *host_name; + char *service_description; + int return_code; + char *output; + time_t check_time; + double latency; + struct passive_check_result_struct *next; + }passive_check_result; + + +/* CIRCULAR_BUFFER structure - used by worker threads */ +typedef struct circular_buffer_struct{ + void **buffer; + int tail; + int head; + int items; + int high; /* highest number of items that has ever been stored in buffer */ + unsigned long overflow; + pthread_mutex_t buffer_lock; + }circular_buffer; + + +/* MMAPFILE structure - used for reading files via mmap() */ +typedef struct mmapfile_struct{ + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; + }mmapfile; + + +/* DBUF structure - dynamic string storage */ +typedef struct dbuf_struct{ + char *buf; + unsigned long used_size; + unsigned long allocated_size; + unsigned long chunk_size; + }dbuf; + + +#define CHECK_STATS_BUCKETS 15 + +/* used for tracking host and service check statistics */ +typedef struct check_stats_struct{ + int current_bucket; + int bucket[CHECK_STATS_BUCKETS]; + int overflow_bucket; + int minute_stats[3]; + time_t last_update; + }check_stats; + + +/******************* THREAD STUFF ********************/ + +/* slots in circular buffers */ +#define DEFAULT_EXTERNAL_COMMAND_BUFFER_SLOTS 4096 + +/* worker threads */ +#define TOTAL_WORKER_THREADS 1 + +#define COMMAND_WORKER_THREAD 0 + + + +/******************** FUNCTIONS **********************/ + +/**** Configuration Functions ****/ +int read_main_config_file(char *); /* reads the main config file (nagios.cfg) */ +int read_resource_file(char *); /* processes macros in resource file */ +int read_all_object_data(char *); /* reads all object config data */ + + +/**** Setup Functions ****/ +int pre_flight_check(void); /* try and verify the configuration data */ +int pre_flight_object_check(int *,int *); /* verify object relationships and settings */ +int pre_flight_circular_check(int *,int *); /* detects circular dependencies and paths */ +void init_timing_loop(void); /* setup the initial scheduling queue */ +void setup_sighandler(void); /* trap signals */ +void reset_sighandler(void); /* reset signals to default action */ +int daemon_init(void); /* switches to daemon mode */ +int drop_privileges(char *,char *); /* drops privileges before startup */ +void display_scheduling_info(void); /* displays service check scheduling information */ + + +/**** Event Queue Functions ****/ +int schedule_new_event(int,int,time_t,int,unsigned long,void *,int,void *,void *,int); /* schedules a new timed event */ +void reschedule_event(timed_event *,timed_event **,timed_event **); /* reschedules an event */ +void add_event(timed_event *,timed_event **,timed_event **); /* adds an event to the execution queue */ +void remove_event(timed_event *,timed_event **,timed_event **); /* remove an event from the execution queue */ +int event_execution_loop(void); /* main monitoring/event handler loop */ +int handle_timed_event(timed_event *); /* top level handler for timed events */ +void adjust_check_scheduling(void); /* auto-adjusts scheduling of host and service checks */ +void compensate_for_system_time_change(unsigned long,unsigned long); /* attempts to compensate for a change in the system time */ +void adjust_timestamp_for_time_change(time_t,time_t,unsigned long,time_t *); /* adjusts a timestamp variable for a system time change */ +void resort_event_list(timed_event **,timed_event **); /* resorts event list by event run time for system time changes */ + + +/**** IPC Functions ****/ +int move_check_result_to_queue(char *); +int process_check_result_queue(char *); +int process_check_result_file(char *); +int add_check_result_to_list(check_result *); +check_result *read_check_result(void); /* reads a host/service check result from the list in memory */ +int delete_check_result_file(char *); +int free_check_result_list(void); +int init_check_result(check_result *); +int free_check_result(check_result *); /* frees memory associated with a host/service check result */ +int parse_check_output(char *,char **,char **,char **,int,int); +int open_command_file(void); /* creates the external command file as a named pipe (FIFO) and opens it for reading */ +int close_command_file(void); /* closes and deletes the external command file (FIFO) */ + + +/**** Monitoring/Event Handler Functions ****/ +int check_service_dependencies(service *,int); /* checks service dependencies */ +int check_host_dependencies(host *,int); /* checks host dependencies */ +void check_for_orphaned_services(void); /* checks for orphaned services */ +void check_for_orphaned_hosts(void); /* checks for orphaned hosts */ +void check_service_result_freshness(void); /* checks the "freshness" of service check results */ +int is_service_result_fresh(service *,time_t,int); /* determines if a service's check results are fresh */ +void check_host_result_freshness(void); /* checks the "freshness" of host check results */ +int is_host_result_fresh(host *,time_t,int); /* determines if a host's check results are fresh */ +int my_system(char *,int,int *,double *,char **,int); /* executes a command via popen(), but also protects against timeouts */ + + +/**** Flap Detection Functions ****/ +void check_for_service_flapping(service *,int,int); /* determines whether or not a service is "flapping" between states */ +void check_for_host_flapping(host *,int,int,int); /* determines whether or not a host is "flapping" between states */ +void set_service_flap(service *,double,double,double,int); /* handles a service that is flapping */ +void clear_service_flap(service *,double,double,double); /* handles a service that has stopped flapping */ +void set_host_flap(host *,double,double,double,int); /* handles a host that is flapping */ +void clear_host_flap(host *,double,double,double); /* handles a host that has stopped flapping */ +void enable_flap_detection_routines(void); /* enables flap detection on a program-wide basis */ +void disable_flap_detection_routines(void); /* disables flap detection on a program-wide basis */ +void enable_host_flap_detection(host *); /* enables flap detection for a particular host */ +void disable_host_flap_detection(host *); /* disables flap detection for a particular host */ +void enable_service_flap_detection(service *); /* enables flap detection for a particular service */ +void disable_service_flap_detection(service *); /* disables flap detection for a particular service */ +void handle_host_flap_detection_disabled(host *); /* handles the details when flap detection is disabled globally or on a per-host basis */ +void handle_service_flap_detection_disabled(service *); /* handles the details when flap detection is disabled globally or on a per-service basis */ + + +/**** Route/Host Check Functions ****/ +int perform_on_demand_host_check(host *,int *,int,int,unsigned long); +int perform_scheduled_host_check(host *,int,double); +int check_host_check_viability_3x(host *,int,int *,time_t *); +int adjust_host_check_attempt_3x(host *,int); +int determine_host_reachability(host *); +int process_host_check_result_3x(host *,int,char *,int,int,int,unsigned long); +int perform_on_demand_host_check_3x(host *,int *,int,int,unsigned long); +int run_sync_host_check_3x(host *,int *,int,int,unsigned long); +int execute_sync_host_check_3x(host *); +int run_scheduled_host_check_3x(host *,int,double); +int run_async_host_check_3x(host *,int,double,int,int,int *,time_t *); +int handle_async_host_check_result_3x(host *,check_result *); + + +/**** Service Check Functions ****/ +int check_service_check_viability(service *,int,int *,time_t *); +int run_scheduled_service_check(service *,int,double); +int run_async_service_check(service *,int,double,int,int,int *,time_t *); +int handle_async_service_check_result(service *,check_result *); + + +/**** Event Handler Functions ****/ +int handle_host_state(host *); /* top level host state handler */ + + + +/**** Common Check Fucntions *****/ +int reap_check_results(void); + + +/**** Check Statistics Functions ****/ +int init_check_stats(void); +int update_check_stats(int,time_t); +int generate_check_stats(void); + + + +/**** Event Handler Functions ****/ +int obsessive_compulsive_service_check_processor(service *); /* distributed monitoring craziness... */ +int obsessive_compulsive_host_check_processor(host *); /* distributed monitoring craziness... */ +int handle_service_event(service *); /* top level service event logic */ +int run_service_event_handler(service *); /* runs the event handler for a specific service */ +int run_global_service_event_handler(service *); /* runs the global service event handler */ +int handle_host_event(host *); /* top level host event logic */ +int run_host_event_handler(host *); /* runs the event handler for a specific host */ +int run_global_host_event_handler(host *); /* runs the global host event handler */ + + +/**** Notification Functions ****/ +int check_service_notification_viability(service *,int,int); /* checks viability of notifying all contacts about a service */ +int is_valid_escalation_for_service_notification(service *,serviceescalation *,int); /* checks if an escalation entry is valid for a particular service notification */ +int should_service_notification_be_escalated(service *); /* checks if a service notification should be escalated */ +int service_notification(service *,int,char *,char *,int); /* notify all contacts about a service (problem or recovery) */ +int check_contact_service_notification_viability(contact *,service *,int,int); /* checks viability of notifying a contact about a service */ +int notify_contact_of_service(contact *,service *,int,char *,char *,int,int); /* notify a single contact about a service */ +int check_host_notification_viability(host *,int,int); /* checks viability of notifying all contacts about a host */ +int is_valid_escalation_for_host_notification(host *,hostescalation *,int); /* checks if an escalation entry is valid for a particular host notification */ +int should_host_notification_be_escalated(host *); /* checks if a host notification should be escalated */ +int host_notification(host *,int,char *,char *,int); /* notify all contacts about a host (problem or recovery) */ +int check_contact_host_notification_viability(contact *,host *,int,int); /* checks viability of notifying a contact about a host */ +int notify_contact_of_host(contact *,host *,int,char *,char *,int,int); /* notify a single contact about a host */ +int create_notification_list_from_host(host *,int,int *); /* given a host, create list of contacts to be notified (remove duplicates) */ +int create_notification_list_from_service(service *,int,int *); /* given a service, create list of contacts to be notified (remove duplicates) */ +int add_notification(contact *); /* adds a notification instance */ +notification *find_notification(contact *); /* finds a notification object */ +time_t get_next_host_notification_time(host *,time_t); /* calculates nex acceptable re-notification time for a host */ +time_t get_next_service_notification_time(service *,time_t); /* calculates nex acceptable re-notification time for a service */ + + +/**** Logging Functions ****/ +void logit(int,int,const char *, ...) + __attribute__((__format__(__printf__, 3, 4))); +int write_to_logs_and_console(char *,unsigned long,int); /* writes a string to screen and logs */ +int write_to_console(char *); /* writes a string to screen */ +int write_to_all_logs(char *,unsigned long); /* writes a string to main log file and syslog facility */ +int write_to_all_logs_with_timestamp(char *,unsigned long,time_t *); /* writes a string to main log file and syslog facility */ +int write_to_log(char *,unsigned long,time_t *); /* write a string to the main log file */ +int write_to_syslog(char *,unsigned long); /* write a string to the syslog facility */ +int log_service_event(service *); /* logs a service event */ +int log_host_event(host *); /* logs a host event */ +int log_host_states(int,time_t *); /* logs initial/current host states */ +int log_service_states(int,time_t *); /* logs initial/current service states */ +int rotate_log_file(time_t); /* rotates the main log file */ +int write_log_file_info(time_t *); /* records log file/version info */ +int open_debug_log(void); +int log_debug_info(int,int,const char *,...) + __attribute__((__format__(__printf__, 3, 4))); +int close_debug_log(void); + + +/**** Cleanup Functions ****/ +void cleanup(void); /* cleanup after ourselves (before quitting or restarting) */ +void free_memory(void); /* free memory allocated to all linked lists in memory */ +int reset_variables(void); /* reset all global variables */ +void free_notification_list(void); /* frees all memory allocated to the notification list */ + + +/**** Hash Functions ****/ +int hashfunc(const char *name1, const char *name2, int hashslots); +int compare_hashdata(const char *,const char *,const char *,const char *); + + +/**** Miscellaneous Functions ****/ +void sighandler(int); /* handles signals */ +void service_check_sighandler(int); /* handles timeouts when executing service checks */ +void host_check_sighandler(int); /* handles timeouts when executing host checks */ +void my_system_sighandler(int); /* handles timeouts when executing commands via my_system() */ +void file_lock_sighandler(int); /* handles timeouts while waiting for file locks */ +void strip(char *); /* strips whitespace from string */ +char *my_strtok(char *,char *); /* my replacement for strtok() function (doesn't skip consecutive tokens) */ +char *my_strsep(char **,const char *); /* Solaris doesn't have strsep(), so I took this from the glibc source code */ +#ifdef REMOVED_10182007 +int my_free(void **); /* my wrapper for free() */ +#endif +int compare_strings(char *,char *); /* compares two strings for equality */ +char *escape_newlines(char *); +int contains_illegal_object_chars(char *); /* tests whether or not an object name (host, service, etc.) contains illegal characters */ +int my_rename(char *,char *); /* renames a file - works across filesystems */ +int my_fcopy(char *,char *); /* copies a file - works across filesystems */ +int get_raw_command_line(command *,char *,char **,int); /* given a raw command line, determine the actual command to run */ +int check_time_against_period(time_t,timeperiod *); /* check to see if a specific time is covered by a time period */ +int is_daterange_single_day(daterange *); +time_t calculate_time_from_weekday_of_month(int,int,int,int); /* calculates midnight time of specific (3rd, last, etc.) weekday of a particular month */ +time_t calculate_time_from_day_of_month(int,int,int); /* calculates midnight time of specific (1st, last, etc.) day of a particular month */ +void get_next_valid_time(time_t, time_t *,timeperiod *); /* get the next valid time in a time period */ +void get_datetime_string(time_t *,char *,int,int); /* get a date/time string for use in output */ +void get_time_breakdown(unsigned long,int *,int *,int *, int *); +time_t get_next_log_rotation_time(void); /* determine the next time to schedule a log rotation */ +int init_embedded_perl(char **); /* initialized embedded perl interpreter */ +int deinit_embedded_perl(void); /* cleans up embedded perl */ +int file_uses_embedded_perl(char *); /* tests whether or not the embedded perl interpreter should be used on a file */ +int dbuf_init(dbuf *,int); +int dbuf_free(dbuf *); +int dbuf_strcat(dbuf *,char *); +int set_environment_var(char *,char *,int); /* sets/clears and environment variable */ + + +/**** External Command Functions ****/ +int check_for_external_commands(void); /* checks for any external commands */ +int process_external_command1(char *); /* top-level external command processor */ +int process_external_command2(int,time_t,char *); /* process an external command */ +int process_external_commands_from_file(char *,int); /* process external commands in a file */ +int process_host_command(int,time_t,char *); /* process an external host command */ +int process_hostgroup_command(int,time_t,char *); /* process an external hostgroup command */ +int process_service_command(int,time_t,char *); /* process an external service command */ +int process_servicegroup_command(int,time_t,char *); /* process an external servicegroup command */ +int process_contact_command(int,time_t,char *); /* process an external contact command */ +int process_contactgroup_command(int,time_t,char *); /* process an external contactgroup command */ + + +/**** External Command Implementations ****/ +int cmd_add_comment(int,time_t,char *); /* add a service or host comment */ +int cmd_delete_comment(int,char *); /* delete a service or host comment */ +int cmd_delete_all_comments(int,char *); /* delete all comments associated with a host or service */ +int cmd_delay_notification(int,char *); /* delay a service or host notification */ +int cmd_schedule_service_check(int,char *,int); /* schedule an immediate or delayed service check */ +int cmd_schedule_check(int,char *); /* schedule an immediate or delayed host check */ +int cmd_schedule_host_service_checks(int,char *,int); /* schedule an immediate or delayed checks of all services on a host */ +int cmd_signal_process(int,char *); /* schedules a program shutdown or restart */ +int cmd_process_service_check_result(int,time_t,char *); /* processes a passive service check */ +int cmd_process_host_check_result(int,time_t,char *); /* processes a passive host check */ +int cmd_acknowledge_problem(int,char *); /* acknowledges a host or service problem */ +int cmd_remove_acknowledgement(int,char *); /* removes a host or service acknowledgement */ +int cmd_schedule_downtime(int,time_t,char *); /* schedules host or service downtime */ +int cmd_delete_downtime(int,char *); /* cancels active/pending host or service scheduled downtime */ +int cmd_change_object_int_var(int,char *); /* changes host/svc (int) variable */ +int cmd_change_object_char_var(int,char *); /* changes host/svc (char) variable */ +int cmd_change_object_custom_var(int,char *); /* changes host/svc custom variable */ +int cmd_process_external_commands_from_file(int,char *); /* process external commands from a file */ + +int process_passive_service_check(time_t,char *,char *,int,char *); +int process_passive_host_check(time_t,char *,int,char *); + + +/**** Internal Command Implementations ****/ +void disable_service_checks(service *); /* disables a service check */ +void enable_service_checks(service *); /* enables a service check */ +void schedule_service_check(service *,time_t,int); /* schedules an immediate or delayed service check */ +void schedule_host_check(host *,time_t,int); /* schedules an immediate or delayed host check */ +void enable_all_notifications(void); /* enables notifications on a program-wide basis */ +void disable_all_notifications(void); /* disables notifications on a program-wide basis */ +void enable_service_notifications(service *); /* enables service notifications */ +void disable_service_notifications(service *); /* disables service notifications */ +void enable_host_notifications(host *); /* enables host notifications */ +void disable_host_notifications(host *); /* disables host notifications */ +void enable_and_propagate_notifications(host *,int,int,int,int); /* enables notifications for all hosts and services beyond a given host */ +void disable_and_propagate_notifications(host *,int,int,int,int); /* disables notifications for all hosts and services beyond a given host */ +void schedule_and_propagate_downtime(host *,time_t,char *,char *,time_t,time_t,int,unsigned long,unsigned long); /* schedules downtime for all hosts beyond a given host */ +void acknowledge_host_problem(host *,char *,char *,int,int,int); /* acknowledges a host problem */ +void acknowledge_service_problem(service *,char *,char *,int,int,int); /* acknowledges a service problem */ +void remove_host_acknowledgement(host *); /* removes a host acknowledgement */ +void remove_service_acknowledgement(service *); /* removes a service acknowledgement */ +void start_executing_service_checks(void); /* starts executing service checks */ +void stop_executing_service_checks(void); /* stops executing service checks */ +void start_accepting_passive_service_checks(void); /* starts accepting passive service check results */ +void stop_accepting_passive_service_checks(void); /* stops accepting passive service check results */ +void enable_passive_service_checks(service *); /* enables passive service checks for a particular service */ +void disable_passive_service_checks(service *); /* disables passive service checks for a particular service */ +void start_using_event_handlers(void); /* enables event handlers on a program-wide basis */ +void stop_using_event_handlers(void); /* disables event handlers on a program-wide basis */ +void enable_service_event_handler(service *); /* enables the event handler for a particular service */ +void disable_service_event_handler(service *); /* disables the event handler for a particular service */ +void enable_host_event_handler(host *); /* enables the event handler for a particular host */ +void disable_host_event_handler(host *); /* disables the event handler for a particular host */ +void enable_host_checks(host *); /* enables checks of a particular host */ +void disable_host_checks(host *); /* disables checks of a particular host */ +void start_obsessing_over_service_checks(void); /* start obsessing about service check results */ +void stop_obsessing_over_service_checks(void); /* stop obsessing about service check results */ +void start_obsessing_over_host_checks(void); /* start obsessing about host check results */ +void stop_obsessing_over_host_checks(void); /* stop obsessing about host check results */ +void enable_service_freshness_checks(void); /* enable service freshness checks */ +void disable_service_freshness_checks(void); /* disable service freshness checks */ +void enable_host_freshness_checks(void); /* enable host freshness checks */ +void disable_host_freshness_checks(void); /* disable host freshness checks */ +void process_passive_checks(void); /* processes passive host and service check results */ +void enable_all_failure_prediction(void); /* enables failure prediction on a program-wide basis */ +void disable_all_failure_prediction(void); /* disables failure prediction on a program-wide basis */ +void enable_performance_data(void); /* enables processing of performance data on a program-wide basis */ +void disable_performance_data(void); /* disables processing of performance data on a program-wide basis */ +void start_executing_host_checks(void); /* starts executing host checks */ +void stop_executing_host_checks(void); /* stops executing host checks */ +void start_accepting_passive_host_checks(void); /* starts accepting passive host check results */ +void stop_accepting_passive_host_checks(void); /* stops accepting passive host check results */ +void enable_passive_host_checks(host *); /* enables passive host checks for a particular host */ +void disable_passive_host_checks(host *); /* disables passive host checks for a particular host */ +void start_obsessing_over_service(service *); /* start obsessing about specific service check results */ +void stop_obsessing_over_service(service *); /* stop obsessing about specific service check results */ +void start_obsessing_over_host(host *); /* start obsessing about specific host check results */ +void stop_obsessing_over_host(host *); /* stop obsessing about specific host check results */ +void set_host_notification_number(host *,int); /* sets current notification number for a specific host */ +void set_service_notification_number(service *,int); /* sets current notification number for a specific service */ +void enable_contact_host_notifications(contact *); /* enables host notifications for a specific contact */ +void disable_contact_host_notifications(contact *); /* disables host notifications for a specific contact */ +void enable_contact_service_notifications(contact *); /* enables service notifications for a specific contact */ +void disable_contact_service_notifications(contact *); /* disables service notifications for a specific contact */ + +int init_check_result_worker_thread(void); +int shutdown_check_result_worker_thread(void); +void * check_result_worker_thread(void *); +void cleanup_check_result_worker_thread(void *); + +int init_command_file_worker_thread(void); +int shutdown_command_file_worker_thread(void); +void * command_file_worker_thread(void *); +void cleanup_command_file_worker_thread(void *); + +int submit_external_command(char *,int *); +int submit_raw_external_command(char *,time_t *,int *); + +char *get_program_version(void); +char *get_program_modification_date(void); + +mmapfile *mmap_fopen(char *); /* open a file read-only via mmap() */ +int mmap_fclose(mmapfile *); +char *mmap_fgets(mmapfile *); +char *mmap_fgets_multiline(mmapfile *); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/include/nebcallbacks.h b/include/nebcallbacks.h new file mode 100644 index 0000000..a0fc3d5 --- /dev/null +++ b/include/nebcallbacks.h @@ -0,0 +1,88 @@ +/***************************************************************************** + * + * NEBCALLBACKS.H - Include file for event broker modules + * + * Copyright (c) 2002-2007 Ethan Galstad (nagios@nagios.org) + * Last Modified: 01-06-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBCALLBACKS_H +#define _NEBCALLBACKS_H + +#include "config.h" +#include "nebmodules.h" + +#ifdef __cplusplus + extern "C" { +#endif + + +/***** CALLBACK TYPES *****/ + +#define NEBCALLBACK_NUMITEMS 33 /* total number of callback types we have */ + +#define NEBCALLBACK_RESERVED0 0 /* reserved for future use */ +#define NEBCALLBACK_RESERVED1 1 +#define NEBCALLBACK_RESERVED2 2 +#define NEBCALLBACK_RESERVED3 3 +#define NEBCALLBACK_RESERVED4 4 + +#define NEBCALLBACK_RAW_DATA 5 +#define NEBCALLBACK_NEB_DATA 6 + +#define NEBCALLBACK_PROCESS_DATA 7 +#define NEBCALLBACK_TIMED_EVENT_DATA 8 +#define NEBCALLBACK_LOG_DATA 9 +#define NEBCALLBACK_SYSTEM_COMMAND_DATA 10 +#define NEBCALLBACK_EVENT_HANDLER_DATA 11 +#define NEBCALLBACK_NOTIFICATION_DATA 12 +#define NEBCALLBACK_SERVICE_CHECK_DATA 13 +#define NEBCALLBACK_HOST_CHECK_DATA 14 +#define NEBCALLBACK_COMMENT_DATA 15 +#define NEBCALLBACK_DOWNTIME_DATA 16 +#define NEBCALLBACK_FLAPPING_DATA 17 +#define NEBCALLBACK_PROGRAM_STATUS_DATA 18 +#define NEBCALLBACK_HOST_STATUS_DATA 19 +#define NEBCALLBACK_SERVICE_STATUS_DATA 20 +#define NEBCALLBACK_ADAPTIVE_PROGRAM_DATA 21 +#define NEBCALLBACK_ADAPTIVE_HOST_DATA 22 +#define NEBCALLBACK_ADAPTIVE_SERVICE_DATA 23 +#define NEBCALLBACK_EXTERNAL_COMMAND_DATA 24 +#define NEBCALLBACK_AGGREGATED_STATUS_DATA 25 +#define NEBCALLBACK_RETENTION_DATA 26 +#define NEBCALLBACK_CONTACT_NOTIFICATION_DATA 27 +#define NEBCALLBACK_CONTACT_NOTIFICATION_METHOD_DATA 28 +#define NEBCALLBACK_ACKNOWLEDGEMENT_DATA 29 +#define NEBCALLBACK_STATE_CHANGE_DATA 30 +#define NEBCALLBACK_CONTACT_STATUS_DATA 31 +#define NEBCALLBACK_ADAPTIVE_CONTACT_DATA 32 + + +/***** CALLBACK FUNCTIONS *****/ + +int neb_register_callback(int callback_type, void *mod_handle, int priority, int (*callback_func)(int,void *)); +int neb_deregister_callback(int callback_type, int (*callback_func)(int,void *)); +int neb_deregister_module_callbacks(nebmodule *); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/nebmodules.h b/include/nebmodules.h new file mode 100644 index 0000000..bb279e8 --- /dev/null +++ b/include/nebmodules.h @@ -0,0 +1,102 @@ +/***************************************************************************** + * + * NEBMODULES.H - Include file for event broker modules + * + * Copyright (c) 2002-2006 Ethan Galstad (nagios@nagios.org) + * Last Modified: 02-27-2006 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBMODULES_H +#define _NEBMODULES_H + +#ifdef __cplusplus + extern "C" { +#endif + +/***** MODULE VERSION INFORMATION *****/ + +#define NEB_API_VERSION(x) int __neb_api_version = x; +#define CURRENT_NEB_API_VERSION 3 + + + +/***** MODULE INFORMATION *****/ + +#define NEBMODULE_MODINFO_NUMITEMS 6 +#define NEBMODULE_MODINFO_TITLE 0 +#define NEBMODULE_MODINFO_AUTHOR 1 +#define NEBMODULE_MODINFO_COPYRIGHT 2 +#define NEBMODULE_MODINFO_VERSION 3 +#define NEBMODULE_MODINFO_LICENSE 4 +#define NEBMODULE_MODINFO_DESC 5 + + + +/***** MODULE LOAD/UNLOAD OPTIONS *****/ + +#define NEBMODULE_NORMAL_LOAD 0 /* module is being loaded normally */ +#define NEBMODULE_REQUEST_UNLOAD 0 /* request module to unload (but don't force it) */ +#define NEBMODULE_FORCE_UNLOAD 1 /* force module to unload */ + + + +/***** MODULES UNLOAD REASONS *****/ + +#define NEBMODULE_NEB_SHUTDOWN 1 /* event broker is shutting down */ +#define NEBMODULE_NEB_RESTART 2 /* event broker is restarting */ +#define NEBMODULE_ERROR_NO_INIT 3 /* _module_init() function was not found in module */ +#define NEBMODULE_ERROR_BAD_INIT 4 /* _module_init() function returned a bad code */ +#define NEBMODULE_ERROR_API_VERSION 5 /* module version is incompatible with current api */ + + + +/***** MODULE STRUCTURES *****/ + +/* NEB module structure */ +typedef struct nebmodule_struct{ + char *filename; + char *args; + char *info[NEBMODULE_MODINFO_NUMITEMS]; + int should_be_loaded; + int is_currently_loaded; +#ifdef USE_LTDL + lt_dlhandle module_handle; + lt_ptr init_func; + lt_ptr deinit_func; +#else + void *module_handle; + void *init_func; + void *deinit_func; +#endif +#ifdef HAVE_PTHREAD_H + pthread_t thread_id; +#endif + struct nebmodule_struct *next; + }nebmodule; + + + +/***** MODULE FUNCTIONS *****/ +int neb_set_module_info(void *,int,char *); + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/include/nebstructs.h b/include/nebstructs.h new file mode 100644 index 0000000..dfb5a16 --- /dev/null +++ b/include/nebstructs.h @@ -0,0 +1,533 @@ +/***************************************************************************** + * + * NEBSTRUCTS.H - Event broker includes for Nagios + * + * Copyright (c) 2003-2007 Ethan Galstad (nagios@nagios.org) + * Last Modified: 10-28-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#ifndef _NEBSTRUCTS_H +#define _NEBSTRUCTS_H + +#include "config.h" +#include "pnp.h" +#include "objects.h" +#include "nagios.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/****** STRUCTURES *************************/ + +/* process data structure */ +typedef struct nebstruct_process_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + }nebstruct_process_data; + + +/* timed event data structure */ +typedef struct nebstruct_timed_event_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int event_type; + int recurring; + time_t run_time; + void *event_data; + + void *event_ptr; + }nebstruct_timed_event_data; + + +/* log data structure */ +typedef struct nebstruct_log_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t entry_time; + int data_type; + char *data; + }nebstruct_log_data; + + +/* system command structure */ +typedef struct nebstruct_system_command_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + struct timeval start_time; + struct timeval end_time; + int timeout; + char *command_line; + int early_timeout; + double execution_time; + int return_code; + char *output; + }nebstruct_system_command_data; + + +/* event handler structure */ +typedef struct nebstruct_event_handler_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int eventhandler_type; + char *host_name; + char *service_description; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + int return_code; + char *output; + + void *object_ptr; + }nebstruct_event_handler_data; + + +/* host check structure */ +typedef struct nebstruct_host_check_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + int current_attempt; + int check_type; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + }nebstruct_host_check_data; + + +/* service check structure */ +typedef struct nebstruct_service_check_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + char *host_name; + char *service_description; + int check_type; + int current_attempt; + int max_attempts; + int state_type; + int state; + int timeout; + char *command_name; + char *command_args; + char *command_line; + struct timeval start_time; + struct timeval end_time; + int early_timeout; + double execution_time; + double latency; + int return_code; + char *output; + char *long_output; + char *perf_data; + + void *object_ptr; + }nebstruct_service_check_data; + + +/* comment data structure */ +typedef struct nebstruct_comment_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int comment_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + int persistent; + int source; + int entry_type; + int expires; + time_t expire_time; + unsigned long comment_id; + + void *object_ptr; /* not implemented yet */ + }nebstruct_comment_data; + + +/* downtime data structure */ +typedef struct nebstruct_downtime_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int downtime_type; + char *host_name; + char *service_description; + time_t entry_time; + char *author_name; + char *comment_data; + time_t start_time; + time_t end_time; + int fixed; + unsigned long duration; + unsigned long triggered_by; + unsigned long downtime_id; + + void *object_ptr; /* not implemented yet */ + }nebstruct_downtime_data; + + +/* flapping data structure */ +typedef struct nebstruct_flapping_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int flapping_type; + char *host_name; + char *service_description; + double percent_change; + double high_threshold; + double low_threshold; + unsigned long comment_id; + + void *object_ptr; + }nebstruct_flapping_data; + + +/* program status structure */ +typedef struct nebstruct_program_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + time_t program_start; + int pid; + int daemon_mode; + time_t last_command_check; + time_t last_log_rotation; + int notifications_enabled; + int active_service_checks_enabled; + int passive_service_checks_enabled; + int active_host_checks_enabled; + int passive_host_checks_enabled; + int event_handlers_enabled; + int flap_detection_enabled; + int failure_prediction_enabled; + int process_performance_data; + int obsess_over_hosts; + int obsess_over_services; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + char *global_host_event_handler; + char *global_service_event_handler; + }nebstruct_program_status_data; + + +/* host status structure */ +typedef struct nebstruct_host_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_host_status_data; + + +/* service status structure */ +typedef struct nebstruct_service_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_service_status_data; + + +/* contact status structure */ +typedef struct nebstruct_contact_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + void *object_ptr; + }nebstruct_contact_status_data; + + +/* notification data structure */ +typedef struct nebstruct_notification_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + int contacts_notified; + + void *object_ptr; + }nebstruct_notification_data; + + +/* contact notification data structure */ +typedef struct nebstruct_contact_notification_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + }nebstruct_contact_notification_data; + + +/* contact notification method data structure */ +typedef struct nebstruct_contact_notification_method_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int notification_type; + struct timeval start_time; + struct timeval end_time; + char *host_name; + char *service_description; + char *contact_name; + char *command_name; + char *command_args; + int reason_type; + int state; + char *output; + char *ack_author; + char *ack_data; + int escalated; + + void *object_ptr; + void *contact_ptr; + }nebstruct_contact_notification_method_data; + + +/* adaptive program data structure */ +typedef struct nebstruct_adaptive_program_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + }nebstruct_adaptive_program_data; + + +/* adaptive host data structure */ +typedef struct nebstruct_adaptive_host_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + }nebstruct_adaptive_host_data; + + +/* adaptive service data structure */ +typedef struct nebstruct_adaptive_service_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + + void *object_ptr; + }nebstruct_adaptive_service_data; + + +/* adaptive contact data structure */ +typedef struct nebstruct_adaptive_contact_data_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + unsigned long modified_attribute; + unsigned long modified_attributes; + unsigned long modified_host_attribute; + unsigned long modified_host_attributes; + unsigned long modified_service_attribute; + unsigned long modified_service_attributes; + + void *object_ptr; + }nebstruct_adaptive_contact_data; + + +/* external command data structure */ +typedef struct nebstruct_external_command_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int command_type; + time_t entry_time; + char *command_string; + char *command_args; + }nebstruct_external_command_data; + + +/* aggregated status data structure */ +typedef struct nebstruct_aggregated_status_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + }nebstruct_aggregated_status_data; + + +/* retention data structure */ +typedef struct nebstruct_retention_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + }nebstruct_retention_data; + + +/* acknowledgement structure */ +typedef struct nebstruct_acknowledgement_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int acknowledgement_type; + char *host_name; + char *service_description; + int state; + char *author_name; + char *comment_data; + int is_sticky; + int persistent_comment; + int notify_contacts; + + void *object_ptr; + }nebstruct_acknowledgement_data; + + +/* state change structure */ +typedef struct nebstruct_statechange_struct{ + int type; + int flags; + int attr; + struct timeval timestamp; + + int statechange_type; + char *host_name; + char *service_description; + int state; + int state_type; + int current_attempt; + int max_attempts; + char *output; + + void *object_ptr; + }nebstruct_statechange_data; + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/include/npcdmod.h b/include/npcdmod.h new file mode 100644 index 0000000..f72d9d3 --- /dev/null +++ b/include/npcdmod.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * + * NPCDMOD.H + * + * Copyright (c) 2008 Hendrik Baecker (http://www.pnp4nagios.org) + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Last Modified: 11-18-2008 + * + *****************************************************************************/ + +#define PERFDATA_BUFFER 65536 + + +/* MMAPFILE structure - used for reading files via mmap() */ +typedef struct pnp_mmapfile_struct { + char *path; + int mode; + int fd; + unsigned long file_size; + unsigned long current_position; + unsigned long current_line; + void *mmap_buf; +} pnp_mmapfile; + +pnp_mmapfile *pnp_mmap_fopen(char *); /* open a file read-only via mmap() */ +int pnp_mmap_fclose(pnp_mmapfile *); +char *pnp_mmap_fgets(pnp_mmapfile *); +char *pnp_mmap_fgets_multiline(pnp_mmapfile *); +extern void pnp_strip(char *); diff --git a/include/objects.h b/include/objects.h new file mode 100644 index 0000000..f82e39f --- /dev/null +++ b/include/objects.h @@ -0,0 +1,771 @@ +/***************************************************************************** + * + * OBJECTS.H - Header file for object addition/search functions + * + * Copyright (c) 1999-2007 Ethan Galstad (nagios@nagios.org) + * Last Modified: 11-10-2007 + * + * License: + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + + +#ifndef _OBJECTS_H +#define _OBJECTS_H + +#include "config.h" +#include "common.h" + +#ifdef __cplusplus + extern "C" { +#endif + + + +/*************** CURRENT OBJECT REVISION **************/ + +#define CURRENT_OBJECT_STRUCTURE_VERSION 307 /* increment when changes are made to data structures... */ + /* Nagios 3 starts at 300, Nagios 4 at 400, etc. */ + + + +/***************** OBJECT SIZE LIMITS *****************/ + +#define MAX_STATE_HISTORY_ENTRIES 21 /* max number of old states to keep track of for flap detection */ +#define MAX_CONTACT_ADDRESSES 6 /* max number of custom addresses a contact can have */ + + + +/***************** SKIP LISTS ****************/ + +#define NUM_OBJECT_SKIPLISTS 13 + +#define HOST_SKIPLIST 1 +#define SERVICE_SKIPLIST 2 +#define COMMAND_SKIPLIST 3 +#define TIMEPERIOD_SKIPLIST 4 +#define CONTACT_SKIPLIST 5 +#define CONTACTGROUP_SKIPLIST 6 +#define HOSTGROUP_SKIPLIST 7 +#define SERVICEGROUP_SKIPLIST 8 +#define HOSTDEPENDENCY_SKIPLIST 9 +#define SERVICEDEPENDENCY_SKIPLIST 10 +#define HOSTESCALATION_SKIPLIST 11 +#define SERVICEESCALATION_SKIPLIST 12 + + +/****************** DATA STRUCTURES *******************/ + +typedef struct host_struct host; +typedef struct service_struct service; +typedef struct contact_struct contact; + +/* OBJECT LIST STRUCTURE */ +typedef struct objectlist_struct{ + void *object_ptr; + struct objectlist_struct *next; + }objectlist; + + +/* TIMERANGE structure */ +typedef struct timerange_struct{ + unsigned long range_start; + unsigned long range_end; + struct timerange_struct *next; + }timerange; + + +/* DATERANGE structure */ +typedef struct daterange_struct{ + int type; + int syear; /* start year */ + int smon; /* start month */ + int smday; /* start day of month (may 3rd, last day in feb) */ + int swday; /* start day of week (thursday) */ + int swday_offset; /* start weekday offset (3rd thursday, last monday in jan) */ + int eyear; + int emon; + int emday; + int ewday; + int ewday_offset; + int skip_interval; + timerange *times; + struct daterange_struct *next; + }daterange; + + +/* TIMEPERIODEXCLUSION structure */ +typedef struct timeperiodexclusion_struct{ + char *timeperiod_name; + struct timeperiod_struct *timeperiod_ptr; + struct timeperiodexclusion_struct *next; + }timeperiodexclusion; + + +/* TIMEPERIOD structure */ +typedef struct timeperiod_struct{ + char *name; + char *alias; + timerange *days[7]; + daterange *exceptions[DATERANGE_TYPES]; + timeperiodexclusion *exclusions; + struct timeperiod_struct *next; + struct timeperiod_struct *nexthash; + }timeperiod; + + +/* CONTACTSMEMBER structure */ +typedef struct contactsmember_struct{ + char *contact_name; +#ifdef NSCORE + contact *contact_ptr; +#endif + struct contactsmember_struct *next; + }contactsmember; + + +/* CONTACTGROUP structure */ +typedef struct contactgroup_struct{ + char *group_name; + char *alias; + contactsmember *members; + struct contactgroup_struct *next; + struct contactgroup_struct *nexthash; + }contactgroup; + + +/* CONTACTGROUPSMEMBER structure */ +typedef struct contactgroupsmember_struct{ + char *group_name; +#ifdef NSCORE + contactgroup *group_ptr; +#endif + struct contactgroupsmember_struct *next; + }contactgroupsmember; + + +/* CUSTOMVARIABLESMEMBER structure */ +typedef struct customvariablesmember_struct{ + char *variable_name; + char *variable_value; + int has_been_modified; + struct customvariablesmember_struct *next; + }customvariablesmember; + + +/* COMMAND structure */ +typedef struct command_struct{ + char *name; + char *command_line; + struct command_struct *next; + struct command_struct *nexthash; + }command; + + +/* COMMANDSMEMBER structure */ +typedef struct commandsmember_struct{ + char *command; +#ifdef NSCORE + command *command_ptr; +#endif + struct commandsmember_struct *next; + }commandsmember; + + +/* CONTACT structure */ +struct contact_struct{ + char *name; + char *alias; + char *email; + char *pager; + char *address[MAX_CONTACT_ADDRESSES]; + commandsmember *host_notification_commands; + commandsmember *service_notification_commands; + int notify_on_service_unknown; + int notify_on_service_warning; + int notify_on_service_critical; + int notify_on_service_recovery; + int notify_on_service_flapping; + int notify_on_service_downtime; + int notify_on_host_down; + int notify_on_host_unreachable; + int notify_on_host_recovery; + int notify_on_host_flapping; + int notify_on_host_downtime; + char *host_notification_period; + char *service_notification_period; + int host_notifications_enabled; + int service_notifications_enabled; + int can_submit_commands; + int retain_status_information; + int retain_nonstatus_information; + customvariablesmember *custom_variables; +#ifdef NSCORE + time_t last_host_notification; + time_t last_service_notification; + unsigned long modified_attributes; + unsigned long modified_host_attributes; + unsigned long modified_service_attributes; + + timeperiod *host_notification_period_ptr; + timeperiod *service_notification_period_ptr; + objectlist *contactgroups_ptr; +#endif + struct contact_struct *next; + struct contact_struct *nexthash; + }; + + +/* SERVICESMEMBER structure */ +typedef struct servicesmember_struct{ + char *host_name; + char *service_description; +#ifdef NSCORE + service *service_ptr; +#endif + struct servicesmember_struct *next; + }servicesmember; + + +/* HOSTSMEMBER structure */ +typedef struct hostsmember_struct{ + char *host_name; +#ifdef NSCORE + host *host_ptr; +#endif + struct hostsmember_struct *next; + }hostsmember; + + +/* HOSTGROUP structure */ +typedef struct hostgroup_struct{ + char *group_name; + char *alias; + hostsmember *members; + char *notes; + char *notes_url; + char *action_url; + struct hostgroup_struct *next; + struct hostgroup_struct *nexthash; + }hostgroup; + + +/* HOST structure */ +struct host_struct{ + char *name; + char *display_name; + char *alias; + char *address; + hostsmember *parent_hosts; + hostsmember *child_hosts; + servicesmember *services; + char *host_check_command; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + char *event_handler; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_down; + int notify_on_unreachable; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_up; + int flap_detection_on_down; + int flap_detection_on_unreachable; + int stalk_on_up; + int stalk_on_down; + int stalk_on_unreachable; + int check_freshness; + int freshness_threshold; + int process_performance_data; + int checks_enabled; + int accept_passive_host_checks; + int event_handler_enabled; + int retain_status_information; + int retain_nonstatus_information; + int failure_prediction_enabled; + char *failure_prediction_options; + int obsess_over_host; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + char *vrml_image; + char *statusmap_image; + int have_2d_coords; + int x_2d; + int y_2d; + int have_3d_coords; + double x_3d; + double y_3d; + double z_3d; + int should_be_drawn; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int notifications_enabled; + time_t last_host_notification; + time_t next_host_notification; + time_t next_check; + int should_be_scheduled; + time_t last_check; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_up; + time_t last_time_down; + time_t last_time_unreachable; + int has_been_checked; + int is_being_freshened; + int notified_on_down; + int notified_on_unreachable; + int current_notification_number; + int no_more_notifications; + unsigned long current_notification_id; + int check_flapping_recovery_notification; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + time_t last_state_history_update; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + int total_services; + unsigned long total_service_check_interval; + unsigned long modified_attributes; + int circular_path_checked; + int contains_circular_path; + + command *event_handler_ptr; + command *check_command_ptr; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *hostgroups_ptr; +#endif + struct host_struct *next; + struct host_struct *nexthash; + }; + + +/* SERVICEGROUP structure */ +typedef struct servicegroup_struct{ + char *group_name; + char *alias; + servicesmember *members; + char *notes; + char *notes_url; + char *action_url; + struct servicegroup_struct *next; + struct servicegroup_struct *nexthash; + }servicegroup; + + +/* SERVICE structure */ +struct service_struct{ + char *host_name; + char *description; + char *display_name; + char *service_check_command; + char *event_handler; + int initial_state; + double check_interval; + double retry_interval; + int max_attempts; + int parallelize; + contactgroupsmember *contact_groups; + contactsmember *contacts; + double notification_interval; + double first_notification_delay; + int notify_on_unknown; + int notify_on_warning; + int notify_on_critical; + int notify_on_recovery; + int notify_on_flapping; + int notify_on_downtime; + int stalk_on_ok; + int stalk_on_warning; + int stalk_on_unknown; + int stalk_on_critical; + int is_volatile; + char *notification_period; + char *check_period; + int flap_detection_enabled; + double low_flap_threshold; + double high_flap_threshold; + int flap_detection_on_ok; + int flap_detection_on_warning; + int flap_detection_on_unknown; + int flap_detection_on_critical; + int process_performance_data; + int check_freshness; + int freshness_threshold; + int accept_passive_service_checks; + int event_handler_enabled; + int checks_enabled; + int retain_status_information; + int retain_nonstatus_information; + int notifications_enabled; + int obsess_over_service; + int failure_prediction_enabled; + char *failure_prediction_options; + char *notes; + char *notes_url; + char *action_url; + char *icon_image; + char *icon_image_alt; + customvariablesmember *custom_variables; +#ifdef NSCORE + int problem_has_been_acknowledged; + int acknowledgement_type; + int host_problem_at_last_check; + int check_type; + int current_state; + int last_state; + int last_hard_state; + char *plugin_output; + char *long_plugin_output; + char *perf_data; + int state_type; + time_t next_check; + int should_be_scheduled; + time_t last_check; + int current_attempt; + unsigned long current_event_id; + unsigned long last_event_id; + unsigned long current_problem_id; + unsigned long last_problem_id; + time_t last_notification; + time_t next_notification; + int no_more_notifications; + int check_flapping_recovery_notification; + time_t last_state_change; + time_t last_hard_state_change; + time_t last_time_ok; + time_t last_time_warning; + time_t last_time_unknown; + time_t last_time_critical; + int has_been_checked; + int is_being_freshened; + int notified_on_unknown; + int notified_on_warning; + int notified_on_critical; + int current_notification_number; + unsigned long current_notification_id; + double latency; + double execution_time; + int is_executing; + int check_options; + int scheduled_downtime_depth; + int pending_flex_downtime; + int state_history[MAX_STATE_HISTORY_ENTRIES]; /* flap detection */ + int state_history_index; + int is_flapping; + unsigned long flapping_comment_id; + double percent_state_change; + unsigned long modified_attributes; + + host *host_ptr; + command *event_handler_ptr; + char *event_handler_args; + command *check_command_ptr; + char *check_command_args; + timeperiod *check_period_ptr; + timeperiod *notification_period_ptr; + objectlist *servicegroups_ptr; +#endif + struct service_struct *next; + struct service_struct *nexthash; + }; + + +/* SERVICE ESCALATION structure */ +typedef struct serviceescalation_struct{ + char *host_name; + char *description; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_warning; + int escalate_on_unknown; + int escalate_on_critical; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + service *service_ptr; + timeperiod *escalation_period_ptr; +#endif + struct serviceescalation_struct *next; + struct serviceescalation_struct *nexthash; + }serviceescalation; + + +/* SERVICE DEPENDENCY structure */ +typedef struct servicedependency_struct{ + int dependency_type; + char *dependent_host_name; + char *dependent_service_description; + char *host_name; + char *service_description; + char *dependency_period; + int inherits_parent; + int fail_on_ok; + int fail_on_warning; + int fail_on_unknown; + int fail_on_critical; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + service *master_service_ptr; + service *dependent_service_ptr; + timeperiod *dependency_period_ptr; +#endif + struct servicedependency_struct *next; + struct servicedependency_struct *nexthash; + }servicedependency; + + +/* HOST ESCALATION structure */ +typedef struct hostescalation_struct{ + char *host_name; + int first_notification; + int last_notification; + double notification_interval; + char *escalation_period; + int escalate_on_recovery; + int escalate_on_down; + int escalate_on_unreachable; + contactgroupsmember *contact_groups; + contactsmember *contacts; +#ifdef NSCORE + host *host_ptr; + timeperiod *escalation_period_ptr; +#endif + struct hostescalation_struct *next; + struct hostescalation_struct *nexthash; + }hostescalation; + + +/* HOST DEPENDENCY structure */ +typedef struct hostdependency_struct{ + int dependency_type; + char *dependent_host_name; + char *host_name; + char *dependency_period; + int inherits_parent; + int fail_on_up; + int fail_on_down; + int fail_on_unreachable; + int fail_on_pending; +#ifdef NSCORE + int circular_path_checked; + int contains_circular_path; + + host *master_host_ptr; + host *dependent_host_ptr; + timeperiod *dependency_period_ptr; +#endif + struct hostdependency_struct *next; + struct hostdependency_struct *nexthash; + }hostdependency; + + + + +/****************** HASH STRUCTURES ********************/ + +typedef struct host_cursor_struct{ + int host_hashchain_iterator; + host *current_host_pointer; + }host_cursor; + + + + + +/********************* FUNCTIONS **********************/ + +/**** Top-level input functions ****/ +int read_object_config_data(char *,int,int,int); /* reads all external configuration data of specific types */ + + +/**** Object Creation Functions ****/ +contact *add_contact(char *,char *,char *,char *,char **,char *,char *,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int); /* adds a contact definition */ +commandsmember *add_service_notification_command_to_contact(contact *,char *); /* adds a service notification command to a contact definition */ +commandsmember *add_host_notification_command_to_contact(contact *,char *); /* adds a host notification command to a contact definition */ +customvariablesmember *add_custom_variable_to_contact(contact *,char *,char *); /* adds a custom variable to a service definition */ +host *add_host(char *,char *,char *,char *,char *,int,double,double,int,int,int,int,int,int,double,double,char *,int,char *,int,int,char *,int,int,double,double,int,int,int,int,int,int,int,int,char *,int,int,char *,char *,char *,char *,char *,char *,char *,int,int,int,double,double,double,int,int,int,int,int); /* adds a host definition */ +hostsmember *add_parent_host_to_host(host *,char *); /* adds a parent host to a host definition */ +hostsmember *add_child_link_to_host(host *,host *); /* adds a child host to a host definition */ +contactgroupsmember *add_contactgroup_to_host(host *,char *); /* adds a contactgroup to a host definition */ +contactsmember *add_contact_to_host(host *,char *); /* adds a contact to a host definition */ +customvariablesmember *add_custom_variable_to_host(host *,char *,char *); /* adds a custom variable to a host definition */ +timeperiod *add_timeperiod(char *,char *); /* adds a timeperiod definition */ +timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *,char *); /* adds an exclusion to a timeperiod */ +timerange *add_timerange_to_timeperiod(timeperiod *,int,unsigned long,unsigned long); /* adds a timerange to a timeperiod definition */ +daterange *add_exception_to_timeperiod(timeperiod *,int,int,int,int,int,int,int,int,int,int,int,int); +timerange *add_timerange_to_daterange(daterange *,unsigned long,unsigned long); +hostgroup *add_hostgroup(char *,char *,char *,char *,char *); /* adds a hostgroup definition */ +hostsmember *add_host_to_hostgroup(hostgroup *, char *); /* adds a host to a hostgroup definition */ +servicegroup *add_servicegroup(char *,char *,char *,char *,char *); /* adds a servicegroup definition */ +servicesmember *add_service_to_servicegroup(servicegroup *,char *,char *); /* adds a service to a servicegroup definition */ +contactgroup *add_contactgroup(char *,char *); /* adds a contactgroup definition */ +contactsmember *add_contact_to_contactgroup(contactgroup *,char *); /* adds a contact to a contact group definition */ +command *add_command(char *,char *); /* adds a command definition */ +service *add_service(char *,char *,char *,char *,int,int,int,int,double,double,double,double,char *,int,int,int,int,int,int,int,int,char *,int,char *,int,int,double,double,int,int,int,int,int,int,int,int,int,int,char *,int,int,char *,char *,char *,char *,char *,int,int,int); /* adds a service definition */ +contactgroupsmember *add_contactgroup_to_service(service *,char *); /* adds a contact group to a service definition */ +contactsmember *add_contact_to_service(service *,char *); /* adds a contact to a host definition */ +serviceescalation *add_serviceescalation(char *,char *,int,int,double,char *,int,int,int,int); /* adds a service escalation definition */ +contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *,char *); /* adds a contact group to a service escalation definition */ +contactsmember *add_contact_to_serviceescalation(serviceescalation *,char *); /* adds a contact to a service escalation definition */ +customvariablesmember *add_custom_variable_to_service(service *,char *,char *); /* adds a custom variable to a service definition */ +servicedependency *add_service_dependency(char *,char *,char *,char *,int,int,int,int,int,int,int,char *); /* adds a service dependency definition */ +hostdependency *add_host_dependency(char *,char *,int,int,int,int,int,int,char *); /* adds a host dependency definition */ +hostescalation *add_hostescalation(char *,int,int,double,char *,int,int,int); /* adds a host escalation definition */ +contactsmember *add_contact_to_hostescalation(hostescalation *,char *); /* adds a contact to a host escalation definition */ +contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *,char *); /* adds a contact group to a host escalation definition */ + +contactsmember *add_contact_to_object(contactsmember **,char *); /* adds a contact to an object */ +customvariablesmember *add_custom_variable_to_object(customvariablesmember **,char *,char *); /* adds a custom variable to an object */ + + +servicesmember *add_service_link_to_host(host *,service *); + + +/*** Object Skiplist Functions ****/ +int init_object_skiplists(void); +int free_object_skiplists(void); +int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b); +int skiplist_compare_host(void *a, void *b); +int skiplist_compare_service(void *a, void *b); +int skiplist_compare_command(void *a, void *b); +int skiplist_compare_timeperiod(void *a, void *b); +int skiplist_compare_contact(void *a, void *b); +int skiplist_compare_contactgroup(void *a, void *b); +int skiplist_compare_hostgroup(void *a, void *b); +int skiplist_compare_servicegroup(void *a, void *b); +int skiplist_compare_hostescalation(void *a, void *b); +int skiplist_compare_serviceescalation(void *a, void *b); +int skiplist_compare_hostdependency(void *a, void *b); +int skiplist_compare_servicedependency(void *a, void *b); + +int get_host_count(void); +int get_service_count(void); + + + +/**** Object Hash Functions ****/ +int add_servicedependency_to_hashlist(servicedependency *); + + +/**** Object Search Functions ****/ +timeperiod * find_timeperiod(char *); /* finds a timeperiod object */ +host * find_host(char *); /* finds a host object */ +hostgroup * find_hostgroup(char *); /* finds a hostgroup object */ +servicegroup * find_servicegroup(char *); /* finds a servicegroup object */ +contact * find_contact(char *); /* finds a contact object */ +contactgroup * find_contactgroup(char *); /* finds a contactgroup object */ +command * find_command(char *); /* finds a command object */ +service * find_service(char *,char *); /* finds a service object */ + + +/**** Object Traversal Functions ****/ +hostescalation *get_first_hostescalation_by_host(char *, void **); +hostescalation *get_next_hostescalation_by_host(char *,void **); +serviceescalation *get_first_serviceescalation_by_service(char *,char *, void **); +serviceescalation *get_next_serviceescalation_by_service(char *,char *,void **); +hostdependency *get_first_hostdependency_by_dependent_host(char *, void **); +hostdependency *get_next_hostdependency_by_dependent_host(char *, void **); +servicedependency *get_first_servicedependency_by_dependent_service(char *,char *, void **); +servicedependency *get_next_servicedependency_by_dependent_service(char *,char *,void **); + +#ifdef NSCORE +int add_object_to_objectlist(objectlist **,void *); +int free_objectlist(objectlist **); +#endif + + +/**** Object Query Functions ****/ +int is_host_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child of another host */ +int is_host_primary_immediate_child_of_host(host *,host *); /* checks if a host is an immediate child (and primary child) of another host */ +int is_host_immediate_parent_of_host(host *,host *); /* checks if a host is an immediate child of another host */ +int is_host_member_of_hostgroup(hostgroup *,host *); /* tests whether or not a host is a member of a specific hostgroup */ +int is_host_member_of_servicegroup(servicegroup *,host *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_service_member_of_servicegroup(servicegroup *,service *); /* tests whether or not a service is a member of a specific servicegroup */ +int is_contact_member_of_contactgroup(contactgroup *, contact *); /* tests whether or not a contact is a member of a specific contact group */ +int is_contact_for_hostgroup(hostgroup *,contact *); /* tests whether or not a contact is a member of a specific hostgroup */ +int is_contact_for_servicegroup(servicegroup *,contact *); /* tests whether or not a contact is a member of a specific servicegroup */ +int is_contact_for_host(host *,contact *); /* tests whether or not a contact is a contact member for a specific host */ +int is_escalated_contact_for_host(host *,contact *); /* checks whether or not a contact is an escalated contact for a specific host */ +int is_contact_for_service(service *,contact *); /* tests whether or not a contact is a contact member for a specific service */ +int is_escalated_contact_for_service(service *,contact *); /* checks whether or not a contact is an escalated contact for a specific service */ +int is_host_immediate_parent_of_host(host *,host *); /* tests whether or not a host is an immediate parent of another host */ + +int number_of_immediate_child_hosts(host *); /* counts the number of immediate child hosts for a particular host */ +int number_of_total_child_hosts(host *); /* counts the number of total child hosts for a particular host */ +int number_of_immediate_parent_hosts(host *); /* counts the number of immediate parents hosts for a particular host */ +int number_of_total_parent_hosts(host *); /* counts the number of total parents hosts for a particular host */ + +#ifdef NSCORE +int check_for_circular_host_path(host *,host *); /* checks if a circular path exists for a given host */ +int check_for_circular_servicedependency_path(servicedependency *,servicedependency *,int); /* checks if a circular dependency exists for a given service */ +int check_for_circular_hostdependency_path(hostdependency *,hostdependency *,int); /* checks if a circular dependency exists for a given host */ +#endif + + +/**** Object Cleanup Functions ****/ +int free_object_data(void); /* frees all allocated memory for the object definitions */ + + + + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/include/pnp.h b/include/pnp.h new file mode 100644 index 0000000..a37da06 --- /dev/null +++ b/include/pnp.h @@ -0,0 +1,126 @@ +/* #include "../include/global.h" */ + +/************************************* + * General Header Files + *************************************/ + +#ifdef HAVE_STDIO_H +#include +#endif + +#ifdef HAVE_ERRNO_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYSLOG_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#ifdef HAVE_SYS_STAT_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_DIRENT_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_TIME_H +#include +#endif + +#ifdef HAVE_PTHREAD_H +#include +#endif + +#ifdef HAVE_GETOPT_H +#include +#endif + +#ifdef HAVE_GRP_H +#include +#endif + +#ifdef HAVE_PWD_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif + +#ifdef HAVE_SYS_MMAN_H +#include +#endif + +/************************************* + Default defines + **************************************/ +extern int do_log(char*); + + +#define LOG(level, msg) (loglevel >= level || loglevel == -1) ? (do_log(msg)) : (0) + +#define TRUE 1 +#define FALSE 0 + +#define OK 0 +#define ERROR -2 + +#define MAX_FILENAME_LENGTH 256 +#define MAX_VARIABLE_LENGTH 256 +#define MAX_VALUE_LENGTH 256 +#define MAX_COMMANDLINE_LENGTH 512 + +#define MAX_BUFFER_SIZE 1024 +#define MAX_LOGMESSAGE_SIZE 768 + +#define CONFIG_OPT_COUNT 15 + +#define CONFIG_OPT_LOGTYPE 0 +#define CONFIG_OPT_LOGFILE 1 +#define CONFIG_OPT_LOGFILESIZE 2 +#define CONFIG_OPT_LOGLEVEL 3 +#define CONFIG_OPT_SCANDIR 4 +#define CONFIG_OPT_RUNCMD 5 +#define CONFIG_OPT_RUNCMD_ARG 6 +#define CONFIG_OPT_MAXTHREADS 7 +#define CONFIG_OPT_USER 8 +#define CONFIG_OPT_GROUP 9 +#define CONFIG_OPT_PIDFILE 10 +#define CONFIG_OPT_USELOAD 11 +#define CONFIG_OPT_LOAD 12 +#define CONFIG_OPT_SLEEPTIME 13 +#define CONFIG_OPT_IDENTMYSELF 14 + diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..4d4a951 --- /dev/null +++ b/install-sh @@ -0,0 +1,323 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2005-05-14.22 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit $?;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit $?;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + shift + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit 1 + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit 1; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit 0 +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/lib/Makefile.in b/lib/Makefile.in new file mode 100644 index 0000000..b103bc8 --- /dev/null +++ b/lib/Makefile.in @@ -0,0 +1,305 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +LOGDIR=@localstatedir@ +CFGDIR=@sysconfdir@ +BINDIR=@bindir@ +CGIDIR=@sbindir@ +LIBDIR=@libdir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +DATAROOTDIR=@datarootdir@ + +CP=@CP@ + +all html: + +clean: + +distclean: clean + -rm -f Makefile + +devclean: distclean + +install: + + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR) + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/controllers + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/helpers + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Image + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Session + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/config + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/core + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8 + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/views + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/views/pagination + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBDIR)/kohana/system/fonts + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/controllers/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/controllers/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/controllers/template.php $(DESTDIR)$(LIBDIR)/kohana/system/controllers/template.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/de_DE/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/de_DE/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/nl_NL/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/nl_NL/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/es_ES/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/es_ES/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/ru_RU/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/ru_RU/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/en_US/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/en_US/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/fr_FR/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/fr_FR/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/validation.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/core.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/core.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/orm.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/orm.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/image.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/session.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/database.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/event.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/errors.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/errors.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/i18n/it_IT/swift.php $(DESTDIR)$(LIBDIR)/kohana/system/i18n/it_IT/swift.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/remote.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/remote.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/url.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/url.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/feed.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/feed.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/expires.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/expires.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/text.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/text.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/email.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/email.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/download.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/download.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/format.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/format.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/form.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/form.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/arr.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/arr.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/html.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/html.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/valid.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/valid.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/date.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/date.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/file.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/file.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/request.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/request.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/cookie.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/cookie.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/security.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/security.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/num.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/num.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/helpers/inflector.php $(DESTDIR)$(LIBDIR)/kohana/system/helpers/inflector.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/ORM_Tree.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/ORM_Tree.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Encrypt.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Encrypt.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Database_Expression.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Database_Expression.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Event_Observer.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Event_Observer.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Event_Subject.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Event_Subject.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Cache.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Session.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database/Mssql.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database/Mssql.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database/Pdosqlite.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database/Pdosqlite.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database/Mysqli.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database/Mysqli.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database/Pgsql.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database/Pgsql.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database/Mysql.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database/Mysql.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Alpha.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Alpha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Math.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Math.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Word.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Word.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Riddle.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Riddle.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Basic.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Basic.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha/Black.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha/Black.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Session.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Image.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/Eaccelerator.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/Eaccelerator.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/Apc.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/Apc.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/Memcache.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/Memcache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/Xcache.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/Xcache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/File.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/File.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Cache/Sqlite.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Cache/Sqlite.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Image/GraphicsMagick.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Image/GraphicsMagick.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Image/GD.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Image/GD.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Image/ImageMagick.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Image/ImageMagick.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Session/Cookie.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Session/Cookie.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Session/Cache.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Session/Cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Session/Database.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Session/Database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/drivers/Database.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/drivers/Database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Image.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Validation.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Validation.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/ORM_Versioned.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/ORM_Versioned.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Controller.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Controller.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Model.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Model.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/View.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/View.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Router.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Router.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/ORM_Iterator.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/ORM_Iterator.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Profiler_Table.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Profiler_Table.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/URI.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/URI.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/ORM.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/ORM.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Calendar_Event.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Calendar_Event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Tagcloud.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Tagcloud.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Input.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Input.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/libraries/Database.php $(DESTDIR)$(LIBDIR)/kohana/system/libraries/Database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/locale.php $(DESTDIR)$(LIBDIR)/kohana/system/config/locale.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/routes.php $(DESTDIR)$(LIBDIR)/kohana/system/config/routes.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/pagination.php $(DESTDIR)$(LIBDIR)/kohana/system/config/pagination.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/sql_types.php $(DESTDIR)$(LIBDIR)/kohana/system/config/sql_types.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/captcha.php $(DESTDIR)$(LIBDIR)/kohana/system/config/captcha.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/email.php $(DESTDIR)$(LIBDIR)/kohana/system/config/email.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/image.php $(DESTDIR)$(LIBDIR)/kohana/system/config/image.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/cache_sqlite.php $(DESTDIR)$(LIBDIR)/kohana/system/config/cache_sqlite.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/cache_memcache.php $(DESTDIR)$(LIBDIR)/kohana/system/config/cache_memcache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/session.php $(DESTDIR)$(LIBDIR)/kohana/system/config/session.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/database.php $(DESTDIR)$(LIBDIR)/kohana/system/config/database.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/credit_cards.php $(DESTDIR)$(LIBDIR)/kohana/system/config/credit_cards.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/http.php $(DESTDIR)$(LIBDIR)/kohana/system/config/http.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/mimes.php $(DESTDIR)$(LIBDIR)/kohana/system/config/mimes.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/config/profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/view.php $(DESTDIR)$(LIBDIR)/kohana/system/config/view.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/cache.php $(DESTDIR)$(LIBDIR)/kohana/system/config/cache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/encryption.php $(DESTDIR)$(LIBDIR)/kohana/system/config/encryption.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/upload.php $(DESTDIR)$(LIBDIR)/kohana/system/config/upload.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/cookie.php $(DESTDIR)$(LIBDIR)/kohana/system/config/cookie.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/user_agents.php $(DESTDIR)$(LIBDIR)/kohana/system/config/user_agents.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/inflector.php $(DESTDIR)$(LIBDIR)/kohana/system/config/inflector.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/config/cache_xcache.php $(DESTDIR)$(LIBDIR)/kohana/system/config/cache_xcache.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/Event.php $(DESTDIR)$(LIBDIR)/kohana/system/core/Event.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/transliterate_to_ascii.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/transliterate_to_ascii.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/ucfirst.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/ucfirst.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/ord.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/ord.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strrpos.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strrpos.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strtolower.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strtolower.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/substr.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/substr.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/str_pad.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/str_pad.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strcspn.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strcspn.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/trim.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/trim.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/rtrim.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/rtrim.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strcasecmp.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strcasecmp.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strtoupper.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strtoupper.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/str_split.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/str_split.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strpos.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strpos.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/stristr.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/stristr.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/ucwords.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/ucwords.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/str_ireplace.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/str_ireplace.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strlen.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strlen.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/to_unicode.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/to_unicode.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/substr_replace.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/substr_replace.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/from_unicode.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/from_unicode.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strrev.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strrev.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/strspn.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/strspn.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8/ltrim.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8/ltrim.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/Benchmark.php $(DESTDIR)$(LIBDIR)/kohana/system/core/Benchmark.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/Bootstrap.php $(DESTDIR)$(LIBDIR)/kohana/system/core/Bootstrap.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/Kohana.php $(DESTDIR)$(LIBDIR)/kohana/system/core/Kohana.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/core/utf8.php $(DESTDIR)$(LIBDIR)/kohana/system/core/utf8.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_profiler_table.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_profiler_table.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana/template.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana/template.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_error_page.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_error_page.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_calendar.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_calendar.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/pagination/digg.php $(DESTDIR)$(LIBDIR)/kohana/system/views/pagination/digg.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/pagination/punbb.php $(DESTDIR)$(LIBDIR)/kohana/system/views/pagination/punbb.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/pagination/extended.php $(DESTDIR)$(LIBDIR)/kohana/system/views/pagination/extended.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/pagination/classic.php $(DESTDIR)$(LIBDIR)/kohana/system/views/pagination/classic.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_profiler_table.css $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_profiler_table.css + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_profiler.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_profiler.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_error_disabled.php $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_error_disabled.php + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/views/kohana_errors.css $(DESTDIR)$(LIBDIR)/kohana/system/views/kohana_errors.css + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/fonts/LICENSE $(DESTDIR)$(LIBDIR)/kohana/system/fonts/LICENSE + $(INSTALL) -m 644 $(INSTALL_OPTS) kohana/system/fonts/DejaVuSerif.ttf $(DESTDIR)$(LIBDIR)/kohana/system/fonts/DejaVuSerif.ttf diff --git a/lib/kohana/system/config/cache.php b/lib/kohana/system/config/cache.php new file mode 100644 index 0000000..ccd3da4 --- /dev/null +++ b/lib/kohana/system/config/cache.php @@ -0,0 +1,32 @@ + File cache is fast and reliable, but requires many filesystem lookups. + * > Database cache can be used to cache items remotely, but is slower. + * > Memcache is very high performance, but prevents cache tags from being used. + * + * params - Driver parameters, specific to each driver. + * + * lifetime - Default lifetime of caches in seconds. By default caches are stored for + * thirty minutes. Specific lifetime can also be set when creating a new cache. + * Setting this to 0 will never automatically delete caches. + * + * requests - Average number of cache requests that will processed before all expired + * caches are deleted. This is commonly referred to as "garbage collection". + * Setting this to 0 or a negative number will disable automatic garbage collection. + */ +$config['default'] = array +( + 'driver' => 'file', + 'params' => APPPATH.'cache', + 'lifetime' => 1800, + 'requests' => 1000 +); diff --git a/lib/kohana/system/config/cache_memcache.php b/lib/kohana/system/config/cache_memcache.php new file mode 100644 index 0000000..43d8f20 --- /dev/null +++ b/lib/kohana/system/config/cache_memcache.php @@ -0,0 +1,20 @@ + '127.0.0.1', + 'port' => 11211, + 'persistent' => FALSE, + ) +); + +/** + * Enable cache data compression. + */ +$config['compression'] = FALSE; diff --git a/lib/kohana/system/config/cache_sqlite.php b/lib/kohana/system/config/cache_sqlite.php new file mode 100644 index 0000000..818b893 --- /dev/null +++ b/lib/kohana/system/config/cache_sqlite.php @@ -0,0 +1,10 @@ + 'basic', + 'width' => 150, + 'height' => 50, + 'complexity' => 4, + 'background' => '', + 'fontpath' => SYSPATH.'fonts/', + 'fonts' => array('DejaVuSerif.ttf'), + 'promote' => FALSE, +); \ No newline at end of file diff --git a/lib/kohana/system/config/cookie.php b/lib/kohana/system/config/cookie.php new file mode 100644 index 0000000..b6ddfe4 --- /dev/null +++ b/lib/kohana/system/config/cookie.php @@ -0,0 +1,32 @@ + array + ( + 'length' => '13,14,15,16,17,18,19', + 'prefix' => '', + 'luhn' => TRUE + ), + 'american express' => array + ( + 'length' => '15', + 'prefix' => '3[47]', + 'luhn' => TRUE + ), + 'diners club' => array + ( + 'length' => '14,16', + 'prefix' => '36|55|30[0-5]', + 'luhn' => TRUE + ), + 'discover' => array + ( + 'length' => '16', + 'prefix' => '6(?:5|011)', + 'luhn' => TRUE, + ), + 'jcb' => array + ( + 'length' => '15,16', + 'prefix' => '3|1800|2131', + 'luhn' => TRUE + ), + 'maestro' => array + ( + 'length' => '16,18', + 'prefix' => '50(?:20|38)|6(?:304|759)', + 'luhn' => TRUE + ), + 'mastercard' => array + ( + 'length' => '16', + 'prefix' => '5[1-5]', + 'luhn' => TRUE + ), + 'visa' => array + ( + 'length' => '13,16', + 'prefix' => '4', + 'luhn' => TRUE + ), +); \ No newline at end of file diff --git a/lib/kohana/system/config/database.php b/lib/kohana/system/config/database.php new file mode 100644 index 0000000..6519156 --- /dev/null +++ b/lib/kohana/system/config/database.php @@ -0,0 +1,45 @@ + 'mysql://dbuser:secret@localhost/kohana' + * character_set - Database character set + * table_prefix - Database table prefix + * object - Enable or disable object results + * cache - Enable or disable query caching + * escape - Enable automatic query builder escaping + */ +$config['default'] = array +( + 'benchmark' => TRUE, + 'persistent' => FALSE, + 'connection' => array + ( + 'type' => 'mysql', + 'user' => 'dbuser', + 'pass' => 'p@ssw0rd', + 'host' => 'localhost', + 'port' => FALSE, + 'socket' => FALSE, + 'database' => 'kohana' + ), + 'character_set' => 'utf8', + 'table_prefix' => '', + 'object' => TRUE, + 'cache' => FALSE, + 'escape' => TRUE +); \ No newline at end of file diff --git a/lib/kohana/system/config/email.php b/lib/kohana/system/config/email.php new file mode 100644 index 0000000..c768367 --- /dev/null +++ b/lib/kohana/system/config/email.php @@ -0,0 +1,22 @@ + 'K0H@NA+PHP_7hE-SW!FtFraM3w0R|<', + 'mode' => MCRYPT_MODE_NOFB, + 'cipher' => MCRYPT_RIJNDAEL_128 +); diff --git a/lib/kohana/system/config/http.php b/lib/kohana/system/config/http.php new file mode 100644 index 0000000..3c4a86a --- /dev/null +++ b/lib/kohana/system/config/http.php @@ -0,0 +1,19 @@ + 'children', + 'clothes' => 'clothing', + 'man' => 'men', + 'movie' => 'movies', + 'person' => 'people', + 'woman' => 'women', + 'mouse' => 'mice', + 'goose' => 'geese', + 'ox' => 'oxen', + 'leaf' => 'leaves', + 'course' => 'courses', + 'size' => 'sizes', +); diff --git a/lib/kohana/system/config/locale.php b/lib/kohana/system/config/locale.php new file mode 100644 index 0000000..3a26882 --- /dev/null +++ b/lib/kohana/system/config/locale.php @@ -0,0 +1,16 @@ + array('text/h323'), + '7z' => array('application/x-7z-compressed'), + 'abw' => array('application/x-abiword'), + 'acx' => array('application/internet-property-stream'), + 'ai' => array('application/postscript'), + 'aif' => array('audio/x-aiff'), + 'aifc' => array('audio/x-aiff'), + 'aiff' => array('audio/x-aiff'), + 'asf' => array('video/x-ms-asf'), + 'asr' => array('video/x-ms-asf'), + 'asx' => array('video/x-ms-asf'), + 'atom' => array('application/atom+xml'), + 'avi' => array('video/avi', 'video/msvideo', 'video/x-msvideo'), + 'bin' => array('application/octet-stream','application/macbinary'), + 'bmp' => array('image/bmp'), + 'c' => array('text/x-csrc'), + 'c++' => array('text/x-c++src'), + 'cab' => array('application/x-cab'), + 'cc' => array('text/x-c++src'), + 'cda' => array('application/x-cdf'), + 'class' => array('application/octet-stream'), + 'cpp' => array('text/x-c++src'), + 'cpt' => array('application/mac-compactpro'), + 'csh' => array('text/x-csh'), + 'css' => array('text/css'), + 'csv' => array('text/x-comma-separated-values', 'application/vnd.ms-excel', 'text/comma-separated-values', 'text/csv'), + 'dbk' => array('application/docbook+xml'), + 'dcr' => array('application/x-director'), + 'deb' => array('application/x-debian-package'), + 'diff' => array('text/x-diff'), + 'dir' => array('application/x-director'), + 'divx' => array('video/divx'), + 'dll' => array('application/octet-stream', 'application/x-msdos-program'), + 'dmg' => array('application/x-apple-diskimage'), + 'dms' => array('application/octet-stream'), + 'doc' => array('application/msword'), + 'dvi' => array('application/x-dvi'), + 'dxr' => array('application/x-director'), + 'eml' => array('message/rfc822'), + 'eps' => array('application/postscript'), + 'evy' => array('application/envoy'), + 'exe' => array('application/x-msdos-program', 'application/octet-stream'), + 'fla' => array('application/octet-stream'), + 'flac' => array('application/x-flac'), + 'flc' => array('video/flc'), + 'fli' => array('video/fli'), + 'flv' => array('video/x-flv'), + 'gif' => array('image/gif'), + 'gtar' => array('application/x-gtar'), + 'gz' => array('application/x-gzip'), + 'h' => array('text/x-chdr'), + 'h++' => array('text/x-c++hdr'), + 'hh' => array('text/x-c++hdr'), + 'hpp' => array('text/x-c++hdr'), + 'hqx' => array('application/mac-binhex40'), + 'hs' => array('text/x-haskell'), + 'htm' => array('text/html'), + 'html' => array('text/html'), + 'ico' => array('image/x-icon'), + 'ics' => array('text/calendar'), + 'iii' => array('application/x-iphone'), + 'ins' => array('application/x-internet-signup'), + 'iso' => array('application/x-iso9660-image'), + 'isp' => array('application/x-internet-signup'), + 'jar' => array('application/java-archive'), + 'java' => array('application/x-java-applet'), + 'jpe' => array('image/jpeg', 'image/pjpeg'), + 'jpeg' => array('image/jpeg', 'image/pjpeg'), + 'jpg' => array('image/jpeg', 'image/pjpeg'), + 'js' => array('application/x-javascript'), + 'json' => array('application/json'), + 'latex' => array('application/x-latex'), + 'lha' => array('application/octet-stream'), + 'log' => array('text/plain', 'text/x-log'), + 'lzh' => array('application/octet-stream'), + 'm4a' => array('audio/mpeg'), + 'm4p' => array('video/mp4v-es'), + 'm4v' => array('video/mp4'), + 'man' => array('application/x-troff-man'), + 'mdb' => array('application/x-msaccess'), + 'midi' => array('audio/midi'), + 'mid' => array('audio/midi'), + 'mif' => array('application/vnd.mif'), + 'mka' => array('audio/x-matroska'), + 'mkv' => array('video/x-matroska'), + 'mov' => array('video/quicktime'), + 'movie' => array('video/x-sgi-movie'), + 'mp2' => array('audio/mpeg'), + 'mp3' => array('audio/mpeg'), + 'mp4' => array('application/mp4','audio/mp4','video/mp4'), + 'mpa' => array('video/mpeg'), + 'mpe' => array('video/mpeg'), + 'mpeg' => array('video/mpeg'), + 'mpg' => array('video/mpeg'), + 'mpg4' => array('video/mp4'), + 'mpga' => array('audio/mpeg'), + 'mpp' => array('application/vnd.ms-project'), + 'mpv' => array('video/x-matroska'), + 'mpv2' => array('video/mpeg'), + 'ms' => array('application/x-troff-ms'), + 'msg' => array('application/msoutlook','application/x-msg'), + 'msi' => array('application/x-msi'), + 'nws' => array('message/rfc822'), + 'oda' => array('application/oda'), + 'odb' => array('application/vnd.oasis.opendocument.database'), + 'odc' => array('application/vnd.oasis.opendocument.chart'), + 'odf' => array('application/vnd.oasis.opendocument.forumla'), + 'odg' => array('application/vnd.oasis.opendocument.graphics'), + 'odi' => array('application/vnd.oasis.opendocument.image'), + 'odm' => array('application/vnd.oasis.opendocument.text-master'), + 'odp' => array('application/vnd.oasis.opendocument.presentation'), + 'ods' => array('application/vnd.oasis.opendocument.spreadsheet'), + 'odt' => array('application/vnd.oasis.opendocument.text'), + 'oga' => array('audio/ogg'), + 'ogg' => array('application/ogg'), + 'ogv' => array('video/ogg'), + 'otg' => array('application/vnd.oasis.opendocument.graphics-template'), + 'oth' => array('application/vnd.oasis.opendocument.web'), + 'otp' => array('application/vnd.oasis.opendocument.presentation-template'), + 'ots' => array('application/vnd.oasis.opendocument.spreadsheet-template'), + 'ott' => array('application/vnd.oasis.opendocument.template'), + 'p' => array('text/x-pascal'), + 'pas' => array('text/x-pascal'), + 'patch' => array('text/x-diff'), + 'pbm' => array('image/x-portable-bitmap'), + 'pdf' => array('application/pdf', 'application/x-download'), + 'php' => array('application/x-httpd-php'), + 'php3' => array('application/x-httpd-php'), + 'php4' => array('application/x-httpd-php'), + 'php5' => array('application/x-httpd-php'), + 'phps' => array('application/x-httpd-php-source'), + 'phtml' => array('application/x-httpd-php'), + 'pl' => array('text/x-perl'), + 'pm' => array('text/x-perl'), + 'png' => array('image/png', 'image/x-png'), + 'po' => array('text/x-gettext-translation'), + 'pot' => array('application/vnd.ms-powerpoint'), + 'pps' => array('application/vnd.ms-powerpoint'), + 'ppt' => array('application/powerpoint'), + 'ps' => array('application/postscript'), + 'psd' => array('application/x-photoshop', 'image/x-photoshop'), + 'pub' => array('application/x-mspublisher'), + 'py' => array('text/x-python'), + 'qt' => array('video/quicktime'), + 'ra' => array('audio/x-realaudio'), + 'ram' => array('audio/x-realaudio', 'audio/x-pn-realaudio'), + 'rar' => array('application/rar'), + 'rgb' => array('image/x-rgb'), + 'rm' => array('audio/x-pn-realaudio'), + 'rpm' => array('audio/x-pn-realaudio-plugin', 'application/x-redhat-package-manager'), + 'rss' => array('application/rss+xml'), + 'rtf' => array('text/rtf'), + 'rtx' => array('text/richtext'), + 'rv' => array('video/vnd.rn-realvideo'), + 'sea' => array('application/octet-stream'), + 'sh' => array('text/x-sh'), + 'shtml' => array('text/html'), + 'sit' => array('application/x-stuffit'), + 'smi' => array('application/smil'), + 'smil' => array('application/smil'), + 'so' => array('application/octet-stream'), + 'src' => array('application/x-wais-source'), + 'svg' => array('image/svg+xml'), + 'swf' => array('application/x-shockwave-flash'), + 't' => array('application/x-troff'), + 'tar' => array('application/x-tar'), + 'tcl' => array('text/x-tcl'), + 'tex' => array('application/x-tex'), + 'text' => array('text/plain'), + 'texti' => array('application/x-texinfo'), + 'textinfo' => array('application/x-texinfo'), + 'tgz' => array('application/x-tar'), + 'tif' => array('image/tiff'), + 'tiff' => array('image/tiff'), + 'torrent' => array('application/x-bittorrent'), + 'tr' => array('application/x-troff'), + 'tsv' => array('text/tab-separated-values'), + 'txt' => array('text/plain'), + 'wav' => array('audio/x-wav'), + 'wax' => array('audio/x-ms-wax'), + 'wbxml' => array('application/wbxml'), + 'wm' => array('video/x-ms-wm'), + 'wma' => array('audio/x-ms-wma'), + 'wmd' => array('application/x-ms-wmd'), + 'wmlc' => array('application/wmlc'), + 'wmv' => array('video/x-ms-wmv', 'application/octet-stream'), + 'wmx' => array('video/x-ms-wmx'), + 'wmz' => array('application/x-ms-wmz'), + 'word' => array('application/msword', 'application/octet-stream'), + 'wp5' => array('application/wordperfect5.1'), + 'wpd' => array('application/vnd.wordperfect'), + 'wvx' => array('video/x-ms-wvx'), + 'xbm' => array('image/x-xbitmap'), + 'xcf' => array('image/xcf'), + 'xhtml' => array('application/xhtml+xml'), + 'xht' => array('application/xhtml+xml'), + 'xl' => array('application/excel', 'application/vnd.ms-excel'), + 'xla' => array('application/excel', 'application/vnd.ms-excel'), + 'xlc' => array('application/excel', 'application/vnd.ms-excel'), + 'xlm' => array('application/excel', 'application/vnd.ms-excel'), + 'xls' => array('application/excel', 'application/vnd.ms-excel'), + 'xlt' => array('application/excel', 'application/vnd.ms-excel'), + 'xml' => array('text/xml'), + 'xof' => array('x-world/x-vrml'), + 'xpm' => array('image/x-xpixmap'), + 'xsl' => array('text/xml'), + 'xvid' => array('video/x-xvid'), + 'xwd' => array('image/x-xwindowdump'), + 'z' => array('application/x-compress'), + 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed') +); diff --git a/lib/kohana/system/config/pagination.php b/lib/kohana/system/config/pagination.php new file mode 100644 index 0000000..808fc31 --- /dev/null +++ b/lib/kohana/system/config/pagination.php @@ -0,0 +1,25 @@ + 'pagination', + 'style' => 'classic', + 'uri_segment' => 3, + 'query_string' => '', + 'items_per_page' => 20, + 'auto_hide' => FALSE, +); diff --git a/lib/kohana/system/config/profiler.php b/lib/kohana/system/config/profiler.php new file mode 100644 index 0000000..98ab5a4 --- /dev/null +++ b/lib/kohana/system/config/profiler.php @@ -0,0 +1,8 @@ + array('type' => 'int', 'max' => 127), + 'smallint' => array('type' => 'int', 'max' => 32767), + 'mediumint' => array('type' => 'int', 'max' => 8388607), + 'int' => array('type' => 'int', 'max' => 2147483647), + 'integer' => array('type' => 'int', 'max' => 2147483647), + 'bigint' => array('type' => 'int', 'max' => 9223372036854775807), + 'float' => array('type' => 'float'), + 'float unsigned' => array('type' => 'float', 'min' => 0), + 'boolean' => array('type' => 'boolean'), + 'time' => array('type' => 'string', 'format' => '00:00:00'), + 'time with time zone' => array('type' => 'string'), + 'date' => array('type' => 'string', 'format' => '0000-00-00'), + 'year' => array('type' => 'string', 'format' => '0000'), + 'datetime' => array('type' => 'string', 'format' => '0000-00-00 00:00:00'), + 'timestamp with time zone' => array('type' => 'string'), + 'char' => array('type' => 'string', 'exact' => TRUE), + 'binary' => array('type' => 'string', 'binary' => TRUE, 'exact' => TRUE), + 'varchar' => array('type' => 'string'), + 'varbinary' => array('type' => 'string', 'binary' => TRUE), + 'blob' => array('type' => 'string', 'binary' => TRUE), + 'text' => array('type' => 'string') +); + +// DOUBLE +$config['double'] = $config['double precision'] = $config['decimal'] = $config['real'] = $config['numeric'] = $config['float']; +$config['double unsigned'] = $config['float unsigned']; + +// BIT +$config['bit'] = $config['boolean']; + +// TIMESTAMP +$config['timestamp'] = $config['timestamp without time zone'] = $config['datetime']; + +// ENUM +$config['enum'] = $config['set'] = $config['varchar']; + +// TEXT +$config['tinytext'] = $config['mediumtext'] = $config['longtext'] = $config['text']; + +// BLOB +$config['tsvector'] = $config['tinyblob'] = $config['mediumblob'] = $config['longblob'] = $config['clob'] = $config['bytea'] = $config['blob']; + +// CHARACTER +$config['character'] = $config['char']; +$config['character varying'] = $config['varchar']; + +// TIME +$config['time without time zone'] = $config['time']; diff --git a/lib/kohana/system/config/upload.php b/lib/kohana/system/config/upload.php new file mode 100644 index 0000000..df26a2d --- /dev/null +++ b/lib/kohana/system/config/upload.php @@ -0,0 +1,17 @@ + 'Windows Vista', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 4.0' => 'Windows NT', + 'winnt4.0' => 'Windows NT', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows' => 'Unknown Windows OS', + 'os x' => 'Mac OS X', + 'intel mac' => 'Intel Mac', + 'ppc mac' => 'PowerPC Mac', + 'powerpc' => 'PowerPC', + 'ppc' => 'PowerPC', + 'cygwin' => 'Cygwin', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'openvms' => 'OpenVMS', + 'sunos' => 'Sun Solaris', + 'amiga' => 'Amiga', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'freebsd' => 'FreeBSD', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'os/2' => 'OS/2', + 'warp' => 'OS/2', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'hurd' => 'GNU/Hurd', + 'unix' => 'Unknown Unix OS', +); + +// The order of this array should NOT be changed. Many browsers return +// multiple browser types so we want to identify the sub-type first. +$config['browser'] = array +( + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Chrome' => 'Chrome', + 'Safari' => 'Safari', + 'Konqueror' => 'Konqueror', + 'Epiphany' => 'Epiphany', + 'Galeon' => 'Galeon', + 'Mozilla' => 'Mozilla', + 'icab' => 'iCab', + 'lynx' => 'Lynx', + 'links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse', +); + +$config['mobile'] = array +( + 'mobileexplorer' => 'Mobile Explorer', + 'openwave' => 'Open Wave', + 'opera mini' => 'Opera Mini', + 'operamini' => 'Opera Mini', + 'elaine' => 'Palm', + 'palmsource' => 'Palm', + 'digital paths' => 'Palm', + 'avantgo' => 'Avantgo', + 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', + 'nokia' => 'Nokia', + 'ericsson' => 'Ericsson', + 'blackBerry' => 'BlackBerry', + 'motorola' => 'Motorola', + 'iphone' => 'iPhone', + 'android' => 'Android', +); + +// There are hundreds of bots but these are the most common. +$config['robot'] = array +( + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'askjeeves' => 'AskJeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos', +); \ No newline at end of file diff --git a/lib/kohana/system/config/view.php b/lib/kohana/system/config/view.php new file mode 100644 index 0000000..6bed22e --- /dev/null +++ b/lib/kohana/system/config/view.php @@ -0,0 +1,17 @@ +" /> + * + * $Id: captcha.php 3769 2008-12-15 00:48:56Z zombor $ + * + * @package Captcha + * @author Kohana Team + * @copyright (c) 2007-2008 Kohana Team + * @license http://kohanaphp.com/license.html + */ +class Captcha_Controller extends Controller { + + public function __call($method, $args) + { + // Output the Captcha challenge resource (no html) + // Pull the config group name from the URL + Captcha::factory($this->uri->segment(2))->render(FALSE); + } + +} // End Captcha_Controller \ No newline at end of file diff --git a/lib/kohana/system/controllers/template.php b/lib/kohana/system/controllers/template.php new file mode 100644 index 0000000..34d1a22 --- /dev/null +++ b/lib/kohana/system/controllers/template.php @@ -0,0 +1,54 @@ +template = new View($this->template); + + if ($this->auto_render == TRUE) + { + // Render the template immediately after the controller method + Event::add('system.post_controller', array($this, '_render')); + } + } + + /** + * Render the loaded template. + */ + public function _render() + { + if ($this->auto_render == TRUE) + { + // Render the template when the class is destroyed + $this->template->render(TRUE); + } + } + +} // End Template_Controller \ No newline at end of file diff --git a/lib/kohana/system/core/Benchmark.php b/lib/kohana/system/core/Benchmark.php new file mode 100644 index 0000000..ce230f1 --- /dev/null +++ b/lib/kohana/system/core/Benchmark.php @@ -0,0 +1,125 @@ + microtime(TRUE), + 'stop' => FALSE, + 'memory_start' => self::memory_usage(), + 'memory_stop' => FALSE + ); + + array_unshift(self::$marks[$name], $mark); + } + + /** + * Set a benchmark stop point. + * + * @param string benchmark name + * @return void + */ + public static function stop($name) + { + if (isset(self::$marks[$name]) AND self::$marks[$name][0]['stop'] === FALSE) + { + self::$marks[$name][0]['stop'] = microtime(TRUE); + self::$marks[$name][0]['memory_stop'] = self::memory_usage(); + } + } + + /** + * Get the elapsed time between a start and stop. + * + * @param string benchmark name, TRUE for all + * @param integer number of decimal places to count to + * @return array + */ + public static function get($name, $decimals = 4) + { + if ($name === TRUE) + { + $times = array(); + $names = array_keys(self::$marks); + + foreach ($names as $name) + { + // Get each mark recursively + $times[$name] = self::get($name, $decimals); + } + + // Return the array + return $times; + } + + if ( ! isset(self::$marks[$name])) + return FALSE; + + if (self::$marks[$name][0]['stop'] === FALSE) + { + // Stop the benchmark to prevent mis-matched results + self::stop($name); + } + + // Return a string version of the time between the start and stop points + // Properly reading a float requires using number_format or sprintf + $time = $memory = 0; + for ($i = 0; $i < count(self::$marks[$name]); $i++) + { + $time += self::$marks[$name][$i]['stop'] - self::$marks[$name][$i]['start']; + $memory += self::$marks[$name][$i]['memory_stop'] - self::$marks[$name][$i]['memory_start']; + } + + return array + ( + 'time' => number_format($time, $decimals), + 'memory' => $memory, + 'count' => count(self::$marks[$name]) + ); + } + + /** + * Returns the current memory usage. This is only possible if the + * memory_get_usage function is supported in PHP. + * + * @return integer + */ + private static function memory_usage() + { + static $func; + + if ($func === NULL) + { + // Test if memory usage can be seen + $func = function_exists('memory_get_usage'); + } + + return $func ? memory_get_usage() : 0; + } + +} // End Benchmark diff --git a/lib/kohana/system/core/Bootstrap.php b/lib/kohana/system/core/Bootstrap.php new file mode 100644 index 0000000..1334190 --- /dev/null +++ b/lib/kohana/system/core/Bootstrap.php @@ -0,0 +1,58 @@ + $event_callback) + { + if ($callback === $event_callback) + { + unset(self::$events[$name][$i]); + } + } + } + } + + /** + * Execute all of the callbacks attached to an event. + * + * @param string event name + * @param array data can be processed as Event::$data by the callbacks + * @return void + */ + public static function run($name, & $data = NULL) + { + if ( ! empty(self::$events[$name])) + { + // So callbacks can access Event::$data + self::$data =& $data; + $callbacks = self::get($name); + + foreach ($callbacks as $callback) + { + call_user_func($callback); + } + + // Do this to prevent data from getting 'stuck' + $clear_data = ''; + self::$data =& $clear_data; + } + + // The event has been run! + self::$has_run[$name] = $name; + } + + /** + * Check if a given event has been run. + * + * @param string event name + * @return boolean + */ + public static function has_run($name) + { + return isset(self::$has_run[$name]); + } + +} // End Event \ No newline at end of file diff --git a/lib/kohana/system/core/Kohana.php b/lib/kohana/system/core/Kohana.php new file mode 100644 index 0000000..c79e30b --- /dev/null +++ b/lib/kohana/system/core/Kohana.php @@ -0,0 +1,1790 @@ + 1, + 'alert' => 2, + 'info' => 3, + 'debug' => 4, + ); + + // Internal caches and write status + private static $internal_cache = array(); + private static $write_cache; + private static $internal_cache_path; + private static $internal_cache_key; + private static $internal_cache_encrypt; + + /** + * Sets up the PHP environment. Adds error/exception handling, output + * buffering, and adds an auto-loading method for loading classes. + * + * This method is run immediately when this file is loaded, and is + * benchmarked as environment_setup. + * + * For security, this function also destroys the $_REQUEST global variable. + * Using the proper global (GET, POST, COOKIE, etc) is inherently more secure. + * The recommended way to fetch a global variable is using the Input library. + * @see http://www.php.net/globals + * + * @return void + */ + public static function setup() + { + static $run; + + // This function can only be run once + if ($run === TRUE) + return; + + // Start the environment setup benchmark + Benchmark::start(SYSTEM_BENCHMARK.'_environment_setup'); + + // Define Kohana error constant + define('E_KOHANA', 42); + + // Define 404 error constant + define('E_PAGE_NOT_FOUND', 43); + + // Define database error constant + define('E_DATABASE_ERROR', 44); + + if (self::$cache_lifetime = self::config('core.internal_cache')) + { + // Are we using encryption for caches? + self::$internal_cache_encrypt = self::config('core.internal_cache_encrypt'); + + if(self::$internal_cache_encrypt===TRUE) + { + self::$internal_cache_key = self::config('core.internal_cache_key'); + + // Be sure the key is of acceptable length for the mcrypt algorithm used + self::$internal_cache_key = substr(self::$internal_cache_key, 0, 24); + } + + // Set the directory to be used for the internal cache + if ( ! self::$internal_cache_path = self::config('core.internal_cache_path')) + { + self::$internal_cache_path = APPPATH.'cache/'; + } + + // Load cached configuration and language files + self::$internal_cache['configuration'] = self::cache('configuration', self::$cache_lifetime); + self::$internal_cache['language'] = self::cache('language', self::$cache_lifetime); + + // Load cached file paths + self::$internal_cache['find_file_paths'] = self::cache('find_file_paths', self::$cache_lifetime); + + // Enable cache saving + Event::add('system.shutdown', array(__CLASS__, 'internal_cache_save')); + } + + // Disable notices and "strict" errors + $ER = error_reporting(~E_NOTICE & ~E_STRICT); + + // Set the user agent + self::$user_agent = ( ! empty($_SERVER['HTTP_USER_AGENT']) ? trim($_SERVER['HTTP_USER_AGENT']) : ''); + + if (function_exists('date_default_timezone_set')) + { + $timezone = self::config('locale.timezone'); + + // Set default timezone, due to increased validation of date settings + // which cause massive amounts of E_NOTICEs to be generated in PHP 5.2+ + date_default_timezone_set(empty($timezone) ? date_default_timezone_get() : $timezone); + } + + // Restore error reporting + error_reporting($ER); + + // Start output buffering + ob_start(array(__CLASS__, 'output_buffer')); + + // Save buffering level + self::$buffer_level = ob_get_level(); + + // Set autoloader + spl_autoload_register(array('Kohana', 'auto_load')); + + // Set error handler + set_error_handler(array('Kohana', 'exception_handler')); + + // Set exception handler + set_exception_handler(array('Kohana', 'exception_handler')); + + // Send default text/html UTF-8 header + header('Content-Type: text/html; charset=UTF-8'); + + // Load locales + $locales = self::config('locale.language'); + + // Make first locale UTF-8 + $locales[0] .= '.UTF-8'; + + // Set locale information + self::$locale = setlocale(LC_ALL, $locales); + + if (self::$configuration['core']['log_threshold'] > 0) + { + // Set the log directory + self::log_directory(self::$configuration['core']['log_directory']); + + // Enable log writing at shutdown + register_shutdown_function(array(__CLASS__, 'log_save')); + } + + // Enable Kohana routing + Event::add('system.routing', array('Router', 'find_uri')); + Event::add('system.routing', array('Router', 'setup')); + + // Enable Kohana controller initialization + Event::add('system.execute', array('Kohana', 'instance')); + + // Enable Kohana 404 pages + Event::add('system.404', array('Kohana', 'show_404')); + + // Enable Kohana output handling + Event::add('system.shutdown', array('Kohana', 'shutdown')); + + if (self::config('core.enable_hooks') === TRUE) + { + // Find all the hook files + $hooks = self::list_files('hooks', TRUE); + + foreach ($hooks as $file) + { + // Load the hook + include $file; + } + } + + // Setup is complete, prevent it from being run again + $run = TRUE; + + // Stop the environment setup routine + Benchmark::stop(SYSTEM_BENCHMARK.'_environment_setup'); + } + + /** + * Loads the controller and initializes it. Runs the pre_controller, + * post_controller_constructor, and post_controller events. Triggers + * a system.404 event when the route cannot be mapped to a controller. + * + * This method is benchmarked as controller_setup and controller_execution. + * + * @return object instance of controller + */ + public static function & instance() + { + if (self::$instance === NULL) + { + Benchmark::start(SYSTEM_BENCHMARK.'_controller_setup'); + + // Include the Controller file + require Router::$controller_path; + + try + { + // Start validation of the controller + $class = new ReflectionClass(ucfirst(Router::$controller).'_Controller'); + } + catch (ReflectionException $e) + { + // Controller does not exist + Event::run('system.404'); + } + + if ($class->isAbstract() OR (IN_PRODUCTION AND $class->getConstant('ALLOW_PRODUCTION') == FALSE)) + { + // Controller is not allowed to run in production + Event::run('system.404'); + } + + // Run system.pre_controller + Event::run('system.pre_controller'); + + // Create a new controller instance + $controller = $class->newInstance(); + + // Controller constructor has been executed + Event::run('system.post_controller_constructor'); + + try + { + // Load the controller method + $method = $class->getMethod(Router::$method); + + // Method exists + if (Router::$method[0] === '_') + { + // Do not allow access to hidden methods + Event::run('system.404'); + } + + if ($method->isProtected() or $method->isPrivate()) + { + // Do not attempt to invoke protected methods + throw new ReflectionException('protected controller method'); + } + + // Default arguments + $arguments = Router::$arguments; + } + catch (ReflectionException $e) + { + // Use __call instead + $method = $class->getMethod('__call'); + + // Use arguments in __call format + $arguments = array(Router::$method, Router::$arguments); + } + + // Stop the controller setup benchmark + Benchmark::stop(SYSTEM_BENCHMARK.'_controller_setup'); + + // Start the controller execution benchmark + Benchmark::start(SYSTEM_BENCHMARK.'_controller_execution'); + + // Execute the controller method + $method->invokeArgs($controller, $arguments); + + // Controller method has been executed + Event::run('system.post_controller'); + + // Stop the controller execution benchmark + Benchmark::stop(SYSTEM_BENCHMARK.'_controller_execution'); + } + + return self::$instance; + } + + /** + * Get all include paths. APPPATH is the first path, followed by module + * paths in the order they are configured, follow by the SYSPATH. + * + * @param boolean re-process the include paths + * @return array + */ + public static function include_paths($process = FALSE) + { + if ($process === TRUE) + { + // Add APPPATH as the first path + self::$include_paths = array(APPPATH); + + foreach (self::$configuration['core']['modules'] as $path) + { + if ($path = str_replace('\\', '/', realpath($path))) + { + // Add a valid path + self::$include_paths[] = $path.'/'; + } + } + + // Add SYSPATH as the last path + self::$include_paths[] = SYSPATH; + } + + return self::$include_paths; + } + + /** + * Get a config item or group. + * + * @param string item name + * @param boolean force a forward slash (/) at the end of the item + * @param boolean is the item required? + * @return mixed + */ + public static function config($key, $slash = FALSE, $required = TRUE) + { + if (self::$configuration === NULL) + { + // Load core configuration + self::$configuration['core'] = self::config_load('core'); + + // Re-parse the include paths + self::include_paths(TRUE); + } + + // Get the group name from the key + $group = explode('.', $key, 2); + $group = $group[0]; + + if ( ! isset(self::$configuration[$group])) + { + // Load the configuration group + self::$configuration[$group] = self::config_load($group, $required); + } + + // Get the value of the key string + $value = self::key_string(self::$configuration, $key); + + if ($slash === TRUE AND is_string($value) AND $value !== '') + { + // Force the value to end with "/" + $value = rtrim($value, '/').'/'; + } + + return $value; + } + + /** + * Sets a configuration item, if allowed. + * + * @param string config key string + * @param string config value + * @return boolean + */ + public static function config_set($key, $value) + { + // Do this to make sure that the config array is already loaded + self::config($key); + + if (substr($key, 0, 7) === 'routes.') + { + // Routes cannot contain sub keys due to possible dots in regex + $keys = explode('.', $key, 2); + } + else + { + // Convert dot-noted key string to an array + $keys = explode('.', $key); + } + + // Used for recursion + $conf =& self::$configuration; + $last = count($keys) - 1; + + foreach ($keys as $i => $k) + { + if ($i === $last) + { + $conf[$k] = $value; + } + else + { + $conf =& $conf[$k]; + } + } + + if ($key === 'core.modules') + { + // Reprocess the include paths + self::include_paths(TRUE); + } + + return TRUE; + } + + /** + * Load a config file. + * + * @param string config filename, without extension + * @param boolean is the file required? + * @return array + */ + public static function config_load($name, $required = TRUE) + { + if ($name === 'core') + { + // Load the application configuration file + require APPPATH.'config/config'.EXT; + + if ( ! isset($config['site_domain'])) + { + // Invalid config file + die('Your Kohana application configuration file is not valid.'); + } + + return $config; + } + + if (isset(self::$internal_cache['configuration'][$name])) + return self::$internal_cache['configuration'][$name]; + + // Load matching configs + $configuration = array(); + + if ($files = self::find_file('config', $name, $required)) + { + foreach ($files as $file) + { + require $file; + + if (isset($config) AND is_array($config)) + { + // Merge in configuration + $configuration = array_merge($configuration, $config); + } + } + } + + if ( ! isset(self::$write_cache['configuration'])) + { + // Cache has changed + self::$write_cache['configuration'] = TRUE; + } + + return self::$internal_cache['configuration'][$name] = $configuration; + } + + /** + * Clears a config group from the cached configuration. + * + * @param string config group + * @return void + */ + public static function config_clear($group) + { + // Remove the group from config + unset(self::$configuration[$group], self::$internal_cache['configuration'][$group]); + + if ( ! isset(self::$write_cache['configuration'])) + { + // Cache has changed + self::$write_cache['configuration'] = TRUE; + } + } + + /** + * Add a new message to the log. + * + * @param string type of message + * @param string message text + * @return void + */ + public static function log($type, $message) + { + if (self::$log_levels[$type] <= self::$configuration['core']['log_threshold']) + { + $message = array(date('Y-m-d H:i:s P'), $type, $message); + + // Run the system.log event + Event::run('system.log', $message); + + self::$log[] = $message; + } + } + + /** + * Save all currently logged messages. + * + * @return void + */ + public static function log_save() + { + if (empty(self::$log) OR self::$configuration['core']['log_threshold'] < 1) + return; + + // Filename of the log + $filename = self::log_directory().date('Y-m-d').'.log'.EXT; + + if ( ! is_file($filename)) + { + // Write the SYSPATH checking header + file_put_contents($filename, + ''.PHP_EOL.PHP_EOL); + + // Prevent external writes + chmod($filename, 0644); + } + + // Messages to write + $messages = array(); + + do + { + // Load the next mess + list ($date, $type, $text) = array_shift(self::$log); + + // Add a new message line + $messages[] = $date.' --- '.$type.': '.$text; + } + while ( ! empty(self::$log)); + + // Write messages to log file + file_put_contents($filename, implode(PHP_EOL, $messages).PHP_EOL, FILE_APPEND); + } + + /** + * Get or set the logging directory. + * + * @param string new log directory + * @return string + */ + public static function log_directory($dir = NULL) + { + static $directory; + + if ( ! empty($dir)) + { + // Get the directory path + $dir = realpath($dir); + + if (is_dir($dir) AND is_writable($dir)) + { + // Change the log directory + $directory = str_replace('\\', '/', $dir).'/'; + } + else + { + // Log directory is invalid + throw new Kohana_Exception('core.log_dir_unwritable', $dir); + } + } + + return $directory; + } + + /** + * Load data from a simple cache file. This should only be used internally, + * and is NOT a replacement for the Cache library. + * + * @param string unique name of cache + * @param integer expiration in seconds + * @return mixed + */ + public static function cache($name, $lifetime) + { + if ($lifetime > 0) + { + $path = self::$internal_cache_path.'kohana_'.$name; + + if (is_file($path)) + { + // Check the file modification time + if ((time() - filemtime($path)) < $lifetime) + { + // Cache is valid! Now, do we need to decrypt it? + if(self::$internal_cache_encrypt===TRUE) + { + $data = file_get_contents($path); + + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + + $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, self::$internal_cache_key, $data, MCRYPT_MODE_ECB, $iv); + + $cache = unserialize($decrypted_text); + + // If the key changed, delete the cache file + if(!$cache) + unlink($path); + + // If cache is false (as above) return NULL, otherwise, return the cache + return ($cache ? $cache : NULL); + } + else + { + return unserialize(file_get_contents($path)); + } + } + else + { + // Cache is invalid, delete it + unlink($path); + } + } + } + + // No cache found + return NULL; + } + + /** + * Save data to a simple cache file. This should only be used internally, and + * is NOT a replacement for the Cache library. + * + * @param string cache name + * @param mixed data to cache + * @param integer expiration in seconds + * @return boolean + */ + public static function cache_save($name, $data, $lifetime) + { + if ($lifetime < 1) + return FALSE; + + $path = self::$internal_cache_path.'kohana_'.$name; + + if ($data === NULL) + { + // Delete cache + return (is_file($path) and unlink($path)); + } + else + { + // Using encryption? Encrypt the data when we write it + if(self::$internal_cache_encrypt===TRUE) + { + // Encrypt and write data to cache file + $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); + $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); + + // Serialize and encrypt! + $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, self::$internal_cache_key, serialize($data), MCRYPT_MODE_ECB, $iv); + + return (bool) file_put_contents($path, $encrypted_text); + } + else + { + // Write data to cache file + return (bool) file_put_contents($path, serialize($data)); + } + } + } + + /** + * Kohana output handler. Called during ob_clean, ob_flush, and their variants. + * + * @param string current output buffer + * @return string + */ + public static function output_buffer($output) + { + // Could be flushing, so send headers first + if ( ! Event::has_run('system.send_headers')) + { + // Run the send_headers event + Event::run('system.send_headers'); + } + + self::$output = $output; + + // Set and return the final output + return self::$output; + } + + /** + * Closes all open output buffers, either by flushing or cleaning, and stores the Kohana + * output buffer for display during shutdown. + * + * @param boolean disable to clear buffers, rather than flushing + * @return void + */ + public static function close_buffers($flush = TRUE) + { + if (ob_get_level() >= self::$buffer_level) + { + // Set the close function + $close = ($flush === TRUE) ? 'ob_end_flush' : 'ob_end_clean'; + + while (ob_get_level() > self::$buffer_level) + { + // Flush or clean the buffer + $close(); + } + + // Store the Kohana output buffer + if ( version_compare(PHP_VERSION, '5.4', '<') ) { + ob_end_clean(); + } + } + } + + /** + * Triggers the shutdown of Kohana by closing the output buffer, runs the system.display event. + * + * @return void + */ + public static function shutdown() + { + // Close output buffers + self::close_buffers(TRUE); + + // Run the output event + Event::run('system.display', self::$output); + + // Render the final output + self::render(self::$output); + } + + /** + * Inserts global Kohana variables into the generated output and prints it. + * + * @param string final output that will displayed + * @return void + */ + public static function render($output) + { + if (self::config('core.render_stats') === TRUE) + { + // Fetch memory usage in MB + $memory = function_exists('memory_get_usage') ? (memory_get_usage() / 1024 / 1024) : 0; + + // Fetch benchmark for page execution time + $benchmark = Benchmark::get(SYSTEM_BENCHMARK.'_total_execution'); + + // Replace the global template variables + $output = str_replace( + array + ( + '{kohana_version}', + '{kohana_codename}', + '{execution_time}', + '{memory_usage}', + '{included_files}', + ), + array + ( + KOHANA_VERSION, + KOHANA_CODENAME, + $benchmark['time'], + number_format($memory, 2).'MB', + count(get_included_files()), + ), + $output + ); + } + + if ($level = self::config('core.output_compression') AND ini_get('output_handler') !== 'ob_gzhandler' AND (int) ini_get('zlib.output_compression') === 0) + { + if ($level < 1 OR $level > 9) + { + // Normalize the level to be an integer between 1 and 9. This + // step must be done to prevent gzencode from triggering an error + $level = max(1, min($level, 9)); + } + + if (stripos(@$_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) + { + $compress = 'gzip'; + } + elseif (stripos(@$_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== FALSE) + { + $compress = 'deflate'; + } + } + + if (isset($compress) AND $level > 0) + { + switch ($compress) + { + case 'gzip': + // Compress output using gzip + $output = gzencode($output, $level); + break; + case 'deflate': + // Compress output using zlib (HTTP deflate) + $output = gzdeflate($output, $level); + break; + } + + // This header must be sent with compressed content to prevent + // browser caches from breaking + header('Vary: Accept-Encoding'); + + // Send the content encoding header + header('Content-Encoding: '.$compress); + + // Sending Content-Length in CGI can result in unexpected behavior + if (stripos(PHP_SAPI, 'cgi') === FALSE) + { + header('Content-Length: '.strlen($output)); + } + } + + echo $output; + } + + /** + * Displays a 404 page. + * + * @throws Kohana_404_Exception + * @param string URI of page + * @param string custom template + * @return void + */ + public static function show_404($page = FALSE, $template = FALSE) + { + throw new Kohana_404_Exception($page, $template); + } + + /** + * Dual-purpose PHP error and exception handler. Uses the kohana_error_page + * view to display the message. + * + * @param integer|object exception object or error code + * @param string error message + * @param string filename + * @param integer line number + * @return void + */ + public static function exception_handler($exception, $message = NULL, $file = NULL, $line = NULL) + { + try + { + // PHP errors have 5 args, always + $PHP_ERROR = (func_num_args() === 5); + + // Test to see if errors should be displayed + if ($PHP_ERROR AND (error_reporting() & $exception) === 0) + return; + + // This is useful for hooks to determine if a page has an error + self::$has_error = TRUE; + + // Error handling will use exactly 5 args, every time + if ($PHP_ERROR) + { + $code = $exception; + $type = 'PHP Error'; + $template = 'kohana_error_page'; + } + else + { + $code = $exception->getCode(); + $type = get_class($exception); + $message = $exception->getMessage(); + $file = $exception->getFile(); + $line = $exception->getLine(); + $template = ($exception instanceof Kohana_Exception) ? $exception->getTemplate() : 'kohana_error_page'; + } + + if (is_numeric($code)) + { + $codes = self::lang('errors'); + + if ( ! empty($codes[$code])) + { + list($level, $error, $description) = $codes[$code]; + } + else + { + $level = 1; + $error = $PHP_ERROR ? 'Unknown Error' : get_class($exception); + $description = ''; + } + } + else + { + // Custom error message, this will never be logged + $level = 5; + $error = $code; + $description = ''; + } + + // Remove the DOCROOT from the path, as a security precaution + $file = str_replace('\\', '/', realpath($file)); + $file = preg_replace('|^'.preg_quote(DOCROOT).'|', '', $file); + + if ($level <= self::$configuration['core']['log_threshold']) + { + // Log the error + self::log('error', self::lang('core.uncaught_exception', $type, $message, $file, $line)); + } + + if ($PHP_ERROR) + { + //$description = self::lang('errors.'.E_RECOVERABLE_ERROR); + $description = is_array($description) ? $description[2] : ''; + + if ( ! headers_sent()) + { + // Send the 500 header + header('HTTP/1.1 500 Internal Server Error'); + } + } + else + { + if (method_exists($exception, 'sendHeaders') AND ! headers_sent()) + { + // Send the headers if they have not already been sent + $exception->sendHeaders(); + } + } + + // Close all output buffers except for Kohana + while (ob_get_level() > self::$buffer_level) + { + ob_end_clean(); + } + + // Test if display_errors is on + if (self::$configuration['core']['display_errors'] === TRUE) + { + if ( ! IN_PRODUCTION AND $line != FALSE) + { + // Remove the first entry of debug_backtrace(), it is the exception_handler call + $trace = $PHP_ERROR ? array_slice(debug_backtrace(), 1) : $exception->getTrace(); + + // Beautify backtrace + $trace = self::backtrace($trace); + } + + // Load the error + require self::find_file('views', empty($template) ? 'kohana_error_page' : $template); + } + else + { + // Get the i18n messages + $error = self::lang('core.generic_error'); + $message = self::lang('core.errors_disabled', url::site(), url::site(Router::$current_uri)); + + // Load the errors_disabled view + require self::find_file('views', 'kohana_error_disabled'); + } + + if ( ! Event::has_run('system.shutdown')) + { + // Run the shutdown even to ensure a clean exit + Event::run('system.shutdown'); + } + + // Turn off error reporting + error_reporting(0); + exit; + } + catch (Exception $e) + { + if (IN_PRODUCTION) + { + die('Fatal Error'); + } + else + { + die('Fatal Error: '.$e->getMessage().' File: '.$e->getFile().' Line: '.$e->getLine()); + } + } + } + + /** + * Provides class auto-loading. + * + * @throws Kohana_Exception + * @param string name of class + * @return bool + */ + public static function auto_load($class) + { + if (class_exists($class, FALSE)) + return TRUE; + + if (($suffix = strrpos($class, '_')) > 0) + { + // Find the class suffix + $suffix = substr($class, $suffix + 1); + } + else + { + // No suffix + $suffix = FALSE; + } + + if ($suffix === 'Core') + { + $type = 'libraries'; + $file = substr($class, 0, -5); + } + elseif ($suffix === 'Controller') + { + $type = 'controllers'; + // Lowercase filename + $file = strtolower(substr($class, 0, -11)); + } + elseif ($suffix === 'Model') + { + $type = 'models'; + // Lowercase filename + $file = strtolower(substr($class, 0, -6)); + } + elseif ($suffix === 'Driver') + { + $type = 'libraries/drivers'; + $file = str_replace('_', '/', substr($class, 0, -7)); + } + else + { + // This could be either a library or a helper, but libraries must + // always be capitalized, so we check if the first character is + // uppercase. If it is, we are loading a library, not a helper. + $type = ($class[0] < 'a') ? 'libraries' : 'helpers'; + $file = $class; + } + + if ($filename = self::find_file($type, $file)) + { + // Load the class + require $filename; + } + else + { + // The class could not be found + return FALSE; + } + + if ($filename = self::find_file($type, self::$configuration['core']['extension_prefix'].$class)) + { + // Load the class extension + require $filename; + } + elseif ($suffix !== 'Core' AND class_exists($class.'_Core', FALSE)) + { + // Class extension to be evaluated + $extension = 'class '.$class.' extends '.$class.'_Core { }'; + + // Start class analysis + $core = new ReflectionClass($class.'_Core'); + + if ($core->isAbstract()) + { + // Make the extension abstract + $extension = 'abstract '.$extension; + } + + // Transparent class extensions are handled using eval. This is + // a disgusting hack, but it gets the job done. + eval($extension); + } + + return TRUE; + } + + /** + * Find a resource file in a given directory. Files will be located according + * to the order of the include paths. Configuration and i18n files will be + * returned in reverse order. + * + * @throws Kohana_Exception if file is required and not found + * @param string directory to search in + * @param string filename to look for (without extension) + * @param boolean file required + * @param string file extension + * @return array if the type is config, i18n or l10n + * @return string if the file is found + * @return FALSE if the file is not found + */ + public static function find_file($directory, $filename, $required = FALSE, $ext = FALSE) + { + // NOTE: This test MUST be not be a strict comparison (===), or empty + // extensions will be allowed! + if ($ext == '') + { + // Use the default extension + $ext = EXT; + } + else + { + // Add a period before the extension + $ext = '.'.$ext; + } + + // Search path + $search = $directory.'/'.$filename.$ext; + + if (isset(self::$internal_cache['find_file_paths'][$search])) + return self::$internal_cache['find_file_paths'][$search]; + + // Load include paths + $paths = self::$include_paths; + + // Nothing found, yet + $found = NULL; + + if ($directory === 'config' OR $directory === 'i18n') + { + // Search in reverse, for merging + $paths = array_reverse($paths); + + foreach ($paths as $path) + { + if (is_file($path.$search)) + { + // A matching file has been found + $found[] = $path.$search; + } + } + } + else + { + foreach ($paths as $path) + { + if (is_file($path.$search)) + { + // A matching file has been found + $found = $path.$search; + + // Stop searching + break; + } + } + } + + if ($found === NULL) + { + if ($required === TRUE) + { + // Directory i18n key + $directory = 'core.'.inflector::singular($directory); + + // If the file is required, throw an exception + throw new Kohana_Exception('core.resource_not_found', self::lang($directory), $filename); + } + else + { + // Nothing was found, return FALSE + $found = FALSE; + } + } + + if ( ! isset(self::$write_cache['find_file_paths'])) + { + // Write cache at shutdown + self::$write_cache['find_file_paths'] = TRUE; + } + + return self::$internal_cache['find_file_paths'][$search] = $found; + } + + /** + * Lists all files and directories in a resource path. + * + * @param string directory to search + * @param boolean list all files to the maximum depth? + * @param string full path to search (used for recursion, *never* set this manually) + * @return array filenames and directories + */ + public static function list_files($directory, $recursive = FALSE, $path = FALSE) + { + $files = array(); + + if ($path === FALSE) + { + $paths = array_reverse(self::include_paths()); + + foreach ($paths as $path) + { + // Recursively get and merge all files + $files = array_merge($files, self::list_files($directory, $recursive, $path.$directory)); + } + } + else + { + $path = rtrim($path, '/').'/'; + + if (is_readable($path)) + { + $items = (array) glob($path.'*'); + + if ( ! empty($items)) + { + foreach ($items as $index => $item) + { + $files[] = $item = str_replace('\\', '/', $item); + + // Handle recursion + if (is_dir($item) AND $recursive == TRUE) + { + // Filename should only be the basename + $item = pathinfo($item, PATHINFO_BASENAME); + + // Append sub-directory search + $files = array_merge($files, self::list_files($directory, TRUE, $path.$item)); + } + } + } + } + } + + return $files; + } + + /** + * Fetch an i18n language item. + * + * @param string language key to fetch + * @param array additional information to insert into the line + * @return string i18n language string, or the requested key if the i18n item is not found + */ + public static function lang($key, $args = array()) + { + // Extract the main group from the key + $group = explode('.', $key, 2); + $group = $group[0]; + + // Get locale name + $locale = self::config('locale.language.0'); + + if ( ! isset(self::$internal_cache['language'][$locale][$group])) + { + // Messages for this group + $messages = array(); + + if ($files = self::find_file('i18n', $locale.'/'.$group)) + { + foreach ($files as $file) + { + include $file; + + // Merge in configuration + if ( ! empty($lang) AND is_array($lang)) + { + foreach ($lang as $k => $v) + { + $messages[$k] = $v; + } + } + } + } + + if ( ! isset(self::$write_cache['language'])) + { + // Write language cache + self::$write_cache['language'] = TRUE; + } + + self::$internal_cache['language'][$locale][$group] = $messages; + } + + // Get the line from cache + $line = self::key_string(self::$internal_cache['language'][$locale], $key); + + if ($line === NULL) + { + self::log('error', 'Missing i18n entry '.$key.' for language '.$locale); + + // Return the key string as fallback + return $key; + } + + if (is_string($line) AND func_num_args() > 1) + { + $args = array_slice(func_get_args(), 1); + + // Add the arguments into the line + $line = vsprintf($line, is_array($args[0]) ? $args[0] : $args); + } + + return $line; + } + + /** + * Returns the value of a key, defined by a 'dot-noted' string, from an array. + * + * @param array array to search + * @param string dot-noted string: foo.bar.baz + * @return string if the key is found + * @return void if the key is not found + */ + public static function key_string($array, $keys) + { + if (empty($array)) + return NULL; + + // Prepare for loop + $keys = explode('.', $keys); + + do + { + // Get the next key + $key = array_shift($keys); + + if (isset($array[$key])) + { + if (is_array($array[$key]) AND ! empty($keys)) + { + // Dig down to prepare the next loop + $array = $array[$key]; + } + else + { + // Requested key was found + return $array[$key]; + } + } + else + { + // Requested key is not set + break; + } + } + while ( ! empty($keys)); + + return NULL; + } + + /** + * Sets values in an array by using a 'dot-noted' string. + * + * @param array array to set keys in (reference) + * @param string dot-noted string: foo.bar.baz + * @return mixed fill value for the key + * @return void + */ + public static function key_string_set( & $array, $keys, $fill = NULL) + { + if (is_object($array) AND ($array instanceof ArrayObject)) + { + // Copy the array + $array_copy = $array->getArrayCopy(); + + // Is an object + $array_object = TRUE; + } + else + { + if ( ! is_array($array)) + { + // Must always be an array + $array = (array) $array; + } + + // Copy is a reference to the array + $array_copy =& $array; + } + + if (empty($keys)) + return $array; + + // Create keys + $keys = explode('.', $keys); + + // Create reference to the array + $row =& $array_copy; + + for ($i = 0, $end = count($keys) - 1; $i <= $end; $i++) + { + // Get the current key + $key = $keys[$i]; + + if ( ! isset($row[$key])) + { + if (isset($keys[$i + 1])) + { + // Make the value an array + $row[$key] = array(); + } + else + { + // Add the fill key + $row[$key] = $fill; + } + } + elseif (isset($keys[$i + 1])) + { + // Make the value an array + $row[$key] = (array) $row[$key]; + } + + // Go down a level, creating a new row reference + $row =& $row[$key]; + } + + if (isset($array_object)) + { + // Swap the array back in + $array->exchangeArray($array_copy); + } + } + + /** + * Retrieves current user agent information: + * keys: browser, version, platform, mobile, robot, referrer, languages, charsets + * tests: is_browser, is_mobile, is_robot, accept_lang, accept_charset + * + * @param string key or test name + * @param string used with "accept" tests: user_agent(accept_lang, en) + * @return array languages and charsets + * @return string all other keys + * @return boolean all tests + */ + public static function user_agent($key = 'agent', $compare = NULL) + { + static $info; + + // Return the raw string + if ($key === 'agent') + return self::$user_agent; + + if ($info === NULL) + { + // Parse the user agent and extract basic information + $agents = self::config('user_agents'); + + foreach ($agents as $type => $data) + { + foreach ($data as $agent => $name) + { + if (stripos(self::$user_agent, $agent) !== FALSE) + { + if ($type === 'browser' AND preg_match('|'.preg_quote($agent).'[^0-9.]*+([0-9.][0-9.a-z]*)|i', self::$user_agent, $match)) + { + // Set the browser version + $info['version'] = $match[1]; + } + + // Set the agent name + $info[$type] = $name; + break; + } + } + } + } + + if (empty($info[$key])) + { + switch ($key) + { + case 'is_robot': + case 'is_browser': + case 'is_mobile': + // A boolean result + $return = ! empty($info[substr($key, 3)]); + break; + case 'languages': + $return = array(); + if ( ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) + { + if (preg_match_all('/[-a-z]{2,}/', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])), $matches)) + { + // Found a result + $return = $matches[0]; + } + } + break; + case 'charsets': + $return = array(); + if ( ! empty($_SERVER['HTTP_ACCEPT_CHARSET'])) + { + if (preg_match_all('/[-a-z0-9]{2,}/', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])), $matches)) + { + // Found a result + $return = $matches[0]; + } + } + break; + case 'referrer': + if ( ! empty($_SERVER['HTTP_REFERER'])) + { + // Found a result + $return = trim($_SERVER['HTTP_REFERER']); + } + break; + } + + // Cache the return value + isset($return) and $info[$key] = $return; + } + + if ( ! empty($compare)) + { + // The comparison must always be lowercase + $compare = strtolower($compare); + + switch ($key) + { + case 'accept_lang': + // Check if the lange is accepted + return in_array($compare, self::user_agent('languages')); + break; + case 'accept_charset': + // Check if the charset is accepted + return in_array($compare, self::user_agent('charsets')); + break; + default: + // Invalid comparison + return FALSE; + break; + } + } + + // Return the key, if set + return isset($info[$key]) ? $info[$key] : NULL; + } + + /** + * Quick debugging of any variable. Any number of parameters can be set. + * + * @return string + */ + public static function debug() + { + if (func_num_args() === 0) + return; + + // Get params + $params = func_get_args(); + $output = array(); + + foreach ($params as $var) + { + $output[] = '
('.gettype($var).') '.html::specialchars(print_r($var, TRUE)).'
'; + } + + return implode("\n", $output); + } + + /** + * Displays nice backtrace information. + * @see http://php.net/debug_backtrace + * + * @param array backtrace generated by an exception or debug_backtrace + * @return string + */ + public static function backtrace($trace) + { + if ( ! is_array($trace)) + return; + + // Final output + $output = array(); + + foreach ($trace as $entry) + { + $temp = '
  • '; + + if (isset($entry['file'])) + { + $temp .= self::lang('core.error_file_line', preg_replace('!^'.preg_quote(DOCROOT).'!', '', $entry['file']), $entry['line']); + } + + $temp .= '
    ';
    +
    +			if (isset($entry['class']))
    +			{
    +				// Add class and call type
    +				$temp .= $entry['class'].$entry['type'];
    +			}
    +
    +			// Add function
    +			$temp .= $entry['function'].'( ';
    +
    +			// Add function args
    +			if (isset($entry['args']) AND is_array($entry['args']))
    +			{
    +				// Separator starts as nothing
    +				$sep = '';
    +
    +				while ($arg = array_shift($entry['args']))
    +				{
    +					if (is_string($arg) AND is_file($arg))
    +					{
    +						// Remove docroot from filename
    +						$arg = preg_replace('!^'.preg_quote(DOCROOT).'!', '', $arg);
    +					}
    +
    +					$temp .= $sep.html::specialchars(print_r($arg, TRUE));
    +
    +					// Change separator to a comma
    +					$sep = ', ';
    +				}
    +			}
    +
    +			$temp .= ' )
  • '; + + $output[] = $temp; + } + + return '
      '.implode("\n", $output).'
    '; + } + + /** + * Saves the internal caches: configuration, include paths, etc. + * + * @return boolean + */ + public static function internal_cache_save() + { + if ( ! is_array(self::$write_cache)) + return FALSE; + + // Get internal cache names + $caches = array_keys(self::$write_cache); + + // Nothing written + $written = FALSE; + + foreach ($caches as $cache) + { + if (isset(self::$internal_cache[$cache])) + { + // Write the cache file + self::cache_save($cache, self::$internal_cache[$cache], self::$configuration['core']['internal_cache']); + + // A cache has been written + $written = TRUE; + } + } + + return $written; + } + +} // End Kohana + +/** + * Creates a generic i18n exception. + */ +class Kohana_Exception extends Exception { + + // Template file + protected $template = 'kohana_error_page'; + + // Header + protected $header = FALSE; + + // Error code + protected $code = E_KOHANA; + + /** + * Set exception message. + * + * @param string i18n language key for the message + * @param array addition line parameters + */ + public function __construct($error) + { + $args = array_slice(func_get_args(), 1); + + // Fetch the error message + $message = Kohana::lang($error, $args); + + if ($message === $error OR empty($message)) + { + // Unable to locate the message for the error + $message = 'Unknown Exception: '.$error; + } + + // Sets $this->message the proper way + parent::__construct($message); + } + + /** + * Magic method for converting an object to a string. + * + * @return string i18n message + */ + public function __toString() + { + return (string) $this->message; + } + + /** + * Fetch the template name. + * + * @return string + */ + public function getTemplate() + { + return $this->template; + } + + /** + * Sends an Internal Server Error header. + * + * @return void + */ + public function sendHeaders() + { + // Send the 500 header + header('HTTP/1.1 500 Internal Server Error'); + } + +} // End Kohana Exception + +/** + * Creates a custom exception. + */ +class Kohana_User_Exception extends Kohana_Exception { + + /** + * Set exception title and message. + * + * @param string exception title string + * @param string exception message string + * @param string custom error template + */ + public function __construct($title, $message, $template = FALSE) + { + Exception::__construct($message); + + $this->code = $title; + + if ($template !== FALSE) + { + $this->template = $template; + } + } + +} // End Kohana PHP Exception + +/** + * Creates a Page Not Found exception. + */ +class Kohana_404_Exception extends Kohana_Exception { + + protected $code = E_PAGE_NOT_FOUND; + + /** + * Set internal properties. + * + * @param string URL of page + * @param string custom error template + */ + public function __construct($page = FALSE, $template = FALSE) + { + if ($page === FALSE) + { + // Construct the page URI using Router properties + $page = Router::$current_uri.Router::$url_suffix.Router::$query_string; + } + + Exception::__construct(Kohana::lang('core.page_not_found', $page)); + + $this->template = $template; + } + + /** + * Sends "File Not Found" headers, to emulate server behavior. + * + * @return void + */ + public function sendHeaders() + { + // Send the 404 header + header('HTTP/1.1 404 File Not Found'); + } + +} // End Kohana 404 Exception diff --git a/lib/kohana/system/core/utf8.php b/lib/kohana/system/core/utf8.php new file mode 100644 index 0000000..9f20f42 --- /dev/null +++ b/lib/kohana/system/core/utf8.php @@ -0,0 +1,743 @@ +PCRE has not been compiled with UTF-8 support. '. + 'See PCRE Pattern Modifiers '. + 'for more information. This application cannot be run without UTF-8 support.', + E_USER_ERROR + ); +} + +if ( ! extension_loaded('iconv')) +{ + trigger_error + ( + 'The iconv extension is not loaded. '. + 'Without iconv, strings cannot be properly translated to UTF-8 from user input. '. + 'This application cannot be run without UTF-8 support.', + E_USER_ERROR + ); +} + +if (extension_loaded('mbstring') AND (ini_get('mbstring.func_overload') & MB_OVERLOAD_STRING)) +{ + trigger_error + ( + 'The mbstring extension is overloading PHP\'s native string functions. '. + 'Disable this by setting mbstring.func_overload to 0, 1, 4 or 5 in php.ini or a .htaccess file.'. + 'This application cannot be run without UTF-8 support.', + E_USER_ERROR + ); +} + +// Check PCRE support for Unicode properties such as \p and \X. +$ER = error_reporting(0); +define('PCRE_UNICODE_PROPERTIES', (bool) preg_match('/^\pL$/u', 'ñ')); +error_reporting($ER); + +// SERVER_UTF8 ? use mb_* functions : use non-native functions +if (extension_loaded('mbstring')) +{ + mb_internal_encoding('UTF-8'); + define('SERVER_UTF8', TRUE); +} +else +{ + define('SERVER_UTF8', FALSE); +} + +// Convert all global variables to UTF-8. +$_GET = utf8::clean($_GET); +$_POST = utf8::clean($_POST); +$_COOKIE = utf8::clean($_COOKIE); +$_SERVER = utf8::clean($_SERVER); + +if (PHP_SAPI == 'cli') +{ + // Convert command line arguments + $_SERVER['argv'] = utf8::clean($_SERVER['argv']); +} + +final class utf8 { + + // Called methods + static $called = array(); + + /** + * Recursively cleans arrays, objects, and strings. Removes ASCII control + * codes and converts to UTF-8 while silently discarding incompatible + * UTF-8 characters. + * + * @param string string to clean + * @return string + */ + public static function clean($str) + { + if (is_array($str) OR is_object($str)) + { + foreach ($str as $key => $val) + { + // Recursion! + $str[self::clean($key)] = self::clean($val); + } + } + elseif (is_string($str) AND $str !== '') + { + // Remove control characters + $str = self::strip_ascii_ctrl($str); + + if ( ! self::is_ascii($str)) + { + // Disable notices + $ER = error_reporting(~E_NOTICE); + + // iconv is expensive, so it is only used when needed + $str = iconv('UTF-8', 'UTF-8//IGNORE', $str); + + // Turn notices back on + error_reporting($ER); + } + } + + return $str; + } + + /** + * Tests whether a string contains only 7bit ASCII bytes. This is used to + * determine when to use native functions or UTF-8 functions. + * + * @param string string to check + * @return bool + */ + public static function is_ascii($str) + { + return ! preg_match('/[^\x00-\x7F]/S', $str); + } + + /** + * Strips out device control codes in the ASCII range. + * + * @param string string to clean + * @return string + */ + public static function strip_ascii_ctrl($str) + { + return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str); + } + + /** + * Strips out all non-7bit ASCII bytes. + * + * @param string string to clean + * @return string + */ + public static function strip_non_ascii($str) + { + return preg_replace('/[^\x00-\x7F]+/S', '', $str); + } + + /** + * Replaces special/accented UTF-8 characters by ASCII-7 'equivalents'. + * + * @author Andreas Gohr + * + * @param string string to transliterate + * @param integer -1 lowercase only, +1 uppercase only, 0 both cases + * @return string + */ + public static function transliterate_to_ascii($str, $case = 0) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _transliterate_to_ascii($str, $case); + } + + /** + * Returns the length of the given string. + * @see http://php.net/strlen + * + * @param string string being measured for length + * @return integer + */ + public static function strlen($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strlen($str); + } + + /** + * Finds position of first occurrence of a UTF-8 string. + * @see http://php.net/strlen + * + * @author Harry Fuecks + * + * @param string haystack + * @param string needle + * @param integer offset from which character in haystack to start searching + * @return integer position of needle + * @return boolean FALSE if the needle is not found + */ + public static function strpos($str, $search, $offset = 0) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strpos($str, $search, $offset); + } + + /** + * Finds position of last occurrence of a char in a UTF-8 string. + * @see http://php.net/strrpos + * + * @author Harry Fuecks + * + * @param string haystack + * @param string needle + * @param integer offset from which character in haystack to start searching + * @return integer position of needle + * @return boolean FALSE if the needle is not found + */ + public static function strrpos($str, $search, $offset = 0) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strrpos($str, $search, $offset); + } + + /** + * Returns part of a UTF-8 string. + * @see http://php.net/substr + * + * @author Chris Smith + * + * @param string input string + * @param integer offset + * @param integer length limit + * @return string + */ + public static function substr($str, $offset, $length = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _substr($str, $offset, $length); + } + + /** + * Replaces text within a portion of a UTF-8 string. + * @see http://php.net/substr_replace + * + * @author Harry Fuecks + * + * @param string input string + * @param string replacement string + * @param integer offset + * @return string + */ + public static function substr_replace($str, $replacement, $offset, $length = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _substr_replace($str, $replacement, $offset, $length); + } + + /** + * Makes a UTF-8 string lowercase. + * @see http://php.net/strtolower + * + * @author Andreas Gohr + * + * @param string mixed case string + * @return string + */ + public static function strtolower($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strtolower($str); + } + + /** + * Makes a UTF-8 string uppercase. + * @see http://php.net/strtoupper + * + * @author Andreas Gohr + * + * @param string mixed case string + * @return string + */ + public static function strtoupper($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strtoupper($str); + } + + /** + * Makes a UTF-8 string's first character uppercase. + * @see http://php.net/ucfirst + * + * @author Harry Fuecks + * + * @param string mixed case string + * @return string + */ + public static function ucfirst($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _ucfirst($str); + } + + /** + * Makes the first character of every word in a UTF-8 string uppercase. + * @see http://php.net/ucwords + * + * @author Harry Fuecks + * + * @param string mixed case string + * @return string + */ + public static function ucwords($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _ucwords($str); + } + + /** + * Case-insensitive UTF-8 string comparison. + * @see http://php.net/strcasecmp + * + * @author Harry Fuecks + * + * @param string string to compare + * @param string string to compare + * @return integer less than 0 if str1 is less than str2 + * @return integer greater than 0 if str1 is greater than str2 + * @return integer 0 if they are equal + */ + public static function strcasecmp($str1, $str2) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strcasecmp($str1, $str2); + } + + /** + * Returns a string or an array with all occurrences of search in subject (ignoring case). + * replaced with the given replace value. + * @see http://php.net/str_ireplace + * + * @note It's not fast and gets slower if $search and/or $replace are arrays. + * @author Harry Fuecks + * + * @param string input string + * @param string needle + * @return string matched substring if found + * @return boolean FALSE if the substring was not found + */ + public static function stristr($str, $search) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _stristr($str, $search); + } + + /** + * Finds the length of the initial segment matching mask. + * @see http://php.net/strspn + * + * @author Harry Fuecks + * + * @param string input string + * @param string mask for search + * @param integer start position of the string to examine + * @param integer length of the string to examine + * @return integer length of the initial segment that contains characters in the mask + */ + public static function strspn($str, $mask, $offset = NULL, $length = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strspn($str, $mask, $offset, $length); + } + + /** + * Finds the length of the initial segment not matching mask. + * @see http://php.net/strcspn + * + * @author Harry Fuecks + * + * @param string input string + * @param string mask for search + * @param integer start position of the string to examine + * @param integer length of the string to examine + * @return integer length of the initial segment that contains characters not in the mask + */ + public static function strcspn($str, $mask, $offset = NULL, $length = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strcspn($str, $mask, $offset, $length); + } + + /** + * Pads a UTF-8 string to a certain length with another string. + * @see http://php.net/str_pad + * + * @author Harry Fuecks + * + * @param string input string + * @param integer desired string length after padding + * @param string string to use as padding + * @param string padding type: STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH + * @return string + */ + public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _str_pad($str, $final_str_length, $pad_str, $pad_type); + } + + /** + * Converts a UTF-8 string to an array. + * @see http://php.net/str_split + * + * @author Harry Fuecks + * + * @param string input string + * @param integer maximum length of each chunk + * @return array + */ + public static function str_split($str, $split_length = 1) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _str_split($str, $split_length); + } + + /** + * Reverses a UTF-8 string. + * @see http://php.net/strrev + * + * @author Harry Fuecks + * + * @param string string to be reversed + * @return string + */ + public static function strrev($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _strrev($str); + } + + /** + * Strips whitespace (or other UTF-8 characters) from the beginning and + * end of a string. + * @see http://php.net/trim + * + * @author Andreas Gohr + * + * @param string input string + * @param string string of characters to remove + * @return string + */ + public static function trim($str, $charlist = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _trim($str, $charlist); + } + + /** + * Strips whitespace (or other UTF-8 characters) from the beginning of a string. + * @see http://php.net/ltrim + * + * @author Andreas Gohr + * + * @param string input string + * @param string string of characters to remove + * @return string + */ + public static function ltrim($str, $charlist = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _ltrim($str, $charlist); + } + + /** + * Strips whitespace (or other UTF-8 characters) from the end of a string. + * @see http://php.net/rtrim + * + * @author Andreas Gohr + * + * @param string input string + * @param string string of characters to remove + * @return string + */ + public static function rtrim($str, $charlist = NULL) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _rtrim($str, $charlist); + } + + /** + * Returns the unicode ordinal for a character. + * @see http://php.net/ord + * + * @author Harry Fuecks + * + * @param string UTF-8 encoded character + * @return integer + */ + public static function ord($chr) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _ord($chr); + } + + /** + * Takes an UTF-8 string and returns an array of ints representing the Unicode characters. + * Astral planes are supported i.e. the ints in the output can be > 0xFFFF. + * Occurrances of the BOM are ignored. Surrogates are not allowed. + * + * The Original Code is Mozilla Communicator client code. + * The Initial Developer of the Original Code is Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer. + * Ported to PHP by Henri Sivonen , see http://hsivonen.iki.fi/php-utf8/. + * Slight modifications to fit with phputf8 library by Harry Fuecks . + * + * @param string UTF-8 encoded string + * @return array unicode code points + * @return boolean FALSE if the string is invalid + */ + public static function to_unicode($str) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _to_unicode($str); + } + + /** + * Takes an array of ints representing the Unicode characters and returns a UTF-8 string. + * Astral planes are supported i.e. the ints in the input can be > 0xFFFF. + * Occurrances of the BOM are ignored. Surrogates are not allowed. + * + * The Original Code is Mozilla Communicator client code. + * The Initial Developer of the Original Code is Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer. + * Ported to PHP by Henri Sivonen , see http://hsivonen.iki.fi/php-utf8/. + * Slight modifications to fit with phputf8 library by Harry Fuecks . + * + * @param array unicode code points representing a string + * @return string utf8 string of characters + * @return boolean FALSE if a code point cannot be found + */ + public static function from_unicode($arr) + { + if ( ! isset(self::$called[__FUNCTION__])) + { + require SYSPATH.'core/utf8/'.__FUNCTION__.EXT; + + // Function has been called + self::$called[__FUNCTION__] = TRUE; + } + + return _from_unicode($arr); + } + +} // End utf8 \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/from_unicode.php b/lib/kohana/system/core/utf8/from_unicode.php new file mode 100644 index 0000000..66c6742 --- /dev/null +++ b/lib/kohana/system/core/utf8/from_unicode.php @@ -0,0 +1,68 @@ += 0) AND ($arr[$k] <= 0x007f)) + { + echo chr($arr[$k]); + } + // 2 byte sequence + elseif ($arr[$k] <= 0x07ff) + { + echo chr(0xc0 | ($arr[$k] >> 6)); + echo chr(0x80 | ($arr[$k] & 0x003f)); + } + // Byte order mark (skip) + elseif ($arr[$k] == 0xFEFF) + { + // nop -- zap the BOM + } + // Test for illegal surrogates + elseif ($arr[$k] >= 0xD800 AND $arr[$k] <= 0xDFFF) + { + // Found a surrogate + trigger_error('utf8::from_unicode: Illegal surrogate at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); + return FALSE; + } + // 3 byte sequence + elseif ($arr[$k] <= 0xffff) + { + echo chr(0xe0 | ($arr[$k] >> 12)); + echo chr(0x80 | (($arr[$k] >> 6) & 0x003f)); + echo chr(0x80 | ($arr[$k] & 0x003f)); + } + // 4 byte sequence + elseif ($arr[$k] <= 0x10ffff) + { + echo chr(0xf0 | ($arr[$k] >> 18)); + echo chr(0x80 | (($arr[$k] >> 12) & 0x3f)); + echo chr(0x80 | (($arr[$k] >> 6) & 0x3f)); + echo chr(0x80 | ($arr[$k] & 0x3f)); + } + // Out of range + else + { + trigger_error('utf8::from_unicode: Codepoint out of Unicode range at index: '.$k.', value: '.$arr[$k], E_USER_WARNING); + return FALSE; + } + } + + $result = ob_get_contents(); + ob_end_clean(); + return $result; +} diff --git a/lib/kohana/system/core/utf8/ltrim.php b/lib/kohana/system/core/utf8/ltrim.php new file mode 100644 index 0000000..556fe07 --- /dev/null +++ b/lib/kohana/system/core/utf8/ltrim.php @@ -0,0 +1,22 @@ += 0 AND $ord0 <= 127) + { + return $ord0; + } + + if ( ! isset($chr[1])) + { + trigger_error('Short sequence - at least 2 bytes expected, only 1 seen', E_USER_WARNING); + return FALSE; + } + + $ord1 = ord($chr[1]); + + if ($ord0 >= 192 AND $ord0 <= 223) + { + return ($ord0 - 192) * 64 + ($ord1 - 128); + } + + if ( ! isset($chr[2])) + { + trigger_error('Short sequence - at least 3 bytes expected, only 2 seen', E_USER_WARNING); + return FALSE; + } + + $ord2 = ord($chr[2]); + + if ($ord0 >= 224 AND $ord0 <= 239) + { + return ($ord0 - 224) * 4096 + ($ord1 - 128) * 64 + ($ord2 - 128); + } + + if ( ! isset($chr[3])) + { + trigger_error('Short sequence - at least 4 bytes expected, only 3 seen', E_USER_WARNING); + return FALSE; + } + + $ord3 = ord($chr[3]); + + if ($ord0 >= 240 AND $ord0 <= 247) + { + return ($ord0 - 240) * 262144 + ($ord1 - 128) * 4096 + ($ord2-128) * 64 + ($ord3 - 128); + } + + if ( ! isset($chr[4])) + { + trigger_error('Short sequence - at least 5 bytes expected, only 4 seen', E_USER_WARNING); + return FALSE; + } + + $ord4 = ord($chr[4]); + + if ($ord0 >= 248 AND $ord0 <= 251) + { + return ($ord0 - 248) * 16777216 + ($ord1-128) * 262144 + ($ord2 - 128) * 4096 + ($ord3 - 128) * 64 + ($ord4 - 128); + } + + if ( ! isset($chr[5])) + { + trigger_error('Short sequence - at least 6 bytes expected, only 5 seen', E_USER_WARNING); + return FALSE; + } + + if ($ord0 >= 252 AND $ord0 <= 253) + { + return ($ord0 - 252) * 1073741824 + ($ord1 - 128) * 16777216 + ($ord2 - 128) * 262144 + ($ord3 - 128) * 4096 + ($ord4 - 128) * 64 + (ord($chr[5]) - 128); + } + + if ($ord0 >= 254 AND $ord0 <= 255) + { + trigger_error('Invalid UTF-8 with surrogate ordinal '.$ord0, E_USER_WARNING); + return FALSE; + } +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/rtrim.php b/lib/kohana/system/core/utf8/rtrim.php new file mode 100644 index 0000000..efa0e19 --- /dev/null +++ b/lib/kohana/system/core/utf8/rtrim.php @@ -0,0 +1,22 @@ + $val) + { + $str[$key] = utf8::str_ireplace($search, $replace, $val, $count); + } + return $str; + } + + if (is_array($search)) + { + $keys = array_keys($search); + + foreach ($keys as $k) + { + if (is_array($replace)) + { + if (array_key_exists($k, $replace)) + { + $str = utf8::str_ireplace($search[$k], $replace[$k], $str, $count); + } + else + { + $str = utf8::str_ireplace($search[$k], '', $str, $count); + } + } + else + { + $str = utf8::str_ireplace($search[$k], $replace, $str, $count); + } + } + return $str; + } + + $search = utf8::strtolower($search); + $str_lower = utf8::strtolower($str); + + $total_matched_strlen = 0; + $i = 0; + + while (preg_match('/(.*?)'.preg_quote($search, '/').'/s', $str_lower, $matches)) + { + $matched_strlen = strlen($matches[0]); + $str_lower = substr($str_lower, $matched_strlen); + + $offset = $total_matched_strlen + strlen($matches[1]) + ($i * (strlen($replace) - 1)); + $str = substr_replace($str, $replace, $offset, strlen($search)); + + $total_matched_strlen += $matched_strlen; + $i++; + } + + $count += $i; + return $str; +} diff --git a/lib/kohana/system/core/utf8/str_pad.php b/lib/kohana/system/core/utf8/str_pad.php new file mode 100644 index 0000000..aab4ccc --- /dev/null +++ b/lib/kohana/system/core/utf8/str_pad.php @@ -0,0 +1,54 @@ +0x0061, 0x03A6=>0x03C6, 0x0162=>0x0163, 0x00C5=>0x00E5, 0x0042=>0x0062, + 0x0139=>0x013A, 0x00C1=>0x00E1, 0x0141=>0x0142, 0x038E=>0x03CD, 0x0100=>0x0101, + 0x0490=>0x0491, 0x0394=>0x03B4, 0x015A=>0x015B, 0x0044=>0x0064, 0x0393=>0x03B3, + 0x00D4=>0x00F4, 0x042A=>0x044A, 0x0419=>0x0439, 0x0112=>0x0113, 0x041C=>0x043C, + 0x015E=>0x015F, 0x0143=>0x0144, 0x00CE=>0x00EE, 0x040E=>0x045E, 0x042F=>0x044F, + 0x039A=>0x03BA, 0x0154=>0x0155, 0x0049=>0x0069, 0x0053=>0x0073, 0x1E1E=>0x1E1F, + 0x0134=>0x0135, 0x0427=>0x0447, 0x03A0=>0x03C0, 0x0418=>0x0438, 0x00D3=>0x00F3, + 0x0420=>0x0440, 0x0404=>0x0454, 0x0415=>0x0435, 0x0429=>0x0449, 0x014A=>0x014B, + 0x0411=>0x0431, 0x0409=>0x0459, 0x1E02=>0x1E03, 0x00D6=>0x00F6, 0x00D9=>0x00F9, + 0x004E=>0x006E, 0x0401=>0x0451, 0x03A4=>0x03C4, 0x0423=>0x0443, 0x015C=>0x015D, + 0x0403=>0x0453, 0x03A8=>0x03C8, 0x0158=>0x0159, 0x0047=>0x0067, 0x00C4=>0x00E4, + 0x0386=>0x03AC, 0x0389=>0x03AE, 0x0166=>0x0167, 0x039E=>0x03BE, 0x0164=>0x0165, + 0x0116=>0x0117, 0x0108=>0x0109, 0x0056=>0x0076, 0x00DE=>0x00FE, 0x0156=>0x0157, + 0x00DA=>0x00FA, 0x1E60=>0x1E61, 0x1E82=>0x1E83, 0x00C2=>0x00E2, 0x0118=>0x0119, + 0x0145=>0x0146, 0x0050=>0x0070, 0x0150=>0x0151, 0x042E=>0x044E, 0x0128=>0x0129, + 0x03A7=>0x03C7, 0x013D=>0x013E, 0x0422=>0x0442, 0x005A=>0x007A, 0x0428=>0x0448, + 0x03A1=>0x03C1, 0x1E80=>0x1E81, 0x016C=>0x016D, 0x00D5=>0x00F5, 0x0055=>0x0075, + 0x0176=>0x0177, 0x00DC=>0x00FC, 0x1E56=>0x1E57, 0x03A3=>0x03C3, 0x041A=>0x043A, + 0x004D=>0x006D, 0x016A=>0x016B, 0x0170=>0x0171, 0x0424=>0x0444, 0x00CC=>0x00EC, + 0x0168=>0x0169, 0x039F=>0x03BF, 0x004B=>0x006B, 0x00D2=>0x00F2, 0x00C0=>0x00E0, + 0x0414=>0x0434, 0x03A9=>0x03C9, 0x1E6A=>0x1E6B, 0x00C3=>0x00E3, 0x042D=>0x044D, + 0x0416=>0x0436, 0x01A0=>0x01A1, 0x010C=>0x010D, 0x011C=>0x011D, 0x00D0=>0x00F0, + 0x013B=>0x013C, 0x040F=>0x045F, 0x040A=>0x045A, 0x00C8=>0x00E8, 0x03A5=>0x03C5, + 0x0046=>0x0066, 0x00DD=>0x00FD, 0x0043=>0x0063, 0x021A=>0x021B, 0x00CA=>0x00EA, + 0x0399=>0x03B9, 0x0179=>0x017A, 0x00CF=>0x00EF, 0x01AF=>0x01B0, 0x0045=>0x0065, + 0x039B=>0x03BB, 0x0398=>0x03B8, 0x039C=>0x03BC, 0x040C=>0x045C, 0x041F=>0x043F, + 0x042C=>0x044C, 0x00DE=>0x00FE, 0x00D0=>0x00F0, 0x1EF2=>0x1EF3, 0x0048=>0x0068, + 0x00CB=>0x00EB, 0x0110=>0x0111, 0x0413=>0x0433, 0x012E=>0x012F, 0x00C6=>0x00E6, + 0x0058=>0x0078, 0x0160=>0x0161, 0x016E=>0x016F, 0x0391=>0x03B1, 0x0407=>0x0457, + 0x0172=>0x0173, 0x0178=>0x00FF, 0x004F=>0x006F, 0x041B=>0x043B, 0x0395=>0x03B5, + 0x0425=>0x0445, 0x0120=>0x0121, 0x017D=>0x017E, 0x017B=>0x017C, 0x0396=>0x03B6, + 0x0392=>0x03B2, 0x0388=>0x03AD, 0x1E84=>0x1E85, 0x0174=>0x0175, 0x0051=>0x0071, + 0x0417=>0x0437, 0x1E0A=>0x1E0B, 0x0147=>0x0148, 0x0104=>0x0105, 0x0408=>0x0458, + 0x014C=>0x014D, 0x00CD=>0x00ED, 0x0059=>0x0079, 0x010A=>0x010B, 0x038F=>0x03CE, + 0x0052=>0x0072, 0x0410=>0x0430, 0x0405=>0x0455, 0x0402=>0x0452, 0x0126=>0x0127, + 0x0136=>0x0137, 0x012A=>0x012B, 0x038A=>0x03AF, 0x042B=>0x044B, 0x004C=>0x006C, + 0x0397=>0x03B7, 0x0124=>0x0125, 0x0218=>0x0219, 0x00DB=>0x00FB, 0x011E=>0x011F, + 0x041E=>0x043E, 0x1E40=>0x1E41, 0x039D=>0x03BD, 0x0106=>0x0107, 0x03AB=>0x03CB, + 0x0426=>0x0446, 0x00DE=>0x00FE, 0x00C7=>0x00E7, 0x03AA=>0x03CA, 0x0421=>0x0441, + 0x0412=>0x0432, 0x010E=>0x010F, 0x00D8=>0x00F8, 0x0057=>0x0077, 0x011A=>0x011B, + 0x0054=>0x0074, 0x004A=>0x006A, 0x040B=>0x045B, 0x0406=>0x0456, 0x0102=>0x0103, + 0x039B=>0x03BB, 0x00D1=>0x00F1, 0x041D=>0x043D, 0x038C=>0x03CC, 0x00C9=>0x00E9, + 0x00D0=>0x00F0, 0x0407=>0x0457, 0x0122=>0x0123, + ); + } + + $uni = utf8::to_unicode($str); + + if ($uni === FALSE) + return FALSE; + + for ($i = 0, $c = count($uni); $i < $c; $i++) + { + if (isset($UTF8_UPPER_TO_LOWER[$uni[$i]])) + { + $uni[$i] = $UTF8_UPPER_TO_LOWER[$uni[$i]]; + } + } + + return utf8::from_unicode($uni); +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/strtoupper.php b/lib/kohana/system/core/utf8/strtoupper.php new file mode 100644 index 0000000..f3ded73 --- /dev/null +++ b/lib/kohana/system/core/utf8/strtoupper.php @@ -0,0 +1,84 @@ +0x0041, 0x03C6=>0x03A6, 0x0163=>0x0162, 0x00E5=>0x00C5, 0x0062=>0x0042, + 0x013A=>0x0139, 0x00E1=>0x00C1, 0x0142=>0x0141, 0x03CD=>0x038E, 0x0101=>0x0100, + 0x0491=>0x0490, 0x03B4=>0x0394, 0x015B=>0x015A, 0x0064=>0x0044, 0x03B3=>0x0393, + 0x00F4=>0x00D4, 0x044A=>0x042A, 0x0439=>0x0419, 0x0113=>0x0112, 0x043C=>0x041C, + 0x015F=>0x015E, 0x0144=>0x0143, 0x00EE=>0x00CE, 0x045E=>0x040E, 0x044F=>0x042F, + 0x03BA=>0x039A, 0x0155=>0x0154, 0x0069=>0x0049, 0x0073=>0x0053, 0x1E1F=>0x1E1E, + 0x0135=>0x0134, 0x0447=>0x0427, 0x03C0=>0x03A0, 0x0438=>0x0418, 0x00F3=>0x00D3, + 0x0440=>0x0420, 0x0454=>0x0404, 0x0435=>0x0415, 0x0449=>0x0429, 0x014B=>0x014A, + 0x0431=>0x0411, 0x0459=>0x0409, 0x1E03=>0x1E02, 0x00F6=>0x00D6, 0x00F9=>0x00D9, + 0x006E=>0x004E, 0x0451=>0x0401, 0x03C4=>0x03A4, 0x0443=>0x0423, 0x015D=>0x015C, + 0x0453=>0x0403, 0x03C8=>0x03A8, 0x0159=>0x0158, 0x0067=>0x0047, 0x00E4=>0x00C4, + 0x03AC=>0x0386, 0x03AE=>0x0389, 0x0167=>0x0166, 0x03BE=>0x039E, 0x0165=>0x0164, + 0x0117=>0x0116, 0x0109=>0x0108, 0x0076=>0x0056, 0x00FE=>0x00DE, 0x0157=>0x0156, + 0x00FA=>0x00DA, 0x1E61=>0x1E60, 0x1E83=>0x1E82, 0x00E2=>0x00C2, 0x0119=>0x0118, + 0x0146=>0x0145, 0x0070=>0x0050, 0x0151=>0x0150, 0x044E=>0x042E, 0x0129=>0x0128, + 0x03C7=>0x03A7, 0x013E=>0x013D, 0x0442=>0x0422, 0x007A=>0x005A, 0x0448=>0x0428, + 0x03C1=>0x03A1, 0x1E81=>0x1E80, 0x016D=>0x016C, 0x00F5=>0x00D5, 0x0075=>0x0055, + 0x0177=>0x0176, 0x00FC=>0x00DC, 0x1E57=>0x1E56, 0x03C3=>0x03A3, 0x043A=>0x041A, + 0x006D=>0x004D, 0x016B=>0x016A, 0x0171=>0x0170, 0x0444=>0x0424, 0x00EC=>0x00CC, + 0x0169=>0x0168, 0x03BF=>0x039F, 0x006B=>0x004B, 0x00F2=>0x00D2, 0x00E0=>0x00C0, + 0x0434=>0x0414, 0x03C9=>0x03A9, 0x1E6B=>0x1E6A, 0x00E3=>0x00C3, 0x044D=>0x042D, + 0x0436=>0x0416, 0x01A1=>0x01A0, 0x010D=>0x010C, 0x011D=>0x011C, 0x00F0=>0x00D0, + 0x013C=>0x013B, 0x045F=>0x040F, 0x045A=>0x040A, 0x00E8=>0x00C8, 0x03C5=>0x03A5, + 0x0066=>0x0046, 0x00FD=>0x00DD, 0x0063=>0x0043, 0x021B=>0x021A, 0x00EA=>0x00CA, + 0x03B9=>0x0399, 0x017A=>0x0179, 0x00EF=>0x00CF, 0x01B0=>0x01AF, 0x0065=>0x0045, + 0x03BB=>0x039B, 0x03B8=>0x0398, 0x03BC=>0x039C, 0x045C=>0x040C, 0x043F=>0x041F, + 0x044C=>0x042C, 0x00FE=>0x00DE, 0x00F0=>0x00D0, 0x1EF3=>0x1EF2, 0x0068=>0x0048, + 0x00EB=>0x00CB, 0x0111=>0x0110, 0x0433=>0x0413, 0x012F=>0x012E, 0x00E6=>0x00C6, + 0x0078=>0x0058, 0x0161=>0x0160, 0x016F=>0x016E, 0x03B1=>0x0391, 0x0457=>0x0407, + 0x0173=>0x0172, 0x00FF=>0x0178, 0x006F=>0x004F, 0x043B=>0x041B, 0x03B5=>0x0395, + 0x0445=>0x0425, 0x0121=>0x0120, 0x017E=>0x017D, 0x017C=>0x017B, 0x03B6=>0x0396, + 0x03B2=>0x0392, 0x03AD=>0x0388, 0x1E85=>0x1E84, 0x0175=>0x0174, 0x0071=>0x0051, + 0x0437=>0x0417, 0x1E0B=>0x1E0A, 0x0148=>0x0147, 0x0105=>0x0104, 0x0458=>0x0408, + 0x014D=>0x014C, 0x00ED=>0x00CD, 0x0079=>0x0059, 0x010B=>0x010A, 0x03CE=>0x038F, + 0x0072=>0x0052, 0x0430=>0x0410, 0x0455=>0x0405, 0x0452=>0x0402, 0x0127=>0x0126, + 0x0137=>0x0136, 0x012B=>0x012A, 0x03AF=>0x038A, 0x044B=>0x042B, 0x006C=>0x004C, + 0x03B7=>0x0397, 0x0125=>0x0124, 0x0219=>0x0218, 0x00FB=>0x00DB, 0x011F=>0x011E, + 0x043E=>0x041E, 0x1E41=>0x1E40, 0x03BD=>0x039D, 0x0107=>0x0106, 0x03CB=>0x03AB, + 0x0446=>0x0426, 0x00FE=>0x00DE, 0x00E7=>0x00C7, 0x03CA=>0x03AA, 0x0441=>0x0421, + 0x0432=>0x0412, 0x010F=>0x010E, 0x00F8=>0x00D8, 0x0077=>0x0057, 0x011B=>0x011A, + 0x0074=>0x0054, 0x006A=>0x004A, 0x045B=>0x040B, 0x0456=>0x0406, 0x0103=>0x0102, + 0x03BB=>0x039B, 0x00F1=>0x00D1, 0x043D=>0x041D, 0x03CC=>0x038C, 0x00E9=>0x00C9, + 0x00F0=>0x00D0, 0x0457=>0x0407, 0x0123=>0x0122, + ); + } + + $uni = utf8::to_unicode($str); + + if ($uni === FALSE) + return FALSE; + + for ($i = 0, $c = count($uni); $i < $c; $i++) + { + if (isset($UTF8_LOWER_TO_UPPER[$uni[$i]])) + { + $uni[$i] = $UTF8_LOWER_TO_UPPER[$uni[$i]]; + } + } + + return utf8::from_unicode($uni); +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/substr.php b/lib/kohana/system/core/utf8/substr.php new file mode 100644 index 0000000..daf66b8 --- /dev/null +++ b/lib/kohana/system/core/utf8/substr.php @@ -0,0 +1,75 @@ += $strlen OR ($length < 0 AND $length <= $offset - $strlen)) + return ''; + + // Whole string + if ($offset == 0 AND ($length === NULL OR $length >= $strlen)) + return $str; + + // Build regex + $regex = '^'; + + // Create an offset expression + if ($offset > 0) + { + // PCRE repeating quantifiers must be less than 65536, so repeat when necessary + $x = (int) ($offset / 65535); + $y = (int) ($offset % 65535); + $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; + $regex .= ($y == 0) ? '' : '.{'.$y.'}'; + } + + // Create a length expression + if ($length === NULL) + { + $regex .= '(.*)'; // No length set, grab it all + } + // Find length from the left (positive length) + elseif ($length > 0) + { + // Reduce length so that it can't go beyond the end of the string + $length = min($strlen - $offset, $length); + + $x = (int) ($length / 65535); + $y = (int) ($length % 65535); + $regex .= '('; + $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; + $regex .= '.{'.$y.'})'; + } + // Find length from the right (negative length) + else + { + $x = (int) (-$length / 65535); + $y = (int) (-$length % 65535); + $regex .= '(.*)'; + $regex .= ($x == 0) ? '' : '(?:.{65535}){'.$x.'}'; + $regex .= '.{'.$y.'}'; + } + + preg_match('/'.$regex.'/us', $str, $matches); + return $matches[1]; +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/substr_replace.php b/lib/kohana/system/core/utf8/substr_replace.php new file mode 100644 index 0000000..45e2d2a --- /dev/null +++ b/lib/kohana/system/core/utf8/substr_replace.php @@ -0,0 +1,22 @@ + 0x10FFFF)) + { + trigger_error('utf8::to_unicode: Illegal sequence or codepoint in UTF-8 at byte '.$i, E_USER_WARNING); + return FALSE; + } + + if (0xFEFF != $mUcs4) + { + // BOM is legal but we don't want to output it + $out[] = $mUcs4; + } + + // Initialize UTF-8 cache + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + } + } + else + { + // ((0xC0 & (*in) != 0x80) AND (mState != 0)) + // Incomplete multi-octet sequence + trigger_error('utf8::to_unicode: Incomplete multi-octet sequence in UTF-8 at byte '.$i, E_USER_WARNING); + return FALSE; + } + } + } + + return $out; +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/transliterate_to_ascii.php b/lib/kohana/system/core/utf8/transliterate_to_ascii.php new file mode 100644 index 0000000..07461fb --- /dev/null +++ b/lib/kohana/system/core/utf8/transliterate_to_ascii.php @@ -0,0 +1,77 @@ + 'a', 'ô' => 'o', 'ď' => 'd', 'ḟ' => 'f', 'ë' => 'e', 'š' => 's', 'ơ' => 'o', + 'ß' => 'ss', 'ă' => 'a', 'ř' => 'r', 'ț' => 't', 'ň' => 'n', 'ā' => 'a', 'ķ' => 'k', + 'ŝ' => 's', 'ỳ' => 'y', 'ņ' => 'n', 'ĺ' => 'l', 'ħ' => 'h', 'ṗ' => 'p', 'ó' => 'o', + 'ú' => 'u', 'ě' => 'e', 'é' => 'e', 'ç' => 'c', 'ẁ' => 'w', 'ċ' => 'c', 'õ' => 'o', + 'ṡ' => 's', 'ø' => 'o', 'ģ' => 'g', 'ŧ' => 't', 'ș' => 's', 'ė' => 'e', 'ĉ' => 'c', + 'ś' => 's', 'î' => 'i', 'ű' => 'u', 'ć' => 'c', 'ę' => 'e', 'ŵ' => 'w', 'ṫ' => 't', + 'ū' => 'u', 'č' => 'c', 'ö' => 'o', 'è' => 'e', 'ŷ' => 'y', 'ą' => 'a', 'ł' => 'l', + 'ų' => 'u', 'ů' => 'u', 'ş' => 's', 'ğ' => 'g', 'ļ' => 'l', 'ƒ' => 'f', 'ž' => 'z', + 'ẃ' => 'w', 'ḃ' => 'b', 'å' => 'a', 'ì' => 'i', 'ï' => 'i', 'ḋ' => 'd', 'ť' => 't', + 'ŗ' => 'r', 'ä' => 'a', 'í' => 'i', 'ŕ' => 'r', 'ê' => 'e', 'ü' => 'u', 'ò' => 'o', + 'ē' => 'e', 'ñ' => 'n', 'ń' => 'n', 'ĥ' => 'h', 'ĝ' => 'g', 'đ' => 'd', 'ĵ' => 'j', + 'ÿ' => 'y', 'ũ' => 'u', 'ŭ' => 'u', 'ư' => 'u', 'ţ' => 't', 'ý' => 'y', 'ő' => 'o', + 'â' => 'a', 'ľ' => 'l', 'ẅ' => 'w', 'ż' => 'z', 'ī' => 'i', 'ã' => 'a', 'ġ' => 'g', + 'ṁ' => 'm', 'ō' => 'o', 'ĩ' => 'i', 'ù' => 'u', 'į' => 'i', 'ź' => 'z', 'á' => 'a', + 'û' => 'u', 'þ' => 'th', 'ð' => 'dh', 'æ' => 'ae', 'µ' => 'u', 'ĕ' => 'e', + ); + } + + $str = str_replace( + array_keys($UTF8_LOWER_ACCENTS), + array_values($UTF8_LOWER_ACCENTS), + $str + ); + } + + if ($case >= 0) + { + if ($UTF8_UPPER_ACCENTS === NULL) + { + $UTF8_UPPER_ACCENTS = array( + 'À' => 'A', 'Ô' => 'O', 'Ď' => 'D', 'Ḟ' => 'F', 'Ë' => 'E', 'Š' => 'S', 'Ơ' => 'O', + 'Ă' => 'A', 'Ř' => 'R', 'Ț' => 'T', 'Ň' => 'N', 'Ā' => 'A', 'Ķ' => 'K', 'Ĕ' => 'E', + 'Ŝ' => 'S', 'Ỳ' => 'Y', 'Ņ' => 'N', 'Ĺ' => 'L', 'Ħ' => 'H', 'Ṗ' => 'P', 'Ó' => 'O', + 'Ú' => 'U', 'Ě' => 'E', 'É' => 'E', 'Ç' => 'C', 'Ẁ' => 'W', 'Ċ' => 'C', 'Õ' => 'O', + 'Ṡ' => 'S', 'Ø' => 'O', 'Ģ' => 'G', 'Ŧ' => 'T', 'Ș' => 'S', 'Ė' => 'E', 'Ĉ' => 'C', + 'Ś' => 'S', 'Î' => 'I', 'Ű' => 'U', 'Ć' => 'C', 'Ę' => 'E', 'Ŵ' => 'W', 'Ṫ' => 'T', + 'Ū' => 'U', 'Č' => 'C', 'Ö' => 'O', 'È' => 'E', 'Ŷ' => 'Y', 'Ą' => 'A', 'Ł' => 'L', + 'Ų' => 'U', 'Ů' => 'U', 'Ş' => 'S', 'Ğ' => 'G', 'Ļ' => 'L', 'Ƒ' => 'F', 'Ž' => 'Z', + 'Ẃ' => 'W', 'Ḃ' => 'B', 'Å' => 'A', 'Ì' => 'I', 'Ï' => 'I', 'Ḋ' => 'D', 'Ť' => 'T', + 'Ŗ' => 'R', 'Ä' => 'A', 'Í' => 'I', 'Ŕ' => 'R', 'Ê' => 'E', 'Ü' => 'U', 'Ò' => 'O', + 'Ē' => 'E', 'Ñ' => 'N', 'Ń' => 'N', 'Ĥ' => 'H', 'Ĝ' => 'G', 'Đ' => 'D', 'Ĵ' => 'J', + 'Ÿ' => 'Y', 'Ũ' => 'U', 'Ŭ' => 'U', 'Ư' => 'U', 'Ţ' => 'T', 'Ý' => 'Y', 'Ő' => 'O', + 'Â' => 'A', 'Ľ' => 'L', 'Ẅ' => 'W', 'Ż' => 'Z', 'Ī' => 'I', 'Ã' => 'A', 'Ġ' => 'G', + 'Ṁ' => 'M', 'Ō' => 'O', 'Ĩ' => 'I', 'Ù' => 'U', 'Į' => 'I', 'Ź' => 'Z', 'Á' => 'A', + 'Û' => 'U', 'Þ' => 'Th', 'Ð' => 'Dh', 'Æ' => 'Ae', + ); + } + + $str = str_replace( + array_keys($UTF8_UPPER_ACCENTS), + array_values($UTF8_UPPER_ACCENTS), + $str + ); + } + + return $str; +} \ No newline at end of file diff --git a/lib/kohana/system/core/utf8/trim.php b/lib/kohana/system/core/utf8/trim.php new file mode 100644 index 0000000..7434102 --- /dev/null +++ b/lib/kohana/system/core/utf8/trim.php @@ -0,0 +1,17 @@ + $value) + { + $value = ($keep_keys === TRUE) ? $value : array_values($value); + foreach ($value as $k => $v) + { + $new_array[$k][$key] = $v; + } + } + + return $new_array; + } + + /** + * Removes a key from an array and returns the value. + * + * @param string key to return + * @param array array to work on + * @return mixed value of the requested array key + */ + public static function remove($key, & $array) + { + if ( ! array_key_exists($key, $array)) + return NULL; + + $val = $array[$key]; + unset($array[$key]); + + return $val; + } + + + /** + * Extract one or more keys from an array. Each key given after the first + * argument (the array) will be extracted. Keys that do not exist in the + * search array will be NULL in the extracted data. + * + * @param array array to search + * @param string key name + * @return array + */ + public static function extract(array $search, $keys) + { + // Get the keys, removing the $search array + $keys = array_slice(func_get_args(), 1); + + $found = array(); + foreach ($keys as $key) + { + if (isset($search[$key])) + { + $found[$key] = $search[$key]; + } + else + { + $found[$key] = NULL; + } + } + + return $found; + } + + /** + * Because PHP does not have this function. + * + * @param array array to unshift + * @param string key to unshift + * @param mixed value to unshift + * @return array + */ + public static function unshift_assoc( array & $array, $key, $val) + { + $array = array_reverse($array, TRUE); + $array[$key] = $val; + $array = array_reverse($array, TRUE); + + return $array; + } + + /** + * Because PHP does not have this function, and array_walk_recursive creates + * references in arrays and is not truly recursive. + * + * @param mixed callback to apply to each member of the array + * @param array array to map to + * @return array + */ + public static function map_recursive($callback, array $array) + { + foreach ($array as $key => $val) + { + // Map the callback to the key + $array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val); + } + + return $array; + } + + /** + * @param mixed $needle the value to search for + * @param array $haystack an array of values to search in + * @param boolean $sort sort the array now + * @return integer|FALSE the index of the match or FALSE when not found + */ + public static function binary_search($needle, $haystack, $sort = FALSE) + { + if ($sort) + { + sort($haystack); + } + + $high = count($haystack) - 1; + $low = 0; + + while ($low <= $high) + { + $mid = ($low + $high) >> 1; + + if ($haystack[$mid] < $needle) + { + $low = $mid + 1; + } + elseif ($haystack[$mid] > $needle) + { + $high = $mid - 1; + } + else + { + return $mid; + } + } + + return FALSE; + } + + + /** + * Emulates array_merge_recursive, but appends numeric keys and replaces + * associative keys, instead of appending all keys. + * + * @param array any number of arrays + * @return array + */ + public static function merge() + { + $total = func_num_args(); + + $result = array(); + for ($i = 0; $i < $total; $i++) + { + foreach (func_get_arg($i) as $key => $val) + { + if (isset($result[$key])) + { + if (is_array($val)) + { + // Arrays are merged recursively + $result[$key] = arr::merge($result[$key], $val); + } + elseif (is_int($key)) + { + // Indexed arrays are appended + array_push($result, $val); + } + else + { + // Associative arrays are replaced + $result[$key] = $val; + } + } + else + { + // New values are added + $result[$key] = $val; + } + } + } + + return $result; + } + + /** + * Overwrites an array with values from input array(s). + * Non-existing keys will not be appended! + * + * @param array key array + * @param array input array(s) that will overwrite key array values + * @return array + */ + public static function overwrite($array1, $array2) + { + foreach (array_intersect_key($array2, $array1) as $key => $value) + { + $array1[$key] = $value; + } + + if (func_num_args() > 2) + { + foreach (array_slice(func_get_args(), 2) as $array2) + { + foreach (array_intersect_key($array2, $array1) as $key => $value) + { + $array1[$key] = $value; + } + } + } + + return $array1; + } + + /** + * Fill an array with a range of numbers. + * + * @param integer stepping + * @param integer ending number + * @return array + */ + public static function range($step = 10, $max = 100) + { + if ($step < 1) + return array(); + + $array = array(); + for ($i = $step; $i <= $max; $i += $step) + { + $array[$i] = $i; + } + + return $array; + } + + /** + * Recursively convert an array to an object. + * + * @param array array to convert + * @return object + */ + public static function to_object(array $array, $class = 'stdClass') + { + $object = new $class; + + foreach ($array as $key => $value) + { + if (is_array($value)) + { + // Convert the array to an object + $value = arr::to_object($value, $class); + } + + // Add the value to the object + $object->{$key} = $value; + } + + return $object; + } + +} // End arr diff --git a/lib/kohana/system/helpers/cookie.php b/lib/kohana/system/helpers/cookie.php new file mode 100644 index 0000000..d58c25d --- /dev/null +++ b/lib/kohana/system/helpers/cookie.php @@ -0,0 +1,84 @@ +cookie($name, $default, $xss_clean); + } + + /** + * Nullify and unset a cookie. + * + * @param string cookie name + * @param string URL path + * @param string URL domain + * @return boolean + */ + public static function delete($name, $path = NULL, $domain = NULL) + { + if ( ! isset($_COOKIE[$name])) + return FALSE; + + // Delete the cookie from globals + unset($_COOKIE[$name]); + + // Sets the cookie value to an empty string, and the expiration to 24 hours ago + return cookie::set($name, '', -86400, $path, $domain, FALSE, FALSE); + } + +} // End cookie diff --git a/lib/kohana/system/helpers/date.php b/lib/kohana/system/helpers/date.php new file mode 100644 index 0000000..7d5a9ab --- /dev/null +++ b/lib/kohana/system/helpers/date.php @@ -0,0 +1,405 @@ +> 1); + } + + /** + * Converts a DOS timestamp to UNIX format. + * + * @param integer DOS timestamp + * @return integer + */ + public static function dos2unix($timestamp = FALSE) + { + $sec = 2 * ($timestamp & 0x1f); + $min = ($timestamp >> 5) & 0x3f; + $hrs = ($timestamp >> 11) & 0x1f; + $day = ($timestamp >> 16) & 0x1f; + $mon = ($timestamp >> 21) & 0x0f; + $year = ($timestamp >> 25) & 0x7f; + + return mktime($hrs, $min, $sec, $mon, $day, $year + 1980); + } + + /** + * Returns the offset (in seconds) between two time zones. + * @see http://php.net/timezones + * + * @param string timezone that to find the offset of + * @param string|boolean timezone used as the baseline + * @return integer + */ + public static function offset($remote, $local = TRUE) + { + static $offsets; + + // Default values + $remote = (string) $remote; + $local = ($local === TRUE) ? date_default_timezone_get() : (string) $local; + + // Cache key name + $cache = $remote.$local; + + if (empty($offsets[$cache])) + { + // Create timezone objects + $remote = new DateTimeZone($remote); + $local = new DateTimeZone($local); + + // Create date objects from timezones + $time_there = new DateTime('now', $remote); + $time_here = new DateTime('now', $local); + + // Find the offset + $offsets[$cache] = $remote->getOffset($time_there) - $local->getOffset($time_here); + } + + return $offsets[$cache]; + } + + /** + * Number of seconds in a minute, incrementing by a step. + * + * @param integer amount to increment each step by, 1 to 30 + * @param integer start value + * @param integer end value + * @return array A mirrored (foo => foo) array from 1-60. + */ + public static function seconds($step = 1, $start = 0, $end = 60) + { + // Always integer + $step = (int) $step; + + $seconds = array(); + + for ($i = $start; $i < $end; $i += $step) + { + $seconds[$i] = ($i < 10) ? '0'.$i : $i; + } + + return $seconds; + } + + /** + * Number of minutes in an hour, incrementing by a step. + * + * @param integer amount to increment each step by, 1 to 30 + * @return array A mirrored (foo => foo) array from 1-60. + */ + public static function minutes($step = 5) + { + // Because there are the same number of minutes as seconds in this set, + // we choose to re-use seconds(), rather than creating an entirely new + // function. Shhhh, it's cheating! ;) There are several more of these + // in the following methods. + return date::seconds($step); + } + + /** + * Number of hours in a day. + * + * @param integer amount to increment each step by + * @param boolean use 24-hour time + * @param integer the hour to start at + * @return array A mirrored (foo => foo) array from start-12 or start-23. + */ + public static function hours($step = 1, $long = FALSE, $start = NULL) + { + // Default values + $step = (int) $step; + $long = (bool) $long; + $hours = array(); + + // Set the default start if none was specified. + if ($start === NULL) + { + $start = ($long === FALSE) ? 1 : 0; + } + + $hours = array(); + + // 24-hour time has 24 hours, instead of 12 + $size = ($long === TRUE) ? 23 : 12; + + for ($i = $start; $i <= $size; $i += $step) + { + $hours[$i] = $i; + } + + return $hours; + } + + /** + * Returns AM or PM, based on a given hour. + * + * @param integer number of the hour + * @return string + */ + public static function ampm($hour) + { + // Always integer + $hour = (int) $hour; + + return ($hour > 11) ? 'PM' : 'AM'; + } + + /** + * Adjusts a non-24-hour number into a 24-hour number. + * + * @param integer hour to adjust + * @param string AM or PM + * @return string + */ + public static function adjust($hour, $ampm) + { + $hour = (int) $hour; + $ampm = strtolower($ampm); + + switch ($ampm) + { + case 'am': + if ($hour == 12) + $hour = 0; + break; + case 'pm': + if ($hour < 12) + $hour += 12; + break; + } + + return sprintf('%02s', $hour); + } + + /** + * Number of days in month. + * + * @param integer number of month + * @param integer number of year to check month, defaults to the current year + * @return array A mirrored (foo => foo) array of the days. + */ + public static function days($month, $year = FALSE) + { + static $months; + + // Always integers + $month = (int) $month; + $year = (int) $year; + + // Use the current year by default + $year = ($year == FALSE) ? date('Y') : $year; + + // We use caching for months, because time functions are used + if (empty($months[$year][$month])) + { + $months[$year][$month] = array(); + + // Use date to find the number of days in the given month + $total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1; + + for ($i = 1; $i < $total; $i++) + { + $months[$year][$month][$i] = $i; + } + } + + return $months[$year][$month]; + } + + /** + * Number of months in a year + * + * @return array A mirrored (foo => foo) array from 1-12. + */ + public static function months() + { + return date::hours(); + } + + /** + * Returns an array of years between a starting and ending year. + * Uses the current year +/- 5 as the max/min. + * + * @param integer starting year + * @param integer ending year + * @return array + */ + public static function years($start = FALSE, $end = FALSE) + { + // Default values + $start = ($start === FALSE) ? date('Y') - 5 : (int) $start; + $end = ($end === FALSE) ? date('Y') + 5 : (int) $end; + + $years = array(); + + // Add one, so that "less than" works + $end += 1; + + for ($i = $start; $i < $end; $i++) + { + $years[$i] = $i; + } + + return $years; + } + + /** + * Returns time difference between two timestamps, in human readable format. + * + * @param integer timestamp + * @param integer timestamp, defaults to the current time + * @param string formatting string + * @return string|array + */ + public static function timespan($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds') + { + // Array with the output formats + $output = preg_split('/[^a-z]+/', strtolower((string) $output)); + + // Invalid output + if (empty($output)) + return FALSE; + + // Make the output values into keys + extract(array_flip($output), EXTR_SKIP); + + // Default values + $time1 = max(0, (int) $time1); + $time2 = empty($time2) ? time() : max(0, (int) $time2); + + // Calculate timespan (seconds) + $timespan = abs($time1 - $time2); + + // All values found using Google Calculator. + // Years and months do not match the formula exactly, due to leap years. + + // Years ago, 60 * 60 * 24 * 365 + isset($years) and $timespan -= 31556926 * ($years = (int) floor($timespan / 31556926)); + + // Months ago, 60 * 60 * 24 * 30 + isset($months) and $timespan -= 2629744 * ($months = (int) floor($timespan / 2629743.83)); + + // Weeks ago, 60 * 60 * 24 * 7 + isset($weeks) and $timespan -= 604800 * ($weeks = (int) floor($timespan / 604800)); + + // Days ago, 60 * 60 * 24 + isset($days) and $timespan -= 86400 * ($days = (int) floor($timespan / 86400)); + + // Hours ago, 60 * 60 + isset($hours) and $timespan -= 3600 * ($hours = (int) floor($timespan / 3600)); + + // Minutes ago, 60 + isset($minutes) and $timespan -= 60 * ($minutes = (int) floor($timespan / 60)); + + // Seconds ago, 1 + isset($seconds) and $seconds = $timespan; + + // Remove the variables that cannot be accessed + unset($timespan, $time1, $time2); + + // Deny access to these variables + $deny = array_flip(array('deny', 'key', 'difference', 'output')); + + // Return the difference + $difference = array(); + foreach ($output as $key) + { + if (isset($$key) AND ! isset($deny[$key])) + { + // Add requested key to the output + $difference[$key] = $$key; + } + } + + // Invalid output formats string + if (empty($difference)) + return FALSE; + + // If only one output format was asked, don't put it in an array + if (count($difference) === 1) + return current($difference); + + // Return array + return $difference; + } + + /** + * Returns time difference between two timestamps, in the format: + * N year, N months, N weeks, N days, N hours, N minutes, and N seconds ago + * + * @param integer timestamp + * @param integer timestamp, defaults to the current time + * @param string formatting string + * @return string + */ + public static function timespan_string($time1, $time2 = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds') + { + if ($difference = date::timespan($time1, $time2, $output) AND is_array($difference)) + { + // Determine the key of the last item in the array + $last = end($difference); + $last = key($difference); + + $span = array(); + foreach ($difference as $name => $amount) + { + if ($amount === 0) + { + // Skip empty amounts + continue; + } + + // Add the amount to the span + $span[] = ($name === $last ? ' and ' : ', ').$amount.' '.($amount === 1 ? inflector::singular($name) : $name); + } + + // If the difference is less than 60 seconds, remove the preceding and. + if (count($span) === 1) + { + $span[0] = ltrim($span[0], 'and '); + } + + // Replace difference by making the span into a string + $difference = trim(implode('', $span), ','); + } + elseif (is_int($difference)) + { + // Single-value return + $difference = $difference.' '.($difference === 1 ? inflector::singular($output) : $output); + } + + return $difference; + } + +} // End date \ No newline at end of file diff --git a/lib/kohana/system/helpers/download.php b/lib/kohana/system/helpers/download.php new file mode 100644 index 0000000..49fed42 --- /dev/null +++ b/lib/kohana/system/helpers/download.php @@ -0,0 +1,105 @@ +setUsername($config['options']['username']); + empty($config['options']['password']) or $connection->setPassword($config['options']['password']); + + if ( ! empty($config['options']['auth'])) + { + // Get the class name and params + list ($class, $params) = arr::callback_string($config['options']['auth']); + + if ($class === 'PopB4Smtp') + { + // Load the PopB4Smtp class manually, due to its odd filename + require Kohana::find_file('vendor', 'swift/Swift/Authenticator/$PopB4Smtp$'); + } + + // Prepare the class name for auto-loading + $class = 'Swift_Authenticator_'.$class; + + // Attach the authenticator + $connection->attachAuthenticator(($params === NULL) ? new $class : new $class($params[0])); + } + + // Set the timeout to 5 seconds + $connection->setTimeout(empty($config['options']['timeout']) ? 5 : (int) $config['options']['timeout']); + break; + case 'sendmail': + // Create a sendmail connection + $connection = new Swift_Connection_Sendmail + ( + empty($config['options']) ? Swift_Connection_Sendmail::AUTO_DETECT : $config['options'] + ); + + // Set the timeout to 5 seconds + $connection->setTimeout(5); + break; + default: + // Use the native connection + $connection = new Swift_Connection_NativeMail($config['options']); + break; + } + + // Create the SwiftMailer instance + return email::$mail = new Swift($connection); + } + + /** + * Send an email message. + * + * @param string|array recipient email (and name), or an array of To, Cc, Bcc names + * @param string|array sender email (and name) + * @param string message subject + * @param string message body + * @param boolean send email as HTML + * @return integer number of emails sent + */ + public static function send($to, $from, $subject, $message, $html = FALSE) + { + // Connect to SwiftMailer + (email::$mail === NULL) and email::connect(); + + // Determine the message type + $html = ($html === TRUE) ? 'text/html' : 'text/plain'; + + // Create the message + $message = new Swift_Message($subject, $message, $html, '8bit', 'utf-8'); + + if (is_string($to)) + { + // Single recipient + $recipients = new Swift_Address($to); + } + elseif (is_array($to)) + { + if (isset($to[0]) AND isset($to[1])) + { + // Create To: address set + $to = array('to' => $to); + } + + // Create a list of recipients + $recipients = new Swift_RecipientList; + + foreach ($to as $method => $set) + { + if ( ! in_array($method, array('to', 'cc', 'bcc'))) + { + // Use To: by default + $method = 'to'; + } + + // Create method name + $method = 'add'.ucfirst($method); + + if (is_array($set)) + { + // Add a recipient with name + $recipients->$method($set[0], $set[1]); + } + else + { + // Add a recipient without name + $recipients->$method($set); + } + } + } + + if (is_string($from)) + { + // From without a name + $from = new Swift_Address($from); + } + elseif (is_array($from)) + { + // From with a name + $from = new Swift_Address($from[0], $from[1]); + } + + return email::$mail->send($message, $recipients, $from); + } + +} // End email \ No newline at end of file diff --git a/lib/kohana/system/helpers/expires.php b/lib/kohana/system/helpers/expires.php new file mode 100644 index 0000000..c43cc0c --- /dev/null +++ b/lib/kohana/system/helpers/expires.php @@ -0,0 +1,111 @@ + 0) + { + // Re-send headers + header('Last-Modified: '.gmdate('D, d M Y H:i:s T', $mod_time)); + header('Expires: '.gmdate('D, d M Y H:i:s T', time() + $mod_time_diff)); + header('Cache-Control: max-age='.$mod_time_diff); + header('Status: 304 Not Modified', TRUE, 304); + + // Prevent any output + Event::add('system.display', array('expires', 'prevent_output')); + + // Exit to prevent other output + exit; + } + } + + return FALSE; + } + + /** + * Check headers already created to not step on download or Img_lib's feet + * + * @return boolean + */ + public static function check_headers() + { + foreach (headers_list() as $header) + { + if ((session_cache_limiter() == '' AND stripos($header, 'Last-Modified:') === 0) + OR stripos($header, 'Expires:') === 0) + { + return FALSE; + } + } + + return TRUE; + } + + /** + * Prevent any output from being displayed. Executed during system.display. + * + * @return void + */ + public static function prevent_output() + { + Kohana::$output = ''; + } + +} // End expires \ No newline at end of file diff --git a/lib/kohana/system/helpers/feed.php b/lib/kohana/system/helpers/feed.php new file mode 100644 index 0000000..74bb2f6 --- /dev/null +++ b/lib/kohana/system/helpers/feed.php @@ -0,0 +1,122 @@ +channel) ? $feed->xpath('//item') : $feed->entry; + + $i = 0; + $items = array(); + + foreach ($feed as $item) + { + if ($limit > 0 AND $i++ === $limit) + break; + + $items[] = (array) $item; + } + + return $items; + } + + /** + * Creates a feed from the given parameters. + * + * @param array feed information + * @param array items to add to the feed + * @param string define which format to use + * @param string define which encoding to use + * @return string + */ + public static function create($info, $items, $format = 'rss2', $encoding = 'UTF-8') + { + $info += array('title' => 'Generated Feed', 'link' => '', 'generator' => 'KohanaPHP'); + + $feed = ''; + $feed = simplexml_load_string($feed); + + foreach ($info as $name => $value) + { + if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value))) + { + // Convert timestamps to RFC 822 formatted dates + $value = date(DATE_RFC822, $value); + } + elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE) + { + // Convert URIs to URLs + $value = url::site($value, 'http'); + } + + // Add the info to the channel + $feed->channel->addChild($name, $value); + } + + foreach ($items as $item) + { + // Add the item to the channel + $row = $feed->channel->addChild('item'); + + foreach ($item as $name => $value) + { + if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value))) + { + // Convert timestamps to RFC 822 formatted dates + $value = date(DATE_RFC822, $value); + } + elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE) + { + // Convert URIs to URLs + $value = url::site($value, 'http'); + } + + // Add the info to the row + $row->addChild($name, $value); + } + } + + return $feed->asXML(); + } + +} // End feed \ No newline at end of file diff --git a/lib/kohana/system/helpers/file.php b/lib/kohana/system/helpers/file.php new file mode 100644 index 0000000..b1b7174 --- /dev/null +++ b/lib/kohana/system/helpers/file.php @@ -0,0 +1,186 @@ +'."\n"; + + // Add hidden fields immediate after opening tag + empty($hidden) or $form .= form::hidden($hidden); + + return $form; + } + + /** + * Generates an opening HTML form tag that can be used for uploading files. + * + * @param string form action attribute + * @param array extra attributes + * @param array hidden fields to be created immediately after the form tag + * @return string + */ + public static function open_multipart($action = NULL, $attr = array(), $hidden = array()) + { + // Set multi-part form type + $attr['enctype'] = 'multipart/form-data'; + + return form::open($action, $attr, $hidden); + } + + /** + * Generates a fieldset opening tag. + * + * @param array html attributes + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function open_fieldset($data = NULL, $extra = '') + { + return ''."\n"; + } + + /** + * Generates a fieldset closing tag. + * + * @return string + */ + public static function close_fieldset() + { + return ''."\n"; + } + + /** + * Generates a legend tag for use with a fieldset. + * + * @param string legend text + * @param array HTML attributes + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function legend($text = '', $data = NULL, $extra = '') + { + return ''.$text.''."\n"; + } + + /** + * Generates hidden form fields. + * You can pass a simple key/value string or an associative array with multiple values. + * + * @param string|array input name (string) or key/value pairs (array) + * @param string input value, if using an input name + * @return string + */ + public static function hidden($data, $value = '') + { + if ( ! is_array($data)) + { + $data = array + ( + $data => $value + ); + } + + $input = ''; + foreach ($data as $name => $value) + { + $attr = array + ( + 'type' => 'hidden', + 'name' => $name, + 'value' => $value + ); + + $input .= form::input($attr)."\n"; + } + + return $input; + } + + /** + * Creates an HTML form input tag. Defaults to a text type. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function input($data, $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + // Type and value are required attributes + $data += array + ( + 'type' => 'text', + 'value' => $value + ); + + return ''; + } + + /** + * Creates a HTML form password input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function password($data, $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'password'; + + return form::input($data, $value, $extra); + } + + /** + * Creates an HTML form upload input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function upload($data, $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'file'; + + return form::input($data, $value, $extra); + } + + /** + * Creates an HTML form textarea tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @param boolean encode existing entities + * @return string + */ + public static function textarea($data, $value = '', $extra = '', $double_encode = TRUE) + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + // Use the value from $data if possible, or use $value + $value = isset($data['value']) ? $data['value'] : $value; + + // Value is not part of the attributes + unset($data['value']); + + return ''.html::specialchars($value, $double_encode).''; + } + + /** + * Creates an HTML form select tag, or "dropdown menu". + * + * @param string|array input name or an array of HTML attributes + * @param array select options, when using a name + * @param string|array option key(s) that should be selected by default + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function dropdown($data, $options = NULL, $selected = NULL, $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + else + { + if (isset($data['options'])) + { + // Use data options + $options = $data['options']; + } + + if (isset($data['selected'])) + { + // Use data selected + $selected = $data['selected']; + } + } + + if (is_array($selected)) + { + // Multi-select box + $data['multiple'] = 'multiple'; + } + else + { + // Single selection (but converted to an array) + $selected = array($selected); + } + + $input = ''."\n"; + foreach ((array) $options as $key => $val) + { + // Key should always be a string + $key = (string) $key; + + if (is_array($val)) + { + $input .= ''."\n"; + foreach ($val as $inner_key => $inner_val) + { + // Inner key should always be a string + $inner_key = (string) $inner_key; + + $sel = in_array($inner_key, $selected) ? ' selected="selected"' : ''; + $input .= ''."\n"; + } + $input .= ''."\n"; + } + else + { + $sel = in_array($key, $selected) ? ' selected="selected"' : ''; + $input .= ''."\n"; + } + } + $input .= ''; + + return $input; + } + + /** + * Creates an HTML form checkbox input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param boolean make the checkbox checked by default + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function checkbox($data, $value = '', $checked = FALSE, $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'checkbox'; + + if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE)) + { + $data['checked'] = 'checked'; + } + else + { + unset($data['checked']); + } + + return form::input($data, $value, $extra); + } + + /** + * Creates an HTML form radio input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param boolean make the radio selected by default + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function radio($data = '', $value = '', $checked = FALSE, $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + $data['type'] = 'radio'; + + if ($checked == TRUE OR (isset($data['checked']) AND $data['checked'] == TRUE)) + { + $data['checked'] = 'checked'; + } + else + { + unset($data['checked']); + } + + return form::input($data, $value, $extra); + } + + /** + * Creates an HTML form submit input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function submit($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + if (empty($data['name'])) + { + // Remove the name if it is empty + unset($data['name']); + } + + $data['type'] = 'submit'; + + return form::input($data, $value, $extra); + } + + /** + * Creates an HTML form button input tag. + * + * @param string|array input name or an array of HTML attributes + * @param string input value, when using a name + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function button($data = '', $value = '', $extra = '') + { + if ( ! is_array($data)) + { + $data = array('name' => $data); + } + + if (empty($data['name'])) + { + // Remove the name if it is empty + unset($data['name']); + } + + if (isset($data['value']) AND empty($value)) + { + $value = arr::remove('value', $data); + } + + return ''.$value.''; + } + + /** + * Closes an open form tag. + * + * @param string string to be attached after the closing tag + * @return string + */ + public static function close($extra = '') + { + return ''."\n".$extra; + } + + /** + * Creates an HTML form label tag. + * + * @param string|array label "for" name or an array of HTML attributes + * @param string label text or HTML + * @param string a string to be attached to the end of the attributes + * @return string + */ + public static function label($data = '', $text = NULL, $extra = '') + { + if ( ! is_array($data)) + { + if (is_string($data)) + { + // Specify the input this label is for + $data = array('for' => $data); + } + else + { + // No input specified + $data = array(); + } + } + + if ($text === NULL AND isset($data['for'])) + { + // Make the text the human-readable input name + $text = ucwords(inflector::humanize($data['for'])); + } + + return ''.$text.''; + } + + /** + * Sorts a key/value array of HTML attributes, putting form attributes first, + * and returns an attribute string. + * + * @param array HTML attributes array + * @return string + */ + public static function attributes($attr, $type = NULL) + { + if (empty($attr)) + return ''; + + if (isset($attr['name']) AND empty($attr['id']) AND strpos($attr['name'], '[') === FALSE) + { + if ($type === NULL AND ! empty($attr['type'])) + { + // Set the type by the attributes + $type = $attr['type']; + } + + switch ($type) + { + case 'text': + case 'textarea': + case 'password': + case 'select': + case 'checkbox': + case 'file': + case 'image': + case 'button': + case 'submit': + // Only specific types of inputs use name to id matching + $attr['id'] = $attr['name']; + break; + } + } + + $order = array + ( + 'action', + 'method', + 'type', + 'id', + 'name', + 'value', + 'src', + 'size', + 'maxlength', + 'rows', + 'cols', + 'accept', + 'tabindex', + 'accesskey', + 'align', + 'alt', + 'title', + 'class', + 'style', + 'selected', + 'checked', + 'readonly', + 'disabled' + ); + + $sorted = array(); + foreach ($order as $key) + { + if (isset($attr[$key])) + { + // Move the attribute to the sorted array + $sorted[$key] = $attr[$key]; + + // Remove the attribute from unsorted array + unset($attr[$key]); + } + } + + // Combine the sorted and unsorted attributes and create an HTML string + return html::attributes(array_merge($sorted, $attr)); + } + +} // End form \ No newline at end of file diff --git a/lib/kohana/system/helpers/format.php b/lib/kohana/system/helpers/format.php new file mode 100644 index 0000000..fb8a029 --- /dev/null +++ b/lib/kohana/system/helpers/format.php @@ -0,0 +1,66 @@ +=')) + { + $str = htmlspecialchars($str, ENT_QUOTES, 'UTF-8', FALSE); + } + else + { + $str = preg_replace('/&(?!(?:#\d++|[a-z]++);)/ui', '&', $str); + $str = str_replace(array('<', '>', '\'', '"'), array('<', '>', ''', '"'), $str); + } + } + + return $str; + } + + /** + * Perform a html::specialchars() with additional URL specific encoding. + * + * @param string string to convert + * @param boolean encode existing entities + * @return string + */ + public static function specialurlencode($str, $double_encode = TRUE) + { + return str_replace(' ', '%20', html::specialchars($str, $double_encode)); + } + + /** + * Create HTML link anchors. + * + * @param string URL or URI string + * @param string link text + * @param array HTML anchor attributes + * @param string non-default protocol, eg: https + * @param boolean option to escape the title that is output + * @return string + */ + public static function anchor($uri, $title = NULL, $attributes = NULL, $protocol = NULL, $escape_title = FALSE) + { + if ($uri === '') + { + $site_url = url::base(FALSE); + } + elseif (strpos($uri, '#') === 0) + { + // This is an id target link, not a URL + $site_url = $uri; + } + elseif (strpos($uri, '://') === FALSE) + { + $site_url = url::site($uri, $protocol); + } + else + { + if (html::$windowed_urls === TRUE AND empty($attributes['target'])) + { + $attributes['target'] = '_blank'; + } + + $site_url = $uri; + } + + return + // Parsed URL + '' + // Title empty? Use the parsed URL + .($escape_title ? html::specialchars((($title === NULL) ? $site_url : $title), FALSE) : (($title === NULL) ? $site_url : $title)).''; + } + + /** + * Creates an HTML anchor to a file. + * + * @param string name of file to link to + * @param string link text + * @param array HTML anchor attributes + * @param string non-default protocol, eg: ftp + * @return string + */ + public static function file_anchor($file, $title = NULL, $attributes = NULL, $protocol = NULL) + { + return + // Base URL + URI = full URL + '' + // Title empty? Use the filename part of the URI + .(($title === NULL) ? end(explode('/', $file)) : $title) .''; + } + + /** + * Similar to anchor, but with the protocol parameter first. + * + * @param string link protocol + * @param string URI or URL to link to + * @param string link text + * @param array HTML anchor attributes + * @return string + */ + public static function panchor($protocol, $uri, $title = NULL, $attributes = FALSE) + { + return html::anchor($uri, $title, $attributes, $protocol); + } + + /** + * Create an array of anchors from an array of link/title pairs. + * + * @param array link/title pairs + * @return array + */ + public static function anchor_array(array $array) + { + $anchors = array(); + foreach ($array as $link => $title) + { + // Create list of anchors + $anchors[] = html::anchor($link, $title); + } + return $anchors; + } + + /** + * Generates an obfuscated version of an email address. + * + * @param string email address + * @return string + */ + public static function email($email) + { + $safe = ''; + foreach (str_split($email) as $letter) + { + switch (($letter === '@') ? rand(1, 2) : rand(1, 3)) + { + // HTML entity code + case 1: $safe .= '&#'.ord($letter).';'; break; + // Hex character code + case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break; + // Raw (no) encoding + case 3: $safe .= $letter; + } + } + + return $safe; + } + + /** + * Creates an email anchor. + * + * @param string email address to send to + * @param string link text + * @param array HTML anchor attributes + * @return string + */ + public static function mailto($email, $title = NULL, $attributes = NULL) + { + if (empty($email)) + return $title; + + // Remove the subject or other parameters that do not need to be encoded + if (strpos($email, '?') !== FALSE) + { + // Extract the parameters from the email address + list ($email, $params) = explode('?', $email, 2); + + // Make the params into a query string, replacing spaces + $params = '?'.str_replace(' ', '%20', $params); + } + else + { + // No parameters + $params = ''; + } + + // Obfuscate email address + $safe = html::email($email); + + // Title defaults to the encoded email address + empty($title) and $title = $safe; + + // Parse attributes + empty($attributes) or $attributes = html::attributes($attributes); + + // Encoded start of the href="" is a static encoded version of 'mailto:' + return ''.$title.''; + } + + /** + * Generate a "breadcrumb" list of anchors representing the URI. + * + * @param array segments to use as breadcrumbs, defaults to using Router::$segments + * @return string + */ + public static function breadcrumb($segments = NULL) + { + empty($segments) and $segments = Router::$segments; + + $array = array(); + while ($segment = array_pop($segments)) + { + $array[] = html::anchor + ( + // Complete URI for the URL + implode('/', $segments).'/'.$segment, + // Title for the current segment + ucwords(inflector::humanize($segment)) + ); + } + + // Retrun the array of all the segments + return array_reverse($array); + } + + /** + * Creates a meta tag. + * + * @param string|array tag name, or an array of tags + * @param string tag "content" value + * @return string + */ + public static function meta($tag, $value = NULL) + { + if (is_array($tag)) + { + $tags = array(); + foreach ($tag as $t => $v) + { + // Build each tag and add it to the array + $tags[] = html::meta($t, $v); + } + + // Return all of the tags as a string + return implode("\n", $tags); + } + + // Set the meta attribute value + $attr = in_array(strtolower($tag), Kohana::config('http.meta_equiv')) ? 'http-equiv' : 'name'; + + return ''; + } + + /** + * Creates a stylesheet link. + * + * @param string|array filename, or array of filenames to match to array of medias + * @param string|array media type of stylesheet, or array to match filenames + * @param boolean include the index_page in the link + * @return string + */ + public static function stylesheet($style, $media = FALSE, $index = FALSE) + { + return html::link($style, 'stylesheet', 'text/css', '.css', $media, $index); + } + + /** + * Creates a link tag. + * + * @param string|array filename + * @param string|array relationship + * @param string|array mimetype + * @param string specifies suffix of the file + * @param string|array specifies on what device the document will be displayed + * @param boolean include the index_page in the link + * @return string + */ + public static function link($href, $rel, $type, $suffix = FALSE, $media = FALSE, $index = FALSE) + { + $compiled = ''; + + if (is_array($href)) + { + foreach ($href as $_href) + { + $_rel = is_array($rel) ? array_shift($rel) : $rel; + $_type = is_array($type) ? array_shift($type) : $type; + $_media = is_array($media) ? array_shift($media) : $media; + + $compiled .= html::link($_href, $_rel, $_type, $suffix, $_media, $index); + } + } + else + { + if (strpos($href, '://') === FALSE) + { + // Make the URL absolute + $href = url::base($index).$href; + } + + $length = strlen($suffix); + + if ( $length > 0 AND substr_compare($href, $suffix, -$length, $length, FALSE) !== 0) + { + // Add the defined suffix + $href .= $suffix; + } + + $attr = array + ( + 'rel' => $rel, + 'type' => $type, + 'href' => $href, + ); + + if ( ! empty($media)) + { + // Add the media type to the attributes + $attr['media'] = $media; + } + + $compiled = ''; + } + + return $compiled."\n"; + } + + /** + * Creates a script link. + * + * @param string|array filename + * @param boolean include the index_page in the link + * @return string + */ + public static function script($script, $index = FALSE) + { + $compiled = ''; + + if (is_array($script)) + { + foreach ($script as $name) + { + $compiled .= html::script($name, $index); + } + } + else + { + if (strpos($script, '://') === FALSE) + { + // Add the suffix only when it's not already present + $script = url::base((bool) $index).$script; + } + + if (substr_compare($script, '.js', -3, 3, FALSE) !== 0) + { + // Add the javascript suffix + $script .= '.js'; + } + + $compiled = ''; + } + + return $compiled."\n"; + } + + /** + * Creates a image link. + * + * @param string image source, or an array of attributes + * @param string|array image alt attribute, or an array of attributes + * @param boolean include the index_page in the link + * @return string + */ + public static function image($src = NULL, $alt = NULL, $index = FALSE) + { + // Create attribute list + $attributes = is_array($src) ? $src : array('src' => $src); + + if (is_array($alt)) + { + $attributes += $alt; + } + elseif ( ! empty($alt)) + { + // Add alt to attributes + $attributes['alt'] = $alt; + } + + if (strpos($attributes['src'], '://') === FALSE) + { + // Make the src attribute into an absolute URL + $attributes['src'] = url::base($index).$attributes['src']; + } + + return ''; + } + + /** + * Compiles an array of HTML attributes into an attribute string. + * + * @param string|array array of attributes + * @return string + */ + public static function attributes($attrs) + { + if (empty($attrs)) + return ''; + + if (is_string($attrs)) + return ' '.$attrs; + + $compiled = ''; + foreach ($attrs as $key => $val) + { + $compiled .= ' '.$key.'="'.html::specialchars($val).'"'; + } + + return $compiled; + } + +} // End html diff --git a/lib/kohana/system/helpers/inflector.php b/lib/kohana/system/helpers/inflector.php new file mode 100644 index 0000000..1e4fee2 --- /dev/null +++ b/lib/kohana/system/helpers/inflector.php @@ -0,0 +1,193 @@ + 1) + return $str; + + // Cache key name + $key = 'singular_'.$str.$count; + + if (isset(inflector::$cache[$key])) + return inflector::$cache[$key]; + + if (inflector::uncountable($str)) + return inflector::$cache[$key] = $str; + + if (empty(inflector::$irregular)) + { + // Cache irregular words + inflector::$irregular = Kohana::config('inflector.irregular'); + } + + if ($irregular = array_search($str, inflector::$irregular)) + { + $str = $irregular; + } + elseif (preg_match('/[sxz]es$/', $str) OR preg_match('/[^aeioudgkprt]hes$/', $str)) + { + // Remove "es" + $str = substr($str, 0, -2); + } + elseif (preg_match('/[^aeiou]ies$/', $str)) + { + $str = substr($str, 0, -3).'y'; + } + elseif (substr($str, -1) === 's' AND substr($str, -2) !== 'ss') + { + $str = substr($str, 0, -1); + } + + return inflector::$cache[$key] = $str; + } + + /** + * Makes a singular word plural. + * + * @param string word to pluralize + * @return string + */ + public static function plural($str, $count = NULL) + { + // Remove garbage + $str = strtolower(trim($str)); + + if (is_string($count)) + { + // Convert to integer when using a digit string + $count = (int) $count; + } + + // Do nothing with singular + if ($count === 1) + return $str; + + // Cache key name + $key = 'plural_'.$str.$count; + + if (isset(inflector::$cache[$key])) + return inflector::$cache[$key]; + + if (inflector::uncountable($str)) + return inflector::$cache[$key] = $str; + + if (empty(inflector::$irregular)) + { + // Cache irregular words + inflector::$irregular = Kohana::config('inflector.irregular'); + } + + if (isset(inflector::$irregular[$str])) + { + $str = inflector::$irregular[$str]; + } + elseif (preg_match('/[sxz]$/', $str) OR preg_match('/[^aeioudgkprt]h$/', $str)) + { + $str .= 'es'; + } + elseif (preg_match('/[^aeiou]y$/', $str)) + { + // Change "y" to "ies" + $str = substr_replace($str, 'ies', -1); + } + else + { + $str .= 's'; + } + + // Set the cache and return + return inflector::$cache[$key] = $str; + } + + /** + * Makes a phrase camel case. + * + * @param string phrase to camelize + * @return string + */ + public static function camelize($str) + { + $str = 'x'.strtolower(trim($str)); + $str = ucwords(preg_replace('/[\s_]+/', ' ', $str)); + + return substr(str_replace(' ', '', $str), 1); + } + + /** + * Makes a phrase underscored instead of spaced. + * + * @param string phrase to underscore + * @return string + */ + public static function underscore($str) + { + return preg_replace('/\s+/', '_', trim($str)); + } + + /** + * Makes an underscored or dashed phrase human-reable. + * + * @param string phrase to make human-reable + * @return string + */ + public static function humanize($str) + { + return preg_replace('/[_-]+/', ' ', trim($str)); + } + +} // End inflector \ No newline at end of file diff --git a/lib/kohana/system/helpers/num.php b/lib/kohana/system/helpers/num.php new file mode 100644 index 0000000..3eb5d5a --- /dev/null +++ b/lib/kohana/system/helpers/num.php @@ -0,0 +1,26 @@ + 0); + } + + /** + * Compare the q values for given array of content types and return the one with the highest value. + * If items are found to have the same q value, the first one encountered in the given array wins. + * If all items in the given array have a q value of 0, FALSE is returned. + * + * @param array content types + * @param boolean set to TRUE to disable wildcard checking + * @return mixed string mime type with highest q value, FALSE if none of the given types are accepted + */ + public static function preferred_accept($types, $explicit_check = FALSE) + { + // Initialize + $mime_types = array(); + $max_q = 0; + $preferred = FALSE; + + // Load q values for all given content types + foreach (array_unique($types) as $type) + { + $mime_types[$type] = request::accepts_at_quality($type, $explicit_check); + } + + // Look for the highest q value + foreach ($mime_types as $type => $q) + { + if ($q > $max_q) + { + $max_q = $q; + $preferred = $type; + } + } + + return $preferred; + } + + /** + * Returns quality factor at which the client accepts content type. + * + * @param string content type (e.g. "image/jpg", "jpg") + * @param boolean set to TRUE to disable wildcard checking + * @return integer|float + */ + public static function accepts_at_quality($type = NULL, $explicit_check = FALSE) + { + request::parse_accept_header(); + + // Normalize type + $type = strtolower((string) $type); + + // General content type (e.g. "jpg") + if (strpos($type, '/') === FALSE) + { + // Don't accept anything by default + $q = 0; + + // Look up relevant mime types + foreach ((array) Kohana::config('mimes.'.$type) as $type) + { + $q2 = request::accepts_at_quality($type, $explicit_check); + $q = ($q2 > $q) ? $q2 : $q; + } + + return $q; + } + + // Content type with subtype given (e.g. "image/jpg") + $type = explode('/', $type, 2); + + // Exact match + if (isset(request::$accept_types[$type[0]][$type[1]])) + return request::$accept_types[$type[0]][$type[1]]; + + // Wildcard match (if not checking explicitly) + if ($explicit_check === FALSE AND isset(request::$accept_types[$type[0]]['*'])) + return request::$accept_types[$type[0]]['*']; + + // Catch-all wildcard match (if not checking explicitly) + if ($explicit_check === FALSE AND isset(request::$accept_types['*']['*'])) + return request::$accept_types['*']['*']; + + // Content type not accepted + return 0; + } + + /** + * Parses client's HTTP Accept request header, and builds array structure representing it. + * + * @return void + */ + protected static function parse_accept_header() + { + // Run this function just once + if (request::$accept_types !== NULL) + return; + + // Initialize accept_types array + request::$accept_types = array(); + + // No HTTP Accept header found + if (empty($_SERVER['HTTP_ACCEPT'])) + { + // Accept everything + request::$accept_types['*']['*'] = 1; + return; + } + + // Remove linebreaks and parse the HTTP Accept header + foreach (explode(',', str_replace(array("\r", "\n"), '', $_SERVER['HTTP_ACCEPT'])) as $accept_entry) + { + // Explode each entry in content type and possible quality factor + $accept_entry = explode(';', trim($accept_entry), 2); + + // Explode each content type (e.g. "text/html") + $type = explode('/', $accept_entry[0], 2); + + // Skip invalid content types + if ( ! isset($type[1])) + continue; + + // Assume a default quality factor of 1 if no custom q value found + $q = (isset($accept_entry[1]) AND preg_match('~\bq\s*+=\s*+([.0-9]+)~', $accept_entry[1], $match)) ? (float) $match[1] : 1; + + // Populate accept_types array + if ( ! isset(request::$accept_types[$type[0]][$type[1]]) OR $q > request::$accept_types[$type[0]][$type[1]]) + { + request::$accept_types[$type[0]][$type[1]] = $q; + } + } + } + +} // End request \ No newline at end of file diff --git a/lib/kohana/system/helpers/security.php b/lib/kohana/system/helpers/security.php new file mode 100644 index 0000000..cd48d2e --- /dev/null +++ b/lib/kohana/system/helpers/security.php @@ -0,0 +1,47 @@ +xss_clean($str); + } + + /** + * Remove image tags from a string. + * + * @param string string to sanitize + * @return string + */ + public static function strip_image_tags($str) + { + return preg_replace('#\s]*)["\']?[^>]*)?>#is', '$1', $str); + } + + /** + * Remove PHP tags from a string. + * + * @param string string to sanitize + * @return string + */ + public static function encode_php_tags($str) + { + return str_replace(array(''), array('<?', '?>'), $str); + } + +} // End security \ No newline at end of file diff --git a/lib/kohana/system/helpers/text.php b/lib/kohana/system/helpers/text.php new file mode 100644 index 0000000..d0e573e --- /dev/null +++ b/lib/kohana/system/helpers/text.php @@ -0,0 +1,410 @@ + 1) + { + if (ctype_alpha($str)) + { + // Add a random digit + $str[mt_rand(0, $length - 1)] = chr(mt_rand(48, 57)); + } + elseif (ctype_digit($str)) + { + // Add a random letter + $str[mt_rand(0, $length - 1)] = chr(mt_rand(65, 90)); + } + } + + return $str; + } + + /** + * Reduces multiple slashes in a string to single slashes. + * + * @param string string to reduce slashes of + * @return string + */ + public static function reduce_slashes($str) + { + return preg_replace('#(? $badword) + { + $badwords[$key] = str_replace('\*', '\S*?', preg_quote((string) $badword)); + } + + $regex = '('.implode('|', $badwords).')'; + + if ($replace_partial_words == TRUE) + { + // Just using \b isn't sufficient when we need to replace a badword that already contains word boundaries itself + $regex = '(?<=\b|\s|^)'.$regex.'(?=\b|\s|$)'; + } + + $regex = '!'.$regex.'!ui'; + + if (utf8::strlen($replacement) == 1) + { + $regex .= 'e'; + return preg_replace($regex, 'str_repeat($replacement, utf8::strlen(\'$1\'))', $str); + } + + return preg_replace($regex, $replacement, $str); + } + + /** + * Finds the text that is similar between a set of words. + * + * @param array words to find similar text of + * @return string + */ + public static function similar(array $words) + { + // First word is the word to match against + $word = current($words); + + for ($i = 0, $max = strlen($word); $i < $max; ++$i) + { + foreach ($words as $w) + { + // Once a difference is found, break out of the loops + if ( ! isset($w[$i]) OR $w[$i] !== $word[$i]) + break 2; + } + } + + // Return the similar text + return substr($word, 0, $i); + } + + /** + * Converts text email addresses and anchors into links. + * + * @param string text to auto link + * @return string + */ + public static function auto_link($text) + { + // Auto link emails first to prevent problems with "www.domain.com@example.com" + return text::auto_link_urls(text::auto_link_emails($text)); + } + + /** + * Converts text anchors into links. + * + * @param string text to auto link + * @return string + */ + public static function auto_link_urls($text) + { + // Finds all http/https/ftp/ftps links that are not part of an existing html anchor + if (preg_match_all('~\b(?)(?:ht|f)tps?://\S+(?:/|\b)~i', $text, $matches)) + { + foreach ($matches[0] as $match) + { + // Replace each link with an anchor + $text = str_replace($match, html::anchor($match), $text); + } + } + + // Find all naked www.links.com (without http://) + if (preg_match_all('~\b(?|58;)(?!\.)[-+_a-z0-9.]++(? and
    markup to text. Basically nl2br() on steroids. + * + * @param string subject + * @return string + */ + public static function auto_p($str) + { + // Trim whitespace + if (($str = trim($str)) === '') + return ''; + + // Standardize newlines + $str = str_replace(array("\r\n", "\r"), "\n", $str); + + // Trim whitespace on each line + $str = preg_replace('~^[ \t]+~m', '', $str); + $str = preg_replace('~[ \t]+$~m', '', $str); + + // The following regexes only need to be executed if the string contains html + if ($html_found = (strpos($str, '<') !== FALSE)) + { + // Elements that should not be surrounded by p tags + $no_p = '(?:p|div|h[1-6r]|ul|ol|li|blockquote|d[dlt]|pre|t[dhr]|t(?:able|body|foot|head)|c(?:aption|olgroup)|form|s(?:elect|tyle)|a(?:ddress|rea)|ma(?:p|th))'; + + // Put at least two linebreaks before and after $no_p elements + $str = preg_replace('~^<'.$no_p.'[^>]*+>~im', "\n$0", $str); + $str = preg_replace('~$~im', "$0\n", $str); + } + + // Do the

    magic! + $str = '

    '.trim($str).'

    '; + $str = preg_replace('~\n{2,}~', "

    \n\n

    ", $str); + + // The following regexes only need to be executed if the string contains html + if ($html_found !== FALSE) + { + // Remove p tags around $no_p elements + $str = preg_replace('~

    (?=]*+>)~i', '', $str); + $str = preg_replace('~(]*+>)

    ~i', '$1', $str); + } + + // Convert single linebreaks to
    + $str = preg_replace('~(?\n", $str); + + return $str; + } + + /** + * Returns human readable sizes. + * @see Based on original functions written by: + * @see Aidan Lister: http://aidanlister.com/repos/v/function.size_readable.php + * @see Quentin Zervaas: http://www.phpriot.com/d/code/strings/filesize-format/ + * + * @param integer size in bytes + * @param string a definitive unit + * @param string the return string format + * @param boolean whether to use SI prefixes or IEC + * @return string + */ + public static function bytes($bytes, $force_unit = NULL, $format = NULL, $si = TRUE) + { + // Format string + $format = ($format === NULL) ? '%01.2f %s' : (string) $format; + + // IEC prefixes (binary) + if ($si == FALSE OR strpos($force_unit, 'i') !== FALSE) + { + $units = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'); + $mod = 1024; + } + // SI prefixes (decimal) + else + { + $units = array('B', 'kB', 'MB', 'GB', 'TB', 'PB'); + $mod = 1000; + } + + // Determine unit to use + if (($power = array_search((string) $force_unit, $units)) === FALSE) + { + $power = ($bytes > 0) ? floor(log($bytes, $mod)) : 0; + } + + return sprintf($format, $bytes / pow($mod, $power), $units[$power]); + } + + /** + * Prevents widow words by inserting a non-breaking space between the last two words. + * @see http://www.shauninman.com/archive/2006/08/22/widont_wordpress_plugin + * + * @param string string to remove widows from + * @return string + */ + public static function widont($str) + { + $str = rtrim($str); + $space = strrpos($str, ' '); + + if ($space !== FALSE) + { + $str = substr($str, 0, $space).' '.substr($str, $space + 1); + } + + return $str; + } + +} // End text \ No newline at end of file diff --git a/lib/kohana/system/helpers/upload.php b/lib/kohana/system/helpers/upload.php new file mode 100644 index 0000000..422e9e8 --- /dev/null +++ b/lib/kohana/system/helpers/upload.php @@ -0,0 +1,162 @@ + 'Refresh', + '300' => 'Multiple Choices', + '301' => 'Moved Permanently', + '302' => 'Found', + '303' => 'See Other', + '304' => 'Not Modified', + '305' => 'Use Proxy', + '307' => 'Temporary Redirect' + ); + + // Validate the method and default to 302 + $method = isset($codes[$method]) ? (string) $method : '302'; + + if ($method === '300') + { + $uri = (array) $uri; + + $output = '
      '; + foreach ($uri as $link) + { + $output .= '
    • '.html::anchor($link).'
    • '; + } + $output .= '
    '; + + // The first URI will be used for the Location header + $uri = $uri[0]; + } + else + { + $output = '

    '.html::anchor($uri).'

    '; + } + + // Run the redirect event + Event::run('system.redirect', $uri); + + if (strpos($uri, '://') === FALSE) + { + // HTTP headers expect absolute URLs + $uri = url::site($uri, request::protocol()); + } + + if ($method === 'refresh') + { + header('Refresh: 0; url='.$uri); + } + else + { + header('HTTP/1.1 '.$method.' '.$codes[$method]); + header('Location: '.$uri); + } + + // We are about to exit, so run the send_headers event + Event::run('system.send_headers'); + + exit('

    '.$method.' - '.$codes[$method].'

    '.$output); + } + +} // End url \ No newline at end of file diff --git a/lib/kohana/system/helpers/valid.php b/lib/kohana/system/helpers/valid.php new file mode 100644 index 0000000..74517c0 --- /dev/null +++ b/lib/kohana/system/helpers/valid.php @@ -0,0 +1,330 @@ += 0; $i -= 2) + { + // Add up every 2nd digit, starting from the right + $checksum += $number[$i]; + } + + for ($i = $length - 2; $i >= 0; $i -= 2) + { + // Add up every 2nd digit doubled, starting from the right + $double = $number[$i] * 2; + + // Subtract 9 from the double where value is greater than 10 + $checksum += ($double >= 10) ? $double - 9 : $double; + } + + // If the checksum is a multiple of 10, the number is valid + return ($checksum % 10 === 0); + } + + /** + * Checks if a phone number is valid. + * + * @param string phone number to check + * @return boolean + */ + public static function phone($number, $lengths = NULL) + { + if ( ! is_array($lengths)) + { + $lengths = array(7,10,11); + } + + // Remove all non-digit characters from the number + $number = preg_replace('/\D+/', '', $number); + + // Check if the number is within range + return in_array(strlen($number), $lengths); + } + + /** + * Tests if a string is a valid date string. + * + * @param string date to check + * @return boolean + */ + public static function date($str) + { + return (strtotime($str) !== FALSE); + } + + /** + * Checks whether a string consists of alphabetical characters only. + * + * @param string input string + * @param boolean trigger UTF-8 compatibility + * @return boolean + */ + public static function alpha($str, $utf8 = FALSE) + { + return ($utf8 === TRUE) + ? (bool) preg_match('/^\pL++$/uD', (string) $str) + : ctype_alpha((string) $str); + } + + /** + * Checks whether a string consists of alphabetical characters and numbers only. + * + * @param string input string + * @param boolean trigger UTF-8 compatibility + * @return boolean + */ + public static function alpha_numeric($str, $utf8 = FALSE) + { + return ($utf8 === TRUE) + ? (bool) preg_match('/^[\pL\pN]++$/uD', (string) $str) + : ctype_alnum((string) $str); + } + + /** + * Checks whether a string consists of alphabetical characters, numbers, underscores and dashes only. + * + * @param string input string + * @param boolean trigger UTF-8 compatibility + * @return boolean + */ + public static function alpha_dash($str, $utf8 = FALSE) + { + return ($utf8 === TRUE) + ? (bool) preg_match('/^[-\pL\pN_]++$/uD', (string) $str) + : (bool) preg_match('/^[-a-z0-9_]++$/iD', (string) $str); + } + + /** + * Checks whether a string consists of digits only (no dots or dashes). + * + * @param string input string + * @param boolean trigger UTF-8 compatibility + * @return boolean + */ + public static function digit($str, $utf8 = FALSE) + { + return ($utf8 === TRUE) + ? (bool) preg_match('/^\pN++$/uD', (string) $str) + : ctype_digit((string) $str); + } + + /** + * Checks whether a string is a valid number (negative and decimal numbers allowed). + * + * @see Uses locale conversion to allow decimal point to be locale specific. + * @see http://www.php.net/manual/en/function.localeconv.php + * + * @param string input string + * @return boolean + */ + public static function numeric($str) + { + // Use localeconv to set the decimal_point value: Usually a comma or period. + $locale = localeconv(); + return (bool) preg_match('/^-?[0-9'.$locale['decimal_point'].']++$/D', (string) $str); + } + + /** + * Checks whether a string is a valid text. Letters, numbers, whitespace, + * dashes, periods, and underscores are allowed. + * + * @param string text to check + * @return boolean + */ + public static function standard_text($str) + { + // pL matches letters + // pN matches numbers + // pZ matches whitespace + // pPc matches underscores + // pPd matches dashes + // pPo matches normal puncuation + return (bool) preg_match('/^[\pL\pN\pZ\p{Pc}\p{Pd}\p{Po}]++$/uD', (string) $str); + } + + /** + * Checks if a string is a proper decimal format. The format array can be + * used to specify a decimal length, or a number and decimal length, eg: + * array(2) would force the number to have 2 decimal places, array(4,2) + * would force the number to have 4 digits and 2 decimal places. + * + * @param string input string + * @param array decimal format: y or x,y + * @return boolean + */ + public static function decimal($str, $format = NULL) + { + // Create the pattern + $pattern = '/^[0-9]%s\.[0-9]%s$/'; + + if ( ! empty($format)) + { + if (count($format) > 1) + { + // Use the format for number and decimal length + $pattern = sprintf($pattern, '{'.$format[0].'}', '{'.$format[1].'}'); + } + elseif (count($format) > 0) + { + // Use the format as decimal length + $pattern = sprintf($pattern, '+', '{'.$format[0].'}'); + } + } + else + { + // No format + $pattern = sprintf($pattern, '+', '+'); + } + + return (bool) preg_match($pattern, (string) $str); + } + +} // End valid diff --git a/lib/kohana/system/i18n/de_DE/cache.php b/lib/kohana/system/i18n/de_DE/cache.php new file mode 100644 index 0000000..53f32aa --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/cache.php @@ -0,0 +1,10 @@ + 'Die Gruppe %s ist in Ihrer Konfiguration nicht definiert.', + 'extension_not_loaded' => 'Die PHP-Erweiterung %s muss geladen sein, um diesen Treiber benutzen zu können.', + 'unwritable' => 'Der eingestellte Speicherort %s ist nicht beschreibbar.', + 'resources' => 'Das Cachen von Ressourcen ist nicht möglich, da diese nicht serialisiert werden können.', + 'driver_error' => '%s' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/calendar.php b/lib/kohana/system/i18n/de_DE/calendar.php new file mode 100644 index 0000000..d95f54b --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/calendar.php @@ -0,0 +1,59 @@ + 'So', + 'mo' => 'Mo', + 'tu' => 'Di', + 'we' => 'Mi', + 'th' => 'Do', + 'fr' => 'Fr', + 'sa' => 'Sa', + + // Short day names + 'sun' => 'Son', + 'mon' => 'Mon', + 'tue' => 'Die', + 'wed' => 'Mit', + 'thu' => 'Don', + 'fri' => 'Fre', + 'sat' => 'Sam', + + // Long day names + 'sunday' => 'Sonntag', + 'monday' => 'Montag', + 'tuesday' => 'Dienstag', + 'wednesday' => 'Mittwoch', + 'thursday' => 'Donnerstag', + 'friday' => 'Freitag', + 'saturday' => 'Samstag', + + // Short month names + 'jan' => 'Jan', + 'feb' => 'Feb', + 'mar' => 'Mär', + 'apr' => 'Apr', + 'may' => 'Mai', + 'jun' => 'Jun', + 'jul' => 'Jul', + 'aug' => 'Aug', + 'sep' => 'Sep', + 'oct' => 'Okt', + 'nov' => 'Nov', + 'dec' => 'Dez', + + // Long month names + 'january' => 'Januar', + 'february' => 'Februar', + 'march' => 'März', + 'april' => 'April', + 'mayl' => 'Mai', + 'june' => 'Juni', + 'july' => 'Juli', + 'august' => 'August', + 'september' => 'September', + 'october' => 'Oktober', + 'november' => 'November', + 'december' => 'Dezember' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/captcha.php b/lib/kohana/system/i18n/de_DE/captcha.php new file mode 100644 index 0000000..0a5ce5e --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/captcha.php @@ -0,0 +1,33 @@ + 'Die eingestellte Datei %s konnte nicht gefunden werden. Kontrollieren Sie bitte, bevor Sie Dateien benutzen, ob diese existieren. Sie können dafür die Funktion file_exists() benutzen.', + 'requires_GD2' => 'Die Captcha-Bibliothek erfordert GD2 mit FreeType-Unterstützung. Sehen Sie sich die Seite http://php.net/gd_info an, um weitere Informationen zu erhalten.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Hasst du Spam? (ja oder nein)', 'ja'), + array('Bist du ein Roboter? (ja oder nein)', 'nein'), + array('Feuer ist ... (heiß or kalt)', 'heiß'), + array('Die Jahreszeit, die nach Herbst kommt ist ...', 'Winter'), + array('Welcher Wochentag ist heute?', strftime('%A')), + array('In welchem Monat befinden wir uns gerade?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/de_DE/core.php b/lib/kohana/system/i18n/de_DE/core.php new file mode 100644 index 0000000..a47ded2 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/core.php @@ -0,0 +1,34 @@ + 'Pro Seitenaufruf kann es nur eine Instanz von Kohana geben', + 'uncaught_exception' => 'Unerwarteter Fehler vom Typ %s: %s in %s in Zeile %s', + 'invalid_method' => 'Ungültige Methode %s aufgerufen in %s', + 'invalid_property' => '%s ist keine Eigenschaft der Klasse %s.', + 'log_dir_unwritable' => 'Das Log-Verzeichnis ist nicht beschreibbar: %s', + 'resource_not_found' => '%s %s konnte nicht gefunden werden', + 'invalid_filetype' => 'Die Dateiendung .%s ist in Ihrer View-Konfiguration nicht vorhanden', + 'view_set_filename' => 'Sie müssen den Dateinamen der Ansicht festlegen, bevor render aufgerufen wird', + 'no_default_route' => 'Erstellen Sie bitte eine Standardroute config/routes.php', + 'no_controller' => 'Kohana gelang es nicht einen Controller zu finden, um diesen Aufruf zu verarbeiten: %s', + 'page_not_found' => 'Die Seite %s konnte nicht gefunden werden.', + 'stats_footer' => 'Seite geladen in {execution_time} Sekunden bei {memory_usage} Speichernutzung. Generiert von Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Die Abfrage konnte nicht abgeschlossen werden', + 'errors_disabled' => 'Sie können zur Startseite zurück kehren oder es erneut versuchen.', + + // Drivers + 'driver_implements' => 'Der Treiber %s für die Bibliothek %s muss das Interface %s implementieren', + 'driver_not_found' => 'Der Treiber %s für die Bibliothek %s konnte nicht gefunden werden', + + // Resource names + 'config' => 'Die Konfigurationsdatei', + 'controller' => 'Der Controller', + 'helper' => 'Der Helfer', + 'library' => 'Die Bibliothek', + 'driver' => 'Der Treiber', + 'model' => 'Das Modell', + 'view' => 'Die Ansicht', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/database.php b/lib/kohana/system/i18n/de_DE/database.php new file mode 100644 index 0000000..58edf3b --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/database.php @@ -0,0 +1,15 @@ + 'Die Gruppe %s ist in Ihrer Konfiguration nicht definiert worden.', + 'error' => 'Es gab einen SQL-Fehler: %s', + 'connection' => 'Es gab einen Fehler bei der Verbindung mit der Datenbank: %s', + 'invalid_dsn' => 'Die von Ihnen angegebene DSN ist ungültig: %s', + 'must_use_set' => 'Sie müssen SET in Ihrem Query benutzen.', + 'must_use_where' => 'Sie müssen WHERE in Ihrem Query benutzen.', + 'must_use_table' => 'Sie müssen eine Tabelle für Ihren Query angeben.', + 'table_not_found' => 'Die Tabelle %s konnte in der Datenbank nicht gefunden werden.', + 'not_implemented' => 'Die Methode %s wird von diesem Datenbanktreiber nicht unterstützt.', + 'result_read_only' => 'Ergebnisse der Anfrage können nur gelesen werden.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/encrypt.php b/lib/kohana/system/i18n/de_DE/encrypt.php new file mode 100644 index 0000000..1933969 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/encrypt.php @@ -0,0 +1,8 @@ + 'Die Gruppe %s ist nicht in Ihrer Konfiguration enthalten.', + 'requires_mcrypt' => 'Um die Bibliothek Encrypt zu benutzen, muss mcrypt in Ihrer PHP-Installation aktiviert werden', + 'no_encryption_key' => 'Um die Bibliothek Encrypt zu benutzen, müssen Sie einen Schlüssel in Ihrer Konfiguration eintragen' +); diff --git a/lib/kohana/system/i18n/de_DE/errors.php b/lib/kohana/system/i18n/de_DE/errors.php new file mode 100644 index 0000000..92e281c --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Framework-Fehler', 'Lesen Sie bitte in der Kohana-Dokumentation, um mehr über den folgenden Fehler zu erfahren.'), + E_PAGE_NOT_FOUND => array( 1, 'Seite Nicht Gefunden', 'Die aufgerufene Seite wurde nicht gefunden. Sie wurde entweder verschoben, gelöscht oder archiviert.'), + E_DATABASE_ERROR => array( 1, 'Datenbank-Fehler', 'Ein Datenbankfehler ist während des Aufrufs aufgetreten. Überprüfen Sie bitte den unten stehenden Fehler für mehr Informationen.'), + E_RECOVERABLE_ERROR => array( 1, 'Behebbarer Fehler', 'Es ist ein Fehler aufgetreten, der das Laden der Seite verhindert hat. Wenn der Fehler weiterhin besteht, kontaktieren Sie bitte den Administrator der Seite.'), + E_ERROR => array( 1, 'Fataler Fehler', ''), + E_USER_ERROR => array( 1, 'Fataler Fehler', ''), + E_PARSE => array( 1, 'Syntax-Fehler', ''), + E_WARNING => array( 1, 'Warnung', ''), + E_USER_WARNING => array( 1, 'Warnung', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Laufzeitfehler', ''), +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/event.php b/lib/kohana/system/i18n/de_DE/event.php new file mode 100644 index 0000000..e299e05 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/event.php @@ -0,0 +1,7 @@ + 'Der Versuch, das ungültige Subjekt %s an %s anzuhängen, ist fehlgeschlagen. Subjekte müssen die Klasse Event_Subject erweitern.', + 'invalid_observer' => 'Der Versuch, den ungültigen Beobachter %s an %s anzuhängen, ist fehlgeschlagen. Beobachter müssen die Klasse Event_Observer erweitern.', +); diff --git a/lib/kohana/system/i18n/de_DE/image.php b/lib/kohana/system/i18n/de_DE/image.php new file mode 100644 index 0000000..b12b13c --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/image.php @@ -0,0 +1,33 @@ + 'Die Bildbibliothek versucht die PHP-Funktion getimagesize() zu benutzen, die aber nicht Bestandteil ihrer PHP-Installation ist.', + 'unsupported_method' => 'Der Bildtreiber, den Sie benutzen, unterstützt nicht die %s-Bildtransformation.', + 'file_not_found' => 'Das angegebene Bild %s konnte nicht gefunden werden. Stellen Sie bitte sicher, dass das Bild existiert. Benutzen Sie hierzu die Funktion file_exists().', + 'type_not_allowed' => 'Das angegebene Bild %s ist kein erlaubter Bildtyp.', + 'invalid_width' => 'Die von Ihnen festgelegte Bildbreite, %s, ist ungültig.', + 'invalid_height' => 'Die von Ihnen festgelegte Bildhöhe, %s, ist ungültig.', + 'invalid_dimensions' => 'Das festgelegte Format für %s ist ungültig.', + 'invalid_master' => 'Die festgelegte Master-Dimension ist ungültig.', + 'invalid_flip' => 'Die festgelegte Richtung der Spiegelung ist ungültig.', + 'directory_unwritable' => 'Das Verzeichnis %s ist nicht beschreibbar.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'Das festgelegte ImageMagic-Verzeichnis enthält nicht das benötigte Programm %s.', + ), + + // GraphicsMagick specific messages + 'graphicsmagick' => array + ( + 'not_found' => 'Das festgelegte GraphicsMagick-Verzeichnis enthält nicht das benötigte Programm %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'Die Bildbibliothek erfordert GD2. Sehen Sie sich die Seite http://php.net/gd_info an, um weitere Informationen zu erhalten.', + ), +); diff --git a/lib/kohana/system/i18n/de_DE/orm.php b/lib/kohana/system/i18n/de_DE/orm.php new file mode 100644 index 0000000..b03df5b --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/orm.php @@ -0,0 +1,3 @@ + 'Die Gruppe %s ist nicht in der Pagination-Konfiguration definiert worden.', + 'page' => 'Seite', + 'pages' => 'Seiten', + 'item' => 'Element', + 'items' => 'Elemente', + 'of' => 'von', + 'first' => 'Erste', + 'last' => 'Letzte', + 'previous' => 'Vorherige', + 'next' => 'Nächste', +); diff --git a/lib/kohana/system/i18n/de_DE/profiler.php b/lib/kohana/system/i18n/de_DE/profiler.php new file mode 100644 index 0000000..1b16433 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/profiler.php @@ -0,0 +1,15 @@ + 'Benchmark-Tests', + 'post_data' => 'POST-Daten:', + 'no_post' => 'Keine POST-Daten', + 'session_data' => 'Session-Daten', + 'no_session' => 'Keine Session-Daten', + 'queries' => 'Datenbank-Anfragen', + 'no_queries' => 'Keine Anfragen', + 'no_database' => 'Datenbank nicht geladen', + 'cookie_data' => 'Cookie-Daten', + 'no_cookie' => 'Keine Cookie-Daten', +); diff --git a/lib/kohana/system/i18n/de_DE/session.php b/lib/kohana/system/i18n/de_DE/session.php new file mode 100644 index 0000000..abbd912 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/session.php @@ -0,0 +1,6 @@ + 'Der Sessionname %s ist ungültig. Dieser darf nur aus alphanumerischen Zeichen und mindestens einem Buchstaben bestehen.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/swift.php b/lib/kohana/system/i18n/de_DE/swift.php new file mode 100644 index 0000000..88b112b --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/swift.php @@ -0,0 +1,6 @@ + 'Fehler beim Senden einer E-Mail aufgetreten.' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/upload.php b/lib/kohana/system/i18n/de_DE/upload.php new file mode 100644 index 0000000..181d389 --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/upload.php @@ -0,0 +1,6 @@ + 'Das Verzeichnis für hochgeladene Dateien, %s, ist nicht beschreibbar.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/de_DE/validation.php b/lib/kohana/system/i18n/de_DE/validation.php new file mode 100644 index 0000000..d1797da --- /dev/null +++ b/lib/kohana/system/i18n/de_DE/validation.php @@ -0,0 +1,41 @@ + 'Ungültige Validierungsregel benutzt: %s', + 'i18n_array' => 'Der i18n-Schlüssel %s muss ein Array sein, um diesen in der in_array-Regel benutzen zu können', + 'not_callable' => 'Die Callback-Funktion %s, die zur Validierung benutzt wird, ist nicht aufrufbar', + + // General errors + 'unknown_error' => 'Unbekannter Fehler bei der Validierungsregel von dem Feld %s aufgetreten.', + 'required' => 'Das Feld %s ist erforderlich.', + 'min_length' => 'Das Feld %s muss mindestens %d Zeichen lang sein.', + 'max_length' => 'Das Feld %s darf höchstens %d Zeichen lang sein.', + 'exact_length' => 'Das Feld %s muss genau %d Zeichen enthalten.', + 'in_array' => 'Das Feld %s muss ausgewählt werden.', + 'matches' => 'Das Feld %s muss mit dem Feld %s übereinstimmen.', + 'valid_url' => 'Das Feld %s muss eine gültige URL beinhalten.', + 'valid_email' => 'Das Feld %s muss eine gültige E-Mailadresse beinhalten.', + 'valid_ip' => 'Das Feld %s muss eine gültige IP-Adresse beinhalten.', + 'valid_type' => 'Das Feld %s darf nur %s beinhalten.', + 'range' => 'Das Feld %s muss zwischen festgelegten Bereichen sein.', + 'regex' => 'Das Feld %s entspricht nicht einer akzeptierten Eingabe.', + 'depends_on' => 'Das Feld %s hängt vom Feld %s ab.', + + // Upload errors + 'user_aborted' => 'Das Hochladen der Datei %s wurde abgebrochen.', + 'invalid_type' => 'Die Datei %s entspricht nicht den erlaubten Dateitypen.', + 'max_size' => 'Die Datei %s ist zu groß. Die maximale Größe beträgt %s.', + 'max_width' => 'Die Datei %s ist zu groß. Die maximal erlaubte Breite betägt %spx.', + 'max_height' => 'Die Datei %s ist zu groß. Die maximal erlaubte Höhe betägt %spx.', + 'min_width' => 'Die Datei %s ist zu klein. Die minimal erlaubte Breite betägt %spx.', + 'min_height' => 'Die Datei %s ist zu klein. Die minimal erlaubte Höhe betägt %spx.', + + // Field types + 'alpha' => 'alphabetische Zeichen', + 'alpha_numeric' => 'alphabetische und numerische Zeichen', + 'alpha_dash' => 'alphabetische Zeichen, Trennstriche und Unterstriche', + 'digit' => 'Zahlen', + 'numeric' => 'Nummern', +); diff --git a/lib/kohana/system/i18n/en_US/cache.php b/lib/kohana/system/i18n/en_US/cache.php new file mode 100644 index 0000000..bef0279 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/cache.php @@ -0,0 +1,10 @@ + 'The %s group is not defined in your configuration.', + 'extension_not_loaded' => 'The %s PHP extension must be loaded to use this driver.', + 'unwritable' => 'The configured storage location, %s, is not writable.', + 'resources' => 'Caching of resources is impossible, because resources cannot be serialized.', + 'driver_error' => '%s', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/calendar.php b/lib/kohana/system/i18n/en_US/calendar.php new file mode 100644 index 0000000..21dad22 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/calendar.php @@ -0,0 +1,59 @@ + 'Su', + 'mo' => 'Mo', + 'tu' => 'Tu', + 'we' => 'We', + 'th' => 'Th', + 'fr' => 'Fr', + 'sa' => 'Sa', + + // Short day names + 'sun' => 'Sun', + 'mon' => 'Mon', + 'tue' => 'Tue', + 'wed' => 'Wed', + 'thu' => 'Thu', + 'fri' => 'Fri', + 'sat' => 'Sat', + + // Long day names + 'sunday' => 'Sunday', + 'monday' => 'Monday', + 'tuesday' => 'Tuesday', + 'wednesday' => 'Wednesday', + 'thursday' => 'Thursday', + 'friday' => 'Friday', + 'saturday' => 'Saturday', + + // Short month names + 'jan' => 'Jan', + 'feb' => 'Feb', + 'mar' => 'Mar', + 'apr' => 'Apr', + 'may' => 'May', + 'jun' => 'Jun', + 'jul' => 'Jul', + 'aug' => 'Aug', + 'sep' => 'Sep', + 'oct' => 'Oct', + 'nov' => 'Nov', + 'dec' => 'Dec', + + // Long month names + 'january' => 'January', + 'february' => 'February', + 'march' => 'March', + 'april' => 'April', + 'mayl' => 'May', + 'june' => 'June', + 'july' => 'July', + 'august' => 'August', + 'september' => 'September', + 'october' => 'October', + 'november' => 'November', + 'december' => 'December' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/captcha.php b/lib/kohana/system/i18n/en_US/captcha.php new file mode 100644 index 0000000..6040471 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/captcha.php @@ -0,0 +1,33 @@ + 'The specified file, %s, was not found. Please verify that files exist by using file_exists() before using them.', + 'requires_GD2' => 'The Captcha library requires GD2 with FreeType support. Please see http://php.net/gd_info for more information.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Do you hate spam? (yes or no)', 'yes'), + array('Are you a robot? (yes or no)', 'no'), + array('Fire is... (hot or cold)', 'hot'), + array('The season after fall is...', 'winter'), + array('Which day of the week is it today?', strftime('%A')), + array('Which month of the year are we in?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/en_US/core.php b/lib/kohana/system/i18n/en_US/core.php new file mode 100644 index 0000000..9711b7c --- /dev/null +++ b/lib/kohana/system/i18n/en_US/core.php @@ -0,0 +1,34 @@ + 'There can be only one instance of Kohana per page request', + 'uncaught_exception' => 'Uncaught %s: %s in file %s on line %s', + 'invalid_method' => 'Invalid method %s called in %s', + 'invalid_property' => 'The %s property does not exist in the %s class.', + 'log_dir_unwritable' => 'The log directory is not writable: %s', + 'resource_not_found' => 'The requested %s, %s, could not be found', + 'invalid_filetype' => 'The requested filetype, .%s, is not allowed in your view configuration file', + 'view_set_filename' => 'You must set the the view filename before calling render', + 'no_default_route' => 'Please set a default route in config/routes.php', + 'no_controller' => 'Kohana was not able to determine a controller to process this request: %s', + 'page_not_found' => 'The page you requested, %s, could not be found.', + 'stats_footer' => 'Loaded in {execution_time} seconds, using {memory_usage} of memory. Generated by Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Unable to Complete Request', + 'errors_disabled' => 'You can go to the home page or try again.', + + // Drivers + 'driver_implements' => 'The %s driver for the %s library must implement the %s interface', + 'driver_not_found' => 'The %s driver for the %s library could not be found', + + // Resource names + 'config' => 'config file', + 'controller' => 'controller', + 'helper' => 'helper', + 'library' => 'library', + 'driver' => 'driver', + 'model' => 'model', + 'view' => 'view', +); diff --git a/lib/kohana/system/i18n/en_US/database.php b/lib/kohana/system/i18n/en_US/database.php new file mode 100644 index 0000000..172e5c9 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/database.php @@ -0,0 +1,15 @@ + 'The %s group is not defined in your configuration.', + 'error' => 'There was an SQL error: %s', + 'connection' => 'There was an error connecting to the database: %s', + 'invalid_dsn' => 'The DSN you supplied is not valid: %s', + 'must_use_set' => 'You must set a SET clause for your query.', + 'must_use_where' => 'You must set a WHERE clause for your query.', + 'must_use_table' => 'You must set a database table for your query.', + 'table_not_found' => 'Table %s does not exist in your database.', + 'not_implemented' => 'The method you called, %s, is not supported by this driver.', + 'result_read_only' => 'Query results are read only.' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/encrypt.php b/lib/kohana/system/i18n/en_US/encrypt.php new file mode 100644 index 0000000..9afd620 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/encrypt.php @@ -0,0 +1,8 @@ + 'The %s group is not defined in your configuration.', + 'requires_mcrypt' => 'To use the Encrypt library, mcrypt must be enabled in your PHP installation', + 'no_encryption_key' => 'To use the Encrypt library, you must set an encryption key in your config file' +); diff --git a/lib/kohana/system/i18n/en_US/errors.php b/lib/kohana/system/i18n/en_US/errors.php new file mode 100644 index 0000000..10f44ff --- /dev/null +++ b/lib/kohana/system/i18n/en_US/errors.php @@ -0,0 +1,15 @@ + array( 1, 'Framework Error', 'Please check the Kohana documentation for information about the following error.'), + E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'The requested page was not found. It may have moved, been deleted, or archived.'), + E_DATABASE_ERROR => array( 1, 'Database Error', 'A database error occurred while performing the requested procedure. Please review the database error below for more information.'), + E_ERROR => array( 1, 'Fatal Error', ''), + E_USER_ERROR => array( 1, 'Fatal Error', ''), + E_PARSE => array( 1, 'Syntax Error', ''), + E_WARNING => array( 1, 'Warning Message', ''), + E_USER_WARNING => array( 1, 'Warning Message', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), +); diff --git a/lib/kohana/system/i18n/en_US/event.php b/lib/kohana/system/i18n/en_US/event.php new file mode 100644 index 0000000..282a0a2 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/event.php @@ -0,0 +1,7 @@ + 'Attempt to attach invalid subject %s to %s failed: Subjects must extend the Event_Subject class', + 'invalid_observer' => 'Attempt to attach invalid observer %s to %s failed: Observers must extend the Event_Observer class', +); diff --git a/lib/kohana/system/i18n/en_US/image.php b/lib/kohana/system/i18n/en_US/image.php new file mode 100644 index 0000000..9f18493 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/image.php @@ -0,0 +1,33 @@ + 'The Image library requires the getimagesize() PHP function, which is not available in your installation.', + 'unsupported_method' => 'Your configured driver does not support the %s image transformation.', + 'file_not_found' => 'The specified image, %s, was not found. Please verify that images exist by using file_exists() before manipulating them.', + 'type_not_allowed' => 'The specified image, %s, is not an allowed image type.', + 'invalid_width' => 'The width you specified, %s, is not valid.', + 'invalid_height' => 'The height you specified, %s, is not valid.', + 'invalid_dimensions' => 'The dimensions specified for %s are not valid.', + 'invalid_master' => 'The master dimension specified is not valid.', + 'invalid_flip' => 'The flip direction specified is not valid.', + 'directory_unwritable' => 'The specified directory, %s, is not writable.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'The ImageMagick directory specified does not contain a required program, %s.', + ), + + // GraphicsMagick specific messages + 'graphicsmagick' => array + ( + 'not_found' => 'The GraphicsMagick directory specified does not contain a required program, %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'The Image library requires GD2. Please see http://php.net/gd_info for more information.', + ), +); diff --git a/lib/kohana/system/i18n/en_US/orm.php b/lib/kohana/system/i18n/en_US/orm.php new file mode 100644 index 0000000..3c5720b --- /dev/null +++ b/lib/kohana/system/i18n/en_US/orm.php @@ -0,0 +1,3 @@ + 'The %s group is not defined in your pagination configuration.', + 'page' => 'page', + 'pages' => 'pages', + 'item' => 'item', + 'items' => 'items', + 'of' => 'of', + 'first' => 'first', + 'last' => 'last', + 'previous' => 'previous', + 'next' => 'next', +); diff --git a/lib/kohana/system/i18n/en_US/profiler.php b/lib/kohana/system/i18n/en_US/profiler.php new file mode 100644 index 0000000..a39c2f5 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/profiler.php @@ -0,0 +1,15 @@ + 'Benchmarks', + 'post_data' => 'Post Data', + 'no_post' => 'No post data', + 'session_data' => 'Session Data', + 'no_session' => 'No session data', + 'queries' => 'Database Queries', + 'no_queries' => 'No queries', + 'no_database' => 'Database not loaded', + 'cookie_data' => 'Cookie Data', + 'no_cookie' => 'No cookie data', +); diff --git a/lib/kohana/system/i18n/en_US/session.php b/lib/kohana/system/i18n/en_US/session.php new file mode 100644 index 0000000..ee781c6 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/session.php @@ -0,0 +1,6 @@ + 'The session_name, %s, is invalid. It must contain only alphanumeric characters and underscores. Also at least one letter must be present.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/swift.php b/lib/kohana/system/i18n/en_US/swift.php new file mode 100644 index 0000000..249c4a8 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/swift.php @@ -0,0 +1,6 @@ + 'An error occurred while sending the email message.' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/upload.php b/lib/kohana/system/i18n/en_US/upload.php new file mode 100644 index 0000000..7f6e216 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/upload.php @@ -0,0 +1,6 @@ + 'The upload destination folder, %s, does not appear to be writable.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/en_US/validation.php b/lib/kohana/system/i18n/en_US/validation.php new file mode 100644 index 0000000..d98e548 --- /dev/null +++ b/lib/kohana/system/i18n/en_US/validation.php @@ -0,0 +1,41 @@ + 'Invalid validation rule used: %s', + 'i18n_array' => 'The %s i18n key must be an array to be used with the in_lang rule', + 'not_callable' => 'Callback %s used for Validation is not callable', + + // General errors + 'unknown_error' => 'Unknown validation error while validating the %s field.', + 'required' => 'The %s field is required.', + 'min_length' => 'The %s field must be at least %d characters long.', + 'max_length' => 'The %s field must be %d characters or fewer.', + 'exact_length' => 'The %s field must be exactly %d characters.', + 'in_array' => 'The %s field must be selected from the options listed.', + 'matches' => 'The %s field must match the %s field.', + 'valid_url' => 'The %s field must contain a valid URL.', + 'valid_email' => 'The %s field must contain a valid email address.', + 'valid_ip' => 'The %s field must contain a valid IP address.', + 'valid_type' => 'The %s field must only contain %s characters.', + 'range' => 'The %s field must be between specified ranges.', + 'regex' => 'The %s field does not match accepted input.', + 'depends_on' => 'The %s field depends on the %s field.', + + // Upload errors + 'user_aborted' => 'The %s file was aborted during upload.', + 'invalid_type' => 'The %s file is not an allowed file type.', + 'max_size' => 'The %s file you uploaded was too large. The maximum size allowed is %s.', + 'max_width' => 'The %s file you uploaded was too big. The maximum allowed width is %spx.', + 'max_height' => 'The %s file you uploaded was too big. The maximum allowed height is %spx.', + 'min_width' => 'The %s file you uploaded was too small. The minimum allowed width is %spx.', + 'min_height' => 'The %s file you uploaded was too small. The minimum allowed height is %spx.', + + // Field types + 'alpha' => 'alphabetical', + 'alpha_numeric' => 'alphabetical and numeric', + 'alpha_dash' => 'alphabetical, dash, and underscore', + 'digit' => 'digit', + 'numeric' => 'numeric', +); diff --git a/lib/kohana/system/i18n/es_ES/cache.php b/lib/kohana/system/i18n/es_ES/cache.php new file mode 100644 index 0000000..c05e4cb --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/cache.php @@ -0,0 +1,10 @@ + 'El grupo %s no esta definido en la configuracion.', + 'extension_not_loaded' => 'La extensión PHP %s tiene que estar cargada para poder utilizar este driver.', + 'unwritable' => 'El directorio seleccionado, %s, no tiene permisos de escritura.', + 'resources' => 'No es posible guardar el contenido en la cache, el contenido no es serializable.', + 'driver_error' => '%s', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/calendar.php b/lib/kohana/system/i18n/es_ES/calendar.php new file mode 100644 index 0000000..961b223 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/calendar.php @@ -0,0 +1,55 @@ + 'Do', + 'mo' => 'Lu', + 'tu' => 'Ma', + 'we' => 'Mi', + 'th' => 'Ju', + 'fr' => 'Vi', + 'sa' => 'Sa', + // Short day names + 'sun' => 'Dom', + 'mon' => 'Lun', + 'tue' => 'Mar', + 'wed' => 'Mie', + 'thu' => 'Jue', + 'fri' => 'Vie', + 'sat' => 'Sab', + // Long day names + 'sunday' => 'Domingo', + 'monday' => 'Lunes', + 'tuesday' => 'Martes', + 'wednesday' => 'Miércoles', + 'thursday' => 'Jueves', + 'friday' => 'Viernes', + 'saturday' => 'Sábado', + // Short month names + 'jan' => 'Ene', + 'feb' => 'Feb', + 'mar' => 'Mar', + 'apr' => 'Abr', + 'may' => 'May', + 'jun' => 'Jun', + 'jul' => 'Jul', + 'aug' => 'Ago', + 'sep' => 'Sep', + 'oct' => 'Oct', + 'nov' => 'Nov', + 'dec' => 'Dic', + // Long month names + 'january' => 'Enero', + 'february' => 'Febrero', + 'march' => 'Marzo', + 'april' => 'Abril', + 'mayl' => 'Mayo', + 'june' => 'Junio', + 'july' => 'Julio', + 'august' => 'Agosto', + 'september' => 'Septiembre', + 'october' => 'Octubre', + 'november' => 'Noviembre', + 'december' => 'Diciembre', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/captcha.php b/lib/kohana/system/i18n/es_ES/captcha.php new file mode 100644 index 0000000..6c2cd15 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/captcha.php @@ -0,0 +1,33 @@ + 'El archivo especificado, %s, no ha sido encontrado. Por favor, verifica que el fichero existe utilizando file_exists() antes de intentar utilizarlo.', + 'requires_GD2' => 'La libreria Captcha requiere GD2 con soporte FreeType. Lea lo siguiente http://php.net/gd_info para ampliar la informacion.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('¿Odias el spam? (si o no)', 'si'), + array('¿Eres un robot? (si o no)', 'no'), + array('El fuego es... (caliente o frio)', 'caliente'), + array('La estación que viene despues del otoño es...', 'invierno'), + array('¿Qué día de la semana es hoy?', strftime('%A')), + array('¿En qué mes del año estamos?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/es_ES/core.php b/lib/kohana/system/i18n/es_ES/core.php new file mode 100644 index 0000000..6cbe5e9 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/core.php @@ -0,0 +1,34 @@ + 'Solo puede haber una instancia de Kohana por cada página.', + 'uncaught_exception' => '%s no capturada: %s en el archivo %s, linea %s', + 'invalid_method' => 'Método inválido %s llamado en %s.', + 'invalid_property' => 'La propiedad %s no existe en la clase %s.', + 'log_dir_unwritable' => 'Tu configuración del &8220;log.directory&8221; no apunta a un directorio con permiso de escritura.', + 'resource_not_found' => 'El fichero de %s con nombre %s, no pudo ser encontrado.', + 'invalid_filetype' => 'El tipo de fichero solicitado, .%s, no esta permitido en la configuración de tus vistas.', + 'view_set_filename' => 'Tienes que definir el nombre de la vista antes de llamar al metodo render', + 'no_default_route' => 'Por favor, especifica la ruta en config/routes.php.', + 'no_controller' => 'Kohana no pudo determinar un controlador para procesar: %s', + 'page_not_found' => 'La página que solicitase, %s, no se encuentra.', + 'stats_footer' => 'Cargado en {execution_time} segundos, usando {memory_usage} de memoria. Generado con Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Imposible completar la solicitud', + 'errors_disabled' => 'Puedes volver a la página de inico o volver a intentarlo.', + + // Drivers + 'driver_implements' => 'El driver %s para la libreria %s debe implementar el interface %s', + 'driver_not_found' => 'No se ha encontrado el driver %s para la libreria %s', + + // Resource names + 'config' => 'fichero de configuración', + 'controller' => 'controlador', + 'helper' => 'helper', + 'library' => 'librería', + 'driver' => 'driver', + 'model' => 'modelo', + 'view' => 'vista', +); diff --git a/lib/kohana/system/i18n/es_ES/database.php b/lib/kohana/system/i18n/es_ES/database.php new file mode 100644 index 0000000..ebfea71 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/database.php @@ -0,0 +1,15 @@ + 'El grupo %s no esta definido en tu configuración.', + 'error' => 'Ocurrió un error de SQL: %s', + 'connection' => 'Ocurrió un error conectando a la base de datos: %s', + 'invalid_dsn' => 'El DSN que pusiste no es válido: %s', + 'must_use_set' => 'Necesitas una clausula SET para tu consulta.', + 'must_use_where' => 'Necesitas una clausula WHERE para tu consulta.', + 'must_use_table' => 'Necesitas especificar la tabla para tu consulta.', + 'table_not_found' => 'La tabla %s no existe en tu base de datos.', + 'not_implemented' => 'El método requerido, %s, no esta soportado por este driver.', + 'result_read_only' => 'Los resultados del query son de solo lectura.' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/encrypt.php b/lib/kohana/system/i18n/es_ES/encrypt.php new file mode 100644 index 0000000..80e32c2 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/encrypt.php @@ -0,0 +1,8 @@ + 'El grupo %s no esta definidp en la configuración.', + 'requires_mcrypt' => 'Para usar la librería de Encriptación, mcrypt debe estar habilitado.', + 'no_encryption_key' => 'Para usar la librería de Encriptación, tienes que especificar una llave de encriptación en tu archivo de configuración.', +); diff --git a/lib/kohana/system/i18n/es_ES/errors.php b/lib/kohana/system/i18n/es_ES/errors.php new file mode 100644 index 0000000..cc22414 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Error del Framework', 'Revisa la documentación de Kohana para información sobre el siguiente error.'), + E_PAGE_NOT_FOUND => array( 1, 'No se encuentra la página', 'No se encontró la página solicitada. Puede ser que haya sido movida, borrada o archivada.'), + E_DATABASE_ERROR => array( 1, 'Error de Base de Datos', 'Ocurrió un error en la base de datos mientras se ejecutaba el procedimiento requerido. Para más información, revisa el error que aparece más abajo.'), + E_RECOVERABLE_ERROR => array( 1, 'Error Recuperable', 'Se detectó un error que evitó que esta página cargara. Si el problema persiste, contacta con el administrador de la web.'), + E_ERROR => array( 1, 'Error Fatal', ''), + E_USER_ERROR => array( 1, 'Error Fatal', ''), + E_PARSE => array( 1, 'Error de Syntaxis', ''), + E_WARNING => array( 1, 'Advertencia', ''), + E_USER_WARNING => array( 1, 'Advertencia', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/event.php b/lib/kohana/system/i18n/es_ES/event.php new file mode 100644 index 0000000..c990771 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/event.php @@ -0,0 +1,7 @@ + 'Fallo el intento de añadir el sujeto %s a %s. Los sujetos deben extender la clase Event_Subject.', + 'invalid_observer' => 'Fallo el intento de añadir el observador %s a %s. Los observadores deben extender la clase Event_Observer.', +); diff --git a/lib/kohana/system/i18n/es_ES/image.php b/lib/kohana/system/i18n/es_ES/image.php new file mode 100644 index 0000000..2b8f6a6 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/image.php @@ -0,0 +1,33 @@ + 'La librería &8220;Image&8221; requiere la función PHP getimagesize, que no parece estar disponible en tu instalación.', + 'unsupported_method' => 'El driver que has elegido en la configuración no soporta el tipo de transformación %s.', + 'file_not_found' => 'La imagen especificada, %s no se ha encontrado. Por favor, verifica que existe utilizando file_exists() antes de manipularla.', + 'type_not_allowed' => 'El tipo de imagen especificado, %s, no es un tipo de imagen permitido.', + 'invalid_width' => 'El ancho que has especificado, %s, no es valido.', + 'invalid_height' => 'El alto que has especificado, %s, no es valido.', + 'invalid_dimensions' => 'Las dimensiones que has especificado para %s no son validas.', + 'invalid_master' => 'The master dim specified is not valid.', + 'invalid_flip' => 'La dirección de rotación especificada no es valida.', + 'directory_unwritable' => 'El directorio especificado, %s, no tiene permisos de escritura.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'El directorio de ImageMagick especificado, no contiene el programa requerido, %s.', + ), + + // GraphicsMagick specific messages + 'graphicsmagick' => array + ( + 'not_found' => 'El directorio de GraphicsMagick especificado, no contiene el programa requerido, %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'La librería &8220;Image&8221; requiere GD2. Por favor, lee http://php.net/gd_info para más información.', + ), +); diff --git a/lib/kohana/system/i18n/es_ES/orm.php b/lib/kohana/system/i18n/es_ES/orm.php new file mode 100644 index 0000000..24070e9 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/orm.php @@ -0,0 +1,3 @@ + 'El grupo %s no esta definido en la configuracion de la paginacion.', + 'page' => 'página', + 'pages' => 'páginas', + 'item' => 'elemento', + 'items' => 'elementos', + 'of' => 'de', + 'first' => 'primero', + 'last' => 'último', + 'previous' => 'anterior', + 'next' => 'siguiente', +); diff --git a/lib/kohana/system/i18n/es_ES/profiler.php b/lib/kohana/system/i18n/es_ES/profiler.php new file mode 100644 index 0000000..506cf65 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/profiler.php @@ -0,0 +1,15 @@ + 'Benchmarks', + 'post_data' => 'Datos Posteados', + 'no_post' => 'No hay datos posteados', + 'session_data' => 'Datos de sesión', + 'no_session' => 'No hay datos de sesión', + 'queries' => 'Consultas a la base de datos', + 'no_queries' => 'No hay consultas a la base de datos', + 'no_database' => 'No se encuentra la base de datos', + 'cookie_data' => 'Datos de la cookie', + 'no_cookie' => 'No se encuentran los datos de la cookie', +); diff --git a/lib/kohana/system/i18n/es_ES/session.php b/lib/kohana/system/i18n/es_ES/session.php new file mode 100644 index 0000000..2f503c2 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/session.php @@ -0,0 +1,6 @@ + 'El parametro session_name, %s, no es valido. Solo debe contener caracteres alfanumericos y guiones bajos. Tambien al menos uno debe de ser una letra.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/swift.php b/lib/kohana/system/i18n/es_ES/swift.php new file mode 100644 index 0000000..79fa6f4 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/swift.php @@ -0,0 +1,6 @@ + 'Ocurrió un error mientras se realizaba el envio del mensaje de correo.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/upload.php b/lib/kohana/system/i18n/es_ES/upload.php new file mode 100644 index 0000000..57bbec4 --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/upload.php @@ -0,0 +1,6 @@ + 'El directorio seleccionado, %s, no tiene permisos de escritura.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/es_ES/validation.php b/lib/kohana/system/i18n/es_ES/validation.php new file mode 100644 index 0000000..9cb114a --- /dev/null +++ b/lib/kohana/system/i18n/es_ES/validation.php @@ -0,0 +1,41 @@ + 'La regla de validación usada es invalida: %s', + 'i18n_array' => 'La clave %s i18n debe de ser un array para ser utilizado en la regla in_lang', + 'not_callable' => 'La llamada de retorno %s utilizada para la validación no puede ser llamada', + + // General errors + 'unknown_error' => 'Error de validación desconocido al comprobar el campo %s.', + 'required' => 'El campo %s es obligatorio.', + 'min_length' => 'El campo %s debe tener un mínimo de %d caracteres.', + 'max_length' => 'El campo %s debe tener un máximo de %d caracteres.', + 'exact_length' => 'El campo %s debe tener exactamente %d caracteres.', + 'in_array' => 'El campo %s debe ser seleccionado de las opciones listadas.', + 'matches' => 'El campo %s debe conincidir con el campo %s.', + 'valid_url' => 'El campo %s debe contener una url valida, empezando con %s://.', + 'valid_email' => 'El campo %s debe contener una dirección de email valida.', + 'valid_ip' => 'El campo %s debe contener una dirección IP valida.', + 'valid_type' => 'El campo %s debe contener unicamente %s.', + 'range' => 'El campo %s debe estar entre los rangos especificados.', + 'regex' => 'El campo %s no coincide con los datos aceptados.', + 'depends_on' => 'El campo %s depende del campo %s.', + + // Upload errors + 'user_aborted' => 'El envio del archivo %s fue abortado antes de completarse.', + 'invalid_type' => 'El archivo %s no es un tipo de archivo permitido.', + 'max_size' => 'El archivo %s que estas enviando es muy grande. El tamaño máximo es de %s.', + 'max_width' => 'El archivo %s debe tener como ancho máximo %s, y tiene %spx.', + 'max_height' => 'El archivo %s debe tener como alto máximo %s, y tiene %spx.', + 'min_width' => 'El archivo %s que estas enviando es muy pequeño. El ancho mínimo permitido es de %spx.', + 'min_height' => 'El archivo %s que estas enviando es muy pequeño. El alto mínimo permitido es de %spx.', + + // Field types + 'alpha' => 'caracteres del alfabeto', + 'alpha_numeric' => 'caracteres del alfabeto y numericos', + 'alpha_dash' => 'caracteres del alfabeto, guiones y subrayado', + 'digit' => 'digitos', + 'numeric' => 'caracteres numéricos', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/fr_FR/cache.php b/lib/kohana/system/i18n/fr_FR/cache.php new file mode 100644 index 0000000..f6ae08d --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/cache.php @@ -0,0 +1,10 @@ + 'Le groupe %s n\'est pas défini dans votre configuration.', + 'extension_not_loaded' => 'l\'extension PHP %s doit être chargée pour utiliser ce driver.', + 'unwritable' => 'Le chemin %s configuré pour le cache n\'est pas accessible en écriture.', + 'resources' => 'La mise en cache des ressources est impossible car elles n\'ont pas pu être sérialisées.', + 'driver_error' => '%s' +); diff --git a/lib/kohana/system/i18n/fr_FR/calendar.php b/lib/kohana/system/i18n/fr_FR/calendar.php new file mode 100644 index 0000000..bf1d52c --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/calendar.php @@ -0,0 +1,59 @@ + 'Di', + 'mo' => 'Lu', + 'tu' => 'Ma', + 'we' => 'Me', + 'th' => 'Je', + 'fr' => 'Ve', + 'sa' => 'Sa', + + // Short day names + 'sun' => 'Dim', + 'mon' => 'Lun', + 'tue' => 'Mar', + 'wed' => 'Mer', + 'thu' => 'Jeu', + 'fri' => 'Ven', + 'sat' => 'Sam', + + // Long day names + 'sunday' => 'Dimanche', + 'monday' => 'Lundi', + 'tuesday' => 'Mardi', + 'wednesday' => 'Mercredi', + 'thursday' => 'Jeudi', + 'friday' => 'Vendredi', + 'saturday' => 'Samedi', + + // Short month names + 'jan' => 'Jan', + 'feb' => 'Fév', + 'mar' => 'Mar', + 'apr' => 'Avr', + 'may' => 'Mai', + 'jun' => 'Jui', + 'jul' => 'Juil', + 'aug' => 'Aoû', + 'sep' => 'Sep', + 'oct' => 'Oct', + 'nov' => 'Nov', + 'dec' => 'Déc', + + // Long month names + 'january' => 'Janvier', + 'february' => 'Février', + 'march' => 'Mars', + 'april' => 'Avril', + 'mayl' => 'Mai', + 'june' => 'Juin', + 'july' => 'Juillet', + 'august' => 'Août', + 'september' => 'Septembre', + 'october' => 'Octobre', + 'november' => 'Novembre', + 'december' => 'Décembre' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/fr_FR/captcha.php b/lib/kohana/system/i18n/fr_FR/captcha.php new file mode 100644 index 0000000..2b1af29 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/captcha.php @@ -0,0 +1,33 @@ + 'Le fichier spécifié, %s, est introuvable. Merci de vérifier que les fichiers existent, grâce à la fontion file_exists, avant de les utiliser.', + 'requires_GD2' => 'La librairie Captcha requiert GD2 avec le support FreeType installé. Voir http://php.net/gd_info pour de plus amples renseignements, merci.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'le', 'il', 'ou', 'an', + 'moi', 'age', 'coq', 'ici', 'bob', 'eau', + 'cake', 'agir', 'bain', 'dodo', 'elle', 'faux', + 'hello', 'monde', 'terre', 'adore', 'baton', 'chats', + 'absent', 'cendre', 'banane', 'cirque', 'violet', 'disque', + 'abricot', 'billets', 'cendres', 'frisson', 'nations', 'respect', + 'accepter', 'batterie', 'collines', 'desserts', 'feuilles', 'sandwich', + 'acheteurs', 'tellement', 'renverser', 'histoires', 'dimanches', 'cinquante', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Détestez-vous le spam? (oui ou non)', 'oui'), + array('Etes vous un robot? (oui ou non)', 'non'), + array('Le feu est... (chaud ou froid)', 'chaud'), + array('La saison après l\'automne est l\'...', 'hiver'), + array('Quel jour est-il?', strftime('%A')), + array('Quel est le mois en cours?', strftime('%B')), + ) +); diff --git a/lib/kohana/system/i18n/fr_FR/core.php b/lib/kohana/system/i18n/fr_FR/core.php new file mode 100644 index 0000000..53d88be --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/core.php @@ -0,0 +1,34 @@ + 'Il ne peut y avoir qu\'une instance de Kohana par page.', + 'uncaught_exception' => 'Uncaught %s: %s dans le fichier %s à la ligne %s', + 'invalid_method' => 'La méthode %s appelée dans %s est invalide.', + 'invalid_property' => 'La propriété %s n\'existe pas dans la classe %s.', + 'log_dir_unwritable' => 'Le répertoire spécifié dans votre fichier de configuration pour le fichier de log ne pointe pas vers un répertoire accessible en écriture.', + 'resource_not_found' => 'La ressource %s, %s, n\'a pas été trouvée.', + 'invalid_filetype' => 'Le type de ficher demandé, .%s, n\'est pas autorisé dans le fichier de configuration des vues (view configuration file).', + 'view_set_filename' => 'Vous devez renseigner le nom de la vue avant d\'appeller la méthode render', + 'no_default_route' => 'Aucune route par défaut n\a été définie. Veuillez la spécifer dans le fichier config/routes.php.', + 'no_controller' => 'Kohana n\'a pu déterminer aucun controlleur pour effectuer la requête: %s.', + 'page_not_found' => 'La page demandée %s n\'a pu être trouvée.', + 'stats_footer' => 'Chargé en {execution_time} secondes, {memory_usage} de mémoire utilisée. Généré par Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Impossible de terminer la requête.', + 'errors_disabled' => 'Vous pouvez aller sur la page d\'accueil ou essayer encore.', + + // Drivers + 'driver_implements' => 'Le driver %s de la librairie %s doit implémenter l\'interface %s.', + 'driver_not_found' => 'Le driver %s de la librairie %s est introuvable.', + + // Resource names + 'config' => 'fichier de configuration', + 'controller' => 'contrôleur', + 'helper' => 'helper', + 'library' => 'librairie', + 'driver' => 'driver', + 'model' => 'modèle', + 'view' => 'vue', +); diff --git a/lib/kohana/system/i18n/fr_FR/database.php b/lib/kohana/system/i18n/fr_FR/database.php new file mode 100644 index 0000000..643a4fe --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/database.php @@ -0,0 +1,15 @@ + 'Le groupe de base de données %s n\'existe pas dans votre fichier de configuration.', + 'error' => 'L\'erreur SQL suivante est survenue: %s', + 'connection' => 'Il y a eu une erreur lors de la connexion à la base de données: %s', + 'invalid_dsn' => 'Le DSN que vous avez spécifié n\'est pas valide: %s', + 'must_use_set' => 'Vous devez spécifier une clause SET pour votre requête.', + 'must_use_where' => 'Vous devez spécifier une clause WHERE pour votre requête.', + 'must_use_table' => 'Vous devez spécifier une table de la base de données pour votre requête.', + 'table_not_found' => 'La table %s n\'existe pas dans votre base de données.', + 'not_implemented' => 'La méthode %s que vous avez appelée n\'est pas supportée par le driver de base de données.', + 'result_read_only' => 'Les résultats de la requête sont en lecture seule.' +); diff --git a/lib/kohana/system/i18n/fr_FR/encrypt.php b/lib/kohana/system/i18n/fr_FR/encrypt.php new file mode 100644 index 0000000..0ca75d5 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/encrypt.php @@ -0,0 +1,8 @@ + 'Le groupe %s n\'est pas défini dans votre configuration.', + 'requires_mcrypt' => 'Afin de pouvoir utiliser la librairie de chiffrement (Encrypt library), mcrypt doit être activé dans votre installation PHP.', + 'no_encryption_key' => 'Afin de pouvoir utiliser la librairie de chiffrement (Encrypt library), vous devez définir une clé de chiffrement dans votre fichier de configuration.' +); diff --git a/lib/kohana/system/i18n/fr_FR/errors.php b/lib/kohana/system/i18n/fr_FR/errors.php new file mode 100644 index 0000000..4f4385b --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Framework Error', 'Veuillez vous référer à la documentation de Kohana pour plus d\'informations sur l\'erreur suivante.'), + E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'La page demandée n\'a pas été trouvée. Elle a peut-être été déplacée, supprimée, ou archivée.'), + E_DATABASE_ERROR => array( 1, 'Database Error', 'Une erreur de base de données est survenue lors de l\'exécution de la procèdure demandée. Veuillez vous référer à l\'erreur renvoyée ci-dessous pour plus d\'informations.'), + E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Une erreur a empêché le chargement de la page. Si le problème persiste, veuillez contacter l\'administrateur du site.'), + E_ERROR => array( 1, 'Fatal Error', ''), + E_USER_ERROR => array( 1, 'Fatal Error', ''), + E_PARSE => array( 1, 'Syntax Error', ''), + E_WARNING => array( 1, 'Warning Message', ''), + E_USER_WARNING => array( 1, 'Warning Message', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), +); diff --git a/lib/kohana/system/i18n/fr_FR/event.php b/lib/kohana/system/i18n/fr_FR/event.php new file mode 100644 index 0000000..65dec21 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/event.php @@ -0,0 +1,7 @@ + 'Le sujet %s n\'a pas pu peut être attaché à %s. Les sujets doivent étendre la classe Event_Subject.', + 'invalid_observer' => 'L\'observeur %s n\'a pas pu peut être attaché à %s. Les observeurs doivent étendre la classe Event_Observer.', +); diff --git a/lib/kohana/system/i18n/fr_FR/image.php b/lib/kohana/system/i18n/fr_FR/image.php new file mode 100644 index 0000000..aa1c4ad --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/image.php @@ -0,0 +1,33 @@ + 'Le répertoire %s spécifié n\'est pas accessible en écriture.', + 'getimagesize_missing' => 'La librairie d\'image requiert la function PHP getimagesize. Celle-ci n\'est pas disponible dans votre installation.', + 'unsupported_method' => 'Le pilote configuré ne supporte pas la transformation d\'image %s.', + 'file_not_found' => 'L\'image spécifié %s n\'a pas été trouvée. Merci de vérifier que l\'image existe bien avec la fonction file_exists avant sa manipulation.', + 'type_not_allowed' => 'L\'image spécifié %s n\'est pas d\'un type autorisé.', + 'invalid_width' => 'La largeur que vous avez spécifiée, %s, est invalide.', + 'invalid_height' => 'La hauteur que vous avez spécifiée, %s, est invalide.', + 'invalid_dimensions' => 'Les dimensions spécifiées pour %s ne sont pas valides.', + 'invalid_master' => 'La dimension principale (master dim) n\'est pas valide.', + 'invalid_flip' => 'La direction de rotation spécifiée n\'est pas valide.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'Le répertoire ImageMagick spécifié ne contient pas le programme requis %s.', + ), + + // GraphicsMagick specific messages + 'graphicsmagick' => array + ( + 'not_found' => 'Le répertoire GraphicsMagick spécifié ne contient pas le programme requis %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'La librairie d\'image requiert GD2. Veuillez consulter http://php.net/gd_info pour de plus amples informations.', + ), +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/fr_FR/orm.php b/lib/kohana/system/i18n/fr_FR/orm.php new file mode 100644 index 0000000..9c9d234 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/orm.php @@ -0,0 +1,3 @@ + 'Le groupe %s n\'est pas défini dans votre configuration de la pagination.', + 'page' => 'page', + 'pages' => 'pages', + 'item' => 'résultat', + 'items' => 'résultats', + 'of' => 'sur', + 'first' => 'premier', + 'last' => 'dernier', + 'previous' => 'précédent', + 'next' => 'suivant', +); diff --git a/lib/kohana/system/i18n/fr_FR/profiler.php b/lib/kohana/system/i18n/fr_FR/profiler.php new file mode 100644 index 0000000..02a95d1 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/profiler.php @@ -0,0 +1,15 @@ + 'Benchmarks', + 'post_data' => 'Données POST', + 'no_post' => 'Aucune donnée POST', + 'session_data' => 'Données de session', + 'no_session' => 'Aucune donnée de session', + 'queries' => 'Requêtes', + 'no_queries' => 'Aucune requête', + 'no_database' => 'Base de données non chargée', + 'cookie_data' => 'Données du Cookie', + 'no_cookie' => 'Aucune donnée de Cookie', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/fr_FR/session.php b/lib/kohana/system/i18n/fr_FR/session.php new file mode 100644 index 0000000..70700a6 --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/session.php @@ -0,0 +1,6 @@ + 'Le nom de session "session_name", %s, est invalide. Il doit contenir uniquement des caractères alphanumériques et au moins une lettre doit être présente.', +); diff --git a/lib/kohana/system/i18n/fr_FR/swift.php b/lib/kohana/system/i18n/fr_FR/swift.php new file mode 100644 index 0000000..5f31f9d --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/swift.php @@ -0,0 +1,6 @@ + 'Une erreur est survenue lors de l\'envoi du message.' +); diff --git a/lib/kohana/system/i18n/fr_FR/upload.php b/lib/kohana/system/i18n/fr_FR/upload.php new file mode 100644 index 0000000..3cace0e --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/upload.php @@ -0,0 +1,6 @@ + 'Le répertoire de destination pour l\'upload, %s, ne semble pas être accessible en écriture.', +); diff --git a/lib/kohana/system/i18n/fr_FR/validation.php b/lib/kohana/system/i18n/fr_FR/validation.php new file mode 100644 index 0000000..9cb17be --- /dev/null +++ b/lib/kohana/system/i18n/fr_FR/validation.php @@ -0,0 +1,41 @@ + 'La règle de validation %s utilisée est invalide', + 'i18n_array' => 'La clé i18n %s doit être un tableau pour pouvoir être utilisée avec la règle in_lang', + 'not_callable' => 'La callback %s utilisé pour la Validation n\'est pas appellable', + + // General errors + 'unknown_error' => 'Erreur de validation inconnue lors de la validation du champ %s.', + 'required' => 'Le champ %s est requis.', + 'min_length' => 'Le champ %s doit contenir au minimum %d caractères.', + 'max_length' => 'Le champ %s ne peut contenir plus de %d caractères.', + 'exact_length' => 'Le champ %s doit contenir exactement %d caractères.', + 'in_array' => 'Le champ %s doit être sélectionné dans parmi les options listées.', + 'matches' => 'Le champ %s doit correspondre au champ %s.', + 'valid_url' => 'Le champ %s doit contenir une URL valide.', + 'valid_email' => 'Le champ %s doit contenir une adresse email valide.', + 'valid_ip' => 'Le champ %s doit contenir une adresse IP valide.', + 'valid_type' => 'Le champ %s doit contenir uniquement %s caractères', + 'range' => 'Le champ %s doit être situé dans la plage de valeurs spécifiée.', + 'regex' => 'Le champ %s ne correspond pas aux valeurs acceptées.', + 'depends_on' => 'Le champ %s est dépendant du champ %s.', + + // Upload errors + 'user_aborted' => 'L\'envoi du fichier %s sur le serveur a échoué.', + 'invalid_type' => 'Le type du fichier %s n\'est pas autorisé.', + 'max_size' => 'La taille du fichier %s que vous tentez d\'envoyer est trop volumineuse. La taille maximale autorisée est de %s', + 'max_width' => 'La largeur de l\'image %s que vous envoyez est trop grande. La largeur maximale autorisée est de %spx', + 'max_height' => 'La hauteur de l\'image %s que vous envoyez est trop grande. La hauteur maximale autorisée est de %spx', + 'min_width' => 'La largeur de l\'image %s que vous envoyez n\'est pas assez grande. La largeur minimale demandée est de %spx', + 'min_height' => 'La hauteur de l\'image %s que vous envoyez n\'est pas assez grande. La hauteur minimale demandée est de %spx', + + // Field types + 'alpha' => 'alphabétiques', + 'alpha_numeric' => 'alphabétiques et numériques', + 'alpha_dash' => 'alphabétiques, tirets haut ou tirets bas (underscore)', + 'digit' => 'digitaux', + 'numeric' => 'numériques', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/cache.php b/lib/kohana/system/i18n/it_IT/cache.php new file mode 100644 index 0000000..c2e9687 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/cache.php @@ -0,0 +1,10 @@ + 'Il gruppo %s non è stato definito in configurazione.', + 'extension_not_loaded' => 'L\'estensione di PHP %s deve essere caricata per poter usare questo driver.', + 'unwritable' => 'La cartella di deposito, %s, non ha i permessi in scrittura.', + 'resources' => 'Risorsa non serializzabile. Impossibile immagazzinare.', + 'driver_error' => '%s', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/calendar.php b/lib/kohana/system/i18n/it_IT/calendar.php new file mode 100644 index 0000000..98e61dd --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/calendar.php @@ -0,0 +1,59 @@ + 'Do', + 'mo' => 'Lu', + 'tu' => 'Ma', + 'we' => 'Me', + 'th' => 'Gi', + 'fr' => 'Ve', + 'sa' => 'Sa', + + // Short day names + 'sun' => 'Dom', + 'mon' => 'Lun', + 'tue' => 'Mar', + 'wed' => 'Mer', + 'thu' => 'Gio', + 'fri' => 'Ven', + 'sat' => 'Sab', + + // Long day names + 'sunday' => 'Domenica', + 'monday' => 'Lunedì', + 'tuesday' => 'Martedì', + 'wednesday' => 'Mercoledì', + 'thursday' => 'Giovedì', + 'friday' => 'Venerdì', + 'saturday' => 'Sabato', + + // Short month names + 'jan' => 'Gen', + 'feb' => 'Feb', + 'mar' => 'Mar', + 'apr' => 'Apr', + 'may' => 'Mag', + 'jun' => 'Giu', + 'jul' => 'Lug', + 'aug' => 'Ago', + 'sep' => 'Set', + 'oct' => 'Ott', + 'nov' => 'Nov', + 'dec' => 'Dic', + + // Long month names + 'january' => 'Gennaio', + 'february' => 'Febbraio', + 'march' => 'Marzo', + 'april' => 'Aprile', + 'mayl' => 'Maggio', + 'june' => 'Giugno', + 'july' => 'Luglio', + 'august' => 'Agosto', + 'september' => 'Settembre', + 'october' => 'Ottobre', + 'november' => 'Novembre', + 'december' => 'Dicembre' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/captcha.php b/lib/kohana/system/i18n/it_IT/captcha.php new file mode 100644 index 0000000..57faa35 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/captcha.php @@ -0,0 +1,33 @@ + 'Il file specificato, %s, non è stato trovato. Verificarne l\'esistenza con file_exists prima di usarlo.', + 'requires_GD2' => 'La libreria Captcha richiede GD2 con supporto FreeType. Leggere http://php.net/gd_info per maggiori informazioni.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Detesti lo spam? (si o no)', 'si'), + array('Sei un robot? (si o no)', 'no'), + array('Il fuoco è... (caldo o freddo)', 'caldo'), + array('La stagione che viene dopo l\'autunno è...', 'inverno'), + array('Che giorno della settimana è oggi?', strftime('%A')), + array('In quale mese dell\'anno siamo?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/it_IT/core.php b/lib/kohana/system/i18n/it_IT/core.php new file mode 100644 index 0000000..662092d --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/core.php @@ -0,0 +1,34 @@ + 'Ci può essere una sola istanza di Kohana per ogni pagina richiesta.', + 'uncaught_exception' => 'Uncaught %s: %s in %s, linea %s', + 'invalid_method' => 'Metodo non valido %s chiamato in %s.', + 'invalid_property' => 'La proprietà %s non esiste nella classe %s.', + 'log_dir_unwritable' => 'Il parametro di configurazione log.directory non punta ad una cartella con permesso di scrittura.', + 'resource_not_found' => 'Il %s richiesto, %s, non è stato trovato.', + 'invalid_filetype' => 'Il tipo di file richiesto, .%s, non è presente nel file di configurazione.', + 'view_set_filename' => 'Bisogna definire il nome di una vista prima di chiamare il metodo render', + 'no_default_route' => 'Non è stato definito il default route in config/routes.php.', + 'no_controller' => 'Kohana non è in grado di determinare a quale controller inoltrare la richiesta: %s', + 'page_not_found' => 'La pagina richiesta, %s, non è stata trovata.', + 'stats_footer' => 'Caricato in {execution_time} secondi, usando {memory_usage} di memoria. Generato da Kohana v{kohana_version}.', + 'error_file_line' => 'Errore in %s linea: %s.', + 'stack_trace' => 'Tracciato', + 'generic_error' => 'Impossibile completare la richiesta', + 'errors_disabled' => 'Puoi andare alla pagina iniziale o ritentare.', + + // Drivers + 'driver_implements' => 'Il driver %s per la libreria %s non implementa l\'interfaccia %s', + 'driver_not_found' => 'Il driver %s per la libreria %s non è stato trovato', + + // Resource names + 'config' => 'file di configurazione', + 'controller' => 'controller', + 'helper' => 'helper', + 'library' => 'libreria', + 'driver' => 'driver', + 'model' => 'modello', + 'view' => 'vista', +); diff --git a/lib/kohana/system/i18n/it_IT/database.php b/lib/kohana/system/i18n/it_IT/database.php new file mode 100644 index 0000000..acd77ad --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/database.php @@ -0,0 +1,15 @@ + 'Il gruppo %s non è stato definito nel file di configurazione.', + 'error' => 'Si è verificato un errore SQL: %s', + 'connection' => 'Si è verificato un errore durante la connessione al database: %s', + 'invalid_dsn' => 'Il DSN fornito non è valido: %s', + 'must_use_set' => 'È necessario definire una clausola SET per la query.', + 'must_use_where' => 'È necessario definire una clausola WHERE per la query.', + 'must_use_table' => 'È necessario definire una tabella per la query.', + 'table_not_found' => 'La tabella %s non esiste nella base di dati.', + 'not_implemented' => 'Il metodo chiamato, %s, non è supportato da questo driver.', + 'result_read_only' => 'Il risultato della query è in sola lettura.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/encrypt.php b/lib/kohana/system/i18n/it_IT/encrypt.php new file mode 100644 index 0000000..8f2b63d --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/encrypt.php @@ -0,0 +1,8 @@ + 'Il gruppo %s non è definito nel file di configurazione.', + 'requires_mcrypt' => 'L\'uso della libreria Encrypt richiede l\'abilitazione di mcrypt.', + 'no_encryption_key' => 'Per usare la libreria Encrypt bisogna definire una chiave di codifica nel file di configurazione.' +); diff --git a/lib/kohana/system/i18n/it_IT/errors.php b/lib/kohana/system/i18n/it_IT/errors.php new file mode 100644 index 0000000..1df3e7a --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Errore del Framework', 'Controlla la documentazione di Kohana per informazioni circa il seguente errore.'), + E_PAGE_NOT_FOUND => array( 1, 'Pagina non trovata', 'La pagina richiesta non è stata trovata. Potrebbe essere stata spostata, rimossa o archiviata.'), + E_DATABASE_ERROR => array( 1, 'Errore del Database', 'Si è verificato un errore durante l\'esecuzione della procedura richiesta. Per maggiori informazioni fare riferimento al messaggio sottostante.'), + E_RECOVERABLE_ERROR => array( 1, 'Errore Recuperabile', 'Un errore ha impedito il caricamento della pagina. Se l\'errore persiste contattare l\'amministratore del sito.'), + E_ERROR => array( 1, 'Errore Fatale', ''), + E_USER_ERROR => array( 1, 'Errore Fatale', ''), + E_PARSE => array( 1, 'Errore di Sintassi', ''), + E_WARNING => array( 1, 'Avviso', ''), + E_USER_WARNING => array( 1, 'Avviso', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/event.php b/lib/kohana/system/i18n/it_IT/event.php new file mode 100644 index 0000000..13c5374 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/event.php @@ -0,0 +1,7 @@ + 'Fallito il tentativo di aggiungere il soggetto %s a %s. I soggetti devono estendere la classe Event_Subject.', + 'invalid_observer' => 'Fallito il tentativo di aggiungere l\'observer %s a %s. Gli observer devono estendere la classe Event_Observer.', +); diff --git a/lib/kohana/system/i18n/it_IT/image.php b/lib/kohana/system/i18n/it_IT/image.php new file mode 100644 index 0000000..493b027 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/image.php @@ -0,0 +1,33 @@ + 'La libreria Image richiede la funzione PHP getimagesize, che non è disponibile nella tua intallazione.', + 'unsupported_method' => 'Il driver impostato in configurazione non supporta il tipo di trasformazione %s.', + 'file_not_found' => 'L\'immagine specificata, %s, non è stata trovata. Verificarne l\'esistenza con file_exists prima di manipolarla.', + 'type_not_allowed' => 'Il tipo d\'immagine specificato, %s, non è permesso.', + 'invalid_width' => 'La larghezza specificata, %s, non è valida.', + 'invalid_height' => 'L\'altezza specificata, %s, non è valida.', + 'invalid_dimensions' => 'Le dimensioni specificate per %s non sono valide.', + 'invalid_master' => 'Master dimension specificato non valido.', + 'invalid_flip' => 'La direzione di rotazione specificata non è valida.', + 'directory_unwritable' => 'La directory specificata, %s, non consente la scrittura.', + + // Messaggi specifici per ImageMagick + 'imagemagick' => array + ( + 'not_found' => 'La cartella di ImageMagick specificata non contiene il programma richiesto, %s.', + ), + + // Messaggi specifici per GraphicsMagick + 'graphicsmagick' => array + ( + 'not_found' => 'La cartella di GraphicsMagick specificata non contiene il programma richiesto, %s.', + ), + + // Messaggi specifici per GD + 'gd' => array + ( + 'requires_v2' => 'La libreria Image richiede GD2. Leggere http://php.net/gd_info per maggiori informazioni.', + ), +); diff --git a/lib/kohana/system/i18n/it_IT/orm.php b/lib/kohana/system/i18n/it_IT/orm.php new file mode 100644 index 0000000..09e3a79 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/orm.php @@ -0,0 +1,3 @@ + 'Il gruppo %s non è stato definito nel file di configurazione per la paginazione.', + 'page' => 'pagina', + 'pages' => 'pagine', + 'item' => 'elemento', + 'items' => 'elementi', + 'of' => 'di', + 'first' => 'primo', + 'last' => 'ultimo', + 'previous' => 'precedente', + 'next' => 'successivo', +); diff --git a/lib/kohana/system/i18n/it_IT/profiler.php b/lib/kohana/system/i18n/it_IT/profiler.php new file mode 100644 index 0000000..5cdd502 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/profiler.php @@ -0,0 +1,15 @@ + 'Benchmarks', + 'post_data' => 'Dati postati', + 'no_post' => 'Non ci sono dati postati', + 'session_data' => 'Dati di sessione', + 'no_session' => 'Non ci sono dati di sessione', + 'queries' => 'Query al database', + 'no_queries' => 'Non ci sono query al database', + 'no_database' => 'Database non caricato', + 'cookie_data' => 'Dati del cookie', + 'no_cookie' => 'I dati del cookie non sono stati trovati', +); diff --git a/lib/kohana/system/i18n/it_IT/session.php b/lib/kohana/system/i18n/it_IT/session.php new file mode 100644 index 0000000..d831894 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/session.php @@ -0,0 +1,6 @@ + 'Il parametro session_name, %s, non è valido. Può contenere solo caratteri alfanumerici o il trattino basso. Almeno una lettera deve essere presente.', +); diff --git a/lib/kohana/system/i18n/it_IT/swift.php b/lib/kohana/system/i18n/it_IT/swift.php new file mode 100644 index 0000000..9f83b40 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/swift.php @@ -0,0 +1,6 @@ + 'Si è verificato un errore durante l\'invio del messaggio di posta elettronica.' +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/it_IT/upload.php b/lib/kohana/system/i18n/it_IT/upload.php new file mode 100644 index 0000000..9ea084f --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/upload.php @@ -0,0 +1,6 @@ + 'La cartella di destinazione, %s, non sembra avere i permessi in scrittura.', +); diff --git a/lib/kohana/system/i18n/it_IT/validation.php b/lib/kohana/system/i18n/it_IT/validation.php new file mode 100644 index 0000000..472a2e5 --- /dev/null +++ b/lib/kohana/system/i18n/it_IT/validation.php @@ -0,0 +1,41 @@ + 'Regola di validazione usata non valida: %s', + 'i18n_array' => 'Il parametro i18n %s deve essere un array per essere utilizzato con la regola in_lang', + 'not_callable' => 'La callback %s usata per la Validation non puo essere richiamata', + + // Errori generici + 'unknown_error' => 'Errore sconosciuto durante la validazione del campo %s.', + 'required' => 'Il campo %s è obbligatorio.', + 'min_length' => 'Il campo %s deve essere lungo almeno %d caratteri.', + 'max_length' => 'Il campo %s non deve superare i %d caratteri.', + 'exact_length' => 'Il campo %s deve contenere esattamente %d caratteri.', + 'in_array' => 'Il campo %s deve essere selezionato dalla lista delle opzioni.', + 'matches' => 'Il campo %s deve coincidere con il campo %s.', + 'valid_url' => 'Il campo %s deve contenere un URL valido.', + 'valid_email' => 'Il campo %s deve contenere un indirizzo email valido.', + 'valid_ip' => 'Il campo %s deve contenere un indirizzo IP valido.', + 'valid_type' => 'Il campo %s deve contenere solo i caratteri %s.', + 'range' => 'Il campo %s deve trovarsi negli intervalli specificati.', + 'regex' => 'Il campo %s non coincide con i dati accettati.', + 'depends_on' => 'Il campo %s dipende dal campo %s.', + + // Errori di upload + 'user_aborted' => 'Il caricamento del file %s è stato interrotto.', + 'invalid_type' => 'Il file %s non è un tipo di file permesso.', + 'max_size' => 'Il file %s inviato è troppo grande. La dimensone massima consentita è %s.', + 'max_width' => 'Il file %s inviato è troppo grande. La larghezza massima consentita è %spx.', + 'max_height' => 'Il file %s inviato è troppo grande. L\'altezza massima consentita è %spx.', + 'min_width' => 'Il file %s inviato è troppo piccolo. La larghezza minima consentita è %spx.', + 'min_height' => 'Il file %s inviato è troppo piccolo. L\'altezza minima consentita è %spx.', + + // Tipi di valore dei campi + 'alpha' => 'alfabetico', + 'alpha_numeric' => 'alfanumerico', + 'alpha_dash' => 'alfabetico, trattino e sottolineato', + 'digit' => 'cifra', + 'numeric' => 'numerico', +); diff --git a/lib/kohana/system/i18n/nl_NL/cache.php b/lib/kohana/system/i18n/nl_NL/cache.php new file mode 100644 index 0000000..b6f1631 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/cache.php @@ -0,0 +1,10 @@ + 'De %s groep is niet gedefinieerd in uw configuratie.', + 'extension_not_loaded' => 'De %s PHP extensie moet geladen zijn om deze driver te gebruiken.', + 'unwritable' => 'De geconfigureerde opslaglocatie, %s, is niet schrijfbaar.', + 'resources' => 'Het cachen van resources is onmogelijk omdat resources niet geserialized kunnen worden.', + 'driver_error' => '%s', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/calendar.php b/lib/kohana/system/i18n/nl_NL/calendar.php new file mode 100644 index 0000000..ce8fa88 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/calendar.php @@ -0,0 +1,59 @@ + 'zo', + 'mo' => 'ma', + 'tu' => 'di', + 'we' => 'wo', + 'th' => 'do', + 'fr' => 'vr', + 'sa' => 'za', + + // Short day names + 'sun' => 'zon', + 'mon' => 'maa', + 'tue' => 'din', + 'wed' => 'woe', + 'thu' => 'don', + 'fri' => 'vri', + 'sat' => 'zat', + + // Long day names + 'sunday' => 'zondag', + 'monday' => 'maandag', + 'tuesday' => 'dinsdag', + 'wednesday' => 'woensdag', + 'thursday' => 'donderdag', + 'friday' => 'vrijdag', + 'saturday' => 'zaterdag', + + // Short month names + 'jan' => 'jan', + 'feb' => 'feb', + 'mar' => 'maa', + 'apr' => 'apr', + 'may' => 'mei', + 'jun' => 'jun', + 'jul' => 'jul', + 'aug' => 'aug', + 'sep' => 'sep', + 'oct' => 'okt', + 'nov' => 'nov', + 'dec' => 'dec', + + // Long month names + 'january' => 'januari', + 'february' => 'februari', + 'march' => 'maart', + 'april' => 'april', + 'mayl' => 'mei', + 'june' => 'juni', + 'july' => 'juli', + 'august' => 'augustus', + 'september' => 'september', + 'october' => 'oktober', + 'november' => 'november', + 'december' => 'december', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/captcha.php b/lib/kohana/system/i18n/nl_NL/captcha.php new file mode 100644 index 0000000..842d5fb --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/captcha.php @@ -0,0 +1,33 @@ + 'Het opgegeven bestand, %s, werd niet gevonden. Controleer met file_exists() of bestanden bestaan, voordat je ze gebruikt.', + 'requires_GD2' => 'De Captcha library vereist GD2 met FreeType ondersteuning. Zie http://php.net/gd_info voor meer informatie.', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'ok', 'pc', 'nu', 'ik', + 'zon', 'kar', 'kat', 'bed', 'tof', 'hoi', + 'puin', 'hoop', 'mens', 'roof', 'auto', 'haar', + 'water', 'beter', 'aarde', 'appel', 'mango', 'liter', + 'ananas', 'bakker', 'wekker', 'kroket', 'zingen', 'dansen', + 'fietsen', 'zwemmen', 'kolonel', 'potlood', 'kookpot', 'voetbal', + 'barbecue', 'computer', 'generaal', 'koelkast', 'fietsers', 'spelling', + 'appelmoes', 'president', 'kangoeroe', 'frankrijk', 'luxemburg', 'apartheid', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Haat jij spam? (ja of nee)', 'ja'), + array('Ben jij een robot? (ja of nee)', 'nee'), + array('Vuur is... (heet of koud)', 'heet'), + array('Het seizoen na herfst is...', 'winter'), + array('Welke dag van de week is het vandaag?', strftime('%A')), + array('In welke maand van het jaar zijn we?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/nl_NL/core.php b/lib/kohana/system/i18n/nl_NL/core.php new file mode 100644 index 0000000..e3668af --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/core.php @@ -0,0 +1,34 @@ + 'Er kan maar één instantie van Kohana zijn per pagina oproep.', + 'uncaught_exception' => 'Uncaught %s: %s in bestand %s op lijn %s', + 'invalid_method' => 'Ongeldige method %s opgeroepen in %s.', + 'invalid_property' => 'De %s property bestaat niet in de %s class.', + 'log_dir_unwritable' => 'De log directory is niet schrijfbaar: %s', + 'resource_not_found' => 'De opgevraagde %s, %s, kon niet gevonden worden.', + 'invalid_filetype' => 'Het opgevraagde bestandstype, .%s, wordt niet toegestaan door het view configuratiebestand.', + 'view_set_filename' => 'Je moet de view bestandsnaam opgeven voordat je render aanroept.', + 'no_default_route' => 'Zet een default route in config/routes.php.', + 'no_controller' => 'Kohana kon geen controller aanduiden om deze pagina te verwerken: %s', + 'page_not_found' => 'De opgevraagde pagina, %s, kon niet gevonden worden.', + 'stats_footer' => 'Geladen in {execution_time} seconden, met een geheugengebruik van {memory_usage}. Aangedreven door Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Stack Trace', + 'generic_error' => 'Oproep kon niet afgewerkt worden', + 'errors_disabled' => 'Ga naar de homepage of probeer opnieuw.', + + // Drivers + 'driver_implements' => 'De %s driver voor de %s library moet de %s interface implementeren.', + 'driver_not_found' => 'De %s driver voor de %s library werd niet gevonden.', + + // Resource names + 'config' => 'configuratiebestand', + 'controller' => 'controller', + 'helper' => 'helper', + 'library' => 'library', + 'driver' => 'driver', + 'model' => 'model', + 'view' => 'view', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/database.php b/lib/kohana/system/i18n/nl_NL/database.php new file mode 100644 index 0000000..b520283 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/database.php @@ -0,0 +1,15 @@ + 'De %s groep is niet opgegeven in je configuratie.', + 'error' => 'Er was een SQL fout: %s', + 'connection' => 'Fout bij het verbinden met de database: %s', + 'invalid_dsn' => 'De DSN die je opgaf is ongeldig: %s', + 'must_use_set' => 'Je moet een SET clause opgeven voor je query.', + 'must_use_where' => 'Je moet een WHERE clause opgeven voor je query.', + 'must_use_table' => 'Je moet een database tabel opgeven voor je query.', + 'table_not_found' => 'De tabel %s bestaat niet in je database.', + 'not_implemented' => 'De method die je opriep, %s, wordt niet ondersteund door deze driver.', + 'result_read_only' => 'Query resultaten kunnen alleen maar gelezen worden.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/encrypt.php b/lib/kohana/system/i18n/nl_NL/encrypt.php new file mode 100644 index 0000000..980cdb1 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/encrypt.php @@ -0,0 +1,8 @@ + 'De %s groep is niet gedefinieerd in je configuratie.', + 'requires_mcrypt' => 'Om de Encrypt library te gebruiken, moet mcrypt ingeschakeld zijn in je PHP installatie.', + 'no_encryption_key' => 'Om de Encrypt library te gebruiken, moet je een encryption key zetten in je config bestand.', +); diff --git a/lib/kohana/system/i18n/nl_NL/errors.php b/lib/kohana/system/i18n/nl_NL/errors.php new file mode 100644 index 0000000..2d4dc94 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Framework Error', 'Bekijk de Kohana documentatie voor meer informatie over deze fout.'), + E_PAGE_NOT_FOUND => array( 1, 'Pagina Niet Gevonden', 'De opgevraagde pagina werd niet gevonden. Mogelijk werd deze verplaatst of verwijderd.'), + E_DATABASE_ERROR => array( 1, 'Database Error', 'Er vond een database fout plaats bij het verwerken van de opgeroepen procedure. Bekijk het errorbericht hieronder voor meer informatie.'), + E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Er vond een fout plaats waardoor deze pagina niet geladen kon worden. Als dit probleem aanhoudt, contacteer dan a.u.b. de website beheerder.'), + E_ERROR => array( 1, 'Fatal Error', ''), + E_USER_ERROR => array( 1, 'Fatal Error', ''), + E_PARSE => array( 1, 'Syntax Error', ''), + E_WARNING => array( 1, 'Warning Message', ''), + E_USER_WARNING => array( 1, 'Warning Message', ''), + E_STRICT => array( 2, 'Strict Mode Error', ''), + E_NOTICE => array( 2, 'Runtime Message', ''), +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/event.php b/lib/kohana/system/i18n/nl_NL/event.php new file mode 100644 index 0000000..2909e3f --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/event.php @@ -0,0 +1,7 @@ + 'Poging om ongeldig subject %s te binden aan %s mislukt. Subjects moeten de Event_Subject class extenden.', + 'invalid_observer' => 'Poging om ongeldige observer %s te binden aan %s mislukt. Observers moeten de Event_Subject class extenden.', +); diff --git a/lib/kohana/system/i18n/nl_NL/image.php b/lib/kohana/system/i18n/nl_NL/image.php new file mode 100644 index 0000000..e7c3cd7 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/image.php @@ -0,0 +1,27 @@ + 'De Image library vereist de getimagesize() functie en die is niet beschikbaar op dit systeem.', + 'unsupported_method' => 'De huidige Image driver ondersteunt volgende transformatie niet: %s.', + 'file_not_found' => 'De opgegeven afbeelding, %s, werd niet gevonden. Controleer a.u.b. eerst of afbeeldingen bestaan via de file_exists() functie voordat je ze begint te bewerken.', + 'type_not_allowed' => 'De opgegeven afbeelding, %s, is geen toegestaan afbeeldingstype.', + 'invalid_width' => 'De breedte die je opgaf, %s, is ongeldig.', + 'invalid_height' => 'De hoogte die je opgaf, %s, is ongeldig.', + 'invalid_dimensions' => 'De afmetingen die je opgaf voor %s zijn ongeldig.', + 'invalid_master' => 'De master afmeting die je opgaf, is ongeldig.', + 'invalid_flip' => 'De spiegelrichting die je opgaf, is ongeldig.', + 'directory_unwritable' => 'De opgegeven directory, %s, is niet schrijfbaar.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'De opgegeven ImageMagick directory bevat een vereist programma niet: %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'De Image library vereist GD2. Kijk op http://php.net/gd_info voor meer informatie.', + ), +); diff --git a/lib/kohana/system/i18n/nl_NL/orm.php b/lib/kohana/system/i18n/nl_NL/orm.php new file mode 100644 index 0000000..bea9238 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/orm.php @@ -0,0 +1,3 @@ + 'De %s groep werd niet gedefinieerd in uw pagination configuratie.', + 'page' => 'pagina', + 'pages' => 'pagina\'s', + 'item' => 'item', + 'items' => 'items', + 'of' => 'van', + 'first' => 'eerste', + 'last' => 'laatste', + 'previous' => 'vorige', + 'next' => 'volgende', +); diff --git a/lib/kohana/system/i18n/nl_NL/profiler.php b/lib/kohana/system/i18n/nl_NL/profiler.php new file mode 100644 index 0000000..03d0f84 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/profiler.php @@ -0,0 +1,15 @@ + 'Benchmarks', + 'post_data' => 'Post Data', + 'no_post' => 'Geen post data', + 'session_data' => 'Session Data', + 'no_session' => 'Geen session data', + 'queries' => 'Database Queries', + 'no_queries' => 'Geen queries', + 'no_database' => 'Database niet geladen', + 'cookie_data' => 'Cookie Data', + 'no_cookie' => 'Geen cookie data', +); diff --git a/lib/kohana/system/i18n/nl_NL/session.php b/lib/kohana/system/i18n/nl_NL/session.php new file mode 100644 index 0000000..391a46d --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/session.php @@ -0,0 +1,6 @@ + 'De sessienaam, %s, is ongeldig. Hij mag alleen maar bestaan uit alfanumerieke tekens en underscores. Hij moet ook minstens één letter bevatten.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/swift.php b/lib/kohana/system/i18n/nl_NL/swift.php new file mode 100644 index 0000000..bdd2af7 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/swift.php @@ -0,0 +1,6 @@ + 'Er vond een fout plaats bij het verzenden van de e-mail.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/upload.php b/lib/kohana/system/i18n/nl_NL/upload.php new file mode 100644 index 0000000..4a6549f --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/upload.php @@ -0,0 +1,6 @@ + 'De upload doelmap, %s, is niet schrijfbaar.', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/nl_NL/validation.php b/lib/kohana/system/i18n/nl_NL/validation.php new file mode 100644 index 0000000..4eb6c60 --- /dev/null +++ b/lib/kohana/system/i18n/nl_NL/validation.php @@ -0,0 +1,39 @@ + 'Ongeldige validatieregel gebruikt: %s', + + // Algemene errors + 'unknown_error' => 'Onbekende validatiefout bij het valideren van het %s veld.', + 'required' => 'Het %s veld is verplicht.', + 'min_length' => 'Het %s veld moet minstens %s karakters lang zijn.', + 'max_length' => 'Het %s veld mag maximum %s karakters lang zijn.', + 'exact_length' => 'Het %s veld moet exact %s karakters lang zijn.', + 'in_array' => 'Het %s veld moet geselecteerd worden uit de gegeven opties.', + 'matches' => 'Het %s veld moet overeenkomen met het %s veld.', + 'valid_url' => 'Het %s veld moet een geldige URL zijn.', + 'valid_email' => 'Het %s veld moet een geldig e-mailadres zijn.', + 'valid_ip' => 'Het %s veld moet een geldig IP-adres zijn.', + 'valid_type' => 'Het %s veld mag alleen maar %s karakters bevatten.', + 'range' => 'Het %s veld moet tussen bepaalde waardes liggen.', + 'regex' => 'Het %s veld valideert niet als geldige invoer.', + 'depends_on' => 'Het %s veld is afhankelijk van het %s veld.', + + // Upload errors + 'user_aborted' => 'Het uploaden van het %s bestand werd afgebroken.', + 'invalid_type' => 'Het bestandstype van het %s bestand is niet toegestaan.', + 'max_size' => 'Het %s bestand dat je wilde uploaden is te groot. De maximum toegelaten grootte is %s.', + 'max_width' => 'Het %s upgeloade bestand is te groot: maximum toegelaten breedte is %spx.', + 'max_height' => 'Het %s upgeloade bestand is te groot: maximum toegelaten hoogte is %spx.', + 'min_width' => 'Het %s upgeloade bestand is te klein: minimum toegelaten breedte is %spx.', + 'min_height' => 'Het %s upgeloade bestand is te klein: minimum toegelaten breedte is %spx.', + + // Field types + 'alpha' => 'alfabetisch', + 'alpha_numeric' => 'alfanumeriek', + 'alpha_dash' => 'alfabetisch, streepje, en underscore', + 'digit' => 'cijfers', + 'numeric' => 'getal', +); \ No newline at end of file diff --git a/lib/kohana/system/i18n/ru_RU/cache.php b/lib/kohana/system/i18n/ru_RU/cache.php new file mode 100644 index 0000000..855e834 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/cache.php @@ -0,0 +1,10 @@ + 'Группа "%s" не определена Вашей конфигурацией.', + 'extension_not_loaded' => 'Расширение PHP "%s" должно быть загружено для использования этого драйвера.', + 'unwritable' => 'Целевая директория хранения кеша, %s, не доступна для записи.', + 'resources' => 'Кеширование ресурсов невозможно, так как ресурсы не могут быть сериализованы.', + 'driver_error' => '%s', +); diff --git a/lib/kohana/system/i18n/ru_RU/calendar.php b/lib/kohana/system/i18n/ru_RU/calendar.php new file mode 100644 index 0000000..a78ad34 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/calendar.php @@ -0,0 +1,59 @@ + 'Пн', + 'tu' => 'Вт', + 'we' => 'Ср', + 'th' => 'Чт', + 'fr' => 'Пт', + 'sa' => 'Сб', + 'su' => 'Вс', + + // Short day names + 'mon' => 'Пнд', + 'tue' => 'Втр', + 'wed' => 'Срд', + 'thu' => 'Чтв', + 'fri' => 'Птн', + 'sat' => 'Сбт', + 'sun' => 'Вск', + + // Long day names + 'monday' => 'Понедельник', + 'tuesday' => 'Вторник', + 'wednesday' => 'Среда', + 'thursday' => 'Четверг', + 'friday' => 'Пятница', + 'saturday' => 'Суббота', + 'sunday' => 'Воскресенье', + + // Short month names + 'jan' => 'Янв', + 'feb' => 'Фев', + 'mar' => 'Мар', + 'apr' => 'Апр', + 'may' => 'Май', + 'jun' => 'Июн', + 'jul' => 'Июл', + 'aug' => 'Авг', + 'sep' => 'Сен', + 'oct' => 'Окт', + 'nov' => 'Ноя', + 'dec' => 'Дек', + + // Long month names + 'january' => 'Январь', + 'february' => 'Февраль', + 'march' => 'Март', + 'april' => 'Апрель', + 'mayl' => 'Май', + 'june' => 'Июнь', + 'july' => 'Июль', + 'august' => 'Август', + 'september' => 'Сентябрь', + 'october' => 'Октябрь', + 'november' => 'Ноябрь', + 'december' => 'Декабрь' +); diff --git a/lib/kohana/system/i18n/ru_RU/captcha.php b/lib/kohana/system/i18n/ru_RU/captcha.php new file mode 100644 index 0000000..98dd5d1 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/captcha.php @@ -0,0 +1,33 @@ + 'Файл "%s" не найден. Убедитесь в наличии файлов функцией file_exists() перед их использованием.', + 'requires_GD2' => 'Библиотека Captcha нуждается в расширении GD2 с поддержкой FreeType. Подробности на http://php.net/gd_info .', + + // Words of varying length for the Captcha_Word_Driver to pick from + // Note: use only alphanumeric characters + 'words' => array + ( + 'cd', 'tv', 'it', 'to', 'be', 'or', + 'sun', 'car', 'dog', 'bed', 'kid', 'egg', + 'bike', 'tree', 'bath', 'roof', 'road', 'hair', + 'hello', 'world', 'earth', 'beard', 'chess', 'water', + 'barber', 'bakery', 'banana', 'market', 'purple', 'writer', + 'america', 'release', 'playing', 'working', 'foreign', 'general', + 'aircraft', 'computer', 'laughter', 'alphabet', 'kangaroo', 'spelling', + 'architect', 'president', 'cockroach', 'encounter', 'terrorism', 'cylinders', + ), + + // Riddles for the Captcha_Riddle_Driver to pick from + // Note: use only alphanumeric characters + 'riddles' => array + ( + array('Do you hate spam? (yes or no)', 'yes'), + array('Are you a robot? (yes or no)', 'no'), + array('Fire is... (hot or cold)', 'hot'), + array('The season after fall is...', 'winter'), + array('Which day of the week is it today?', strftime('%A')), + array('Which month of the year are we in?', strftime('%B')), + ), +); diff --git a/lib/kohana/system/i18n/ru_RU/core.php b/lib/kohana/system/i18n/ru_RU/core.php new file mode 100644 index 0000000..45840eb --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/core.php @@ -0,0 +1,34 @@ + 'Наличие более, чем одного экземпляра Kohana, в пределах одного запроса страницы, невозможно', + 'uncaught_exception' => 'Не пойманное %s: %s в файле %s, на строке %s', + 'invalid_method' => 'Вызов метода %s из файла %s невозможен', + 'invalid_property' => 'Свойство %s не входит в состав класса %s.', + 'log_dir_unwritable' => 'Директория для хранения журналов, %s, не доступна для записи', + 'resource_not_found' => 'Запрошенный %s, %s, не найден', + 'invalid_filetype' => 'Запрошенный тип файла, .%s, не разрешён конфигурацией видов', + 'view_set_filename' => 'Необходимо задать файл вида перед вызовом render()', + 'no_default_route' => 'Установите путь по умолчанию в файле config/routes.php.', + 'no_controller' => 'Kohana не удалось найти контроллер для обработки этого запроса: %s', + 'page_not_found' => 'Запрошенная страница, %s, не найдена.', + 'stats_footer' => 'Загружено за {execution_time} секунд, используя {memory_usage} памяти. Сгенерировано Kohana v{kohana_version}.', + 'error_file_line' => '%s [%s]:', + 'stack_trace' => 'Стек вызовов', + 'generic_error' => 'Не удалось обработать запрос', + 'errors_disabled' => 'Вы можете вернуться на начальную страницу или повторить попытку.', + + // Drivers + 'driver_implements' => 'Драйвер %s библиотеки %s не реализует интерфейс %s', + 'driver_not_found' => 'Драйвер %s библиотеки %s не найден', + + // Resource names + 'config' => 'конфигурация', + 'controller' => 'контроллер', + 'helper' => 'помощник', + 'library' => 'библиотека', + 'driver' => 'драйвер', + 'model' => 'модель', + 'view' => 'вид', +); diff --git a/lib/kohana/system/i18n/ru_RU/database.php b/lib/kohana/system/i18n/ru_RU/database.php new file mode 100644 index 0000000..ab13b9f --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/database.php @@ -0,0 +1,15 @@ + 'Группа %s не определена Вашей конфигурацией.', + 'error' => 'Ошибка SQL: %s', + 'connection' => 'Не удалось подключиться к базе данных: %s', + 'invalid_dsn' => 'Переданный DSN некорректен: %s', + 'must_use_set' => 'Необходимо использовать оператор SET в этом запросе.', + 'must_use_where' => 'Необходимо использовать оператор WHERE в этом запросе.', + 'must_use_table' => 'Необходимо указать таблицу базы данных в этом запросе.', + 'table_not_found' => 'Таблица %s не существует в Вашей базе данных.', + 'not_implemented' => 'Запрошенный метод, %s, не поддерживается этим драйвером.', + 'result_read_only' => 'Результат запроса доступен только для чтения.' +); diff --git a/lib/kohana/system/i18n/ru_RU/encrypt.php b/lib/kohana/system/i18n/ru_RU/encrypt.php new file mode 100644 index 0000000..49f1237 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/encrypt.php @@ -0,0 +1,8 @@ + 'Группа %s не определена вашей конфигурацией.', + 'requires_mcrypt' => 'Для использования библиотеки Encrypt необходимо включить расширение "mcrypt" в конфигурации PHP.', + 'no_encryption_key' => 'Для использования библиотеки Encrypt необходимо задать ключ шифрования в конфигурационном файле.' +); diff --git a/lib/kohana/system/i18n/ru_RU/errors.php b/lib/kohana/system/i18n/ru_RU/errors.php new file mode 100644 index 0000000..ca6c6b8 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/errors.php @@ -0,0 +1,16 @@ + array( 1, 'Ошибка фреймворка', 'Информация об этой ошибке доступна в документации Kohana.'), + E_PAGE_NOT_FOUND => array( 1, 'Page Not Found', 'Запрошенная страница не найдена. Возможно, она была перемещена, удалена, или архивирована.'), + E_DATABASE_ERROR => array( 1, 'Database Error', 'При обработке запроса произошла ошибка в базе данных. Пожалуйста, уточните причину ошибки ниже'), + E_RECOVERABLE_ERROR => array( 1, 'Recoverable Error', 'Обнаружена ошибка, препятствующая загрузке этой страницы. Если это повторится, пожалуйста, уведомите администрацию сайта.'), + E_ERROR => array( 1, 'Фатальная ошибка', ''), + E_USER_ERROR => array( 1, 'Фатальная ошибка', ''), + E_PARSE => array( 1, 'Синтаксическая ошибка', ''), + E_WARNING => array( 1, 'Предупреждение', ''), + E_USER_WARNING => array( 1, 'Предупреждение', ''), + E_STRICT => array( 2, 'Стилистическая ошибка', ''), + E_NOTICE => array( 2, 'Уведомление', ''), +); diff --git a/lib/kohana/system/i18n/ru_RU/event.php b/lib/kohana/system/i18n/ru_RU/event.php new file mode 100644 index 0000000..92b091b --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/event.php @@ -0,0 +1,7 @@ + 'Попытка привязать некорректный субъект %s к %s не удалась: Субъект должен быть наследником класса Event_Subject', + 'invalid_observer' => 'Попытка привязать некорректный наблюдатель %s к %s не удалась: Наблюдатель должен быть наследником класса Event_Observer', +); diff --git a/lib/kohana/system/i18n/ru_RU/image.php b/lib/kohana/system/i18n/ru_RU/image.php new file mode 100644 index 0000000..e00757e --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/image.php @@ -0,0 +1,28 @@ + 'Библиотеке Image необходима функция getimagesize(), недоступная в вашей инсталляции PHP.', + 'unsupported_method' => 'Указанный драйвер не поддерживает операцию %s.', + 'file_not_found' => 'Заданное изображение, %s, не найдено. Удостоверьтесь в наличии изображения функцией file_exists() перед его обработкой.', + 'type_not_allowed' => 'Заданное изображение, %s, не является разрешённым типом изображений.', + 'invalid_width' => 'Заданная ширина, %s, некорректна.', + 'invalid_height' => 'Заданная высота, %s, некорректна.', + 'invalid_dimensions' => 'Заданный размер для %s некорректен.', + 'invalid_master' => 'Заданная основная сторона некорректна.', + 'invalid_flip' => 'Направление разворота некорректно.', + + 'directory_unwritable' => 'Заданная директория, %s, недоступна для записи.', + + // ImageMagick specific messages + 'imagemagick' => array + ( + 'not_found' => 'Директория ImageMagick не содержит запрошенную программу, %s.', + ), + + // GD specific messages + 'gd' => array + ( + 'requires_v2' => 'Библиотеке Image необходимо расширение GD2. Подробности на http://php.net/gd_info .', + ), +); diff --git a/lib/kohana/system/i18n/ru_RU/orm.php b/lib/kohana/system/i18n/ru_RU/orm.php new file mode 100644 index 0000000..2c9a382 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/orm.php @@ -0,0 +1,3 @@ + 'Группа %s не определена конфигурацией нумератора страниц.', + 'page' => 'страница', + 'pages' => 'страницы', + 'item' => 'пункт', + 'items' => 'пунктов', + 'of' => 'из', + 'first' => 'первая', + 'last' => 'последняя', + 'previous' => 'предыдущая', + 'next' => 'следующая', +); diff --git a/lib/kohana/system/i18n/ru_RU/profiler.php b/lib/kohana/system/i18n/ru_RU/profiler.php new file mode 100644 index 0000000..2d45e7e --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/profiler.php @@ -0,0 +1,15 @@ + 'Производительность', + 'post_data' => 'Данные POST', + 'no_post' => 'Нет данных POST', + 'session_data' => 'Данные сессии', + 'no_session' => 'Нет данных сессии', + 'queries' => 'Запросов к БД', + 'no_queries' => 'Нет запросов к БД', + 'no_database' => 'БД не загружена', + 'cookie_data' => 'Данные cookie', + 'no_cookie' => 'Нет данных cookie', +); diff --git a/lib/kohana/system/i18n/ru_RU/session.php b/lib/kohana/system/i18n/ru_RU/session.php new file mode 100644 index 0000000..882fb27 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/session.php @@ -0,0 +1,6 @@ + 'Имя сессии, %s, некорректно. Оно должно состоять только из буквенно-цифровых символов, и, как минимум, одной буквы.', +); diff --git a/lib/kohana/system/i18n/ru_RU/swift.php b/lib/kohana/system/i18n/ru_RU/swift.php new file mode 100644 index 0000000..9033d0c --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/swift.php @@ -0,0 +1,6 @@ + 'Отправка письма не удалась.' +); diff --git a/lib/kohana/system/i18n/ru_RU/upload.php b/lib/kohana/system/i18n/ru_RU/upload.php new file mode 100644 index 0000000..1363ee2 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/upload.php @@ -0,0 +1,23 @@ + 'POST-переменная %s не найдена.', + 'file_exceeds_limit' => 'Размер закачанного файла превышает максимальный разрешённый конфигурацией PHP', + 'file_partial' => 'Файл закачан не полностью', + 'no_file_selected' => 'Вы не выбрали файл для закачивания', + 'invalid_filetype' => 'Тип файла, который вы пытаетесь закачать, не разрешён.', + 'invalid_filesize' => 'Размер файла, который вы пытаетесь закачать, превышает максимальный разрешённый (%s)', + 'invalid_dimensions' => 'Разрешение картинки, которую вы пытаетесь закачать, превышает максимальное разрешённое (%s)', + 'destination_error' => 'Не удалось переместить закачанный файл в пункт назначения.', + 'no_filepath' => 'Путь для закачивания некорректен.', + 'no_file_types' => 'Вы не разрешили ни один тип файлов.', + 'bad_filename' => 'Файл с таким именем уже существует на сервере.', + 'not_writable' => 'Запись в целевой каталог, %s, не возможна.', + 'error_on_file' => 'Ошибка при закачивании %s:', + // Error code responses + 'set_allowed' => 'В целях безопасности, установите разрешённые для закачивания типы файлов.', + 'max_file_size' => 'В целях безопасности, не используйте MAX_FILE_SIZE для ограничения размера закачиваемых файлов.', + 'no_tmp_dir' => 'Временная директория для закачивания файлов не найдена.', + 'tmp_unwritable' => 'Нет прав записи во временную директорию для закачивания файлов, %s.' +); diff --git a/lib/kohana/system/i18n/ru_RU/validation.php b/lib/kohana/system/i18n/ru_RU/validation.php new file mode 100644 index 0000000..edf6a02 --- /dev/null +++ b/lib/kohana/system/i18n/ru_RU/validation.php @@ -0,0 +1,39 @@ + 'Некорректное правило валидации: %s', + + // General errors + 'unknown_error' => 'Неизвестная ошибка при валидации поля %s.', + 'required' => 'Поле %s обязательно для заполнения.', + 'min_length' => 'Поле %s должно быть не короче %d символов.', + 'max_length' => 'Поле %s должно быть не длиннее %d символов.', + 'exact_length' => 'Поле %s должно быть длиной в %d символов.', + 'in_array' => 'Поле %s должно содержать одно из перечисленных значений.', + 'matches' => 'Поле %s должно совпадать с полем %s.', + 'valid_url' => 'Поле %s должно содержать корректный URL.', + 'valid_email' => 'Поле %s должно содержать корректный email.', + 'valid_ip' => 'Поле %s должно содержать корректный IP-адрес.', + 'valid_type' => 'Поле %s должно содержать только символы %s.', + 'range' => 'Поле %s должно сожержать значение из заданных пределов.', + 'regex' => 'Поле %s не является принимаемым значением.', + 'depends_on' => 'Поле %s зависит от поля %s.', + + // Upload errors + 'user_aborted' => 'Загрузка файла %s отменена пользователем.', + 'invalid_type' => 'Загруженный файл, %s, не является файлом разрешённого типа.', + 'max_size' => 'Загруженный файл, %s, слишком велик. Максимальный разрешённый размер файла: %s.', + 'max_width' => 'Загруженный файл, %s, слишком велик. Максимальная разрешённая ширина: %s пикселей.', + 'max_height' => 'Загруженный файл, %s, слишком велик. Максимальная разрешённая высота: %s пикселей.', + 'min_width' => 'Загруженный файл, %s, слишком мал. Минимальная разрешённая ширина: %s пикселей.', + 'min_height' => 'Загруженный файл, %s, слишком мал. Минимальная разрешённая высота: %s пикселей.', + + // Field types + 'alpha' => 'буквенное', + 'alpha_numeric' => 'буквенно-цифровое', + 'alpha_dash' => 'буквенное, c дефисом и символом подчёркивания', + 'digit' => 'цифровое', + 'numeric' => 'числовое', +); diff --git a/lib/kohana/system/libraries/Cache.php b/lib/kohana/system/libraries/Cache.php new file mode 100644 index 0000000..8a02a90 --- /dev/null +++ b/lib/kohana/system/libraries/Cache.php @@ -0,0 +1,208 @@ +config = $config; + + // Set driver name + $driver = 'Cache_'.ucfirst($this->config['driver']).'_Driver'; + + // Load the driver + if ( ! Kohana::auto_load($driver)) + throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); + + // Initialize the driver + $this->driver = new $driver($this->config['params']); + + // Validate the driver + if ( ! ($this->driver instanceof Cache_Driver)) + throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Cache_Driver'); + + Kohana::log('debug', 'Cache Library initialized'); + + if (Cache::$loaded !== TRUE) + { + $this->config['requests'] = (int) $this->config['requests']; + + if ($this->config['requests'] > 0 AND mt_rand(1, $this->config['requests']) === 1) + { + // Do garbage collection + $this->driver->delete_expired(); + + Kohana::log('debug', 'Cache: Expired caches deleted.'); + } + + // Cache has been loaded once + Cache::$loaded = TRUE; + } + } + + /** + * Fetches a cache by id. NULL is returned when a cache item is not found. + * + * @param string cache id + * @return mixed cached data or NULL + */ + public function get($id) + { + // Sanitize the ID + $id = $this->sanitize_id($id); + + return $this->driver->get($id); + } + + /** + * Fetches all of the caches for a given tag. An empty array will be + * returned when no matching caches are found. + * + * @param string cache tag + * @return array all cache items matching the tag + */ + public function find($tag) + { + return $this->driver->find($tag); + } + + /** + * Set a cache item by id. Tags may also be added and a custom lifetime + * can be set. Non-string data is automatically serialized. + * + * @param string unique cache id + * @param mixed data to cache + * @param array|string tags for this item + * @param integer number of seconds until the cache expires + * @return boolean + */ + function set($id, $data, $tags = NULL, $lifetime = NULL) + { + if (is_resource($data)) + throw new Kohana_Exception('cache.resources'); + + // Sanitize the ID + $id = $this->sanitize_id($id); + + if ($lifetime === NULL) + { + // Get the default lifetime + $lifetime = $this->config['lifetime']; + } + + return $this->driver->set($id, $data, (array) $tags, $lifetime); + } + + /** + * Delete a cache item by id. + * + * @param string cache id + * @return boolean + */ + public function delete($id) + { + // Sanitize the ID + $id = $this->sanitize_id($id); + + return $this->driver->delete($id); + } + + /** + * Delete all cache items with a given tag. + * + * @param string cache tag name + * @return boolean + */ + public function delete_tag($tag) + { + return $this->driver->delete($tag, TRUE); + } + + /** + * Delete ALL cache items items. + * + * @return boolean + */ + public function delete_all() + { + return $this->driver->delete(TRUE); + } + + /** + * Replaces troublesome characters with underscores. + * + * @param string cache id + * @return string + */ + protected function sanitize_id($id) + { + // Change slashes and spaces to underscores + return str_replace(array('/', '\\', ' '), '_', $id); + } + +} // End Cache diff --git a/lib/kohana/system/libraries/Calendar.php b/lib/kohana/system/libraries/Calendar.php new file mode 100644 index 0000000..193a6fb --- /dev/null +++ b/lib/kohana/system/libraries/Calendar.php @@ -0,0 +1,362 @@ + 3) ? '%A' : '%a'; + + // Days of the week + $days = array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); + + if (Calendar::$start_monday === TRUE) + { + // Push Sunday to the end of the days + array_push($days, array_shift($days)); + } + + if (strpos(Kohana::config('locale.language.0'), 'en') !== 0) + { + // This is a bit awkward, but it works properly and is reliable + foreach ($days as $i => $day) + { + // Convert the English names to i18n names + $days[$i] = strftime($format, strtotime($day)); + } + } + + if (is_int($length) OR ctype_digit($length)) + { + foreach ($days as $i => $day) + { + // Shorten the days to the expected length + $days[$i] = utf8::substr($day, 0, $length); + } + } + + return $days; + } + + /** + * Create a new Calendar instance. A month and year can be specified. + * By default, the current month and year are used. + * + * @param integer month number + * @param integer year number + * @return object + */ + public static function factory($month = NULL, $year = NULL) + { + return new Calendar($month, $year); + } + + /** + * Create a new Calendar instance. A month and year can be specified. + * By default, the current month and year are used. + * + * @param integer month number + * @param integer year number + * @return void + */ + public function __construct($month = NULL, $year = NULL) + { + empty($month) and $month = date('n'); // Current month + empty($year) and $year = date('Y'); // Current year + + // Set the month and year + $this->month = (int) $month; + $this->year = (int) $year; + + if (Calendar::$start_monday === TRUE) + { + // Week starts on Monday + $this->week_start = 1; + } + } + + /** + * Allows fetching the current month and year. + * + * @param string key to get + * @return mixed + */ + public function __get($key) + { + if ($key === 'month' OR $key === 'year') + { + return $this->$key; + } + } + + /** + * Calendar_Event factory method. + * + * @param string unique name for the event + * @return object Calendar_Event + */ + public function event($name = NULL) + { + return new Calendar_Event($this); + } + + /** + * Calendar_Event factory method. + * + * @chainable + * @param string standard event type + * @return object + */ + public function standard($name) + { + switch ($name) + { + case 'today': + // Add an event for the current day + $this->attach($this->event()->condition('timestamp', strtotime('today'))->add_class('today')); + break; + case 'prev-next': + // Add an event for padding days + $this->attach($this->event()->condition('current', FALSE)->add_class('prev-next')); + break; + case 'holidays': + // Base event + $event = $this->event()->condition('current', TRUE)->add_class('holiday'); + + // Attach New Years + $holiday = clone $event; + $this->attach($holiday->condition('month', 1)->condition('day', 1)); + + // Attach Valentine's Day + $holiday = clone $event; + $this->attach($holiday->condition('month', 2)->condition('day', 14)); + + // Attach St. Patrick's Day + $holiday = clone $event; + $this->attach($holiday->condition('month', 3)->condition('day', 17)); + + // Attach Easter + $holiday = clone $event; + $this->attach($holiday->condition('easter', TRUE)); + + // Attach Memorial Day + $holiday = clone $event; + $this->attach($holiday->condition('month', 5)->condition('day_of_week', 1)->condition('last_occurrence', TRUE)); + + // Attach Independance Day + $holiday = clone $event; + $this->attach($holiday->condition('month', 7)->condition('day', 4)); + + // Attach Labor Day + $holiday = clone $event; + $this->attach($holiday->condition('month', 9)->condition('day_of_week', 1)->condition('occurrence', 1)); + + // Attach Halloween + $holiday = clone $event; + $this->attach($holiday->condition('month', 10)->condition('day', 31)); + + // Attach Thanksgiving + $holiday = clone $event; + $this->attach($holiday->condition('month', 11)->condition('day_of_week', 4)->condition('occurrence', 4)); + + // Attach Christmas + $holiday = clone $event; + $this->attach($holiday->condition('month', 12)->condition('day', 25)); + break; + case 'weekends': + // Weekend events + $this->attach($this->event()->condition('weekend', TRUE)->add_class('weekend')); + break; + } + + return $this; + } + + /** + * Returns an array for use with a view. The array contains an array for + * each week. Each week contains 7 arrays, with a day number and status: + * TRUE if the day is in the month, FALSE if it is padding. + * + * @return array + */ + public function weeks() + { + // First day of the month as a timestamp + $first = mktime(1, 0, 0, $this->month, 1, $this->year); + + // Total number of days in this month + $total = (int) date('t', $first); + + // Last day of the month as a timestamp + $last = mktime(1, 0, 0, $this->month, $total, $this->year); + + // Make the month and week empty arrays + $month = $week = array(); + + // Number of days added. When this reaches 7, start a new week + $days = 0; + $week_number = 1; + + if (($w = (int) date('w', $first) - $this->week_start) < 0) + { + $w = 6; + } + + if ($w > 0) + { + // Number of days in the previous month + $n = (int) date('t', mktime(1, 0, 0, $this->month - 1, 1, $this->year)); + + // i = number of day, t = number of days to pad + for ($i = $n - $w + 1, $t = $w; $t > 0; $t--, $i++) + { + // Notify the listeners + $this->notify(array($this->month - 1, $i, $this->year, $week_number, FALSE)); + + // Add previous month padding days + $week[] = array($i, FALSE, $this->observed_data); + $days++; + } + } + + // i = number of day + for ($i = 1; $i <= $total; $i++) + { + if ($days % 7 === 0) + { + // Start a new week + $month[] = $week; + $week = array(); + + $week_number++; + } + + // Notify the listeners + $this->notify(array($this->month, $i, $this->year, $week_number, TRUE)); + + // Add days to this month + $week[] = array($i, TRUE, $this->observed_data); + $days++; + } + + if (($w = (int) date('w', $last) - $this->week_start) < 0) + { + $w = 6; + } + + if ($w >= 0) + { + // i = number of day, t = number of days to pad + for ($i = 1, $t = 6 - $w; $t > 0; $t--, $i++) + { + // Notify the listeners + $this->notify(array($this->month + 1, $i, $this->year, $week_number, FALSE)); + + // Add next month padding days + $week[] = array($i, FALSE, $this->observed_data); + } + } + + if ( ! empty($week)) + { + // Append the remaining days + $month[] = $week; + } + + return $month; + } + + /** + * Adds new data from an observer. All event data contains and array of CSS + * classes and an array of output messages. + * + * @param array observer data. + * @return void + */ + public function add_data(array $data) + { + // Add new classes + $this->observed_data['classes'] += $data['classes']; + + if ( ! empty($data['output'])) + { + // Only add output if it's not empty + $this->observed_data['output'][] = $data['output']; + } + } + + /** + * Resets the observed data and sends a notify to all attached events. + * + * @param array UNIX timestamp + * @return void + */ + public function notify($data) + { + // Reset observed data + $this->observed_data = array + ( + 'classes' => array(), + 'output' => array(), + ); + + // Send a notify + parent::notify($data); + } + + /** + * Convert the calendar to HTML using the kohana_calendar view. + * + * @return string + */ + public function render() + { + $view = new View('kohana_calendar', array + ( + 'month' => $this->month, + 'year' => $this->year, + 'weeks' => $this->weeks(), + )); + + return $view->render(); + } + + /** + * Magically convert this object to a string, the rendered calendar. + * + * @return string + */ + public function __toString() + { + return $this->render(); + } + +} // End Calendar \ No newline at end of file diff --git a/lib/kohana/system/libraries/Calendar_Event.php b/lib/kohana/system/libraries/Calendar_Event.php new file mode 100644 index 0000000..ba9b5ad --- /dev/null +++ b/lib/kohana/system/libraries/Calendar_Event.php @@ -0,0 +1,307 @@ +conditions[$key]); + } + else + { + if ($key === 'callback') + { + // Do nothing + } + elseif (in_array($key, $this->booleans)) + { + // Make the value boolean + $value = (bool) $value; + } + else + { + // Make the value an int + $value = (int) $value; + } + + $this->conditions[$key] = $value; + } + + return $this; + } + + /** + * Add a CSS class for this event. This can be called multiple times. + * + * @chainable + * @param string CSS class name + * @return object + */ + public function add_class($class) + { + $this->classes[$class] = $class; + + return $this; + } + + /** + * Remove a CSS class for this event. This can be called multiple times. + * + * @chainable + * @param string CSS class name + * @return object + */ + public function remove_class($class) + { + unset($this->classes[$class]); + + return $this; + } + + /** + * Set HTML output for this event. + * + * @chainable + * @param string HTML output + * @return object + */ + public function output($str) + { + $this->output = $str; + + return $this; + } + + /** + * Add a CSS class for this event. This can be called multiple times. + * + * @chainable + * @param string CSS class name + * @return object + */ + public function notify($data) + { + // Split the date and current status + list ($month, $day, $year, $week, $current) = $data; + + // Get a timestamp for the day + $timestamp = mktime(0, 0, 0, $month, $day, $year); + + // Date conditionals + $condition = array + ( + 'timestamp' => (int) $timestamp, + 'day' => (int) date('j', $timestamp), + 'week' => (int) $week, + 'month' => (int) date('n', $timestamp), + 'year' => (int) date('Y', $timestamp), + 'day_of_week' => (int) date('w', $timestamp), + 'current' => (bool) $current, + ); + + // Tested conditions + $tested = array(); + + foreach ($condition as $key => $value) + { + // Timestamps need to be handled carefully + if($key === 'timestamp' AND isset($this->conditions['timestamp'])) + { + // This adds 23 hours, 59 minutes and 59 seconds to today's timestamp, as 24 hours + // is classed as a new day + $next_day = $timestamp + 86399; + + if($this->conditions['timestamp'] < $timestamp OR $this->conditions['timestamp'] > $next_day) + return FALSE; + } + // Test basic conditions first + elseif (isset($this->conditions[$key]) AND $this->conditions[$key] !== $value) + return FALSE; + + // Condition has been tested + $tested[$key] = TRUE; + } + + if (isset($this->conditions['weekend'])) + { + // Weekday vs Weekend + $condition['weekend'] = ($condition['day_of_week'] === 0 OR $condition['day_of_week'] === 6); + } + + if (isset($this->conditions['first_day'])) + { + // First day of month + $condition['first_day'] = ($condition['day'] === 1); + } + + if (isset($this->conditions['last_day'])) + { + // Last day of month + $condition['last_day'] = ($condition['day'] === (int) date('t', $timestamp)); + } + + if (isset($this->conditions['occurrence'])) + { + // Get the occurance of the current day + $condition['occurrence'] = $this->day_occurrence($timestamp); + } + + if (isset($this->conditions['last_occurrence'])) + { + // Test if the next occurance of this date is next month + $condition['last_occurrence'] = ((int) date('n', $timestamp + 604800) !== $condition['month']); + } + + if (isset($this->conditions['easter'])) + { + if ($condition['month'] === 3 OR $condition['month'] === 4) + { + // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter + // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in + // 1876. This algorithm has also been published in the 1922 book General Astronomy by + // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page + // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus. + + $a = $condition['year'] % 19; + $b = (int) ($condition['year'] / 100); + $c = $condition['year'] % 100; + $d = (int) ($b / 4); + $e = $b % 4; + $f = (int) (($b + 8) / 25); + $g = (int) (($b - $f + 1) / 3); + $h = (19 * $a + $b - $d - $g + 15) % 30; + $i = (int) ($c / 4); + $k = $c % 4; + $l = (32 + 2 * $e + 2 * $i - $h - $k) % 7; + $m = (int) (($a + 11 * $h + 22 * $l) / 451); + $p = ($h + $l - 7 * $m + 114) % 31; + + $month = (int) (($h + $l - 7 * $m + 114) / 31); + $day = $p + 1; + + $condition['easter'] = ($condition['month'] === $month AND $condition['day'] === $day); + } + else + { + // Easter can only happen in March or April + $condition['easter'] = FALSE; + } + } + + if (isset($this->conditions['callback'])) + { + // Use a callback to determine validity + $condition['callback'] = call_user_func($this->conditions['callback'], $condition, $this); + } + + $conditions = array_diff_key($this->conditions, $tested); + + foreach ($conditions as $key => $value) + { + if ($key === 'callback') + { + // Callbacks are tested on a TRUE/FALSE basis + $value = TRUE; + } + + // Test advanced conditions + if ($condition[$key] !== $value) + return FALSE; + } + + $this->caller->add_data(array + ( + 'classes' => $this->classes, + 'output' => $this->output, + )); + } + + /** + * Find the week day occurrence for a specific timestamp. The occurrence is + * relative to the current month. For example, the second Saturday of any + * given month will return "2" as the occurrence. This is used in combination + * with the "occurrence" condition. + * + * @param integer UNIX timestamp + * @return integer + */ + protected function day_occurrence($timestamp) + { + // Get the current month for the timestamp + $month = date('m', $timestamp); + + // Default occurrence is one + $occurrence = 1; + + // Reduce the timestamp by one week for each loop. This has the added + // benefit of preventing an infinite loop. + while ($timestamp -= 604800) + { + if (date('m', $timestamp) !== $month) + { + // Once the timestamp has gone into the previous month, the + // proper occurrence has been found. + return $occurrence; + } + + // Increment the occurrence + $occurrence++; + } + } + +} // End Calendar Event diff --git a/lib/kohana/system/libraries/Captcha.php b/lib/kohana/system/libraries/Captcha.php new file mode 100644 index 0000000..f5f2b46 --- /dev/null +++ b/lib/kohana/system/libraries/Captcha.php @@ -0,0 +1,279 @@ + 'basic', + 'width' => 150, + 'height' => 50, + 'complexity' => 4, + 'background' => '', + 'fontpath' => '', + 'fonts' => array(), + 'promote' => FALSE, + ); + + /** + * Singleton instance of Captcha. + * + * @return object + */ + public static function instance() + { + // Create the instance if it does not exist + empty(Captcha::$instance) and new Captcha; + + return Captcha::$instance; + } + + /** + * Constructs and returns a new Captcha object. + * + * @param string config group name + * @return object + */ + public static function factory($group = NULL) + { + return new Captcha($group); + } + + /** + * Constructs a new Captcha object. + * + * @throws Kohana_Exception + * @param string config group name + * @return void + */ + public function __construct($group = NULL) + { + // Create a singleton instance once + empty(Captcha::$instance) and Captcha::$instance = $this; + + // No config group name given + if ( ! is_string($group)) + { + $group = 'default'; + } + + // Load and validate config group + if ( ! is_array($config = Kohana::config('captcha.'.$group))) + throw new Kohana_Exception('captcha.undefined_group', $group); + + // All captcha config groups inherit default config group + if ($group !== 'default') + { + // Load and validate default config group + if ( ! is_array($default = Kohana::config('captcha.default'))) + throw new Kohana_Exception('captcha.undefined_group', 'default'); + + // Merge config group with default config group + $config += $default; + } + + // Assign config values to the object + foreach ($config as $key => $value) + { + if (array_key_exists($key, Captcha::$config)) + { + Captcha::$config[$key] = $value; + } + } + + // Store the config group name as well, so the drivers can access it + Captcha::$config['group'] = $group; + + // If using a background image, check if it exists + if ( ! empty($config['background'])) + { + Captcha::$config['background'] = str_replace('\\', '/', realpath($config['background'])); + + if ( ! is_file(Captcha::$config['background'])) + throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['background']); + } + + // If using any fonts, check if they exist + if ( ! empty($config['fonts'])) + { + Captcha::$config['fontpath'] = str_replace('\\', '/', realpath($config['fontpath'])).'/'; + + foreach ($config['fonts'] as $font) + { + if ( ! is_file(Captcha::$config['fontpath'].$font)) + throw new Kohana_Exception('captcha.file_not_found', Captcha::$config['fontpath'].$font); + } + } + + // Set driver name + $driver = 'Captcha_'.ucfirst($config['style']).'_Driver'; + + // Load the driver + if ( ! Kohana::auto_load($driver)) + throw new Kohana_Exception('core.driver_not_found', $config['style'], get_class($this)); + + // Initialize the driver + $this->driver = new $driver; + + // Validate the driver + if ( ! ($this->driver instanceof Captcha_Driver)) + throw new Kohana_Exception('core.driver_implements', $config['style'], get_class($this), 'Captcha_Driver'); + + Kohana::log('debug', 'Captcha Library initialized'); + } + + /** + * Validates a Captcha response and updates response counter. + * + * @param string captcha response + * @return boolean + */ + public static function valid($response) + { + // Maximum one count per page load + static $counted; + + // User has been promoted, always TRUE and don't count anymore + if (Captcha::instance()->promoted()) + return TRUE; + + // Challenge result + $result = (bool) Captcha::instance()->driver->valid($response); + + // Increment response counter + if ($counted !== TRUE) + { + $counted = TRUE; + + // Valid response + if ($result === TRUE) + { + Captcha::instance()->valid_count(Session::instance()->get('captcha_valid_count') + 1); + } + // Invalid response + else + { + Captcha::instance()->invalid_count(Session::instance()->get('captcha_invalid_count') + 1); + } + } + + return $result; + } + + /** + * Gets or sets the number of valid Captcha responses for this session. + * + * @param integer new counter value + * @param boolean trigger invalid counter (for internal use only) + * @return integer counter value + */ + public function valid_count($new_count = NULL, $invalid = FALSE) + { + // Pick the right session to use + $session = ($invalid === TRUE) ? 'captcha_invalid_count' : 'captcha_valid_count'; + + // Update counter + if ($new_count !== NULL) + { + $new_count = (int) $new_count; + + // Reset counter = delete session + if ($new_count < 1) + { + Session::instance()->delete($session); + } + // Set counter to new value + else + { + Session::instance()->set($session, (int) $new_count); + } + + // Return new count + return (int) $new_count; + } + + // Return current count + return (int) Session::instance()->get($session); + } + + /** + * Gets or sets the number of invalid Captcha responses for this session. + * + * @param integer new counter value + * @return integer counter value + */ + public function invalid_count($new_count = NULL) + { + return $this->valid_count($new_count, TRUE); + } + + /** + * Resets the Captcha response counters and removes the count sessions. + * + * @return void + */ + public function reset_count() + { + $this->valid_count(0); + $this->valid_count(0, TRUE); + } + + /** + * Checks whether user has been promoted after having given enough valid responses. + * + * @param integer valid response count threshold + * @return boolean + */ + public function promoted($threshold = NULL) + { + // Promotion has been disabled + if (Captcha::$config['promote'] === FALSE) + return FALSE; + + // Use the config threshold + if ($threshold === NULL) + { + $threshold = Captcha::$config['promote']; + } + + // Compare the valid response count to the threshold + return ($this->valid_count() >= $threshold); + } + + /** + * Returns or outputs the Captcha challenge. + * + * @param boolean TRUE to output html, e.g. + * @return mixed html string or void + */ + public function render($html = TRUE) + { + return $this->driver->render($html); + } + + /** + * Magically outputs the Captcha challenge. + * + * @return mixed + */ + public function __toString() + { + return $this->render(); + } + +} // End Captcha Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/Controller.php b/lib/kohana/system/libraries/Controller.php new file mode 100644 index 0000000..2f64c21 --- /dev/null +++ b/lib/kohana/system/libraries/Controller.php @@ -0,0 +1,86 @@ +uri = URI::instance(); + + // Input should always be available + $this->input = Input::instance(); + } + + /** + * Handles methods that do not exist. + * + * @param string method name + * @param array arguments + * @return void + */ + public function __call($method, $args) + { + // Default to showing a 404 page + Event::run('system.404'); + } + + /** + * Includes a View within the controller scope. + * + * @param string view filename + * @param array array of view variables + * @return string + */ + public function _kohana_load_view($kohana_view_filename, $kohana_input_data) + { + if ($kohana_view_filename == '') + return; + + // Buffering on + ob_start(); + + // Import the view variables to local namespace + extract($kohana_input_data, EXTR_SKIP); + + // Views are straight HTML pages with embedded PHP, so importing them + // this way insures that $this can be accessed as if the user was in + // the controller, which gives the easiest access to libraries in views + try + { + include $kohana_view_filename; + } + catch (Exception $e) + { + ob_end_clean(); + throw $e; + } + + // Fetch the output and close the buffer + return ob_get_clean(); + } + +} // End Controller Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/Database.php b/lib/kohana/system/libraries/Database.php new file mode 100644 index 0000000..6267f63 --- /dev/null +++ b/lib/kohana/system/libraries/Database.php @@ -0,0 +1,1444 @@ + TRUE, + 'persistent' => FALSE, + 'connection' => '', + 'character_set' => 'utf8', + 'table_prefix' => '', + 'object' => TRUE, + 'cache' => FALSE, + 'escape' => TRUE, + ); + + // Database driver object + protected $driver; + protected $link; + + // Un-compiled parts of the SQL query + protected $select = array(); + protected $set = array(); + protected $from = array(); + protected $join = array(); + protected $where = array(); + protected $orderby = array(); + protected $order = array(); + protected $groupby = array(); + protected $having = array(); + protected $distinct = FALSE; + protected $limit = FALSE; + protected $offset = FALSE; + protected $last_query = ''; + + // Stack of queries for push/pop + protected $query_history = array(); + + /** + * Returns a singleton instance of Database. + * + * @param mixed configuration array or DSN + * @return Database_Core + */ + public static function & instance($name = 'default', $config = NULL) + { + if ( ! isset(Database::$instances[$name])) + { + // Create a new instance + Database::$instances[$name] = new Database($config === NULL ? $name : $config); + } + + return Database::$instances[$name]; + } + + /** + * Returns the name of a given database instance. + * + * @param Database instance of Database + * @return string + */ + public static function instance_name(Database $db) + { + return array_search($db, Database::$instances, TRUE); + } + + /** + * Sets up the database configuration, loads the Database_Driver. + * + * @throws Kohana_Database_Exception + */ + public function __construct($config = array()) + { + if (empty($config)) + { + // Load the default group + $config = Kohana::config('database.default'); + } + elseif (is_array($config) AND count($config) > 0) + { + if ( ! array_key_exists('connection', $config)) + { + $config = array('connection' => $config); + } + } + elseif (is_string($config)) + { + // The config is a DSN string + if (strpos($config, '://') !== FALSE) + { + $config = array('connection' => $config); + } + // The config is a group name + else + { + $name = $config; + + // Test the config group name + if (($config = Kohana::config('database.'.$config)) === NULL) + throw new Kohana_Database_Exception('database.undefined_group', $name); + } + } + + // Merge the default config with the passed config + $this->config = array_merge($this->config, $config); + + if (is_string($this->config['connection'])) + { + // Make sure the connection is valid + if (strpos($this->config['connection'], '://') === FALSE) + throw new Kohana_Database_Exception('database.invalid_dsn', $this->config['connection']); + + // Parse the DSN, creating an array to hold the connection parameters + $db = array + ( + 'type' => FALSE, + 'user' => FALSE, + 'pass' => FALSE, + 'host' => FALSE, + 'port' => FALSE, + 'socket' => FALSE, + 'database' => FALSE + ); + + // Get the protocol and arguments + list ($db['type'], $connection) = explode('://', $this->config['connection'], 2); + + if (strpos($connection, '@') !== FALSE) + { + // Get the username and password + list ($db['pass'], $connection) = explode('@', $connection, 2); + // Check if a password is supplied + $logindata = explode(':', $db['pass'], 2); + $db['pass'] = (count($logindata) > 1) ? $logindata[1] : ''; + $db['user'] = $logindata[0]; + + // Prepare for finding the database + $connection = explode('/', $connection); + + // Find the database name + $db['database'] = array_pop($connection); + + // Reset connection string + $connection = implode('/', $connection); + + // Find the socket + if (preg_match('/^unix\([^)]++\)/', $connection)) + { + // This one is a little hairy: we explode based on the end of + // the socket, removing the 'unix(' from the connection string + list ($db['socket'], $connection) = explode(')', substr($connection, 5), 2); + } + elseif (strpos($connection, ':') !== FALSE) + { + // Fetch the host and port name + list ($db['host'], $db['port']) = explode(':', $connection, 2); + } + else + { + $db['host'] = $connection; + } + } + else + { + // File connection + $connection = explode('/', $connection); + + // Find database file name + $db['database'] = array_pop($connection); + + // Find database directory name + $db['socket'] = implode('/', $connection).'/'; + } + + // Reset the connection array to the database config + $this->config['connection'] = $db; + } + // Set driver name + $driver = 'Database_'.ucfirst($this->config['connection']['type']).'_Driver'; + + // Load the driver + if ( ! Kohana::auto_load($driver)) + throw new Kohana_Database_Exception('core.driver_not_found', $this->config['connection']['type'], get_class($this)); + + // Initialize the driver + $this->driver = new $driver($this->config); + + // Validate the driver + if ( ! ($this->driver instanceof Database_Driver)) + throw new Kohana_Database_Exception('core.driver_implements', $this->config['connection']['type'], get_class($this), 'Database_Driver'); + + Kohana::log('debug', 'Database Library initialized'); + } + + /** + * Simple connect method to get the database queries up and running. + * + * @return void + */ + public function connect() + { + // A link can be a resource or an object + if ( ! is_resource($this->link) AND ! is_object($this->link)) + { + $this->link = $this->driver->connect(); + if ( ! is_resource($this->link) AND ! is_object($this->link)) + throw new Kohana_Database_Exception('database.connection', $this->driver->show_error()); + + // Clear password after successful connect + $this->config['connection']['pass'] = NULL; + } + } + + /** + * Runs a query into the driver and returns the result. + * + * @param string SQL query to execute + * @return Database_Result + */ + public function query($sql = '') + { + if ($sql == '') return FALSE; + + // No link? Connect! + $this->link or $this->connect(); + + // Start the benchmark + $start = microtime(TRUE); + + if (func_num_args() > 1) //if we have more than one argument ($sql) + { + $argv = func_get_args(); + $binds = (is_array(next($argv))) ? current($argv) : array_slice($argv, 1); + } + + // Compile binds if needed + if (isset($binds)) + { + $sql = $this->compile_binds($sql, $binds); + } + + // Fetch the result + $result = $this->driver->query($this->last_query = $sql); + + // Stop the benchmark + $stop = microtime(TRUE); + + if ($this->config['benchmark'] == TRUE) + { + // Benchmark the query + Database::$benchmarks[] = array('query' => $sql, 'time' => $stop - $start, 'rows' => count($result)); + } + + return $result; + } + + /** + * Selects the column names for a database query. + * + * @param string string or array of column names to select + * @return Database_Core This Database object. + */ + public function select($sql = '*') + { + if (func_num_args() > 1) + { + $sql = func_get_args(); + } + elseif (is_string($sql)) + { + $sql = explode(',', $sql); + } + else + { + $sql = (array) $sql; + } + + foreach ($sql as $val) + { + if (($val = trim($val)) === '') continue; + + if (strpos($val, '(') === FALSE AND $val !== '*') + { + if (preg_match('/^DISTINCT\s++(.+)$/i', $val, $matches)) + { + // Only prepend with table prefix if table name is specified + $val = (strpos($matches[1], '.') !== FALSE) ? $this->config['table_prefix'].$matches[1] : $matches[1]; + + $this->distinct = TRUE; + } + else + { + $val = (strpos($val, '.') !== FALSE) ? $this->config['table_prefix'].$val : $val; + } + + $val = $this->driver->escape_column($val); + } + + $this->select[] = $val; + } + + return $this; + } + + /** + * Selects the from table(s) for a database query. + * + * @param string string or array of tables to select + * @return Database_Core This Database object. + */ + public function from($sql) + { + if (func_num_args() > 1) + { + $sql = func_get_args(); + } + elseif (is_string($sql)) + { + $sql = explode(',', $sql); + } + else + { + $sql = array($sql); + } + + foreach ($sql as $val) + { + if (is_string($val)) + { + if (($val = trim($val)) === '') continue; + + // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) + if (stripos($val, ' AS ') !== FALSE) + { + $val = str_ireplace(' AS ', ' AS ', $val); + + list($table, $alias) = explode(' AS ', $val); + + // Attach prefix to both sides of the AS + $val = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; + } + else + { + $val = $this->config['table_prefix'].$val; + } + } + + $this->from[] = $val; + } + + return $this; + } + + /** + * Generates the JOIN portion of the query. + * + * @param string table name + * @param string|array where key or array of key => value pairs + * @param string where value + * @param string type of join + * @return Database_Core This Database object. + */ + public function join($table, $key, $value = NULL, $type = '') + { + $join = array(); + + if ( ! empty($type)) + { + $type = strtoupper(trim($type)); + + if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) + { + $type = ''; + } + else + { + $type .= ' '; + } + } + + $cond = array(); + $keys = is_array($key) ? $key : array($key => $value); + foreach ($keys as $key => $value) + { + $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; + + if (is_string($value)) + { + // Only escape if it's a string + $value = $this->driver->escape_column($this->config['table_prefix'].$value); + } + + $cond[] = $this->driver->where($key, $value, 'AND ', count($cond), FALSE); + } + + if ( ! is_array($this->join)) + { + $this->join = array(); + } + + if ( ! is_array($table)) + { + $table = array($table); + } + + foreach ($table as $t) + { + if (is_string($t)) + { + // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) + if (stripos($t, ' AS ') !== FALSE) + { + $t = str_ireplace(' AS ', ' AS ', $t); + + list($table, $alias) = explode(' AS ', $t); + + // Attach prefix to both sides of the AS + $t = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; + } + else + { + $t = $this->config['table_prefix'].$t; + } + } + + $join['tables'][] = $this->driver->escape_column($t); + } + + $join['conditions'] = '('.trim(implode(' ', $cond)).')'; + $join['type'] = $type; + + $this->join[] = $join; + + return $this; + } + + + /** + * Selects the where(s) for a database query. + * + * @param string|array key name or array of key => value pairs + * @param string value to match with key + * @param boolean disable quoting of WHERE clause + * @return Database_Core This Database object. + */ + public function where($key, $value = NULL, $quote = TRUE) + { + $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; + if (is_object($key)) + { + $keys = array((string) $key => ''); + } + elseif ( ! is_array($key)) + { + $keys = array($key => $value); + } + else + { + $keys = $key; + } + + foreach ($keys as $key => $value) + { + $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; + $this->where[] = $this->driver->where($key, $value, 'AND ', count($this->where), $quote); + } + + return $this; + } + + /** + * Selects the or where(s) for a database query. + * + * @param string|array key name or array of key => value pairs + * @param string value to match with key + * @param boolean disable quoting of WHERE clause + * @return Database_Core This Database object. + */ + public function orwhere($key, $value = NULL, $quote = TRUE) + { + $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; + if (is_object($key)) + { + $keys = array((string) $key => ''); + } + elseif ( ! is_array($key)) + { + $keys = array($key => $value); + } + else + { + $keys = $key; + } + + foreach ($keys as $key => $value) + { + $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; + $this->where[] = $this->driver->where($key, $value, 'OR ', count($this->where), $quote); + } + + return $this; + } + + /** + * Selects the like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @param boolean automatically add starting and ending wildcards + * @return Database_Core This Database object. + */ + public function like($field, $match = '', $auto = TRUE) + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->like($field, $match, $auto, 'AND ', count($this->where)); + } + + return $this; + } + + /** + * Selects the or like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @param boolean automatically add starting and ending wildcards + * @return Database_Core This Database object. + */ + public function orlike($field, $match = '', $auto = TRUE) + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->like($field, $match, $auto, 'OR ', count($this->where)); + } + + return $this; + } + + /** + * Selects the not like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @param boolean automatically add starting and ending wildcards + * @return Database_Core This Database object. + */ + public function notlike($field, $match = '', $auto = TRUE) + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->notlike($field, $match, $auto, 'AND ', count($this->where)); + } + + return $this; + } + + /** + * Selects the or not like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @return Database_Core This Database object. + */ + public function ornotlike($field, $match = '', $auto = TRUE) + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->notlike($field, $match, $auto, 'OR ', count($this->where)); + } + + return $this; + } + + /** + * Selects the like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @return Database_Core This Database object. + */ + public function regex($field, $match = '') + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->regex($field, $match, 'AND ', count($this->where)); + } + + return $this; + } + + /** + * Selects the or like(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string like value to match with field + * @return Database_Core This Database object. + */ + public function orregex($field, $match = '') + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->regex($field, $match, 'OR ', count($this->where)); + } + + return $this; + } + + /** + * Selects the not regex(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string regex value to match with field + * @return Database_Core This Database object. + */ + public function notregex($field, $match = '') + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->notregex($field, $match, 'AND ', count($this->where)); + } + + return $this; + } + + /** + * Selects the or not regex(s) for a database query. + * + * @param string|array field name or array of field => match pairs + * @param string regex value to match with field + * @return Database_Core This Database object. + */ + public function ornotregex($field, $match = '') + { + $fields = is_array($field) ? $field : array($field => $match); + + foreach ($fields as $field => $match) + { + $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; + $this->where[] = $this->driver->notregex($field, $match, 'OR ', count($this->where)); + } + + return $this; + } + + /** + * Chooses the column to group by in a select query. + * + * @param string column name to group by + * @return Database_Core This Database object. + */ + public function groupby($by) + { + if ( ! is_array($by)) + { + $by = explode(',', (string) $by); + } + + foreach ($by as $val) + { + $val = trim($val); + + if ($val != '') + { + // Add the table prefix if we are using table.column names + if(strpos($val, '.')) + { + $val = $this->config['table_prefix'].$val; + } + + $this->groupby[] = $this->driver->escape_column($val); + } + } + + return $this; + } + + /** + * Selects the having(s) for a database query. + * + * @param string|array key name or array of key => value pairs + * @param string value to match with key + * @param boolean disable quoting of WHERE clause + * @return Database_Core This Database object. + */ + public function having($key, $value = '', $quote = TRUE) + { + $this->having[] = $this->driver->where($key, $value, 'AND', count($this->having), TRUE); + return $this; + } + + /** + * Selects the or having(s) for a database query. + * + * @param string|array key name or array of key => value pairs + * @param string value to match with key + * @param boolean disable quoting of WHERE clause + * @return Database_Core This Database object. + */ + public function orhaving($key, $value = '', $quote = TRUE) + { + $this->having[] = $this->driver->where($key, $value, 'OR', count($this->having), TRUE); + return $this; + } + + /** + * Chooses which column(s) to order the select query by. + * + * @param string|array column(s) to order on, can be an array, single column, or comma seperated list of columns + * @param string direction of the order + * @return Database_Core This Database object. + */ + public function orderby($orderby, $direction = NULL) + { + if ( ! is_array($orderby)) + { + $orderby = array($orderby => $direction); + } + + foreach ($orderby as $column => $direction) + { + $direction = strtoupper(trim($direction)); + + // Add a direction if the provided one isn't valid + if ( ! in_array($direction, array('ASC', 'DESC', 'RAND()', 'RANDOM()', 'NULL'))) + { + $direction = 'ASC'; + } + + // Add the table prefix if a table.column was passed + if (strpos($column, '.')) + { + $column = $this->config['table_prefix'].$column; + } + + $this->orderby[] = $this->driver->escape_column($column).' '.$direction; + } + + return $this; + } + + /** + * Selects the limit section of a query. + * + * @param integer number of rows to limit result to + * @param integer offset in result to start returning rows from + * @return Database_Core This Database object. + */ + public function limit($limit, $offset = NULL) + { + $this->limit = (int) $limit; + + if ($offset !== NULL OR ! is_int($this->offset)) + { + $this->offset($offset); + } + + return $this; + } + + /** + * Sets the offset portion of a query. + * + * @param integer offset value + * @return Database_Core This Database object. + */ + public function offset($value) + { + $this->offset = (int) $value; + + return $this; + } + + /** + * Allows key/value pairs to be set for inserting or updating. + * + * @param string|array key name or array of key => value pairs + * @param string value to match with key + * @return Database_Core This Database object. + */ + public function set($key, $value = '') + { + if ( ! is_array($key)) + { + $key = array($key => $value); + } + + foreach ($key as $k => $v) + { + // Add a table prefix if the column includes the table. + if (strpos($k, '.')) + $k = $this->config['table_prefix'].$k; + + $this->set[$k] = $this->driver->escape($v); + } + + return $this; + } + + /** + * Compiles the select statement based on the other functions called and runs the query. + * + * @param string table name + * @param string limit clause + * @param string offset clause + * @return Database_Result + */ + public function get($table = '', $limit = NULL, $offset = NULL) + { + if ($table != '') + { + $this->from($table); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->driver->compile_select(get_object_vars($this)); + + $this->reset_select(); + + $result = $this->query($sql); + + $this->last_query = $sql; + + return $result; + } + + /** + * Compiles the select statement based on the other functions called and runs the query. + * + * @param string table name + * @param array where clause + * @param string limit clause + * @param string offset clause + * @return Database_Core This Database object. + */ + public function getwhere($table = '', $where = NULL, $limit = NULL, $offset = NULL) + { + if ($table != '') + { + $this->from($table); + } + + if ( ! is_null($where)) + { + $this->where($where); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->driver->compile_select(get_object_vars($this)); + + $this->reset_select(); + + $result = $this->query($sql); + + return $result; + } + + /** + * Compiles the select statement based on the other functions called and returns the query string. + * + * @param string table name + * @param string limit clause + * @param string offset clause + * @return string sql string + */ + public function compile($table = '', $limit = NULL, $offset = NULL) + { + if ($table != '') + { + $this->from($table); + } + + if ( ! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $sql = $this->driver->compile_select(get_object_vars($this)); + + $this->reset_select(); + + return $sql; + } + + /** + * Compiles an insert string and runs the query. + * + * @param string table name + * @param array array of key/value pairs to insert + * @return Database_Result Query result + */ + public function insert($table = '', $set = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if ($this->set == NULL) + throw new Kohana_Database_Exception('database.must_use_set'); + + if ($table == '') + { + if ( ! isset($this->from[0])) + throw new Kohana_Database_Exception('database.must_use_table'); + + $table = $this->from[0]; + } + + // If caching is enabled, clear the cache before inserting + ($this->config['cache'] === TRUE) and $this->clear_cache(); + + $sql = $this->driver->insert($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); + + $this->reset_write(); + + return $this->query($sql); + } + + /** + * Adds an "IN" condition to the where clause + * + * @param string Name of the column being examined + * @param mixed An array or string to match against + * @param bool Generate a NOT IN clause instead + * @return Database_Core This Database object. + */ + public function in($field, $values, $not = FALSE) + { + if (is_array($values)) + { + $escaped_values = array(); + foreach ($values as $v) + { + if (is_numeric($v)) + { + $escaped_values[] = $v; + } + else + { + $escaped_values[] = "'".$this->driver->escape_str($v)."'"; + } + } + $values = implode(",", $escaped_values); + } + + $where = $this->driver->escape_column(((strpos($field,'.') !== FALSE) ? $this->config['table_prefix'] : ''). $field).' '.($not === TRUE ? 'NOT ' : '').'IN ('.$values.')'; + $this->where[] = $this->driver->where($where, '', 'AND ', count($this->where), -1); + + return $this; + } + + /** + * Adds a "NOT IN" condition to the where clause + * + * @param string Name of the column being examined + * @param mixed An array or string to match against + * @return Database_Core This Database object. + */ + public function notin($field, $values) + { + return $this->in($field, $values, TRUE); + } + + /** + * Compiles a merge string and runs the query. + * + * @param string table name + * @param array array of key/value pairs to merge + * @return Database_Result Query result + */ + public function merge($table = '', $set = NULL) + { + if ( ! is_null($set)) + { + $this->set($set); + } + + if ($this->set == NULL) + throw new Kohana_Database_Exception('database.must_use_set'); + + if ($table == '') + { + if ( ! isset($this->from[0])) + throw new Kohana_Database_Exception('database.must_use_table'); + + $table = $this->from[0]; + } + + $sql = $this->driver->merge($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); + + $this->reset_write(); + return $this->query($sql); + } + + /** + * Compiles an update string and runs the query. + * + * @param string table name + * @param array associative array of update values + * @param array where clause + * @return Database_Result Query result + */ + public function update($table = '', $set = NULL, $where = NULL) + { + if ( is_array($set)) + { + $this->set($set); + } + + if ( ! is_null($where)) + { + $this->where($where); + } + + if ($this->set == FALSE) + throw new Kohana_Database_Exception('database.must_use_set'); + + if ($table == '') + { + if ( ! isset($this->from[0])) + throw new Kohana_Database_Exception('database.must_use_table'); + + $table = $this->from[0]; + } + + $sql = $this->driver->update($this->config['table_prefix'].$table, $this->set, $this->where); + + $this->reset_write(); + return $this->query($sql); + } + + /** + * Compiles a delete string and runs the query. + * + * @param string table name + * @param array where clause + * @return Database_Result Query result + */ + public function delete($table = '', $where = NULL) + { + if ($table == '') + { + if ( ! isset($this->from[0])) + throw new Kohana_Database_Exception('database.must_use_table'); + + $table = $this->from[0]; + } + else + { + $table = $this->config['table_prefix'].$table; + } + + if (! is_null($where)) + { + $this->where($where); + } + + if (count($this->where) < 1) + throw new Kohana_Database_Exception('database.must_use_where'); + + $sql = $this->driver->delete($table, $this->where); + + $this->reset_write(); + return $this->query($sql); + } + + /** + * Returns the last query run. + * + * @return string SQL + */ + public function last_query() + { + return $this->last_query; + } + + /** + * Count query records. + * + * @param string table name + * @param array where clause + * @return integer + */ + public function count_records($table = FALSE, $where = NULL) + { + if (count($this->from) < 1) + { + if ($table == FALSE) + throw new Kohana_Database_Exception('database.must_use_table'); + + $this->from($table); + } + + if ($where !== NULL) + { + $this->where($where); + } + + $query = $this->select('COUNT(*) AS '.$this->escape_column('records_found'))->get()->result(TRUE); + + return (int) $query->current()->records_found; + } + + /** + * Resets all private select variables. + * + * @return void + */ + protected function reset_select() + { + $this->select = array(); + $this->from = array(); + $this->join = array(); + $this->where = array(); + $this->orderby = array(); + $this->groupby = array(); + $this->having = array(); + $this->distinct = FALSE; + $this->limit = FALSE; + $this->offset = FALSE; + } + + /** + * Resets all private insert and update variables. + * + * @return void + */ + protected function reset_write() + { + $this->set = array(); + $this->from = array(); + $this->where = array(); + } + + /** + * Lists all the tables in the current database. + * + * @return array + */ + public function list_tables() + { + $this->link or $this->connect(); + + return $this->driver->list_tables(); + } + + /** + * See if a table exists in the database. + * + * @param string table name + * @param boolean True to attach table prefix + * @return boolean + */ + public function table_exists($table_name, $prefix = TRUE) + { + if ($prefix) + return in_array($this->config['table_prefix'].$table_name, $this->list_tables()); + else + return in_array($table_name, $this->list_tables()); + } + + /** + * Combine a SQL statement with the bind values. Used for safe queries. + * + * @param string query to bind to the values + * @param array array of values to bind to the query + * @return string + */ + public function compile_binds($sql, $binds) + { + foreach ((array) $binds as $val) + { + // If the SQL contains no more bind marks ("?"), we're done. + if (($next_bind_pos = strpos($sql, '?')) === FALSE) + break; + + // Properly escape the bind value. + $val = $this->driver->escape($val); + + // Temporarily replace possible bind marks ("?"), in the bind value itself, with a placeholder. + $val = str_replace('?', '{%B%}', $val); + + // Replace the first bind mark ("?") with its corresponding value. + $sql = substr($sql, 0, $next_bind_pos).$val.substr($sql, $next_bind_pos + 1); + } + + // Restore placeholders. + return str_replace('{%B%}', '?', $sql); + } + + /** + * Get the field data for a database table, along with the field's attributes. + * + * @param string table name + * @return array + */ + public function field_data($table = '') + { + $this->link or $this->connect(); + + return $this->driver->field_data($this->config['table_prefix'].$table); + } + + /** + * Get the field data for a database table, along with the field's attributes. + * + * @param string table name + * @return array + */ + public function list_fields($table = '') + { + $this->link or $this->connect(); + + return $this->driver->list_fields($this->config['table_prefix'].$table); + } + + /** + * Escapes a value for a query. + * + * @param mixed value to escape + * @return string + */ + public function escape($value) + { + return $this->driver->escape($value); + } + + /** + * Escapes a string for a query. + * + * @param string string to escape + * @return string + */ + public function escape_str($str) + { + return $this->driver->escape_str($str); + } + + /** + * Escapes a table name for a query. + * + * @param string string to escape + * @return string + */ + public function escape_table($table) + { + return $this->driver->escape_table($table); + } + + /** + * Escapes a column name for a query. + * + * @param string string to escape + * @return string + */ + public function escape_column($table) + { + return $this->driver->escape_column($table); + } + + /** + * Returns table prefix of current configuration. + * + * @return string + */ + public function table_prefix() + { + return $this->config['table_prefix']; + } + + /** + * Clears the query cache. + * + * @param string|TRUE clear cache by SQL statement or TRUE for last query + * @return Database_Core This Database object. + */ + public function clear_cache($sql = NULL) + { + if ($sql === TRUE) + { + $this->driver->clear_cache($this->last_query); + } + elseif (is_string($sql)) + { + $this->driver->clear_cache($sql); + } + else + { + $this->driver->clear_cache(); + } + + return $this; + } + + /** + * Pushes existing query space onto the query stack. Use push + * and pop to prevent queries from clashing before they are + * executed + * + * @return Database_Core This Databaes object + */ + public function push() + { + array_push($this->query_history, array( + $this->select, + $this->from, + $this->join, + $this->where, + $this->orderby, + $this->order, + $this->groupby, + $this->having, + $this->distinct, + $this->limit, + $this->offset + )); + + $this->reset_select(); + + return $this; + } + + /** + * Pops from query stack into the current query space. + * + * @return Database_Core This Databaes object + */ + public function pop() + { + if (count($this->query_history) == 0) + { + // No history + return $this; + } + + list( + $this->select, + $this->from, + $this->join, + $this->where, + $this->orderby, + $this->order, + $this->groupby, + $this->having, + $this->distinct, + $this->limit, + $this->offset + ) = array_pop($this->query_history); + + return $this; + } + + /** + * Count the number of records in the last query, without LIMIT or OFFSET applied. + * + * @return integer + */ + public function count_last_query() + { + if ($sql = $this->last_query()) + { + if (stripos($sql, 'LIMIT') !== FALSE) + { + // Remove LIMIT from the SQL + $sql = preg_replace('/\sLIMIT\s+[^a-z]+/i', ' ', $sql); + } + + if (stripos($sql, 'OFFSET') !== FALSE) + { + // Remove OFFSET from the SQL + $sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql); + } + + // Get the total rows from the last query executed + $result = $this->query + ( + 'SELECT COUNT(*) AS '.$this->escape_column('total_rows').' '. + 'FROM ('.trim($sql).') AS '.$this->escape_table('counted_results') + ); + + // Return the total number of rows from the query + return (int) $result->current()->total_rows; + } + + return FALSE; + } + +} // End Database Class + + +/** + * Sets the code for a Database exception. + */ +class Kohana_Database_Exception extends Kohana_Exception { + + protected $code = E_DATABASE_ERROR; + +} // End Kohana Database Exception diff --git a/lib/kohana/system/libraries/Database_Expression.php b/lib/kohana/system/libraries/Database_Expression.php new file mode 100644 index 0000000..940a636 --- /dev/null +++ b/lib/kohana/system/libraries/Database_Expression.php @@ -0,0 +1,26 @@ +expression = $expression; + } + + public function __toString() + { + return (string) $this->expression; + } + +} // End Database Expr Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/Encrypt.php b/lib/kohana/system/libraries/Encrypt.php new file mode 100644 index 0000000..3d564f9 --- /dev/null +++ b/lib/kohana/system/libraries/Encrypt.php @@ -0,0 +1,164 @@ + $size) + { + // Shorten the key to the maximum size + $config['key'] = substr($config['key'], 0, $size); + } + + // Find the initialization vector size + $config['iv_size'] = mcrypt_get_iv_size($config['cipher'], $config['mode']); + + // Cache the config in the object + $this->config = $config; + + Kohana::log('debug', 'Encrypt Library initialized'); + } + + /** + * Encrypts a string and returns an encrypted string that can be decoded. + * + * @param string data to be encrypted + * @return string encrypted data + */ + public function encode($data) + { + // Set the rand type if it has not already been set + if (Encrypt::$rand === NULL) + { + if (KOHANA_IS_WIN) + { + // Windows only supports the system random number generator + Encrypt::$rand = MCRYPT_RAND; + } + else + { + if (defined('MCRYPT_DEV_URANDOM')) + { + // Use /dev/urandom + Encrypt::$rand = MCRYPT_DEV_URANDOM; + } + elseif (defined('MCRYPT_DEV_RANDOM')) + { + // Use /dev/random + Encrypt::$rand = MCRYPT_DEV_RANDOM; + } + else + { + // Use the system random number generator + Encrypt::$rand = MCRYPT_RAND; + } + } + } + + if (Encrypt::$rand === MCRYPT_RAND) + { + // The system random number generator must always be seeded each + // time it is used, or it will not produce true random results + mt_srand(); + } + + // Create a random initialization vector of the proper size for the current cipher + $iv = mcrypt_create_iv($this->config['iv_size'], Encrypt::$rand); + + // Encrypt the data using the configured options and generated iv + $data = mcrypt_encrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv); + + // Use base64 encoding to convert to a string + return base64_encode($iv.$data); + } + + /** + * Decrypts an encoded string back to its original value. + * + * @param string encoded string to be decrypted + * @return string decrypted data + */ + public function decode($data) + { + // Convert the data back to binary + $data = base64_decode($data); + + // Extract the initialization vector from the data + $iv = substr($data, 0, $this->config['iv_size']); + + // Remove the iv from the data + $data = substr($data, $this->config['iv_size']); + + // Return the decrypted data, trimming the \0 padding bytes from the end of the data + return rtrim(mcrypt_decrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv), "\0"); + } + +} // End Encrypt diff --git a/lib/kohana/system/libraries/Event_Observer.php b/lib/kohana/system/libraries/Event_Observer.php new file mode 100644 index 0000000..086c8a2 --- /dev/null +++ b/lib/kohana/system/libraries/Event_Observer.php @@ -0,0 +1,70 @@ +update($caller); + } + + /** + * Updates the observer subject with a new caller. + * + * @chainable + * @param object Event_Subject + * @return object + */ + public function update(SplSubject $caller) + { + if ( ! ($caller instanceof Event_Subject)) + throw new Kohana_Exception('event.invalid_subject', get_class($caller), get_class($this)); + + // Update the caller + $this->caller = $caller; + + return $this; + } + + /** + * Detaches this observer from the subject. + * + * @chainable + * @return object + */ + public function remove() + { + // Detach this observer from the caller + $this->caller->detach($this); + + return $this; + } + + /** + * Notify the observer of a new message. This function must be defined in + * all observers and must take exactly one parameter of any type. + * + * @param mixed message string, object, or array + * @return void + */ + abstract public function notify($message); + +} // End Event Observer \ No newline at end of file diff --git a/lib/kohana/system/libraries/Event_Subject.php b/lib/kohana/system/libraries/Event_Subject.php new file mode 100644 index 0000000..d1ccc54 --- /dev/null +++ b/lib/kohana/system/libraries/Event_Subject.php @@ -0,0 +1,67 @@ +listeners[spl_object_hash($obj)] = $obj; + + return $this; + } + + /** + * Detach an observer from the object. + * + * @chainable + * @param object Event_Observer + * @return object + */ + public function detach(SplObserver $obj) + { + // Remove the listener + unset($this->listeners[spl_object_hash($obj)]); + + return $this; + } + + /** + * Notify all attached observers of a new message. + * + * @chainable + * @param mixed message string, object, or array + * @return object + */ + public function notify($message) + { + foreach ($this->listeners as $obj) + { + $obj->notify($message); + } + + return $this; + } + +} // End Event Subject \ No newline at end of file diff --git a/lib/kohana/system/libraries/Image.php b/lib/kohana/system/libraries/Image.php new file mode 100644 index 0000000..2de0658 --- /dev/null +++ b/lib/kohana/system/libraries/Image.php @@ -0,0 +1,431 @@ + 'gif', + IMAGETYPE_JPEG => 'jpg', + IMAGETYPE_PNG => 'png', + IMAGETYPE_TIFF_II => 'tiff', + IMAGETYPE_TIFF_MM => 'tiff', + ); + + // Driver instance + protected $driver; + + // Driver actions + protected $actions = array(); + + // Reference to the current image filename + protected $image = ''; + + /** + * Creates a new Image instance and returns it. + * + * @param string filename of image + * @param array non-default configurations + * @return object + */ + public static function factory($image, $config = NULL) + { + return new Image($image, $config); + } + + /** + * Creates a new image editor instance. + * + * @throws Kohana_Exception + * @param string filename of image + * @param array non-default configurations + * @return void + */ + public function __construct($image, $config = NULL) + { + static $check; + + // Make the check exactly once + ($check === NULL) and $check = function_exists('getimagesize'); + + if ($check === FALSE) + throw new Kohana_Exception('image.getimagesize_missing'); + + // Check to make sure the image exists + if ( ! is_file($image)) + throw new Kohana_Exception('image.file_not_found', $image); + + // Disable error reporting, to prevent PHP warnings + $ER = error_reporting(0); + + // Fetch the image size and mime type + $image_info = getimagesize($image); + + // Turn on error reporting again + error_reporting($ER); + + // Make sure that the image is readable and valid + if ( ! is_array($image_info) OR count($image_info) < 3) + throw new Kohana_Exception('image.file_unreadable', $image); + + // Check to make sure the image type is allowed + if ( ! isset(Image::$allowed_types[$image_info[2]])) + throw new Kohana_Exception('image.type_not_allowed', $image); + + // Image has been validated, load it + $this->image = array + ( + 'file' => str_replace('\\', '/', realpath($image)), + 'width' => $image_info[0], + 'height' => $image_info[1], + 'type' => $image_info[2], + 'ext' => Image::$allowed_types[$image_info[2]], + 'mime' => $image_info['mime'] + ); + + // Load configuration + $this->config = (array) $config + Kohana::config('image'); + + // Set driver class name + $driver = 'Image_'.ucfirst($this->config['driver']).'_Driver'; + + // Load the driver + if ( ! Kohana::auto_load($driver)) + throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); + + // Initialize the driver + $this->driver = new $driver($this->config['params']); + + // Validate the driver + if ( ! ($this->driver instanceof Image_Driver)) + throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Image_Driver'); + } + + /** + * Handles retrieval of pre-save image properties + * + * @param string property name + * @return mixed + */ + public function __get($property) + { + if (isset($this->image[$property])) + { + return $this->image[$property]; + } + else + { + throw new Kohana_Exception('core.invalid_property', $property, get_class($this)); + } + } + + /** + * Resize an image to a specific width and height. By default, Kohana will + * maintain the aspect ratio using the width as the master dimension. If you + * wish to use height as master dim, set $image->master_dim = Image::HEIGHT + * This method is chainable. + * + * @throws Kohana_Exception + * @param integer width + * @param integer height + * @param integer one of: Image::NONE, Image::AUTO, Image::WIDTH, Image::HEIGHT + * @return object + */ + public function resize($width, $height, $master = NULL) + { + if ( ! $this->valid_size('width', $width)) + throw new Kohana_Exception('image.invalid_width', $width); + + if ( ! $this->valid_size('height', $height)) + throw new Kohana_Exception('image.invalid_height', $height); + + if (empty($width) AND empty($height)) + throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); + + if ($master === NULL) + { + // Maintain the aspect ratio by default + $master = Image::AUTO; + } + elseif ( ! $this->valid_size('master', $master)) + throw new Kohana_Exception('image.invalid_master'); + + $this->actions['resize'] = array + ( + 'width' => $width, + 'height' => $height, + 'master' => $master, + ); + + return $this; + } + + /** + * Crop an image to a specific width and height. You may also set the top + * and left offset. + * This method is chainable. + * + * @throws Kohana_Exception + * @param integer width + * @param integer height + * @param integer top offset, pixel value or one of: top, center, bottom + * @param integer left offset, pixel value or one of: left, center, right + * @return object + */ + public function crop($width, $height, $top = 'center', $left = 'center') + { + if ( ! $this->valid_size('width', $width)) + throw new Kohana_Exception('image.invalid_width', $width); + + if ( ! $this->valid_size('height', $height)) + throw new Kohana_Exception('image.invalid_height', $height); + + if ( ! $this->valid_size('top', $top)) + throw new Kohana_Exception('image.invalid_top', $top); + + if ( ! $this->valid_size('left', $left)) + throw new Kohana_Exception('image.invalid_left', $left); + + if (empty($width) AND empty($height)) + throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); + + $this->actions['crop'] = array + ( + 'width' => $width, + 'height' => $height, + 'top' => $top, + 'left' => $left, + ); + + return $this; + } + + /** + * Allows rotation of an image by 180 degrees clockwise or counter clockwise. + * + * @param integer degrees + * @return object + */ + public function rotate($degrees) + { + $degrees = (int) $degrees; + + if ($degrees > 180) + { + do + { + // Keep subtracting full circles until the degrees have normalized + $degrees -= 360; + } + while($degrees > 180); + } + + if ($degrees < -180) + { + do + { + // Keep adding full circles until the degrees have normalized + $degrees += 360; + } + while($degrees < -180); + } + + $this->actions['rotate'] = $degrees; + + return $this; + } + + /** + * Flip an image horizontally or vertically. + * + * @throws Kohana_Exception + * @param integer direction + * @return object + */ + public function flip($direction) + { + if ($direction !== Image::HORIZONTAL AND $direction !== Image::VERTICAL) + throw new Kohana_Exception('image.invalid_flip'); + + $this->actions['flip'] = $direction; + + return $this; + } + + /** + * Change the quality of an image. + * + * @param integer quality as a percentage + * @return object + */ + public function quality($amount) + { + $this->actions['quality'] = max(1, min($amount, 100)); + + return $this; + } + + /** + * Sharpen an image. + * + * @param integer amount to sharpen, usually ~20 is ideal + * @return object + */ + public function sharpen($amount) + { + $this->actions['sharpen'] = max(1, min($amount, 100)); + + return $this; + } + + /** + * Save the image to a new image or overwrite this image. + * + * @throws Kohana_Exception + * @param string new image filename + * @param integer permissions for new image + * @param boolean keep or discard image process actions + * @return object + */ + public function save($new_image = FALSE, $chmod = 0644, $keep_actions = FALSE) + { + // If no new image is defined, use the current image + empty($new_image) and $new_image = $this->image['file']; + + // Separate the directory and filename + $dir = pathinfo($new_image, PATHINFO_DIRNAME); + $file = pathinfo($new_image, PATHINFO_BASENAME); + + // Normalize the path + $dir = str_replace('\\', '/', realpath($dir)).'/'; + + if ( ! is_writable($dir)) + throw new Kohana_Exception('image.directory_unwritable', $dir); + + if ($status = $this->driver->process($this->image, $this->actions, $dir, $file)) + { + if ($chmod !== FALSE) + { + // Set permissions + chmod($new_image, $chmod); + } + } + + // Reset actions. Subsequent save() or render() will not apply previous actions. + if ($keep_actions === FALSE) + $this->actions = array(); + + return $status; + } + + /** + * Output the image to the browser. + * + * @param boolean keep or discard image process actions + * @return object + */ + public function render($keep_actions = FALSE) + { + $new_image = $this->image['file']; + + // Separate the directory and filename + $dir = pathinfo($new_image, PATHINFO_DIRNAME); + $file = pathinfo($new_image, PATHINFO_BASENAME); + + // Normalize the path + $dir = str_replace('\\', '/', realpath($dir)).'/'; + + // Process the image with the driver + $status = $this->driver->process($this->image, $this->actions, $dir, $file, $render = TRUE); + + // Reset actions. Subsequent save() or render() will not apply previous actions. + if ($keep_actions === FALSE) + $this->actions = array(); + + return $status; + } + + /** + * Sanitize a given value type. + * + * @param string type of property + * @param mixed property value + * @return boolean + */ + protected function valid_size($type, & $value) + { + if (is_null($value)) + return TRUE; + + if ( ! is_scalar($value)) + return FALSE; + + switch ($type) + { + case 'width': + case 'height': + if (is_string($value) AND ! ctype_digit($value)) + { + // Only numbers and percent signs + if ( ! preg_match('/^[0-9]++%$/D', $value)) + return FALSE; + } + else + { + $value = (int) $value; + } + break; + case 'top': + if (is_string($value) AND ! ctype_digit($value)) + { + if ( ! in_array($value, array('top', 'bottom', 'center'))) + return FALSE; + } + else + { + $value = (int) $value; + } + break; + case 'left': + if (is_string($value) AND ! ctype_digit($value)) + { + if ( ! in_array($value, array('left', 'right', 'center'))) + return FALSE; + } + else + { + $value = (int) $value; + } + break; + case 'master': + if ($value !== Image::NONE AND + $value !== Image::AUTO AND + $value !== Image::WIDTH AND + $value !== Image::HEIGHT) + return FALSE; + break; + } + + return TRUE; + } + +} // End Image \ No newline at end of file diff --git a/lib/kohana/system/libraries/Input.php b/lib/kohana/system/libraries/Input.php new file mode 100644 index 0000000..0e23c80 --- /dev/null +++ b/lib/kohana/system/libraries/Input.php @@ -0,0 +1,452 @@ +use_xss_clean = (bool) Kohana::config('core.global_xss_filtering'); + + if (Input::$instance === NULL) + { + // magic_quotes_runtime is enabled + if (get_magic_quotes_runtime()) + { + set_magic_quotes_runtime(0); + Kohana::log('debug', 'Disable magic_quotes_runtime! It is evil and deprecated: http://php.net/magic_quotes'); + } + + // magic_quotes_gpc is enabled + if (get_magic_quotes_gpc()) + { + $this->magic_quotes_gpc = TRUE; + Kohana::log('debug', 'Disable magic_quotes_gpc! It is evil and deprecated: http://php.net/magic_quotes'); + } + + // register_globals is enabled + if (ini_get('register_globals')) + { + if (isset($_REQUEST['GLOBALS'])) + { + // Prevent GLOBALS override attacks + exit('Global variable overload attack.'); + } + + // Destroy the REQUEST global + $_REQUEST = array(); + + // These globals are standard and should not be removed + $preserve = array('GLOBALS', '_REQUEST', '_GET', '_POST', '_FILES', '_COOKIE', '_SERVER', '_ENV', '_SESSION'); + + // This loop has the same effect as disabling register_globals + foreach (array_diff(array_keys($GLOBALS), $preserve) as $key) + { + global $$key; + $$key = NULL; + + // Unset the global variable + unset($GLOBALS[$key], $$key); + } + + // Warn the developer about register globals + Kohana::log('debug', 'Disable register_globals! It is evil and deprecated: http://php.net/register_globals'); + } + + if (is_array($_GET)) + { + foreach ($_GET as $key => $val) + { + // Sanitize $_GET + $_GET[$this->clean_input_keys($key)] = $this->clean_input_data($val); + } + } + else + { + $_GET = array(); + } + + if (is_array($_POST)) + { + foreach ($_POST as $key => $val) + { + // Sanitize $_POST + $_POST[$this->clean_input_keys($key)] = $this->clean_input_data($val); + } + } + else + { + $_POST = array(); + } + + if (is_array($_COOKIE)) + { + foreach ($_COOKIE as $key => $val) + { + // Ignore special attributes in RFC2109 compliant cookies + if ($key == '$Version' OR $key == '$Path' OR $key == '$Domain') + continue; + + // Sanitize $_COOKIE + $_COOKIE[$this->clean_input_keys($key)] = $this->clean_input_data($val); + } + } + else + { + $_COOKIE = array(); + } + + // Create a singleton + Input::$instance = $this; + + Kohana::log('debug', 'Global GET, POST and COOKIE data sanitized'); + } + } + + /** + * Fetch an item from the $_GET array. + * + * @param string key to find + * @param mixed default value + * @param boolean XSS clean the value + * @return mixed + */ + public function get($key = array(), $default = NULL, $xss_clean = FALSE) + { + return $this->search_array($_GET, $key, $default, $xss_clean); + } + + /** + * Fetch an item from the $_POST array. + * + * @param string key to find + * @param mixed default value + * @param boolean XSS clean the value + * @return mixed + */ + public function post($key = array(), $default = NULL, $xss_clean = FALSE) + { + return $this->search_array($_POST, $key, $default, $xss_clean); + } + + /** + * Fetch an item from the $_COOKIE array. + * + * @param string key to find + * @param mixed default value + * @param boolean XSS clean the value + * @return mixed + */ + public function cookie($key = array(), $default = NULL, $xss_clean = FALSE) + { + return $this->search_array($_COOKIE, $key, $default, $xss_clean); + } + + /** + * Fetch an item from the $_SERVER array. + * + * @param string key to find + * @param mixed default value + * @param boolean XSS clean the value + * @return mixed + */ + public function server($key = array(), $default = NULL, $xss_clean = FALSE) + { + return $this->search_array($_SERVER, $key, $default, $xss_clean); + } + + /** + * Fetch an item from a global array. + * + * @param array array to search + * @param string key to find + * @param mixed default value + * @param boolean XSS clean the value + * @return mixed + */ + protected function search_array($array, $key, $default = NULL, $xss_clean = FALSE) + { + if ($key === array()) + return $array; + + if ( ! isset($array[$key])) + return $default; + + // Get the value + $value = $array[$key]; + + if ($this->use_xss_clean === FALSE AND $xss_clean === TRUE) + { + // XSS clean the value + $value = $this->xss_clean($value); + } + + return $value; + } + + /** + * Fetch the IP Address. + * + * @return string + */ + public function ip_address() + { + if ($this->ip_address !== NULL) + return $this->ip_address; + + // Server keys that could contain the client IP address + $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'); + + foreach ($keys as $key) + { + if ($ip = $this->server($key)) + { + $this->ip_address = $ip; + + // An IP address has been found + break; + } + } + + if ($comma = strrpos($this->ip_address, ',') !== FALSE) + { + $this->ip_address = substr($this->ip_address, $comma + 1); + } + + if ( ! valid::ip($this->ip_address)) + { + // Use an empty IP + $this->ip_address = '0.0.0.0'; + } + + return $this->ip_address; + } + + /** + * Clean cross site scripting exploits from string. + * HTMLPurifier may be used if installed, otherwise defaults to built in method. + * Note - This function should only be used to deal with data upon submission. + * It's not something that should be used for general runtime processing + * since it requires a fair amount of processing overhead. + * + * @param string data to clean + * @param string xss_clean method to use ('htmlpurifier' or defaults to built-in method) + * @return string + */ + public function xss_clean($data, $tool = NULL) + { + if ($tool === NULL) + { + // Use the default tool + $tool = Kohana::config('core.global_xss_filtering'); + } + + if (is_array($data)) + { + foreach ($data as $key => $val) + { + $data[$key] = $this->xss_clean($val, $tool); + } + + return $data; + } + + // Do not clean empty strings + if (trim($data) === '') + return $data; + + if ($tool === TRUE) + { + // NOTE: This is necessary because switch is NOT type-sensative! + $tool = 'default'; + } + + switch ($tool) + { + case 'htmlpurifier': + /** + * @todo License should go here, http://htmlpurifier.org/ + */ + if ( ! class_exists('HTMLPurifier_Config', FALSE)) + { + // Load HTMLPurifier + require Kohana::find_file('vendor', 'htmlpurifier/HTMLPurifier.auto', TRUE); + require 'HTMLPurifier.func.php'; + } + + // Set configuration + $config = HTMLPurifier_Config::createDefault(); + $config->set('HTML', 'TidyLevel', 'none'); // Only XSS cleaning now + + // Run HTMLPurifier + $data = HTMLPurifier($data, $config); + break; + default: + // http://svn.bitflux.ch/repos/public/popoon/trunk/classes/externalinput.php + // +----------------------------------------------------------------------+ + // | Copyright (c) 2001-2006 Bitflux GmbH | + // +----------------------------------------------------------------------+ + // | Licensed under the Apache License, Version 2.0 (the "License"); | + // | you may not use this file except in compliance with the License. | + // | You may obtain a copy of the License at | + // | http://www.apache.org/licenses/LICENSE-2.0 | + // | Unless required by applicable law or agreed to in writing, software | + // | distributed under the License is distributed on an "AS IS" BASIS, | + // | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | + // | implied. See the License for the specific language governing | + // | permissions and limitations under the License. | + // +----------------------------------------------------------------------+ + // | Author: Christian Stocker | + // +----------------------------------------------------------------------+ + // + // Kohana Modifications: + // * Changed double quotes to single quotes, changed indenting and spacing + // * Removed magic_quotes stuff + // * Increased regex readability: + // * Used delimeters that aren't found in the pattern + // * Removed all unneeded escapes + // * Deleted U modifiers and swapped greediness where needed + // * Increased regex speed: + // * Made capturing parentheses non-capturing where possible + // * Removed parentheses where possible + // * Split up alternation alternatives + // * Made some quantifiers possessive + + // Fix &entity\n; + $data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data); + $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); + $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); + $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); + + // Remove any attribute starting with "on" or xmlns + $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); + + // Remove javascript: and vbscript: protocols + $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); + $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); + $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); + + // Only works in IE: + $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); + $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); + $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); + + // Remove namespaced elements (we do not need them) + $data = preg_replace('#]*+>#i', '', $data); + + do + { + // Remove really unwanted tags + $old_data = $data; + $data = preg_replace('#]*+>#i', '', $data); + } + while ($old_data !== $data); + break; + } + + return $data; + } + + /** + * This is a helper method. It enforces W3C specifications for allowed + * key name strings, to prevent malicious exploitation. + * + * @param string string to clean + * @return string + */ + public function clean_input_keys($str) + { + $chars = PCRE_UNICODE_PROPERTIES ? '\pL' : 'a-zA-Z'; + + if ( ! preg_match('#^['.$chars.'0-9:_.-]++$#uD', $str)) + { + exit('Disallowed key characters in global data.'); + } + + return $str; + } + + /** + * This is a helper method. It escapes data and forces all newline + * characters to "\n". + * + * @param unknown_type string to clean + * @return string + */ + public function clean_input_data($str) + { + if (is_array($str)) + { + $new_array = array(); + foreach ($str as $key => $val) + { + // Recursion! + $new_array[$this->clean_input_keys($key)] = $this->clean_input_data($val); + } + return $new_array; + } + + if ($this->magic_quotes_gpc === TRUE) + { + // Remove annoying magic quotes + $str = stripslashes($str); + } + + if ($this->use_xss_clean === TRUE) + { + $str = $this->xss_clean($str); + } + + if (strpos($str, "\r") !== FALSE) + { + // Standardize newlines + $str = str_replace(array("\r\n", "\r"), "\n", $str); + } + + return $str; + } + +} // End Input Class diff --git a/lib/kohana/system/libraries/Model.php b/lib/kohana/system/libraries/Model.php new file mode 100644 index 0000000..0c9fd8d --- /dev/null +++ b/lib/kohana/system/libraries/Model.php @@ -0,0 +1,31 @@ +db)) + { + // Load the default database + $this->db = Database::instance($this->db); + } + } + +} // End Model \ No newline at end of file diff --git a/lib/kohana/system/libraries/ORM.php b/lib/kohana/system/libraries/ORM.php new file mode 100644 index 0000000..c104860 --- /dev/null +++ b/lib/kohana/system/libraries/ORM.php @@ -0,0 +1,1431 @@ +object_name = strtolower(substr(get_class($this), 0, -6)); + $this->object_plural = inflector::plural($this->object_name); + + if (!isset($this->sorting)) + { + // Default sorting + $this->sorting = array($this->primary_key => 'asc'); + } + + // Initialize database + $this->__initialize(); + + // Clear the object + $this->clear(); + + if (is_object($id)) + { + // Load an object + $this->load_values((array) $id); + } + elseif (!empty($id)) + { + // Find an object + $this->find($id); + } + } + + /** + * Prepares the model database connection, determines the table name, + * and loads column information. + * + * @return void + */ + public function __initialize() + { + if ( ! is_object($this->db)) + { + // Get database instance + $this->db = Database::instance($this->db); + } + + if (empty($this->table_name)) + { + // Table name is the same as the object name + $this->table_name = $this->object_name; + + if ($this->table_names_plural === TRUE) + { + // Make the table name plural + $this->table_name = inflector::plural($this->table_name); + } + } + + if (is_array($this->ignored_columns)) + { + // Make the ignored columns mirrored = mirrored + $this->ignored_columns = array_combine($this->ignored_columns, $this->ignored_columns); + } + + // Load column information + $this->reload_columns(); + } + + /** + * Allows serialization of only the object data and state, to prevent + * "stale" objects being unserialized, which also requires less memory. + * + * @return array + */ + public function __sleep() + { + // Store only information about the object + return array('object_name', 'object', 'changed', 'loaded', 'saved', 'sorting'); + } + + /** + * Prepares the database connection and reloads the object. + * + * @return void + */ + public function __wakeup() + { + // Initialize database + $this->__initialize(); + + if ($this->reload_on_wakeup === TRUE) + { + // Reload the object + $this->reload(); + } + } + + /** + * Handles pass-through to database methods. Calls to query methods + * (query, get, insert, update) are not allowed. Query builder methods + * are chainable. + * + * @param string method name + * @param array method arguments + * @return mixed + */ + public function __call($method, array $args) + { + if (method_exists($this->db, $method)) + { + if (in_array($method, array('query', 'get', 'insert', 'update', 'delete'))) + throw new Kohana_Exception('orm.query_methods_not_allowed'); + + // Method has been applied to the database + $this->db_applied[$method] = $method; + + // Number of arguments passed + $num_args = count($args); + + if ($method === 'select' AND $num_args > 3) + { + // Call select() manually to avoid call_user_func_array + $this->db->select($args); + } + else + { + // We use switch here to manually call the database methods. This is + // done for speed: call_user_func_array can take over 300% longer to + // make calls. Most database methods are 4 arguments or less, so this + // avoids almost any calls to call_user_func_array. + + switch ($num_args) + { + case 0: + if (in_array($method, array('open_paren', 'close_paren', 'enable_cache', 'disable_cache'))) + { + // Should return ORM, not Database + $this->db->$method(); + } + else + { + // Support for things like reset_select, reset_write, list_tables + return $this->db->$method(); + } + break; + case 1: + $this->db->$method($args[0]); + break; + case 2: + $this->db->$method($args[0], $args[1]); + break; + case 3: + $this->db->$method($args[0], $args[1], $args[2]); + break; + case 4: + $this->db->$method($args[0], $args[1], $args[2], $args[3]); + break; + default: + // Here comes the snail... + call_user_func_array(array($this->db, $method), $args); + break; + } + } + + return $this; + } + else + { + throw new Kohana_Exception('core.invalid_method', $method, get_class($this)); + } + } + + /** + * Handles retrieval of all model values, relationships, and metadata. + * + * @param string column name + * @return mixed + */ + public function __get($column) + { + if (array_key_exists($column, $this->object)) + { + return $this->object[$column]; + } + elseif (isset($this->related[$column])) + { + return $this->related[$column]; + } + elseif ($column === 'primary_key_value') + { + return $this->object[$this->primary_key]; + } + elseif ($model = $this->related_object($column)) + { + // This handles the has_one and belongs_to relationships + + if (in_array($model->object_name, $this->belongs_to) OR ! array_key_exists($this->foreign_key($column), $model->object)) + { + // Foreign key lies in this table (this model belongs_to target model) OR an invalid has_one relationship + $where = array($model->table_name.'.'.$model->primary_key => $this->object[$this->foreign_key($column)]); + } + else + { + // Foreign key lies in the target table (this model has_one target model) + $where = array($this->foreign_key($column, $model->table_name) => $this->primary_key_value); + } + + // one<>alias:one relationship + return $this->related[$column] = $model->find($where); + } + elseif (isset($this->has_many[$column])) + { + // Load the "middle" model + $through = ORM::factory(inflector::singular($this->has_many[$column])); + + // Load the "end" model + $model = ORM::factory(inflector::singular($column)); + + // Join ON target model's primary key set to 'through' model's foreign key + // User-defined foreign keys must be defined in the 'through' model + $join_table = $through->table_name; + $join_col1 = $through->foreign_key($model->object_name, $join_table); + $join_col2 = $model->table_name.'.'.$model->primary_key; + + // one<>alias:many relationship + return $this->related[$column] = $model + ->join($join_table, $join_col1, $join_col2) + ->where($through->foreign_key($this->object_name, $join_table), $this->object[$this->primary_key]) + ->find_all(); + } + elseif (in_array($column, $this->has_many)) + { + // one<>many relationship + $model = ORM::factory(inflector::singular($column)); + return $this->related[$column] = $model + ->where($this->foreign_key($column, $model->table_name), $this->object[$this->primary_key]) + ->find_all(); + } + elseif (in_array($column, $this->has_and_belongs_to_many)) + { + // Load the remote model, always singular + $model = ORM::factory(inflector::singular($column)); + + if ($this->has($model, TRUE)) + { + // many<>many relationship + return $this->related[$column] = $model + ->in($model->table_name.'.'.$model->primary_key, $this->changed_relations[$column]) + ->find_all(); + } + else + { + // empty many<>many relationship + return $this->related[$column] = $model + ->where($model->table_name.'.'.$model->primary_key, NULL) + ->find_all(); + } + } + elseif (isset($this->ignored_columns[$column])) + { + return NULL; + } + elseif (in_array($column, array + ( + 'object_name', 'object_plural', // Object + 'primary_key', 'primary_val', 'table_name', 'table_columns', // Table + 'loaded', 'saved', // Status + 'has_one', 'belongs_to', 'has_many', 'has_and_belongs_to_many', 'load_with' // Relationships + ))) + { + // Model meta information + return $this->$column; + } + else + { + throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); + } + } + + /** + * Handles setting of all model values, and tracks changes between values. + * + * @param string column name + * @param mixed column value + * @return void + */ + public function __set($column, $value) + { + if (isset($this->ignored_columns[$column])) + { + return NULL; + } + elseif (isset($this->object[$column]) OR array_key_exists($column, $this->object)) + { + if (isset($this->table_columns[$column])) + { + // Data has changed + $this->changed[$column] = $column; + + // Object is no longer saved + $this->saved = FALSE; + } + + $this->object[$column] = $this->load_type($column, $value); + } + elseif (in_array($column, $this->has_and_belongs_to_many) AND is_array($value)) + { + // Load relations + $model = ORM::factory(inflector::singular($column)); + + if ( ! isset($this->object_relations[$column])) + { + // Load relations + $this->has($model); + } + + // Change the relationships + $this->changed_relations[$column] = $value; + + if (isset($this->related[$column])) + { + // Force a reload of the relationships + unset($this->related[$column]); + } + } + else + { + throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); + } + } + + /** + * Checks if object data is set. + * + * @param string column name + * @return boolean + */ + public function __isset($column) + { + return (isset($this->object[$column]) OR isset($this->related[$column])); + } + + /** + * Unsets object data. + * + * @param string column name + * @return void + */ + public function __unset($column) + { + unset($this->object[$column], $this->changed[$column], $this->related[$column]); + } + + /** + * Displays the primary key of a model when it is converted to a string. + * + * @return string + */ + public function __toString() + { + return (string) $this->object[$this->primary_key]; + } + + /** + * Returns the values of this object as an array. + * + * @return array + */ + public function as_array() + { + $object = array(); + + foreach ($this->object as $key => $val) + { + // Reconstruct the array (calls __get) + $object[$key] = $this->$key; + } + + return $object; + } + + /** + * Binds another one-to-one object to this model. One-to-one objects + * can be nested using 'object1:object2' syntax + * + * @param string $target_path + * @return void + */ + public function with($target_path) + { + if (isset($this->with_applied[$target_path])) + { + // Don't join anything already joined + return $this; + } + + // Split object parts + $objects = explode(':', $target_path); + $target = $this; + foreach ($objects as $object) + { + // Go down the line of objects to find the given target + $parent = $target; + $target = $parent->related_object($object); + + if ( ! $target) + { + // Can't find related object + return $this; + } + } + + $target_name = $object; + + // Pop-off top object to get the parent object (user:photo:tag becomes user:photo - the parent table prefix) + array_pop($objects); + $parent_path = implode(':', $objects); + + if (empty($parent_path)) + { + // Use this table name itself for the parent object + $parent_path = $this->table_name; + } + else + { + if( ! isset($this->with_applied[$parent_path])) + { + // If the parent object hasn't been joined yet, do it first (otherwise LEFT JOINs fail) + $this->with($parent_path); + } + } + + // Add to with_applied to prevent duplicate joins + $this->with_applied[$target_path] = TRUE; + + // Use the keys of the empty object to determine the columns + $select = array_keys($target->object); + foreach ($select as $i => $column) + { + // Add the prefix so that load_result can determine the relationship + $select[$i] = $target_path.'.'.$column.' AS '.$target_path.':'.$column; + } + + + // Select all of the prefixed keys in the object + $this->db->select($select); + + if (in_array($target->object_name, $parent->belongs_to) OR ! isset($target->object[$parent->foreign_key($target_name)])) + { + // Parent belongs_to target, use target's primary key as join column + $join_col1 = $target->foreign_key(TRUE, $target_path); + $join_col2 = $parent->foreign_key($target_name, $parent_path); + } + else + { + // Parent has_one target, use parent's primary key as join column + $join_col2 = $parent->foreign_key(TRUE, $parent_path); + $join_col1 = $parent->foreign_key($target_name, $target_path); + } + + // This allows for models to use different table prefixes (sharing the same database) + $join_table = new Database_Expression($target->db->table_prefix().$target->table_name.' AS '.$this->db->table_prefix().$target_path); + + // Join the related object into the result + $this->db->join($join_table, $join_col1, $join_col2, 'LEFT'); + + return $this; + } + + /** + * Finds and loads a single database row into the object. + * + * @chainable + * @param mixed primary key or an array of clauses + * @return ORM + */ + public function find($id = NULL) + { + if ($id !== NULL) + { + if (is_array($id)) + { + // Search for all clauses + $this->db->where($id); + } + else + { + // Search for a specific column + $this->db->where($this->table_name.'.'.$this->unique_key($id), $id); + } + } + + return $this->load_result(); + } + + /** + * Finds multiple database rows and returns an iterator of the rows found. + * + * @chainable + * @param integer SQL limit + * @param integer SQL offset + * @return ORM_Iterator + */ + public function find_all($limit = NULL, $offset = NULL) + { + if ($limit !== NULL AND ! isset($this->db_applied['limit'])) + { + // Set limit + $this->limit($limit); + } + + if ($offset !== NULL AND ! isset($this->db_applied['offset'])) + { + // Set offset + $this->offset($offset); + } + + return $this->load_result(TRUE); + } + + /** + * Creates a key/value array from all of the objects available. Uses find_all + * to find the objects. + * + * @param string key column + * @param string value column + * @return array + */ + public function select_list($key = NULL, $val = NULL) + { + if ($key === NULL) + { + $key = $this->primary_key; + } + + if ($val === NULL) + { + $val = $this->primary_val; + } + + // Return a select list from the results + return $this->select($key, $val)->find_all()->select_list($key, $val); + } + + /** + * Validates the current object. This method should generally be called + * via the model, after the $_POST Validation object has been created. + * + * @param object Validation array + * @return boolean + */ + public function validate(Validation $array, $save = FALSE) + { + $safe_array = $array->safe_array(); + + if ( ! $array->submitted()) + { + foreach ($safe_array as $key => $value) + { + // Get the value from this object + $value = $this->$key; + + if (is_object($value) AND $value instanceof ORM_Iterator) + { + // Convert the value to an array of primary keys + $value = $value->primary_key_array(); + } + + // Pre-fill data + $array[$key] = $value; + } + } + + // Validate the array + if ($status = $array->validate()) + { + // Grab only set fields (excludes missing data, unlike safe_array) + $fields = $array->as_array(); + + foreach ($fields as $key => $value) + { + if (isset($safe_array[$key])) + { + // Set new data, ignoring any missing fields or fields without rules + $this->$key = $value; + } + } + + if ($save === TRUE OR is_string($save)) + { + // Save this object + $this->save(); + + if (is_string($save)) + { + // Redirect to the saved page + url::redirect($save); + } + } + } + + // Return validation status + return $status; + } + + /** + * Saves the current object. + * + * @chainable + * @return ORM + */ + public function save() + { + if ( ! empty($this->changed)) + { + $data = array(); + foreach ($this->changed as $column) + { + // Compile changed data + $data[$column] = $this->object[$column]; + } + + if ($this->loaded === TRUE) + { + $query = $this->db + ->where($this->primary_key, $this->object[$this->primary_key]) + ->update($this->table_name, $data); + + // Object has been saved + $this->saved = TRUE; + } + else + { + $query = $this->db + ->insert($this->table_name, $data); + + if ($query->count() > 0) + { + if (empty($this->object[$this->primary_key])) + { + // Load the insert id as the primary key + $this->object[$this->primary_key] = $query->insert_id(); + } + + // Object is now loaded and saved + $this->loaded = $this->saved = TRUE; + } + } + + if ($this->saved === TRUE) + { + // All changes have been saved + $this->changed = array(); + } + } + + if ($this->saved === TRUE AND ! empty($this->changed_relations)) + { + foreach ($this->changed_relations as $column => $values) + { + // All values that were added + $added = array_diff($values, $this->object_relations[$column]); + + // All values that were saved + $removed = array_diff($this->object_relations[$column], $values); + + if (empty($added) AND empty($removed)) + { + // No need to bother + continue; + } + + // Clear related columns + unset($this->related[$column]); + + // Load the model + $model = ORM::factory(inflector::singular($column)); + + if (($join_table = array_search($column, $this->has_and_belongs_to_many)) === FALSE) + continue; + + if (is_int($join_table)) + { + // No "through" table, load the default JOIN table + $join_table = $model->join_table($this->table_name); + } + + // Foreign keys for the join table + $object_fk = $this->foreign_key(NULL); + $related_fk = $model->foreign_key(NULL); + + if ( ! empty($added)) + { + foreach ($added as $id) + { + // Insert the new relationship + $this->db->insert($join_table, array + ( + $object_fk => $this->object[$this->primary_key], + $related_fk => $id, + )); + } + } + + if ( ! empty($removed)) + { + $this->db + ->where($object_fk, $this->object[$this->primary_key]) + ->in($related_fk, $removed) + ->delete($join_table); + } + + // Clear all relations for this column + unset($this->object_relations[$column], $this->changed_relations[$column]); + } + } + + return $this; + } + + /** + * Deletes the current object from the database. This does NOT destroy + * relationships that have been created with other objects. + * + * @chainable + * @return ORM + */ + public function delete($id = NULL) + { + if ($id === NULL AND $this->loaded) + { + // Use the the primary key value + $id = $this->object[$this->primary_key]; + } + + // Delete this object + $this->db->where($this->primary_key, $id)->delete($this->table_name); + + return $this->clear(); + } + + /** + * Delete all objects in the associated table. This does NOT destroy + * relationships that have been created with other objects. + * + * @chainable + * @param array ids to delete + * @return ORM + */ + public function delete_all($ids = NULL) + { + if (is_array($ids)) + { + // Delete only given ids + $this->db->in($this->primary_key, $ids); + } + elseif (is_null($ids)) + { + // Delete all records + $this->db->where('1=1'); + } + else + { + // Do nothing - safeguard + return $this; + } + + // Delete all objects + $this->db->delete($this->table_name); + + return $this->clear(); + } + + /** + * Unloads the current object and clears the status. + * + * @chainable + * @return ORM + */ + public function clear() + { + // Create an array with all the columns set to NULL + $columns = array_keys($this->table_columns); + $values = array_combine($columns, array_fill(0, count($columns), NULL)); + + // Replace the current object with an empty one + $this->load_values($values); + + return $this; + } + + /** + * Reloads the current object from the database. + * + * @chainable + * @return ORM + */ + public function reload() + { + return $this->find($this->object[$this->primary_key]); + } + + /** + * Reload column definitions. + * + * @chainable + * @param boolean force reloading + * @return ORM + */ + public function reload_columns($force = FALSE) + { + if ($force === TRUE OR empty($this->table_columns)) + { + if (isset(ORM::$column_cache[$this->object_name])) + { + // Use cached column information + $this->table_columns = ORM::$column_cache[$this->object_name]; + } + else + { + // Load table columns + ORM::$column_cache[$this->object_name] = $this->table_columns = $this->list_fields(); + } + } + + return $this; + } + + /** + * Tests if this object has a relationship to a different model. + * + * @param object related ORM model + * @param boolean check for any relations to given model + * @return boolean + */ + public function has(ORM $model, $any = FALSE) + { + // Determine plural or singular relation name + $related = ($model->table_names_plural === TRUE) ? $model->object_plural : $model->object_name; + + if (($join_table = array_search($related, $this->has_and_belongs_to_many)) === FALSE) + return FALSE; + + if (is_int($join_table)) + { + // No "through" table, load the default JOIN table + $join_table = $model->join_table($this->table_name); + } + + if ( ! isset($this->object_relations[$related])) + { + // Load the object relationships + $this->changed_relations[$related] = $this->object_relations[$related] = $this->load_relations($join_table, $model); + } + + if ( ! $model->empty_primary_key()) + { + // Check if a specific object exists + return in_array($model->primary_key_value, $this->changed_relations[$related]); + } + elseif ($any) + { + // Check if any relations to given model exist + return ! empty($this->changed_relations[$related]); + } + else + { + return FALSE; + } + } + + /** + * Adds a new relationship to between this model and another. + * + * @param object related ORM model + * @return boolean + */ + public function add(ORM $model) + { + if ($this->has($model)) + return TRUE; + + // Get the faked column name + $column = $model->object_plural; + + // Add the new relation to the update + $this->changed_relations[$column][] = $model->primary_key_value; + + if (isset($this->related[$column])) + { + // Force a reload of the relationships + unset($this->related[$column]); + } + + return TRUE; + } + + /** + * Adds a new relationship to between this model and another. + * + * @param object related ORM model + * @return boolean + */ + public function remove(ORM $model) + { + if ( ! $this->has($model)) + return FALSE; + + // Get the faked column name + $column = $model->object_plural; + + if (($key = array_search($model->primary_key_value, $this->changed_relations[$column])) === FALSE) + return FALSE; + + // Remove the relationship + unset($this->changed_relations[$column][$key]); + + if (isset($this->related[$column])) + { + // Force a reload of the relationships + unset($this->related[$column]); + } + + return TRUE; + } + + /** + * Count the number of records in the table. + * + * @return integer + */ + public function count_all() + { + // Return the total number of records in a table + return $this->db->count_records($this->table_name); + } + + /** + * Proxy method to Database list_fields. + * + * @param string table name or NULL to use this table + * @return array + */ + public function list_fields($table = NULL) + { + if ($table === NULL) + { + $table = $this->table_name; + } + + // Proxy to database + return $this->db->list_fields($table); + } + + /** + * Proxy method to Database field_data. + * + * @param string table name + * @return array + */ + public function field_data($table) + { + // Proxy to database + return $this->db->field_data($table); + } + + /** + * Proxy method to Database field_data. + * + * @chainable + * @param string SQL query to clear + * @return ORM + */ + public function clear_cache($sql = NULL) + { + // Proxy to database + $this->db->clear_cache($sql); + + ORM::$column_cache = array(); + + return $this; + } + + /** + * Returns the unique key for a specific value. This method is expected + * to be overloaded in models if the model has other unique columns. + * + * @param mixed unique value + * @return string + */ + public function unique_key($id) + { + return $this->primary_key; + } + + /** + * Determines the name of a foreign key for a specific table. + * + * @param string related table name + * @param string prefix table name (used for JOINs) + * @return string + */ + public function foreign_key($table = NULL, $prefix_table = NULL) + { + if ($table === TRUE) + { + if (is_string($prefix_table)) + { + // Use prefix table name and this table's PK + return $prefix_table.'.'.$this->primary_key; + } + else + { + // Return the name of this table's PK + return $this->table_name.'.'.$this->primary_key; + } + } + + if (is_string($prefix_table)) + { + // Add a period for prefix_table.column support + $prefix_table .= '.'; + } + + if (isset($this->foreign_key[$table])) + { + // Use the defined foreign key name, no magic here! + $foreign_key = $this->foreign_key[$table]; + } + else + { + if ( ! is_string($table) OR ! array_key_exists($table.'_'.$this->primary_key, $this->object)) + { + // Use this table + $table = $this->table_name; + + if (strpos($table, '.') !== FALSE) + { + // Hack around support for PostgreSQL schemas + list ($schema, $table) = explode('.', $table, 2); + } + + if ($this->table_names_plural === TRUE) + { + // Make the key name singular + $table = inflector::singular($table); + } + } + + $foreign_key = $table.'_'.$this->primary_key; + } + + return $prefix_table.$foreign_key; + } + + /** + * This uses alphabetical comparison to choose the name of the table. + * + * Example: The joining table of users and roles would be roles_users, + * because "r" comes before "u". Joining products and categories would + * result in categories_products, because "c" comes before "p". + * + * Example: zoo > zebra > robber > ocean > angel > aardvark + * + * @param string table name + * @return string + */ + public function join_table($table) + { + if ($this->table_name > $table) + { + $table = $table.'_'.$this->table_name; + } + else + { + $table = $this->table_name.'_'.$table; + } + + return $table; + } + + /** + * Returns an ORM model for the given object name; + * + * @param string object name + * @return ORM + */ + protected function related_object($object) + { + if (isset($this->has_one[$object])) + { + $object = ORM::factory($this->has_one[$object]); + } + elseif (isset($this->belongs_to[$object])) + { + $object = ORM::factory($this->belongs_to[$object]); + } + elseif (in_array($object, $this->has_one) OR in_array($object, $this->belongs_to)) + { + $object = ORM::factory($object); + } + else + { + return FALSE; + } + + return $object; + } + + /** + * Loads an array of values into into the current object. + * + * @chainable + * @param array values to load + * @return ORM + */ + public function load_values(array $values) + { + if (array_key_exists($this->primary_key, $values)) + { + // Replace the object and reset the object status + $this->object = $this->changed = $this->related = array(); + + // Set the loaded and saved object status based on the primary key + $this->loaded = $this->saved = ($values[$this->primary_key] !== NULL); + } + + // Related objects + $related = array(); + + foreach ($values as $column => $value) + { + if (strpos($column, ':') === FALSE) + { + if (isset($this->table_columns[$column])) + { + // The type of the value can be determined, convert the value + $value = $this->load_type($column, $value); + } + + $this->object[$column] = $value; + } + else + { + list ($prefix, $column) = explode(':', $column, 2); + + $related[$prefix][$column] = $value; + } + } + + if ( ! empty($related)) + { + foreach ($related as $object => $values) + { + // Load the related objects with the values in the result + $this->related[$object] = $this->related_object($object)->load_values($values); + } + } + + return $this; + } + + /** + * Loads a value according to the types defined by the column metadata. + * + * @param string column name + * @param mixed value to load + * @return mixed + */ + protected function load_type($column, $value) + { + $type = gettype($value); + if ($type == 'object' OR $type == 'array' OR ! isset($this->table_columns[$column])) + return $value; + + // Load column data + $column = $this->table_columns[$column]; + + if ($value === NULL AND ! empty($column['null'])) + return $value; + + if ( ! empty($column['binary']) AND ! empty($column['exact']) AND (int) $column['length'] === 1) + { + // Use boolean for BINARY(1) fields + $column['type'] = 'boolean'; + } + + switch ($column['type']) + { + case 'int': + if ($value === '' AND ! empty($column['null'])) + { + // Forms will only submit strings, so empty integer values must be null + $value = NULL; + } + elseif ((float) $value > PHP_INT_MAX) + { + // This number cannot be represented by a PHP integer, so we convert it to a string + $value = (string) $value; + } + else + { + $value = (int) $value; + } + break; + case 'float': + $value = (float) $value; + break; + case 'boolean': + $value = (bool) $value; + break; + case 'string': + $value = (string) $value; + break; + } + + return $value; + } + + /** + * Loads a database result, either as a new object for this model, or as + * an iterator for multiple rows. + * + * @chainable + * @param boolean return an iterator or load a single row + * @return ORM for single rows + * @return ORM_Iterator for multiple rows + */ + protected function load_result($array = FALSE) + { + if ($array === FALSE) + { + // Only fetch 1 record + $this->db->limit(1); + } + + if ( ! isset($this->db_applied['select'])) + { + // Select all columns by default + $this->db->select($this->table_name.'.*'); + } + + if ( ! empty($this->load_with)) + { + foreach ($this->load_with as $alias => $object) + { + // Join each object into the results + if (is_string($alias)) + { + // Use alias + $this->with($alias); + } + else + { + // Use object + $this->with($object); + } + } + } + + if ( ! isset($this->db_applied['orderby']) AND ! empty($this->sorting)) + { + $sorting = array(); + foreach ($this->sorting as $column => $direction) + { + if (strpos($column, '.') === FALSE) + { + // Keeps sorting working properly when using JOINs on + // tables with columns of the same name + $column = $this->table_name.'.'.$column; + } + + $sorting[$column] = $direction; + } + + // Apply the user-defined sorting + $this->db->orderby($sorting); + } + + // Load the result + $result = $this->db->get($this->table_name); + + if ($array === TRUE) + { + // Return an iterated result + return new ORM_Iterator($this, $result); + } + + if ($result->count() === 1) + { + // Load object values + $this->load_values($result->result(FALSE)->current()); + } + else + { + // Clear the object, nothing was found + $this->clear(); + } + + return $this; + } + + /** + * Return an array of all the primary keys of the related table. + * + * @param string table name + * @param object ORM model to find relations of + * @return array + */ + protected function load_relations($table, ORM $model) + { + // Save the current query chain (otherwise the next call will clash) + $this->db->push(); + + $query = $this->db + ->select($model->foreign_key(NULL).' AS id') + ->from($table) + ->where($this->foreign_key(NULL, $table), $this->object[$this->primary_key]) + ->get() + ->result(TRUE); + + $this->db->pop(); + + $relations = array(); + foreach ($query as $row) + { + $relations[] = $row->id; + } + + return $relations; + } + + /** + * Returns whether or not primary key is empty + * + * @return bool + */ + protected function empty_primary_key() + { + return (empty($this->object[$this->primary_key]) AND $this->object[$this->primary_key] !== '0'); + } + +} // End ORM diff --git a/lib/kohana/system/libraries/ORM_Iterator.php b/lib/kohana/system/libraries/ORM_Iterator.php new file mode 100644 index 0000000..41aa806 --- /dev/null +++ b/lib/kohana/system/libraries/ORM_Iterator.php @@ -0,0 +1,228 @@ +class_name = get_class($model); + $this->primary_key = $model->primary_key; + $this->primary_val = $model->primary_val; + + // Database result + $this->result = $result->result(TRUE); + } + + /** + * Returns an array of the results as ORM objects. + * + * @return array + */ + public function as_array() + { + $array = array(); + + if ($results = $this->result->result_array()) + { + // Import class name + $class = $this->class_name; + + foreach ($results as $obj) + { + $array[] = new $class($obj); + } + } + + return $array; + } + + /** + * Return an array of all of the primary keys for this object. + * + * @return array + */ + public function primary_key_array() + { + $ids = array(); + foreach ($this->result as $row) + { + $ids[] = $row->{$this->primary_key}; + } + return $ids; + } + + /** + * Create a key/value array from the results. + * + * @param string key column + * @param string value column + * @return array + */ + public function select_list($key = NULL, $val = NULL) + { + if ($key === NULL) + { + // Use the default key + $key = $this->primary_key; + } + + if ($val === NULL) + { + // Use the default value + $val = $this->primary_val; + } + + $array = array(); + foreach ($this->result->result_array() as $row) + { + $array[$row->$key] = $row->$val; + } + return $array; + } + + /** + * Return a range of offsets. + * + * @param integer start + * @param integer end + * @return array + */ + public function range($start, $end) + { + // Array of objects + $array = array(); + + if ($this->result->offsetExists($start)) + { + // Import the class name + $class = $this->class_name; + + // Set the end offset + $end = $this->result->offsetExists($end) ? $end : $this->count(); + + for ($i = $start; $i < $end; $i++) + { + // Insert each object in the range + $array[] = new $class($this->result->offsetGet($i)); + } + } + + return $array; + } + + /** + * Countable: count + */ + public function count() + { + return $this->result->count(); + } + + /** + * Iterator: current + */ + public function current() + { + if ($row = $this->result->current()) + { + // Import class name + $class = $this->class_name; + + $row = new $class($row); + } + + return $row; + } + + /** + * Iterator: key + */ + public function key() + { + return $this->result->key(); + } + + /** + * Iterator: next + */ + public function next() + { + return $this->result->next(); + } + + /** + * Iterator: rewind + */ + public function rewind() + { + $this->result->rewind(); + } + + /** + * Iterator: valid + */ + public function valid() + { + return $this->result->valid(); + } + + /** + * ArrayAccess: offsetExists + */ + public function offsetExists($offset) + { + return $this->result->offsetExists($offset); + } + + /** + * ArrayAccess: offsetGet + */ + public function offsetGet($offset) + { + if ($this->result->offsetExists($offset)) + { + // Import class name + $class = $this->class_name; + + return new $class($this->result->offsetGet($offset)); + } + } + + /** + * ArrayAccess: offsetSet + * + * @throws Kohana_Database_Exception + */ + public function offsetSet($offset, $value) + { + throw new Kohana_Database_Exception('database.result_read_only'); + } + + /** + * ArrayAccess: offsetUnset + * + * @throws Kohana_Database_Exception + */ + public function offsetUnset($offset) + { + throw new Kohana_Database_Exception('database.result_read_only'); + } + +} // End ORM Iterator \ No newline at end of file diff --git a/lib/kohana/system/libraries/ORM_Tree.php b/lib/kohana/system/libraries/ORM_Tree.php new file mode 100644 index 0000000..cdb09fd --- /dev/null +++ b/lib/kohana/system/libraries/ORM_Tree.php @@ -0,0 +1,76 @@ +related[$column])) + { + // Load child model + $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); + + if (array_key_exists($this->ORM_Tree_parent_key, $this->object)) + { + // Find children of this parent + $model->where($model->primary_key, $this->object[$this->ORM_Tree_parent_key])->find(); + } + + $this->related[$column] = $model; + } + + return $this->related[$column]; + } + elseif ($column === 'children') + { + if (empty($this->related[$column])) + { + $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); + + if ($this->ORM_Tree_children === $this->table_name) + { + // Load children within this table + $this->related[$column] = $model + ->where($this->ORM_Tree_parent_key, $this->object[$this->primary_key]) + ->find_all(); + } + else + { + // Find first selection of children + $this->related[$column] = $model + ->where($this->foreign_key(), $this->object[$this->primary_key]) + ->where($this->ORM_Tree_parent_key, NULL) + ->find_all(); + } + } + + return $this->related[$column]; + } + + return parent::__get($column); + } + +} // End ORM Tree \ No newline at end of file diff --git a/lib/kohana/system/libraries/ORM_Versioned.php b/lib/kohana/system/libraries/ORM_Versioned.php new file mode 100644 index 0000000..7c3ee5d --- /dev/null +++ b/lib/kohana/system/libraries/ORM_Versioned.php @@ -0,0 +1,143 @@ +last_version = 1 + ($this->last_version === NULL ? $this->object['version'] : $this->last_version); + $this->__set('version', $this->last_version); + + parent::save(); + + if ($this->saved) + { + $data = array(); + foreach ($this->object as $key => $value) + { + if ($key === 'id') + continue; + + $data[$key] = $value; + } + $data[$this->foreign_key()] = $this->id; + + $this->db->insert($this->table_name.'_versions', $data); + } + + return $this; + } + + /** + * Loads previous version from current object + * + * @chainable + * @return ORM + */ + public function previous() + { + if ( ! $this->loaded) + return $this; + + $this->last_version = ($this->last_version === NULL) ? $this->object['version'] : $this->last_version; + $version = $this->last_version - 1; + + $query = $this->db + ->where($this->foreign_key(), $this->object[$this->primary_key]) + ->where('version', $version) + ->limit(1) + ->get($this->table_name.'_versions'); + + if ($query->count()) + { + $this->load_values($query->result(FALSE)->current()); + } + + return $this; + } + + /** + * Restores the object with data from stored version + * + * @param integer version number you want to restore + * @return ORM + */ + public function restore($version) + { + if ( ! $this->loaded) + return $this; + + $query = $this->db + ->where($this->foreign_key(), $this->object[$this->primary_key]) + ->where('version', $version) + ->limit(1) + ->get($this->table_name.'_versions'); + + if ($query->count()) + { + $row = $query->result(FALSE)->current(); + + foreach ($row as $key => $value) + { + if ($key === $this->primary_key OR $key === $this->foreign_key()) + { + // Do not overwrite the primary key + continue; + } + + if ($key === 'version') + { + // Always use the current version + $value = $this->version; + } + + $this->__set($key, $value); + } + + $this->save(); + } + + return $this; + } + + /** + * Overloads ORM::delete() to delete all versioned entries of current object + * and the object itself + * + * @param integer id of the object you want to delete + * @return ORM + */ + public function delete($id = NULL) + { + if ($id === NULL) + { + // Use the current object id + $id = $this->object[$this->primary_key]; + } + + if ($status = parent::delete($id)) + { + $this->db->where($this->foreign_key(), $id)->delete($this->table_name.'_versions'); + } + + return $status; + } + +} \ No newline at end of file diff --git a/lib/kohana/system/libraries/Pagination.php b/lib/kohana/system/libraries/Pagination.php new file mode 100644 index 0000000..a8f7bb1 --- /dev/null +++ b/lib/kohana/system/libraries/Pagination.php @@ -0,0 +1,236 @@ +initialize($config); + + Kohana::log('debug', 'Pagination Library initialized'); + } + + /** + * Sets config values. + * + * @throws Kohana_Exception + * @param array configuration settings + * @return void + */ + public function initialize($config = array()) + { + // Load config group + if (isset($config['group'])) + { + // Load and validate config group + if ( ! is_array($group_config = Kohana::config('pagination.'.$config['group']))) + throw new Kohana_Exception('pagination.undefined_group', $config['group']); + + // All pagination config groups inherit default config group + if ($config['group'] !== 'default') + { + // Load and validate default config group + if ( ! is_array($default_config = Kohana::config('pagination.default'))) + throw new Kohana_Exception('pagination.undefined_group', 'default'); + + // Merge config group with default config group + $group_config += $default_config; + } + + // Merge custom config items with config group + $config += $group_config; + } + + // Assign config values to the object + foreach ($config as $key => $value) + { + if (property_exists($this, $key)) + { + $this->$key = $value; + } + } + + // Clean view directory + $this->directory = trim($this->directory, '/').'/'; + + // Build generic URL with page in query string + if ($this->query_string !== '') + { + // Extract current page + $this->current_page = isset($_GET[$this->query_string]) ? (int) $_GET[$this->query_string] : 1; + + // Insert {page} placeholder + $_GET[$this->query_string] = '{page}'; + + // Create full URL + $base_url = ($this->base_url === '') ? Router::$current_uri : $this->base_url; + $this->url = url::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET)); + + // Reset page number + $_GET[$this->query_string] = $this->current_page; + } + + // Build generic URL with page as URI segment + else + { + // Use current URI if no base_url set + $this->url = ($this->base_url === '') ? Router::$segments : explode('/', trim($this->base_url, '/')); + + // Convert uri 'label' to corresponding integer if needed + if (is_string($this->uri_segment)) + { + if (($key = array_search($this->uri_segment, $this->url)) === FALSE) + { + // If uri 'label' is not found, auto add it to base_url + $this->url[] = $this->uri_segment; + $this->uri_segment = count($this->url) + 1; + } + else + { + $this->uri_segment = $key + 2; + } + } + + // Insert {page} placeholder + $this->url[$this->uri_segment - 1] = '{page}'; + + // Create full URL + $this->url = url::site(implode('/', $this->url)).Router::$query_string; + + // Extract current page + $this->current_page = URI::instance()->segment($this->uri_segment); + } + + // Core pagination values + $this->total_items = (int) max(0, $this->total_items); + $this->items_per_page = (int) max(1, $this->items_per_page); + $this->total_pages = (int) ceil($this->total_items / $this->items_per_page); + $this->current_page = (int) min(max(1, $this->current_page), max(1, $this->total_pages)); + $this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items); + $this->current_last_item = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items); + + // If there is no first/last/previous/next page, relative to the + // current page, value is set to FALSE. Valid page number otherwise. + $this->first_page = ($this->current_page === 1) ? FALSE : 1; + $this->last_page = ($this->current_page >= $this->total_pages) ? FALSE : $this->total_pages; + $this->previous_page = ($this->current_page > 1) ? $this->current_page - 1 : FALSE; + $this->next_page = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : FALSE; + + // SQL values + $this->sql_offset = (int) ($this->current_page - 1) * $this->items_per_page; + $this->sql_limit = sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page, $this->sql_offset); + } + + /** + * Generates the HTML for the chosen pagination style. + * + * @param string pagination style + * @return string pagination html + */ + public function render($style = NULL) + { + // Hide single page pagination + if ($this->auto_hide === TRUE AND $this->total_pages <= 1) + return ''; + + if ($style === NULL) + { + // Use default style + $style = $this->style; + } + + // Return rendered pagination view + return View::factory($this->directory.$style, get_object_vars($this))->render(); + } + + /** + * Magically converts Pagination object to string. + * + * @return string pagination html + */ + public function __toString() + { + return $this->render(); + } + + /** + * Magically gets a pagination variable. + * + * @param string variable key + * @return mixed variable value if the key is found + * @return void if the key is not found + */ + public function __get($key) + { + if (isset($this->$key)) + return $this->$key; + } + + /** + * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages(). + * Note that $pagination->total_pages is the recommended way to access properties. + * + * @param string function name + * @return string + */ + public function __call($func, $args = NULL) + { + return $this->__get($func); + } + +} // End Pagination Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/Profiler.php b/lib/kohana/system/libraries/Profiler.php new file mode 100644 index 0000000..9da053f --- /dev/null +++ b/lib/kohana/system/libraries/Profiler.php @@ -0,0 +1,271 @@ +show OR (is_array($this->show) AND ! in_array($args[0], $this->show))) + return FALSE; + + // Class name + $class = 'Profiler_'.ucfirst($method); + + $class = new $class(); + + $this->profiles[$args[0]] = $class; + + return $class; + } + + /** + * Disables the profiler for this page only. + * Best used when profiler is autoloaded. + * + * @return void + */ + public function disable() + { + // Removes itself from the event queue + Event::clear('system.display', array($this, 'render')); + } + + /** + * Render the profiler. Output is added to the bottom of the page by default. + * + * @param boolean return the output if TRUE + * @return void|string + */ + public function render($return = FALSE) + { + $start = microtime(TRUE); + + $get = isset($_GET['profiler']) ? explode(',', $_GET['profiler']) : array(); + $this->show = empty($get) ? Kohana::config('profiler.show') : $get; + + Event::run('profiler.run', $this); + + $styles = ''; + foreach ($this->profiles as $profile) + { + $styles .= $profile->styles(); + } + + // Don't display if there's no profiles + if (empty($this->profiles)) + return; + + // Load the profiler view + $data = array + ( + 'profiles' => $this->profiles, + 'styles' => $styles, + 'execution_time' => microtime(TRUE) - $start + ); + $view = new View('kohana_profiler', $data); + + // Return rendered view if $return is TRUE + if ($return === TRUE) + return $view->render(); + + // Add profiler data to the output + if (stripos(Kohana::$output, '') !== FALSE) + { + // Closing body tag was found, insert the profiler data before it + Kohana::$output = str_ireplace('', $view->render().'', Kohana::$output); + } + else + { + // Append the profiler data to the output + Kohana::$output .= $view->render(); + } + } + + /** + * Benchmark times and memory usage from the Benchmark library. + * + * @return void + */ + public function benchmarks() + { + if ( ! $table = $this->table('benchmarks')) + return; + + $table->add_column(); + $table->add_column('kp-column kp-data'); + $table->add_column('kp-column kp-data'); + $table->add_column('kp-column kp-data'); + $table->add_row(array('Benchmarks', 'Time', 'Count', 'Memory'), 'kp-title', 'background-color: #FFE0E0'); + + $benchmarks = Benchmark::get(TRUE); + + // Moves the first benchmark (total execution time) to the end of the array + $benchmarks = array_slice($benchmarks, 1) + array_slice($benchmarks, 0, 1); + + text::alternate(); + foreach ($benchmarks as $name => $benchmark) + { + // Clean unique id from system benchmark names + $name = ucwords(str_replace(array('_', '-'), ' ', str_replace(SYSTEM_BENCHMARK.'_', '', $name))); + + $data = array($name, number_format($benchmark['time'], 3), $benchmark['count'], number_format($benchmark['memory'] / 1024 / 1024, 2).'MB'); + $class = text::alternate('', 'kp-altrow'); + + if ($name == 'Total Execution') + $class = 'kp-totalrow'; + + $table->add_row($data, $class); + } + } + + /** + * Database query benchmarks. + * + * @return void + */ + public function database() + { + if ( ! $table = $this->table('database')) + return; + + $table->add_column(); + $table->add_column('kp-column kp-data'); + $table->add_column('kp-column kp-data'); + $table->add_row(array('Queries', 'Time', 'Rows'), 'kp-title', 'background-color: #E0FFE0'); + + $queries = Database::$benchmarks; + + text::alternate(); + $total_time = $total_rows = 0; + foreach ($queries as $query) + { + $data = array($query['query'], number_format($query['time'], 3), $query['rows']); + $class = text::alternate('', 'kp-altrow'); + $table->add_row($data, $class); + $total_time += $query['time']; + $total_rows += $query['rows']; + } + + $data = array('Total: ' . count($queries), number_format($total_time, 3), $total_rows); + $table->add_row($data, 'kp-totalrow'); + } + + /** + * Session data. + * + * @return void + */ + public function session() + { + if (empty($_SESSION)) return; + + if ( ! $table = $this->table('session')) + return; + + $table->add_column('kp-name'); + $table->add_column(); + $table->add_row(array('Session', 'Value'), 'kp-title', 'background-color: #CCE8FB'); + + text::alternate(); + foreach($_SESSION as $name => $value) + { + if (is_object($value)) + { + $value = get_class($value).' [object]'; + } + + $data = array($name, $value); + $class = text::alternate('', 'kp-altrow'); + $table->add_row($data, $class); + } + } + + /** + * POST data. + * + * @return void + */ + public function post() + { + if (empty($_POST)) return; + + if ( ! $table = $this->table('post')) + return; + + $table->add_column('kp-name'); + $table->add_column(); + $table->add_row(array('POST', 'Value'), 'kp-title', 'background-color: #E0E0FF'); + + text::alternate(); + foreach($_POST as $name => $value) + { + $data = array($name, $value); + $class = text::alternate('', 'kp-altrow'); + $table->add_row($data, $class); + } + } + + /** + * Cookie data. + * + * @return void + */ + public function cookies() + { + if (empty($_COOKIE)) return; + + if ( ! $table = $this->table('cookies')) + return; + + $table->add_column('kp-name'); + $table->add_column(); + $table->add_row(array('Cookies', 'Value'), 'kp-title', 'background-color: #FFF4D7'); + + text::alternate(); + foreach($_COOKIE as $name => $value) + { + $data = array($name, $value); + $class = text::alternate('', 'kp-altrow'); + $table->add_row($data, $class); + } + } +} \ No newline at end of file diff --git a/lib/kohana/system/libraries/Profiler_Table.php b/lib/kohana/system/libraries/Profiler_Table.php new file mode 100644 index 0000000..a0058a5 --- /dev/null +++ b/lib/kohana/system/libraries/Profiler_Table.php @@ -0,0 +1,69 @@ +columns[] = array('class' => $class, 'style' => $style); + } + + /** + * Add row to table. + * + * @param array data to go in table cells + * @param string CSS class + * @param string CSS style + */ + public function add_row($data, $class = '', $style = '') + { + $this->rows[] = array('data' => $data, 'class' => $class, 'style' => $style); + } + + /** + * Render table. + * + * @return string + */ + public function render() + { + $data['rows'] = $this->rows; + $data['columns'] = $this->columns; + return View::factory('kohana_profiler_table', $data)->render(); + } +} \ No newline at end of file diff --git a/lib/kohana/system/libraries/Router.php b/lib/kohana/system/libraries/Router.php new file mode 100644 index 0000000..ef0e1e4 --- /dev/null +++ b/lib/kohana/system/libraries/Router.php @@ -0,0 +1,304 @@ + 1) + { + // Custom routing + Router::$rsegments = Router::routed_uri(Router::$current_uri); + } + + // The routed URI is now complete + Router::$routed_uri = Router::$rsegments; + + // Routed segments will never be empty + Router::$rsegments = explode('/', Router::$rsegments); + + // Prepare to find the controller + $controller_path = ''; + $method_segment = NULL; + + // Paths to search + $paths = Kohana::include_paths(); + + foreach (Router::$rsegments as $key => $segment) + { + // Add the segment to the search path + $controller_path .= $segment; + + $found = FALSE; + foreach ($paths as $dir) + { + // Search within controllers only + $dir .= 'controllers/'; + + if (is_dir($dir.$controller_path) OR is_file($dir.$controller_path.EXT)) + { + // Valid path + $found = TRUE; + + // The controller must be a file that exists with the search path + if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT)) + AND is_file($c) AND strpos($c, $dir) === 0) + { + // Set controller name + Router::$controller = $segment; + + // Change controller path + Router::$controller_path = $c; + + // Set the method segment + $method_segment = $key + 1; + + // Stop searching + break; + } + } + } + + if ($found === FALSE) + { + // Maximum depth has been reached, stop searching + break; + } + + // Add another slash + $controller_path .= '/'; + } + + if ($method_segment !== NULL AND isset(Router::$rsegments[$method_segment])) + { + // Set method + Router::$method = Router::$rsegments[$method_segment]; + + if (isset(Router::$rsegments[$method_segment + 1])) + { + // Set arguments + Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1); + } + } + + // Last chance to set routing before a 404 is triggered + Event::run('system.post_routing'); + + if (Router::$controller === NULL) + { + // No controller was found, so no page can be rendered + Event::run('system.404'); + } + } + + /** + * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF. + * + * @return void + */ + public static function find_uri() + { + if (PHP_SAPI === 'cli') + { + // Command line requires a bit of hacking + if (isset($_SERVER['argv'][1])) + { + Router::$current_uri = $_SERVER['argv'][1]; + + // Remove GET string from segments + if (($query = strpos(Router::$current_uri, '?')) !== FALSE) + { + list (Router::$current_uri, $query) = explode('?', Router::$current_uri, 2); + + // Parse the query string into $_GET + parse_str($query, $_GET); + + // Convert $_GET to UTF-8 + $_GET = utf8::clean($_GET); + } + } + } + elseif (isset($_GET['kohana_uri'])) + { + // Use the URI defined in the query string + Router::$current_uri = $_GET['kohana_uri']; + + // Remove the URI from $_GET + unset($_GET['kohana_uri']); + + // Remove the URI from $_SERVER['QUERY_STRING'] + $_SERVER['QUERY_STRING'] = preg_replace('~\bkohana_uri\b[^&]*+&?~', '', $_SERVER['QUERY_STRING']); + } + elseif (isset($_SERVER['PATH_INFO']) AND $_SERVER['PATH_INFO']) + { + Router::$current_uri = $_SERVER['PATH_INFO']; + } + elseif (isset($_SERVER['ORIG_PATH_INFO']) AND $_SERVER['ORIG_PATH_INFO']) + { + Router::$current_uri = $_SERVER['ORIG_PATH_INFO']; + } + elseif (isset($_SERVER['PHP_SELF']) AND $_SERVER['PHP_SELF']) + { + Router::$current_uri = $_SERVER['PHP_SELF']; + } + + if (($strpos_fc = strpos(Router::$current_uri, KOHANA)) !== FALSE) + { + // Remove the front controller from the current uri + Router::$current_uri = (string) substr(Router::$current_uri, $strpos_fc + strlen(KOHANA)); + } + + // Remove slashes from the start and end of the URI + Router::$current_uri = trim(Router::$current_uri, '/'); + + if (Router::$current_uri !== '') + { + if ($suffix = Kohana::config('core.url_suffix') AND strpos(Router::$current_uri, $suffix) !== FALSE) + { + // Remove the URL suffix + Router::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', Router::$current_uri); + + // Set the URL suffix + Router::$url_suffix = $suffix; + } + + // Reduce multiple slashes into single slashes + Router::$current_uri = preg_replace('#//+#', '/', Router::$current_uri); + } + } + + /** + * Generates routed URI from given URI. + * + * @param string URI to convert + * @return string Routed uri + */ + public static function routed_uri($uri) + { + if (Router::$routes === NULL) + { + // Load routes + Router::$routes = Kohana::config('routes'); + } + + // Prepare variables + $routed_uri = $uri = trim($uri, '/'); + + if (isset(Router::$routes[$uri])) + { + // Literal match, no need for regex + $routed_uri = Router::$routes[$uri]; + } + else + { + // Loop through the routes and see if anything matches + foreach (Router::$routes as $key => $val) + { + if ($key === '_default') continue; + + // Trim slashes + $key = trim($key, '/'); + $val = trim($val, '/'); + + if (preg_match('#^'.$key.'$#u', $uri)) + { + if (strpos($val, '$') !== FALSE) + { + // Use regex routing + $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri); + } + else + { + // Standard routing + $routed_uri = $val; + } + + // A valid route has been found + break; + } + } + } + + if (isset(Router::$routes[$routed_uri])) + { + // Check for double routing (without regex) + $routed_uri = Router::$routes[$routed_uri]; + } + + return trim($routed_uri, '/'); + } + +} // End Router \ No newline at end of file diff --git a/lib/kohana/system/libraries/Session.php b/lib/kohana/system/libraries/Session.php new file mode 100644 index 0000000..7ae79cf --- /dev/null +++ b/lib/kohana/system/libraries/Session.php @@ -0,0 +1,457 @@ +input = Input::instance(); + + // This part only needs to be run once + if (Session::$instance === NULL) + { + // Load config + Session::$config = Kohana::config('session'); + + // Makes a mirrored array, eg: foo=foo + Session::$protect = array_combine(Session::$protect, Session::$protect); + + // Configure garbage collection + ini_set('session.gc_probability', (int) Session::$config['gc_probability']); + ini_set('session.gc_divisor', 100); + ini_set('session.gc_maxlifetime', (Session::$config['expiration'] == 0) ? 86400 : Session::$config['expiration']); + + // Create a new session + $this->create(); + + if (Session::$config['regenerate'] > 0 AND ($_SESSION['total_hits'] % Session::$config['regenerate']) === 0) + { + // Regenerate session id and update session cookie + $this->regenerate(); + } + else + { + // Always update session cookie to keep the session alive + cookie::set(Session::$config['name'], $_SESSION['session_id'], Session::$config['expiration']); + } + + // Close the session just before sending the headers, so that + // the session cookie(s) can be written. + Event::add('system.send_headers', array($this, 'write_close')); + + // Make sure that sessions are closed before exiting + register_shutdown_function(array($this, 'write_close')); + + // Singleton instance + Session::$instance = $this; + } + + Kohana::log('debug', 'Session Library initialized'); + } + + /** + * Get the session id. + * + * @return string + */ + public function id() + { + return $_SESSION['session_id']; + } + + /** + * Create a new session. + * + * @param array variables to set after creation + * @return void + */ + public function create($vars = NULL) + { + // Destroy any current sessions + $this->destroy(); + + if (Session::$config['driver'] !== 'native') + { + // Set driver name + $driver = 'Session_'.ucfirst(Session::$config['driver']).'_Driver'; + + // Load the driver + if ( ! Kohana::auto_load($driver)) + throw new Kohana_Exception('core.driver_not_found', Session::$config['driver'], get_class($this)); + + // Initialize the driver + Session::$driver = new $driver(); + + // Validate the driver + if ( ! (Session::$driver instanceof Session_Driver)) + throw new Kohana_Exception('core.driver_implements', Session::$config['driver'], get_class($this), 'Session_Driver'); + + // Register non-native driver as the session handler + session_set_save_handler + ( + array(Session::$driver, 'open'), + array(Session::$driver, 'close'), + array(Session::$driver, 'read'), + array(Session::$driver, 'write'), + array(Session::$driver, 'destroy'), + array(Session::$driver, 'gc') + ); + } + + // Validate the session name + if ( ! preg_match('~^(?=.*[a-z])[a-z0-9_]++$~iD', Session::$config['name'])) + throw new Kohana_Exception('session.invalid_session_name', Session::$config['name']); + + // Name the session, this will also be the name of the cookie + session_name(Session::$config['name']); + + // Set the session cookie parameters + session_set_cookie_params + ( + Session::$config['expiration'], + Kohana::config('cookie.path'), + Kohana::config('cookie.domain'), + Kohana::config('cookie.secure') + ); + + // Start the session! + session_start(); + + // Put session_id in the session variable + $_SESSION['session_id'] = session_id(); + + // Set defaults + if ( ! isset($_SESSION['_kf_flash_'])) + { + $_SESSION['total_hits'] = 0; + $_SESSION['_kf_flash_'] = array(); + + $_SESSION['user_agent'] = Kohana::$user_agent; + $_SESSION['ip_address'] = $this->input->ip_address(); + } + + // Set up flash variables + Session::$flash =& $_SESSION['_kf_flash_']; + + // Increase total hits + $_SESSION['total_hits'] += 1; + + // Validate data only on hits after one + if ($_SESSION['total_hits'] > 1) + { + // Validate the session + foreach (Session::$config['validate'] as $valid) + { + switch ($valid) + { + // Check user agent for consistency + case 'user_agent': + if ($_SESSION[$valid] !== Kohana::$user_agent) + return $this->create(); + break; + + // Check ip address for consistency + case 'ip_address': + if ($_SESSION[$valid] !== $this->input->$valid()) + return $this->create(); + break; + + // Check expiration time to prevent users from manually modifying it + case 'expiration': + if (time() - $_SESSION['last_activity'] > ini_get('session.gc_maxlifetime')) + return $this->create(); + break; + } + } + } + + // Expire flash keys + $this->expire_flash(); + + // Update last activity + $_SESSION['last_activity'] = time(); + + // Set the new data + Session::set($vars); + } + + /** + * Regenerates the global session id. + * + * @return void + */ + public function regenerate() + { + if (Session::$config['driver'] === 'native') + { + // Generate a new session id + // Note: also sets a new session cookie with the updated id + session_regenerate_id(TRUE); + + // Update session with new id + $_SESSION['session_id'] = session_id(); + } + else + { + // Pass the regenerating off to the driver in case it wants to do anything special + $_SESSION['session_id'] = Session::$driver->regenerate(); + } + + // Get the session name + $name = session_name(); + + if (isset($_COOKIE[$name])) + { + // Change the cookie value to match the new session id to prevent "lag" + $_COOKIE[$name] = $_SESSION['session_id']; + } + } + + /** + * Destroys the current session. + * + * @return void + */ + public function destroy() + { + if (session_id() !== '') + { + // Get the session name + $name = session_name(); + + // Destroy the session + session_destroy(); + + // Re-initialize the array + $_SESSION = array(); + + // Delete the session cookie + cookie::delete($name); + } + } + + /** + * Runs the system.session_write event, then calls session_write_close. + * + * @return void + */ + public function write_close() + { + static $run; + + if ($run === NULL) + { + $run = TRUE; + + // Run the events that depend on the session being open + Event::run('system.session_write'); + + // Expire flash keys + $this->expire_flash(); + + // Close the session + session_write_close(); + } + } + + /** + * Set a session variable. + * + * @param string|array key, or array of values + * @param mixed value (if keys is not an array) + * @return void + */ + public function set($keys, $val = FALSE) + { + if (empty($keys)) + return FALSE; + + if ( ! is_array($keys)) + { + $keys = array($keys => $val); + } + + foreach ($keys as $key => $val) + { + if (isset(Session::$protect[$key])) + continue; + + // Set the key + $_SESSION[$key] = $val; + } + } + + /** + * Set a flash variable. + * + * @param string|array key, or array of values + * @param mixed value (if keys is not an array) + * @return void + */ + public function set_flash($keys, $val = FALSE) + { + if (empty($keys)) + return FALSE; + + if ( ! is_array($keys)) + { + $keys = array($keys => $val); + } + + foreach ($keys as $key => $val) + { + if ($key == FALSE) + continue; + + Session::$flash[$key] = 'new'; + Session::set($key, $val); + } + } + + /** + * Freshen one, multiple or all flash variables. + * + * @param string variable key(s) + * @return void + */ + public function keep_flash($keys = NULL) + { + $keys = ($keys === NULL) ? array_keys(Session::$flash) : func_get_args(); + + foreach ($keys as $key) + { + if (isset(Session::$flash[$key])) + { + Session::$flash[$key] = 'new'; + } + } + } + + /** + * Expires old flash data and removes it from the session. + * + * @return void + */ + public function expire_flash() + { + static $run; + + // Method can only be run once + if ($run === TRUE) + return; + + if ( ! empty(Session::$flash)) + { + foreach (Session::$flash as $key => $state) + { + if ($state === 'old') + { + // Flash has expired + unset(Session::$flash[$key], $_SESSION[$key]); + } + else + { + // Flash will expire + Session::$flash[$key] = 'old'; + } + } + } + + // Method has been run + $run = TRUE; + } + + /** + * Get a variable. Access to sub-arrays is supported with key.subkey. + * + * @param string variable key + * @param mixed default value returned if variable does not exist + * @return mixed Variable data if key specified, otherwise array containing all session data. + */ + public function get($key = FALSE, $default = FALSE) + { + if (empty($key)) + return $_SESSION; + + $result = isset($_SESSION[$key]) ? $_SESSION[$key] : Kohana::key_string($_SESSION, $key); + + return ($result === NULL) ? $default : $result; + } + + /** + * Get a variable, and delete it. + * + * @param string variable key + * @param mixed default value returned if variable does not exist + * @return mixed + */ + public function get_once($key, $default = FALSE) + { + $return = Session::get($key, $default); + Session::delete($key); + + return $return; + } + + /** + * Delete one or more variables. + * + * @param string variable key(s) + * @return void + */ + public function delete($keys) + { + $args = func_get_args(); + + foreach ($args as $key) + { + if (isset(Session::$protect[$key])) + continue; + + // Unset the key + unset($_SESSION[$key]); + } + } + +} // End Session Class diff --git a/lib/kohana/system/libraries/Tagcloud.php b/lib/kohana/system/libraries/Tagcloud.php new file mode 100644 index 0000000..8fd7bfc --- /dev/null +++ b/lib/kohana/system/libraries/Tagcloud.php @@ -0,0 +1,130 @@ + 'tag'); + public $shuffle = FALSE; + + // Tag elements, biggest and smallest values + protected $elements; + protected $biggest; + protected $smallest; + + /** + * Construct a new tagcloud. The elements must be passed in as an array, + * with each entry in the array having a "title" ,"link", and "count" key. + * Font sizes will be applied via the "style" attribute as a percentage. + * + * @param array elements of the tagcloud + * @param integer minimum font size + * @param integer maximum font size + * @return void + */ + public function __construct(array $elements, $min_size = NULL, $max_size = NULL, $shuffle = FALSE) + { + $this->elements = $elements; + + if($shuffle !== FALSE) + { + $this->shuffle = TRUE; + } + + $counts = array(); + foreach ($elements as $data) + { + $counts[] = $data['count']; + } + + // Find the biggest and smallest values of the elements + $this->biggest = max($counts); + $this->smallest = min($counts); + + if ($min_size !== NULL) + { + $this->min_size = $min_size; + } + + if ($max_size !== NULL) + { + $this->max_size = $max_size; + } + } + + /** + * Magic __toString method. Returns all of the links as a single string. + * + * @return string + */ + public function __toString() + { + return implode("\n", $this->render()); + } + + /** + * Renders the elements of the tagcloud into an array of links. + * + * @return array + */ + public function render() + { + if ($this->shuffle === TRUE) + { + shuffle($this->elements); + } + + // Minimum values must be 1 to prevent divide by zero errors + $range = max($this->biggest - $this->smallest, 1); + $scale = max($this->max_size - $this->min_size, 1); + + // Import the attributes locally to prevent overwrites + $attr = $this->attributes; + + $output = array(); + foreach ($this->elements as $data) + { + if (strpos($data['title'], ' ') !== FALSE) + { + // Replace spaces with non-breaking spaces to prevent line wrapping + // in the middle of a link + $data['title'] = str_replace(' ', ' ', $data['title']); + } + + // Determine the size based on the min/max scale and the smallest/biggest range + $size = ((($data['count'] - $this->smallest) * $scale) / $range) + $this->min_size; + + $attr['style'] = 'font-size: '.round($size, 0).'%'; + + $output[] = html::anchor($data['link'], $data['title'], $attr)."\n"; + } + + return $output; + } + +} // End Tagcloud \ No newline at end of file diff --git a/lib/kohana/system/libraries/URI.php b/lib/kohana/system/libraries/URI.php new file mode 100644 index 0000000..d9ccdcf --- /dev/null +++ b/lib/kohana/system/libraries/URI.php @@ -0,0 +1,279 @@ +build_array(URI::$segments, $offset, $associative); + } + + /** + * Returns an array containing all the re-routed URI segments. + * + * @param integer rsegment offset + * @param boolean return an associative array + * @return array + */ + public function rsegment_array($offset = 0, $associative = FALSE) + { + return $this->build_array(URI::$rsegments, $offset, $associative); + } + + /** + * Returns an array containing all the URI arguments. + * + * @param integer segment offset + * @param boolean return an associative array + * @return array + */ + public function argument_array($offset = 0, $associative = FALSE) + { + return $this->build_array(URI::$arguments, $offset, $associative); + } + + /** + * Creates a simple or associative array from an array and an offset. + * Used as a helper for (r)segment_array and argument_array. + * + * @param array array to rebuild + * @param integer offset to start from + * @param boolean create an associative array + * @return array + */ + public function build_array($array, $offset = 0, $associative = FALSE) + { + // Prevent the keys from being improperly indexed + array_unshift($array, 0); + + // Slice the array, preserving the keys + $array = array_slice($array, $offset + 1, count($array) - 1, TRUE); + + if ($associative === FALSE) + return $array; + + $associative = array(); + $pairs = array_chunk($array, 2); + + foreach ($pairs as $pair) + { + // Add the key/value pair to the associative array + $associative[$pair[0]] = isset($pair[1]) ? $pair[1] : ''; + } + + return $associative; + } + + /** + * Returns the complete URI as a string. + * + * @return string + */ + public function string() + { + return URI::$current_uri; + } + + /** + * Magic method for converting an object to a string. + * + * @return string + */ + public function __toString() + { + return URI::$current_uri; + } + + /** + * Returns the total number of URI segments. + * + * @return integer + */ + public function total_segments() + { + return count(URI::$segments); + } + + /** + * Returns the total number of re-routed URI segments. + * + * @return integer + */ + public function total_rsegments() + { + return count(URI::$rsegments); + } + + /** + * Returns the total number of URI arguments. + * + * @return integer + */ + public function total_arguments() + { + return count(URI::$arguments); + } + + /** + * Returns the last URI segment. + * + * @param mixed default value returned if segment does not exist + * @return string + */ + public function last_segment($default = FALSE) + { + if (($end = $this->total_segments()) < 1) + return $default; + + return URI::$segments[$end - 1]; + } + + /** + * Returns the last re-routed URI segment. + * + * @param mixed default value returned if segment does not exist + * @return string + */ + public function last_rsegment($default = FALSE) + { + if (($end = $this->total_segments()) < 1) + return $default; + + return URI::$rsegments[$end - 1]; + } + + /** + * Returns the path to the current controller (not including the actual + * controller), as a web path. + * + * @param boolean return a full url, or only the path specifically + * @return string + */ + public function controller_path($full = TRUE) + { + return ($full) ? url::site(URI::$controller_path) : URI::$controller_path; + } + + /** + * Returns the current controller, as a web path. + * + * @param boolean return a full url, or only the controller specifically + * @return string + */ + public function controller($full = TRUE) + { + return ($full) ? url::site(URI::$controller_path.URI::$controller) : URI::$controller; + } + + /** + * Returns the current method, as a web path. + * + * @param boolean return a full url, or only the method specifically + * @return string + */ + public function method($full = TRUE) + { + return ($full) ? url::site(URI::$controller_path.URI::$controller.'/'.URI::$method) : URI::$method; + } + +} // End URI Class diff --git a/lib/kohana/system/libraries/Validation.php b/lib/kohana/system/libraries/Validation.php new file mode 100644 index 0000000..5a48bfc --- /dev/null +++ b/lib/kohana/system/libraries/Validation.php @@ -0,0 +1,826 @@ +submitted = ! empty($array); + + parent::__construct($array, ArrayObject::ARRAY_AS_PROPS | ArrayObject::STD_PROP_LIST); + } + + /** + * Magic clone method, clears errors and messages. + * + * @return void + */ + public function __clone() + { + $this->errors = array(); + $this->messages = array(); + } + + /** + * Create a copy of the current validation rules and change the array. + * + * @chainable + * @param array new array to validate + * @return Validation + */ + public function copy(array $array) + { + $copy = clone $this; + + $copy->exchangeArray($array); + + return $copy; + } + + /** + * Test if the data has been submitted. + * + * @return boolean + */ + public function submitted($value = NULL) + { + if (is_bool($value)) + { + $this->submitted = $value; + } + + return $this->submitted; + } + + /** + * Returns an array of all the field names that have filters, rules, or callbacks. + * + * @return array + */ + public function field_names() + { + // All the fields that are being validated + $fields = array_keys(array_merge + ( + $this->pre_filters, + $this->rules, + $this->callbacks, + $this->post_filters + )); + + // Remove wildcard fields + $fields = array_diff($fields, array('*')); + + return $fields; + } + + /** + * Returns the array values of the current object. + * + * @return array + */ + public function as_array() + { + return $this->getArrayCopy(); + } + + /** + * Returns the ArrayObject values, removing all inputs without rules. + * To choose specific inputs, list the field name as arguments. + * + * @param boolean return only fields with filters, rules, and callbacks + * @return array + */ + public function safe_array() + { + // Load choices + $choices = func_get_args(); + $choices = empty($choices) ? NULL : array_combine($choices, $choices); + + // Get field names + $fields = $this->field_names(); + + $safe = array(); + foreach ($fields as $field) + { + if ($choices === NULL OR isset($choices[$field])) + { + if (isset($this[$field])) + { + $value = $this[$field]; + + if (is_object($value)) + { + // Convert the value back into an array + $value = $value->getArrayCopy(); + } + } + else + { + // Even if the field is not in this array, it must be set + $value = NULL; + } + + // Add the field to the array + $safe[$field] = $value; + } + } + + return $safe; + } + + /** + * Add additional rules that will forced, even for empty fields. All arguments + * passed will be appended to the list. + * + * @chainable + * @param string rule name + * @return object + */ + public function allow_empty_rules($rules) + { + // Any number of args are supported + $rules = func_get_args(); + + // Merge the allowed rules + $this->empty_rules = array_merge($this->empty_rules, $rules); + + return $this; + } + + /** + * Converts a filter, rule, or callback into a fully-qualified callback array. + * + * @return mixed + */ + protected function callback($callback) + { + if (is_string($callback)) + { + if (strpos($callback, '::') !== FALSE) + { + $callback = explode('::', $callback); + } + elseif (function_exists($callback)) + { + // No need to check if the callback is a method + $callback = $callback; + } + elseif (method_exists($this, $callback)) + { + // The callback exists in Validation + $callback = array($this, $callback); + } + elseif (method_exists('valid', $callback)) + { + // The callback exists in valid:: + $callback = array('valid', $callback); + } + } + + if ( ! is_callable($callback, FALSE)) + { + if (is_array($callback)) + { + if (is_object($callback[0])) + { + // Object instance syntax + $name = get_class($callback[0]).'->'.$callback[1]; + } + else + { + // Static class syntax + $name = $callback[0].'::'.$callback[1]; + } + } + else + { + // Function syntax + $name = $callback; + } + + throw new Kohana_Exception('validation.not_callable', $name); + } + + return $callback; + } + + /** + * Add a pre-filter to one or more inputs. Pre-filters are applied before + * rules or callbacks are executed. + * + * @chainable + * @param callback filter + * @param string fields to apply filter to, use TRUE for all fields + * @return object + */ + public function pre_filter($filter, $field = TRUE) + { + if ($field === TRUE OR $field === '*') + { + // Use wildcard + $fields = array('*'); + } + else + { + // Add the filter to specific inputs + $fields = func_get_args(); + $fields = array_slice($fields, 1); + } + + // Convert to a proper callback + $filter = $this->callback($filter); + + foreach ($fields as $field) + { + // Add the filter to specified field + $this->pre_filters[$field][] = $filter; + } + + return $this; + } + + /** + * Add a post-filter to one or more inputs. Post-filters are applied after + * rules and callbacks have been executed. + * + * @chainable + * @param callback filter + * @param string fields to apply filter to, use TRUE for all fields + * @return object + */ + public function post_filter($filter, $field = TRUE) + { + if ($field === TRUE) + { + // Use wildcard + $fields = array('*'); + } + else + { + // Add the filter to specific inputs + $fields = func_get_args(); + $fields = array_slice($fields, 1); + } + + // Convert to a proper callback + $filter = $this->callback($filter); + + foreach ($fields as $field) + { + // Add the filter to specified field + $this->post_filters[$field][] = $filter; + } + + return $this; + } + + /** + * Add rules to a field. Validation rules may only return TRUE or FALSE and + * can not manipulate the value of a field. + * + * @chainable + * @param string field name + * @param callback rules (one or more arguments) + * @return object + */ + public function add_rules($field, $rules) + { + // Get the rules + $rules = func_get_args(); + $rules = array_slice($rules, 1); + + if ($field === TRUE) + { + // Use wildcard + $field = '*'; + } + + foreach ($rules as $rule) + { + // Arguments for rule + $args = NULL; + + if (is_string($rule)) + { + if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) + { + // Split the rule into the function and args + $rule = $matches[1]; + $args = preg_split('/(?array_fields[$field] = $field; + } + + // Convert to a proper callback + $rule = $this->callback($rule); + + // Add the rule, with args, to the field + $this->rules[$field][] = array($rule, $args); + } + + return $this; + } + + /** + * Add callbacks to a field. Callbacks must accept the Validation object + * and the input name. Callback returns are not processed. + * + * @chainable + * @param string field name + * @param callbacks callbacks (unlimited number) + * @return object + */ + public function add_callbacks($field, $callbacks) + { + // Get all callbacks as an array + $callbacks = func_get_args(); + $callbacks = array_slice($callbacks, 1); + + if ($field === TRUE) + { + // Use wildcard + $field = '*'; + } + + foreach ($callbacks as $callback) + { + // Convert to a proper callback + $callback = $this->callback($callback); + + // Add the callback to specified field + $this->callbacks[$field][] = $callback; + } + + return $this; + } + + /** + * Validate by processing pre-filters, rules, callbacks, and post-filters. + * All fields that have filters, rules, or callbacks will be initialized if + * they are undefined. Validation will only be run if there is data already + * in the array. + * + * @param object Validation object, used only for recursion + * @param object name of field for errors + * @return bool + */ + public function validate($object = NULL, $field_name = NULL) + { + if ($object === NULL) + { + // Use the current object + $object = $this; + } + + // Get all field names + $fields = $this->field_names(); + + // Copy the array from the object, to optimize multiple sets + $array = $this->getArrayCopy(); + + foreach ($fields as $field) + { + if ($field === '*') + { + // Ignore wildcard + continue; + } + + if ( ! isset($array[$field])) + { + if (isset($this->array_fields[$field])) + { + // This field must be an array + $array[$field] = array(); + } + else + { + $array[$field] = NULL; + } + } + } + + // Swap the array back into the object + $this->exchangeArray($array); + + // Get all defined field names + $fields = array_keys($array); + + foreach ($this->pre_filters as $field => $callbacks) + { + foreach ($callbacks as $callback) + { + if ($field === '*') + { + foreach ($fields as $f) + { + $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); + } + } + else + { + $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); + } + } + } + + if ($this->submitted === FALSE) + return FALSE; + + foreach ($this->rules as $field => $callbacks) + { + foreach ($callbacks as $callback) + { + // Separate the callback and arguments + list ($callback, $args) = $callback; + + // Function or method name of the rule + $rule = is_array($callback) ? $callback[1] : $callback; + + if ($field === '*') + { + foreach ($fields as $f) + { + // Note that continue, instead of break, is used when + // applying rules using a wildcard, so that all fields + // will be validated. + + if (isset($this->errors[$f])) + { + // Prevent other rules from being evaluated if an error has occurred + continue; + } + + if (empty($this[$f]) AND ! in_array($rule, $this->empty_rules)) + { + // This rule does not need to be processed on empty fields + continue; + } + + if ($args === NULL) + { + if ( ! call_user_func($callback, $this[$f])) + { + $this->errors[$f] = $rule; + + // Stop validating this field when an error is found + continue; + } + } + else + { + if ( ! call_user_func($callback, $this[$f], $args)) + { + $this->errors[$f] = $rule; + + // Stop validating this field when an error is found + continue; + } + } + } + } + else + { + if (isset($this->errors[$field])) + { + // Prevent other rules from being evaluated if an error has occurred + break; + } + + if ( ! in_array($rule, $this->empty_rules) AND ! $this->required($this[$field])) + { + // This rule does not need to be processed on empty fields + continue; + } + + if ($args === NULL) + { + if ( ! call_user_func($callback, $this[$field])) + { + $this->errors[$field] = $rule; + + // Stop validating this field when an error is found + break; + } + } + else + { + if ( ! call_user_func($callback, $this[$field], $args)) + { + $this->errors[$field] = $rule; + + // Stop validating this field when an error is found + break; + } + } + } + } + } + + foreach ($this->callbacks as $field => $callbacks) + { + foreach ($callbacks as $callback) + { + if ($field === '*') + { + foreach ($fields as $f) + { + // Note that continue, instead of break, is used when + // applying rules using a wildcard, so that all fields + // will be validated. + + if (isset($this->errors[$f])) + { + // Stop validating this field when an error is found + continue; + } + + call_user_func($callback, $this, $f); + } + } + else + { + if (isset($this->errors[$field])) + { + // Stop validating this field when an error is found + break; + } + + call_user_func($callback, $this, $field); + } + } + } + + foreach ($this->post_filters as $field => $callbacks) + { + foreach ($callbacks as $callback) + { + if ($field === '*') + { + foreach ($fields as $f) + { + $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); + } + } + else + { + $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); + } + } + } + + // Return TRUE if there are no errors + return $this->errors === array(); + } + + /** + * Add an error to an input. + * + * @chainable + * @param string input name + * @param string unique error name + * @return object + */ + public function add_error($field, $name) + { + $this->errors[$field] = $name; + + return $this; + } + + /** + * Sets or returns the message for an input. + * + * @chainable + * @param string input key + * @param string message to set + * @return string|object + */ + public function message($input = NULL, $message = NULL) + { + if ($message === NULL) + { + if ($input === NULL) + { + $messages = array(); + $keys = array_keys($this->messages); + + foreach ($keys as $input) + { + $messages[] = $this->message($input); + } + + return implode("\n", $messages); + } + + // Return nothing if no message exists + if (empty($this->messages[$input])) + return ''; + + // Return the HTML message string + return $this->messages[$input]; + } + else + { + $this->messages[$input] = $message; + } + + return $this; + } + + /** + * Return the errors array. + * + * @param boolean load errors from a lang file + * @return array + */ + public function errors($file = NULL) + { + if ($file === NULL) + { + return $this->errors; + } + else + { + + $errors = array(); + foreach ($this->errors as $input => $error) + { + // Key for this input error + $key = "$file.$input.$error"; + + if (($errors[$input] = Kohana::lang($key)) === $key) + { + // Get the default error message + $errors[$input] = Kohana::lang("$file.$input.default"); + } + } + + return $errors; + } + } + + /** + * Rule: required. Generates an error if the field has an empty value. + * + * @param mixed input value + * @return bool + */ + public function required($str) + { + if (is_object($str) AND $str instanceof ArrayObject) + { + // Get the array from the ArrayObject + $str = $str->getArrayCopy(); + } + + if (is_array($str)) + { + return ! empty($str); + } + else + { + return ! ($str === '' OR $str === NULL OR $str === FALSE); + } + } + + /** + * Rule: matches. Generates an error if the field does not match one or more + * other fields. + * + * @param mixed input value + * @param array input names to match against + * @return bool + */ + public function matches($str, array $inputs) + { + foreach ($inputs as $key) + { + if ($str !== (isset($this[$key]) ? $this[$key] : NULL)) + return FALSE; + } + + return TRUE; + } + + /** + * Rule: length. Generates an error if the field is too long or too short. + * + * @param mixed input value + * @param array minimum, maximum, or exact length to match + * @return bool + */ + public function length($str, array $length) + { + if ( ! is_string($str)) + return FALSE; + + $size = utf8::strlen($str); + $status = FALSE; + + if (count($length) > 1) + { + list ($min, $max) = $length; + + if ($size >= $min AND $size <= $max) + { + $status = TRUE; + } + } + else + { + $status = ($size === (int) $length[0]); + } + + return $status; + } + + /** + * Rule: depends_on. Generates an error if the field does not depend on one + * or more other fields. + * + * @param mixed field name + * @param array field names to check dependency + * @return bool + */ + public function depends_on($field, array $fields) + { + foreach ($fields as $depends_on) + { + if ( ! isset($this[$depends_on]) OR $this[$depends_on] == NULL) + return FALSE; + } + + return TRUE; + } + + /** + * Rule: chars. Generates an error if the field contains characters outside of the list. + * + * @param string field value + * @param array allowed characters + * @return bool + */ + public function chars($value, array $chars) + { + return ! preg_match('![^'.implode('', $chars).']!u', $value); + } + +} // End Validation diff --git a/lib/kohana/system/libraries/View.php b/lib/kohana/system/libraries/View.php new file mode 100644 index 0000000..2b8471c --- /dev/null +++ b/lib/kohana/system/libraries/View.php @@ -0,0 +1,309 @@ +set_filename($name, $type); + } + + if (is_array($data) AND ! empty($data)) + { + // Preload data using array_merge, to allow user extensions + $this->kohana_local_data = array_merge($this->kohana_local_data, $data); + } + } + + /** + * Magic method access to test for view property + * + * @param string View property to test for + * @return boolean + */ + public function __isset($key = NULL) + { + return $this->is_set($key); + } + + /** + * Sets the view filename. + * + * @chainable + * @param string view filename + * @param string view file type + * @return object + */ + public function set_filename($name, $type = NULL) + { + if ($type == NULL) + { + // Load the filename and set the content type + $this->kohana_filename = Kohana::find_file('views', $name, TRUE); + $this->kohana_filetype = EXT; + } + else + { + // Check if the filetype is allowed by the configuration + if ( ! in_array($type, Kohana::config('view.allowed_filetypes'))) + throw new Kohana_Exception('core.invalid_filetype', $type); + + // Load the filename and set the content type + $this->kohana_filename = Kohana::find_file('views', $name, TRUE, $type); + $this->kohana_filetype = Kohana::config('mimes.'.$type); + + if ($this->kohana_filetype == NULL) + { + // Use the specified type + $this->kohana_filetype = $type; + } + } + + return $this; + } + + /** + * Sets a view variable. + * + * @param string|array name of variable or an array of variables + * @param mixed value when using a named variable + * @return object + */ + public function set($name, $value = NULL) + { + if (is_array($name)) + { + foreach ($name as $key => $value) + { + $this->__set($key, $value); + } + } + else + { + $this->__set($name, $value); + } + + return $this; + } + + /** + * Checks for a property existence in the view locally or globally. Unlike the built in __isset(), + * this method can take an array of properties to test simultaneously. + * + * @param string $key property name to test for + * @param array $key array of property names to test for + * @return boolean property test result + * @return array associative array of keys and boolean test result + */ + public function is_set( $key = FALSE ) + { + // Setup result; + $result = FALSE; + + // If key is an array + if (is_array($key)) + { + // Set the result to an array + $result = array(); + + // Foreach key + foreach ($key as $property) + { + // Set the result to an associative array + $result[$property] = (array_key_exists($property, $this->kohana_local_data) OR array_key_exists($property, View::$kohana_global_data)) ? TRUE : FALSE; + } + } + else + { + // Otherwise just check one property + $result = (array_key_exists($key, $this->kohana_local_data) OR array_key_exists($key, View::$kohana_global_data)) ? TRUE : FALSE; + } + + // Return the result + return $result; + } + + /** + * Sets a bound variable by reference. + * + * @param string name of variable + * @param mixed variable to assign by reference + * @return object + */ + public function bind($name, & $var) + { + $this->kohana_local_data[$name] =& $var; + + return $this; + } + + /** + * Sets a view global variable. + * + * @param string|array name of variable or an array of variables + * @param mixed value when using a named variable + * @return void + */ + public static function set_global($name, $value = NULL) + { + if (is_array($name)) + { + foreach ($name as $key => $value) + { + View::$kohana_global_data[$key] = $value; + } + } + else + { + View::$kohana_global_data[$name] = $value; + } + } + + /** + * Magically sets a view variable. + * + * @param string variable key + * @param string variable value + * @return void + */ + public function __set($key, $value) + { + $this->kohana_local_data[$key] = $value; + } + + /** + * Magically gets a view variable. + * + * @param string variable key + * @return mixed variable value if the key is found + * @return void if the key is not found + */ + public function &__get($key) + { + if (isset($this->kohana_local_data[$key])) + return $this->kohana_local_data[$key]; + + if (isset(View::$kohana_global_data[$key])) + return View::$kohana_global_data[$key]; + + if (isset($this->$key)) + return $this->$key; + } + + /** + * Magically converts view object to string. + * + * @return string + */ + public function __toString() + { + try + { + return $this->render(); + } + catch (Exception $e) + { + // Display the exception using its internal __toString method + return (string) $e; + } + } + + /** + * Renders a view. + * + * @param boolean set to TRUE to echo the output instead of returning it + * @param callback special renderer to pass the output through + * @return string if print is FALSE + * @return void if print is TRUE + */ + public function render($print = FALSE, $renderer = FALSE) + { + if (empty($this->kohana_filename)) + throw new Kohana_Exception('core.view_set_filename'); + + if (is_string($this->kohana_filetype)) + { + // Merge global and local data, local overrides global with the same name + $data = array_merge(View::$kohana_global_data, $this->kohana_local_data); + + // Load the view in the controller for access to $this + $output = Kohana::$instance->_kohana_load_view($this->kohana_filename, $data); + + if ($renderer !== FALSE AND is_callable($renderer, TRUE)) + { + // Pass the output through the user defined renderer + $output = call_user_func($renderer, $output); + } + + if ($print === TRUE) + { + // Display the output + echo $output; + return; + } + } + else + { + // Set the content type and size + header('Content-Type: '.$this->kohana_filetype[0]); + + if ($print === TRUE) + { + if ($file = fopen($this->kohana_filename, 'rb')) + { + // Display the output + fpassthru($file); + fclose($file); + } + return; + } + + // Fetch the file contents + $output = file_get_contents($this->kohana_filename); + } + + return $output; + } +} // End View \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Cache.php b/lib/kohana/system/libraries/drivers/Cache.php new file mode 100644 index 0000000..7c5e3c3 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Cache.php @@ -0,0 +1,40 @@ +directory = $directory; + } + + /** + * Finds an array of files matching the given id or tag. + * + * @param string cache id or tag + * @param bool search for tags + * @return array of filenames matching the id or tag + */ + public function exists($id, $tag = FALSE) + { + if ($id === TRUE) + { + // Find all the files + return glob($this->directory.'*~*~*'); + } + elseif ($tag === TRUE) + { + // Find all the files that have the tag name + $paths = glob($this->directory.'*~*'.$id.'*~*'); + + // Find all tags matching the given tag + $files = array(); + foreach ($paths as $path) + { + // Split the files + $tags = explode('~', basename($path)); + + // Find valid tags + if (count($tags) !== 3 OR empty($tags[1])) + continue; + + // Split the tags by plus signs, used to separate tags + $tags = explode('+', $tags[1]); + + if (in_array($tag, $tags)) + { + // Add the file to the array, it has the requested tag + $files[] = $path; + } + } + + return $files; + } + else + { + // Find the file matching the given id + return glob($this->directory.$id.'~*'); + } + } + + /** + * Sets a cache item to the given data, tags, and lifetime. + * + * @param string cache id to set + * @param string data in the cache + * @param array cache tags + * @param integer lifetime + * @return bool + */ + public function set($id, $data, array $tags = NULL, $lifetime) + { + // Remove old cache files + $this->delete($id); + + // Cache File driver expects unix timestamp + if ($lifetime !== 0) + { + $lifetime += time(); + } + + if ( ! empty($tags)) + { + // Convert the tags into a string list + $tags = implode('+', $tags); + } + + // Write out a serialized cache + return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data)); + } + + /** + * Finds an array of ids for a given tag. + * + * @param string tag name + * @return array of ids that match the tag + */ + public function find($tag) + { + // An array will always be returned + $result = array(); + + if ($paths = $this->exists($tag, TRUE)) + { + // Length of directory name + $offset = strlen($this->directory); + + // Find all the files with the given tag + foreach ($paths as $path) + { + // Get the id from the filename + list($id, $junk) = explode('~', basename($path), 2); + + if (($data = $this->get($id)) !== FALSE) + { + // Add the result to the array + $result[$id] = $data; + } + } + } + + return $result; + } + + /** + * Fetches a cache item. This will delete the item if it is expired or if + * the hash does not match the stored hash. + * + * @param string cache id + * @return mixed|NULL + */ + public function get($id) + { + if ($file = $this->exists($id)) + { + // Use the first file + $file = current($file); + + // Validate that the cache has not expired + if ($this->expired($file)) + { + // Remove this cache, it has expired + $this->delete($id); + } + else + { + // Turn off errors while reading the file + $ER = error_reporting(0); + + if (($data = file_get_contents($file)) !== FALSE) + { + // Unserialize the data + $data = unserialize($data); + } + else + { + // Delete the data + unset($data); + } + + // Turn errors back on + error_reporting($ER); + } + } + + // Return NULL if there is no data + return isset($data) ? $data : NULL; + } + + /** + * Deletes a cache item by id or tag + * + * @param string cache id or tag, or TRUE for "all items" + * @param boolean use tags + * @return boolean + */ + public function delete($id, $tag = FALSE) + { + $files = $this->exists($id, $tag); + + if (empty($files)) + return FALSE; + + // Disable all error reporting while deleting + $ER = error_reporting(0); + + foreach ($files as $file) + { + // Remove the cache file + if ( ! unlink($file)) + Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); + } + + // Turn on error reporting again + error_reporting($ER); + + return TRUE; + } + + /** + * Deletes all cache files that are older than the current time. + * + * @return void + */ + public function delete_expired() + { + if ($files = $this->exists(TRUE)) + { + // Disable all error reporting while deleting + $ER = error_reporting(0); + + foreach ($files as $file) + { + if ($this->expired($file)) + { + // The cache file has already expired, delete it + if ( ! unlink($file)) + Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); + } + } + + // Turn on error reporting again + error_reporting($ER); + } + } + + /** + * Check if a cache file has expired by filename. + * + * @param string filename + * @return bool + */ + protected function expired($file) + { + // Get the expiration time + $expires = (int) substr($file, strrpos($file, '~') + 1); + + // Expirations of 0 are "never expire" + return ($expires !== 0 AND $expires <= time()); + } + +} // End Cache File Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Cache/Memcache.php b/lib/kohana/system/libraries/drivers/Cache/Memcache.php new file mode 100644 index 0000000..d801de9 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Cache/Memcache.php @@ -0,0 +1,191 @@ +backend = new Memcache; + $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE; + + $servers = Kohana::config('cache_memcache.servers'); + + foreach ($servers as $server) + { + // Make sure all required keys are set + $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE); + + // Add the server to the pool + $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent']) + or Kohana::log('error', 'Cache: Connection failed: '.$server['host']); + } + + // Load tags + self::$tags = $this->backend->get(self::TAGS_KEY); + + if ( ! is_array(self::$tags)) + { + // Create a new tags array + self::$tags = array(); + + // Tags have been created + self::$tags_changed = TRUE; + } + } + + public function __destruct() + { + if (self::$tags_changed === TRUE) + { + // Save the tags + $this->backend->set(self::TAGS_KEY, self::$tags, $this->flags, 0); + + // Tags are now unchanged + self::$tags_changed = FALSE; + } + } + + public function find($tag) + { + if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag])) + { + // Return all the found caches + return $results; + } + else + { + // No matching tags + return array(); + } + } + + public function get($id) + { + return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return; + } + + public function set($id, $data, array $tags = NULL, $lifetime) + { + if ( ! empty($tags)) + { + // Tags will be changed + self::$tags_changed = TRUE; + + foreach ($tags as $tag) + { + // Add the id to each tag + self::$tags[$tag][$id] = $id; + } + } + + if ($lifetime !== 0) + { + // Memcache driver expects unix timestamp + $lifetime += time(); + } + + // Set a new value + return $this->backend->set($id, $data, $this->flags, $lifetime); + } + + public function delete($id, $tag = FALSE) + { + // Tags will be changed + self::$tags_changed = TRUE; + + if ($id === TRUE) + { + if ($status = $this->backend->flush()) + { + // Remove all tags, all items have been deleted + self::$tags = array(); + + // We must sleep after flushing, or overwriting will not work! + // @see http://php.net/manual/en/function.memcache-flush.php#81420 + sleep(1); + } + + return $status; + } + elseif ($tag === TRUE) + { + if (isset(self::$tags[$id])) + { + foreach (self::$tags[$id] as $_id) + { + // Delete each id in the tag + $this->backend->delete($_id); + } + + // Delete the tag + unset(self::$tags[$id]); + } + + return TRUE; + } + else + { + foreach (self::$tags as $tag => $_ids) + { + if (isset(self::$tags[$tag][$id])) + { + // Remove the id from the tags + unset(self::$tags[$tag][$id]); + } + } + + return $this->backend->delete($id); + } + } + + public function delete_expired() + { + // Tags will be changed + self::$tags_changed = TRUE; + + foreach (self::$tags as $tag => $_ids) + { + foreach ($_ids as $id) + { + if ( ! $this->backend->get($id)) + { + // This id has disappeared, delete it from the tags + unset(self::$tags[$tag][$id]); + } + } + + if (empty(self::$tags[$tag])) + { + // The tag no longer has any valid ids + unset(self::$tags[$tag]); + } + } + + // Memcache handles garbage collection internally + return TRUE; + } + +} // End Cache Memcache Driver diff --git a/lib/kohana/system/libraries/drivers/Cache/Sqlite.php b/lib/kohana/system/libraries/drivers/Cache/Sqlite.php new file mode 100644 index 0000000..9458d85 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Cache/Sqlite.php @@ -0,0 +1,257 @@ +db = new SQLiteDatabase($filename, '0666', $error); + + // Throw an exception if there's an error + if ( ! empty($error)) + throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); + + $query = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'caches'"; + $tables = $this->db->query($query, SQLITE_BOTH, $error); + + // Throw an exception if there's an error + if ( ! empty($error)) + throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); + + if ($tables->numRows() == 0) + { + Kohana::log('error', 'Cache: Initializing new SQLite cache database'); + + // Issue a CREATE TABLE command + $this->db->unbufferedQuery(Kohana::config('cache_sqlite.schema')); + } + } + + /** + * Checks if a cache id is already set. + * + * @param string cache id + * @return boolean + */ + public function exists($id) + { + // Find the id that matches + $query = "SELECT id FROM caches WHERE id = '$id'"; + + return ($this->db->query($query)->numRows() > 0); + } + + /** + * Sets a cache item to the given data, tags, and lifetime. + * + * @param string cache id to set + * @param string data in the cache + * @param array cache tags + * @param integer lifetime + * @return bool + */ + public function set($id, $data, array $tags = NULL, $lifetime) + { + // Serialize and escape the data + $data = sqlite_escape_string(serialize($data)); + + if ( ! empty($tags)) + { + // Escape the tags, adding brackets so the tag can be explicitly matched + $tags = sqlite_escape_string('<'.implode('>,<', $tags).'>'); + } + + // Cache Sqlite driver expects unix timestamp + if ($lifetime !== 0) + { + $lifetime += time(); + } + + $query = $this->exists($id) + ? "UPDATE caches SET tags = '$tags', expiration = '$lifetime', cache = '$data' WHERE id = '$id'" + : "INSERT INTO caches VALUES('$id', '$tags', '$lifetime', '$data')"; + + // Run the query + $this->db->unbufferedQuery($query, SQLITE_BOTH, $error); + + if ( ! empty($error)) + { + self::log_error($error); + return FALSE; + } + else + { + return TRUE; + } + } + + /** + * Finds an array of ids for a given tag. + * + * @param string tag name + * @return array of ids that match the tag + */ + public function find($tag) + { + $query = "SELECT id,cache FROM caches WHERE tags LIKE '%<{$tag}>%'"; + $query = $this->db->query($query, SQLITE_BOTH, $error); + + // An array will always be returned + $result = array(); + + if ( ! empty($error)) + { + self::log_error($error); + } + elseif ($query->numRows() > 0) + { + // Disable notices for unserializing + $ER = error_reporting(~E_NOTICE); + + while ($row = $query->fetchObject()) + { + // Add each cache to the array + $result[$row->id] = unserialize($row->cache); + } + + // Turn notices back on + error_reporting($ER); + } + + return $result; + } + + /** + * Fetches a cache item. This will delete the item if it is expired or if + * the hash does not match the stored hash. + * + * @param string cache id + * @return mixed|NULL + */ + public function get($id) + { + $query = "SELECT id, expiration, cache FROM caches WHERE id = '$id' LIMIT 0, 1"; + $query = $this->db->query($query, SQLITE_BOTH, $error); + + if ( ! empty($error)) + { + self::log_error($error); + } + elseif ($cache = $query->fetchObject()) + { + // Make sure the expiration is valid and that the hash matches + if ($cache->expiration != 0 AND $cache->expiration <= time()) + { + // Cache is not valid, delete it now + $this->delete($cache->id); + } + else + { + // Disable notices for unserializing + $ER = error_reporting(~E_NOTICE); + + // Return the valid cache data + $data = $cache->cache; + + // Turn notices back on + error_reporting($ER); + } + } + + // No valid cache found + return NULL; + } + + /** + * Deletes a cache item by id or tag + * + * @param string cache id or tag, or TRUE for "all items" + * @param bool delete a tag + * @return bool + */ + public function delete($id, $tag = FALSE) + { + if ($id === TRUE) + { + // Delete all caches + $where = '1'; + } + elseif ($tag === TRUE) + { + // Delete by tag + $where = "tags LIKE '%<{$id}>%'"; + } + else + { + // Delete by id + $where = "id = '$id'"; + } + + $this->db->unbufferedQuery('DELETE FROM caches WHERE '.$where, SQLITE_BOTH, $error); + + if ( ! empty($error)) + { + self::log_error($error); + return FALSE; + } + else + { + return TRUE; + } + } + + /** + * Deletes all cache files that are older than the current time. + */ + public function delete_expired() + { + // Delete all expired caches + $query = 'DELETE FROM caches WHERE expiration != 0 AND expiration <= '.time(); + + $this->db->unbufferedQuery($query); + + return TRUE; + } + +} // End Cache SQLite Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Cache/Xcache.php b/lib/kohana/system/libraries/drivers/Cache/Xcache.php new file mode 100644 index 0000000..6254bbb --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Cache/Xcache.php @@ -0,0 +1,119 @@ +auth(); + $result = TRUE; + for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) + { + if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL) + { + $result = FALSE; + break; + } + } + + // Undo the login + $this->auth(TRUE); + return $result; + } + + return TRUE; + } + + public function delete_expired() + { + return TRUE; + } + + private function auth($reverse = FALSE) + { + static $backup = array(); + + $keys = array('PHP_AUTH_USER', 'PHP_AUTH_PW'); + + foreach ($keys as $key) + { + if ($reverse) + { + if (isset($backup[$key])) + { + $_SERVER[$key] = $backup[$key]; + unset($backup[$key]); + } + else + { + unset($_SERVER[$key]); + } + } + else + { + $value = getenv($key); + + if ( ! empty($value)) + { + $backup[$key] = $value; + } + + $_SERVER[$key] = Kohana::config('cache_xcache.'.$key); + } + } + } + +} // End Cache Xcache Driver diff --git a/lib/kohana/system/libraries/drivers/Captcha.php b/lib/kohana/system/libraries/drivers/Captcha.php new file mode 100644 index 0000000..a4343e1 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha.php @@ -0,0 +1,227 @@ +response = $this->generate_challenge(); + + // Store the correct Captcha response in a session + Event::add('system.post_controller', array($this, 'update_response_session')); + } + + /** + * Generate a new Captcha challenge. + * + * @return string the challenge answer + */ + abstract public function generate_challenge(); + + /** + * Output the Captcha challenge. + * + * @param boolean html output + * @return mixed the rendered Captcha (e.g. an image, riddle, etc.) + */ + abstract public function render($html); + + /** + * Stores the response for the current Captcha challenge in a session so it is available + * on the next page load for Captcha::valid(). This method is called after controller + * execution (in the system.post_controller event) in order not to overwrite itself too soon. + * + * @return void + */ + public function update_response_session() + { + Session::instance()->set('captcha_response', sha1(strtoupper($this->response))); + } + + /** + * Validates a Captcha response from a user. + * + * @param string captcha response + * @return boolean + */ + public function valid($response) + { + return (sha1(strtoupper($response)) === Session::instance()->get('captcha_response')); + } + + /** + * Returns the image type. + * + * @param string filename + * @return string|FALSE image type ("png", "gif" or "jpeg") + */ + public function image_type($filename) + { + switch (strtolower(substr(strrchr($filename, '.'), 1))) + { + case 'png': + return 'png'; + + case 'gif': + return 'gif'; + + case 'jpg': + case 'jpeg': + // Return "jpeg" and not "jpg" because of the GD2 function names + return 'jpeg'; + + default: + return FALSE; + } + } + + /** + * Creates an image resource with the dimensions specified in config. + * If a background image is supplied, the image dimensions are used. + * + * @throws Kohana_Exception if no GD2 support + * @param string path to the background image file + * @return void + */ + public function image_create($background = NULL) + { + // Check for GD2 support + if ( ! function_exists('imagegd2')) + throw new Kohana_Exception('captcha.requires_GD2'); + + // Create a new image (black) + $this->image = imagecreatetruecolor(Captcha::$config['width'], Captcha::$config['height']); + + // Use a background image + if ( ! empty($background)) + { + // Create the image using the right function for the filetype + $function = 'imagecreatefrom'.$this->image_type($background); + $this->background_image = $function($background); + + // Resize the image if needed + if (imagesx($this->background_image) !== Captcha::$config['width'] + OR imagesy($this->background_image) !== Captcha::$config['height']) + { + imagecopyresampled + ( + $this->image, $this->background_image, 0, 0, 0, 0, + Captcha::$config['width'], Captcha::$config['height'], + imagesx($this->background_image), imagesy($this->background_image) + ); + } + + // Free up resources + imagedestroy($this->background_image); + } + } + + /** + * Fills the background with a gradient. + * + * @param resource gd image color identifier for start color + * @param resource gd image color identifier for end color + * @param string direction: 'horizontal' or 'vertical', 'random' by default + * @return void + */ + public function image_gradient($color1, $color2, $direction = NULL) + { + $directions = array('horizontal', 'vertical'); + + // Pick a random direction if needed + if ( ! in_array($direction, $directions)) + { + $direction = $directions[array_rand($directions)]; + + // Switch colors + if (mt_rand(0, 1) === 1) + { + $temp = $color1; + $color1 = $color2; + $color2 = $temp; + } + } + + // Extract RGB values + $color1 = imagecolorsforindex($this->image, $color1); + $color2 = imagecolorsforindex($this->image, $color2); + + // Preparations for the gradient loop + $steps = ($direction === 'horizontal') ? Captcha::$config['width'] : Captcha::$config['height']; + + $r1 = ($color1['red'] - $color2['red']) / $steps; + $g1 = ($color1['green'] - $color2['green']) / $steps; + $b1 = ($color1['blue'] - $color2['blue']) / $steps; + + if ($direction === 'horizontal') + { + $x1 =& $i; + $y1 = 0; + $x2 =& $i; + $y2 = Captcha::$config['height']; + } + else + { + $x1 = 0; + $y1 =& $i; + $x2 = Captcha::$config['width']; + $y2 =& $i; + } + + // Execute the gradient loop + for ($i = 0; $i <= $steps; $i++) + { + $r2 = $color1['red'] - floor($i * $r1); + $g2 = $color1['green'] - floor($i * $g1); + $b2 = $color1['blue'] - floor($i * $b1); + $color = imagecolorallocate($this->image, $r2, $g2, $b2); + + imageline($this->image, $x1, $y1, $x2, $y2, $color); + } + } + + /** + * Returns the img html element or outputs the image to the browser. + * + * @param boolean html output + * @return mixed html string or void + */ + public function image_render($html) + { + // Output html element + if ($html) + return 'Captcha'; + + // Send the correct HTTP header + header('Content-Type: image/'.$this->image_type); + + // Pick the correct output function + $function = 'image'.$this->image_type; + $function($this->image); + + // Free up resources + imagedestroy($this->image); + } + +} // End Captcha Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Alpha.php b/lib/kohana/system/libraries/drivers/Captcha/Alpha.php new file mode 100644 index 0000000..2779580 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Alpha.php @@ -0,0 +1,92 @@ +image + $this->image_create(Captcha::$config['background']); + + // Add a random gradient + if (empty(Captcha::$config['background'])) + { + $color1 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); + $color2 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); + $this->image_gradient($color1, $color2); + } + + // Add a few random circles + for ($i = 0, $count = mt_rand(10, Captcha::$config['complexity'] * 3); $i < $count; $i++) + { + $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255), mt_rand(80, 120)); + $size = mt_rand(5, Captcha::$config['height'] / 3); + imagefilledellipse($this->image, mt_rand(0, Captcha::$config['width']), mt_rand(0, Captcha::$config['height']), $size, $size, $color); + } + + // Calculate character font-size and spacing + $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / strlen($this->response); + $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); + + // Background alphabetic character attributes + $color_limit = mt_rand(96, 160); + $chars = 'ABEFGJKLPQRTVY'; + + // Draw each Captcha character with varying attributes + for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) + { + // Use different fonts if available + $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; + + $angle = mt_rand(-40, 20); + // Scale the character size on image height + $size = $default_size / 10 * mt_rand(8, 12); + $box = imageftbbox($size, $angle, $font, $this->response[$i]); + + // Calculate character starting coordinates + $x = $spacing / 4 + $i * $spacing; + $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; + + // Draw captcha text character + // Allocate random color, size and rotation attributes to text + $color = imagecolorallocate($this->image, mt_rand(150, 255), mt_rand(200, 255), mt_rand(0, 255)); + + // Write text character to image + imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); + + // Draw "ghost" alphabetic character + $text_color = imagecolorallocatealpha($this->image, mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand(70, 120)); + $char = $chars[mt_rand(0, 14)]; + imagettftext($this->image, $size * 2, mt_rand(-45, 45), ($x - (mt_rand(5, 10))), ($y + (mt_rand(5, 10))), $text_color, $font, $char); + } + + // Output + return $this->image_render($html); + } + +} // End Captcha Alpha Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Basic.php b/lib/kohana/system/libraries/drivers/Captcha/Basic.php new file mode 100644 index 0000000..d212e72 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Basic.php @@ -0,0 +1,81 @@ +image + $this->image_create(Captcha::$config['background']); + + // Add a random gradient + if (empty(Captcha::$config['background'])) + { + $color1 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); + $color2 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); + $this->image_gradient($color1, $color2); + } + + // Add a few random lines + for ($i = 0, $count = mt_rand(5, Captcha::$config['complexity'] * 4); $i < $count; $i++) + { + $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(100, 255), mt_rand(50, 120)); + imageline($this->image, mt_rand(0, Captcha::$config['width']), 0, mt_rand(0, Captcha::$config['width']), Captcha::$config['height'], $color); + } + + // Calculate character font-size and spacing + $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / (strlen($this->response) + 1); + $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); + + // Draw each Captcha character with varying attributes + for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) + { + // Use different fonts if available + $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; + + // Allocate random color, size and rotation attributes to text + $color = imagecolorallocate($this->image, mt_rand(0, 150), mt_rand(0, 150), mt_rand(0, 150)); + $angle = mt_rand(-40, 20); + + // Scale the character size on image height + $size = $default_size / 10 * mt_rand(8, 12); + $box = imageftbbox($size, $angle, $font, $this->response[$i]); + + // Calculate character starting coordinates + $x = $spacing / 4 + $i * $spacing; + $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; + + // Write text character to image + imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); + } + + // Output + return $this->image_render($html); + } + +} // End Captcha Basic Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Black.php b/lib/kohana/system/libraries/drivers/Captcha/Black.php new file mode 100644 index 0000000..6a2e222 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Black.php @@ -0,0 +1,72 @@ +image_create(Captcha::$config['background']); + + // Add random white/gray arcs, amount depends on complexity setting + $count = (Captcha::$config['width'] + Captcha::$config['height']) / 2; + $count = $count / 5 * min(10, Captcha::$config['complexity']); + for ($i = 0; $i < $count; $i++) + { + imagesetthickness($this->image, mt_rand(1, 2)); + $color = imagecolorallocatealpha($this->image, 255, 255, 255, mt_rand(0, 120)); + imagearc($this->image, mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(0, 360), mt_rand(0, 360), $color); + } + + // Use different fonts if available + $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; + + // Draw the character's white shadows + $size = (int) min(Captcha::$config['height'] / 2, Captcha::$config['width'] * 0.8 / strlen($this->response)); + $angle = mt_rand(-15 + strlen($this->response), 15 - strlen($this->response)); + $x = mt_rand(1, Captcha::$config['width'] * 0.9 - $size * strlen($this->response)); + $y = ((Captcha::$config['height'] - $size) / 2) + $size; + $color = imagecolorallocate($this->image, 255, 255, 255); + imagefttext($this->image, $size, $angle, $x + 1, $y + 1, $color, $font, $this->response); + + // Add more shadows for lower complexities + (Captcha::$config['complexity'] < 10) and imagefttext($this->image, $size, $angle, $x - 1, $y - 1, $color, $font , $this->response); + (Captcha::$config['complexity'] < 8) and imagefttext($this->image, $size, $angle, $x - 2, $y + 2, $color, $font , $this->response); + (Captcha::$config['complexity'] < 6) and imagefttext($this->image, $size, $angle, $x + 2, $y - 2, $color, $font , $this->response); + (Captcha::$config['complexity'] < 4) and imagefttext($this->image, $size, $angle, $x + 3, $y + 3, $color, $font , $this->response); + (Captcha::$config['complexity'] < 2) and imagefttext($this->image, $size, $angle, $x - 3, $y - 3, $color, $font , $this->response); + + // Finally draw the foreground characters + $color = imagecolorallocate($this->image, 0, 0, 0); + imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response); + + // Output + return $this->image_render($html); + } + +} // End Captcha Black Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Math.php b/lib/kohana/system/libraries/drivers/Captcha/Math.php new file mode 100644 index 0000000..4ac2024 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Math.php @@ -0,0 +1,61 @@ +math_exercice = implode(' + ', $numbers).' = '; + + // Return the answer + return array_sum($numbers); + } + + /** + * Outputs the Captcha riddle. + * + * @param boolean html output + * @return mixed + */ + public function render($html) + { + return $this->math_exercice; + } + +} // End Captcha Math Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Riddle.php b/lib/kohana/system/libraries/drivers/Captcha/Riddle.php new file mode 100644 index 0000000..765eeaa --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Riddle.php @@ -0,0 +1,47 @@ +riddle = $riddle[0]; + + // Return the answer + return $riddle[1]; + } + + /** + * Outputs the Captcha riddle. + * + * @param boolean html output + * @return mixed + */ + public function render($html) + { + return $this->riddle; + } + +} // End Captcha Riddle Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Captcha/Word.php b/lib/kohana/system/libraries/drivers/Captcha/Word.php new file mode 100644 index 0000000..856bd9b --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Captcha/Word.php @@ -0,0 +1,37 @@ +escape_table($table).' WHERE '.implode(' ', $where); + } + + /** + * Builds an UPDATE query. + * + * @param string table name + * @param array key => value pairs + * @param array where clause + * @return string + */ + public function update($table, $values, $where) + { + foreach ($values as $key => $val) + { + $valstr[] = $this->escape_column($key).' = '.$val; + } + return 'UPDATE '.$this->escape_table($table).' SET '.implode(', ', $valstr).' WHERE '.implode(' ',$where); + } + + /** + * Set the charset using 'SET NAMES '. + * + * @param string character set to use + */ + public function set_charset($charset) + { + throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); + } + + /** + * Wrap the tablename in backticks, has support for: table.field syntax. + * + * @param string table name + * @return string + */ + abstract public function escape_table($table); + + /** + * Escape a column/field name, has support for special commands. + * + * @param string column name + * @return string + */ + abstract public function escape_column($column); + + /** + * Builds a WHERE portion of a query. + * + * @param mixed key + * @param string value + * @param string type + * @param int number of where clauses + * @param boolean escape the value + * @return string + */ + public function where($key, $value, $type, $num_wheres, $quote) + { + $prefix = ($num_wheres == 0) ? '' : $type; + + if ($quote === -1) + { + $value = ''; + } + else + { + if ($value === NULL) + { + if ( ! $this->has_operator($key)) + { + $key .= ' IS'; + } + + $value = ' NULL'; + } + elseif (is_bool($value)) + { + if ( ! $this->has_operator($key)) + { + $key .= ' ='; + } + + $value = ($value == TRUE) ? ' 1' : ' 0'; + } + else + { + if ( ! $this->has_operator($key) AND ! empty($key)) + { + $key = $this->escape_column($key).' ='; + } + else + { + preg_match('/^(.+?)([<>!=]+|\bIS(?:\s+NULL))\s*$/i', $key, $matches); + if (isset($matches[1]) AND isset($matches[2])) + { + $key = $this->escape_column(trim($matches[1])).' '.trim($matches[2]); + } + } + + $value = ' '.(($quote == TRUE) ? $this->escape($value) : $value); + } + } + + return $prefix.$key.$value; + } + + /** + * Builds a LIKE portion of a query. + * + * @param mixed field name + * @param string value to match with field + * @param boolean add wildcards before and after the match + * @param string clause type (AND or OR) + * @param int number of likes + * @return string + */ + public function like($field, $match, $auto, $type, $num_likes) + { + $prefix = ($num_likes == 0) ? '' : $type; + + $match = $this->escape_str($match); + + if ($auto === TRUE) + { + // Add the start and end quotes + $match = '%'.str_replace('%', '\\%', $match).'%'; + } + + return $prefix.' '.$this->escape_column($field).' LIKE \''.$match . '\''; + } + + /** + * Builds a NOT LIKE portion of a query. + * + * @param mixed field name + * @param string value to match with field + * @param string clause type (AND or OR) + * @param int number of likes + * @return string + */ + public function notlike($field, $match, $auto, $type, $num_likes) + { + $prefix = ($num_likes == 0) ? '' : $type; + + $match = $this->escape_str($match); + + if ($auto === TRUE) + { + // Add the start and end quotes + $match = '%'.$match.'%'; + } + + return $prefix.' '.$this->escape_column($field).' NOT LIKE \''.$match.'\''; + } + + /** + * Builds a REGEX portion of a query. + * + * @param string field name + * @param string value to match with field + * @param string clause type (AND or OR) + * @param integer number of regexes + * @return string + */ + public function regex($field, $match, $type, $num_regexs) + { + throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); + } + + /** + * Builds a NOT REGEX portion of a query. + * + * @param string field name + * @param string value to match with field + * @param string clause type (AND or OR) + * @param integer number of regexes + * @return string + */ + public function notregex($field, $match, $type, $num_regexs) + { + throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); + } + + /** + * Builds an INSERT query. + * + * @param string table name + * @param array keys + * @param array values + * @return string + */ + public function insert($table, $keys, $values) + { + // Escape the column names + foreach ($keys as $key => $value) + { + $keys[$key] = $this->escape_column($value); + } + return 'INSERT INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; + } + + /** + * Builds a MERGE portion of a query. + * + * @param string table name + * @param array keys + * @param array values + * @return string + */ + public function merge($table, $keys, $values) + { + throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); + } + + /** + * Builds a LIMIT portion of a query. + * + * @param integer limit + * @param integer offset + * @return string + */ + abstract public function limit($limit, $offset = 0); + + /** + * Creates a prepared statement. + * + * @param string SQL query + * @return Database_Stmt + */ + public function stmt_prepare($sql = '') + { + throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); + } + + /** + * Compiles the SELECT statement. + * Generates a query string based on which functions were used. + * Should not be called directly, the get() function calls it. + * + * @param array select query values + * @return string + */ + abstract public function compile_select($database); + + /** + * Determines if the string has an arithmetic operator in it. + * + * @param string string to check + * @return boolean + */ + public function has_operator($str) + { + return (bool) preg_match('/[<>!=]|\sIS(?:\s+NOT\s+)?\b|BETWEEN/i', trim($str)); + } + + /** + * Escapes any input value. + * + * @param mixed value to escape + * @return string + */ + public function escape($value) + { + if ( ! $this->db_config['escape']) + return $value; + + switch (gettype($value)) + { + case 'string': + $value = '\''.$this->escape_str($value).'\''; + break; + case 'boolean': + $value = (int) $value; + break; + case 'double': + // Convert to non-locale aware float to prevent possible commas + $value = sprintf('%F', $value); + break; + default: + $value = ($value === NULL) ? 'NULL' : $value; + break; + } + + return (string) $value; + } + + /** + * Escapes a string for a query. + * + * @param mixed value to escape + * @return string + */ + abstract public function escape_str($str); + + /** + * Lists all tables in the database. + * + * @return array + */ + abstract public function list_tables(); + + /** + * Lists all fields in a table. + * + * @param string table name + * @return array + */ + abstract function list_fields($table); + + /** + * Returns the last database error. + * + * @return string + */ + abstract public function show_error(); + + /** + * Returns field data about a table. + * + * @param string table name + * @return array + */ + abstract public function field_data($table); + + /** + * Fetches SQL type information about a field, in a generic format. + * + * @param string field datatype + * @return array + */ + protected function sql_type($str) + { + static $sql_types; + + if ($sql_types === NULL) + { + // Load SQL data types + $sql_types = Kohana::config('sql_types'); + } + + $str = strtolower(trim($str)); + + if (($open = strpos($str, '(')) !== FALSE) + { + // Find closing bracket + $close = strpos($str, ')', $open) - 1; + + // Find the type without the size + $type = substr($str, 0, $open); + } + else + { + // No length + $type = $str; + } + + empty($sql_types[$type]) and exit + ( + 'Unknown field type: '.$type.'. '. + 'Please report this: http://trac.kohanaphp.com/newticket' + ); + + // Fetch the field definition + $field = $sql_types[$type]; + + switch ($field['type']) + { + case 'string': + case 'float': + if (isset($close)) + { + // Add the length to the field info + $field['length'] = substr($str, $open + 1, $close - $open); + } + break; + case 'int': + // Add unsigned value + $field['unsigned'] = (strpos($str, 'unsigned') !== FALSE); + break; + } + + return $field; + } + + /** + * Clears the internal query cache. + * + * @param string SQL query + */ + public function clear_cache($sql = NULL) + { + if (empty($sql)) + { + $this->query_cache = array(); + } + else + { + unset($this->query_cache[$this->query_hash($sql)]); + } + + Kohana::log('debug', 'Database cache cleared: '.get_class($this)); + } + + /** + * Creates a hash for an SQL query string. Replaces newlines with spaces, + * trims, and hashes. + * + * @param string SQL query + * @return string + */ + protected function query_hash($sql) + { + return sha1(str_replace("\n", ' ', trim($sql))); + } + +} // End Database Driver Interface + +/** + * Database_Result + * + */ +abstract class Database_Result implements ArrayAccess, Iterator, Countable { + + // Result resource, insert id, and SQL + protected $result; + protected $insert_id; + protected $sql; + + // Current and total rows + protected $current_row = 0; + protected $total_rows = 0; + + // Fetch function and return type + protected $fetch_type; + protected $return_type; + + /** + * Returns the SQL used to fetch the result. + * + * @return string + */ + public function sql() + { + return $this->sql; + } + + /** + * Returns the insert id from the result. + * + * @return mixed + */ + public function insert_id() + { + return $this->insert_id; + } + + /** + * Prepares the query result. + * + * @param boolean return rows as objects + * @param mixed type + * @return Database_Result + */ + abstract function result($object = TRUE, $type = FALSE); + + /** + * Builds an array of query results. + * + * @param boolean return rows as objects + * @param mixed type + * @return array + */ + abstract function result_array($object = NULL, $type = FALSE); + + /** + * Gets the fields of an already run query. + * + * @return array + */ + abstract public function list_fields(); + + /** + * Seek to an offset in the results. + * + * @return boolean + */ + abstract public function seek($offset); + + /** + * Countable: count + */ + public function count() + { + return $this->total_rows; + } + + /** + * ArrayAccess: offsetExists + */ + public function offsetExists($offset) + { + if ($this->total_rows > 0) + { + $min = 0; + $max = $this->total_rows - 1; + + return ! ($offset < $min OR $offset > $max); + } + + return FALSE; + } + + /** + * ArrayAccess: offsetGet + */ + public function offsetGet($offset) + { + if ( ! $this->seek($offset)) + return FALSE; + + // Return the row by calling the defined fetching callback + return call_user_func($this->fetch_type, $this->result, $this->return_type); + } + + /** + * ArrayAccess: offsetSet + * + * @throws Kohana_Database_Exception + */ + final public function offsetSet($offset, $value) + { + throw new Kohana_Database_Exception('database.result_read_only'); + } + + /** + * ArrayAccess: offsetUnset + * + * @throws Kohana_Database_Exception + */ + final public function offsetUnset($offset) + { + throw new Kohana_Database_Exception('database.result_read_only'); + } + + /** + * Iterator: current + */ + public function current() + { + return $this->offsetGet($this->current_row); + } + + /** + * Iterator: key + */ + public function key() + { + return $this->current_row; + } + + /** + * Iterator: next + */ + public function next() + { + ++$this->current_row; + return $this; + } + + /** + * Iterator: prev + */ + public function prev() + { + --$this->current_row; + return $this; + } + + /** + * Iterator: rewind + */ + public function rewind() + { + $this->current_row = 0; + return $this; + } + + /** + * Iterator: valid + */ + public function valid() + { + return $this->offsetExists($this->current_row); + } + +} // End Database Result Interface diff --git a/lib/kohana/system/libraries/drivers/Database/Mssql.php b/lib/kohana/system/libraries/drivers/Database/Mssql.php new file mode 100644 index 0000000..8b5ed50 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Database/Mssql.php @@ -0,0 +1,462 @@ +db_config = $config; + + Kohana::log('debug', 'MSSQL Database Driver Initialized'); + } + + /** + * Closes the database connection. + */ + public function __destruct() + { + is_resource($this->link) and mssql_close($this->link); + } + + /** + * Make the connection + * + * @return return connection + */ + public function connect() + { + // Check if link already exists + if (is_resource($this->link)) + return $this->link; + + // Import the connect variables + extract($this->db_config['connection']); + + // Persistent connections enabled? + $connect = ($this->db_config['persistent'] == TRUE) ? 'mssql_pconnect' : 'mssql_connect'; + + // Build the connection info + $host = isset($host) ? $host : $socket; + + // Windows uses a comma instead of a colon + $port = (isset($port) AND is_string($port)) ? (KOHANA_IS_WIN ? ',' : ':').$port : ''; + + // Make the connection and select the database + if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mssql_select_db($database, $this->link)) + { + /* This is being removed so I can use it, will need to come up with a more elegant workaround in the future... + * + if ($charset = $this->db_config['character_set']) + { + $this->set_charset($charset); + } + */ + + // Clear password after successful connect + $this->db_config['connection']['pass'] = NULL; + + return $this->link; + } + + return FALSE; + } + + public function query($sql) + { + // Only cache if it's turned on, and only cache if it's not a write statement + if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql)) + { + $hash = $this->query_hash($sql); + + if ( ! isset($this->query_cache[$hash])) + { + // Set the cached object + $this->query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); + } + else + { + // Rewind cached result + $this->query_cache[$hash]->rewind(); + } + + // Return the cached query + return $this->query_cache[$hash]; + } + + return new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); + } + + public function escape_table($table) + { + if (stripos($table, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $table = str_ireplace(' AS ', ' AS ', $table); + + // Runs escape_table on both sides of an AS statement + $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); + + // Re-create the AS statement + return implode(' AS ', $table); + } + return '['.str_replace('.', '[.]', $table).']'; + } + + public function escape_column($column) + { + if (!$this->db_config['escape']) + return $column; + + if ($column == '*') + return $column; + + // This matches any functions we support to SELECT. + if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) + { + if ( count($matches) == 3) + { + return $matches[1].'('.$this->escape_column($matches[2]).')'; + } + else if ( count($matches) == 5) + { + return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); + } + } + + // This matches any modifiers we support to SELECT. + if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) + { + if (stripos($column, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $column = str_ireplace(' AS ', ' AS ', $column); + + // Runs escape_column on both sides of an AS statement + $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); + + // Re-create the AS statement + return implode(' AS ', $column); + } + + return preg_replace('/[^.*]+/', '[$0]', $column); + } + + $parts = explode(' ', $column); + $column = ''; + + for ($i = 0, $c = count($parts); $i < $c; $i++) + { + // The column is always last + if ($i == ($c - 1)) + { + $column .= preg_replace('/[^.*]+/', '[$0]', $parts[$i]); + } + else // otherwise, it's a modifier + { + $column .= $parts[$i].' '; + } + } + return $column; + } + + /** + * Limit in SQL Server 2000 only uses the keyword + * 'TOP'; 2007 may have an offset keyword, but + * I am unsure - for pagination style limit,offset + * functionality, a fancy query needs to be built. + * + * @param unknown_type $limit + * @return unknown + */ + public function limit($limit, $offset=null) + { + return 'TOP '.$limit; + } + + public function compile_select($database) + { + $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; + $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; + + if (count($database['from']) > 0) + { + // Escape the tables + $froms = array(); + foreach ($database['from'] as $from) + $froms[] = $this->escape_column($from); + $sql .= "\nFROM "; + $sql .= implode(', ', $froms); + } + + if (count($database['join']) > 0) + { + foreach($database['join'] AS $join) + { + $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; + } + } + + if (count($database['where']) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $database['where']); + + if (count($database['groupby']) > 0) + { + $sql .= "\nGROUP BY "; + $sql .= implode(', ', $database['groupby']); + } + + if (count($database['having']) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $database['having']); + } + + if (count($database['orderby']) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $database['orderby']); + } + + if (is_numeric($database['limit'])) + { + $sql .= "\n"; + $sql .= $this->limit($database['limit']); + } + + return $sql; + } + + public function escape_str($str) + { + if (!$this->db_config['escape']) + return $str; + + is_resource($this->link) or $this->connect(); + //mssql_real_escape_string($str, $this->link); <-- this function doesn't exist + + $characters = array('/\x00/', '/\x1a/', '/\n/', '/\r/', '/\\\/', '/\'/'); + $replace = array('\\\x00', '\\x1a', '\\n', '\\r', '\\\\', "''"); + return preg_replace($characters, $replace, $str); + } + + public function list_tables() + { + $sql = 'SHOW TABLES FROM ['.$this->db_config['connection']['database'].']'; + $result = $this->query($sql)->result(FALSE, MSSQL_ASSOC); + + $retval = array(); + foreach ($result as $row) + { + $retval[] = current($row); + } + + return $retval; + } + + public function show_error() + { + return mssql_get_last_message($this->link); + } + + public function list_fields($table) + { + $result = array(); + + foreach ($this->field_data($table) as $row) + { + // Make an associative array + $result[$row->Field] = $this->sql_type($row->Type); + } + + return $result; + } + + public function field_data($table) + { + $query = $this->query("SELECT COLUMN_NAME AS Field, DATA_TYPE as Type FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->escape_table($table)."'", $this->link); + + return $query->result_array(TRUE); + } +} + +/** + * MSSQL Result + */ +class Mssql_Result extends Database_Result { + + // Fetch function and return type + protected $fetch_type = 'mssql_fetch_object'; + protected $return_type = MSSQL_ASSOC; + + /** + * Sets up the result variables. + * + * @param resource query result + * @param resource database link + * @param boolean return objects or arrays + * @param string SQL query that was run + */ + public function __construct($result, $link, $object = TRUE, $sql) + { + $this->result = $result; + + // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query + if (is_resource($result)) + { + $this->current_row = 0; + $this->total_rows = mssql_num_rows($this->result); + $this->fetch_type = ($object === TRUE) ? 'mssql_fetch_object' : 'mssql_fetch_array'; + } + elseif (is_bool($result)) + { + if ($result == FALSE) + { + // SQL error + throw new Kohana_Database_Exception('database.error', mssql_get_last_message($link).' - '.$sql); + } + else + { + // Its an DELETE, INSERT, REPLACE, or UPDATE querys + $last_id = mssql_query('SELECT @@IDENTITY AS last_id', $link); + $result = mssql_fetch_assoc($last_id); + $this->insert_id = $result['last_id']; + $this->total_rows = mssql_rows_affected($link); + } + } + + // Set result type + $this->result($object); + + // Store the SQL + $this->sql = $sql; + } + + /** + * Destruct, the cleanup crew! + */ + public function __destruct() + { + if (is_resource($this->result)) + { + mssql_free_result($this->result); + } + } + + public function result($object = TRUE, $type = MSSQL_ASSOC) + { + $this->fetch_type = ((bool) $object) ? 'mssql_fetch_object' : 'mssql_fetch_array'; + + // This check has to be outside the previous statement, because we do not + // know the state of fetch_type when $object = NULL + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + if ($this->fetch_type == 'mssql_fetch_object') + { + $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $this->return_type = $type; + } + + return $this; + } + + public function as_array($object = NULL, $type = MSSQL_ASSOC) + { + return $this->result_array($object, $type); + } + + public function result_array($object = NULL, $type = MSSQL_ASSOC) + { + $rows = array(); + + if (is_string($object)) + { + $fetch = $object; + } + elseif (is_bool($object)) + { + if ($object === TRUE) + { + $fetch = 'mssql_fetch_object'; + + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $fetch = 'mssql_fetch_array'; + } + } + else + { + // Use the default config values + $fetch = $this->fetch_type; + + if ($fetch == 'mssql_fetch_object') + { + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + } + + if (mssql_num_rows($this->result)) + { + // Reset the pointer location to make sure things work properly + mssql_data_seek($this->result, 0); + + while ($row = $fetch($this->result, $type)) + { + $rows[] = $row; + } + } + + return isset($rows) ? $rows : array(); + } + + public function list_fields() + { + $field_names = array(); + while ($field = mssql_fetch_field($this->result)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + public function seek($offset) + { + if ( ! $this->offsetExists($offset)) + return FALSE; + + return mssql_data_seek($this->result, $offset); + } + +} // End mssql_Result Class diff --git a/lib/kohana/system/libraries/drivers/Database/Mysql.php b/lib/kohana/system/libraries/drivers/Database/Mysql.php new file mode 100644 index 0000000..d5222f5 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Database/Mysql.php @@ -0,0 +1,496 @@ +db_config = $config; + + Kohana::log('debug', 'MySQL Database Driver Initialized'); + } + + /** + * Closes the database connection. + */ + public function __destruct() + { + is_resource($this->link) and mysql_close($this->link); + } + + public function connect() + { + // Check if link already exists + if (is_resource($this->link)) + return $this->link; + + // Import the connect variables + extract($this->db_config['connection']); + + // Persistent connections enabled? + $connect = ($this->db_config['persistent'] == TRUE) ? 'mysql_pconnect' : 'mysql_connect'; + + // Build the connection info + $host = isset($host) ? $host : $socket; + $port = isset($port) ? ':'.$port : ''; + + // Make the connection and select the database + if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mysql_select_db($database, $this->link)) + { + if ($charset = $this->db_config['character_set']) + { + $this->set_charset($charset); + } + + // Clear password after successful connect + $this->db_config['connection']['pass'] = NULL; + + return $this->link; + } + + return FALSE; + } + + public function query($sql) + { + // Only cache if it's turned on, and only cache if it's not a write statement + if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) + { + $hash = $this->query_hash($sql); + + if ( ! isset($this->query_cache[$hash])) + { + // Set the cached object + $this->query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); + } + else + { + // Rewind cached result + $this->query_cache[$hash]->rewind(); + } + + // Return the cached query + return $this->query_cache[$hash]; + } + + return new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); + } + + public function set_charset($charset) + { + $this->query('SET NAMES '.$this->escape_str($charset)); + } + + public function escape_table($table) + { + if (!$this->db_config['escape']) + return $table; + + if (stripos($table, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $table = str_ireplace(' AS ', ' AS ', $table); + + // Runs escape_table on both sides of an AS statement + $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); + + // Re-create the AS statement + return implode(' AS ', $table); + } + return '`'.str_replace('.', '`.`', $table).'`'; + } + + public function escape_column($column) + { + if (!$this->db_config['escape']) + return $column; + + if ($column == '*') + return $column; + + // This matches any functions we support to SELECT. + if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) + { + if ( count($matches) == 3) + { + return $matches[1].'('.$this->escape_column($matches[2]).')'; + } + else if ( count($matches) == 5) + { + return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); + } + } + + // This matches any modifiers we support to SELECT. + if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) + { + if (stripos($column, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $column = str_ireplace(' AS ', ' AS ', $column); + + // Runs escape_column on both sides of an AS statement + $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); + + // Re-create the AS statement + return implode(' AS ', $column); + } + + return preg_replace('/[^.*]+/', '`$0`', $column); + } + + $parts = explode(' ', $column); + $column = ''; + + for ($i = 0, $c = count($parts); $i < $c; $i++) + { + // The column is always last + if ($i == ($c - 1)) + { + $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); + } + else // otherwise, it's a modifier + { + $column .= $parts[$i].' '; + } + } + return $column; + } + + public function regex($field, $match, $type, $num_regexs) + { + $prefix = ($num_regexs == 0) ? '' : $type; + + return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\''; + } + + public function notregex($field, $match, $type, $num_regexs) + { + $prefix = $num_regexs == 0 ? '' : $type; + + return $prefix.' '.$this->escape_column($field).' NOT REGEXP \''.$this->escape_str($match) . '\''; + } + + public function merge($table, $keys, $values) + { + // Escape the column names + foreach ($keys as $key => $value) + { + $keys[$key] = $this->escape_column($value); + } + return 'REPLACE INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; + } + + public function limit($limit, $offset = 0) + { + return 'LIMIT '.$offset.', '.$limit; + } + + public function compile_select($database) + { + $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; + $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; + + if (count($database['from']) > 0) + { + // Escape the tables + $froms = array(); + foreach ($database['from'] as $from) + { + $froms[] = $this->escape_column($from); + } + $sql .= "\nFROM ("; + $sql .= implode(', ', $froms).")"; + } + + if (count($database['join']) > 0) + { + foreach($database['join'] AS $join) + { + $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; + } + } + + if (count($database['where']) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $database['where']); + + if (count($database['groupby']) > 0) + { + $sql .= "\nGROUP BY "; + $sql .= implode(', ', $database['groupby']); + } + + if (count($database['having']) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $database['having']); + } + + if (count($database['orderby']) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $database['orderby']); + } + + if (is_numeric($database['limit'])) + { + $sql .= "\n"; + $sql .= $this->limit($database['limit'], $database['offset']); + } + + return $sql; + } + + public function escape_str($str) + { + if (!$this->db_config['escape']) + return $str; + + is_resource($this->link) or $this->connect(); + + return mysql_real_escape_string($str, $this->link); + } + + public function list_tables() + { + $tables = array(); + + if ($query = $this->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database']))) + { + foreach ($query->result(FALSE) as $row) + { + $tables[] = current($row); + } + } + + return $tables; + } + + public function show_error() + { + return mysql_error($this->link); + } + + public function list_fields($table) + { + $result = NULL; + + foreach ($this->field_data($table) as $row) + { + // Make an associative array + $result[$row->Field] = $this->sql_type($row->Type); + + if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment') + { + // For sequenced (AUTO_INCREMENT) tables + $result[$row->Field]['sequenced'] = TRUE; + } + + if ($row->Null === 'YES') + { + // Set NULL status + $result[$row->Field]['null'] = TRUE; + } + } + + if (!isset($result)) + throw new Kohana_Database_Exception('database.table_not_found', $table); + + return $result; + } + + public function field_data($table) + { + $result = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table)); + + return $result->result_array(TRUE); + } + +} // End Database_Mysql_Driver Class + +/** + * MySQL Result + */ +class Mysql_Result extends Database_Result { + + // Fetch function and return type + protected $fetch_type = 'mysql_fetch_object'; + protected $return_type = MYSQL_ASSOC; + + /** + * Sets up the result variables. + * + * @param resource query result + * @param resource database link + * @param boolean return objects or arrays + * @param string SQL query that was run + */ + public function __construct($result, $link, $object = TRUE, $sql) + { + $this->result = $result; + + // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query + if (is_resource($result)) + { + $this->current_row = 0; + $this->total_rows = mysql_num_rows($this->result); + $this->fetch_type = ($object === TRUE) ? 'mysql_fetch_object' : 'mysql_fetch_array'; + } + elseif (is_bool($result)) + { + if ($result == FALSE) + { + // SQL error + throw new Kohana_Database_Exception('database.error', mysql_error($link).' - '.$sql); + } + else + { + // Its an DELETE, INSERT, REPLACE, or UPDATE query + $this->insert_id = mysql_insert_id($link); + $this->total_rows = mysql_affected_rows($link); + } + } + + // Set result type + $this->result($object); + + // Store the SQL + $this->sql = $sql; + } + + /** + * Destruct, the cleanup crew! + */ + public function __destruct() + { + if (is_resource($this->result)) + { + mysql_free_result($this->result); + } + } + + public function result($object = TRUE, $type = MYSQL_ASSOC) + { + $this->fetch_type = ((bool) $object) ? 'mysql_fetch_object' : 'mysql_fetch_array'; + + // This check has to be outside the previous statement, because we do not + // know the state of fetch_type when $object = NULL + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + if ($this->fetch_type == 'mysql_fetch_object' AND $object === TRUE) + { + $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $this->return_type = $type; + } + + return $this; + } + + public function as_array($object = NULL, $type = MYSQL_ASSOC) + { + return $this->result_array($object, $type); + } + + public function result_array($object = NULL, $type = MYSQL_ASSOC) + { + $rows = array(); + + if (is_string($object)) + { + $fetch = $object; + } + elseif (is_bool($object)) + { + if ($object === TRUE) + { + $fetch = 'mysql_fetch_object'; + + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $fetch = 'mysql_fetch_array'; + } + } + else + { + // Use the default config values + $fetch = $this->fetch_type; + + if ($fetch == 'mysql_fetch_object') + { + $type = (is_string($this->return_type) AND Kohana::auto_load($this->return_type)) ? $this->return_type : 'stdClass'; + } + } + + if (mysql_num_rows($this->result)) + { + // Reset the pointer location to make sure things work properly + mysql_data_seek($this->result, 0); + + while ($row = $fetch($this->result, $type)) + { + $rows[] = $row; + } + } + + return isset($rows) ? $rows : array(); + } + + public function list_fields() + { + $field_names = array(); + while ($field = mysql_fetch_field($this->result)) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + public function seek($offset) + { + if ($this->offsetExists($offset) AND mysql_data_seek($this->result, $offset)) + { + // Set the current row to the offset + $this->current_row = $offset; + + return TRUE; + } + else + { + return FALSE; + } + } + +} // End Mysql_Result Class diff --git a/lib/kohana/system/libraries/drivers/Database/Mysqli.php b/lib/kohana/system/libraries/drivers/Database/Mysqli.php new file mode 100644 index 0000000..0dd9f05 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Database/Mysqli.php @@ -0,0 +1,358 @@ +db_config = $config; + + Kohana::log('debug', 'MySQLi Database Driver Initialized'); + } + + /** + * Closes the database connection. + */ + public function __destruct() + { + is_object($this->link) and $this->link->close(); + } + + public function connect() + { + // Check if link already exists + if (is_object($this->link)) + return $this->link; + + // Import the connect variables + extract($this->db_config['connection']); + + // Build the connection info + $host = isset($host) ? $host : $socket; + + // Make the connection and select the database + if ($this->link = new mysqli($host, $user, $pass, $database, $port)) + { + if ($charset = $this->db_config['character_set']) + { + $this->set_charset($charset); + } + + // Clear password after successful connect + $this->db_config['connection']['pass'] = NULL; + + return $this->link; + } + + return FALSE; + } + + public function query($sql) + { + // Only cache if it's turned on, and only cache if it's not a write statement + if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) + { + $hash = $this->query_hash($sql); + + if ( ! isset($this->query_cache[$hash])) + { + // Set the cached object + $this->query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); + } + else + { + // Rewind cached result + $this->query_cache[$hash]->rewind(); + } + + // Return the cached query + return $this->query_cache[$hash]; + } + + return new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); + } + + public function set_charset($charset) + { + if ($this->link->set_charset($charset) === FALSE) + throw new Kohana_Database_Exception('database.error', $this->show_error()); + } + + public function escape_str($str) + { + if (!$this->db_config['escape']) + return $str; + + is_object($this->link) or $this->connect(); + + return $this->link->real_escape_string($str); + } + + public function show_error() + { + return $this->link->error; + } + +} // End Database_Mysqli_Driver Class + +/** + * MySQLi Result + */ +class Kohana_Mysqli_Result extends Database_Result { + + // Database connection + protected $link; + + // Data fetching types + protected $fetch_type = 'mysqli_fetch_object'; + protected $return_type = MYSQLI_ASSOC; + + /** + * Sets up the result variables. + * + * @param object database link + * @param boolean return objects or arrays + * @param string SQL query that was run + */ + public function __construct($link, $object = TRUE, $sql) + { + $this->link = $link; + + if ( ! $this->link->multi_query($sql)) + { + // SQL error + throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); + } + else + { + $this->result = $this->link->store_result(); + + // If the query is an object, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query + if (is_object($this->result)) + { + $this->current_row = 0; + $this->total_rows = $this->result->num_rows; + $this->fetch_type = ($object === TRUE) ? 'fetch_object' : 'fetch_array'; + } + elseif ($this->link->error) + { + // SQL error + throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); + } + else + { + // Its an DELETE, INSERT, REPLACE, or UPDATE query + $this->insert_id = $this->link->insert_id; + $this->total_rows = $this->link->affected_rows; + } + } + + // Set result type + $this->result($object); + + // Store the SQL + $this->sql = $sql; + } + + /** + * Magic __destruct function, frees the result. + */ + public function __destruct() + { + if (is_object($this->result)) + { + $this->result->free_result(); + + // this is kinda useless, but needs to be done to avoid the "Commands out of sync; you + // can't run this command now" error. Basically, we get all results after the first one + // (the one we actually need) and free them. + if (is_resource($this->link) AND $this->link->more_results()) + { + do + { + if ($result = $this->link->store_result()) + { + $result->free_result(); + } + } while ($this->link->next_result()); + } + } + } + + public function result($object = TRUE, $type = MYSQLI_ASSOC) + { + $this->fetch_type = ((bool) $object) ? 'fetch_object' : 'fetch_array'; + + // This check has to be outside the previous statement, because we do not + // know the state of fetch_type when $object = NULL + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + if ($this->fetch_type == 'fetch_object') + { + $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $this->return_type = $type; + } + + return $this; + } + + public function as_array($object = NULL, $type = MYSQLI_ASSOC) + { + return $this->result_array($object, $type); + } + + public function result_array($object = NULL, $type = MYSQLI_ASSOC) + { + $rows = array(); + + if (is_string($object)) + { + $fetch = $object; + } + elseif (is_bool($object)) + { + if ($object === TRUE) + { + $fetch = 'fetch_object'; + + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $fetch = 'fetch_array'; + } + } + else + { + // Use the default config values + $fetch = $this->fetch_type; + + if ($fetch == 'fetch_object') + { + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + } + + if ($this->result->num_rows) + { + // Reset the pointer location to make sure things work properly + $this->result->data_seek(0); + + while ($row = $this->result->$fetch($type)) + { + $rows[] = $row; + } + } + + return isset($rows) ? $rows : array(); + } + + public function list_fields() + { + $field_names = array(); + while ($field = $this->result->fetch_field()) + { + $field_names[] = $field->name; + } + + return $field_names; + } + + public function seek($offset) + { + if ($this->offsetExists($offset) AND $this->result->data_seek($offset)) + { + // Set the current row to the offset + $this->current_row = $offset; + + return TRUE; + } + + return FALSE; + } + + public function offsetGet($offset) + { + if ( ! $this->seek($offset)) + return FALSE; + + // Return the row + $fetch = $this->fetch_type; + return $this->result->$fetch($this->return_type); + } + +} // End Mysqli_Result Class + +/** + * MySQLi Prepared Statement (experimental) + */ +class Kohana_Mysqli_Statement { + + protected $link = NULL; + protected $stmt; + protected $var_names = array(); + protected $var_values = array(); + + public function __construct($sql, $link) + { + $this->link = $link; + + $this->stmt = $this->link->prepare($sql); + + return $this; + } + + public function __destruct() + { + $this->stmt->close(); + } + + // Sets the bind parameters + public function bind_params($param_types, $params) + { + $this->var_names = array_keys($params); + $this->var_values = array_values($params); + call_user_func_array(array($this->stmt, 'bind_param'), array_merge($param_types, $var_names)); + + return $this; + } + + public function bind_result($params) + { + call_user_func_array(array($this->stmt, 'bind_result'), $params); + } + + // Runs the statement + public function execute() + { + foreach ($this->var_names as $key => $name) + { + $$name = $this->var_values[$key]; + } + $this->stmt->execute(); + return $this->stmt; + } +} diff --git a/lib/kohana/system/libraries/drivers/Database/Pdosqlite.php b/lib/kohana/system/libraries/drivers/Database/Pdosqlite.php new file mode 100644 index 0000000..c2d1bb2 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Database/Pdosqlite.php @@ -0,0 +1,486 @@ + + */ + +class Database_Pdosqlite_Driver extends Database_Driver { + + // Database connection link + protected $link; + protected $db_config; + + /* + * Constructor: __construct + * Sets up the config for the class. + * + * Parameters: + * config - database configuration + * + */ + public function __construct($config) + { + $this->db_config = $config; + + Kohana::log('debug', 'PDO:Sqlite Database Driver Initialized'); + } + + public function connect() + { + // Import the connect variables + extract($this->db_config['connection']); + + try + { + $this->link = new PDO('sqlite:'.$socket.$database, $user, $pass, + array(PDO::ATTR_PERSISTENT => $this->db_config['persistent'])); + + $this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); + //$this->link->query('PRAGMA count_changes=1;'); + + if ($charset = $this->db_config['character_set']) + { + $this->set_charset($charset); + } + } + catch (PDOException $e) + { + throw new Kohana_Database_Exception('database.error', $e->getMessage()); + } + + // Clear password after successful connect + $this->db_config['connection']['pass'] = NULL; + + return $this->link; + } + + public function query($sql) + { + try + { + $sth = $this->link->prepare($sql); + } + catch (PDOException $e) + { + throw new Kohana_Database_Exception('database.error', $e->getMessage()); + } + return new Pdosqlite_Result($sth, $this->link, $this->db_config['object'], $sql); + } + + public function set_charset($charset) + { + $this->link->query('PRAGMA encoding = '.$this->escape_str($charset)); + } + + public function escape_table($table) + { + if ( ! $this->db_config['escape']) + return $table; + + return '`'.str_replace('.', '`.`', $table).'`'; + } + + public function escape_column($column) + { + if ( ! $this->db_config['escape']) + return $column; + + if ($column == '*') + return $column; + + // This matches any functions we support to SELECT. + if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) + { + if ( count($matches) == 3) + { + return $matches[1].'('.$this->escape_column($matches[2]).')'; + } + else if ( count($matches) == 5) + { + return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); + } + } + + // This matches any modifiers we support to SELECT. + if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) + { + if (stripos($column, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $column = str_ireplace(' AS ', ' AS ', $column); + + // Runs escape_column on both sides of an AS statement + $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); + + // Re-create the AS statement + return implode(' AS ', $column); + } + + return preg_replace('/[^.*]+/', '`$0`', $column); + } + + $parts = explode(' ', $column); + $column = ''; + + for ($i = 0, $c = count($parts); $i < $c; $i++) + { + // The column is always last + if ($i == ($c - 1)) + { + $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); + } + else // otherwise, it's a modifier + { + $column .= $parts[$i].' '; + } + } + return $column; + } + + public function limit($limit, $offset = 0) + { + return 'LIMIT '.$offset.', '.$limit; + } + + public function compile_select($database) + { + $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; + $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; + + if (count($database['from']) > 0) + { + $sql .= "\nFROM "; + $sql .= implode(', ', $database['from']); + } + + if (count($database['join']) > 0) + { + foreach($database['join'] AS $join) + { + $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; + } + } + + if (count($database['where']) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $database['where']); + + if (count($database['groupby']) > 0) + { + $sql .= "\nGROUP BY "; + $sql .= implode(', ', $database['groupby']); + } + + if (count($database['having']) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $database['having']); + } + + if (count($database['orderby']) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $database['orderby']); + } + + if (is_numeric($database['limit'])) + { + $sql .= "\n"; + $sql .= $this->limit($database['limit'], $database['offset']); + } + + return $sql; + } + + public function escape_str($str) + { + if ( ! $this->db_config['escape']) + return $str; + + if (function_exists('sqlite_escape_string')) + { + $res = sqlite_escape_string($str); + } + else + { + $res = str_replace("'", "''", $str); + } + return $res; + } + + public function list_tables() + { + $sql = "SELECT `name` FROM `sqlite_master` WHERE `type`='table' ORDER BY `name`;"; + try + { + $result = $this->query($sql)->result(FALSE, PDO::FETCH_ASSOC); + $tables = array(); + foreach ($result as $row) + { + $tables[] = current($row); + } + } + catch (PDOException $e) + { + throw new Kohana_Database_Exception('database.error', $e->getMessage()); + } + return $tables; + } + + public function show_error() + { + $err = $this->link->errorInfo(); + return isset($err[2]) ? $err[2] : 'Unknown error!'; + } + + public function list_fields($table, $query = FALSE) + { + static $tables; + if (is_object($query)) + { + if (empty($tables[$table])) + { + $tables[$table] = array(); + + foreach ($query->result() as $row) + { + $tables[$table][] = $row->name; + } + } + + return $tables[$table]; + } + else + { + $result = $this->link->query( 'PRAGMA table_info('.$this->escape_table($table).')' ); + + foreach ($result as $row) + { + $tables[$table][$row['name']] = $this->sql_type($row['type']); + } + + return $tables[$table]; + } + } + + public function field_data($table) + { + Kohana::log('error', 'This method is under developing'); + } + /** + * Version number query string + * + * @access public + * @return string + */ + function version() + { + return $this->link->getAttribute(constant("PDO::ATTR_SERVER_VERSION")); + } + +} // End Database_PdoSqlite_Driver Class + +/* + * PDO-sqlite Result + */ +class Pdosqlite_Result extends Database_Result { + + // Data fetching types + protected $fetch_type = PDO::FETCH_OBJ; + protected $return_type = PDO::FETCH_ASSOC; + + /** + * Sets up the result variables. + * + * @param resource query result + * @param resource database link + * @param boolean return objects or arrays + * @param string SQL query that was run + */ + public function __construct($result, $link, $object = TRUE, $sql) + { + if (is_object($result) OR $result = $link->prepare($sql)) + { + // run the query. Return true if success, false otherwise + if( ! $result->execute()) + { + // Throw Kohana Exception with error message. See PDOStatement errorInfo() method + $arr_infos = $result->errorInfo(); + throw new Kohana_Database_Exception('database.error', $arr_infos[2]); + } + + if (preg_match('/^SELECT|PRAGMA|EXPLAIN/i', $sql)) + { + $this->result = $result; + $this->current_row = 0; + + $this->total_rows = $this->sqlite_row_count(); + + $this->fetch_type = ($object === TRUE) ? PDO::FETCH_OBJ : PDO::FETCH_ASSOC; + } + elseif (preg_match('/^DELETE|INSERT|UPDATE/i', $sql)) + { + $this->insert_id = $link->lastInsertId(); + + $this->total_rows = $result->rowCount(); + } + } + else + { + // SQL error + throw new Kohana_Database_Exception('database.error', $link->errorInfo().' - '.$sql); + } + + // Set result type + $this->result($object); + + // Store the SQL + $this->sql = $sql; + } + + private function sqlite_row_count() + { + $count = 0; + while ($this->result->fetch()) + { + $count++; + } + + // The query must be re-fetched now. + $this->result->execute(); + + return $count; + } + + /* + * Destructor: __destruct + * Magic __destruct function, frees the result. + */ + public function __destruct() + { + if (is_object($this->result)) + { + $this->result->closeCursor(); + $this->result = NULL; + } + } + + public function result($object = TRUE, $type = PDO::FETCH_BOTH) + { + $this->fetch_type = (bool) $object ? PDO::FETCH_OBJ : PDO::FETCH_BOTH; + + if ($this->fetch_type == PDO::FETCH_OBJ) + { + $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $this->return_type = $type; + } + + return $this; + } + + public function as_array($object = NULL, $type = PDO::FETCH_ASSOC) + { + return $this->result_array($object, $type); + } + + public function result_array($object = NULL, $type = PDO::FETCH_ASSOC) + { + $rows = array(); + + if (is_string($object)) + { + $fetch = $object; + } + elseif (is_bool($object)) + { + if ($object === TRUE) + { + $fetch = PDO::FETCH_OBJ; + + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $fetch = PDO::FETCH_OBJ; + } + } + else + { + // Use the default config values + $fetch = $this->fetch_type; + + if ($fetch == PDO::FETCH_OBJ) + { + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + } + try + { + while ($row = $this->result->fetch($fetch)) + { + $rows[] = $row; + } + } + catch(PDOException $e) + { + throw new Kohana_Database_Exception('database.error', $e->getMessage()); + return FALSE; + } + return $rows; + } + + public function list_fields() + { + $field_names = array(); + for ($i = 0, $max = $this->result->columnCount(); $i < $max; $i++) + { + $info = $this->result->getColumnMeta($i); + $field_names[] = $info['name']; + } + return $field_names; + } + + public function seek($offset) + { + // To request a scrollable cursor for your PDOStatement object, you must + // set the PDO::ATTR_CURSOR attribute to PDO::CURSOR_SCROLL when you + // prepare the statement. + Kohana::log('error', get_class($this).' does not support scrollable cursors, '.__FUNCTION__.' call ignored'); + + return FALSE; + } + + public function offsetGet($offset) + { + try + { + return $this->result->fetch($this->fetch_type, PDO::FETCH_ORI_ABS, $offset); + } + catch(PDOException $e) + { + throw new Kohana_Database_Exception('database.error', $e->getMessage()); + } + } + + public function rewind() + { + // Same problem that seek() has, see above. + return $this->seek(0); + } + +} // End PdoSqlite_Result Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Database/Pgsql.php b/lib/kohana/system/libraries/drivers/Database/Pgsql.php new file mode 100644 index 0000000..c53c843 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Database/Pgsql.php @@ -0,0 +1,538 @@ +db_config = $config; + + Kohana::log('debug', 'PgSQL Database Driver Initialized'); + } + + public function connect() + { + // Check if link already exists + if (is_resource($this->link)) + return $this->link; + + // Import the connect variables + extract($this->db_config['connection']); + + // Persistent connections enabled? + $connect = ($this->db_config['persistent'] == TRUE) ? 'pg_pconnect' : 'pg_connect'; + + // Build the connection info + $port = isset($port) ? 'port=\''.$port.'\'' : ''; + $host = isset($host) ? 'host=\''.$host.'\' '.$port : ''; // if no host, connect with the socket + + $connection_string = $host.' dbname=\''.$database.'\' user=\''.$user.'\' password=\''.$pass.'\''; + // Make the connection and select the database + if ($this->link = $connect($connection_string)) + { + if ($charset = $this->db_config['character_set']) + { + echo $this->set_charset($charset); + } + + // Clear password after successful connect + $this->db_config['connection']['pass'] = NULL; + + return $this->link; + } + + return FALSE; + } + + public function query($sql) + { + // Only cache if it's turned on, and only cache if it's not a write statement + if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|SET)\b#i', $sql)) + { + $hash = $this->query_hash($sql); + + if ( ! isset($this->query_cache[$hash])) + { + // Set the cached object + $this->query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); + } + else + { + // Rewind cached result + $this->query_cache[$hash]->rewind(); + } + + return $this->query_cache[$hash]; + } + + // Suppress warning triggered when a database error occurs (e.g., a constraint violation) + return new Pgsql_Result(@pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); + } + + public function set_charset($charset) + { + $this->query('SET client_encoding TO '.pg_escape_string($this->link, $charset)); + } + + public function escape_table($table) + { + if (!$this->db_config['escape']) + return $table; + + return '"'.str_replace('.', '"."', $table).'"'; + } + + public function escape_column($column) + { + if (!$this->db_config['escape']) + return $column; + + if ($column == '*') + return $column; + + // This matches any functions we support to SELECT. + if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) + { + if ( count($matches) == 3) + { + return $matches[1].'('.$this->escape_column($matches[2]).')'; + } + else if ( count($matches) == 5) + { + return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); + } + } + + // This matches any modifiers we support to SELECT. + if ( ! preg_match('/\b(?:all|distinct)\s/i', $column)) + { + if (stripos($column, ' AS ') !== FALSE) + { + // Force 'AS' to uppercase + $column = str_ireplace(' AS ', ' AS ', $column); + + // Runs escape_column on both sides of an AS statement + $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); + + // Re-create the AS statement + return implode(' AS ', $column); + } + + return preg_replace('/[^.*]+/', '"$0"', $column); + } + + $parts = explode(' ', $column); + $column = ''; + + for ($i = 0, $c = count($parts); $i < $c; $i++) + { + // The column is always last + if ($i == ($c - 1)) + { + $column .= preg_replace('/[^.*]+/', '"$0"', $parts[$i]); + } + else // otherwise, it's a modifier + { + $column .= $parts[$i].' '; + } + } + return $column; + } + + public function regex($field, $match, $type, $num_regexs) + { + $prefix = ($num_regexs == 0) ? '' : $type; + + return $prefix.' '.$this->escape_column($field).' ~* \''.$this->escape_str($match).'\''; + } + + public function notregex($field, $match, $type, $num_regexs) + { + $prefix = $num_regexs == 0 ? '' : $type; + + return $prefix.' '.$this->escape_column($field).' !~* \''.$this->escape_str($match) . '\''; + } + + public function limit($limit, $offset = 0) + { + return 'LIMIT '.$limit.' OFFSET '.$offset; + } + + public function compile_select($database) + { + $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; + $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; + + if (count($database['from']) > 0) + { + $sql .= "\nFROM "; + $sql .= implode(', ', $database['from']); + } + + if (count($database['join']) > 0) + { + foreach($database['join'] AS $join) + { + $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; + } + } + + if (count($database['where']) > 0) + { + $sql .= "\nWHERE "; + } + + $sql .= implode("\n", $database['where']); + + if (count($database['groupby']) > 0) + { + $sql .= "\nGROUP BY "; + $sql .= implode(', ', $database['groupby']); + } + + if (count($database['having']) > 0) + { + $sql .= "\nHAVING "; + $sql .= implode("\n", $database['having']); + } + + if (count($database['orderby']) > 0) + { + $sql .= "\nORDER BY "; + $sql .= implode(', ', $database['orderby']); + } + + if (is_numeric($database['limit'])) + { + $sql .= "\n"; + $sql .= $this->limit($database['limit'], $database['offset']); + } + + return $sql; + } + + public function escape_str($str) + { + if (!$this->db_config['escape']) + return $str; + + is_resource($this->link) or $this->connect(); + + return pg_escape_string($this->link, $str); + } + + public function list_tables() + { + $sql = 'SELECT table_schema || \'.\' || table_name FROM information_schema.tables WHERE table_schema NOT IN (\'pg_catalog\', \'information_schema\')'; + $result = $this->query($sql)->result(FALSE, PGSQL_ASSOC); + + $retval = array(); + foreach ($result as $row) + { + $retval[] = current($row); + } + + return $retval; + } + + public function show_error() + { + return pg_last_error($this->link); + } + + public function list_fields($table) + { + $result = NULL; + + foreach ($this->field_data($table) as $row) + { + // Make an associative array + $result[$row->column_name] = $this->sql_type($row->data_type); + + if (!strncmp($row->column_default, 'nextval(', 8)) + { + $result[$row->column_name]['sequenced'] = TRUE; + } + + if ($row->is_nullable === 'YES') + { + $result[$row->column_name]['null'] = TRUE; + } + } + + if (!isset($result)) + throw new Kohana_Database_Exception('database.table_not_found', $table); + + return $result; + } + + public function field_data($table) + { + // http://www.postgresql.org/docs/8.3/static/infoschema-columns.html + $result = $this->query(' + SELECT column_name, column_default, is_nullable, data_type, udt_name, + character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale + FROM information_schema.columns + WHERE table_name = \''. $this->escape_str($table) .'\' + ORDER BY ordinal_position + '); + + return $result->result_array(TRUE); + } + +} // End Database_Pgsql_Driver Class + +/** + * PostgreSQL Result + */ +class Pgsql_Result extends Database_Result { + + // Data fetching types + protected $fetch_type = 'pgsql_fetch_object'; + protected $return_type = PGSQL_ASSOC; + + /** + * Sets up the result variables. + * + * @param resource query result + * @param resource database link + * @param boolean return objects or arrays + * @param string SQL query that was run + */ + public function __construct($result, $link, $object = TRUE, $sql) + { + $this->link = $link; + $this->result = $result; + + // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query + if (is_resource($result)) + { + // Its an DELETE, INSERT, REPLACE, or UPDATE query + if (preg_match('/^(?:delete|insert|replace|update)\b/iD', trim($sql), $matches)) + { + $this->insert_id = (strtolower($matches[0]) == 'insert') ? $this->insert_id() : FALSE; + $this->total_rows = pg_affected_rows($this->result); + } + else + { + $this->current_row = 0; + $this->total_rows = pg_num_rows($this->result); + $this->fetch_type = ($object === TRUE) ? 'pg_fetch_object' : 'pg_fetch_array'; + } + } + else + { + throw new Kohana_Database_Exception('database.error', pg_last_error().' - '.$sql); + } + + // Set result type + $this->result($object); + + // Store the SQL + $this->sql = $sql; + } + + /** + * Magic __destruct function, frees the result. + */ + public function __destruct() + { + if (is_resource($this->result)) + { + pg_free_result($this->result); + } + } + + public function result($object = TRUE, $type = PGSQL_ASSOC) + { + $this->fetch_type = ((bool) $object) ? 'pg_fetch_object' : 'pg_fetch_array'; + + // This check has to be outside the previous statement, because we do not + // know the state of fetch_type when $object = NULL + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + if ($this->fetch_type == 'pg_fetch_object') + { + $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $this->return_type = $type; + } + + return $this; + } + + public function as_array($object = NULL, $type = PGSQL_ASSOC) + { + return $this->result_array($object, $type); + } + + public function result_array($object = NULL, $type = PGSQL_ASSOC) + { + $rows = array(); + + if (is_string($object)) + { + $fetch = $object; + } + elseif (is_bool($object)) + { + if ($object === TRUE) + { + $fetch = 'pg_fetch_object'; + + // NOTE - The class set by $type must be defined before fetching the result, + // autoloading is disabled to save a lot of stupid overhead. + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + else + { + $fetch = 'pg_fetch_array'; + } + } + else + { + // Use the default config values + $fetch = $this->fetch_type; + + if ($fetch == 'pg_fetch_object') + { + $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; + } + } + + if ($this->total_rows) + { + pg_result_seek($this->result, 0); + + while ($row = $fetch($this->result, NULL, $type)) + { + $rows[] = $row; + } + } + + return $rows; + } + + public function insert_id() + { + if ($this->insert_id === NULL) + { + $query = 'SELECT LASTVAL() AS insert_id'; + + // Disable error reporting for this, just to silence errors on + // tables that have no serial column. + $ER = error_reporting(0); + + $result = pg_query($this->link, $query); + $insert_id = pg_fetch_array($result, NULL, PGSQL_ASSOC); + + $this->insert_id = $insert_id['insert_id']; + + // Reset error reporting + error_reporting($ER); + } + + return $this->insert_id; + } + + public function seek($offset) + { + if ($this->offsetExists($offset) AND pg_result_seek($this->result, $offset)) + { + // Set the current row to the offset + $this->current_row = $offset; + + return TRUE; + } + + return FALSE; + } + + public function list_fields() + { + $field_names = array(); + + $fields = pg_num_fields($this->result); + for ($i = 0; $i < $fields; ++$i) + { + $field_names[] = pg_field_name($this->result, $i); + } + + return $field_names; + } + + /** + * ArrayAccess: offsetGet + */ + public function offsetGet($offset) + { + if ( ! $this->seek($offset)) + return FALSE; + + // Return the row by calling the defined fetching callback + $fetch = $this->fetch_type; + return $fetch($this->result, NULL, $this->return_type); + } + +} // End Pgsql_Result Class + +/** + * PostgreSQL Prepared Statement (experimental) + */ +class Kohana_Pgsql_Statement { + + protected $link = NULL; + protected $stmt; + + public function __construct($sql, $link) + { + $this->link = $link; + + $this->stmt = $this->link->prepare($sql); + + return $this; + } + + public function __destruct() + { + $this->stmt->close(); + } + + // Sets the bind parameters + public function bind_params() + { + $argv = func_get_args(); + return $this; + } + + // sets the statement values to the bound parameters + public function set_vals() + { + return $this; + } + + // Runs the statement + public function execute() + { + return $this; + } +} diff --git a/lib/kohana/system/libraries/drivers/Image.php b/lib/kohana/system/libraries/drivers/Image.php new file mode 100644 index 0000000..5c4ab1b --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Image.php @@ -0,0 +1,149 @@ + $args) + { + if ( ! $this->$func($args)) + return FALSE; + } + + return TRUE; + } + + /** + * Sanitize and normalize a geometry array based on the temporary image + * width and height. Valid properties are: width, height, top, left. + * + * @param array geometry properties + * @return void + */ + protected function sanitize_geometry( & $geometry) + { + list($width, $height) = $this->properties(); + + // Turn off error reporting + $reporting = error_reporting(0); + + // Width and height cannot exceed current image size + $geometry['width'] = min($geometry['width'], $width); + $geometry['height'] = min($geometry['height'], $height); + + // Set standard coordinates if given, otherwise use pixel values + if ($geometry['top'] === 'center') + { + $geometry['top'] = floor(($height / 2) - ($geometry['height'] / 2)); + } + elseif ($geometry['top'] === 'top') + { + $geometry['top'] = 0; + } + elseif ($geometry['top'] === 'bottom') + { + $geometry['top'] = $height - $geometry['height']; + } + + // Set standard coordinates if given, otherwise use pixel values + if ($geometry['left'] === 'center') + { + $geometry['left'] = floor(($width / 2) - ($geometry['width'] / 2)); + } + elseif ($geometry['left'] === 'left') + { + $geometry['left'] = 0; + } + elseif ($geometry['left'] === 'right') + { + $geometry['left'] = $width - $geometry['height']; + } + + // Restore error reporting + error_reporting($reporting); + } + + /** + * Return the current width and height of the temporary image. This is mainly + * needed for sanitizing the geometry. + * + * @return array width, height + */ + abstract protected function properties(); + + /** + * Process an image with a set of actions. + * + * @param string image filename + * @param array actions to execute + * @param string destination directory path + * @param string destination filename + * @return boolean + */ + abstract public function process($image, $actions, $dir, $file); + + /** + * Flip an image. Valid directions are horizontal and vertical. + * + * @param integer direction to flip + * @return boolean + */ + abstract function flip($direction); + + /** + * Crop an image. Valid properties are: width, height, top, left. + * + * @param array new properties + * @return boolean + */ + abstract function crop($properties); + + /** + * Resize an image. Valid properties are: width, height, and master. + * + * @param array new properties + * @return boolean + */ + abstract public function resize($properties); + + /** + * Rotate an image. Valid amounts are -180 to 180. + * + * @param integer amount to rotate + * @return boolean + */ + abstract public function rotate($amount); + + /** + * Sharpen and image. Valid amounts are 1 to 100. + * + * @param integer amount to sharpen + * @return boolean + */ + abstract public function sharpen($amount); + +} // End Image Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Image/GD.php b/lib/kohana/system/libraries/drivers/Image/GD.php new file mode 100644 index 0000000..b3610b3 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Image/GD.php @@ -0,0 +1,379 @@ +image = $image; + + // Create the GD image resource + $this->tmp_image = $create($image['file']); + + // Get the quality setting from the actions + $quality = arr::remove('quality', $actions); + + if ($status = $this->execute($actions)) + { + // Prevent the alpha from being lost + imagealphablending($this->tmp_image, TRUE); + imagesavealpha($this->tmp_image, TRUE); + + switch ($save) + { + case 'imagejpeg': + // Default the quality to 95 + ($quality === NULL) and $quality = 95; + break; + case 'imagegif': + // Remove the quality setting, GIF doesn't use it + unset($quality); + break; + case 'imagepng': + // Always use a compression level of 9 for PNGs. This does not + // affect quality, it only increases the level of compression! + $quality = 9; + break; + } + + if ($render === FALSE) + { + // Set the status to the save return value, saving with the quality requested + $status = isset($quality) ? $save($this->tmp_image, $dir.$file, $quality) : $save($this->tmp_image, $dir.$file); + } + else + { + // Output the image directly to the browser + switch ($save) + { + case 'imagejpeg': + header('Content-Type: image/jpeg'); + break; + case 'imagegif': + header('Content-Type: image/gif'); + break; + case 'imagepng': + header('Content-Type: image/png'); + break; + } + + $status = isset($quality) ? $save($this->tmp_image, NULL, $quality) : $save($this->tmp_image); + } + + // Destroy the temporary image + imagedestroy($this->tmp_image); + } + + return $status; + } + + public function flip($direction) + { + // Get the current width and height + $width = imagesx($this->tmp_image); + $height = imagesy($this->tmp_image); + + // Create the flipped image + $flipped = $this->imagecreatetransparent($width, $height); + + if ($direction === Image::HORIZONTAL) + { + for ($x = 0; $x < $width; $x++) + { + $status = imagecopy($flipped, $this->tmp_image, $x, 0, $width - $x - 1, 0, 1, $height); + } + } + elseif ($direction === Image::VERTICAL) + { + for ($y = 0; $y < $height; $y++) + { + $status = imagecopy($flipped, $this->tmp_image, 0, $y, 0, $height - $y - 1, $width, 1); + } + } + else + { + // Do nothing + return TRUE; + } + + if ($status === TRUE) + { + // Swap the new image for the old one + imagedestroy($this->tmp_image); + $this->tmp_image = $flipped; + } + + return $status; + } + + public function crop($properties) + { + // Sanitize the cropping settings + $this->sanitize_geometry($properties); + + // Get the current width and height + $width = imagesx($this->tmp_image); + $height = imagesy($this->tmp_image); + + // Create the temporary image to copy to + $img = $this->imagecreatetransparent($properties['width'], $properties['height']); + + // Execute the crop + if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, $properties['left'], $properties['top'], $width, $height, $width, $height)) + { + // Swap the new image for the old one + imagedestroy($this->tmp_image); + $this->tmp_image = $img; + } + + return $status; + } + + public function resize($properties) + { + // Get the current width and height + $width = imagesx($this->tmp_image); + $height = imagesy($this->tmp_image); + + if (substr($properties['width'], -1) === '%') + { + // Recalculate the percentage to a pixel size + $properties['width'] = round($width * (substr($properties['width'], 0, -1) / 100)); + } + + if (substr($properties['height'], -1) === '%') + { + // Recalculate the percentage to a pixel size + $properties['height'] = round($height * (substr($properties['height'], 0, -1) / 100)); + } + + // Recalculate the width and height, if they are missing + empty($properties['width']) and $properties['width'] = round($width * $properties['height'] / $height); + empty($properties['height']) and $properties['height'] = round($height * $properties['width'] / $width); + + if ($properties['master'] === Image::AUTO) + { + // Change an automatic master dim to the correct type + $properties['master'] = (($width / $properties['width']) > ($height / $properties['height'])) ? Image::WIDTH : Image::HEIGHT; + } + + if (empty($properties['height']) OR $properties['master'] === Image::WIDTH) + { + // Recalculate the height based on the width + $properties['height'] = round($height * $properties['width'] / $width); + } + + if (empty($properties['width']) OR $properties['master'] === Image::HEIGHT) + { + // Recalculate the width based on the height + $properties['width'] = round($width * $properties['height'] / $height); + } + + // Test if we can do a resize without resampling to speed up the final resize + if ($properties['width'] > $width / 2 AND $properties['height'] > $height / 2) + { + // Presize width and height + $pre_width = $width; + $pre_height = $height; + + // The maximum reduction is 10% greater than the final size + $max_reduction_width = round($properties['width'] * 1.1); + $max_reduction_height = round($properties['height'] * 1.1); + + // Reduce the size using an O(2n) algorithm, until it reaches the maximum reduction + while ($pre_width / 2 > $max_reduction_width AND $pre_height / 2 > $max_reduction_height) + { + $pre_width /= 2; + $pre_height /= 2; + } + + // Create the temporary image to copy to + $img = $this->imagecreatetransparent($pre_width, $pre_height); + + if ($status = imagecopyresized($img, $this->tmp_image, 0, 0, 0, 0, $pre_width, $pre_height, $width, $height)) + { + // Swap the new image for the old one + imagedestroy($this->tmp_image); + $this->tmp_image = $img; + } + + // Set the width and height to the presize + $width = $pre_width; + $height = $pre_height; + } + + // Create the temporary image to copy to + $img = $this->imagecreatetransparent($properties['width'], $properties['height']); + + // Execute the resize + if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, 0, 0, $properties['width'], $properties['height'], $width, $height)) + { + // Swap the new image for the old one + imagedestroy($this->tmp_image); + $this->tmp_image = $img; + } + + return $status; + } + + public function rotate($amount) + { + // Use current image to rotate + $img = $this->tmp_image; + + // White, with an alpha of 0 + $transparent = imagecolorallocatealpha($img, 255, 255, 255, 127); + + // Rotate, setting the transparent color + $img = imagerotate($img, 360 - $amount, $transparent, -1); + + // Fill the background with the transparent "color" + imagecolortransparent($img, $transparent); + + // Merge the images + if ($status = imagecopymerge($this->tmp_image, $img, 0, 0, 0, 0, imagesx($this->tmp_image), imagesy($this->tmp_image), 100)) + { + // Prevent the alpha from being lost + imagealphablending($img, TRUE); + imagesavealpha($img, TRUE); + + // Swap the new image for the old one + imagedestroy($this->tmp_image); + $this->tmp_image = $img; + } + + return $status; + } + + public function sharpen($amount) + { + // Make sure that the sharpening function is available + if ( ! function_exists('imageconvolution')) + throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); + + // Amount should be in the range of 18-10 + $amount = round(abs(-18 + ($amount * 0.08)), 2); + + // Gaussian blur matrix + $matrix = array + ( + array(-1, -1, -1), + array(-1, $amount, -1), + array(-1, -1, -1), + ); + + // Perform the sharpen + return imageconvolution($this->tmp_image, $matrix, $amount - 8, 0); + } + + protected function properties() + { + return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); + } + + /** + * Returns an image with a transparent background. Used for rotating to + * prevent unfilled backgrounds. + * + * @param integer image width + * @param integer image height + * @return resource + */ + protected function imagecreatetransparent($width, $height) + { + if (self::$blank_png === NULL) + { + // Decode the blank PNG if it has not been done already + self::$blank_png = imagecreatefromstring(base64_decode + ( + 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29'. + 'mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBN'. + 'CgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQ'. + 'AANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoH'. + 'AgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB'. + '3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=' + )); + + // Set the blank PNG width and height + self::$blank_png_width = imagesx(self::$blank_png); + self::$blank_png_height = imagesy(self::$blank_png); + } + + $img = imagecreatetruecolor($width, $height); + + // Resize the blank image + imagecopyresized($img, self::$blank_png, 0, 0, 0, 0, $width, $height, self::$blank_png_width, self::$blank_png_height); + + // Prevent the alpha from being lost + imagealphablending($img, FALSE); + imagesavealpha($img, TRUE); + + return $img; + } + +} // End Image GD Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Image/GraphicsMagick.php b/lib/kohana/system/libraries/drivers/Image/GraphicsMagick.php new file mode 100644 index 0000000..8840eb8 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Image/GraphicsMagick.php @@ -0,0 +1,211 @@ +ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; + + // Check to make sure the provided path is correct + if ( ! is_file(realpath($config['directory']).'/gm'.$this->ext)) + throw new Kohana_Exception('image.graphicsmagick.not_found', 'gm'.$this->ext); + + + // Set the installation directory + $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; + } + + /** + * Creates a temporary image and executes the given actions. By creating a + * temporary copy of the image before manipulating it, this process is atomic. + */ + public function process($image, $actions, $dir, $file, $render = FALSE) + { + // We only need the filename + $image = $image['file']; + + // Unique temporary filename + $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); + + // Copy the image to the temporary file + copy($image, $this->tmp_image); + + // Quality change is done last + $quality = (int) arr::remove('quality', $actions); + + // Use 95 for the default quality + empty($quality) and $quality = 95; + + // All calls to these will need to be escaped, so do it now + $this->cmd_image = escapeshellarg($this->tmp_image); + $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); + + if ($status = $this->execute($actions)) + { + // Use convert to change the image into its final version. This is + // done to allow the file type to change correctly, and to handle + // the quality conversion in the most effective way possible. + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) + { + $this->errors[] = $error; + } + else + { + // Output the image directly to the browser + if ($render !== FALSE) + { + $contents = file_get_contents($this->tmp_image); + switch (substr($file, strrpos($file, '.') + 1)) + { + case 'jpg': + case 'jpeg': + header('Content-Type: image/jpeg'); + break; + case 'gif': + header('Content-Type: image/gif'); + break; + case 'png': + header('Content-Type: image/png'); + break; + } + echo $contents; + } + } + } + + // Remove the temporary image + unlink($this->tmp_image); + $this->tmp_image = ''; + + return $status; + } + + public function crop($prop) + { + // Sanitize and normalize the properties into geometry + $this->sanitize_geometry($prop); + + // Set the IM geometry based on the properties + $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); + + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function flip($dir) + { + // Convert the direction into a GM command + $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; + + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function resize($prop) + { + switch ($prop['master']) + { + case Image::WIDTH: // Wx + $dim = escapeshellarg($prop['width'].'x'); + break; + case Image::HEIGHT: // xH + $dim = escapeshellarg('x'.$prop['height']); + break; + case Image::AUTO: // WxH + $dim = escapeshellarg($prop['width'].'x'.$prop['height']); + break; + case Image::NONE: // WxH! + $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); + break; + } + + // Use "convert" to change the width and height + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function rotate($amt) + { + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function sharpen($amount) + { + // Set the sigma, radius, and amount. The amount formula allows a nice + // spread between 1 and 100 without pixelizing the image badly. + $sigma = 0.5; + $radius = $sigma * 2; + $amount = round(($amount / 80) * 3.14, 2); + + // Convert the amount to an GM command + $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); + + if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + protected function properties() + { + return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); + } + +} // End Image GraphicsMagick Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Image/ImageMagick.php b/lib/kohana/system/libraries/drivers/Image/ImageMagick.php new file mode 100644 index 0000000..5a86663 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Image/ImageMagick.php @@ -0,0 +1,212 @@ +ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; + + // Check to make sure the provided path is correct + if ( ! is_file(realpath($config['directory']).'/convert'.$this->ext)) + throw new Kohana_Exception('image.imagemagick.not_found', 'convert'.$this->ext); + + // Set the installation directory + $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; + } + + /** + * Creates a temporary image and executes the given actions. By creating a + * temporary copy of the image before manipulating it, this process is atomic. + */ + public function process($image, $actions, $dir, $file, $render = FALSE) + { + // We only need the filename + $image = $image['file']; + + // Unique temporary filename + $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); + + // Copy the image to the temporary file + copy($image, $this->tmp_image); + + // Quality change is done last + $quality = (int) arr::remove('quality', $actions); + + // Use 95 for the default quality + empty($quality) and $quality = 95; + + // All calls to these will need to be escaped, so do it now + $this->cmd_image = escapeshellarg($this->tmp_image); + $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); + + if ($status = $this->execute($actions)) + { + // Use convert to change the image into its final version. This is + // done to allow the file type to change correctly, and to handle + // the quality conversion in the most effective way possible. + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) + { + $this->errors[] = $error; + } + else + { + // Output the image directly to the browser + if ($render !== FALSE) + { + $contents = file_get_contents($this->tmp_image); + switch (substr($file, strrpos($file, '.') + 1)) + { + case 'jpg': + case 'jpeg': + header('Content-Type: image/jpeg'); + break; + case 'gif': + header('Content-Type: image/gif'); + break; + case 'png': + header('Content-Type: image/png'); + break; + } + echo $contents; + } + } + } + + // Remove the temporary image + unlink($this->tmp_image); + $this->tmp_image = ''; + + return $status; + } + + public function crop($prop) + { + // Sanitize and normalize the properties into geometry + $this->sanitize_geometry($prop); + + // Set the IM geometry based on the properties + $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); + + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function flip($dir) + { + // Convert the direction into a IM command + $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; + + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function resize($prop) + { + switch ($prop['master']) + { + case Image::WIDTH: // Wx + $dim = escapeshellarg($prop['width'].'x'); + break; + case Image::HEIGHT: // xH + $dim = escapeshellarg('x'.$prop['height']); + break; + case Image::AUTO: // WxH + $dim = escapeshellarg($prop['width'].'x'.$prop['height']); + break; + case Image::NONE: // WxH! + $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); + break; + } + + // Use "convert" to change the width and height + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function rotate($amt) + { + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + public function sharpen($amount) + { + // Set the sigma, radius, and amount. The amount formula allows a nice + // spread between 1 and 100 without pixelizing the image badly. + $sigma = 0.5; + $radius = $sigma * 2; + $amount = round(($amount / 80) * 3.14, 2); + + // Convert the amount to an IM command + $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); + + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) + { + $this->errors[] = $error; + return FALSE; + } + + return TRUE; + } + + protected function properties() + { + return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); + } + +} // End Image ImageMagick Driver \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Session.php b/lib/kohana/system/libraries/drivers/Session.php new file mode 100644 index 0000000..fb58c8d --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Session.php @@ -0,0 +1,70 @@ + 'apc', + * 'requests' => 10000 + * ); + * Lifetime does not need to be set as it is + * overridden by the session expiration setting. + * + * $Id: Cache.php 3769 2008-12-15 00:48:56Z zombor $ + * + * @package Core + * @author Kohana Team + * @copyright (c) 2007-2008 Kohana Team + * @license http://kohanaphp.com/license.html + */ +class Session_Cache_Driver implements Session_Driver { + + protected $cache; + protected $encrypt; + + public function __construct() + { + // Load Encrypt library + if (Kohana::config('session.encryption')) + { + $this->encrypt = new Encrypt; + } + + Kohana::log('debug', 'Session Cache Driver Initialized'); + } + + public function open($path, $name) + { + $config = Kohana::config('session.storage'); + + if (empty($config)) + { + // Load the default group + $config = Kohana::config('cache.default'); + } + elseif (is_string($config)) + { + $name = $config; + + // Test the config group name + if (($config = Kohana::config('cache.'.$config)) === NULL) + throw new Kohana_Exception('cache.undefined_group', $name); + } + + $config['lifetime'] = (Kohana::config('session.expiration') == 0) ? 86400 : Kohana::config('session.expiration'); + $this->cache = new Cache($config); + + return is_object($this->cache); + } + + public function close() + { + return TRUE; + } + + public function read($id) + { + $id = 'session_'.$id; + if ($data = $this->cache->get($id)) + { + return Kohana::config('session.encryption') ? $this->encrypt->decode($data) : $data; + } + + // Return value must be string, NOT a boolean + return ''; + } + + public function write($id, $data) + { + $id = 'session_'.$id; + $data = Kohana::config('session.encryption') ? $this->encrypt->encode($data) : $data; + + return $this->cache->set($id, $data); + } + + public function destroy($id) + { + $id = 'session_'.$id; + return $this->cache->delete($id); + } + + public function regenerate() + { + session_regenerate_id(TRUE); + + // Return new session id + return session_id(); + } + + public function gc($maxlifetime) + { + // Just return, caches are automatically cleaned up + return TRUE; + } + +} // End Session Cache Driver diff --git a/lib/kohana/system/libraries/drivers/Session/Cookie.php b/lib/kohana/system/libraries/drivers/Session/Cookie.php new file mode 100644 index 0000000..7b79106 --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Session/Cookie.php @@ -0,0 +1,80 @@ +cookie_name = Kohana::config('session.name').'_data'; + + if (Kohana::config('session.encryption')) + { + $this->encrypt = Encrypt::instance(); + } + + Kohana::log('debug', 'Session Cookie Driver Initialized'); + } + + public function open($path, $name) + { + return TRUE; + } + + public function close() + { + return TRUE; + } + + public function read($id) + { + $data = (string) cookie::get($this->cookie_name); + + if ($data == '') + return $data; + + return empty($this->encrypt) ? base64_decode($data) : $this->encrypt->decode($data); + } + + public function write($id, $data) + { + $data = empty($this->encrypt) ? base64_encode($data) : $this->encrypt->encode($data); + + if (strlen($data) > 4048) + { + Kohana::log('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); + return FALSE; + } + + return cookie::set($this->cookie_name, $data, Kohana::config('session.expiration')); + } + + public function destroy($id) + { + return cookie::delete($this->cookie_name); + } + + public function regenerate() + { + session_regenerate_id(TRUE); + + // Return new id + return session_id(); + } + + public function gc($maxlifetime) + { + return TRUE; + } + +} // End Session Cookie Driver Class \ No newline at end of file diff --git a/lib/kohana/system/libraries/drivers/Session/Database.php b/lib/kohana/system/libraries/drivers/Session/Database.php new file mode 100644 index 0000000..b4144ff --- /dev/null +++ b/lib/kohana/system/libraries/drivers/Session/Database.php @@ -0,0 +1,163 @@ +encrypt = Encrypt::instance(); + } + + if (is_array($config['storage'])) + { + if ( ! empty($config['storage']['group'])) + { + // Set the group name + $this->db = $config['storage']['group']; + } + + if ( ! empty($config['storage']['table'])) + { + // Set the table name + $this->table = $config['storage']['table']; + } + } + + // Load database + $this->db = Database::instance($this->db); + + Kohana::log('debug', 'Session Database Driver Initialized'); + } + + public function open($path, $name) + { + return TRUE; + } + + public function close() + { + return TRUE; + } + + public function read($id) + { + // Load the session + $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); + + if ($query->count() === 0) + { + // No current session + $this->session_id = NULL; + + return ''; + } + + // Set the current session id + $this->session_id = $id; + + // Load the data + $data = $query->current()->data; + + return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data); + } + + public function write($id, $data) + { + $data = array + ( + 'session_id' => $id, + 'last_activity' => time(), + 'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data) + ); + + if ($this->session_id === NULL) + { + // Insert a new session + $query = $this->db->insert($this->table, $data); + } + elseif ($id === $this->session_id) + { + // Do not update the session_id + unset($data['session_id']); + + // Update the existing session + $query = $this->db->update($this->table, $data, array('session_id' => $id)); + } + else + { + // Update the session and id + $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); + + // Set the new session id + $this->session_id = $id; + } + + return (bool) $query->count(); + } + + public function destroy($id) + { + // Delete the requested session + $this->db->delete($this->table, array('session_id' => $id)); + + // Session id is no longer valid + $this->session_id = NULL; + + return TRUE; + } + + public function regenerate() + { + // Generate a new session id + session_regenerate_id(); + + // Return new session id + return session_id(); + } + + public function gc($maxlifetime) + { + // Delete all expired sessions + $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); + + Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); + + return TRUE; + } + +} // End Session Database Driver diff --git a/lib/kohana/system/views/kohana/template.php b/lib/kohana/system/views/kohana/template.php new file mode 100644 index 0000000..b090fd8 --- /dev/null +++ b/lib/kohana/system/views/kohana/template.php @@ -0,0 +1,36 @@ + + + + + + + + <?php echo html::specialchars($title) ?> + + + + + + +

    + + + + + + \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_calendar.php b/lib/kohana/system/views/kohana_calendar.php new file mode 100644 index 0000000..39545e2 --- /dev/null +++ b/lib/kohana/system/views/kohana_calendar.php @@ -0,0 +1,52 @@ + date('n', $prev), 'year' => date('Y', $prev)))); +$next = Router::$current_uri.'?'.http_build_query(array_merge($qs, array('month' => date('n', $next), 'year' => date('Y', $next)))); + +?> + + + + + + + + + + + + + +
  • '.implode('
  • ', $data['output']).'
  • '; +} +else +{ + $classes = array(); + $output = ''; +} + +?> + + + + +
    diff --git a/lib/kohana/system/views/kohana_error_disabled.php b/lib/kohana/system/views/kohana_error_disabled.php new file mode 100644 index 0000000..cd91132 --- /dev/null +++ b/lib/kohana/system/views/kohana_error_disabled.php @@ -0,0 +1,17 @@ + + + + + + +<?php echo $error ?> + + +
    +

    +

    +
    + + \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_error_page.php b/lib/kohana/system/views/kohana_error_page.php new file mode 100644 index 0000000..944064c --- /dev/null +++ b/lib/kohana/system/views/kohana_error_page.php @@ -0,0 +1,27 @@ + + + + + + +<?php echo $error ?> + + + +
    +

    +

    + +

    + +

    + +

    + + +

    +
    + + \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_errors.css b/lib/kohana/system/views/kohana_errors.css new file mode 100644 index 0000000..1341f57 --- /dev/null +++ b/lib/kohana/system/views/kohana_errors.css @@ -0,0 +1,21 @@ +div#framework_error { background:#fff; border:solid 1px #ccc; font-family:sans-serif; color:#111; font-size:14px; line-height:130%; } +div#framework_error h3 { color:#fff; font-size:16px; padding:8px 6px; margin:0 0 8px; background:#f15a00; text-align:center; } +div#framework_error a { color:#228; text-decoration:none; } +div#framework_error a:hover { text-decoration:underline; } +div#framework_error strong { color:#900; } +div#framework_error p { margin:0; padding:4px 6px 10px; } +div#framework_error tt, +div#framework_error pre, +div#framework_error code { font-family:monospace; padding:2px 4px; font-size:12px; color:#333; + white-space:pre-wrap; /* CSS 2.1 */ + white-space:-moz-pre-wrap; /* For Mozilla */ + word-wrap:break-word; /* For IE5.5+ */ +} +div#framework_error tt { font-style:italic; } +div#framework_error tt:before { content:">"; color:#aaa; } +div#framework_error code tt:before { content:""; } +div#framework_error pre, +div#framework_error code { background:#eaeee5; border:solid 0 #D6D8D1; border-width:0 1px 1px 0; } +div#framework_error .block { display:block; text-align:left; } +div#framework_error .stats { padding:4px; background: #eee; border-top:solid 1px #ccc; text-align:center; font-size:10px; color:#888; } +div#framework_error .backtrace { margin:0; padding:0 6px; list-style:none; line-height:12px; } \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_profiler.php b/lib/kohana/system/views/kohana_profiler.php new file mode 100644 index 0000000..da77a66 --- /dev/null +++ b/lib/kohana/system/views/kohana_profiler.php @@ -0,0 +1,37 @@ + + +
    +render(); +} +?> +

    Profiler executed in s

    +
    \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_profiler_table.css b/lib/kohana/system/views/kohana_profiler_table.css new file mode 100644 index 0000000..6e7601c --- /dev/null +++ b/lib/kohana/system/views/kohana_profiler_table.css @@ -0,0 +1,53 @@ +#kohana-profiler .kp-table +{ + font-size: 1.0em; + color: #4D6171; + width: 100%; + border-collapse: collapse; + border-top: 1px solid #E5EFF8; + border-right: 1px solid #E5EFF8; + border-left: 1px solid #E5EFF8; + margin-bottom: 10px; +} +#kohana-profiler .kp-table td +{ + background-color: #FFFFFF; + border-bottom: 1px solid #E5EFF8; + padding: 3px; + vertical-align: top; +} +#kohana-profiler .kp-table .kp-title td +{ + font-weight: bold; + background-color: inherit; +} +#kohana-profiler .kp-table .kp-altrow td +{ + background-color: #F7FBFF; +} +#kohana-profiler .kp-table .kp-totalrow td +{ + background-color: #FAFAFA; + border-top: 1px solid #D2DCE5; + font-weight: bold; +} +#kohana-profiler .kp-table .kp-column +{ + width: 100px; + border-left: 1px solid #E5EFF8; + text-align: center; +} +#kohana-profiler .kp-table .kp-data, #kohana-profiler .kp-table .kp-name +{ + background-color: #FAFAFB; + vertical-align: top; +} +#kohana-profiler .kp-table .kp-name +{ + width: 200px; + border-right: 1px solid #E5EFF8; +} +#kohana-profiler .kp-table .kp-altrow .kp-data, #kohana-profiler .kp-table .kp-altrow .kp-name +{ + background-color: #F6F8FB; +} \ No newline at end of file diff --git a/lib/kohana/system/views/kohana_profiler_table.php b/lib/kohana/system/views/kohana_profiler_table.php new file mode 100644 index 0000000..b6b4653 --- /dev/null +++ b/lib/kohana/system/views/kohana_profiler_table.php @@ -0,0 +1,25 @@ + + + + > + $column) + { + $class = empty($column['class']) ? '' : ' class="'.$column['class'].'"'; + $style = empty($column['style']) ? '' : ' style="'.$column['style'].'"'; + $value = $row['data'][$index]; + $value = (is_array($value) OR is_object($value)) ? '
    '.html::specialchars(print_r($value, TRUE)).'
    ' : html::specialchars($value); + echo '', $value, ''; + } + ?> + + +
    \ No newline at end of file diff --git a/lib/kohana/system/views/pagination/classic.php b/lib/kohana/system/views/pagination/classic.php new file mode 100644 index 0000000..5272c2c --- /dev/null +++ b/lib/kohana/system/views/pagination/classic.php @@ -0,0 +1,39 @@ + Last › + */ +?> + +

    + + + ‹  + + + + < + + + + + + + + + + + + + + + + > + + + +  › + + +

    \ No newline at end of file diff --git a/lib/kohana/system/views/pagination/digg.php b/lib/kohana/system/views/pagination/digg.php new file mode 100644 index 0000000..0e065a6 --- /dev/null +++ b/lib/kohana/system/views/pagination/digg.php @@ -0,0 +1,83 @@ + + +

    + + + «  + + «  + + + + + + + + + + + + + + + + + + + + + + + + … + + + + $total_pages - 8): /* « Previous 1 2 … 17 18 19 20 21 22 23 24 25 26 Next » */ ?> + + 1 + 2 + … + + + + + + + + + + + + 1 + 2 + … + + + + + + + + + + … + + + + + + + +  » + +  » + + +

    \ No newline at end of file diff --git a/lib/kohana/system/views/pagination/extended.php b/lib/kohana/system/views/pagination/extended.php new file mode 100644 index 0000000..2427a4e --- /dev/null +++ b/lib/kohana/system/views/pagination/extended.php @@ -0,0 +1,27 @@ + + +

    + + + «  + + «  + + + | + + | + + | +  » + +  » + + +

    \ No newline at end of file diff --git a/lib/kohana/system/views/pagination/punbb.php b/lib/kohana/system/views/pagination/punbb.php new file mode 100644 index 0000000..6599831 --- /dev/null +++ b/lib/kohana/system/views/pagination/punbb.php @@ -0,0 +1,37 @@ + + +

    + + : + + 3): ?> + 1 + + + + + + + $total_pages) continue ?> + + + + + + + + + + + + + + + +

    \ No newline at end of file diff --git a/man/Makefile.in b/man/Makefile.in new file mode 100644 index 0000000..614ea84 --- /dev/null +++ b/man/Makefile.in @@ -0,0 +1,23 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +MANDIR=@mandir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +DATAROOTDIR=@datarootdir@ + +CP=@CP@ + +all html: + +clean: + -rm -f npcd.8 + +distclean: clean + -rm -f Makefile + +devclean: distclean + +install: + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(MANDIR)/man8 + $(INSTALL) -m 755 $(INSTALL_OPTS) npcd.8 $(DESTDIR)$(MANDIR)/man8 + diff --git a/man/npcd.8.in b/man/npcd.8.in new file mode 100644 index 0000000..c3153ce --- /dev/null +++ b/man/npcd.8.in @@ -0,0 +1,38 @@ +.\" In .TH, FOO should be all caps, SECTION should be 1-8, maybe w/ subsection +.\" other parms are allowed: see man(7), man(1) +.\" +.\" This template provided by Tom Christiansen . +.\" +.TH NPCD 8 +.SH NAME +npcd \- Nagios Performance C Daemon +.SH SYNOPSIS +\fBnpcd\fR [ \fB\-d | \--daemon\fR ] ( \fB\-f | \--config\fR ) \fI +.SH DESCRIPTION +The \fBnpcd\fR is a daemon processing nagios performance data. +.PP +For more information you can visit pnp4nagios website: +.IP +http://docs.pnp4nagios.org/ +.PP +and SourceForge project: +.IP +http://pnp4nagios.sourceforge.net +.SH OPTIONS +.TP +\fB\-d, \--daemon +Run \fBnpcd\fR as daemon in the background. +.TP +\fB\-f, \--config\fR \fI +Path to the \fBnpcd\fR config file (typically @sysconfdir@/npcd.cfg). +.SH "RETURN VALUE" +On success starting \fBnpcd\fR 0 is returned. +.SH ERRORS +On error starting \fBnpcd\fR 1 is returned. +.SH FILES +.br +.nf +\fI@sysconfdir@/npcd.cfg\fR default config file +.SH AUTHORS +Joerg Linge , +Hendrik Baecker diff --git a/sample-config/Makefile.in b/sample-config/Makefile.in new file mode 100644 index 0000000..3f6b171 --- /dev/null +++ b/sample-config/Makefile.in @@ -0,0 +1,84 @@ +prefix=@prefix@ +SYSCONFDIR=@sysconfdir@ +BINDIR=@bindir@ +LIBEXECDIR=@libexecdir@ +LIBDIR=@libdir@ +CGIDIR=@sbindir@ +HTMLDIR=@datadir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +PERFDATADIR=@PERFDATA_DIR@ +DATAROOTDIR=@datarootdir@ +PKG_NAME=@PKG_NAME@ +PKG_VERSION=@PKG_VERSION@ +HTTPD_CONF=@HTTPD_CONF@ +CP=@CP@ + +all html: + +clean: + -rm -f pnp/config.php + -rm -f pnp/process_perfdata.cfg-sample + -rm -f pnp/npcd.cfg-sample + -rm -f misccommands.cfg-sample + -rm -f nagios.cfg-sample + -rm -f httpd.conf + -rm -f pnp/pnp4nagios_release + -rm -f lighttpd.pnp4nagios.conf + -rm -f nginx.pnp4nagios.conf + +distclean: clean + -rm -f Makefile + +devclean: distclean + +install: + -rm -f $(DESTDIR)$(HTMLDIR)/conf/config.php + + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR)/config.d + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR)/check_commands + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR)/pages + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/pnp4nagios_release $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/background.pdf $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/config.php $(DESTDIR)$(SYSCONFDIR)/config.php.$(PKG_VERSION); \ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/config.php $(DESTDIR)$(SYSCONFDIR); \ + +install-config: + + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR)/check_commands + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(SYSCONFDIR)/pages + + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/config.php $(DESTDIR)$(SYSCONFDIR)/config.php.$(PKG_VERSION); \ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/config.php $(DESTDIR)$(SYSCONFDIR); \ + + if [ ! -e $(DESTDIR)$(SYSCONFDIR)/config_local.php ] ;then \ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/config.php $(DESTDIR)$(SYSCONFDIR)/config_local.php; \ + fi + + if [ -e $(DESTDIR)$(SYSCONFDIR)/process_perfdata.cfg ] ;then \ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/process_perfdata.cfg-sample $(DESTDIR)$(SYSCONFDIR)/process_perfdata.cfg.$(PKG_VERSION); \ + else\ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/process_perfdata.cfg-sample $(DESTDIR)$(SYSCONFDIR)/process_perfdata.cfg; \ + fi + + if [ -e $(DESTDIR)$(SYSCONFDIR)/npcd.cfg ] ;then \ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/npcd.cfg-sample $(DESTDIR)$(SYSCONFDIR)/npcd.cfg.$(PKG_VERSION); \ + else\ + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/npcd.cfg-sample $(DESTDIR)$(SYSCONFDIR)/npcd.cfg; \ + fi + + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/rra.cfg-sample $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 644 $(INSTALL_OPTS) misccommands.cfg-sample $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 644 $(INSTALL_OPTS) nagios.cfg-sample $(DESTDIR)$(SYSCONFDIR) + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/check_commands/check_nwstat.cfg-sample $(DESTDIR)$(SYSCONFDIR)/check_commands + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/check_commands/check_nrpe.cfg-sample $(DESTDIR)$(SYSCONFDIR)/check_commands + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/check_commands/check_all_local_disks.cfg-sample $(DESTDIR)$(SYSCONFDIR)/check_commands + $(INSTALL) -m 644 $(INSTALL_OPTS) pnp/pages/web_traffic.cfg-sample $(DESTDIR)$(SYSCONFDIR)/pages + +install-webconf: + + $(INSTALL) -m 755 -d $(DESTDIR)$(HTTPD_CONF) + $(INSTALL) -m 644 httpd.conf $(DESTDIR)$(HTTPD_CONF)/$(PKG_NAME).conf + diff --git a/sample-config/httpd.conf.in b/sample-config/httpd.conf.in new file mode 100644 index 0000000..72b81cb --- /dev/null +++ b/sample-config/httpd.conf.in @@ -0,0 +1,30 @@ +# SAMPLE CONFIG SNIPPETS FOR APACHE WEB SERVER + +Alias @BASE_URL@ "@datarootdir@" + + + AllowOverride None + Order allow,deny + Allow from all + # + # Use the same value as defined in nagios.conf + # + AuthName "Nagios Access" + AuthType Basic + AuthUserFile /usr/local/nagios/etc/htpasswd.users + Require valid-user + + # Turn on URL rewriting + RewriteEngine On + Options symLinksIfOwnerMatch + # Installation directory + RewriteBase @BASE_URL@/ + # Protect application and system files from being viewed + RewriteRule "^(?:application|modules|system)/" - [F] + # Allow any files or directories that exist to be displayed directly + RewriteCond "%{REQUEST_FILENAME}" !-f + RewriteCond "%{REQUEST_FILENAME}" !-d + # Rewrite all other URLs to index.php/URL + RewriteRule "^.*$" "index.php/$0" [PT] + + diff --git a/sample-config/lighttpd.pnp4nagios.conf.in b/sample-config/lighttpd.pnp4nagios.conf.in new file mode 100644 index 0000000..a0b3a3b --- /dev/null +++ b/sample-config/lighttpd.pnp4nagios.conf.in @@ -0,0 +1,20 @@ +# +# Sample Lighttpd Config snippet. +# Tested on Debian. +# +server.modules += ( "mod_auth" ) + +alias.url += ( + "@BASE_URL@" => "@datarootdir@" + ) + +$HTTP["url"] =~ "(^@BASE_URL@)" { + auth.backend = "htpasswd" + auth.backend.htpasswd.userfile = "/usr/local/nagios/etc/htpasswd.users" + auth.require = ( "" => ( + "method" => "basic", + "realm" => "Nagios Access", + "require" => "valid-user" + ) + ) +} diff --git a/sample-config/misccommands.cfg-sample.in b/sample-config/misccommands.cfg-sample.in new file mode 100644 index 0000000..1280c27 --- /dev/null +++ b/sample-config/misccommands.cfg-sample.in @@ -0,0 +1,44 @@ +# +# definitions for PNP processing commands +# +# please uncomment the appropriate definitions and make sure +# that there aren't duplicate entries in your config +# +# Synchronous mode +# + +#define command { +# command_name process-service-perfdata +# command_line @PERL@ @libexecdir@/process_perfdata.pl +#} +# +#define command { +# command_name process-host-perfdata +# command_line @PERL@ @libexecdir@/process_perfdata.pl -d HOSTPERFDATA +#} + +# +# Bulk mode +# +#define command { +# command_name process-service-perfdata-file +# command_line @libexecdir@/process_perfdata.pl --bulk @localstatedir@/service-perfdata +#} + +#define command { +# command_name process-host-perfdata-file +# command_line @libexecdir@/process_perfdata.pl --bulk @localstatedir@/host-perfdata +#} + +# +# Bulk with NPCD mode +# +#define command { +# command_name process-service-perfdata-file +# command_line /bin/mv @localstatedir@/service-perfdata @PERFDATA_SPOOL_DIR@/service-perfdata.$TIMET$ +#} + +#define command { +# command_name process-host-perfdata-file +# command_line /bin/mv @localstatedir@/host-perfdata @PERFDATA_SPOOL_DIR@/host-perfdata.$TIMET$ +#} diff --git a/sample-config/nagios.cfg-sample.in b/sample-config/nagios.cfg-sample.in new file mode 100644 index 0000000..fef969b --- /dev/null +++ b/sample-config/nagios.cfg-sample.in @@ -0,0 +1,42 @@ +# +# definitions for PNP in nagios.cfg (icinga.cfg) +# please make sure that you don't have duplicate entries +# +# Synchronous mode +# +process_performance_data=1 + +enable_environment_macros=1 # available since Nagios 3.x + +service_perfdata_command=process-service-perfdata + +host_perfdata_command=process-host-perfdata # NOT advisable prior to Nagios 3.0 + +# +# Bulk / NPCD mode +# + +process_performance_data=1 + +# *** the template definition differs from the one in the original nagios.cfg +# +service_perfdata_file=@localstatedir@/service-perfdata +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$ +service_perfdata_file_mode=a +service_perfdata_file_processing_interval=15 +service_perfdata_file_processing_command=process-service-perfdata-file + +# *** the template definition differs from the one in the original nagios.cfg +# +host_perfdata_file=@localstatedir@/host-perfdata +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$ +host_perfdata_file_mode=a +host_perfdata_file_processing_interval=15 +host_perfdata_file_processing_command=process-host-perfdata-file + +# +# Module mode +# +event_broker_options=-1 # minimum 4+8=12 +process_performance_data=1 +broker_module=@libdir@/npcdmod.o config_file=@sysconfdir@/npcd.cfg diff --git a/sample-config/nginx.pnp4nagios.conf.in b/sample-config/nginx.pnp4nagios.conf.in new file mode 100644 index 0000000..1a1bfc4 --- /dev/null +++ b/sample-config/nginx.pnp4nagios.conf.in @@ -0,0 +1,34 @@ +# SAMPLE CONFIG SNIPPETS FOR NGINX WEB SERVER +# Contributed by Thomas Charbonnel +# +location @BASE_URL@ { + # e.g. /usr/local/pnp4nagios/share; + alias @datarootdir@; + auth_basic "Nagios Access"; + auth_basic_user_file /usr/local/nagios/etc/htpasswd.users; + index index.php; + # if we have e.g. /pnp4nagios/media/css/common.css + # nginx will check + # /usr/local/png4nagios/share/media/css/common/css + # and return it if it's found + # if it can't find a matching file even adding a trailing / + # the request is handled to the @pnp4nagios location + try_files $uri $uri/ @pnp4nagios; +} +location @pnp4nagios { + # this implies the definition of some backend + # e.g + # upstream php { + # server 127.0.0.1:9000; + # } + fastcgi_pass php; + fastcgi_index index.php; + # implies an external file, but this is common nginx practice + include fastcgi_params; + # this splits out the trailing path + # eg index.php?host -> $fastcgi_path_info == 'host' + fastcgi_split_path_info ^(.+\.php)(.*)$; + fastcgi_param PATH_INFO $fastcgi_path_info; + fastcgi_param SCRIPT_FILENAME @datarootdir@/index.php; +} + diff --git a/sample-config/pnp/background-letter.pdf b/sample-config/pnp/background-letter.pdf new file mode 100644 index 0000000..83e4c66 Binary files /dev/null and b/sample-config/pnp/background-letter.pdf differ diff --git a/sample-config/pnp/background.pdf b/sample-config/pnp/background.pdf new file mode 100644 index 0000000..174428c Binary files /dev/null and b/sample-config/pnp/background.pdf differ diff --git a/sample-config/pnp/check_commands/check_all_local_disks.cfg-sample b/sample-config/pnp/check_commands/check_all_local_disks.cfg-sample new file mode 100644 index 0000000..4b53da6 --- /dev/null +++ b/sample-config/pnp/check_commands/check_all_local_disks.cfg-sample @@ -0,0 +1,45 @@ +# +# Adapt the Template if check_command should not be the PNP Template +# +# check_command check_nrpe!check_all_local_disks +# ________0__________| | +# ________1________________________| +# +# CUSTOM_TEMPLATE = 0,1 +# +# Change the RRD Datatype based on the check_command Name. +# Defaults to GAUGE. +# +# Adjust the whole RRD Database +# DATATYPE = COUNTER +# +# Adjust every single DS by using a List of Datatypes. +# DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER + +# Use the MIN value for newly created RRD Databases. +# This value defaults to 0 +# USE_MIN_ON_CREATE = 1 +# +# Use the MAX value for newly created RRD Databases. +# This value defaults to 0 +# USE_MAX_ON_CREATE = 1 + +# Use a single RRD Database per Service +# This Option is only used while creating new RRD Databases +# +# RRD_STORAGE_TYPE = SINGLE +# +# Use multiple RRD Databases per Service +# One RRD Database per Datasource. +# RRD_STORAGE_TYPE = MULTIPLE +# +RRD_STORAGE_TYPE = MULTIPLE + +# RRD Heartbeat in seconds +# This Option is only used while creating new RRD Databases +# Existing RRDs can be changed by "rrdtool tune" +# More on http://oss.oetiker.ch/rrdtool/doc/rrdtune.en.html +# +# This value defaults to 8640 +# RRD_HEARTBEAT = 305 + diff --git a/sample-config/pnp/check_commands/check_nrpe.cfg-sample b/sample-config/pnp/check_commands/check_nrpe.cfg-sample new file mode 100644 index 0000000..93e9729 --- /dev/null +++ b/sample-config/pnp/check_commands/check_nrpe.cfg-sample @@ -0,0 +1,46 @@ +# +# Adapt the Template if check_command should not be the PNP Template +# +# check_command check_nrpe!check_all_local_disks +# ________0__________| | +# ________1________________________| +# +# User ARG1 +CUSTOM_TEMPLATE = 1 +# +# Change the RRD Datatype based on the check_command Name. +# Defaults to GAUGE. +# +# Adjust the whole RRD Database +# DATATYPE = COUNTER +# +# Adjust every single DS by using a List of Datatypes. +# DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER + +# Use the MIN value for newly created RRD Databases. +# This value defaults to 0 +# USE_MIN_ON_CREATE = 1 +# +# Use the MAX value for newly created RRD Databases. +# This value defaults to 0 +# USE_MAX_ON_CREATE = 1 + +# Use a single RRD Database per Service +# This Option is only used while creating new RRD Databases +# +# RRD_STORAGE_TYPE = SINGLE +# +# Use multiple RRD Databases per Service +# One RRD Database per Datasource. +# RRD_STORAGE_TYPE = MULTIPLE +# +# RRD_STORAGE_TYPE = SINGLE + +# RRD Heartbeat in seconds +# This Option is only used while creating new RRD Databases +# Existing RRDs can be changed by "rrdtool tune" +# More on http://oss.oetiker.ch/rrdtool/doc/rrdtune.en.html +# +# This value defaults to 8640 +# RRD_HEARTBEAT = 305 + diff --git a/sample-config/pnp/check_commands/check_nwstat.cfg-sample b/sample-config/pnp/check_commands/check_nwstat.cfg-sample new file mode 100644 index 0000000..9e4f8bf --- /dev/null +++ b/sample-config/pnp/check_commands/check_nwstat.cfg-sample @@ -0,0 +1,46 @@ +# +# Adapt the Template if check_command should not be the PNP Template +# +# check_command check_nwstat!LOAD5!80%!90% +# ________0__________| | | | +# ________1____________________| | | +# ________2_________________________| | +# ________3____________________________| +# +CUSTOM_TEMPLATE = 0,1 +# +# Change the RRD Datatype based on the check_command Name. +# Defaults to GAUGE. +# +# Adjust the whole RRD Database +# DATATYPE = COUNTER +# +# Adjust every single DS by using a List of Datatypes. +# DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER + +# Use the MIN value for newly created RRD Databases. +# This value defaults to 0 +# USE_MIN_ON_CREATE = 1 +# +# Use the MAX value for newly created RRD Databases. +# This value defaults to 0 +# USE_MAX_ON_CREATE = 1 + +# Use a single RRD Database per Service +# This Option is only used while creating new RRD Databases +# RRD_STORAGE_TYPE = SINGLE +# +# Use multiple RRD Databases per Service +# One RRD Database per Datasource. +# RRD_STORAGE_TYPE = MULTIPLE +# +# RRD_STORAGE_TYPE = SINGLE + +# RRD Heartbeat in seconds +# This Option is only used while creating new RRD Databases +# Existing RRDs can be changed by "rrdtool tune" +# More on http://oss.oetiker.ch/rrdtool/doc/rrdtune.en.html +# +# This value defaults to 8640 +# RRD_HEARTBEAT = 305 + diff --git a/sample-config/pnp/config.php.in b/sample-config/pnp/config.php.in new file mode 100644 index 0000000..eb01f73 --- /dev/null +++ b/sample-config/pnp/config.php.in @@ -0,0 +1,275 @@ + +# Example: conf['allowed_for_all_services'] = "nagiosadmin,operator"; +# This option is used while $conf['auth_enabled'] = TRUE +$conf['allowed_for_all_services'] = ""; +$conf['allowed_for_all_hosts'] = ""; + +# Which user is allowed to see additional service links ? +# Keywords: EVERYONE NONE +# Example: conf['allowed_for_service_links'] = "nagiosadmin,operator"; +# +$conf['allowed_for_service_links'] = "EVERYONE"; + +# +# Who can use the host search function ? +# Keywords: EVERYONE NONE +# +$conf['allowed_for_host_search'] = "EVERYONE"; + +# +# Who can use the host overview ? +# This function is called if no Service Description is given. +# +$conf['allowed_for_host_overview'] = "EVERYONE"; + +# +# Who can use the Pages function? +# Keywords: EVERYONE NONE +# Example: conf['allowed_for_pages'] = "nagiosadmin,operator"; +# +$conf['allowed_for_pages'] = "EVERYONE"; + +# +# Which timerange should be used for the host overview site ? +# use a key from array $views[] +# +$conf['overview-range'] = 1 ; + +# +# Scale the preview images used in /popup +# +$conf['popup-width'] = "300px"; + +# +# jQuery UI Theme +# http://jqueryui.com/themeroller/ +# Possible values are: lightness, smoothness, redmond, multisite +$conf['ui-theme'] = 'smoothness'; + +# Language definitions to use. +# valid options are en_US, de_DE, es_ES, ru_RU, fr_FR +# +$conf['lang'] = "en_US"; + +# +# Date format +# +$conf['date_fmt'] = "d.m.y G:i"; + +# +# This option breaks down the template name based on _ and then starts to +# build it up and check the different template directories for a suitable template. +# +# Example: +# +# Template to be used: check_esx3_host_net_usage you create a check_esx3.php +# +# It will find and match on check_esx3 first in templates dir then in templates.dist +# +$conf['enable_recursive_template_search'] = 1; + +# +# Direct link to the raw XML file. +# +$conf['show_xml_icon'] = 1; + +# +# Use FPDF Lib for PDF creation ? +# +$conf['use_fpdf'] = 1; + +# +# Use this file as PDF background. +# +$conf['background_pdf'] = '@sysconfdir@/background.pdf' ; + +# +# Enable Calendar +# +$conf['use_calendar'] = 1; + +# +# Define default views with title and start timerange in seconds +# +# remarks: required escape on " with backslash +# +#$views[] = array('title' => 'One Hour', 'start' => (60*60) ); +$views[] = array('title' => '4 Hours', 'start' => (60*60*4) ); +$views[] = array('title' => '25 Hours', 'start' => (60*60*25) ); +$views[] = array('title' => 'One Week', 'start' => (60*60*25*7) ); +$views[] = array('title' => 'One Month', 'start' => (60*60*24*32) ); +$views[] = array('title' => 'One Year', 'start' => (60*60*24*380) ); + +# +# rrdcached support +# Use only with rrdtool svn revision 1511+ +# +# $conf['RRD_DAEMON_OPTS'] = 'unix:/tmp/rrdcached.sock'; +$conf['RRD_DAEMON_OPTS'] = ''; + +# A list of directories to search for templates +# @datarootdir@/templates.dist is always the last directory to be searched for templates +# +# Add your own template directories here +# First match wins! +#$conf['template_dirs'][] = '/usr/local/check_mk/pnp-templates'; +$conf['template_dirs'][] = '@datarootdir@/templates'; +$conf['template_dirs'][] = '@datarootdir@/templates.dist'; + +# +# Directory to search for special templates +# +$conf['special_template_dir'] = '@datarootdir@/templates.special'; + +# +# Regex to detect mobile devices +# This regex is evaluated against the USER_AGENT String +# +$conf['mobile_devices'] = 'iPhone|iPod|iPad|android'; + +# +# additional colour schemes +# values taken from www.colorbrewer2.org +# for details on usage refer to the documentation of the helper functions +# +$scheme['Reds'] = array ('#FEE0D2','#FCBBA1','#FC9272','#FB6A4A','#EF3B2C','#CB181D','#A50F15','#67000D'); +$scheme['Greens'] = array ('#E5F5E0','#C7E9C0','#A1D99B','#74C476','#41AB5D','#23AB45','#006D2C','#00441B'); +$scheme['Blues'] = array ('#DEEBF7','#C6DBEF','#9ECAE1','#6BAED6','#4292C6','#2171B5','#08519C','#08306B'); +$scheme['Oranges'] = array ('#FEE6CE','#FDD0A2','#FDAE6B','#FD8D3C','#F16913','#D94801','#A63603','#7F2704'); +$scheme['Purples'] = array ('#EFEDF5','#DADAEB','#BDBDDC','#9E9AC8','#807DBA','#6A51A3','#54278F','#3F007A'); +$scheme['RdPu'] = array ('#FDE0DD','#FCC5C0','#FA9FB5','#F768A1','#DD3497','#AE017E','#7A0177','#49006A'); +$scheme['Dark2'] = array ('#1B9E77','#D95F02','#7570B3','#E7298A','#66A61E','#E6ab02','#a6761d','#666666'); +$scheme['BrBG'] = array ('#543005','#8C510A','#BF812D','#DFC27D','#F6E8C3','#C7EAE5','#80CDC1','#35978F','#01665E','#003C30'); +$scheme['PiYG'] = array ('#8E0152','#C51B7D','#DE77AE','#F1B6DA','#FDE0EF','#E6F5D0','#B8E186','#7FBC41','#4D9221','#276419'); +$scheme['PRGn'] = array ('#40004B','#762A83','#9970AB','#C2A5CF','#E7D4E8','#D9F0D3','#A6DBA0','#5AAE61','#1B7837','#00441B'); +$scheme['PuOr'] = array ('#7F3B08','#B35806','#E08214','#FDB863','#FEE0B6','#D8DAEB','#B2ABD2','#8073AC','#542788','#2D004B'); +$scheme['RdBu'] = array ('#67001F','#B2182B','#D6604D','#F4A582','#FDDBC7','#D1E5F0','#92C5DE','#4393C3','#2166AC','#053061'); +$scheme['RdGy'] = array ('#67001F','#B2182B','#D6604D','#F4A582','#FDDBC7','#E0E0E0','#BABABA','#878787','#4D4D4D','#1A1A1A'); +$scheme['RdYlBu'] = array ('#A50026','#D73027','#F46D43','#FDAE61','#FEE090','#E0F3F8','#ABD9E9','#74ADD1','#4575B4','#313695'); +$scheme['RdYlGn'] = array ('#A50026','#D73027','#F46D43','#FDAE61','#FEE08B','#D9EF8B','#A6D96A','#66BD63','#1A9850','#006837'); +$scheme['Spectral'] = array ('#9E0142','#D53E4F','#F46D43','#FDAE61','#FEE08B','#E6F598','#ABDDA4','#66C2A5','#3288BD','#5E4FA2'); +$scheme['Paired'] = array ('#A6CEE3','#1F78B4','#B2DF8A','#33A02C','#FB9A99','#E31A1C','#FDBF6F','#FF7F00','#CAB2D6','#6A3D9A'); +$scheme['mixed1'] = array ('#8C510A','#2166ac','#BF812D','#4393c3','#DFC27D','#92c5de','#F6E8C3','#d1e5f0', + '#fddbc7','#C7EAE5','#f4a582','#80CDC1','#d6604d','#35978F','#b2182b','#01665E'); +$scheme['mixed2'] = array ('#b2182b','#2166ac','#d6604d','#4393c3','#f4a582','#92c5de','#fddbc7','#d1e5f0', + '#F6E8C3','#C7EAE5','#DFC27D','#80CDC1','#BF812D','#35978F','#8C510A','#01665E'); +$scheme['mixed3'] = array ('#67001F','#80CDC1','#B2182B','#35978F','#D6604D','#01665E','#F4A582','#003C30', + '#FDDBC7','#92C5DE','#D1E5F0','#2166AC','#4393C3','#8C510A','#053061','#BF812D'); +?> diff --git a/sample-config/pnp/npcd.cfg-sample.in b/sample-config/pnp/npcd.cfg-sample.in new file mode 100644 index 0000000..7811530 --- /dev/null +++ b/sample-config/pnp/npcd.cfg-sample.in @@ -0,0 +1,195 @@ +# NPCD.cfg - sample configuration file for PNPs NPCD +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation; +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +# Privilege Options + +user = @nagios_user@ +group = @nagios_grp@ + +######################### +# # +# Logging Options # +# # +######################### + +# log_type - define if you want your logs to +# 'syslog' or to a 'file' +# +# log_type = +# + +#log_type = file +log_type = syslog + + +# log_file - define a path to your logfile +# needed if 'log_type'='file' +# +# log_file =
    +# + +log_file = @localstatedir@/npcd.log + + +# max_logfile_size - defines the maximum filesize (bytes) +# before the logfile will rotated. +# +# max_logfile_size = (default 10Mbyte) +# + +max_logfile_size = 10485760 + + +# log_level - how much should we log? +# +# log_level = +# +# 0 = No logging - except errors +# 1 = Small logging - some few more output +# 2 = More Logging (actual ALL logs) +# -1 = DEBUG Mode - ALL Logging and slower processing +# + +log_level = 0 + +######################### +# # +# NEEDED OPTIONS # +# # +######################### + +# perfdata_spool_dir - where we can find the +# performance data files +# +# perfdata_spool_dir =
    +# + +perfdata_spool_dir = @PERFDATA_SPOOL_DIR@ + + +# Execute following command for each found file +# in 'perfdata_spool_dir' +# +# perfdata_file_run_cmd = +# +# Must be executable by user/group from above +# +# perfdata_file_run_cmd = +# + +perfdata_file_run_cmd = @libexecdir@/@pp_pl_name@ + + +# perfdata_file_run_cmd_args (optional) +# +# If you wish, you can apply more arguments to the +# perfdata_file_run_cmd +# +# Hint: +# NPCD will create a command line like this: +# ' ' +# + +perfdata_file_run_cmd_args = --bulk + + +# identify_npcd (optional) +# +# If set to one (by default) npcd will append +# '-n' to the perfdata_file_run_cmd +# +# identify_npcd = 0|1 (default: 1) + +identify_npcd = 1 + + +# npcd_max_threads - define how many parallel threads we +# should start + +npcd_max_threads = 5 + +# sleep_time - how many seconds npcd should wait between dirscans +# +# sleep_time = 15 (default) + +sleep_time = 15 + + +# EXPERIMENTAL +# +# load_threshold - npcd won't start new threads +# if your system load is above this threshold +# +# load_threshold = (default: 0.0) +# +# Hint: Do not use "," as decimal delimiter +# +# 07/15/2008: Every value above 0.0 will +# enable this feature + +load_threshold = 0.0 + + +# location of your pid file + +pid_file=/var/run/npcd.pid + + +######################### +# # +# NPCDMOD OPTIONS # +# # +######################### + + +# perfdata_file - where should the npcdmod.o +# write the performance data +# +# must not be within the same directory as +# perfdata_spool_dir +# +# perfdata_file = +# + +perfdata_file = @localstatedir@/perfdata.dump + + +# perfdata_spool_filename - declare the destination +# filename for the spooled files +# +# This option allows you a customized filename. +# Usefull if you own different nagios servers +# which write their data to a shared storage. +# +# perfdata_spool_filename = +# +# Hint: +# The final files will be moved to +# 'perfdata_spool_dir/perfdata_spool_filename-TIMESTAMP' +# +# Example: +# +# perfdata_spool_filename = perfdata-NY +# perfdata_spool_filename = perfdata-LA + +perfdata_spool_filename = perfdata + +# +# perfdata_file_processing_interval +# +perfdata_file_processing_interval = 15 + +# We have to end with a newline + diff --git a/sample-config/pnp/pages/web_traffic.cfg-sample b/sample-config/pnp/pages/web_traffic.cfg-sample new file mode 100644 index 0000000..0d0c80a --- /dev/null +++ b/sample-config/pnp/pages/web_traffic.cfg-sample @@ -0,0 +1,23 @@ +# +# Sample Page Config +# +# Global Section +# use_regex [0|1] +# page_name < your page title > +# background_pdf + +define page { + use_regex 1 + page_name Webserver Traffic +} + +# +# Define the first Graph +# +define graph { + host_name ^websrv # Every host starting with 'websrv' + service_desc ^traffic # Every service starting with 'traffic' + source 0 # OPTIONAL Show only the first image +} + + diff --git a/sample-config/pnp/pnp4nagios_release.in b/sample-config/pnp/pnp4nagios_release.in new file mode 100644 index 0000000..b4ba121 --- /dev/null +++ b/sample-config/pnp/pnp4nagios_release.in @@ -0,0 +1,8 @@ +PKG_REL_DATE="@PKG_REL_DATE@" +PKG_VERSION="@PKG_VERSION@" +PKG_NAME="@PKG_NAME@" + +# +# Configure Arguments +# +CONFIGURE_ARGS=@ac_configure_args@ diff --git a/sample-config/pnp/process_perfdata.cfg-sample.in b/sample-config/pnp/process_perfdata.cfg-sample.in new file mode 100644 index 0000000..67a7c4c --- /dev/null +++ b/sample-config/pnp/process_perfdata.cfg-sample.in @@ -0,0 +1,135 @@ +# @PKG_NAME@–@PKG_VERSION@ +# Config File for process_perfdata.pl +# +# More info on RRDtool can be found at www.rrdtool.org + +# +# process_perfdata.pl timeout in seconds +# +TIMEOUT = 15 + +# +# Use RRDs Perl module +# +USE_RRDs = 1 + +# +# Path to XML/RRD files +# +RRDPATH = @PERFDATA_DIR@ + +# +# Location of RRDtool binary +# +RRDTOOL = @RRDTOOL@ + +# +# Location of PNP config files +# +CFG_DIR = @sysconfdir@ + +# +# Use a single RRD database per service +# one or more datasources per RRD database +# RRD_STORAGE_TYPE = SINGLE +# +# Use multiple RRD databases per service +# one RRD database per datasource. +# RRD_STORAGE_TYPE = MULTIPLE +# +RRD_STORAGE_TYPE = SINGLE + +# +# Max. interval between samples/updates +# +RRD_HEARTBEAT = 8460 + +# +# File with RRA options used to create new RRD files +# +RRA_CFG = @sysconfdir@/rra.cfg + +# +# Interval at which PDPs are generated +# +RRA_STEP = 60 + +# +# Name of the log file +# +LOG_FILE = @PERFDATA_LOG@ + +# +# Loglevel 0=silent 1=normal 2=debug +# +LOG_LEVEL = @DEBUG@ + +# +# XML encoding +# The supported encodings are ISO-8859-1, UTF-8 and US-ASCII. +# http://www.php.net/xml-parser-create +# +XML_ENC = UTF-8 + +# +# XML update delay in seconds +# 0 = Update XML Files everytime new data arrives +# +# Use this option to reduce disk I/O +# +XML_UPDATE_DELAY = 0 + +# +# Use only with RRDtool svn revision 1511+ +# +# RRD_DAEMON_OPTS = unix:/tmp/rrdcached.sock +RRD_DAEMON_OPTS = + +# +# Spool directory used for internal statistics +# +STATS_DIR = @localstatedir@/stats + + +######################################################### +# Gearman Worker Config +# Only used when running as Gearman worker + +# +# How many child processes +# +PREFORK = 1 + +# +# Gearman server to connect to +# Comma separated list of Gearman job servers +# +GEARMAN_HOST = localhost:4730 + +# +# Restart child process after a given count of requests +# +REQUESTS_PER_CHILD = 10000 + +# +# Enables or disables encryption. +# It is strongly advised to not disable encryption, or +# anybody will be able to inject packages to your worker. +# When using encryption, you will have to specify a shared +# secret eithr via the KEY or the KEY_FILE option. +# Default is 1. +# +ENCRYPTION = 1 + +# +# A shared password which will be used for +# encryption of data pakets. Should be at least 8 +# bytes long. Maximum length is 32 characters. +# +KEY = should_be_changed + +# +# The shared password will be read from this file. +# Only the first 32 characters will be used. +# +# KEY_FILE = @sysconfdir@/secret.key diff --git a/sample-config/pnp/rra.cfg-sample b/sample-config/pnp/rra.cfg-sample new file mode 100644 index 0000000..7c427f5 --- /dev/null +++ b/sample-config/pnp/rra.cfg-sample @@ -0,0 +1,36 @@ +# +# Define the default RRA Step in seconds +# More Infos on +# http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +# +RRA_STEP=60 +# +# PNP default RRA config +# +# you will get 400kb of data per datasource +# +# 2880 entries with 1 minute step = 48 hours +# +RRA:AVERAGE:0.5:1:2880 +# +# 2880 entries with 5 minute step = 10 days +# +RRA:AVERAGE:0.5:5:2880 +# +# 4320 entries with 30 minute step = 90 days +# +RRA:AVERAGE:0.5:30:4320 +# +# 5840 entries with 360 minute step = 4 years +# +RRA:AVERAGE:0.5:360:5840 + +RRA:MAX:0.5:1:2880 +RRA:MAX:0.5:5:2880 +RRA:MAX:0.5:30:4320 +RRA:MAX:0.5:360:5840 + +RRA:MIN:0.5:1:2880 +RRA:MIN:0.5:5:2880 +RRA:MIN:0.5:30:4320 +RRA:MIN:0.5:360:5840 diff --git a/scripts/Makefile.in b/scripts/Makefile.in new file mode 100644 index 0000000..ebcee9a --- /dev/null +++ b/scripts/Makefile.in @@ -0,0 +1,52 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +LOGDIR=@localstatedir@ +CFGDIR=@sysconfdir@ +BINDIR=@bindir@ +LIBEXECDIR=@libexecdir@ +CGIDIR=@sbindir@ +INIT_DIR=@init_dir@ +INIT_OPTS=-o root -g root +HTMLDIR=@datarootdir@ +INSTALL=@INSTALL@ +INSTALL_OPTS=@INSTALL_OPTS@ +PERFDATADIR=@PERFDATA_DIR@ + +CP=@CP@ + +all html: + +clean: + +distclean: clean + -rm -f process_perfdata.pl check_pnp_rrds.pl net2pnp.pl rc.npcd rc.pnp_gearman_worker rrd_convert.pl + -rm -f Makefile + +devclean: distclean + +install-init: + $(INSTALL) -m 755 $(INIT_OPTS) -d $(DESTDIR)$(INIT_DIR) + $(INSTALL) -m 755 $(INIT_OPTS) rc.npcd $(DESTDIR)$(INIT_DIR)/npcd + $(INSTALL) -m 755 $(INIT_OPTS) rc.pnp_gearman_worker $(DESTDIR)$(INIT_DIR)/pnp_gearman_worker + +install-processperfdata: + $(INSTALL) -m 755 $(INSTALL_OPTS) process_perfdata.pl $(DESTDIR)$(LIBEXECDIR) + +install-plugins: + $(INSTALL) -m 755 $(INSTALL_OPTS) check_pnp_rrds.pl $(DESTDIR)$(LIBEXECDIR) + +install-rrdconvert: + $(INSTALL) -m 755 $(INSTALL_OPTS) rrd_convert.pl $(DESTDIR)$(LIBEXECDIR) + +install-rrdmodify: + $(INSTALL) -m 755 $(INSTALL_OPTS) rrd_modify.pl $(DESTDIR)$(LIBEXECDIR) + +install: + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(PERFDATADIR) + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LIBEXECDIR) + $(INSTALL) -m 755 $(INSTALL_OPTS) -d $(DESTDIR)$(LOGDIR)/stats + $(MAKE) install-processperfdata + $(MAKE) install-plugins + $(MAKE) install-rrdconvert + $(MAKE) install-rrdmodify + diff --git a/scripts/check_pnp_rrds.pl.in b/scripts/check_pnp_rrds.pl.in new file mode 100644 index 0000000..be08e52 --- /dev/null +++ b/scripts/check_pnp_rrds.pl.in @@ -0,0 +1,298 @@ +#!@PERL@ +# nagios: -epn +## check_pnp_rrds - PNP4Nagios. +## Copyright (c) 2006-2009 Joerg Linge (http://www.pnp4nagios.org) +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## 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 Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +use File::Find; +use File::Basename; +use warnings; +use strict; +use Getopt::Long; + +my $read_input; +if (eval {require "Term/ReadKey.pm"}) { + import Term::ReadKey; + $read_input = \&read_key; +} else { + $read_input = \&read_stdin; +} + +Getopt::Long::Configure('bundling'); +my ( $opt_V, $opt_h, $opt_b ); +my $opt_a = 7; +my $opt_dxml = 0; +my $opt_drrd = 0; +my $opt_w = 1; +my $opt_c = 10; +my $opt_t = 10; +my $opt_p = "@PERFDATA_DIR@"; +my $opt_ncmd = "/usr/local/nagios/var/rw/nagios.cmd"; +my $opt_phost = ""; +my $opt_pservice = ""; +my $opt_ignore; +my $VERSION = "@PKG_VERSION@"; +my $PROGNAME = basename($0); +my $PASV = 0; +my $USER = getpwuid($<); + +sub print_help () ; +sub print_usage () ; + +GetOptions( + "V" => \$opt_V, + "version" => \$opt_V, + "h" => \$opt_h, + "help" => \$opt_h, + "t=i" => \$opt_t, + "timeout=i" => \$opt_t, + "w=i" => \$opt_w, + "warning=i" => \$opt_w, + "c=i" => \$opt_c, + "critical=i" => \$opt_c, + "fileage=i" => \$opt_a, + "a=i" => \$opt_a, + "deletexml" => \$opt_dxml, + "deleterrd" => \$opt_drrd, + "p=s" => \$opt_p, + "rrdpath=s" => \$opt_p, + "passiv-hostname=s" => \$opt_phost, + "passiv-servicedesc=s" => \$opt_pservice, + "nagios-cmd=s" => \$opt_ncmd, + "ignore-hosts=s" => \$opt_ignore, +) or print_help(); + + + +print_help() if ($opt_h); + +my $RRD_ERRORS = 0; +my $RRD_ERR = ""; +my $RRD_AGE = ""; +my $XML_COUNT_AGE = 0; +my $XML_COUNT = 0; +my $RRD_COUNT = 0; +my $RC = 0; +my $OUT = "OK: "; +my $PERF = ""; + +$SIG{'ALRM'} = sub { + print "UNKNOWN: Timeout after $opt_t sec.\n"; + exit 3; +}; + +alarm($opt_t); + +$PASV = 1 if($opt_phost && $opt_pservice && $opt_ncmd); + +if($PASV == 1 && !-e $opt_ncmd){ + print "\n\nUNKNOWN: $opt_ncmd does not exist\n\n"; + print_usage(); + exit 3; +} + +if($PASV == 1 && !-w $opt_ncmd){ + print "\n\nUNKNOWN: $opt_ncmd is not writable by \"$USER\" \n\n"; + print_usage(); + exit 3; +} + +if ( -r $opt_p ) { + find { no_chdir => 1, + wanted => \&inspect_files, + } => $opt_p +} +else { + print "UNKNOWN: $opt_p not readable\n"; + exit 3; +} + +sub inspect_files { + my $file = $File::Find::name; + return unless m/\.xml$/; + return unless -f $file; + my $found = -1; + my $TXT = "invalid xml file"; + my $host; + my $service; + my $dir = $File::Find::dir; + if ( $file =~ /\.xml/ ) { + $service = basename($file); + $host = dirname($file); + $host = basename($host); + + if ( defined $opt_ignore && $host =~ $opt_ignore ) { + return; + } + + $XML_COUNT++; + open F, $file or print "couldn't open $file\n" && return; + while () { + if (m/(.*)<\/RC>/) { + $found = $1; + } + if ( $found != 0 && m/(.*)<\/TXT>/ ) { + $TXT = $1; + last; + } + } + close F; + my $mtime = ( stat($file) )[9]; + my $fileage = ( ( time() - $mtime ) / 86400 ); + if ( $fileage >= ( $opt_a ) ) { + if ($opt_dxml) { + print $host . " / " . $service . " is ".$fileage." days old. Delete? (y/n/q) "; + my $ret1 = &$read_input; +# my $ret1 = <>; + if ($ret1 =~ /y/i) { + if (! unlink($file)) { + print " ...Deletion of $file failed!"; + } else { + print " ...Deleted file $file."; + } + } elsif ($ret1 =~ /q/i) { + exit; + } + print "\n"; + + if ($opt_drrd) { + my $rrd = $file; + $rrd =~ s/\.[^.]+$//; + $rrd .= ".rrd"; + if (-e $rrd) { + print " Delete " . basename($rrd) . "? (y/n/q) "; + my $ret2 = &$read_input; + if ($ret2 =~ /y/i) { + unlink($rrd) ? print " $rrd deleted." : print " Deletion of $rrd failed."; + } elsif ($ret2 =~/q/i) { + exit; + } + } + } + print "\n\n"; + } else { + $XML_COUNT_AGE++; + $RRD_AGE .= sprintf(".../%s/%s is %d days old.\n",$host,$service,$fileage); + } + } + $RRD_ERRORS++ if $found != "0"; + $RRD_ERR .= ".../$host/$service $TXT\n" if $found != 0; + } + else { + return; + } +} + +sub PROCESS_SERVICE_CHECK_RESULT { + my $RC = shift; + my $OUT = shift; + my $time = time(); + my $CommandLine = "[$time] PROCESS_SERVICE_CHECK_RESULT;$opt_phost;$opt_pservice;$RC;$OUT"; + + print "PROCESS_SERVICE_CHECK_RESULT\n"; + print $OUT; + + open(CommandFile, ">>$opt_ncmd"); + print CommandFile $CommandLine; + close CommandFile; +} + + +if ( $XML_COUNT == 0 ) { + print "UNKNOWN: No XML files found in $opt_p\n"; + exit 3; +} + +if ( $RRD_ERRORS >= $opt_w || $XML_COUNT_AGE >= $opt_w ) { + $RC = 1; + $OUT = "WARNING: "; +} +if ( $RRD_ERRORS >= $opt_c || $XML_COUNT_AGE >= $opt_c ) { + $RC = 2; + $OUT = "CRITICAL: "; +} + +$OUT .= "$XML_COUNT XML Files checked. $RRD_ERRORS RRD Errors found. $XML_COUNT_AGE old XML Files found"; +$PERF = " | total=$XML_COUNT errors=$RRD_ERRORS;$opt_w;$opt_c;0;$XML_COUNT old=$XML_COUNT_AGE;$opt_w;$opt_c;0;$XML_COUNT\n"; +$OUT .= $PERF . $RRD_ERR . $RRD_AGE; +if($PASV == 0){ + print $OUT; + exit $RC; +}else{ + PROCESS_SERVICE_CHECK_RESULT($RC,$OUT); +} + +sub print_help (){ + print "Copyright (c) 2008 Joerg Linge, Pitchfork\@pnp4nagios.org\n\n"; + print "\n"; + print "$PROGNAME $VERSION\n"; + print "$PROGNAME is used to find old or unusable RRD Files\n"; + print "\n"; + print_usage(); + print "\n"; + print "\n"; + print_support(); + exit 3; +} + +sub print_usage () { + print "USAGE: $PROGNAME [OPTIONS]\n"; + print " -w,--warning\n"; + print " Default: $opt_w\n"; + print " -c,--critical\n"; + print " Default: $opt_c\n"; + print " -a,--fileage Max XML File Age.\n"; + print " Default: $opt_a Days\n"; + print " -p,--rrdpath Path to your RRD and XML Files.\n"; + print " Default: $opt_p\n"; + print " -t,--timeout Max Plugin Runtime.\n"; + print " Default: $opt_t Seconds\n"; + print " --ignore-hosts \n"; + print " Regular expression to ignore a set of hosts"; + print "\n\n"; + print " --deletexml\n"; + print " delete old XML files (interactive). \n"; + print " --deleterrd\n"; + print " delete old RRD files (interactive, only if --deletexml). \n"; + print "\n\n"; + print " --passiv-hostname=\n"; + print " Nagios Hostname\n"; + print " --passiv-servicedesc=\n"; + print " Nagios Servicedesc\n"; + print " --nagios-cmd=\n"; + print " External Command File (nagios.cmd)\n"; + +} + +sub print_support { + print "SUPPORT: http://www.pnp4nagios.org/pnp/\n"; + print "\n\n"; +} + +sub read_stdin { + my $rk; + $rk = <>; + return $rk; +} + +sub read_key { + my $rk; + ReadMode('cbreak'); + $rk = ReadKey(0); + ReadMode('normal'); + return $rk; +} +# vim: set ai tabstop=4 shiftwidth=4 diff --git a/scripts/process_perfdata.pl.in b/scripts/process_perfdata.pl.in new file mode 100644 index 0000000..4cc3d83 --- /dev/null +++ b/scripts/process_perfdata.pl.in @@ -0,0 +1,1596 @@ +#!@PERL@ +# nagios: -epn +## @PKG_NAME@–@PKG_VERSION@ +## Copyright (c) 2005-2010 Joerg Linge (http://www.pnp4nagios.org) +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## 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 Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +@PERL_LIB_PATH_CODE@ + +if( $< == 0 ){ + print "dont try this as root \n"; + exit 1; +} + +use warnings; +use strict; +use POSIX; +use Getopt::Long; +use Time::HiRes qw(gettimeofday tv_interval); +use vars qw ( $TEMPLATE %NAGIOS $t0 $t1 $rt $delayed_write $rrdfile @ds_create $count $line $name $ds_update $dstype %CTPL); + +my %conf = ( + TIMEOUT => 15, + CFG_DIR => "@sysconfdir@/", + USE_RRDs => 1, + RRDPATH => "@PERFDATA_DIR@", + RRDTOOL => "@RRDTOOL@", + RRD_STORAGE_TYPE => "SINGLE", + RRD_HEARTBEAT => 8640, + RRA_STEP => 60, + RRA_CFG => "@sysconfdir@/rra.cfg", + STATS_DIR => "@localstatedir@/stats", + LOG_FILE => "@PERFDATA_LOG@", + LOG_FILE_MAX_SIZE => "10485760", #Truncate after 10MB + LOG_LEVEL => @DEBUG@, + XML_ENC => "UTF-8", + XML_UPDATE_DELAY => 0, # Write XML only if file is older then XML_UPDATE_DELAY seconds + RRD_DAEMON_OPTS => "", + GEARMAN_HOST => "localhost:4730", # How many gearman worker childs to start + PREFORK => 2, # How many gearman worker childs to start + REQUESTS_PER_CHILD => 20000, # Restart after a given count of requests + ENCRYPTION => 1, # Decrypt mod_gearman packets + KEY => 'should_be_changed', + KEY_FILE => '@sysconfdir@/secret.key', + UOM2TYPE => { 'c' => 'DERIVE', 'd' => 'DERIVE' }, +); + +my %const = ( + XML_STRUCTURE_VERSION => "@XML_STRUCTURE_VERSION@", + VERSION => "@PKG_VERSION@", +); + +# +# Dont change anything below these lines ... +# +# +# "rrdtool create" Syntax +# +my @default_rrd_create = ( "RRA:AVERAGE:0.5:1:2880", "RRA:AVERAGE:0.5:5:2880", "RRA:AVERAGE:0.5:30:4320", "RRA:AVERAGE:0.5:360:5840", "RRA:MAX:0.5:1:2880", "RRA:MAX:0.5:5:2880", "RRA:MAX:0.5:30:4320", "RRA:MAX:0.5:360:5840", "RRA:MIN:0.5:1:2880", "RRA:MIN:0.5:5:2880", "RRA:MIN:0.5:30:4320", "RRA:MIN:0.5:360:5840", ); + +Getopt::Long::Configure('bundling'); +my ( $opt_d, $opt_V, $opt_h, $opt_i, $opt_n, $opt_b, $opt_s, $opt_gm, $opt_pidfile,$opt_daemon ); +my $opt_t = my $opt_t_default = $conf{TIMEOUT}; # Default Timeout +my $opt_c = $conf{CFG_DIR} . "process_perfdata.cfg"; +GetOptions( + "V" => \$opt_V, + "version" => \$opt_V, + "h" => \$opt_h, + "help" => \$opt_h, + "i" => \$opt_i, + "inetd" => \$opt_i, + "b=s" => \$opt_b, + "bulk=s" => \$opt_b, + "d=s" => \$opt_d, + "datatype=s" => \$opt_d, + "t=i" => \$opt_t, + "timeout=i" => \$opt_t, + "c=s" => \$opt_c, + "config=s" => \$opt_c, + "n" => \$opt_n, + "npcd" => \$opt_n, + "s" => \$opt_s, + "stdin" => \$opt_s, + "gearman:s" => \$opt_gm, + "daemon" => \$opt_daemon, + "pidfile=s" => \$opt_pidfile, +); + +parse_config($opt_c); +$conf{'GLOBAL_RRD_STORAGE_TYPE'} = uc($conf{'RRD_STORAGE_TYPE'}); # store the initial value for later use + +my %stats = init_stats(); +my $cypher; + +# +# RRDs Perl Module Detection +# +if ( $conf{USE_RRDs} == 1 ) { + unless ( eval "use RRDs;1" ) { + $conf{USE_RRDs} = 0; + } +} + +# +# Include Gearman modules if needed +# +if ( defined($opt_gm) ) { + unless ( eval "use Gearman::Worker;1" ) { + print "Perl module Gearman::Worker not found\n"; + exit 1; + } + unless ( eval "use MIME::Base64;1" ) { + print "Perl module MIME::Base64 not found\n"; + exit 1; + } + unless ( eval "use Crypt::Rijndael;1" ) { + print "Perl module Crypt::Rijndael not found\n"; + exit 1; + } +} + +print_help() if ($opt_h); +print_version() if ($opt_V); + +# Use the timeout specified on the command line and if none use what is in the configuration +# If timeout is not in command line or the config file use the default +$opt_t = $conf{TIMEOUT} if ( $opt_t == $opt_t_default && $opt_t != $conf{TIMEOUT} ); +print_log( "Default Timeout: $opt_t_default secs.", 2 ); +print_log( "Config Timeout: $conf{TIMEOUT} secs.", 2 ); +print_log( "Actual Timeout: $opt_t secs.", 2 ); + +init_signals(); +my %children = (); # keys are current child process IDs +my $children = 0; # current number of children +if( ! defined($opt_gm) ){ + # + # synchronos / bulk / npcd mode + # + main(); +}else{ + # + # Gearman worker main loop + # + print_log( "process_perfdata.pl-$const{VERSION} Gearman Worker Daemon", 0 ); + if($opt_gm =~ /:\d+/ ){ + $conf{'GEARMAN_HOST'} = $opt_gm; + } + if($conf{ENCRYPTION} == 1){ + print_log( "Encryptions is enabled", 0 ); + read_keyfile($conf{'KEY_FILE'}); + # fill key up to 32 bytes + $conf{'KEY'} = substr($conf{'KEY'},0,32) . chr(0) x ( 32 - length( $conf{'KEY'} ) ); + $cypher = Crypt::Rijndael->new( $conf{'KEY'}, Crypt::Rijndael::MODE_ECB() ); + } + daemonize(); +} + +# +# Subs +# +# Main function to switch to the right mode. +sub main { + my $job = shift; + my $t0 = [gettimeofday]; + my $t1; + my $rt; + my $lines = 0; + # Gearman Worker + if (defined $opt_gm) { + print_log( "Gearman Worker Job start", 1 ); + %NAGIOS = parse_env($job->arg); + $lines = process_perfdata(); + $t1 = [gettimeofday]; + $rt = tv_interval $t0, $t1; + $stats{runtime} += $rt; + $stats{rows}++; + if( ( int $stats{timet} / 60 ) < ( int time / 60 )){ + store_internals(); + init_stats(); + } + print_log( "Gearman job end (runtime ${rt}s) ...", 1 ); + return 1; + } elsif ( $opt_b && !$opt_n && !$opt_s ) { + # Bulk mode + alarm($opt_t); + print_log( "process_perfdata.pl-$const{VERSION} starting in BULK Mode called by Nagios", 1 ); + $lines = process_perfdata_file(); + } elsif ( $opt_b && $opt_n && !$opt_s ) { + # Bulk mode with npcd + alarm($opt_t); + print_log( "process_perfdata.pl-$const{VERSION} starting in BULK Mode called by NPCD", 1 ); + $lines = process_perfdata_file(); + } elsif ( $opt_s ) { + # STDIN mode + alarm($opt_t); + print_log( "starting in STDIN Mode", 1 ); + $lines = process_perfdata_stdin(); + } else { + # Synchronous mode + $opt_t = 5 if $opt_t > 5; # maximum timeout + alarm($opt_t); + print_log( "process_perfdata.pl-$const{VERSION} starting in SYNC Mode", 1 ); + %NAGIOS = parse_env(); + $lines = process_perfdata(); + } + $rt = tv_interval $t0, $t1; + $stats{runtime} = $rt; + $stats{rows} = $lines; + store_internals(); + print_log( "PNP exiting (runtime ${rt}s) ...", 1 ); + exit 0; +} + +# +# Parse %ENV and return a global hash %NAGIOS +# +sub parse_env { + my $job_data = shift; + %NAGIOS = (); + $NAGIOS{DATATYPE} = "SERVICEPERFDATA"; + + if(defined $opt_gm){ + # Gearman Worker + $job_data = decode_base64($job_data); + if($conf{ENCRYPTION} == 1){ + $job_data = $cypher->decrypt( $job_data ); + } + my @LINE = split(/\t/, $job_data); + foreach my $k (@LINE) { + $k =~ /([A-Z 0-9_]+)::(.*)$/; + $NAGIOS{$1} = $2 if ($2); + } + if ( !$NAGIOS{HOSTNAME} ) { + print_log( "Gearman job data missmatch. Please check your encryption key.", 0 ); + return %NAGIOS; + } + } elsif ( defined($opt_b) || defined($opt_s) ){ + # Bulk Mode/Stdin Mode + my @LINE = split(/\t/, $job_data); + foreach my $k (@LINE) { + $k =~ /([A-Z 0-9_]+)::(.*)$/; + $NAGIOS{$1} = $2 if ($2); + } + }else{ + + if ( ( !$ENV{NAGIOS_HOSTNAME} ) and ( !$ENV{ICINGA_HOSTNAME} ) ) { + print_log( "Cant find Nagios Environment. Exiting ....", 1 ); + exit 2; + } + foreach my $key ( sort keys %ENV ) { + if ( $key =~ /^(NAGIOS|ICINGA)_(.*)/ ) { + $NAGIOS{$2} = $ENV{$key}; + } + } + + } + + if ($opt_d) { + $NAGIOS{DATATYPE} = $opt_d; + } + + $NAGIOS{DISP_HOSTNAME} = $NAGIOS{HOSTNAME}; + $NAGIOS{DISP_SERVICEDESC} = $NAGIOS{SERVICEDESC}; + $NAGIOS{HOSTNAME} = cleanup( $NAGIOS{HOSTNAME} ); + $NAGIOS{SERVICEDESC} = cleanup( $NAGIOS{SERVICEDESC} ); + $NAGIOS{PERFDATA} = $NAGIOS{SERVICEPERFDATA}; + $NAGIOS{CHECK_COMMAND} = $NAGIOS{SERVICECHECKCOMMAND}; + + if ( $NAGIOS{DATATYPE} eq "HOSTPERFDATA" ) { + $NAGIOS{SERVICEDESC} = "_HOST_"; + $NAGIOS{DISP_SERVICEDESC} = "Host Perfdata"; + $NAGIOS{PERFDATA} = $NAGIOS{HOSTPERFDATA}; + $NAGIOS{CHECK_COMMAND} = $NAGIOS{HOSTCHECKCOMMAND}; + } + print_log( "Datatype set to '$NAGIOS{DATATYPE}' ", 2 ); + return %NAGIOS; +} + +# +# Perfdata sanity check +# +sub process_perfdata { + if ( keys( %NAGIOS ) == 1 && defined($opt_gm) ) { + $stats{skipped}++; + return 1; + } + if ( ! defined($NAGIOS{PERFDATA}) && ! defined($opt_gm) ) { + print_log( "No Performance Data for $NAGIOS{HOSTNAME} / $NAGIOS{SERVICEDESC} ", 1 ); + if ( !$opt_b && !$opt_s ) { + print_log( "PNP exiting ...", 1 ); + exit 3; + } + } + + if ( $NAGIOS{PERFDATA} =~ /^(.*)\s\[(.*)\]$/ ) { + $NAGIOS{PERFDATA} = $1; + $NAGIOS{CHECK_COMMAND} = $2; + print_log( "Found Perfdata from Distributed Server $NAGIOS{HOSTNAME} / $NAGIOS{SERVICEDESC} ($NAGIOS{PERFDATA})", 1 ); + } + else { + print_log( "Found Performance Data for $NAGIOS{HOSTNAME} / $NAGIOS{SERVICEDESC} ($NAGIOS{PERFDATA}) ", 1 ); + } + + $NAGIOS{PERFDATA} =~ s/,/./g; + $NAGIOS{PERFDATA} =~ s/\s+=/=/g; + $NAGIOS{PERFDATA} =~ s/=\s+/=/g; + $NAGIOS{PERFDATA} =~ s/\\n//g; + $NAGIOS{PERFDATA} .= " "; + parse_perfstring( $NAGIOS{PERFDATA} ); + return 1; +} + +# +# Process Perfdata in Bulk Mode +# +sub process_perfdata_file { + if ( $opt_b =~ /-PID-(\d+)/ ) { + print_log( "Oops: $opt_b already processed by $1 - please check timeout settings", 0 ); + } + + print_log( "searching for $opt_b", 2 ); + if ( -e "$opt_b" ) { + my $pdfile = "$opt_b" . "-PID-" . $$; + print_log( "renaming $opt_b to $pdfile for bulk update", 2 ); + unless ( rename "$opt_b", "$pdfile" ) { + print_log( "ERROR: rename $opt_b to $pdfile failed", 1 ); + exit 4; + } + + print_log( "reading $pdfile for bulk update", 2 ); + open( PDFILE, "< $pdfile" ); + my $count = 0; + while () { + my $job_data = $_; + $count++; + print_log( "Processing Line $count", 2 ); + my @LINE = split(/\t/); + %NAGIOS = (); # cleaning %NAGIOS Hash + #foreach my $k (@LINE) { + # $k =~ /([A-Z 0-9_]+)::(.*)$/; + # $ENV{ 'NAGIOS_' . $1 } = $2 if ($2); + #} + parse_env($job_data); + if ( $NAGIOS{SERVICEPERFDATA} || $NAGIOS{HOSTPERFDATA} ) { + process_perfdata(); + } else { + print_log( "No Perfdata. Skipping line $count", 2 ); + $stats{skipped}++; + } + } + + print_log( "$count lines processed", 1 ); + + if ( unlink("$pdfile") == 1 ) { + print_log( "$pdfile deleted", 1 ); + }else { + print_log( "Could not delete $pdfile:$!", 1 ); + } + return $count; + } + else { + print_log( "ERROR: File $opt_b not found", 1 ); + } +} + +# +# Process Perfdata in STDIN Mode +# +sub process_perfdata_stdin { + print_log( "reading from STDIN for bulk update", 2 ); + my $count = 0; + while () { + my $job_data = $_; + $count++; + print_log( "Processing Line $count", 2 ); + my @LINE = split(/\t/); + %NAGIOS = (); # cleaning %NAGIOS Hash + parse_env($job_data); + if ( $NAGIOS{SERVICEPERFDATA} || $NAGIOS{HOSTPERFDATA} ) { + process_perfdata(); + } else { + print_log( "No Perfdata. Skipping line $count", 2 ); + $stats{skipped}++; + } + } + + print_log( "$count lines processed", 1 ); + return $count; +} + +# +# Write Data to RRD Files +# +sub data2rrd { + + my @data = @_; + my @rrd_state = (); + my $rrd_storage_type; + + print_log( "data2rrd called", 2 ); + $NAGIOS{XMLFILE} = $conf{RRDPATH} . "/" . $data[0]{hostname} . "/" . $data[0]{servicedesc} . ".xml"; + $NAGIOS{SERVICEDESC} = $data[0]{servicedesc}; + $NAGIOS{DISP_SERVICEDESC} = $data[0]{disp_servicedesc}; + $NAGIOS{AUTH_SERVICEDESC} = $data[0]{auth_servicedesc} || ""; + $NAGIOS{AUTH_HOSTNAME} = $data[0]{auth_hostname} || ""; + $NAGIOS{MULTI_PARENT} = ""; + $NAGIOS{MULTI_PARENT} = $data[0]{multi_parent} || ""; + $TEMPLATE = $data[0]{template}; + + unless ( -d "$conf{RRDPATH}" ) { + unless ( mkdir "$conf{RRDPATH}" ) { + print_log( "mkdir $conf{RRDPATH}, permission denied ", 1 ); + print_log( "PNP exiting ...", 1 ); + exit 5; + } + } + + unless ( -d "$conf{RRDPATH}/$NAGIOS{HOSTNAME}" ) { + unless ( mkdir "$conf{RRDPATH}/$NAGIOS{HOSTNAME}" ) { + print_log( "mkdir $conf{RRDPATH}/$NAGIOS{HOSTNAME}, permission denied ", 1 ); + print_log( "PNP exiting ...", 1 ); + exit 6; + } + } + + # + # Create PHP Template File + # + open_template( $NAGIOS{XMLFILE} ); + + @ds_create = (); + $ds_update = ''; + + for my $i ( 0 .. $#data ) { + print_log( " -- Job $i ", 3 ); + my $DS = $i + 1; + + # + # for each datasource + # + for my $job ( sort keys %{ $data[$i] } ) { + if ( defined $data[$i]{$job} ) { + print_log( " -- $job -> $data[$i]{$job}", 3 ); + } + } + + if ( uc($conf{'GLOBAL_RRD_STORAGE_TYPE'}) eq "MULTIPLE" ) { + my $file = $conf{RRDPATH} . "/" . $data[$i]{hostname} . "/" . $data[$i]{servicedesc} . ".rrd"; + if ( -e $file ){ + print_log("RRD_STORAGE_TYPE=MULTIPLE ignored because $file exists!", 1 ) if $i == 0; + $data[$i]{rrd_storage_type} = "SINGLE"; + } + } + + if ( $i == 0 ){ + $ds_update = "$data[$i]{timet}"; + } + + if ( $data[$i]{rrd_storage_type} eq "MULTIPLE" ) { + print_log( "DEBUG: MULTIPLE Storage Type", 3 ); + $DS = 1; + # PNP 0.4.x Template compatibility + $NAGIOS{RRDFILE} = ""; + + # + $rrd_storage_type = "MULTIPLE"; + $rrdfile = $conf{RRDPATH} . "/" . $data[$i]{hostname} . "/" . $data[$i]{servicedesc} . "_" . $data[$i]{name} . ".rrd"; + + # DS is set to 1 + @ds_create = "DS:$DS:$data[$i]{dstype}:$data[$i]{rrd_heartbeat}:$data[$i]{rrd_min}:$data[$i]{rrd_max}"; + $ds_update = "$data[$i]{timet}:$data[$i]{value}"; + @rrd_state = write_rrd(); + @ds_create = (); + $ds_update = ""; + } + else { + print_log( "DEBUG: SINGLE Storage Type", 3 ); + + # PNP 0.4.x Template compatibility + $NAGIOS{RRDFILE} = $conf{RRDPATH} . "/" . $data[0]{hostname} . "/" . $data[0]{servicedesc} . ".rrd"; + + # + $rrd_storage_type = "SINGLE"; + $rrdfile = $conf{RRDPATH} . "/" . $data[$i]{hostname} . "/" . $data[$i]{servicedesc} . ".rrd"; + push( @ds_create, "DS:$DS:$data[$i]{dstype}:$data[$i]{rrd_heartbeat}:$data[$i]{rrd_min}:$data[$i]{rrd_max}" ); + $ds_update = "$ds_update:$data[$i]{value}"; + } + + write_to_template( "TEMPLATE", $data[0]{template} ); + write_to_template( "RRDFILE", $rrdfile ); + write_to_template( "RRD_STORAGE_TYPE", $data[$i]{rrd_storage_type} ); + write_to_template( "RRD_HEARTBEAT", $data[$i]{rrd_heartbeat} ); + write_to_template( "IS_MULTI", $data[0]{multi} ); + write_to_template( "DS", $DS ); + write_to_template( "NAME", $data[$i]{name} ); + write_to_template( "LABEL", $data[$i]{label} ); + write_to_template( "UNIT", $data[$i]{uom} ); + write_to_template( "ACT", $data[$i]{value} ); + write_to_template( "WARN", $data[$i]{warning} ); + write_to_template( "WARN_MIN", $data[$i]{warning_min} ); + write_to_template( "WARN_MAX", $data[$i]{warning_max} ); + write_to_template( "WARN_RANGE_TYPE", $data[$i]{warning_range_type} ); + write_to_template( "CRIT", $data[$i]{critical} ); + write_to_template( "CRIT_MIN", $data[$i]{critical_min} ); + write_to_template( "CRIT_MAX", $data[$i]{critical_max} ); + write_to_template( "CRIT_RANGE_TYPE", $data[$i]{critical_range_type} ); + write_to_template( "MIN", $data[$i]{min} ); + write_to_template( "MAX", $data[$i]{max} ); + + } + + if ( $rrd_storage_type eq "SINGLE" ) { + @rrd_state = write_rrd(); + } + + write_state_to_template(@rrd_state); + write_env_to_template(); + close_template( $NAGIOS{XMLFILE} ); +} + +sub write_rrd { + my @rrd_create = (); + my @rrd_state = (); + + print_log( "DEBUG: TPL-> $TEMPLATE", 3 ); + print_log( "DEBUG: CRE-> @ds_create", 3 ); + print_log( "DEBUG: UPD-> $ds_update", 3 ); + + if ( !-e "$rrdfile" ) { + @rrd_create = parse_rra_config($TEMPLATE); + if ( $conf{USE_RRDs} == 1 ) { + print_log( "RRDs::create $rrdfile @rrd_create @ds_create --start=$NAGIOS{TIMET} --step=$conf{RRA_STEP}", 2 ); + RRDs::create( "$rrdfile", @rrd_create, @ds_create, "--start=$NAGIOS{TIMET}", "--step=$conf{RRA_STEP}" ); + + my $err = RRDs::error(); + if ($err) { + print_log( "RRDs::create $rrdfile @rrd_create @ds_create --start=$NAGIOS{TIMET} --step=$conf{RRA_STEP}", 0 ); + print_log( "RRDs::create ERROR $err", 0 ); + @rrd_state = ( 1, $err ); + $stats{error}++; + } + else { + print_log( "$rrdfile created", 2 ); + @rrd_state = ( 0, "just created" ); + $stats{create}++; + } + } + else { + print_log( "RRDs Perl Modules are not installed. Falling back to rrdtool system call.", 2 ); + print_log( "$conf{RRDTOOL} create $rrdfile @rrd_create @ds_create --start=$NAGIOS{TIMET} --step=$conf{RRA_STEP}", 2 ); + system("$conf{RRDTOOL} create $rrdfile @rrd_create @ds_create --start=$NAGIOS{TIMET} --step=$conf{RRA_STEP}"); + if ( $? > 0 ) { + print_log( "$conf{RRDTOOL} create $rrdfile @rrd_create @ds_create --start=$NAGIOS{TIMET} --step=$conf{RRA_STEP}", 0 ); + print_log( "rrdtool create returns $?", 0 ); + @rrd_state = ( $?, "create failed" ); + $stats{error}++; + } + else { + print_log( "rrdtool create returns $?", 1 ); + @rrd_state = ( 0, "just created" ); + $stats{create}++; + } + } + } + else { + if ( $conf{USE_RRDs} == 1 ) { + if ( $conf{RRD_DAEMON_OPTS} ) { + print_log( "RRDs::update --daemon=$conf{RRD_DAEMON_OPTS} $rrdfile $ds_update", 2 ); + RRDs::update( "--daemon=$conf{RRD_DAEMON_OPTS}", "$rrdfile", "$ds_update" ); + } + else { + print_log( "RRDs::update $rrdfile $ds_update", 2 ); + RRDs::update( "$rrdfile", "$ds_update" ); + } + my $err = RRDs::error(); + if ($err) { + print_log( "RRDs::update $rrdfile $ds_update", 0 ); + print_log( "RRDs::update ERROR $err", 0 ); + @rrd_state = ( 1, $err ); + $stats{error}++; + } + else { + print_log( "$rrdfile updated", 2 ); + @rrd_state = ( 0, "successful updated" ); + $stats{update}++; + } + } + else { + print_log( "RRDs Perl Modules are not installed. Falling back to rrdtool system call.", 2 ); + if ( $conf{RRD_DAEMON_OPTS} ) { + print_log( "$conf{RRDTOOL} update --daemon=$conf{RRD_DAEMON_OPTS} $rrdfile $ds_update", 2 ); + system("$conf{RRDTOOL} update --daemon=$conf{RRD_DAEMON_OPTS} $rrdfile $ds_update"); + } + else { + print_log( "$conf{RRDTOOL} update $rrdfile $ds_update", 2 ); + system("$conf{RRDTOOL} update $rrdfile $ds_update"); + } + if ( $? > 0 ) { + print_log( "$conf{RRDTOOL} update $rrdfile $ds_update", 0 ); + print_log( "rrdtool update returns $?", 0 ); + @rrd_state = ( $?, "update failed" ); + $stats{error}++; + } + else { + print_log( "rrdtool update returns $?", 1 ); + @rrd_state = ( $?, "successful updated" ); + $stats{update}++; + } + } + } + return @rrd_state; +} + +# +# Write Template +# +sub open_template { + my $xmlfile = shift; + $delayed_write = 0; + if( -e $xmlfile ){ + my $mtime = (stat($xmlfile))[9]; + my $t = time(); + my $age = ($t - $mtime); + if ( $age < $conf{'XML_UPDATE_DELAY'} ){ + print_log( "DEBUG: XML File is $age seconds old. No update needed", 3 ); + $delayed_write = 1; + return; + } + print_log( "DEBUG: XML File is $age seconds old. UPDATE!", 3 ); + } + open( XML, "> $xmlfile.$$" ) or die "Cant create temporary XML file ", $!; + print XML "\n"; + print XML "\n"; +} + +# +# Close Template FH +# +sub close_template { + return if $delayed_write == 1; + my $xmlfile = shift; + printf( XML " \n" ); + printf( XML " %d\n", $const{'XML_STRUCTURE_VERSION'} ); + printf( XML " \n" ); + + printf( XML "\n" ); + close(XML); + rename( "$xmlfile.$$", "$xmlfile" ); +} + +# +# Add Lines +# +sub write_to_template { + return if $delayed_write == 1; + my $tag = shift; + my $data = shift; + if ( !defined $data ) { + $data = ""; + } + if ( $tag =~ /^TEMPLATE$/ ) { + printf( XML " \n" ); + printf( XML " <%s>%s\n", $tag, "$data", $tag ); + } + elsif ( $tag =~ /^MAX$/ ) { + printf( XML " <%s>%s\n", $tag, "$data", $tag ); + printf( XML " \n" ); + } + else { + printf( XML " <%s>%s\n", $tag, "$data", $tag ); + } +} + +sub write_state_to_template { + return if $delayed_write == 1; + my @rrd_state = @_; + printf( XML " \n" ); + printf( XML " %s\n", $rrd_state[0] ); + printf( XML " %s\n", $rrd_state[1] ); + printf( XML " \n" ); +} + +# +# Store the complete Nagios ENV +# +sub write_env_to_template { + return if $delayed_write == 1; + foreach my $key ( sort keys %NAGIOS ) { + $NAGIOS{$key} = urlencode($NAGIOS{$key}); + printf( XML " %s\n", $key, $NAGIOS{$key}, $key ); + } +} + +# +# Recursive Template search +# +sub adjust_template { + my $command = shift; + my $uom = shift; + my $count = shift; + my @temp_template = split /\!/, $command; + my $initial_template = cleanup( $temp_template[0] ); + my $template = cleanup( $temp_template[0] ); + %CTPL = ( + UOM => $uom, + COUNT => $count, + COMMAND => $command, + TEMPLATE => $template, + DSTYPE => $dstype, + RRD_STORAGE_TYPE => $conf{'RRD_STORAGE_TYPE'}, + RRD_HEARTBEAT => $conf{'RRD_HEARTBEAT'}, + USE_MIN_ON_CREATE => 0, + USE_MAX_ON_CREATE => 0, + ); + + read_custom_template ( ); + # + if ( $CTPL{'TEMPLATE'} ne $initial_template ){ + read_custom_template ( ); + } + return %CTPL; +} + + +# +# Analyse check_command to find PNP Template . +# +sub read_custom_template { + my $command = $CTPL{'COMMAND'}; + my $uom = $CTPL{'UOM'}; + my $count = $CTPL{'COUNT'}; + my @dstype_list = (); + my $use_min_on_create = 0; + my $use_max_on_create = 0; + my $rrd_storage_type = $CTPL{'RRD_STORAGE_TYPE'}; + my $rrd_heartbeat = $CTPL{'RRD_HEARTBEAT'}; + + if ( defined($conf{'UOM2TYPE'}{$uom}) ) { + $dstype = $conf{'UOM2TYPE'}{$uom}; + print_log( "DEBUG: DSTYPE adjusted to $dstype by UOM", 3 ); + }else { + $dstype = 'GAUGE'; + } + + print_log( "DEBUG: RAW Command -> $command", 3 ); + my @temp_template = split /\!/, $command; + my $template = cleanup( $temp_template[0] ); + $template = trim($template); + my $template_cfg = "$conf{CFG_DIR}/check_commands/$template.cfg"; + print_log( "DEBUG: read_custom_template() => $command", 3 ); + if ( -e $template_cfg ) { + print_log( "DEBUG: adjust_template() => $template_cfg", 3 ); + my $initial_dstype = $dstype; + open FH, "<", $template_cfg; + while () { + next if /^#/; + next if /^$/; + s/#.*//; + s/ //g; + if (/^(.*)=(.*)$/) { + if ( $1 eq "DATATYPE" ) { + $dstype = uc($2); + $dstype =~ s/ //g; + @dstype_list = split /,/, $dstype; + if ( exists $dstype_list[$count] && $dstype_list[$count] =~ /^(COUNTER|GAUGE|ABSOLUTE|DERIVE)$/ ) { + $dstype = $dstype_list[$count]; + print_log( "Adapting RRD Datatype to \"$dstype\" as defined in $template_cfg with key $count", 2 ); + } + elsif ( $dstype =~ /^(COUNTER|GAUGE|ABSOLUTE|DERIVE)$/ ) { + print_log( "Adapting RRD Datatype to \"$dstype\" as defined in $template_cfg", 2 ); + } + else { + print_log( "RRD Datatype \"$dstype\" defined in $template_cfg is invalid", 2 ); + $dstype = $initial_dstype; + } + + } + if ( $1 eq "CUSTOM_TEMPLATE" ) { + print_log( "Adapting Template using ARG $2", 2 ); + my $i = 1; + my @keys = split /,/, $2; + foreach my $keys (@keys) { + if ( $i == 1 && exists $temp_template[$keys] ) { + $template = trim( $temp_template[$keys] ); + print_log( "Adapting Template to $template.php (added ARG$keys)", 2 ); + }elsif( exists $temp_template[$keys] ){ + $template .= "_" . trim( $temp_template[$keys] ); + print_log( "Adapting Template to $template.php (added ARG$keys)", 2 ); + } + $i++; + } + print_log( "Adapting Template to $template.php as defined in $template_cfg", 2 ); + } + if ( $1 eq "USE_MIN_ON_CREATE" && $2 eq "1" ) { + $use_min_on_create = 1; + } + if ( $1 eq "USE_MAX_ON_CREATE" && $2 eq "1" ) { + $use_max_on_create = 1; + } + if ( $1 eq "RRD_STORAGE_TYPE" && uc($2) eq "MULTIPLE" ) { + $rrd_storage_type = uc($2); + } + if ( $1 eq "RRD_HEARTBEAT" ) { + $rrd_heartbeat = $2; + } + } + } + close FH; + } + else { + print_log( "No Custom Template found for $template ($template_cfg) ", 3 ); + print_log( "RRD Datatype is $dstype", 3 ); + } + print_log( "Template is $template.php", 3 ); + $CTPL{'COMMAND'} = $template; + $CTPL{'TEMPLATE'} = $template; + $CTPL{'DSTYPE'} = $dstype; + $CTPL{'RRD_STORAGE_TYPE'} = $rrd_storage_type; + $CTPL{'RRD_HEARTBEAT'} = $rrd_heartbeat; + $CTPL{'USE_MIN_ON_CREATE'} = $use_min_on_create; + $CTPL{'USE_MAX_ON_CREATE'} = $use_max_on_create; + return %CTPL; +} + +# +# Parse process_perfdata.cfg +# +sub parse_config { + my $config_file = shift; + my $line = 0; + + if ( -e $config_file ) { + open CFG, '<', "$config_file"; + while () { + $line++; + chomp; + s/ //g; + next if /^#/; + next if /^$/; + s/#.*//; + + if (/^(.*)=(.*)$/) { + if ( defined $conf{$1} ) { + $conf{$1} = $2; + } + } + } + close CFG; + print_log( "Using Config File $config_file parameters", 2 ); + } + else { + print_log( "Config File $config_file not found, using defaults", 2 ); + } +} + +# +# Parse rra.cfg +# +sub parse_rra_config { + my $template = shift; + my $rra_template = ""; + my @rrd_create = @default_rrd_create; + if ( -r $conf{'CFG_DIR'} . "/" . $template . ".rra.cfg" ) { + $rra_template = $conf{'CFG_DIR'} . "/" . $template . ".rra.cfg"; + print_log( "Reading $rra_template", 2 ); + } + elsif ( -r $conf{'RRA_CFG'} ) { + $rra_template = $conf{'RRA_CFG'}; + print_log( "Reading $conf{'RRA_CFG'}", 2 ); + } + else { + print_log( "No usable rra.cfg found. Using default values.", 2 ); + } + + if ( $rra_template ne "" ) { + @rrd_create = (); + open RRA, "<", $rra_template; + while () { + next if /^#/; + next if /^$/; + s/#.*//; + if(/^RRA_STEP=(\d+)/i){ + $conf{'RRA_STEP'} = $1; + next; + } + chomp; + push @rrd_create, "$_"; + } + close RRA; + } + else { + @rrd_create = @default_rrd_create; + } + return @rrd_create; + +} + +# +# Function adapted from Nagios::Plugin::Performance +# Thanks to Gavin Carr and Ton Voon +# + +sub _parse { + # Nagios::Plugin::Performance + my $string = shift; + my $tmp_string = $string; + $string =~ s/^([^=]+)=(U|[\d\.\-]+)([\w\/%]*);?([\d\.\-:~@]+)?;?([\d\.\-:~@]+)?;?([\d\.\-]+)?;?([\d\.\-]+)?;?\s*//; + + if ( $tmp_string eq $string ) { + print_log( "No pattern match in function _parse($string)", 2 ); + return undef; + } + + return undef unless ( ( defined $1 && $1 ne "" ) && ( defined $2 && $2 ne "" ) ); + + # create hash from all performance data values + + my %p = ( + "label" => $1, + "name" => $1, + "value" => $2, + "uom" => $3, + "warning" => $4, + "critical" => $5, + "min" => $6, + "max" => $7 + ); + + $p{label} =~ s/[&"']//g; # cleanup + $p{name} =~ s/["']//g; # cleanup + $p{name} =~ s/[\/\\]/_/g; # cleanup + $p{name} = cleanup($p{name}); + + if ( $p{uom} eq "%" ) { + $p{uom} = "%%"; + print_log( "DEBUG: UOM adjust = $p{uom}", 3 ); + } + + # + # Check for warning and critical ranges + # + if ( $p{warning} && $p{warning} =~ /^([\d\.\-~@]+)?:([\d\.\-~@]+)?$/ ) { + print_log( "DEBUG: Processing warning ranges ( $p{warning} )", 3 ); + $p{warning_min} = $1; + $p{warning_max} = $2; + delete( $p{warning} ); + if ( $p{warning_min} =~ /^@/ ) { + $p{warning_min} =~ s/@//; + $p{warning_range_type} = "inside"; + } + else { + $p{warning_range_type} = "outside"; + } + } + if ( $p{critical} && $p{critical} =~ /^([\d\.\-~@]+)?:([\d\.\-~@]+)?$/ ) { + print_log( "DEBUG: Processing critical ranges ( $p{critical} )", 3 ); + $p{critical_min} = $1; + $p{critical_max} = $2; + delete( $p{critical} ); + if ( $p{critical_min} =~ /^@/ ) { + $p{critical_min} =~ s/@//; + $p{critical_range_type} = "inside"; + } + else { + $p{critical_range_type} = "outside"; + } + } + # Strip Range indicators + $p{warning} =~ s/[~@]// if($p{warning}); + $p{critical} =~ s/[~@]// if($p{critical}); + + return ( $string, %p ); +} + +# +# clean Strings +# +sub cleanup { + my $string = shift; + if ($string) { + $string =~ s/[& :\/\\]/_/g; + } + return $string; +} + +# +# Urlencode +# +sub urlencode { + my $string = shift; + if ($string) { + $string =~ s/([<>&])/sprintf("%%%02x",ord($1))/eg; # URLencode; + } + return $string; +} + +# +# Trim leading whitespaces +# +sub trim { + my $string = shift; + $string =~ s/^\s*//g; + return $string; +} + +# +# Parse the Performance String and call data2rrd() +# +sub parse_perfstring { + + # + # Default RRD Datatype + # Value will be overwritten by adjust_template() + # + my %CTPL = (); + $dstype = "GAUGE"; + my $perfstring = shift; + my $is_multi = "0"; + my @perfs; + my @multi; + my %p; + my $use_min_on_create = 0; + my $use_max_on_create = 0; + + # + # check_multi + # + if ( $perfstring =~ /^[']?([a-zA-Z0-9\.\-_\s\/\#]+)::([a-zA-Z0-9\.\-_\s]+)::([^=]+)[']?=/ ) { + $is_multi = 1; + print_log( "check_multi Perfdata start", 3 ); + my $count = 0; + my $check_multi_blockcount = 0; + my $multi_parent = cleanup( $NAGIOS{SERVICEDESC} ); + my $auth_servicedesc = $NAGIOS{DISP_SERVICEDESC}; + while ($perfstring) { + ( $perfstring, %p ) = _parse($perfstring); + if ( !$p{label} ) { + print_log( "Invalid Perfdata detected ", 1 ); + $stats{invalid}++; + @perfs = (); + last; + } + if ( $p{label} =~ /^[']?([a-zA-Z0-9\.\-_\s\/\#]+)::([a-zA-Z0-9\.\-_\s]+)::([^=]+)[']?$/ ) { + @multi = ( $1, $2, $3 ); + if ( $count == 0 ) { + print_log( "DEBUG: First check_multi block", 3 ); + + # Keep servicedesc while processing the first block. + $p{servicedesc} = cleanup( $NAGIOS{SERVICEDESC} ); + $p{disp_servicedesc} = $NAGIOS{DISP_SERVICEDESC}; + $p{auth_servicedesc} = $auth_servicedesc; + $p{multi} = 1; + $p{multi_parent} = $multi_parent; + } + else { + print_log( "DEBUG: A new check_multi block ($count) starts", 3 ); + $p{servicedesc} = cleanup( $multi[0] ); # Use the multi servicedesc. + $p{multi} = 2; + $p{multi_parent} = $multi_parent; + $p{servicedesc} = cleanup( $multi[0] ); # Use the multi servicedesc. + $p{disp_servicedesc} = cleanup( $multi[0] ); # Use the multi servicedesc. + $p{auth_servicedesc} = $auth_servicedesc; + data2rrd(@perfs) if ( $#perfs >= 0 ); # Process when a new block starts. + @perfs = (); # Clear the perfs array. + # reset check_multi block count + $check_multi_blockcount = 0; + } + %CTPL = adjust_template( $multi[1], $p{uom}, $check_multi_blockcount++ ); + + if ( $CTPL{'USE_MAX_ON_CREATE'} == 1 && defined $p{max} ) { + $p{rrd_max} = $p{max}; + } else { + $p{rrd_max} = "U"; + } + if ( $CTPL{'USE_MIN_ON_CREATE'} == 1 && defined $p{min} ) { + $p{rrd_min} = $p{min}; + } elsif( $CTPL{'DSTYPE'} eq 'DERIVE' ){ + $p{rrd_min} = 0; # Add minimum value 0 if DSTYPE = DERIVE + } else { + $p{rrd_min} = "U"; + } + $p{template} = $CTPL{'TEMPLATE'}; + $p{dstype} = $CTPL{'DSTYPE'}; + $p{rrd_storage_type} = $CTPL{'RRD_STORAGE_TYPE'}; + $p{rrd_heartbeat} = $CTPL{'RRD_HEARTBEAT'}; + $p{label} = cleanup( $multi[2] ); # store the original label from check_multi header + $p{name} = cleanup( $multi[2] ); # store the original label from check_multi header + $p{hostname} = cleanup( $NAGIOS{HOSTNAME} ); + $p{disp_hostname} = $NAGIOS{DISP_HOSTNAME}; + $p{auth_hostname} = $NAGIOS{HOSTNAME}; + $p{timet} = $NAGIOS{TIMET}; + push @perfs, {%p}; + $count++; + } + else { + print_log( "DEBUG: Next check_multi data for block $count multiblock $check_multi_blockcount", 3 ); + + # additional check_multi data + %CTPL = adjust_template( $multi[1], $p{uom}, $check_multi_blockcount++ ); + + if ( $CTPL{'USE_MAX_ON_CREATE'} == 1 && defined $p{max} ) { + $p{rrd_max} = $p{max}; + } else { + $p{rrd_max} = "U"; + } + + if ( $CTPL{'USE_MIN_ON_CREATE'} == 1 && defined $p{min} ) { + $p{rrd_min} = $p{min}; + } elsif( $CTPL{'DSTYPE'} eq 'DERIVE' ){ + $p{rrd_min} = 0; # Add minimum value 0 if DSTYPE = DERIVE + } else { + $p{rrd_min} = "U"; + } + + $p{template} = $CTPL{'TEMPLATE'}; + $p{dstype} = $CTPL{'DSTYPE'}; + $p{rrd_storage_type} = $CTPL{'RRD_STORAGE_TYPE'}; + $p{rrd_heartbeat} = $CTPL{'RRD_HEARTBEAT'}; + $p{hostname} = cleanup( $NAGIOS{HOSTNAME} ); + $p{disp_hostname} = $NAGIOS{DISP_HOSTNAME}; + $p{auth_hostname} = $NAGIOS{HOSTNAME}; + $p{timet} = $NAGIOS{TIMET}; + if ( $count == 1 ) { + $p{servicedesc} = cleanup( $NAGIOS{SERVICEDESC} ); # Use the servicedesc. + $p{disp_servicedesc} = $NAGIOS{DISP_SERVICEDESC}; # Use the servicedesc. + } else { + $p{servicedesc} = cleanup( $multi[0] ); # Use the multi servicedesc. + $p{disp_servicedesc} = $multi[0]; # Use the multi servicedesc. + } + $p{multi} = $is_multi; + $p{multi_parent} = $multi_parent; + $p{auth_servicedesc} = $auth_servicedesc; # Use the servicedesc. + push @perfs, {%p}; + } + } + data2rrd(@perfs) if ( $#perfs >= 0 ); + @perfs = (); + } else { + + # + # Normal Performance Data + # + print_log( "DEBUG: Normal perfdata", 3 ); + my $count = 0; + while ($perfstring) { + ( $perfstring, %p ) = _parse($perfstring); + if ( !$p{label} ) { + print_log( "Invalid Perfdata detected ", 1 ); + @perfs = (); + last; + } + %CTPL = adjust_template( $NAGIOS{CHECK_COMMAND}, $p{uom}, $count ); + + if ( $CTPL{'USE_MAX_ON_CREATE'} == 1 && defined $p{max} ) { + $p{rrd_max} = $p{max}; + } else { + $p{rrd_max} = "U"; + } + if ( $CTPL{'USE_MIN_ON_CREATE'} == 1 && defined $p{min} ) { + $p{rrd_min} = $p{min}; + } elsif ( $CTPL{'DSTYPE'} eq 'DERIVE' ){ + $p{rrd_min} = 0; # Add minimum value 0 if DSTYPE = DERIVE + } else { + $p{rrd_min} = "U"; + } + + $p{template} = $CTPL{'TEMPLATE'}; + $p{dstype} = $CTPL{'DSTYPE'}; + $p{rrd_storage_type} = $CTPL{'RRD_STORAGE_TYPE'}; + $p{rrd_heartbeat} = $CTPL{'RRD_HEARTBEAT'}; + $p{multi} = $is_multi; + $p{hostname} = cleanup( $NAGIOS{HOSTNAME} ); + $p{disp_hostname} = $NAGIOS{DISP_HOSTNAME}; + $p{auth_hostname} = $NAGIOS{DISP_HOSTNAME}; + $p{servicedesc} = cleanup( $NAGIOS{SERVICEDESC} ); + $p{disp_servicedesc} = $NAGIOS{DISP_SERVICEDESC}; + $p{auth_servicedesc} = $NAGIOS{DISP_SERVICEDESC}; + $p{timet} = $NAGIOS{TIMET}; + + push @perfs, {%p}; + $count++; + } + data2rrd(@perfs) if ( $#perfs >= 0 ); + @perfs = (); + } +} + +# +# Write to Logfile +# +sub print_log { + my $out = shift; + my $severity = shift; + if ( $severity <= $conf{LOG_LEVEL} ) { + open( LOG, ">>" . $conf{LOG_FILE} ) || die "Can't open logfile ($conf{LOG_FILE}) ", $!; + if ( -s LOG > $conf{LOG_FILE_MAX_SIZE} ) { + truncate( LOG, 0 ); + printf( LOG "File truncated" ); + } + my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) = localtime(time); + printf( LOG "%02d-%02d-%02d %02d:%02d:%02d [%d] [%d] %s\n", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $$, $severity, $out ); + close(LOG); + } +} + +# +# Signals and Handlers +# +sub init_signals { + $SIG{'INT'} = \&handle_signal; + $SIG{'QUIT'} = \&handle_signal; + $SIG{'ALRM'} = \&handle_signal; + $SIG{'ILL'} = \&handle_signal; + $SIG{'ABRT'} = \&handle_signal; + $SIG{'FPE'} = \&handle_signal; + $SIG{'SEGV'} = \&handle_signal; + $SIG{'TERM'} = \&handle_signal; + $SIG{'BUS'} = \&handle_signal; + $SIG{'SYS'} = \&handle_signal; + $SIG{'XCPU'} = \&handle_signal; + $SIG{'XFSZ'} = \&handle_signal; + $SIG{'IOT'} = \&handle_signal; + $SIG{'PIPE'} = \&handle_signal; + $SIG{'HUP'} = \&handle_signal; + $SIG{'CHLD'} = \&handle_signal; +} + +# +# Handle Signals +# +sub handle_signal { + my ($signal) = (@_); + # + # Gearman child process + # + if ( defined ( $opt_gm ) ){ + if($signal eq "CHLD" && defined($opt_gm) ){ + my $pid = waitpid(-1, &WNOHANG); + if($pid == -1){ + print_log( "### no hanging child ###", 1 ); + } elsif ( WIFEXITED($?)) { + print_log( "### child $pid exited ###", 1 ); + $children--; + } else { + print_log( "### wrong signal ###", 1 ); + $children--; + } + $SIG{'CHLD'} = \&handle_signal; + } + if($signal eq "INT" || $signal eq "TERM"){ + local($SIG{CHLD}) = 'IGNORE'; # we're going to kill our children + kill $signal => keys %children; + print_log( "*** process_perfdata.pl terminated on signal $signal", 0 ); + pidlock("remove"); + exit; # clean up with dignity + } + print_log( "*** process_perfdata.pl received signal $signal (ignored)", 0 ); + }else{ + if ( $signal eq "ALRM" ) { + print_log( "*** TIMEOUT: Timeout after $opt_t secs. ***", 0 ); + if ( $opt_b && !$opt_n && !$opt_s ) { + print_log( "*** TIMEOUT: Deleting current file to avoid loops", 0 ); + print_log( "*** TIMEOUT: Please check your process_perfdata.cfg", 0 ); + } + elsif ( $opt_b && $opt_n && !$opt_s ) { + print_log( "*** TIMEOUT: Deleting current file to avoid NPCD loops", 0 ); + print_log( "*** TIMEOUT: Please check your process_perfdata.cfg", 0 ); + } + if ($opt_b && !$opt_s ) { + my $pdfile = "$opt_b" . "-PID-" . $$; + if ( unlink("$pdfile") == 1 ) { + print_log( "*** TIMEOUT: $pdfile deleted", 0 ); + } + else { + print_log( "*** TIMEOUT: Could not delete $pdfile:$!", 0 ); + } + } + my $temp_file = "$conf{RRDPATH}/$NAGIOS{HOSTNAME}/$NAGIOS{SERVICEDESC}.xml.$$"; + if ( -f $temp_file ) { + unlink($temp_file); + } + $t1 = [gettimeofday]; + $rt = tv_interval $t0, $t1; + $stats{runtime} = $rt; + print_log( "*** Timeout while processing Host: \"$NAGIOS{HOSTNAME}\" Service: \"$NAGIOS{SERVICEDESC}\"", 0 ); + print_log( "*** process_perfdata.pl terminated on signal $signal", 0 ); + exit 7; + } + } +} + + +sub init_stats { + %stats = ( + timet => time, + error => 0, + invalid => 0, + skipped => 0, + runtime => 0, + rows => 0, + create => 0, + update => 0, + ); +} + +# +# Store some internal runtime infos +# +sub store_internals { + if( ! -w $conf{'STATS_DIR'}){ + print_log("*** ERROR: ".$conf{'STATS_DIR'}." is not writable or does not exist",0); + return; + } + my $statsfile = $conf{'STATS_DIR'}."/".(int $stats{timet} / 60); + open( STAT, ">> $statsfile" ) or die "Cant create statistic file ", $!; + printf(STAT "%d %f %d %d %d %d %d %d\n", $stats{timet},$stats{runtime},$stats{rows},$stats{update},$stats{create},$stats{error},$stats{invalid},$stats{skipped}); + close(STAT); + check_internals(); +} + +# +# Search for statistic files +# +sub check_internals { + my $file; + my @files; + opendir(STATS, $conf{'STATS_DIR'}); + while ( defined ( my $file = readdir STATS) ){ + next if $file =~ /^\.\.?$/; # skip . and .. + next if $file =~ /-PID-/; # skip temporary files + next if $file == (int $stats{timet} / 60); # skip our current file + push @files, $file; + } + read_internals(@files); +} + +# +# Read and aggregate files found by check_internals() +# +sub read_internals { + my @files = @_; + my @chunks; + foreach my $file (sort { $a <=> $b} @files){ + unless ( rename($conf{'STATS_DIR'}."/".$file, $conf{'STATS_DIR'}."/".$file."-PID-".$$) ){ + print_log( "ERROR: renaming stats file " . $conf{'STATS_DIR'}."/".$file . " to " . $conf{'STATS_DIR'}."/".$file."-PID-".$$ . " failed", 1 ); + next; + } + open( STAT, "< ".$conf{'STATS_DIR'}."/".$file."-PID-".$$ ); + %stats = ( + timet => 0, + error => 0, + invalid => 0, + skipped => 0, + runtime => 0, + rows => 0, + create => 0, + update => 0, + ); + while(){ + @chunks = split(); + $stats{timet} = $chunks[0]; + $stats{runtime} += $chunks[1]; + $stats{rows} += $chunks[2]; + $stats{update} += $chunks[3]; + $stats{create} += $chunks[4]; + $stats{error} += $chunks[5]; + $stats{invalid} += $chunks[6]; + $stats{skipped} += $chunks[7]; + } + close(STAT); + unlink($conf{'STATS_DIR'}."/".$file."-PID-".$$); + process_internals(); + } +} +# +# +# +sub process_internals { + my $last_rrd_dtorage_type = $conf{'RRD_STORAGE_TYPE'}; + $conf{'RRD_STORAGE_TYPE'} = "MULTIPLE"; + %NAGIOS = ( + HOSTNAME => '.pnp-internal', + DISP_HOSTNAME => 'pnp-internal', + SERVICEDESC => 'runtime', + DISP_SERVICEDESC => 'runtime', + TIMET => $stats{timet}, + DATATYPE => 'SERVICEPERFDATA', + CHECK_COMMAND => 'pnp-runtime', + PERFDATA => "runtime=".$stats{runtime}."s rows=".$stats{rows}." errors=".$stats{error}." invalid=".$stats{invalid}." skipped=".$stats{skipped} ." update=".$stats{update}. " create=".$stats{create} + ); + parse_perfstring( $NAGIOS{PERFDATA} ); + $conf{'RRD_STORAGE_TYPE'} = $last_rrd_dtorage_type; +} + +# +# Gearman Worker Daemon +# +sub daemonize { + if( defined($opt_daemon) ){ + print_log("daemonize init",1); + chdir '/' or die "Can't chdir to /: $!"; + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!"; + open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!"; + defined( my $pid = fork ) or die "Can't fork: $!"; + exit if $pid; + pidlock("create"); + setsid or die "Can't start a new session: $!"; + } else { + pidlock("create"); + } + # Fork off our children. + for (1 .. $conf{'PREFORK'}) { + new_child(); + print_log( "starting child process $children", 1 ); + } + while (1) { + sleep; # wait for a signal (i.e., child's death) + for (my $i = $children; $i < $conf{'PREFORK'}; $i++) { + print_log("starting new child (running = $i)",1); + new_child(); # top up the child pool + } + } + return; +} + +# +# start a new worker process +# +sub new_child { + my $pid; + my $sigset; + my $req = 0; + # block signal for fork + $sigset = POSIX::SigSet->new(SIGINT); + sigprocmask(SIG_BLOCK, $sigset) + or die "Can't block SIGINT for fork: $!\n"; + + die "fork: $!" unless defined ($pid = fork); + + if ($pid) { + # Parent records the child's birth and returns. + sigprocmask(SIG_UNBLOCK, $sigset) + or die "Can't unblock SIGINT for fork: $!\n"; + $children{$pid} = 1; + $children++; + return; + } else { + # Child can *not* return from this subroutine. + $SIG{INT} = 'DEFAULT'; # make SIGINT kill us as it did before + + # unblock signals + sigprocmask(SIG_UNBLOCK, $sigset) + or die "Can't unblock SIGINT for fork: $!\n"; + + my $worker = Gearman::Worker->new(); + my @job_servers = split(/,/, $conf{'GEARMAN_HOST'}); # allow multiple gearman job servers + $worker->job_servers(@job_servers); + $worker->register_function("perfdata", 2, sub { return main(@_); }); + my %opt = ( + on_complete => sub { $req++; }, + stop_if => sub { if ( $req > $conf{'REQUESTS_PER_CHILD'} ) { return 1;}; } + ); + print_log("connecting to gearmand '".$conf{'GEARMAN_HOST'}."'",0); + $worker->work( %opt ); + print_log("max requests per child reached (".$conf{'REQUESTS_PER_CHILD'}.")",1); + # this exit is VERY important, otherwise the child will become + # a producer of more and more children, forking yourself into + # process death. + exit; + } +} +# +# Create a pid file +# +sub pidlock { + return unless defined $opt_pidfile; + my $action = shift; + my $PIDFILE = $opt_pidfile; + if($action eq "create"){ + if ( -e $PIDFILE ) { + if ( open( OLDPID, "<$PIDFILE" ) ) { + $_ = ; + chop($_); + my $oldpid = $_; + close(OLDPID); + if ( -e "/proc/$oldpid/cmdline" ) { + print_log("Another instance is already running with PID: $oldpid",0); + exit 0; + } else { + print_log("Pidfile $PIDFILE seems to be stale!",0); + print_log("Removing old pidfile",0); + unlink $PIDFILE; + } + } + } + if ( !open( PID, ">$PIDFILE" ) ) { + print_log("Can not create $PIDFILE ( $! )",0); + exit 1; + } + print( PID "$$\n" ); + close(PID); + print_log("Pidfile ($PIDFILE) created",0); + }elsif( $action eq "remove" ){ + if ( -e $PIDFILE ) { + print_log("Removing pidfile ($PIDFILE)",0); + unlink $PIDFILE; + } + } +} + +# +# Read crypt key +# +sub read_keyfile { + my $file = shift; + my $key = ''; + if( -r $file){ + open(FH, "<", $file); + while(){ + chomp(); # avoid \n on last field + $conf{'KEY'} = $_; + last; + } + close(FH); + print_log("Using encryption key specified in '$file'",0); + return 1; + }else{ + print_log("Using encryption key specified in ".$conf{'CFG_DIR'}."/process_perfdata.cfg",0); + return 0; + } +} +# +# +# +sub print_help { + print < + Use process_perfdata.pl to store Nagios Plugin Performance Data into RRD Databases + + Options: + -h, --help + Print detailed help screen + -V, --version + Print version information + -t, --timeout=INTEGER + Seconds before process_perfdata.pl times out (default: $opt_t_default) + -i, --inetd + Use this Option if process_perfdata.pl is executed by inetd/xinetd. + -d, --datatype + Defaults to \"SERVICEPERFDATA\". Use \"HOSTPERFDATA\" to process Perfdata from regular Host Checks + Only used in default or inetd mode + -b, --bulk + Provide a file for bulk update + -s, --stdin + Read input from stdin + -n, --npcd + Hint the program, that it was invoked by NPCD + -c, --config + Optional process_perfdata config file + Default: @sysconfdir@/process_perfdata.cfg + + Gearman Worker Options: + --gearman + Start in Gearman worker mode + --daemon + Run as daemon + --pidfile=/var/run/process_perfdata.pid + The pidfile used while running in as Gearman worker daemon + +EOD + exit 0; +} + +# +# +# +sub print_version { + print "Version: process_perfdata.pl $const{VERSION}\n"; + print "Copyright (c) 2005-2010 Joerg Linge \n"; + exit 0; +} + diff --git a/scripts/rc.npcd.in b/scripts/rc.npcd.in new file mode 100644 index 0000000..c5f2c9e --- /dev/null +++ b/scripts/rc.npcd.in @@ -0,0 +1,162 @@ +#!@SHELL@ +# +### BEGIN INIT INFO +# Provides: npcd +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: @PKG_NAME@ NPCD Daemon Version @PKG_VERSION@ +# Description: Nagios Performance Data C Daemon +### END INIT INFO + +# chkconfig: 345 99 01 +# +# File : npcd +# + +servicename=@npcd_name@ +prefix=@prefix@ +exec_prefix=${prefix} +NpcdBin=@bindir@/@npcd_name@ +NpcdCfgFile=@sysconfdir@/npcd.cfg +NpcdVarDir=@localstatedir@ +NpcdRunFile=/var/run/npcd.pid +NpcdLockDir=/var/lock/subsys +NpcdLockFile=@npcd_name@ +NpcdUser=@nagios_user@ +NpcdGroup=@nagios_grp@ + +status_npcd (){ + pid_npcd + if ps -p $NpcdPID > /dev/null 2>&1; then + return 0 + else + if test -f $NpcdLockDir/$NpcdLockFile; then + return 2 + else + return 1 + fi + fi + return 1 +} + +printstatus_npcd(){ + if status_npcd $1 $2; then + echo "$servicename (pid $NpcdPID) is running..." + exit 0 + elif test $? -eq 2; then + echo "$servicename is not running but subsystem locked" + exit 2 + else + echo "$servicename is not running" + exit 1 + fi +} + +killproc_npcd (){ + kill $2 $NpcdPID +} + +pid_npcd (){ + if test ! -f $NpcdRunFile; then + return 1 + fi + NpcdPID=`head -n 1 $NpcdRunFile` + return 0 +} + + +# Source function library +# Solaris doesn't have an rc.d directory, so do a test first +if [ -f /etc/rc.d/init.d/functions ]; then + . /etc/rc.d/init.d/functions +elif [ -f /etc/init.d/functions ]; then + . /etc/init.d/functions +fi + +# Check that npcd exists. +if [ ! -f $NpcdBin ]; then + echo "Executable file $NpcdBin not found. Exiting." + exit 1 +fi + +# Check that npcd.cfg exists. +if [ ! -f $NpcdCfgFile ]; then + echo "Configuration file $NpcdCfgFile not found. Exiting." + exit 1 +fi + +# See how we were called. +case "$1" in + + start) + status_npcd + if [ $? -eq 0 ]; then + echo "$servicename already started..." + exit 1 + fi + echo -n "Starting $servicename:" + touch $NpcdRunFile + chown $NpcdUser:$NpcdGroup $NpcdRunFile + $NpcdBin -d -f $NpcdCfgFile + if [ -d $NpcdLockDir ]; then touch $NpcdLockDir/$NpcdLockFile; fi + echo " done." + exit 0 + ;; + + stop) + status_npcd + if ! [ $? -eq 0 ]; then + echo "$servicename was not running... could not stop" + exit 1 + fi + echo -n "Stopping $servicename: " + + pid_npcd + killproc_npcd npcd + + # now we have to wait for npcd to exit and remove its + # own NpcdRunFile, otherwise a following "start" could + # happen, and then the exiting npcd will remove the + # new NpcdRunFile, allowing multiple npcd daemons + # to (sooner or later) run - John Sellens + #echo -n 'Waiting for npcd to exit .' + for i in 1 2 3 4 5 6 7 8 9 10 ; do + if status_npcd > /dev/null; then + echo -n '.' + sleep 1 + else + break + fi + done + if status_npcd > /dev/null; then + echo '' + echo 'Warning - $servicename did not exit in a timely manner' + else + echo 'done.' + fi + rm -f $NpcdLockDir/$NpcdLockFile + ;; + + status) + printstatus_npcd + ;; + + reload) + $0 restart + ;; + + restart) + $0 stop + $0 start + ;; + + *) + echo "Usage: $servicename {start|stop|restart|status}" + exit 1 + ;; + +esac + +# End of this script diff --git a/scripts/rc.pnp_gearman_worker.in b/scripts/rc.pnp_gearman_worker.in new file mode 100644 index 0000000..b2325ba --- /dev/null +++ b/scripts/rc.pnp_gearman_worker.in @@ -0,0 +1,113 @@ +#!@SHELL@ + +### BEGIN INIT INFO +# Provides: pnp_gearman_worker +# Required-Start: $all +# Required-Stop: $all +# Should-Start: +# Should-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Start/Stop the pnp4nagios gearman worker +### END INIT INFO + +DAEMON="@libexecdir@/process_perfdata.pl" +CFG="@sysconfdir@/process_perfdata.cfg" +NAME=pnp_gearman_worker +PIDFILE=@localstatedir@/${NAME}.pid +LOCKFILE=/var/lock/subsys/${NAME} +USER=@nagios_user@ +USERID=`id -u` +CMD="$DAEMON --pidfile=$PIDFILE --config=$CFG --gearman --daemon" + +function get_status() { + pid=`cat $PIDFILE 2>/dev/null` + if [ "$pid" != "" ]; then + ps -p $pid > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "$NAME is running with pid $pid" + return 0; + fi + fi + echo "$NAME is not running" + return 1; +} + +function kill_procs() { + pid=`cat $PIDFILE 2>/dev/null` + if [ -z $pid ]; then + echo ". Not running." + else + # do a kill if still now down + ps -p $pid > /dev/null 2>&1 && kill $pid + for x in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5; do + echo -n "." + ps -p $pid > /dev/null 2>&1 && sleep 1; + done + ps -p $pid > /dev/null 2>&1; + if [ $? -ne 0 ]; then + rm -f $PIDFILE + if [ "$USERID" -eq 0 ]; then + rm -f $LOCKFILE + fi + echo "done" + exit 0; + else + echo "failed" + exit 1; + fi + fi +} + +case "$1" in + start) + echo -n "Starting $NAME " + get_status > /dev/null; + if [ $? = 0 ]; then + echo "failed" + echo "$NAME already running" + exit 0; + fi + + if [ "$USERID" -eq 0 ]; then + su -s $SHELL - $USER -c "$CMD" + else + $CMD + fi + if [ $? -eq 0 ]; then + if [ "$USERID" -eq 0 ]; then + touch $LOCKFILE + fi + echo "done" + exit 0; + else + echo "failed" + exit 1; + fi + ;; + stop) + echo -n "Stopping $NAME" + pid=`cat $PIDFILE 2>/dev/null` + if [ -z $pid ]; then + echo ". Not running." + else + # kill if still running + ps -p $pid > /dev/null 2>&1 && kill_procs; + fi + ;; + status) + get_status; + exit $?; + ;; + restart) + $0 stop && sleep 1 && $0 start + exit $? + ;; + *) + echo "Usage: $NAME {start|stop|status|restart}" + exit 1 + ;; +esac + +exit 0 + diff --git a/scripts/rrd_convert.pl.in b/scripts/rrd_convert.pl.in new file mode 100644 index 0000000..4dd3651 --- /dev/null +++ b/scripts/rrd_convert.pl.in @@ -0,0 +1,555 @@ +#!@PERL@ +## @PKG_NAME@–@PKG_VERSION@ rrd_convert.pl +## Copyright (c) 2006-2010 Joerg Linge (http://www.pnp4nagios.org) +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## 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 Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +@PERL_LIB_PATH_CODE@ + +use strict; +use warnings; +use Getopt::Long; +use Time::HiRes qw(gettimeofday tv_interval); +use File::Find; +use File::Copy; + +if( $< == 0 ){ + print "dont try this as root \n"; + exit 1; +} + +# +# Some global Vars +# + +my %conf = ( + CFG_DIR => "@sysconfdir@/", + RRDPATH => "@PERFDATA_DIR@", + RRDTOOL => "@RRDTOOL@", + LOG_LEVEL => 0, + DRY_RUN => 0, + FORCE => 0, + RRD_BACKUP => 1, + RRD_STORAGE_TYPE => "SINGLE", + TMP_DIR => '/tmp/rrd_convert', + RRD_DAEMON_OPTS => "", + XML_MAX_AGE => 3600, +); + +Getopt::Long::Configure('bundling'); +my ( $opt_V, $opt_h, $opt_c, $opt_l, $opt_x, $opt_p ); +# defaults +$opt_x = 1; + +GetOptions( + "V|version" => \$opt_V, + "h|help" => \$opt_h, + "c|check_command=s" => \$opt_c, + "p|cfg_dir=s" => \$opt_p, + "l|list_commands" => \$opt_l, + "x|no_structure_check" => \$opt_x, + "d|dry-run" => \$conf{DRY_RUN}, + "t|tmp_dir=s" => \$conf{TMP_DIR}, + "force" => \$conf{FORCE}, +); + +print_help() if $opt_h; +print_help_opt_p() if !$opt_p; +print_help() if !$opt_c and !$opt_l; +print_version() if $opt_V; + +if($opt_p){ + $conf{CFG_DIR} = $opt_p; +} +parse_config($conf{CFG_DIR}."/process_perfdata.cfg"); +if ( $conf{RRD_DAEMON_OPTS} ){ + $conf{RRD_DAEMON_OPTS} = "--daemon=".$conf{RRD_DAEMON_OPTS}; +} + +my @STRUCT; +my %FILEHANDLE; + +my @commands; # list of commands +my @worklist; # list of found xml files + +my %ds_list; +my %original_ds_list; +my $max_age = time() - $conf{XML_MAX_AGE}; + +my %stats = ( + 'rrd_in' => 0, + 'rrd_out' => 0, + 'old_xml' => 0, + 'xml_without_rrd' => 0, + 'runtime' => 0, +); + +main(); + +sub main{ + check_storage_type(); + find(\&wanted_xml_files, $conf{RRDPATH}); + summary(); + if($opt_l){ # List commands and exit + summary_command_list(); + exit; + } + if($#worklist+1 > 0 ){ + my $answer = read_choice("Start Converter [n|y]?"); + unless ( $answer =~ m/^y$/i ){ + print "Exit...\n"; + exit; + } + }else{ + print "Check Command '".$opt_c."' not found in any XML File\n"; + print "\n"; + print "\n"; + summary_command_list(); + exit; + } + check_custom_template(); + write_custom_template(); + my $t0 = [gettimeofday]; + my $i = 0; + foreach my $xmlfile ( @worklist ) { + $i++; + undef %ds_list; + undef %original_ds_list; + my($host,$service) = parse_xml_filename($xmlfile); + my ($rrdfile) = $xmlfile =~ /^(.*)\.xml$/; + $rrdfile .= ".rrd"; + if(-r $rrdfile){ + create_dir($conf{TMP_DIR}); + my $dumpfile = sprintf("%s/%s-%s.dump",$conf{TMP_DIR},$host,$service); + print "File ".$i."/".($#worklist+1)."\n"; + rrdtool_dump($rrdfile,$dumpfile); + parse_pnp_xml($xmlfile); + build_ds_list($rrdfile); + next if check_ds_list(); + open_files($host,$service); + manipulate_rrd_dump($dumpfile); + close_files(); + restore_files($host,$service); + backup_rrd_file($rrdfile); + } + } + my $t1 = [gettimeofday]; + $stats{runtime} = tv_interval $t0, $t1; + print "DONE\n"; + stats(); +} + + +sub build_ds_list{ + my $rrdfile = shift; + my @info; + @info = `$conf{'RRDTOOL'} info $rrdfile`; + if( $? > 0 ){ + print "ERROR: $conf{'RRDTOOL'} info $rrdfile returns with $?\n"; + exit 1; + } + foreach(@info){ + if(m/ds\[(\d+)\]\.type/ ) { + $ds_list{$1} = $1; + } + } + my $test = keys %ds_list; + %original_ds_list = %ds_list; +} + +sub check_ds_list{ + my $rrd_ds_count = keys %ds_list; + my $xml_ds_count = $#STRUCT; + if($rrd_ds_count == $xml_ds_count){ + return 0; + }elsif($rrd_ds_count <= $xml_ds_count && $opt_x){ + printf("OK: RRD contains '%s' DS but XML contains '%s'. Convert forced by --no_structure_check\n",$rrd_ds_count,$xml_ds_count); + return 0; + }else{ + printf ("ERROR: RRD Structure mismatch. DS Count is '%s' but should be '%s'\n",$rrd_ds_count,$xml_ds_count); + return 1; + } +} + +sub wanted_xml_files{ + if(m/.xml$/){ + #printf("File: %s\n",$File::Find::name); + my $xmlfile = $File::Find::name; + my ($rrdfile) = $xmlfile =~ /^(.*)\.xml$/; + $rrdfile .= ".rrd"; + my $mtime = (stat($xmlfile))[9]; + if ( $mtime < $max_age ){ + $stats{old_xml}++; + return; + } + open(XML, $xmlfile); + while () { + if(/TEMPLATE>(.*) $seen{$a} } keys %seen ) { + printf " |- %-36s %5s\n",$key,$seen{$key}; + } +} + +sub stats{ + print "\n\n \\Statistics:\n"; + foreach my $key (sort { $stats{$b} cmp $stats{$a} } keys %stats ) { + printf " |- %-15s %s\n",$key,$stats{$key}; + } +} + +sub create_dir{ + my $dir = shift; + unless ( -d "$dir" ) { + unless ( mkdir "$dir" ) { + print "ERROR: $dir is not writable\n"; + exit 1; + } + } +} + +sub open_files(){ + my $host = shift; + my $service = shift; + foreach my $ds (keys %ds_list){ + my $file = sprintf("%s/%s-%s-%s.restore",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME}); + #print "Open Filehandle ".$file."\n"; + open($FILEHANDLE{$ds}, ">", $file); + } +} + +sub close_files(){ + foreach my $ds (keys %ds_list){ + #$ds--; + #print "Close Filehandle ".$STRUCT[$ds]{NAME}."\n"; + close($FILEHANDLE{$ds}); + } +} + +sub write_to_files{ + my $data = shift; + foreach my $ds (keys %ds_list){ + print { $FILEHANDLE{$ds} } $data; + } +} + +sub restore_files(){ + my $host = shift; + my $service = shift; + my $err; + $| = 1; + print "Restoring File\n"; + foreach my $ds (keys %ds_list){ + my $rrdfile = ''; + my $restorefile = sprintf("%s/%s-%s-%s.restore",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME}); + if( $conf{'DRY_RUN'} == 1 ){ + $rrdfile = sprintf("%s/%s/%s_%s.rrd",$conf{TMP_DIR},$host,$service,$STRUCT[$ds]{NAME}); + create_dir(sprintf("%s/%s", $conf{TMP_DIR},$host )); + }else{ + $rrdfile = sprintf("%s/%s/%s_%s.rrd",$conf{RRDPATH},$host,$service,$STRUCT[$ds]{NAME}); + } + print "$rrdfile\n"; + $err = system("$conf{'RRDTOOL'} restore -f '$restorefile' '$rrdfile'"); + if($err){ + printf("RRDtool Error: %s\n",$err); + exit; + } + unlink($restorefile); + $stats{rrd_out}++; + } + print "... done\n"; + $| = 0; +} + +sub backup_rrd_file{ + my $rrdfile = shift; + if ( $conf{RRD_BACKUP} == 1 ){ + move($rrdfile, $rrdfile.".backup"); + } +} + +sub parse_pnp_xml{ + my $xmlfile = shift; + undef @STRUCT; + #print "reading $xmlfile\n"; + open(XML, $xmlfile); + my $DATASOURCE = 0; + while () { + if(//){ + $DATASOURCE++; + } + if(//){ + $DATASOURCE = 0; + } + if(/<([A-Z_]+)>(.*)<\/[A-Z_]+>/ && $DATASOURCE != -1){ + $STRUCT[$DATASOURCE]{$1} = $2; + } + } + close(XML); + return @STRUCT; +} + +sub rrdtool_dump{ + my $rrdfile = shift; + my $dumpfile = shift; + my $err; + print "RRDtool dump to $dumpfile\n"; + if ( $conf{RRD_DAEMON_OPTS} ){ + $err = system("$conf{'RRDTOOL'} dump $conf{RRD_DAEMON_OPTS} $rrdfile > $dumpfile"); + }else{ + $err = system("$conf{'RRDTOOL'} dump $rrdfile > $dumpfile"); + } + if($err){ + printf("RRDtool Error: %s\n",$err); + exit; + } + $stats{rrd_in}++; + return $dumpfile; +} + +sub manipulate_rrd_dump{ + my $tmpfile = shift; + my $i = 0; + open (XML,$tmpfile); + my @ROW = (); + my $tmpds = 1; + my $inside_ds_block = 0; + print "Manipulating $tmpfile\n"; + while (){ + $i++; + unless ( $i % 5000 ){ + $| = 1; print "."; $| = 0; + } + my $d = $_; + # + # A Data Row + if(m//){ + m/(.*)/; + my $rowstart = $1; + @ROW = m{([^<].*?)<\/v>}gc; + my $fh = 1; + foreach my $VAL (@ROW){ + undef %ds_list; + $ds_list{$fh} = $fh; + write_to_files($rowstart."".$VAL."\n"); + $fh++; + } + next; + } + if(m//){ + $inside_ds_block = 1; + undef %ds_list; + $ds_list{$tmpds} = $tmpds; + write_to_files($d); + $tmpds++; + next; + } + if(m//){ + write_to_files($d); + $inside_ds_block = 0; + $tmpds = 1; + %ds_list = %original_ds_list; + next; + } + if(m/<\/ds>/){ + write_to_files($d); + $inside_ds_block = 0; + # write to all files alter + %ds_list = %original_ds_list; + next; + } + if(m/<\/database>/){ + # write to all files alter + %ds_list = %original_ds_list; + write_to_files($d); + next; + } + if($inside_ds_block == 1){ + # rename DS + $d =~ s/(.*)<\/name>/ 1 <\/name>/; + } + write_to_files($d); + } + close(XML); + print "... done $i lines\n"; + unlink($tmpfile); +} + +# +# Parse process_perfdata.cfg +# +sub parse_config { + my $config_file = shift; + my $line = 0; + if( ! -e $config_file ){ + print "$config_file not found\n"; + exit; + } + if ( -e $config_file ) { + open CFG, '<', "$config_file"; + while () { + $line++; + chomp; + s/ //g; + next if /^#/; + next if /^$/; + s/#.*//; + + if (/^(.*)=(.*)$/) { + if ( defined $conf{$1} ) { + $conf{$1} = $2; + } + } + } + close CFG; + } +} + +# +# Change RRD_STORAGE_TYPE to MULTIPLE +# +sub change_config { + my $cfg_file = $conf{'CFG_DIR'}."/process_perfdata.cfg"; + my $error = system("sed -i -e ".'s/\s*RRD_STORAGE_TYPE\s*=\s*SINGLE/RRD_STORAGE_TYPE=MULTIPLE/i'." $cfg_file"); +} + +sub check_storage_type{ + if($conf{'RRD_STORAGE_TYPE'} eq "MULTIPLE"){ + print "RRD_STORAGE_TYPE is already set to ".$conf{'RRD_STORAGE_TYPE'}."\n"; + } +} +sub check_custom_template { + my $command = $opt_c; + if ( $conf{DRY_RUN} == 1 ){ + print "No config check while DRY_RUN = 1\n"; + return; + } + if ( $command eq "ALL" ){ + return; + } + my $config_file = $conf{'CFG_DIR'}."/check_commands/".$command.".cfg"; + my $storage_type = "MULTIPLE"; + if ( -e $config_file && $conf{'FORCE'} == 0 ) { + print "\nConfig for command $command does already exist ($config_file)\n\n"; + exit 0; + } +} + +sub write_custom_template { + my $command = $opt_c; + if ( $conf{DRY_RUN} == 1 ){ + print "No config check while DRY_RUN = 1\n"; + return; + } + if ( $opt_c eq "ALL"){ + change_config(); + return; + } + my $config_file = $conf{'CFG_DIR'}."/check_commands/".$command.".cfg"; + my $storage_type = "MULTIPLE"; + open(CFG, ">", $config_file); + print CFG "# Generated by rrd_convert.pl @PKG_VERSION@\n"; + print CFG "RRD_STORAGE_TYPE = MULTIPLE\n"; + close(CFG); + if ( -s $config_file ) { + print "\nConfig for command $command created ($config_file)\n"; + } +} +sub read_choice{ + my $question = shift; + print $question.":"; + my $answer = ; + chomp $answer; + return $answer; +} + + +sub print_help{ + print "Usage: $0 --check_command=\n"; + print " --cfg_dir=\n"; + print " [ --list_commands ]\n"; + print " [ --dry-run ]\n"; + print " [ --tmp_dir= ]\n"; + print " [ --no_structure_check ]\n"; + print "\n"; + print "This script is used to switch to RRD_STORAGE_TYPE = MULTIPLE for a given Nagios Check Command\n"; + print "More info online http://docs.pnp4nagios.org/pnp-0.6/rrd_convert\n"; + exit; +} + +sub print_help_opt_p{ + print "\n"; + print "--cfg_dir not set\n"; + print "Please provide the path to your PNP4Nagios config directory\n"; + print "\n"; + print_help(); +} + +sub print_version{ + print "Version @PKG_VERSION@\n"; + exit; +} diff --git a/scripts/rrd_modify.pl.in b/scripts/rrd_modify.pl.in new file mode 100644 index 0000000..241dfcd --- /dev/null +++ b/scripts/rrd_modify.pl.in @@ -0,0 +1,282 @@ +#!@PERL@ -w +# nagios: -epn +## @PKG_NAME@–@PKG_VERSION@ +# +# Copyright (c) 2012 PNP4Nagios Developer Team (http://www.pnp4nagios.org) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# 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 Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# There are several Perl modules out there on www.cpan.org which allow adding +# columns to an RRD file, so if this one doesn't fit your needs please have +# a look there. +# Please report any errors nevertheless. +# See http://docs.pnp4nagios.org/pnp-0.6/about#support for details. + +use strict; +use warnings; + +# you may have to adapt the path to your environment +my $rrdtool = "@RRDTOOL@"; +# set to 1 if using PNP4Nagios where data source names are numerical +my $PNP = 1; + +### ---------------------------------------- ### +### no user servicable parts below this line ### + +my $pgm = "rrd_modify.pl"; +my $version = "0.01"; +my $legal = "Copyright (c) 2012 PNP4Nagios Developer Team (http://www.pnp4nagios.org)"; + +my ($rrd,$action,$columns,$type) = @ARGV; +# valid actions +my %action = (insert => 1, delete => 2); +# valid data types +my %type = (GAUGE => 1, COUNTER => 2, DERIVE => 3, ABSOLUTE => 4, COMPUTE => 5); +# xml tags within cdp_prep +my @cdp = ('primary_value','secondary_value','value', + 'unknown_datapoints','seasonal','last_seasonal', + 'init_flag','intercept','last_intercept', + 'slope','last_slope','nan_count','last_nan_count'); + +my @ds = (); # number of data sources within the rrd file +my $out = 1; # output lines to file +my $sign = "."; # decimal sign (locale dependent) +my %xml = (); # lines within ds structure + +# defined? +if ($#ARGV < 2) { + usage(); + exit 1; +} + +die "$rrd does not exist\n" unless (-f $rrd); +die "$rrd is not readable\n" unless (-r $rrd); +die "$rrd is not writable\n" unless (-w $rrd); +die "$rrdtool is a directory\n" if (-d $rrdtool); +die "$rrdtool does not exist\n" unless (-f $rrdtool); +die "$rrdtool is not executable\n" unless (-x $rrdtool); + +$action = lc($action); +unless (exists($action{$action})) { + print "ERROR: action $action is not valid\n\n"; + usage(); + exit 1; +} + +my ($start,$no) = split(/,/,$columns); +$no = 1 unless (defined $no); +# determine the number of data sources +my $ds = `$rrdtool info $rrd | grep '^ds' | grep 'value' | wc -l`; +# determine the decimal sign +$sign = `$rrdtool info $rrd | grep '^ds' | grep 'value' | tail -1`; +($sign) = $sign =~ /.* \d(.)\d+/; +my $end = ($action eq "insert" ? $ds+$no : $ds); +if (($start < 1) or ($start > $ds + 1)) { + print "ERROR: number ($start) must be within 1..".($ds+1)."\n"; + exit 2; +} + +# check / set type of data source to be created +if ($action eq "insert") { + if (defined $type) { + $type = uc($type); + unless (exists($type{$type})) { + print "ERROR: type $type is not valid\n\n"; + usage(); + exit 3; + } + } else { + $type = "GAUGE"; + } +} + +# names of temporary/output files +my $tmp1 = "$rrd.in"; +my $tmp2 = "$rrd.out"; +my $cmd = "$rrdtool dump $rrd > $tmp1"; +my $erg = system("$cmd"); +print "$cmd: RC=$erg\n" if ($erg); + +processing ("$rrd"); + +$cmd = "$rrdtool restore $tmp2 $rrd.chg"; +$erg = system("$cmd"); +print "$cmd: RC=$erg\n" if ($erg); +unlink "$tmp1"; +unlink "$tmp2"; +exit; + +### some sub routines + +sub processing { + open (IFILE, "$tmp1") || die "error during open of $tmp1, RC=$!\n"; + open (OFILE, ">$tmp2") || die "error during create of $tmp2, RC=$!\n"; + while () { + my $tmp = $_; + if (//) { + $out = 0; + %xml = (); + next; + } + if (/<\/ds>/) { + my %tmp = %xml; + push @ds, \%tmp; + next; + } + if ((m|Round Robin Archives|) or (m||)) { + $out = 1; + if ($action eq "insert") { + my @save = splice(@ds,$start-1); + for (1..$no) { + my %xml = (@save) ? %{$save[0]} : %{$ds[0]}; + $xml{name} = $start+$_-1; + # set defaults + if (m|Round Robin Archives|) { + $xml{last_ds} = "U"; + $xml{value} = "0${sign}0000000000e+00"; + $xml{unknown_sec} = 0; + } else { + $xml{primary_value} = "0${sign}0000000000e+00"; + $xml{secondary_value} = "0${sign}0000000000e+00"; + $xml{value} = "NaN" if (exists $xml{value}); + $xml{unknown_datapoints} = 0 if (exists $xml{unknown_datapoints}); + $xml{init_flag} = 1 if (exists $xml{init_flag}); + $xml{seasonal} = "NaN" if (exists $xml{seasonal}); + $xml{last_seasonal} = "NaN" if (exists $xml{last_seasonal}); + $xml{intercept} = "NaN" if (exists $xml{intercept}); + $xml{last_intercept} = "NaN" if (exists $xml{last_intercept}); + $xml{slope} = "NaN" if (exists $xml{slope}); + $xml{last_slope} = "NaN" if (exists $xml{last_slope}); + $xml{nan_count} = 1 if (exists $xml{nan_count}); + $xml{last_nan_count} = 1 if (exists $xml{last_nan_count}); + } + push @ds,\%xml; + } + push @ds,@save; + } else { + my @save = splice(@ds,$start-1,$no); + if ($PNP) { # renumber data source names + for my $idx ($start..$end-$no) { + $ds[$idx-1]->{name} = $idx; + } + } + } + if (m|Round Robin Archives|) { + out_ds1(); + } else { + out_ds2(); + } + print OFILE $tmp; + @ds = (); + next; + } + if (//) { + row($_); + next; + } + # value enclosed in XML tags + if (/<(\S+)>\s+(\S+)\s+)(.*)<\/row>/; + for (1..$start-1) { + if ($r =~ s#^(.*?)##) { + $line .= $1; + } + } + for ($start..$start+$no-1) { + if ($action eq "insert") { + $line .= " NaN "; + } else { + $r =~ s#^(.*?)##; + } + } + for ($start+$no..$end) { + if ($r =~ s#^(.*?)##) { + $line .= $1; + } + } + $line .= "\n"; + print OFILE $line; +} + +sub out_ds1 { + for (0..$#ds) { + print OFILE < +\t\t $ds[$_]->{name} +\t\t $ds[$_]->{type} +\t\t $ds[$_]->{minimal_heartbeat} +\t\t $ds[$_]->{min} +\t\t $ds[$_]->{max} + +\t\t +\t\t $ds[$_]->{last_ds} +\t\t $ds[$_]->{value} +\t\t $ds[$_]->{unknown_sec} +\t + +EOD + } +} + +sub out_ds2 { + for my $ds_no (0..$#ds) { + print OFILE "\t\t\t\n"; + for my $tag (0..$#cdp) { + print OFILE "\t\t\t<$cdp[$tag]> $ds[$ds_no]->{$cdp[$tag]} \n" if (exists($ds[$ds_no]->{$cdp[$tag]})); + } + print OFILE "\t\t\t\n"; + } +} + +sub usage { +print < \$help, + "d|debug" => \$debug, + "m|mode=s" => \$mode, + "c|config=s" => \$MainCfg, + "p|pnpcfg=s" => \$PNPCfg, + "o|object=s" => \$object, +); + +my @modes = ("bulk", "bulk+npcd", "sync", "npcdmod"); +my @products = ("nagios", "icinga"); +my @states = ("OK", "WARN", "CRIT", "UNKN", "INFO", "HINT", "DBG"); +my @colors = ("bold green", "bold yellow", "bold red", "bold blue", "bold blue", "bold yellow", "black on_red"); +my %process_perf_data_stats = ('hosts' => 0, 'services' => 0, 'noperf' => 0, 'noperf_but_enabled' => 0 , 0 => 0, 1 => 0); +my %stats = ( 0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 =>0 ); +my %sizing = ( + 50 => 'sync', + 200 => 'bulk', + 5000 => 'bulk+npcd', + 10000 => 'npcdmod', +); + +if ( ! $MainCfg ){ + usage(); + usage_no_config(); + exit; +} + +if ( ! $mode ){ + usage(); + usage_no_mode(); + exit; +} + +if ( ! $PNPCfg ){ + usage(); + usage_no_pnpcfg(); + exit; +} + +if( ! in_array(\@modes, $mode)){ + usage(); + info("'$mode' is not a valid option",2); + info("Valid modes are [@modes]",2); + exit; +} + +my %statistics = ( + 'OK' => 0, + 'WARN' => 0, + 'CRIT' => 0, +); + + +my %cfg = (); +my %commands = (); +my $uid = 0; +my $gid = 0; +my $process_perfdata_cfg = 0; + +# +# Begin +# + +info("========== Starting Environment Checks ============",4); +info("My version is: ".$version,4); +info("Start Options: ".$start_options, 4); + +# +# Read Main config file +# +process_nagios_cfg(); +# +# get the product name +# +my $product = get_product(); +if( $product eq 0 ){ + info("Can´t determine product while reading $MainCfg", 4); + info_and_exit("$MainCfg does not look like a valid config file", 2); +}else{ + info("Running product is '$product'", 0); +} + +# +# Read objects cache file to get more information +# Needs a running product +# +check_config_var('object_cache_file', 'exists', 'break'); +if( -r $cfg{'object_cache_file'} ){ + process_objects_file($cfg{'object_cache_file'}); +}else{ + info_and_exit($cfg{'object_cache_file'}. " is not readable", 2); +} + +# +# Read resource.cfg +# +check_config_var('resource_file', 'exists', 'break'); +if( -r $cfg{'resource_file'} ){ + process_npcd_cfg($cfg{'resource_file'}); +}else{ + info_and_exit($cfg{'resource_file'}. " is not readable", 2); +} + +# +# Read process_perfdata.cfg +# +if ( ! -d $PNPCfg ){ + info_and_exit("Directory $PNPCfg does not exist",2); +} +if ( ! -d "$PNPCfg/check_commands" ){ + info("Directory $PNPCfg/check_commands does not exist",2); + info_and_exit("$PNPCfg does not look like a PNP4Nagios config directory",2); +} +my $ppcfg = "$PNPCfg/process_perfdata.cfg"; +process_perfdata_cfg($ppcfg); + +# +# Read etc/pnp_release file if exists +# +if( -r "$PNPCfg/pnp4nagios_release" ){ + process_pnp4nagios_release("$PNPCfg/pnp4nagios_release"); + info("Found PNP4Nagios version ".get_config_var('PKG_VERSION'), 0); + info("./configure Options ".get_config_var('CONFIGURE_ARGS'), 0) if get_config_var('CONFIGURE_ARGS'); +}else{ + info("No pnp4nagios_release file found. This might be an older version of PNP4Nagios", 0); +} + +# +# Start Main config checks +# + +if(config_var_exists($product.'_user') ){ + my $user = get_config_var($product.'_user'); + $uid = getpwnam($user); + info( "Effective User is '$user'", 0); + if($uid){ + info("User $user exists with ID '$uid'", 0 ); + }else{ + info_and_exit("User $user does not exist", 2 ); + } +}else{ + info_and_exit("Option '".$product."_user' not found in $MainCfg", 2); +} + +if(config_var_exists($product.'_group') ){ + my $group = get_config_var($product.'_group'); + $gid = getgrnam($group); + info( "Effective group is '$group'", 0); + if($gid){ + info("Group $group exists with ID '$gid'", 0 ); + }else{ + info_and_exit("Group $group does not exist", 2 ); + } +}else{ + info_and_exit("Option '".$product."_group' not found in $MainCfg", 2); +} + +# +# Start sync config checks +# + +if($mode eq "sync"){ + info("========== Checking Sync Mode Config ============",4); + + compare_config_var('process_performance_data', '1'); + compare_config_var('enable_environment_macros', '1'); + + check_config_var('service_perfdata_command', 'exists'); + check_config_var('host_perfdata_command', 'exists');; + last_info("Needed config options are missing.",5,$last_check); + + # Options not allowed in sync mode + check_config_var('service_perfdata_file', 'notexists'); + check_config_var('service_perfdata_file_template', 'notexists'); + check_config_var('service_perfdata_file_mode', 'notexists'); + check_config_var('service_perfdata_file_processing_interval', 'notexists'); + check_config_var('service_perfdata_file_processing_command', 'notexists',); + check_config_var('host_perfdata_file', 'notexists'); + check_config_var('host_perfdata_file_template', 'notexists'); + check_config_var('host_perfdata_file_mode', 'notexists'); + check_config_var('host_perfdata_file_processing_interval', 'notexists'); + check_config_var('host_perfdata_file_processing_command', 'notexists'); + check_config_var('broker_module', 'notexists'); + last_info("Config options are not allowed in sync mode. http://docs.pnp4nagios.org",5,$last_check); + + info(ucfirst($product)." config looks good so far",4); + info("========== Checking config values ============",4); + my $command_line; + + $command_line = check_command_definition('service_perfdata_command'); + check_process_perfdata_pl($command_line); + + $command_line = check_command_definition('host_perfdata_command'); + check_process_perfdata_pl($command_line); + +} + +if($mode eq "bulk"){ + info("========== Checking Bulk Mode Config ============",4); + + compare_config_var('process_performance_data', '1'); + check_config_var('service_perfdata_file', 'exists'); + check_config_var('service_perfdata_file_template', 'exists'); + check_perfdata_file_template(get_config_var('service_perfdata_file_template')); + check_config_var('service_perfdata_file_mode', 'exists'); + check_config_var('service_perfdata_file_processing_interval', 'exists'); + check_config_var('service_perfdata_file_processing_command', 'exists'); + + check_config_var('host_perfdata_file', 'exists'); + check_config_var('host_perfdata_file_template', 'exists'); + check_perfdata_file_template(get_config_var('host_perfdata_file_template')); + check_config_var('host_perfdata_file_mode', 'exists'); + check_config_var('host_perfdata_file_processing_interval', 'exists'); + check_config_var('host_perfdata_file_processing_command', 'exists'); + last_info("Needed config options are missing.",5,$last_check); + + # Options not allowed in bulk mode + check_config_var('service_perfdata_command', 'notexists'); + check_config_var('host_perfdata_command', 'notexists'); + check_config_var('broker_module', 'notexists'); + last_info("Config options are not allowed in bulk mode",5,$last_check); + + info(ucfirst($product)." config looks good so far",4); + info("========== Checking config values ============",4); + my $command_line; + + $command_line = check_command_definition('service_perfdata_file_processing_command'); + check_process_perfdata_pl($command_line); + + $command_line = check_command_definition('host_perfdata_file_processing_command'); + check_process_perfdata_pl($command_line); +} + +if($mode eq "bulk+npcd"){ + info("========== Checking Bulk Mode + NPCD Config ============",4); + + compare_config_var('process_performance_data', '1'); + check_config_var('service_perfdata_file', 'exists'); + check_config_var('service_perfdata_file_template', 'exists'); + check_perfdata_file_template(get_config_var('service_perfdata_file_template')); + check_config_var('service_perfdata_file_mode', 'exists'); + check_config_var('service_perfdata_file_processing_interval', 'exists'); + check_config_var('service_perfdata_file_processing_command', 'exists'); + + check_config_var('host_perfdata_file', 'exists'); + check_config_var('host_perfdata_file_template', 'exists'); + check_perfdata_file_template(get_config_var('host_perfdata_file_template')); + check_config_var('host_perfdata_file_mode', 'exists'); + check_config_var('host_perfdata_file_processing_interval', 'exists'); + check_config_var('host_perfdata_file_processing_command', 'exists'); + last_info("Needed config options are missing. http://docs.pnp4nagios.org",5,$last_check); + + # Options not allowed in bulk mode + check_config_var('service_perfdata_command', 'notexists'); + check_config_var('host_perfdata_command', 'notexists'); + check_config_var('broker_module', 'notexists'); + last_info("Config options are not allowed in bulk mode with npcd",5,$last_check); + + info(ucfirst($product)." config looks good so far",4); + info("========== Checking config values ============",4); + my $command_line; + + my $npcd_cfg = check_proc_npcd(get_config_var($product.'_user')); + + if( -r $npcd_cfg){ + info("$npcd_cfg is used by npcd and readable",0); + }else{ + info_and_exit("$npcd_cfg is not readable",0); + } + # read npcd.cfg into %cfg + process_npcd_cfg($npcd_cfg); + + check_config_var('perfdata_spool_dir', 'exists'); + count_spool_files(get_config_var('perfdata_spool_dir')); + + $command_line = check_command_definition('service_perfdata_file_processing_command'); + $command_line = check_command_definition('host_perfdata_file_processing_command'); + + check_process_perfdata_pl($cfg{'perfdata_file_run_cmd'}); +} + +if($mode eq "npcdmod"){ + my $val; + + info("========== Checking npcdmod Mode Config ============",4); + + compare_config_var('process_performance_data', '1'); + last_info ("Needed config options are missing. http://docs.pnp4nagios.org",5,$last_check); + + # Options not allowed in sync mode + check_config_var('service_perfdata_file', 'notexists'); + check_config_var('service_perfdata_file_template', 'notexists'); + check_config_var('service_perfdata_file_mode', 'notexists'); + check_config_var('service_perfdata_file_processing_interval', 'notexists'); + check_config_var('service_perfdata_file_processing_command', 'notexists'); + check_config_var('host_perfdata_file', 'notexists'); + check_config_var('host_perfdata_file_template', 'notexists'); + check_config_var('host_perfdata_file_mode', 'notexists'); + check_config_var('host_perfdata_file_processing_interval', 'notexists'); + check_config_var('host_perfdata_file_processing_command', 'notexists'); + last_info("Config options are not allowed in bulk mode with npcd",5,$last_check); + + # event_broker_option must have enabled bits 2 and 3 (0b01100) + check_config_var ('event_broker_options', 'exists'); + $val = get_config_var('event_broker_options') & 0x0c; + if($val == 12){ + info("event_broker_option bits 2 and 3 enabled ($val)",0); + }else{ + info_and_exit("event_broker_option bits 2 and/or 3 not enabled",2); + } + + check_config_var('broker_module', 'exists', 'break'); + + $val = get_config_var('broker_module'); + # extract npcd.cfg patch from broker_module definition + my $npcdmod_npcd_cfg; + $val =~ /npcdmod\.o\s+config_file=(.*)$/; + if($1){ + $npcdmod_npcd_cfg=$1; + info("npcdmod.o config file is $npcdmod_npcd_cfg",0); + if( -r $npcdmod_npcd_cfg){ + info("$npcdmod_npcd_cfg used by npcdmod.o is readable",0); + }else{ + info_and_exit("$npcdmod_npcd_cfg used by npcdmod.o is not readable",2); + } + }else{ + info("broker_module definition looks suspect '$val'",2); + info_and_exit("Can´t extract path to npcd.cfg from your broker_module definition",2); + } + # extract npcd.cfg path from process list + my $npcd_cfg = check_proc_npcd(get_config_var($product.'_user')); + if( -r $npcd_cfg){ + info("$npcd_cfg is used by npcd and readable",0); + } + if($npcd_cfg eq $npcdmod_npcd_cfg){ + info("npcd and npcdmod.o are using the same config file ($npcd_cfg)",0); + }else{ + info_and_exit("npcd and npcdmod.o are not using the same config file($npcd_cfg<=>$npcdmod_npcd_cfg)",2); + } + + # read npcd.cfg into %cfg + process_npcd_cfg($npcd_cfg); + check_config_var('perfdata_spool_dir', 'exists'); + count_spool_files(get_config_var('perfdata_spool_dir')); + + info(ucfirst($product)." config looks good so far",4); + info("========== Checking config values ============",4); + + # read npcd.cfg into %cfg + process_npcd_cfg($npcd_cfg); + check_process_perfdata_pl($cfg{'perfdata_file_run_cmd'}); + +} + +info("========== Starting global checks ============",4); +check_config_var('status_file', 'exists', 'break'); +process_status_file(); +info("==== Starting rrdtool checks ====",4); +check_rrdtool(); + +info("==== Starting directory checks ====",4); +check_config_var('RRDPATH', 'exists', 'break'); +check_perfdata_dir(get_config_var('RRDPATH')); + +if($process_perf_data_stats{1} == 0){ + info("'process_perf_data 1' is not set for any of your hosts/services",2); +} +if($process_perf_data_stats{'noperf'} > 0){ + info($process_perf_data_stats{'noperf'}." hosts/services are not providing performance data",1); +} +if($process_perf_data_stats{'noperf_but_enabled'} > 0){ + info("'process_perf_data 1' is set for ".$process_perf_data_stats{'noperf_but_enabled'}." hosts/services which are not providing performance data!",1); +} +if($process_perf_data_stats{0} > 0){ + info("'process_perf_data 0' is set for ".$process_perf_data_stats{0}." of your hosts/services",1); +} +if($process_perf_data_stats{1} > 0){ + info("'process_perf_data 1' is set for ".$process_perf_data_stats{1}." of your hosts/services",0); +} + +if ( get_config_var('LOG_LEVEL') gt 0 ){ + info("Logging is enabled in process_perfdata.cfg. This will reduce the overall performance of PNP4Nagios",1) +} + +info("==== System sizing ====",4); +print_sizing(); + +info("==== Check statistics ====",4); +print_stats(); +exit; + +# +# Helper Functions +# + +sub config_var_exists { + my $key = shift; + if(exists $cfg{$key}){ + return 1; + }else{ + return 0; + } +} + +sub get_config_var { + my $key = shift; + if(exists $cfg{$key}){ + return $cfg{$key}; + }else{ + return undef; + } +} + +sub count_spool_files { + my $spool_dir = shift; + my @all_files = glob "$spool_dir/*"; + if($#all_files >= 10){ + info("$#all_files files found in $spool_dir",2); + info("Something went wrong here!",5); + }elsif($#all_files >= 3){ + info("$#all_files files found in $spool_dir",1); + info("Something went wrong here!",5); + }else{ + info("$#all_files files found in $spool_dir",0); + } +} +sub check_command_definition { + my $option = shift; + warn $option; + my $key = get_config_var($option); + my $val = $commands{$key}; + if(exists $commands{$key}){ + info("Command $key is defined",0); + info("'$val'",0); + }else{ + info_and_exit("Command $key is not defined",2); + } + if($mode eq "sync"){ + if ( $option eq "host_perfdata_command"){ + if( $val =~ m/process_perfdata.pl\s+-d\s+HOSTPERFDATA/ ){ + info ( "Command looks good",0 ); + }else{ + info_and_exit ( "Command looks suspect ($val)",2 ); + } + }else{ + if( $val =~ m/process_perfdata.pl$/ or $val =~ m/process_perfdata.pl\s+-d\s+SERVICEPERFDATA/ ){ + info ( "Command looks good",0 ); + }else{ + info_and_exit ( "Command looks suspect ($val)",2 ); + } + } + } + if($mode eq "bulk"){ + if( $val =~ m/process_perfdata.pl\s+--bulk=/){ + info ( "Command looks good",0 ); + }else{ + info_and_exit ( "Command looks suspect ($val)",2 ); + } + } + if($mode eq "bulk+npcd"){ + my $dump_file = get_config_var( $option =~m/(.*)_processing_command/ ); + my $perfdata_spool_dir = get_config_var( 'perfdata_spool_dir'); + #print "$dump_file\n"; + my $regex = qr/\/bin\/mv\s+$dump_file\s+$perfdata_spool_dir/; + if( $val =~ m/$regex/){ + info ( "Command looks good",0 ); + }else{ + info ( "Regex = $regex", 4 ); + info_and_exit ( "Command looks suspect ($val)",2 ); + } + } + return $commands{$key}; + +} + +# +# Max three parameters +# +sub check_config_var { + my $key = shift; + my $check = shift; + my $break = shift||0; + my $var = get_config_var($key); + if($check eq "exists"){ + if(defined($var)){ + info("$key is defined",0); + info("$key=$var",0); + #$last_check = 0; + }else{ + info("$key is not defined",2); + $last_check++; + exit if $break; + } + } + if($check eq "notexists"){ + if( ! defined($var)){ + #info("$key is not defined",0); + #$last_check = 0; + }else{ + info("$key is defined ($key=$var)",2); + info("$key is not allowed in mode '$mode'",2); + $last_check++; + exit if $break; + } + } +} + +sub compare_config_var { + my $key = shift; + my $compare = shift; + my $break = shift||0; + my $var = get_config_var($key); + if( $var =~ /$compare/){ + info("$key is $var compared with '/$compare/'",0); + }else{ + info("$key is $var compared with '/$compare/'",2); + exit if $break; + } +} + +sub check_perfdata_file_template { + $_ = shift; + if ( not $_ ){ + return; + } + + if( /^DATATYPE::(HOST|SERVICE)PERFDATA/ ){ + info("PERFDATA template looks good",0); + }else{ + info("PERFDATA template looks suspect",2); + } +} + +sub info { + my $string = shift; + my $state = shift||0; + my $break = shift||0; + + $stats{$state}++; + return if $state == 6 and not defined $debug; + $statistics{$states[$state]}++; + print color $colors[$state]; + printf("[%-4s]", $states[$state]); + print color 'reset'; + printf(" %s\n", $string); +} + +sub last_info { + my $string = shift; + my $state = shift; + my $break = shift||0; + return if $break == 0; + info("$string ($break)", $state); + exit if $break > 0; +} +sub info_and_exit { + my $string = shift; + my $state = shift; + info($string, $state); + exit $state; +} + +sub print_stats { + my $state = 0; + $state = 1 if $stats{1} > 0; + $state = 2 if $stats{2} > 0; + info(sprintf("Warning: %d, Critical: %d",$stats{1}, $stats{2}),$state); + info("Checks finished...", $state); +} + +sub print_sizing { + my $object_count = ($process_perf_data_stats{'hosts'} + $process_perf_data_stats{'services'}); + my $graph_count = ($process_perf_data_stats{'hosts'} + $process_perf_data_stats{'services'}); + info("$object_count hosts/service objects defined",0); + foreach my $limit ( sort {$a <=> $b} keys %sizing){ + if($graph_count >= $limit and $sizing{$limit} eq $mode){ + info("Use at least mode '".get_mode_by_size($graph_count)."' to reduce I/O",5); + last; + } + } +} + +sub get_mode_by_size { + my $graph_count = shift; + foreach my $limit ( sort {$a <=> $b} keys %sizing){ + return $sizing{$limit} if $limit >= $graph_count; + } + return 'gearman'; +} + +sub check_rrdtool { + check_config_var('RRDTOOL', 'exists', 'break'); + my $rrdtool = get_config_var('RRDTOOL'); + if ( -x $rrdtool ){ + info("$rrdtool is executable",0); + }else{ + info_and_exit("$rrdtool is not executable",2); + } + my @version = `$rrdtool`; + chomp $version[0]; + info($version[0],0); + check_config_var('USE_RRDs', 'exists', 'break'); + if(get_config_var('USE_RRDs')){ + unless ( eval "use RRDs;1" ) { + info("Perl RRDs modules are not loadable",1); + }else{ + info("Perl RRDs modules are loadable",0); + } + }else{ + unless ( eval "use RRDs;1" ) { + info("Perl RRDs modules are neither loadable nor enabled (USE_RRDs = 0)",1); + }else{ + info("RRDs modules are loadable but not enabled (USE_RRDs = 0)",1); + } + } +} + +sub check_proc_npcd { + my $user = shift; + my $out = `ps -u $user -o cmd | grep /npcd | grep -v grep`; + my $rc = $?; + chomp $out; + info("Check process: 'ps -u $user -o cmd | grep /npcd | grep -v grep'", 6); + info("Result: $out", 6); + info("Returncode: $rc", 6); + #extract npcd.cfg + $out =~ /-f\s?(\S+)/; + my $npcd_cfg = $1; + if($rc == 0){ + info("npcd daemon is running",0); + }else{ + info("npcd daemon is not running",2); + info_and_exit("A running npcd daemon is needed to process data.",4); + } + return $npcd_cfg; +} + +# process nagios.cfg +sub process_nagios_cfg { + info ("Reading $MainCfg", 4); + open (NFILE, "$MainCfg") || info_and_exit("Failed to open '$MainCfg'. $! ", 2); + while () { + process_main_cfg_line(); + } + close (NFILE); +} + +# process process_perfdata.cfg +sub process_perfdata_cfg { + my $cfg_file = shift; + if ( -r $cfg_file ){ + if ( process_cfg($cfg_file) ){ + $process_perfdata_cfg = 1; + }else{ + $process_perfdata_cfg = 0; + } + }elsif(-e "$PNPCfg/process_perfdata.cfg-sample"){ + info ("$cfg_file does not exist.",1); + info ("We will try to parse defaults from process_perfdata.pl later on", 1); + info ("process_perfdata.cfg-sample exists in $PNPCfg", 5); + info ("It is recommended to rename process_perfdata.cfg-sample to process_perfdata.cfg", 5); + $process_perfdata_cfg = 0; # we have to parse process_perfdata.pl to get defaults + }else{ + info ("$cfg_file does not exist.",1); + info ("We will try to parse defaults from process_perfdata.pl later on", 1); + info ("It is recommended to place $cfg_file in $PNPCfg", 5); + info ("A sample file is installed by 'make install-config'", 5); + $process_perfdata_cfg = 0; # we have to parse process_perfdata.pl to get defaults + } +} + +sub process_pnp4nagios_release { + my $cfg_file = shift; + if ( -r $cfg_file ){ + process_cfg($cfg_file); + } +} + +sub process_cfg { + my $cfg_file = shift; + if ( -r $cfg_file ){ + info ("Reading $cfg_file", 4); + + open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2); + while () { + process_main_cfg_line(); + } + close (NFILE); + return 1; + } + return 0; +} + +# process npcd.cfg +sub process_npcd_cfg { + my $cfg_file = shift; + if ( -r $cfg_file ){ + info ("Reading $cfg_file", 4); + }else{ + info ("$cfg_file does not exist", 4); + info ("this file is needed to get more information about your system", 5); + info_and_exit("no further processing possible",2); + } + + open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2); + while () { + process_main_cfg_line(); + } + close (NFILE); +} + +# process main config line +sub process_main_cfg_line { + chomp; + return if (/^$/); + return if (/^#/); + s/#.*//; + s/\s*$//; + if (my ($par, $val) = /([^=]+)\s?=\s?(.*)/){ + $par = trim($par); + $val = trim($val);; + if ( (defined($par) && $par eq "") ) { + info ("oddLine -> $_" ,4); + return;; + } + # skip broker_module lines. + return if (($par eq "broker_module") and ($val !~ /npcdmod.o/)); + info("'$par' -> '$val'",6); + $cfg{"$par"} = $val; + } +} + +sub trim { + my $string = shift; + $string =~ s/^\s+//; + $string =~ s/\s+$//; + return $string; +} + +# read object_file +sub process_objects_file { + my ($file) = @_; + my $cmd = ""; + my $line = ""; + info ("Reading $file", 4); + open (CFILE, "$file") || info_and_exit("Failed to open '$file'. $! ", 2); + while () { + s/#.*//; + next if (/^$/); + chomp; + if (/command_name/) { + ($cmd) = /command_name\s*(.*)/; + next; + } + next unless ( /command_line/); + ($line) = /command_line\s*(.*)/ ; + $commands{"$cmd"} = "$line"; + next unless (/process_perfdata.pl/); + my @cmd = split (/\s+/,$line); + } + close (CFILE); +} + +sub process_status_file { + my ($file) = get_config_var('status_file'); + my $line = ""; + my $perfdata_found = 0; + my ($host_query,$service_query) = split(/;/,$object) if ($object); + $host_query = "" unless (defined $host_query); + $service_query = "" unless (defined $service_query); + info("host_query = $host_query",4); + info("service_query = $service_query",4); + my $hst = ""; + my $srv = ""; + my $perf = ""; + my $ppd = ""; + info ("Reading $file", 4); + open (CFILE, "$file") || info_and_exit("Failed to open '$file'. $! ", 2); + while () { + s/#.*//; + next if (/^$/); + chomp; + if(/\shost_name=(.+)/){ + $hst = $1; + $srv = ""; + } + if(/\sservice_description=(.+)/){ + $srv = $1; + } + if(/\sperformance_data=$/){ + $process_perf_data_stats{'noperf'}++; + $perfdata_found = 0; + $perf = " $hst/$srv: [empty perf data]"; + } + if(/\sperformance_data=(.+)$/){ + $perfdata_found = 1; + $perf = " $hst/$srv: [$1]"; + } + # count process_perf_data definitions + if (/process_performance_data=(\d)$/){ + $ppd=$1; + $process_perf_data_stats{$1}++ ; + if ( $perfdata_found == 0 && $1 == 1){ + $process_perf_data_stats{'noperf_but_enabled'}++; + } + if ($host_query ne '') { + $perf = "" if ($hst !~ /$host_query/i); + if ($service_query ne '') { + $perf = "" if ($srv !~ /$service_query/i); + }else{ + $perf = ''; + } + }else{ + $perf=''; + } + if ($perf ne ""){ + info ("$perf, ppd=$ppd", 4); + } + } + if(/^hoststatus /){ + $process_perf_data_stats{'hosts'}++; + } + if(/^servicestatus /){ + $process_perf_data_stats{'services'}++; + } + } + close (CFILE); +} + +sub check_process_perfdata_pl { + my $command_line = shift; + my $path = ''; + if( $command_line =~ /\s?([^\s]*)\/process_perfdata.pl\s?/ ){ + $path = $1; + if ($path =~ /(\$USER\d+\$)/) { + if (exists $cfg{"$1"}) { + my $val = $cfg{"$1"}; + $path =~ s/\$USER\d+\$/$val/; + } + } + if( -x "$path/process_perfdata.pl" ){ + info("Script $path/process_perfdata.pl is executable",0); + }else{ + info_and_exit("Script $path/process_perfdata.pl is not executable",2); + } + process_pp_pl ("$path/process_perfdata.pl") if $process_perfdata_cfg == 0; + }else{ + info_and_exit("Can´t find path to process_perfdata.pl",2); + } +} + +sub check_perfdata_spool_dir { + my $dir = shift; + if( -d $dir ){ + info("Spool directory '$dir' exists",0); + }else{ + info_and_exit("Spool directory $dir does not exist",2); + } + my @files = <$dir/*>; + my $count = @files; + if($count > 1){ + info("$count files in $dir", 1); + }else{ + info("$dir is empty", 0); + } +} + +# +sub check_perfdata_dir { + my $dir = shift; + if( -d $dir ){ + info("Perfdata directory '$dir' exists",0); + find(\&check_perm, "$dir"); + }else{ + info_and_exit("Perfdata directory $dir does not exist",2); + } +} + +sub check_perm { + -d ; + my $f = "$File::Find::name"; + return unless (($f =~ /\/$/) or ($f =~ /rrd$|xml$/)); + check_usrgrp ($f); +} + +sub check_usrgrp { + my $file = shift; + my $break = shift || 0; + if ($uid) { + my $fuid = (stat("$file"))[4]; + my $fname = getpwuid($fuid); + info ("$file: owner is $fname", 2, $break) if ($fuid != $uid); + } + if ($gid) { + my $fgid = (stat("$file"))[5]; + my $fgroup = getgrgid($fgid); + info ("$file: group is $fgroup", 2, $break) if ($fgid != $gid); + } +} + +# read config inside process_perfdata.pl +sub process_pp_pl { + my $cfg_file = shift; + my $loop = 0; + info ("Reading $cfg_file", 4); + open (NFILE, "$cfg_file") || info_and_exit("Failed to open '$cfg_file'. $! ", 2); + while () { + chomp; + last if (/^\s*\);/); + s/#.*//; + s/\s*$//; + s/^\s+//; + next if (/^$/); + #$loop++ if (/%conf/); + #next unless ($loop); + my ($par, $val) = /([^\s]+)\s+=>\s+([^\s]+)/; # shortest string + next unless ((defined $par) and (defined $val)); + $val =~ s/['",]//g; + $cfg{"$par"} = $val; + } + close (NFILE); +} + +sub get_product { + for my $product (@products){ + my $string = $product . "_user"; + if ( exists $cfg{$string} ){ + return $product; + } + } + return 0; +} + +sub in_array{ + my ($arr,$search_for) = @_; + my %items = map {$_ => 1} @$arr; + return (exists($items{$search_for}))?1:0; +} + +sub usage{ +print <auto_render = FALSE; + } + + public function index(){ + url::redirect("start", 302); + } + + public function search() { + $query = pnp::clean($this->input->get('term')); + $result = array(); + if(strlen($query)>=1) { + $hosts = $this->data->getHosts(); + foreach($hosts as $host){ + if(preg_match("/$query/i",$host['name'])){ + array_push($result,$host['name']); + } + } + echo json_encode($result); + } + } + + public function remove($what){ + if($what == 'timerange'){ + $this->session->delete('start'); + $this->session->delete('end'); + $this->session->set('timerange-reset', 1); + } + } + + public function filter($what){ + if($what == 'set-sfilter'){ + $this->session->set('sfilter', $_POST['sfilter']); + }elseif($what == 'set-spfilter'){ + $this->session->set('spfilter', $_POST['spfilter']); + }elseif($what == 'set-pfilter'){ + $this->session->set('pfilter', $_POST['pfilter']); + } + } + + public function basket($action=FALSE){ + // Disable auto-rendering + $this->auto_render = FALSE; + $host = false; + $service = false; + $basket = array(); + + if($action == "list"){ + $basket = $this->session->get("basket"); + if(is_array($basket) && sizeof($basket) > 0){ + foreach($basket as $item){ + printf("
  • %s
  • \n", + "basket_action_remove", + $item, + $item, + Kohana::lang('common.basket-remove', $item), + url::base(), + pnp::shorten($item) + ); + } + } + }elseif($action == "add"){ + $item = $_POST['item']; + $basket = $this->session->get("basket"); + if(!is_array($basket)){ + $basket[] = "$item"; + }else{ + if(!in_array($item,$basket)){ + $basket[] = $item; + } + } + $this->session->set("basket", $basket); + foreach($basket as $item){ + printf("
  • %s
  • \n", + "basket_action_remove", + $item, + $item, + Kohana::lang('common.basket-remove', $item), + url::base(), + pnp::shorten($item) + ); + } + }elseif($action == "sort"){ + $items = $_POST['items']; + $basket = explode(',', $items); + array_pop($basket); + $this->session->set("basket", $basket); + foreach($basket as $item){ + printf("
  • %s
  • \n", + "basket_action_remove", + $item, + $item, + Kohana::lang('common.basket-remove', $item), + url::base(), + pnp::shorten($item) + ); + } + }elseif($action == "remove"){ + $basket = $this->session->get("basket"); + $item_to_remove = $_POST['item']; + $new_basket = array(); + foreach($basket as $item){ + if($item == $item_to_remove){ + continue; + } + $new_basket[] = $item; + } + $basket = $new_basket; + $this->session->set("basket", $basket); + foreach($basket as $item){ + printf("
  • %s
  • \n", + "basket_action_remove", + $item, + $item, + Kohana::lang('common.basket-remove', $item), + url::base(), + pnp::shorten($item) + ); + } + }elseif($action == "clear"){ + $this->session->delete("basket"); + }else{ + echo "Action $action not known"; + } + $basket = $this->session->get("basket"); + if(is_array($basket) && sizeof($basket) == 0){ + echo Kohana::lang('common.basket-empty'); + }else{ + echo "
    \n"; + echo "\n"; + echo "\n"; + echo "
    \n"; + } + } + +} diff --git a/share/pnp/application/controllers/color.php b/share/pnp/application/controllers/color.php new file mode 100644 index 0000000..b75ce00 --- /dev/null +++ b/share/pnp/application/controllers/color.php @@ -0,0 +1,26 @@ +template = $this->add_view('template'); + $this->template->color = $this->add_view('color'); + $this->template->color->color_box = $this->add_view('color_box'); + $this->template->color->logo_box = $this->add_view('logo_box'); + } + + public function index() + { + $this->scheme = $this->config->scheme; + + } +} diff --git a/share/pnp/application/controllers/debug.php b/share/pnp/application/controllers/debug.php new file mode 100644 index 0000000..b67354e --- /dev/null +++ b/share/pnp/application/controllers/debug.php @@ -0,0 +1,66 @@ +template = $this->add_view('template'); + $this->template->debug = $this->add_view('debug'); + } + + public function index() + { + + $this->data->getTimeRange($this->start,$this->end,$this->view); + + if(isset($this->host) && isset($this->service)){ + $this->url = "?host=".$this->host."&srv=".$this->service; + if($this->start){ + $this->url .= "&start=".$this->start; + $this->session->set("start", $this->start); + } + if($this->end){ + $this->url .= "&end=".$this->end; + $this->session->set("end", $this->end); + } + $services = $this->data->getServices($this->host); + $this->data->buildDataStruct($this->host,$this->service,$this->view); + $this->is_authorized = $this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']); + $this->title = "Service Details ". $this->host ." -> " . $this->data->MACRO['DISP_SERVICEDESC']; + }elseif(isset($this->host)){ + $this->is_authorized = $this->auth->is_authorized($this->host); + if($this->view == ""){ + $this->view = $this->config->conf['overview-range']; + } + if($this->start){ + $this->url .= "&start=".$this->start; + $this->session->set("start", $this->start); + } + if($this->end){ + $this->url .= "&end=".$this->end; + $this->session->set("end", $this->end); + } + $this->title = "Start $this->host"; + $services = $this->data->getServices($this->host); + $this->title = "Service Overview for $this->host"; + foreach($services as $service){ + if($service['state'] == 'active') + $this->data->buildDataStruct($this->host,$service['name'],$this->view); + } + }else{ + if(isset($this->host)){ + url::redirect("/graph"); + }else{ + throw new Kohana_Exception('error.get-first-host'); + } + } + } +} diff --git a/share/pnp/application/controllers/docs.php b/share/pnp/application/controllers/docs.php new file mode 100644 index 0000000..004b8b7 --- /dev/null +++ b/share/pnp/application/controllers/docs.php @@ -0,0 +1,80 @@ +template = $this->add_view('template'); + $this->template->docs = $this->add_view('docs'); + $this->template->docs->search_box = $this->add_view('search_box'); + $this->template->docs->docs_box = $this->add_view('docs_box'); + $this->template->docs->logo_box = $this->add_view('logo_box'); + $this->doc_language = $this->config->conf['doc_language']; + } + + public function index(){ + url::redirect("docs/view/"); + } + + public function view($lang=FALSE, $page=FALSE){ + if($lang == FALSE){ + if(!in_array($this->config->conf['lang'],$this->doc_language) ){ + $this->lang = $this->doc_language[0]; + }else{ + $this->lang = $this->config->conf['lang'] ; + } + }else{ + if(in_array($lang,$this->doc_language) ){ + $this->lang = $lang; + }else{ + $this->lang = $this->doc_language[0]; + url::redirect("docs/view/"); + } + } + + if($page == FALSE){ + url::redirect("docs/view/".$this->lang."/start"); + } + + $this->page = $page; + $file = sprintf("documents/%s/%s.html", $this->lang, $this->page); + $file_toc = sprintf("documents/%s/start.html", $this->lang); + if(!file_exists($file)){ + url::redirect("docs/view/start"); + } + $this->content = file_get_contents($file); + $toc = file( $file_toc ); + $this->toc = ""; + $in = FALSE; + foreach($toc as $t){ + if(preg_match("/SECTION/", $t) ){ + $in = ! $in; + continue; + } + if($in == TRUE){ + $this->toc .= $t; + } + } + # + # some string replacements + # + $this->toc = str_replace("/de/pnp-0.6/", "", $this->toc); + $this->toc = str_replace("/pnp-0.6/", "", $this->toc); + $this->toc = preg_replace("/

    .*<\/h2>/", "" , $this->toc); + $this->content = str_replace("/templates/", "http://docs.pnp4nagios.org/templates/", $this->content); + $this->content = str_replace("/de/pnp-0.6/", "", $this->content); + $this->content = str_replace("/pnp-0.6/", "", $this->content); + $this->content = str_replace("/_media", url::base()."documents/_media", $this->content); + $this->content = str_replace("gallery", "", $this->content); + $this->content = str_replace("/_detail", url::base()."documents/_media", $this->content); + $this->content = str_replace("/lib/images", url::base()."documents/images", $this->content); + $this->graph_width = ($this->config->conf['graph_width'] + 140); + } +} diff --git a/share/pnp/application/controllers/graph.php b/share/pnp/application/controllers/graph.php new file mode 100644 index 0000000..7dd72ca --- /dev/null +++ b/share/pnp/application/controllers/graph.php @@ -0,0 +1,129 @@ +template = $this->add_view('template'); + if (isset($this->version) && $this->version == "tiny" ) + $this->template->graph = $this->add_view('graph_tiny'); + else + $this->template->graph = $this->add_view('graph'); + $this->template->zoom_header = $this->add_view('zoom_header'); + $this->template->zoom_header->graph_width = ($this->config->conf['zgraph_width'] + 140); + $this->template->zoom_header->graph_height = ($this->config->conf['zgraph_height'] + 230); + $this->template->graph->icon_box = $this->add_view('icon_box'); + $this->template->graph->icon_box->position = "graph"; + $this->template->graph->icon_box->xml_icon = TRUE; + $this->template->graph->icon_box->pdf_icon = TRUE; + } + + public function index() + { + $this->template->graph->graph_content = $this->add_view('graph_content'); + $this->template->graph->graph_content->graph_width = ($this->config->conf['graph_width'] + 85); + $this->template->graph->graph_content->timerange_select = $this->add_view('timerange_select'); + $this->template->graph->header = $this->add_view('header'); + $this->template->graph->search_box = $this->add_view('search_box'); + $this->template->graph->service_box = $this->add_view('service_box'); + $this->template->graph->basket_box = $this->add_view('basket_box'); + $this->template->graph->widget_menu = $this->add_view('widget_menu'); + $this->template->graph->graph_content->widget_graph = $this->add_view('widget_graph'); + // Change the status box while multisite theme is in use + if($this->theme == "multisite"){ + $this->template->graph->status_box = $this->add_view('multisite_box'); + $this->template->graph->status_box->base_url = $this->config->conf['multisite_base_url']; + $this->template->graph->status_box->site = $this->config->conf['multisite_site']; + }else{ + $this->template->graph->status_box = $this->add_view('status_box'); + } + // Service Details + if($this->host != "" && $this->service != ""){ + $this->service = pnp::clean($this->service); + $this->host = pnp::clean($this->host); + $this->url = "?host=".$this->host."&srv=".$this->service; + $services = $this->data->getServices($this->host); + #Landingpage for mobile devices + if($this->isMobileDevice()){ + url::redirect( "mobile/host/".urlencode($this->host)."/".urlencode($this->service) ); + } + #print Kohana::debug($services); + $this->data->buildDataStruct($this->host,$this->service,$this->view); + $this->is_authorized = $this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']); + + $this->title = Kohana::lang('common.service-details') . " ". $this->host ." -> " . $this->data->MACRO['DISP_SERVICEDESC']; + $this->template->graph->graph_content->graph_width = ($this->data->STRUCT[0]['GRAPH_WIDTH'] + 85); + // Status Box Vars + $this->template->graph->status_box->host = $this->data->MACRO['DISP_HOSTNAME']; + $this->template->graph->status_box->lhost = $this->data->MACRO['HOSTNAME']; + $this->template->graph->status_box->service = $this->data->MACRO['DISP_SERVICEDESC']; + $this->template->graph->status_box->lservice = $this->data->MACRO['SERVICEDESC']; + $this->template->graph->status_box->timet = date($this->config->conf['date_fmt'],intval($this->data->MACRO['TIMET'])); + // Service Box Vars + $this->template->graph->service_box->services = $services; + $this->template->graph->service_box->host = $this->host; + // Timerange Box Vars + $this->template->graph->timerange_box = $this->add_view('timerange_box'); + $this->template->graph->timerange_box->timeranges = $this->data->TIMERANGE; + // + // Host Overview + }elseif($this->host != ""){ + $this->is_authorized = $this->auth->is_authorized($this->host); + $this->host = pnp::clean($this->host); + #Landingpage for mobile devices + if($this->isMobileDevice()){ + url::redirect( "mobile/host/".urlencode($this->host) ); + } + if($this->view == ""){ + $this->view = $this->config->conf['overview-range']; + } + $this->url = "?host=".$this->host; + $this->title = Kohana::lang('common.start'). " ". $this->host; + $services = $this->data->getServices($this->host); + // Status Box Vars + $this->template->graph->status_box->host = $this->data->MACRO['DISP_HOSTNAME']; + $this->template->graph->status_box->lhost = $this->data->MACRO['HOSTNAME']; + $this->template->graph->status_box->shost = pnp::shorten($this->data->MACRO['DISP_HOSTNAME']); + $this->template->graph->status_box->timet = date($this->config->conf['date_fmt'],intval($this->data->MACRO['TIMET'])); + // Service Box Vars + $this->template->graph->service_box->services = $services; + $this->template->graph->service_box->host = $this->host; + // Timerange Box Vars + $this->template->graph->timerange_box = $this->add_view('timerange_box'); + $this->template->graph->timerange_box->timeranges = $this->data->TIMERANGE; + + $this->template->graph->icon_box->xml_icon = FALSE; + + $this->title = Kohana::lang('common.service-overview', $this->host); + foreach($services as $service){ + if($service['state'] == 'active') + $this->data->buildDataStruct($this->host,$service['name'],$this->view); + } + }else{ + #Landingpage for mobile devices + if($this->isMobileDevice()){ + url::redirect("mobile"); + return; + } + if($this->isAuthorizedFor('host_overview' ) ){ + $this->host = $this->data->getFirstHost(); + if(isset($this->host)){ + url::redirect("graph?host=".$this->host); + }else{ + throw new Kohana_Exception('error.get-first-host'); + } + }else{ + throw new Kohana_Exception('error.not_authorized_for_host_overview'); + } + } + $this->template->graph->logo_box = $this->add_view('logo_box'); + $this->template->graph->header->title = $this->title; + } +} diff --git a/share/pnp/application/controllers/image.php b/share/pnp/application/controllers/image.php new file mode 100644 index 0000000..ddf1725 --- /dev/null +++ b/share/pnp/application/controllers/image.php @@ -0,0 +1,56 @@ +auto_render = FALSE; + + if($this->input->get('w') != "" ) + $this->rrdtool->config->conf['graph_width'] = intval($this->input->get('w')); + if($this->input->get('graph_width') != "" ) + $this->rrdtool->config->conf['graph_width'] = intval($this->input->get('graph_width')); + + if($this->input->get('h') != "" ) + $this->rrdtool->config->conf['graph_height'] = intval($this->input->get('h')); + if($this->input->get('graph_height') != "" ) + $this->rrdtool->config->conf['graph_height'] = intval($this->input->get('graph_height')); + + $this->data->getTimeRange($this->start,$this->end,$this->view); + + if($this->tpl != ""){ + $this->data->buildDataStruct('__special',$this->tpl,$this->view,$this->source); + #print Kohana::debug($this->data->STRUCT); + $image = $this->rrdtool->doImage($this->data->STRUCT[0]['RRD_CALL']); + $this->rrdtool->streamImage($image); + }elseif(isset($this->host) && isset($this->service)){ + $this->data->buildDataStruct($this->host,$this->service,$this->view,$this->source); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE) + $this->rrdtool->streamImage("ERROR: NOT_AUTHORIZED"); + + #print Kohana::debug($this->data->STRUCT); + if(sizeof($this->data->STRUCT) > 0){ + $image = $this->rrdtool->doImage($this->data->STRUCT[0]['RRD_CALL']); + }else{ + $image = FALSE; + } + $this->rrdtool->streamImage($image); + }else{ + url::redirect("start", 302); + } + } + + +} diff --git a/share/pnp/application/controllers/json.php b/share/pnp/application/controllers/json.php new file mode 100644 index 0000000..306ec93 --- /dev/null +++ b/share/pnp/application/controllers/json.php @@ -0,0 +1,75 @@ +auto_render = FALSE; + // Service Details + if($this->host != "" && $this->service != ""){ + $services = $this->data->getServices($this->host); + $this->data->buildDataStruct($this->host,$this->service,$this->view); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE){ + print json_encode("not authorized"); + exit; + } + $i = 0; + $json = array(); + foreach($this->data->STRUCT as $struct){ + $json[$i]['image_url'] = "host=".$struct['MACRO']['HOSTNAME']."&srv=".$struct['MACRO']['SERVICEDESC']."&source=".$struct['SOURCE']."&view=".$struct['VIEW']; + $json[$i]['ds_name'] = $struct['ds_name']; + $json[$i]['start'] = $struct['TIMERANGE']['start']; + $json[$i]['end'] = $struct['TIMERANGE']['end']; + $json[$i]['title'] = $struct['TIMERANGE']['title']; + $i++; + } + print json_encode($json); + // Host Overview + }elseif($this->host != ""){ + if($this->auth->is_authorized($this->host) === FALSE){ + print json_encode("not authorized"); + exit; + } + $services = $this->data->getServices($this->host); + foreach($services as $service){ + if($service['state'] == 'active'){ + $this->data->buildDataStruct($this->host,$service['name'],$this->view); + } + } + $i = 0; + $json = array(); + foreach($this->data->STRUCT as $struct){ + $json[$i]['image_url'] = "host=".$struct['MACRO']['HOSTNAME']."&srv=".$struct['MACRO']['SERVICEDESC']."&source=".$struct['SOURCE']."&view=".$struct['VIEW']; + $json[$i]['servicedesc'] = $struct['MACRO']['SERVICEDESC']; + $json[$i]['ds_name'] = $struct['ds_name']; + $json[$i]['start'] = $struct['TIMERANGE']['start']; + $json[$i]['end'] = $struct['TIMERANGE']['end']; + $json[$i]['title'] = $struct['TIMERANGE']['title']; + $i++; + } + print json_encode($json); + }else{ + $this->hosts = $this->data->getHosts(); + $i = 0; + $json = array(); + foreach($this->hosts as $host){ + if($host['state'] == "active"){ + $json[$i]['hostname'] = $host['name']; + $i++; + } + } + print json_encode($json); + } + } +} diff --git a/share/pnp/application/controllers/mobile.php b/share/pnp/application/controllers/mobile.php new file mode 100644 index 0000000..dace76f --- /dev/null +++ b/share/pnp/application/controllers/mobile.php @@ -0,0 +1,93 @@ +session->set('classic-ui',0); + $this->template = $this->add_view('mobile'); + } + + public function index() + { + $this->template->home = $this->add_view('mobile_home'); + } + public function about() + { + $this->template->about = $this->add_view('mobile_about'); + } + public function overview() + { + $this->template->overview = $this->add_view('mobile_overview'); + $this->template->overview->hosts = $this->data->getHosts(); + } + public function host($host=NULL) + { + $this->template->host = $this->add_view('mobile_host'); + $this->is_authorized = $this->auth->is_authorized($host); + $this->template->host->hostname = $host; + $this->template->host->services = $this->data->getServices($host); + } + public function graph($host=NULL, $service=NULL) + { + $this->template->graph = $this->add_view('mobile_graph'); + $this->data->buildDataStruct($host,$service,$this->view); + $this->is_authorized = $this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']); + } + public function search() + { + $this->template->query = $this->add_view('mobile_search'); + $query = pnp::clean($this->input->post('term')); + $result = array(); + if(strlen($query)>=1) { + $hosts = $this->data->getHosts(); + foreach($hosts as $host){ + if(preg_match("/$query/i",$host['name'])){ + array_push($result,$host['name']); + } + } + } + $this->result = $result; + } + public function pages($page=NULL) + { + $this->is_authorized=TRUE; + if($this->view == ""){ + $this->view = $this->config->conf['overview-range']; + } + + $this->page = $page; + if(is_null($this->page) ){ + $this->template->pages = $this->add_view('mobile_pages'); + $this->template->pages->pages = $this->data->getPages(); + return; + } + $this->data->buildPageStruct($this->page,$this->view); + $this->template->pages = $this->add_view('mobile_graph'); + } + public function special($tpl=NULL) + { + $this->tpl = $tpl; + if(is_null($this->tpl) ){ + $this->template->special = $this->add_view('mobile_special'); + $this->template->special->templates = $this->data->getSpecialTemplates(); + return; + } + $this->data->buildDataStruct('__special',$this->tpl,$this->view); + $this->template->special = $this->add_view('mobile_graph_special'); + } + public function go($goto=FALSE) + { + if($goto == 'classic'){ + $this->session->set('classic-ui',1); + url::redirect("graph"); + } + } +} diff --git a/share/pnp/application/controllers/page.php b/share/pnp/application/controllers/page.php new file mode 100644 index 0000000..7bd877e --- /dev/null +++ b/share/pnp/application/controllers/page.php @@ -0,0 +1,80 @@ +template = $this->add_view('template'); + $this->template->page = $this->add_view('page'); + $this->template->zoom_header = $this->add_view('zoom_header'); + $this->template->zoom_header->graph_width = ($this->config->conf['graph_width'] + 140); + $this->template->zoom_header->graph_height = ($this->config->conf['graph_height'] + 230); + $this->template->page->graph_content = $this->add_view('graph_content'); + $this->template->page->graph_content->graph_width = ($this->config->conf['graph_width'] + 85); + $this->template->page->graph_content->timerange_select = $this->add_view('timerange_select'); + $this->template->page->header = $this->add_view('header'); + $this->template->page->search_box = $this->add_view('search_box'); + $this->template->page->logo_box = $this->add_view('logo_box'); + $this->is_authorized=TRUE; + } + + public function index(){ + if( !$this->isAuthorizedFor('pages') ){ + throw new Kohana_Exception('error.auth-pages'); + } + $this->page = pnp::clean($this->input->get('page')); + if($this->page == ""){ + $this->page = $this->data->getFirstPage(); + } + if($this->page == ""){ + throw new Kohana_Exception('error.page-config-dir', $this->config->conf['page_dir']); + } + if($this->view == ""){ + $this->view = $this->config->conf['overview-range']; + } + $this->data->buildPageStruct($this->page,$this->view); + $this->template->page->header->title = Kohana::lang('common.page',$this->data->PAGE_DEF['page_name']); + $this->url = "?page&page=$this->page"; + // Timerange Box Vars + $this->template->page->timerange_box = $this->add_view('timerange_box'); + $this->template->page->timerange_box->timeranges = $this->data->TIMERANGE; + // Pages Box + $this->pages = $this->data->getPages(); + $this->template->page->pages_box = $this->add_view('pages_box'); + $this->template->page->pages_box->pages = $this->pages; + // Basket Box + $this->template->page->basket_box = $this->add_view('basket_box'); + // Icon Box + $this->template->page->icon_box = $this->add_view('icon_box'); + $this->template->page->icon_box->position = "page"; + + } + + public function basket(){ + $basket = $this->session->get("basket"); + if(is_array($basket) && sizeof($basket) > 0){ + $this->data->buildBasketStruct($basket,$this->view); + $this->template->page->basket_box = $this->add_view('basket_box'); + $this->template->page->header->title = Kohana::lang('common.page-basket'); + $this->url = "basket?"; + // Timerange Box Vars + $this->template->page->timerange_box = $this->add_view('timerange_box'); + $this->template->page->timerange_box->timeranges = $this->data->TIMERANGE; + // Pages Box + $this->pages = $this->data->getPages(); + $this->template->page->pages_box = $this->add_view('pages_box'); + $this->template->page->pages_box->pages = $this->pages; + // Icon Box + $this->template->page->icon_box = $this->add_view('icon_box'); + $this->template->page->icon_box->position = "basket"; + }else{ + url::redirect("start", 302); + } + } +} diff --git a/share/pnp/application/controllers/pdf.php b/share/pnp/application/controllers/pdf.php new file mode 100644 index 0000000..15f2ab4 --- /dev/null +++ b/share/pnp/application/controllers/pdf.php @@ -0,0 +1,280 @@ +use_bg = 0; + $this->bg = $this->config->conf['background_pdf']; + $this->pdf_page_size = $this->config->conf['pdf_page_size']; + $this->pdf_margin_left = $this->config->conf['pdf_margin_left']; + $this->pdf_margin_top = $this->config->conf['pdf_margin_top']; + $this->pdf_margin_right = $this->config->conf['pdf_margin_right']; + + // Define PDF background per url option + if(isset($this->bg) && $this->bg != ""){ + if( is_readable( Kohana::config( 'core.pnp_etc_path')."/".$this->bg ) ){ + $this->bg = Kohana::config('core.pnp_etc_path')."/".$this->bg; + }else{ + $this->bg = $this->config->conf['background_pdf']; + } + } + // Use PDF background if readable + if(is_readable($this->bg)){ + $this->use_bg = 1; + } + + } + + public function index(){ + + $this->tpl = pnp::clean($this->input->get('tpl')); + $this->type = "normal"; + + $this->data->getTimeRange($this->start,$this->end,$this->view); + + // Service Details + if($this->host != "" && $this->service != ""){ + $this->data->buildDataStruct($this->host,$this->service,$this->view); + // Host Overview + }elseif($this->host != ""){ + if($this->view == ""){ + $this->view = $this->config->conf['overview-range']; + } + $services = $this->data->getServices($this->host); + foreach($services as $service){ + if($service['state'] == 'active') + $this->data->buildDataStruct($this->host,$service['name'],$this->view); + } + // Special Templates + }elseif($this->tpl != ""){ + $this->data->buildDataStruct('__special',$this->tpl,$this->view); + $this->type = 'special'; + }else{ + $this->host = $this->data->getFirstHost(); + if(isset($this->host)){ + url::redirect("/graph?host=$this->host"); + }else{ + throw new Kohana_User_Exception('Hostname not set ;-)', "RTFM my Friend, RTFM!"); + } + } + #throw new Kohana_Exception(print_r($this->data->STRUCT,TRUE)); + /* + * PDF Output + */ + $pdf = new PDF("P", "mm", $this->pdf_page_size); + $pdf->AliasNbPages(); + $pdf->SetAutoPageBreak('off'); + $pdf->SetMargins($this->pdf_margin_left,$this->pdf_margin_top,$this->pdf_margin_right); + $pdf->AddPage(); + if($this->use_bg){ + $pdf->setSourceFile($this->bg); + $tplIdx = $pdf->importPage(1,'/MediaBox'); + $pdf->useTemplate($tplIdx); + } + $pdf->SetCreator('Created with PNP'); + $pdf->SetFont('Arial', '', 10); + // Title + $header = TRUE; + foreach($this->data->STRUCT as $key=>$data){ + if($key != 0){ + $header = FALSE; + } + if ($pdf->GetY() > 200) { + $pdf->AddPage(); + if($this->use_bg){$pdf->useTemplate($tplIdx);} + } + if($this->type == 'normal'){ + if($data['LEVEL'] == 0){ + $pdf->SetFont('Arial', '', 12); + $pdf->CELL(120, 10, $data['MACRO']['DISP_HOSTNAME']." -- ".$data['MACRO']['DISP_SERVICEDESC'], 0, 1); + $pdf->SetFont('Arial', '', 10); + $pdf->CELL(120, 5, $data['TIMERANGE']['title']." (".$data['TIMERANGE']['f_start']." - ".$data['TIMERANGE']['f_end'].")", 0, 1); + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + }else{ + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + } + }elseif($this->type == 'special'){ + if($header){ + $pdf->SetFont('Arial', '', 12); + $pdf->CELL(120, 10, $data['MACRO']['TITLE'], 0, 1); + $pdf->SetFont('Arial', '', 10); + $pdf->CELL(120, 5, $data['TIMERANGE']['title']." (".$data['TIMERANGE']['f_start']." - ".$data['TIMERANGE']['f_end'].")", 0, 1); + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + }else{ + $pdf->SetFont('Arial', '', 10); + $pdf->CELL(120, 5, $data['TIMERANGE']['title']." (".$data['TIMERANGE']['f_start']." - ".$data['TIMERANGE']['f_end'].")", 0, 1); + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + } + } + $image = $this->rrdtool->doImage($data['RRD_CALL'],$out='PDF'); + $img = $this->rrdtool->saveImage($image); + $Y = $pdf->GetY(); + $cell_height = ($img['height'] * 0.23); + $cell_width = ($img['width'] * 0.23); + $pdf->Image($img['file'], $this->pdf_margin_left, $Y, $cell_width, $cell_height, 'PNG'); + $pdf->CELL(120, $cell_height, '', 0, 1); + unlink($img['file']); + } + $pdf->Output("pnp4nagios.pdf","I"); + + } + + public function page($page){ + $this->start = $this->input->get('start'); + $this->end = $this->input->get('end'); + $this->view = ""; + + if(isset($_GET['view']) && $_GET['view'] != "" ){ + $this->view = pnp::clean($_GET['view']); + } + + $this->data->getTimeRange($this->start,$this->end,$this->view); + $this->data->buildPageStruct($page,$this->view); + // Define PDF background per url option + if(isset($this->data->PAGE_DEF['background_pdf'])){ + if( is_readable( Kohana::config( 'core.pnp_etc_path')."/".$this->data->PAGE_DEF['background_pdf'] ) ){ + $this->bg = Kohana::config('core.pnp_etc_path')."/".$this->data->PAGE_DEF['background_pdf']; + } + } + /* + * PDF Output + */ + $pdf = new PDF("P", "mm", $this->pdf_page_size); + $pdf->AliasNbPages(); + $pdf->SetAutoPageBreak('off'); + $pdf->SetMargins($this->pdf_margin_left,$this->pdf_margin_top,$this->pdf_margin_right); + $pdf->AddPage(); + if($this->use_bg){ + $pdf->setSourceFile($this->bg); + $tplIdx = $pdf->importPage(1,'/MediaBox'); + $pdf->useTemplate($tplIdx); + } + + $pdf->SetCreator('Created with PNP'); + $pdf->SetFont('Arial', '', 10); + // Title + foreach($this->data->STRUCT as $data){ + if ($pdf->GetY() > 200) { + $pdf->AddPage(); + if($this->use_bg){$pdf->useTemplate($tplIdx);} + } + if($data['LEVEL'] == 0){ + $pdf->SetFont('Arial', '', 12); + $pdf->CELL(120, 10, $data['MACRO']['DISP_HOSTNAME']." -- ".$data['MACRO']['DISP_SERVICEDESC'], 0, 1); + $pdf->SetFont('Arial', '', 10); + $pdf->CELL(120, 5, $data['TIMERANGE']['title']." (".$data['TIMERANGE']['f_start']." - ".$data['TIMERANGE']['f_end'].")", 0, 1); + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + }else{ + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + } + $image = $this->rrdtool->doImage($data['RRD_CALL'],$out='PDF'); + $img = $this->rrdtool->saveImage($image); + $Y = $pdf->GetY(); + $cell_height = ($img['height'] * 0.23); + $cell_width = ($img['width'] * 0.23); + $pdf->Image($img['file'], $this->pdf_margin_left, $Y, $cell_width, $cell_height, 'PNG'); + $pdf->CELL(120, $cell_height, '', 0, 1); + unlink($img['file']); + } + $pdf->Output("pnp4nagios.pdf","I"); + } + + public function basket(){ + $this->start = $this->input->get('start'); + $this->end = $this->input->get('end'); + $this->view = ""; + if(isset($_GET['view']) && $_GET['view'] != "" ){ + $this->view = pnp::clean($_GET['view']); + } + $this->data->getTimeRange($this->start,$this->end,$this->view); + $basket = $this->session->get("basket"); + if(is_array($basket) && sizeof($basket) > 0){ + $this->data->buildBasketStruct($basket,$this->view); + } + //echo Kohana::debug($this->data->STRUCT); + /* + * PDF Output + */ + $pdf = new PDF("P", "mm", $this->pdf_page_size); + $pdf->AliasNbPages(); + $pdf->SetAutoPageBreak('off'); + $pdf->SetMargins($this->pdf_margin_left,$this->pdf_margin_top,$this->pdf_margin_right); + $pdf->AddPage(); + if($this->use_bg){ + $pdf->setSourceFile($this->config->conf['background_pdf']); + $tplIdx = $pdf->importPage(1,'/MediaBox'); + $pdf->useTemplate($tplIdx); + } + + $pdf->SetCreator('Created with PNP'); + $pdf->SetFont('Arial', '', 10); + // Title + foreach($this->data->STRUCT as $data){ + if ($pdf->GetY() > 200) { + $pdf->AddPage(); + if($this->use_bg){$pdf->useTemplate($tplIdx);} + } + if($data['LEVEL'] == 0){ + $pdf->SetFont('Arial', '', 12); + $pdf->CELL(120, 10, $data['MACRO']['DISP_HOSTNAME']." -- ".$data['MACRO']['DISP_SERVICEDESC'], 0, 1); + $pdf->SetFont('Arial', '', 10); + $pdf->CELL(120, 5, $data['TIMERANGE']['title']." (".$data['TIMERANGE']['f_start']." - ".$data['TIMERANGE']['f_end'].")", 0, 1); + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + }else{ + $pdf->SetFont('Arial', '', 8); + $pdf->CELL(120, 5, "Datasource ".$data["ds_name"], 0, 1); + } + $image = $this->rrdtool->doImage($data['RRD_CALL'],$out='PDF'); + $img = $this->rrdtool->saveImage($image); + $Y = $pdf->GetY(); + $cell_height = ($img['height'] * 0.23); + $cell_width = ($img['width'] * 0.23); + $pdf->Image($img['file'], $this->pdf_margin_left, $Y, $cell_width, $cell_height, 'PNG'); + $pdf->CELL(120, $cell_height, '', 0, 1); + unlink($img['file']); + } + $pdf->Output("pnp4nagios.pdf","I"); + + } +} + + +/* ++ +* +*/ +require Kohana::find_file('vendor/fpdf', 'fpdf'); +require Kohana::find_file('vendor/fpdf', 'fpdi'); +class PDF extends FPDI { + //Page header + function Header() { + //Arial bold 10 + $this->SetFont('Arial', 'B', 10); + } + + //Page footer + function Footer() { + //Position at 1.5 cm from bottom + $this->SetY(-20); + //Arial italic 8 + $this->SetFont('Arial', 'I', 8); + //Page number + $this->Cell(0, 10, $this->PageNo() . '/{nb}', 0, 0, 'C'); + } +} + diff --git a/share/pnp/application/controllers/popup.php b/share/pnp/application/controllers/popup.php new file mode 100644 index 0000000..162ca73 --- /dev/null +++ b/share/pnp/application/controllers/popup.php @@ -0,0 +1,41 @@ +template = $this->add_view('popup'); + } + + public function index() + { + if ( $this->view == "" ){ + $this->view = $this->config->conf['overview-range']; + } + + $this->imgwidth = pnp::clean($this->input->get('width',$this->config->conf['popup-width'])); + + $this->data->getTimeRange($this->start,$this->end,$this->view); + + if(isset($this->host) && isset($this->service)){ + $this->data->buildDataStruct($this->host,$this->service,$this->view,$this->source); + $this->template->host = $this->host; + $this->template->srv = $this->service; + $this->template->view = $this->view; + $this->template->source = $this->source; + $this->template->end = $this->end; + $this->template->start = $this->start; + $this->template->imgwidth = $this->imgwidth; + }else{ + url::redirect("/graph"); + } + } +} diff --git a/share/pnp/application/controllers/special.php b/share/pnp/application/controllers/special.php new file mode 100644 index 0000000..bc98518 --- /dev/null +++ b/share/pnp/application/controllers/special.php @@ -0,0 +1,52 @@ +template = $this->add_view('template'); + $this->template->graph = $this->add_view('graph'); + $this->templates = $this->data->getSpecialTemplates(); + $this->data->GRAPH_TYPE = 'special'; + if($this->tpl == ''){ + if($this->templates) + $this->tpl = $this->templates[0]; + url::redirect('special?tpl='.$this->tpl, 302); + } + } + + public function index(){ + $this->url = "?tpl=".$this->tpl; + $this->template->zoom_header = $this->add_view('zoom_header'); + $this->template->zoom_header->graph_width = ($this->config->conf['graph_width'] + 140); + $this->template->zoom_header->graph_height = ($this->config->conf['graph_height'] + 230); + $this->template->graph->graph_content = $this->add_view('graph_content_special'); + $this->template->graph->graph_content->graph_width = ($this->config->conf['graph_width'] + 85); + $this->template->graph->graph_content->timerange_select = $this->add_view('timerange_select'); + $this->template->graph->header = $this->add_view('header'); + $this->template->graph->search_box = $this->add_view('search_box'); + $this->template->graph->service_box = $this->add_view('special_templates_box'); + #$this->template->graph->status_box = $this->add_view('status_box'); + #$this->template->graph->basket_box = $this->add_view('basket_box'); + $this->template->graph->widget_menu = $this->add_view('widget_menu'); + $this->template->graph->graph_content->widget_graph = $this->add_view('widget_graph'); + #print Kohana::debug($services); + $this->data->buildDataStruct('__special',$this->tpl,$this->view); + $this->template->graph->icon_box = $this->add_view('icon_box'); + $this->template->graph->icon_box->position = "special"; + $this->template->graph->logo_box = $this->add_view('logo_box'); + // Timerange Box Vars + $this->template->graph->timerange_box = $this->add_view('timerange_box'); + $this->template->graph->timerange_box->timeranges = $this->data->TIMERANGE; + $this->template->graph->header->title = $this->data->MACRO['TITLE']; + //print Kohana::debug($this->data); + } + +} diff --git a/share/pnp/application/controllers/start.php b/share/pnp/application/controllers/start.php new file mode 100644 index 0000000..b575655 --- /dev/null +++ b/share/pnp/application/controllers/start.php @@ -0,0 +1,21 @@ +data = new Data_Model(); + $this->config = new Config_Model(); + $this->rrdtool = new Rrdtool_Model(); + $this->auth = new Auth_Model(); + #$this->system = new System_Model(); + + $this->config->read_config(); + Kohana::config_set('locale.language',$this->config->conf['lang']); + // Check for mod_rewrite + $this->check_mod_rewrite(); + + $this->start = pnp::clean($this->input->get('start',FALSE)); + $this->end = pnp::clean($this->input->get('end',FALSE)); + $this->theme = pnp::clean($this->input->get('theme',FALSE)); + $this->view = pnp::clean($this->input->get('view', "")); + $this->host = pnp::clean($this->input->get('host',NULL)); + $this->service = pnp::clean($this->input->get('srv',NULL)); + $this->source = pnp::clean($this->input->get('source',0)); + $this->version = pnp::clean($this->input->get('version',NULL)); + $this->tpl = pnp::clean($this->input->get('tpl')); + $this->controller = Router::$controller; + + $this->data->getTimeRange($this->start,$this->end,$this->view); + if(Router::$controller != "image" && Router::$controller != "image_special"){ + $this->session = Session::instance(); + + # Session withou theme info + if($this->session->get("theme","new") == "new"){ + if($this->theme){ + # store $this->theme if available + Kohana::config_set('core.theme',$this->theme); + $this->session->set('theme', $this->theme ); + }else{ + # set $this->theme to default value + $this->theme = $this->config->conf['ui-theme']; + Kohana::config_set('core.theme',$this->theme); + } + # Sesion with theme info + }else{ + if($this->theme && $this->theme != 'default'){ + # store $this->theme if available + $this->session->set('theme', $this->theme ); + Kohana::config_set('core.theme',$this->theme); + }elseif($this->theme == 'default'){ + # reset to default theme + $this->theme = $this->config->conf['ui-theme']; + $this->session->set('theme', $this->theme ); + Kohana::config_set('core.theme',$this->theme); + }else{ + # set $this->theme with session infos + $this->theme = $this->session->get('theme'); + Kohana::config_set('core.theme',$this->theme); + } + } + + if($this->start && $this->end ){ + if($this->session->get('timerange-reset',0) == 0){ + $this->session->set("start", $this->start); + $this->session->set("end", $this->end); + }else{ + $this->session->set('timerange-reset', 0); + } + } + if($this->start && !$this->end){ + if($this->session->get('timerange-reset',0) == 0){ + $this->session->set("start", $this->start); + $this->session->set("end", ""); + }else{ + $this->session->set('timerange-reset', 0); + } + } + if($this->end && !$this->start){ + if($this->session->get('timerange-reset',0) == 0){ + $this->session->set("end", $this->end); + $this->session->set("start", ""); + }else{ + $this->session->set('timerange-reset', 0); + } + } + } + } + + public function __call($method, $arguments) + { + // Disable auto-rendering + $this->auto_render = FALSE; + + // By defining a __call method, all pages routed to this controller + // that result in 404 errors will be handled by this method, instead of + // being displayed as "Page Not Found" errors. + echo $this->_("The requested page doesn't exist") . " ($method)"; + } + + /** + * Handle paths to current theme etc + * + */ + public function add_view($view=false) + { + $view = trim($view); + if (empty($view)) { + return false; + } + if (!file_exists(APPPATH."/views/".$view.".php")) { + return false; + } + #return new View($this->theme_path.$view); + return new View($view); + } + + public function check_mod_rewrite(){ + if(!function_exists('apache_get_modules')){ + // Add index.php to every URL while not running withn apache mod_php + Kohana::config_set('core.index_page','index.php'); + return TRUE; + } + if(!in_array('mod_rewrite', apache_get_modules())){ + // Add index.php to every URL while mod_rewrite is not available + Kohana::config_set('core.index_page','index.php'); + } + if ( $this->config->conf['use_url_rewriting'] == 0 ){ + Kohana::config_set('core.index_page','index.php'); + } + } + + public function isAuthorizedFor($auth) { + $conf = $this->config->conf; + if ($auth == "service_links") { + + $users = explode(",", $conf['allowed_for_service_links']); + if (in_array('EVERYONE', $users)) { + return 1; + } + elseif (in_array('NONE', $users)) { + return 0; + } + elseif (in_array($this->auth->REMOTE_USER, $users)) { + return 1; + } else { + return 0; + } + } + if ($auth == "host_search") { + $users = explode(",", $conf['allowed_for_host_search']); + if (in_array('EVERYONE', $users)) { + return 1; + } + elseif (in_array('NONE', $users)) { + return 0; + } + elseif (in_array($this->auth->REMOTE_USER, $users)) { + return 1; + } else { + return 0; + } + } + if ($auth == "host_overview") { + $users = explode(",", $conf['allowed_for_host_overview']); + if (in_array('EVERYONE', $users)) { + return 1; + } + elseif (in_array('NONE', $users)) { + return 0; + } + elseif (in_array($this->auth->REMOTE_USER, $users)) { + return 1; + } else { + return 0; + } + } + if ($auth == "pages") { + $users = explode(",", $conf['allowed_for_pages']); + if (in_array('EVERYONE', $users)) { + return 1; + } + elseif (in_array('NONE', $users)) { + return 0; + } + elseif (in_array($this->auth->REMOTE_USER, $users)) { + return 1; + } else { + return 0; + } + } + } + public function isMobileDevice (){ + if( $this->session->get('classic-ui',0) == 1){ + return FALSE; + } + if ( preg_match('/'.$this->config->conf['mobile_devices'].'/', $_SERVER['HTTP_USER_AGENT'] ) ){ + return TRUE; + }else{ + return FALSE; + } + } +} diff --git a/share/pnp/application/controllers/xml.php b/share/pnp/application/controllers/xml.php new file mode 100644 index 0000000..3931a72 --- /dev/null +++ b/share/pnp/application/controllers/xml.php @@ -0,0 +1,48 @@ +config->read_config(); + } + + public function index() + { + $this->auto_render = FALSE; + if($this->service == "" && $this->host == ""){ + url::redirect("graph", 302); + } + $this->data->readXML($this->host, $this->service); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE){ + header('Content-Type: application/xml'); + print "\n"; + print "\n"; + print "not authorized\n"; + print "\n"; + exit; + }else{ + $xmlfile = $this->config->conf['rrdbase'].$this->host."/".$this->service.".xml"; + if(is_readable($xmlfile)){ + $fh = fopen($xmlfile, 'r'); + header('Content-Type: application/xml'); + fpassthru($fh); + fclose($fh); + exit; + }else{ + header('Content-Type: application/xml'); + print "\n"; + print "\n"; + print "file not found\n"; + print "\n"; + } + } + } +} diff --git a/share/pnp/application/controllers/xport.php b/share/pnp/application/controllers/xport.php new file mode 100644 index 0000000..fa26fad --- /dev/null +++ b/share/pnp/application/controllers/xport.php @@ -0,0 +1,74 @@ +auto_render = FALSE; + $this->data->getTimeRange($this->start,$this->end,$this->view); + + } + + public function xml(){ + if(isset($this->host) && isset($this->service)){ + $this->data->buildXport($this->host,$this->service); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE){ + header('Content-Type: application/xml'); + print "\n"; + print "\n"; + print "not authorized\n"; + print "\n"; + exit; + } + $data = $this->rrdtool->doXport($this->data->XPORT); + header('Content-Type: application/xml'); + print $data; + }else{ + throw new Kohana_Exception('error.xport-host-service'); + } + } + + public function json(){ + if(isset($this->host) && isset($this->service)){ + $this->data->buildXport($this->host,$this->service); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE){ + header('Content-type: application/json'); + print json_encode("not authorized"); + exit; + } + $data = $this->rrdtool->doXport($this->data->XPORT); + $json = json_encode(simplexml_load_string($data)); + header('Content-type: application/json'); + print $json; + }else{ + throw new Kohana_Exception('error.xport-host-service'); + } + } + + public function csv(){ + if(isset($this->host) && isset($this->service)){ + $this->data->buildXport($this->host,$this->service); + if($this->auth->is_authorized($this->data->MACRO['AUTH_HOSTNAME'], $this->data->MACRO['AUTH_SERVICEDESC']) === FALSE){ + header("Content-Type: text/plain; charset=UTF-8"); + print "not authorized"; + exit; + } + $data = $this->rrdtool->doXport($this->data->XPORT); + $csv = $this->data->xml2csv($data); + header("Content-Type: text/plain; charset=UTF-8"); + print $csv; + }else{ + throw new Kohana_Exception('error.xport-host-service'); + } + } + + +} diff --git a/share/pnp/application/controllers/zoom.php b/share/pnp/application/controllers/zoom.php new file mode 100644 index 0000000..7355738 --- /dev/null +++ b/share/pnp/application/controllers/zoom.php @@ -0,0 +1,80 @@ +template = $this->add_view('zoom'); + #$this->tpl = $this->input->get('tpl'); + $this->graph_width = $this->config->conf['zgraph_width']; + $this->graph_height = $this->config->conf['zgraph_height']; + } + + public function index() + { + #$this->source = intval($this->input->get('source')); + #$this->view = ""; + + #if(isset($_GET['view']) && $_GET['view'] != "" ){ + # $this->view = pnp::clean($_GET['view']); + #}else{ + # $this->view = $this->config->conf['overview-range']; + #} + + # + # Limit startto 2000/01/01 + # + $start_limit = strtotime("2000/01/01"); + $this->start = abs((int)$this->start); + if($this->start < $start_limit) + $this->start = $start_limit; + # + # Limit end to now + one hour + # + $end_limit = time() + 3600; + $this->end = abs((int)$this->end); + if($this->end > $end_limit) + $this->end = $end_limit; + + $this->data->getTimeRange($this->start,$this->end,$this->view); + + if(isset($this->tpl) && $this->tpl != 'undefined' ){ + if($this->start && $this->end ){ + $this->session->set("start", $this->start); + $this->session->set("end", $this->end); + } + $this->template->tpl = $this->tpl; + $this->template->view = $this->view; + $this->template->source = $this->source; + $this->template->end = $this->end; + $this->template->start = $this->start; + $this->url = "?tpl=".$this->tpl; + $this->template->graph_height = $this->graph_height; + $this->template->graph_width = $this->graph_width; + }elseif(isset($this->host) && isset($this->service)){ + if($this->start && $this->end ){ + $this->session->set("start", $this->start); + $this->session->set("end", $this->end); + } + $this->template->host = $this->host; + $this->template->srv = $this->service; + $this->template->view = $this->view; + $this->template->source = $this->source; + $this->template->end = $this->end; + $this->template->start = $this->start; + $this->url = "?host=".$this->host."&srv=".$this->service; + $this->template->graph_height = $this->graph_height; + $this->template->graph_width = $this->graph_width; + }else{ + url::redirect("/graph"); + } + } +} diff --git a/share/pnp/application/helpers/nagios.php b/share/pnp/application/helpers/nagios.php new file mode 100644 index 0000000..e1f70a9 --- /dev/null +++ b/share/pnp/application/helpers/nagios.php @@ -0,0 +1,58 @@ +read_config(); + + $smon = date('m' , $start); + $sday = date('d' , $start); + $syear = date('Y' , $start); + $shour = date('G' , $start); + $smin = date('i' , $start); + $ssec = date('s' , $start); + $emon = date('m' , $end); + $eday = date('d' , $end); + $eyear = date('Y' , $end); + $ehour = date('G' , $end); + $emin = date('i' , $end); + $esec = date('s' , $end); + $nagios_base = $config->conf['nagios_base']; + print "\n"; + } + + public static function AvailLink($hostname,$servicedesc,$start,$end){ + $config = new Config_Model(); + $config->read_config(); + $hostname = urlencode($hostname); + $servicedesc = urlencode($servicedesc); + $smon = date('m' , $start); + $sday = date('d' , $start); + $syear = date('Y' , $start); + $shour = date('G' , $start); + $smin = date('i' , $start); + $ssec = date('s' , $start); + $emon = date('m' , $end); + $eday = date('d' , $end); + $eyear = date('Y' , $end); + $ehour = date('G' , $end); + $emin = date('i' , $end); + $esec = date('s' , $end); + $nagios_base = $config->conf['nagios_base']; + if($servicedesc == "Host+Perfdata"){ + print "\n"; +} + + + +} diff --git a/share/pnp/application/helpers/pnp.php b/share/pnp/application/helpers/pnp.php new file mode 100644 index 0000000..7134a55 --- /dev/null +++ b/share/pnp/application/helpers/pnp.php @@ -0,0 +1,150 @@ + $length){ + $string = substr($string, 0, $length) . "..."; + } + return $string; + } + /* + * + */ + public static function xml_version_check($string = FALSE){ + if($string === FALSE){ + return FALSE; + } + if( $string == XML_STRUCTURE_VERSION ){ + $string = "valid"; + }else{ + $string = Kohana::lang('error.xml-structure-mismatch', $string, XML_STRUCTURE_VERSION); + } + return $string; + } + /* + * + */ + public static function zoom_icon($host,$service,$start,$end,$source,$view,$graph_width,$graph_height){ + print "\n"; + } + + /* + * + */ + public static function zoom_icon_special($tpl,$start,$end,$source,$view,$graph_width,$graph_height){ + print "\n"; + } + + /* + * + */ + public static function add_to_basket_icon($host,$service,$source=FALSE){ + if($source === FALSE){ + print "\n"; + }else{ + print "\n"; + } + } + + /* + * + */ + public static function multisite_link($base_url=FALSE,$site=FALSE,$host=FALSE,$service=FALSE){ + if($host && $service){ + $link = sprintf("'%s/view.py?view_name=service&site=%s&host=%s&service=%s'", $base_url,$site,urlencode($host),urlencode($service)); + return $link; + } + if($host){ + $link = sprintf("'%s/view.py?view_name=host&site=%s&host=%s'", $base_url,$site,urlencode($host)); + return $link; + } + } + + public static function addToUri($fields = array(),$base = True){ + if(!is_array($fields)){ + return false; + } + $get = $_GET; + if($base === True){ + $uri = url::base(TRUE); + $uri .= Router::$current_uri; + }else{ + $uri = ""; + } + $uri .= '?'; + foreach($fields as $key=>$value){ + $get[$key] = $value; + } + foreach($get as $key=>$value){ + if($value === ''){ + continue; + } + $uri .= $key."=".urlencode($value)."&"; + } + return rtrim($uri,"&"); + } + + /* "normalize" and adjust value / unit (similar to format string %s in RRDtool) + * Parameters in: + * value := number, maybe suffixed by unit string + * examples: 1234, 1.234, 1234M, 1234Kb + * base := base of value (1000, e.g. traffic or 1024, e.g. disk size) + * format := format string + * Parameters out: + * val_unit := formatted value (including unit) + * val_fmt := formatted value (without leading blanks and unit) + * unit := adjusted unit + * divisor := number used to "normalize" value + */ + public static function adjust_unit($value,$base=1000,$format='%.3lf'){ + preg_match('/^(-?[0-9\.,]+)\s*(\S?)(\S?)/',$value,$matches); + + $mag = 0; + while ($value >= $base){ + $value /= $base; + $mag++; + } + $pos = 0; + if ($matches[2] == "%") { + $unit = '%'; + } else { + if ($matches[2] == "") { + $matches[2] = " "; + } + if (($matches[2] == "B") or ($matches[2] == "b")) { + $matches[3] = $matches[2]; + $matches[2] = " "; + } + $pos = strpos(' KMGTP',strtoupper($matches[2])); + $unit = substr(' KMGTP',$mag+$pos,1).$matches[3]; + } + $val_unit = sprintf ("$format %s", $value, $unit); + $val_fmt = sprintf ($format, $value); + $val_fmt = str_replace(' ','',$val_fmt); + return array ($val_unit,$val_fmt,$unit,pow($base,$mag)); + } + + public static function print_version(){ + return PNP_NAME . "-" . PNP_VERSION . " [ " . PNP_REL_DATE . " ]"; + } + +} diff --git a/share/pnp/application/helpers/rrd.php b/share/pnp/application/helpers/rrd.php new file mode 100644 index 0000000..2da22f4 --- /dev/null +++ b/share/pnp/application/helpers/rrd.php @@ -0,0 +1,459 @@ += 1 ){ + $color .= "$ri"; + } else { + $color .= "00"; + } + if ( ($z & 2) >= 1 ){ + $color .= "$ri"; + } else { + $color .= "00"; + } + if ( ($z & 1) >= 1 ){ + $color .= "$ri"; + } else { + $color .= "00"; + } + $icolor = rrd::color_inverse($color); + $pos = array_search($color,$colors); + $ipos = array_search($icolor,$colors); + if ( $pos == false ) { + $colors[] = $color . $alpha; + } + if ( $ipos == false ) { + $colors[] = $icolor . $alpha; + } + } + } + if (array_key_exists($num, $colors)) { + return $colors[$num]; + } else { + return $colors[0]; + } + } + + /* + * Gradient Function + * Concept by Stefan Triep + */ + public static function gradient($vname=FALSE, $start_color='#0000a0', $end_color='#f0f0f0', $label=FALSE, $steps=20, $lower=FALSE){ + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if(preg_match('/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i',$start_color,$matches)){ + $r1=hexdec($matches[1]); + $g1=hexdec($matches[2]); + $b1=hexdec($matches[3]); + }else{ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Wrong Color Format: '".$start_color."'"); + } + + if(preg_match('/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i',$end_color,$matches)){ + $r2=hexdec($matches[1]); + $g2=hexdec($matches[2]); + $b2=hexdec($matches[3]); + }else{ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Wrong Color Format: '".$end_color."'"); + } + + $diff_r=$r2-$r1; + $diff_g=$g2-$g1; + $diff_b=$b2-$b1; + $spline = ""; + $spline_vname = "var".substr(sha1(rand()),1,4); + if(preg_match('/^([0-9]{1,3})%$/', $lower, $matches)){ + if($matches[1] > 100) + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Lower gradient start > 100% is not allowed: '".$lower."'"); + + $lower = $matches[1]; + $spline .= sprintf("CDEF:%sminimum=%s,100,/,%d,* ", $vname, $vname, $lower); + }elseif(preg_match('/^([0-9]+)$/', $lower, $matches)){ + $lower = $matches[1]; + $spline .= sprintf("CDEF:%sminimum=%s,%d,- ", $vname, $vname, $lower); + }else{ + $lower = 0; + $spline .= sprintf("CDEF:%sminimum=%s,%s,- ", $vname, $vname, $vname); + } + # debug + # $spline .= sprintf("GPRINT:%sminimum:MAX:\"minumum %%lf\\n\" ",$vname); + for ($i=$steps; $i>0; $i--){ + $spline .= sprintf("CDEF:%s%d=%s,%sminimum,-,%d,/,%d,*,%sminimum,+ ",$spline_vname,$i,$vname,$vname,$steps,$i,$vname ); + # debug + # $spline .= sprintf("GPRINT:%s%d:MAX:\"%22d %%lf\\n\" ",$spline_vname,$i,$i); + } + for ($i=$steps; $i>0; $i--){ + $factor=$i / $steps; + $r=round($r1 + $diff_r * $factor); + $g=round($g1 + $diff_g * $factor); + $b=round($b1 + $diff_b * $factor); + if (($i==$steps) and ($label!=FALSE)){ + $spline .= sprintf("AREA:%s%d#%02X%02X%02X:\"%s\" ", $spline_vname,$i,$r,$g,$b,$label); + }else{ + $spline .= sprintf("AREA:%s%d#%02X%02X%02X ", $spline_vname,$i,$r,$g,$b); + } + } + return $spline; + } + + + public static function cut($string, $length=18, $align='left'){ + if(strlen($string) > $length){ + $string = substr($string,0,($length-3))."..."; + } + if($align == 'left'){ + $format = "%-".$length."s"; + }else{ + $format = "%".$length."s"; + } + $s = sprintf($format,$string); + return $s; + } + + public static function area($vname=FALSE, $color=FALSE, $text=FALSE, $stack=FALSE){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + }else{ + $line .= "AREA:".$vname; + } + if($color === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'color' is missing"); + }else{ + $line .= $color; + } + $line .= ":\"$text\""; + if($stack != FALSE){ + $line .= ":STACK"; + } + $line .= " "; + return $line; + } + + public static function line($type=1,$vname=FALSE, $color=FALSE, $text=FALSE, $stack=FALSE){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + }else{ + $line .= "LINE".$type.":".$vname; + } + if($color === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'color' is missing"); + }else{ + $line .= $color; + } + $line .= ":\"$text\""; + if($stack != FALSE){ + $line .= ":STACK"; + } + $line .= " "; + return $line; + } + + public static function line1($vname=FALSE, $color=FALSE, $text=FALSE, $stack=FALSE){ + return rrd::line(1,$vname, $color,$text, $stack); + } + + public static function line2($vname=FALSE, $color=FALSE, $text=FALSE, $stack=FALSE){ + return rrd::line(2,$vname, $color,$text, $stack); + } + + public static function line3($vname=FALSE, $color=FALSE, $text=FALSE, $stack=FALSE){ + return rrd::line(3,$vname, $color,$text, $stack); + } + + public static function gprint($vname=FALSE, $cf="AVERAGE", $text="%6.2lf %s"){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + + if(is_array($cf)){ + foreach($cf as $key => $val){ + $line .= sprintf("GPRINT:%s:%s:",$vname,$val); + if($key == sizeof($cf)-1){ + $line .= '"'.$text.' '.ucfirst(strtolower($val)).'\\l" '; + }else{ + $line .= '"'.$text.' '.ucfirst(strtolower($val)).'" '; + } + } + }else{ + $line .= sprintf("GPRINT:%s:%s:",$vname,$cf); + $line .= '"'.$text.'" '; + } + return $line; + } + + /* + * Function to modify alignment of gprint + */ + public static function gprinta($vname=FALSE, $cf="AVERAGE", $text="%6.2lf %s", $align=""){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($align != ""){ + $align = '\\' . $align; + } + if(is_array($cf)){ + foreach($cf as $key => $val){ + $line .= sprintf("GPRINT:%s:%s:",$vname,$val); + if(($key == sizeof($cf)-1)and($align != "")){ + $line .= '"'.$text.' '.ucfirst(strtolower($val)).$align.'" '; + }else{ + $line .= '"'.$text.' '.ucfirst(strtolower($val)).'" '; + } + } + }else{ + $line .= sprintf("GPRINT:%s:%s:",$vname,$cf); + $line .= '"'.$text.'" '; + } + return $line; + } + + public static function def($vname=FALSE, $rrdfile=FALSE, $ds=FALSE, $cf="AVERAGE"){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($rrdfile === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'rrdfile' is missing"); + } + if($rrdfile === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Third Parameter 'ds' is missing"); + } + $line = sprintf("DEF:%s=%s:%s:%s ",$vname,$rrdfile,$ds,$cf); + return $line; + } + + public static function cdef($vname=FALSE, $rpn=FALSE){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($rpn === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'rpn' is missing"); + } + $line = sprintf("CDEF:%s=%s ",$vname,$rpn); + return $line; + } + + public static function vdef($vname=FALSE, $rpn=FALSE){ + $line = ""; + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($rpn === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'rpn' is missing"); + } + $line = sprintf("VDEF:%s=%s ",$vname,$rpn); + return $line; + } + + public static function hrule($value=FALSE, $color=FALSE, $text=FALSE){ + $line = ""; + if($value === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ ."() First Parameter 'value' is missing"); + } + if($color === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'color' is missing"); + } + if($value == "~" ) { + return ""; + } + $line = sprintf("HRULE:%s%s:\"%s\" ",$value,$color,$text); + return $line; + } + + public static function comment($text=FALSE){ + $line = sprintf("COMMENT:\"%s\" ", $text); + return $line; + } + + public static function tick($vname=FALSE, $color=FALSE, $fraction=FALSE, $label=FALSE){ + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'value' is missing"); + } + if($color === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'color' is missing"); + } + $line = sprintf("TICK:%s%s",$vname,$color); + if($fraction != FALSE) + $line .= ":$fraction"; + + if($label != FALSE) + $line .= ":$label"; + + $line .= " "; + return $line; + } + + + public static function alerter($vname=FALSE, $label=FALSE, $warning=FALSE, $critical=FALSE, $opacity = 'ff', $unit, $color_green = '#00ff00', $color_btw = '#ffff00', $color_red = '#ff0000', $line_col = '#0000ff') { + + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($label === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'label' is missing"); + } + if($warning === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Third Parameter 'warning' is missing"); + } + if($critical === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Fourth Parameter 'critical' is missing"); + } + $line = ""; + $green_vname = "var".substr(sha1(rand()),1,4); + $btw_vname = "var".substr(sha1(rand()),1,4); + $blue_vname = "var".substr(sha1(rand()),1,4); + $red_vname = "var".substr(sha1(rand()),1,4); + if($warning < $critical){ + $line .= "CDEF:".$green_vname."=".$vname.",".$warning.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$btw_vname."=".$vname.",".$critical.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$blue_vname."=".$btw_vname.",".$warning.",GE,".$btw_vname.",UNKN,IF "; + $line .= "CDEF:".$red_vname."=".$vname.",".$critical.",GE,".$vname.",UNKN,IF "; + } else { + $line .= "CDEF:".$green_vname."=".$vname.",".$warning.",GT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$btw_vname."=".$vname.",".$critical.",GE,".$vname.",UNKN,IF "; + $line .= "CDEF:".$blue_vname."=".$btw_vname.",".$warning.",LE,".$btw_vname.",UNKN,IF "; + $line .= "CDEF:".$red_vname."=".$vname.",".$critical.",LT,".$vname.",UNKN,IF "; + } + $line .= rrd::area($green_vname, $color_green.$opacity); + $line .= rrd::area($blue_vname, $color_btw.$opacity); + $line .= rrd::area($red_vname, $color_red.$opacity); + $line .= rrd::line1($vname,$line_col,$label); + + return $line; + } + + public static function alerter_gr($vname=FALSE,$label=FALSE,$warning=FALSE,$critical=FALSE,$opacity='ff',$unit,$color_green='#00ff00',$color_btw='#ffff00',$color_red='#ff0000',$line_col='#0000ff',$start_color="#ffffff") { + + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($label === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'label' is missing"); + } + if($warning === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Third Parameter 'warning' is missing"); + } + if($critical === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Fourth Parameter 'critical' is missing"); + } + $line = ""; + $green_vname = "var".substr(sha1(rand()),1,4); + $btw_vname = "var".substr(sha1(rand()),1,4); + $blue_vname = "var".substr(sha1(rand()),1,4); + $red_vname = "var".substr(sha1(rand()),1,4); + $line = ""; + if($warning < $critical){ + $line .= "CDEF:".$green_vname."=".$vname.",".$warning.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$btw_vname."=".$vname.",".$critical.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$blue_vname."=".$btw_vname.",".$warning.",GE,".$btw_vname.",UNKN,IF "; + $line .= "CDEF:".$red_vname."=".$vname.",".$critical.",GE,".$vname.",UNKN,IF "; + } else { + $line .= "CDEF:".$green_vname."=".$vname.",".$warning.",GT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$btw_vname."=".$vname.",".$critical.",GE,".$vname.",UNKN,IF "; + $line .= "CDEF:".$blue_vname."=".$btw_vname.",".$warning.",LE,".$btw_vname.",UNKN,IF "; + $line .= "CDEF:".$red_vname."=".$vname.",".$critical.",LT,".$vname.",UNKN,IF "; + } + $line .= rrd::gradient($green_vname, $start_color, $color_green.$opacity); + $line .= rrd::gradient($blue_vname, $start_color, $color_btw.$opacity); + $line .= rrd::gradient($red_vname, $start_color, $color_red.$opacity); + $line .= rrd::line1($vname,$line_col,$label); + return $line; + } + + public static function ticker($vname=FALSE, $warning=FALSE, $critical=FALSE, $fraction = -0.05, $opacity = 'ff', $color_green = '#00ff00', $color_btw = '#ffff00', $color_red = '#ff0000') { + + if($vname === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() First Parameter 'vname' is missing"); + } + if($warning === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Second Parameter 'warning' is missing"); + } + if($critical === FALSE){ + throw new Kohana_exception("rrd::". __FUNCTION__ . "() Third Parameter 'critical' is missing"); + } + $line = ""; + $green_vname = "var".substr(sha1(rand()),1,4); + $btw_vname = "var".substr(sha1(rand()),1,4); + $blue_vname = "var".substr(sha1(rand()),1,4); + $red_vname = "var".substr(sha1(rand()),1,4); + $green2_vname = "var".substr(sha1(rand()),1,4); + $line .= "CDEF:".$green_vname."=".$vname.",".$warning.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$btw_vname."=".$vname.",".$critical.",LT,".$vname.",UNKN,IF "; + $line .= "CDEF:".$blue_vname."=".$btw_vname.",".$warning.",GE,".$btw_vname.",UNKN,IF "; + $line .= "CDEF:".$red_vname."=".$vname.",".$critical.",GE,".$vname.",UNKN,IF "; + $line .= "CDEF:".$green2_vname."=".$green_vname.",0,EQ,0.000001,".$green_vname.",IF "; + $line .= rrd::tick($green2_vname, $color_green.$opacity, $fraction); + $line .= rrd::tick($blue_vname, $color_btw.$opacity, $fraction); + $line .= rrd::tick($red_vname, $color_red.$opacity, $fraction); + + return $line; + } + + public static function darkteint(){ + $line = ''; + $line .= '--color=BACK#000000 '; + $line .= '--color=FONT#F7F7F7 '; + $line .= '--color=SHADEA#ffffff '; + $line .= '--color=SHADEB#ffffff '; + $line .= '--color=CANVAS#000000 '; + $line .= '--color=GRID#00991A '; + $line .= '--color=MGRID#00991A '; + $line .= '--color=ARROW#00FF00 '; + + return $line; + } + + public static function debug($data=FALSE){ + if($data != FALSE){ + ob_start(); + + var_dump($data); + $var_dump = ob_get_contents(); + $var_dump = preg_replace('/(HRULE|VDEF|DEF|CDEF|GPRINT|LINE|AREA|COMMENT)/',"\n\${1}", $var_dump); + ob_end_clean(); + throw new Kohana_exception("
    ".$var_dump."
    "); + } + } + +} diff --git a/share/pnp/application/i18n/de_DE/common.php b/share/pnp/application/i18n/de_DE/common.php new file mode 100644 index 0000000..bd7657c --- /dev/null +++ b/share/pnp/application/i18n/de_DE/common.php @@ -0,0 +1,59 @@ + 'Host: %s', + 'service' => 'Service: %s', + 'page' => 'Page: %s', + 'page-basket' => 'Page: Basket', + 'datasource' => 'Datasource: %s', + 'zoom-header' => 'Zoom', + 'status-box-header' => 'Status', + 'multisite-box-header' => 'Multisite Links', + 'search-box-header' => 'Suche', + 'icon-box-header' => 'Aktionen', + 'basket-box-header' => 'Mein Korb', + 'timerange-box-header' => 'Zeitbereiche', + 'service-box-header' => 'Services', + 'special-templates-box-header' => 'Special Templates', + 'pages-box-header' => 'Pages', + 'nagios-summary-link-title' => 'aktuellste Alarme für diesen Zeitbereich', + 'nagios-avail-link-title' => 'Nagios-Verügbarkeitsbericht für diesen Zeitbereich', + 'timerange-selector-legend' => 'Auswahl eines Zeitbereichs', + 'timerange-selector-title' => 'Auswahl eines Zeitbereichs', + 'timerange-selector-submit-button' => 'absenden', + 'timerange-selector-clear-button' => 'löschen', + 'timerange-selector-link' => 'Spezieller Zeitbereich', + 'timerange-selector-overview' => 'Übersicht', + 'start' => 'Start', + 'end' => 'Ende', + 'service-details' => 'Service-Details', + 'service-overview' => 'Service-Übersicht für "%s"', + 'title-pages-link' => 'Pages anzeigen', + 'title-pdf-link' => 'PDF anzeigen', + 'title-xml-link' => 'XML anzeigen', + 'title-statistics-link' => 'Interne PNP Statistiken', + 'title-calendar-link' => 'Einen Zeitbereich definieren', + 'title-special-templates-link' => 'Spezial Templates anzeigen', + 'title-docs-link' => 'Dokumentation', + 'title-home-link' => 'Zu den Graphen', + 'title-color-link' => 'View Color Schemes', + 'docs-home' => 'Home', + 'docs-box-header' => 'Menu', + 'docs-header' => 'Dokumentation Version %s', + 'back' => 'zurück', + 'mobile-all-hosts' => 'Alle Hosts', + 'mobile-search-hosts' => 'Hosts suchen', + 'mobile-pages' => 'Pages anzeigen', + 'mobile-special-templates' => 'Special Templates anzeigen', + 'mobile-statistics' => 'Interne PNP Statistiken', + 'mobile-go-classic' => 'Classic UI', + 'mobile-submit' => 'absenden', + 'basket-empty' => 'Basket ist leer', + 'basket-show' => 'Zeige Basket', + 'basket-clear' => 'Leere Basket', + 'basket-remove' => 'Entferne %s', + 'basket-add-item' => 'Graphen zum Basket hinzufügen', + 'basket-add-service' => 'Alle Graphen zum Basket hinzufügen', + 'color-box-header' => 'Colors', + 'color-header' => 'Colors Schemes', +); diff --git a/share/pnp/application/i18n/de_DE/error.php b/share/pnp/application/i18n/de_DE/error.php new file mode 100644 index 0000000..5814b7b --- /dev/null +++ b/share/pnp/application/i18n/de_DE/error.php @@ -0,0 +1,32 @@ + '"rrdtool"-Binary nicht in %s gefunden. FAQ online lesen', + 'config-not-found' => 'Config-Datei %s nicht gefunden. FAQ online lesen', + 'perfdata-dir-empty' => 'Das perfdata-Verzeichnis "%s" ist leer. Bitte die Nagios-Konfiguration prüfen. FAQ online lesen', + 'host-perfdata-dir-empty' => 'Das perfdata-Verzeichnis "%s" ist leer. Bitte die Nagios-Konfiguration prüfen. FAQ online lesen', + 'perfdata-dir-for-host' => 'Das perfdata-Verzeichnis "%s" für Host "%s" existiert nicht. FAQ online lesen', + 'xml-not-found' => 'XML-Datei "%s" nicht gefunden. FAQ online lesen', + 'get-first-service' => 'Konnte ersten Service für Host "%s" nicht finden. FAQ online lesen', + 'get-first-host' => 'Keinen Host gefunden. FAQ online lesen', + 'xml-structure-mismatch' => 'Version der XML-Struktur ungültig. Fand Version "%d", sollte aber "%d" sein. FAQ online lesen', + 'save-rrd-image' => 'Speichern des Graphen gescheitert. php fopen("%s") failed. FAQ online lesen', + 'xml-structure-without-version-tag' => 'Versionshinweis fehlt im XML-File. FAQ online lesen', + 'template-without-opt' => 'Template %s übergibt Array $opt[] nicht. FAQ online lesen', + 'template-without-def' => 'Template %s übergibt Array $def[] nicht. FAQ online lesen', + 'no-data-for-page' => 'Keine Daten für die Page "%s", FAQ online lesen', + 'page-not-readable' => 'Konfigurationsdatei "%s" ist nicht lesbar oder existiert nicht. FAQ online lesen', + 'auth-pages' => 'Sie sind nicht berechtigt, "Pages" anzusehen FAQ online lesen', + 'page-config-dir' => 'Keine page-Konfigurationsdatei in "%s" gefunden FAQ online lesen', + 'xport-host-service' => 'Xport-Controller benötigt "host"- und "srv"-URL-Parameter. FAQ online lesen', + 'mod-rewrite' => 'Apache Rewrite Module ist nicht aktiviert. Read FAQ online', + 'tpl-no-services-found' => 'Es wurden keine Services gefunden "%s". Read FAQ online', + 'tpl-no-hosts-found' => 'Es wurden keine Hosts gefunden "%s". Read FAQ online', + 'no-templates-found' => 'Es wurde kein passendes Template gefunden. Read FAQ online', + 'not_authorized' => 'You are not authorized to view this host/service', + 'remote_user_missing' => 'Remote user is missing. Authentication check cancled. Read FAQ online', + 'livestatus_socket_error' => 'Livestatus Socket error: %s (%s) Read FAQ online', + 'not_authorized_for_host_overview' => 'You are not authorized to access this host overview page.', + 'xml-generic_error' => 'XML file "%s" not parsable.

    XML Errors:%s

    ', + 'gd-missing' => 'PHP GD functions are missing. More on www.php.net', +); diff --git a/share/pnp/application/i18n/en_US/common.php b/share/pnp/application/i18n/en_US/common.php new file mode 100644 index 0000000..6c67c09 --- /dev/null +++ b/share/pnp/application/i18n/en_US/common.php @@ -0,0 +1,59 @@ + 'Datasource: %s', + 'host' => 'Host: %s', + 'service' => 'Service: %s', + 'page' => 'Page: %s', + 'page-basket' => 'Page: Basket', + 'zoom-header' => 'Zoom', + 'status-box-header' => 'Status', + 'multisite-box-header' => 'Multisite links', + 'search-box-header' => 'Search', + 'icon-box-header' => 'Actions', + 'basket-box-header' => 'My basket', + 'timerange-box-header' => 'Time ranges', + 'service-box-header' => 'Services', + 'special-templates-box-header' => 'Special Templates', + 'pages-box-header' => 'Pages', + 'nagios-summary-link-title' => 'Most recent alerts for this time range', + 'nagios-avail-link-title' => 'Nagios availability report for this time range', + 'timerange-selector-legend' => 'Select a custom time range', + 'timerange-selector-title' => 'Select a custom time range', + 'timerange-selector-submit-button' => 'Submit', + 'timerange-selector-clear-button' => 'Clear', + 'timerange-selector-link' => 'Custom time range', + 'timerange-selector-overview' => 'Overview', + 'start' => 'Start', + 'end' => 'End', + 'service-details' => 'Service details', + 'service-overview' => 'Service overview for "%s"', + 'title-pages-link' => 'View Pages', + 'title-pdf-link' => 'View PDF', + 'title-xml-link' => 'View XML', + 'title-statistics-link' => 'View internal statistics', + 'title-calendar-link' => 'Define a custom time range', + 'title-special-templates-link' => 'View Special Templates', + 'title-docs-link' => 'View Documentation', + 'title-home-link' => 'View Graphs', + 'title-color-link' => 'View Color Schemes', + 'docs-home' => 'Home', + 'docs-box-header' => 'Menu', + 'docs-header' => 'Documentation Version %s', + 'back' => 'back', + 'mobile-all-hosts' => 'All Hosts', + 'mobile-search-hosts' => 'Search Hosts', + 'mobile-pages' => 'View Pages', + 'mobile-special-templates' => 'View Special Templates', + 'mobile-statistics' => 'View internal statistics', + 'mobile-go-classic' => 'Classic UI', + 'mobile-submit' => 'Submit', + 'basket-empty' => 'Basket is empty', + 'basket-show' => 'Show basket', + 'basket-clear' => 'Clear basket', + 'basket-remove' => 'Remove %s', + 'basket-add-item' => 'Add this item to my basket', + 'basket-add-service' => 'Add this service to my basket', + 'color-box-header' => 'Colors', + 'color-header' => 'Colors Schemes', +); diff --git a/share/pnp/application/i18n/en_US/error.php b/share/pnp/application/i18n/en_US/error.php new file mode 100644 index 0000000..8d5d395 --- /dev/null +++ b/share/pnp/application/i18n/en_US/error.php @@ -0,0 +1,32 @@ + 'RRDTool not found in %s. Read FAQ online', + 'config-not-found' => 'Config file %s not found. Read FAQ online', + 'perfdata-dir-empty' => 'perfdata directory "%s" is empty. Please check your Nagios config. Read FAQ online', + 'host-perfdata-dir-empty' => 'perfdata directory "%s" is empty. Please check your Nagios config. Read FAQ online', + 'perfdata-dir-for-host' => 'perfdata directory "%s" for host "%s" does not exist. Read FAQ online', + 'xml-not-found' => 'XML file "%s" not found. Read FAQ online', + 'get-first-service' => 'Can´t find first service for host "%s". Read FAQ online', + 'get-first-host' => 'Can´t find any Host. Read FAQ online', + 'xml-structure-mismatch' => 'XML structure mismatch. Found version "%d" but should be "%d". Read FAQ online', + 'save-rrd-image' => 'php fopen("%s") failed. Read FAQ online', + 'xml-structure-without-version-tag' => 'XML structure mismatch. Version tag not found in "%s". Read FAQ online', + 'template-without-opt' => 'Template %s does not provide array $opt[]. Read FAQ online', + 'template-without-def' => 'Template %s does not provide array $def[]. Read FAQ online', + 'no-data-for-page' => 'Sorry, but we can´t find any data using config file "%s", Read FAQ online', + 'page-not-readable' => 'Config file "%s" is not readable or does not exist. Read FAQ online', + 'auth-pages' => 'You are not authorized to view "pages" Read FAQ online', + 'page-config-dir' => 'No page config file found in "%s" Read FAQ online', + 'xport-host-service' => 'Xport controller needs "host" and "srv" URL parameters. Read FAQ online', + 'mod-rewrite' => 'Apache Rewrite Module is not enabled. Read FAQ online', + 'tpl-no-services-found' => 'No services could be found "%s". Read FAQ online', + 'tpl-no-hosts-found' => 'No hosts could be found "%s". Read FAQ online', + 'no-templates-found' => 'No templates could be found. Read FAQ online', + 'not_authorized' => 'You are not authorized to view this host/service', + 'remote_user_missing' => 'Remote user is missing. Authentication check cancled. Read FAQ online', + 'livestatus_socket_error' => 'Livestatus Socket error: %s (%s) Read FAQ online', + 'not_authorized_for_host_overview' => 'You are not authorized to access this host overview page.', + 'xml-generic_error' => 'XML file "%s" not parsable.

    XML Errors:%s

    ', + 'gd-missing' => 'PHP GD functions are missing. More on www.php.net', +); diff --git a/share/pnp/application/i18n/es_ES/common.php b/share/pnp/application/i18n/es_ES/common.php new file mode 100644 index 0000000..0c9cc0b --- /dev/null +++ b/share/pnp/application/i18n/es_ES/common.php @@ -0,0 +1,58 @@ + 'Fuente de Datos: %s', + 'host' => 'Equipo: %s', + 'service' => 'Servicio: %s', + 'page' => 'Page: %s', + 'page-basket' => 'Página: Cesta', + 'zoom-header' => 'Zoom', + 'status-box-header' => 'Estado', + 'multisite-box-header' => 'Multisite links', + 'search-box-header' => 'Buscar', + 'icon-box-header' => 'Acciones', + 'basket-box-header' => 'Mi Cesta', + 'timerange-box-header' => 'Intervalos de Tiempo', + 'service-box-header' => 'Servicios', + 'pages-box-header' => 'Páginas', + 'nagios-summary-link-title' => 'Alertas Recientes en el Intervalo de Tiempo', + 'nagios-avail-link-title' => 'Informe de Disponibilidad en el Intervalo de Tiempo', + 'timerange-selector-legend' => 'Seleccione un intervalo de tiempo personalizado', + 'timerange-selector-title' => 'Seleccione un intervalo de tiempo personalizado', + 'timerange-selector-submit-button' => 'enviar', + 'timerange-selector-clear-button' => 'limpiar', + 'timerange-selector-link' => 'Intervalo de tiempo personalizado', + 'timerange-selector-overview' => 'Overview', + 'start' => 'Comienzo', + 'end' => 'Fin', + 'service-details' => 'Detalles de Servicio', + 'service-overview' => 'Vista General de Servicio para "%s"', + 'title-pages-link' => 'Ver páginas', + 'title-pdf-link' => 'Ver PDF', + 'title-xml-link' => 'Ver XML', + 'title-statistics-link' => 'Ver estadísticas internas de PNP', + 'title-calendar-link' => 'Definir un intervalo de tiempo personalizado', + 'title-special-templates-link' => 'View Special Templates', + 'title-docs-link' => 'View Documentation', + 'title-home-link' => 'View Graphs', + 'title-color-link' => 'View Color Schemes', + 'docs-home' => 'Home', + 'docs-box-header' => 'Menu', + 'docs-header' => 'Documentation Version %s', + 'back' => 'back', + 'mobile-all-hosts' => 'All Hosts', + 'mobile-search-hosts' => 'Search Hosts', + 'mobile-pages' => 'View Pages', + 'mobile-special-templates' => 'View Special Templates', + 'mobile-statistics' => 'View internal statistics', + 'mobile-go-classic' => 'Classic UI', + 'mobile-submit' => 'Submit', + 'basket-empty' => 'Basket is empty', + 'basket-show' => 'Show basket', + 'basket-clear' => 'Clear basket', + 'basket-remove' => 'Remove %s', + 'basket-add-item' => 'Add this item to my basket', + 'basket-add-service' => 'Add this service to my basket', + 'color-box-header' => 'Colors', + 'color-header' => 'Colors Schemes', +); diff --git a/share/pnp/application/i18n/es_ES/error.php b/share/pnp/application/i18n/es_ES/error.php new file mode 100644 index 0000000..5a638b1 --- /dev/null +++ b/share/pnp/application/i18n/es_ES/error.php @@ -0,0 +1,32 @@ + 'RRDTool no se encuentra en %s. Leer FAQ en línea', + 'config-not-found' => 'El fichero de configuración %s no se ha encontrado. Leer FAQ en línea', + 'perfdata-dir-empty' => 'El directorio de Perfdata "%s" está vacío. Compruebe la configuración de Nagios. Leer FAQ en línea', + 'host-perfdata-dir-empty' => 'El directorio de Perfdata "%s" está vacío. Compruebe la configuración de Nagios. Leer FAQ en línea', + 'perfdata-dir-for-host' => 'El directorio Perfdata "%s" para el Equipo "%s" no existe. Leer FAQ en línea', + 'xml-not-found' => 'Fichero XML "%s" no encontrado. Leer FAQ en línea', + 'get-first-service' => 'No puedo encontrar el primer servicio para el equipo "%s". Leer FAQ en línea', + 'get-first-host' => 'No puedo encuentrar ningún Equipo. Leer FAQ en línea', + 'xml-structure-mismatch' => 'Error en la Estructura XML. Versión Encontrada "%d" pero debería ser "%d". Read FAQ online', + 'save-rrd-image' => 'fallo en php fopen("%s"). Leer FAQ en línea', + 'xml-structure-without-version-tag' => 'Error en la estructura XML. Etiqueta de Versión no encontrada. Leer FAQ en línea', + 'template-without-opt' => 'La plantilla %s no tiene el array $opt[]. Leer FAQ en línea', + 'template-without-def' => 'La plantilla %s no tiene el array $def[]. Leer FAQ en línea', + 'no-data-for-page' => 'Lo siento, no puedo encontrar ningún dato usando el fichero de configuración "%s", Leer FAQ en línea', + 'page-not-readable' => 'El fichero de configuración "%s" no es legible o no existe. Leer FAQ en línea', + 'auth-pages' => 'No está autorizado a ver "páginas" Leer FAQ en línea', + 'page-config-dir' => 'No hay fichero de configuración de página en "%s" Leer FAQ en línea', + 'xport-host-service' => 'El controlador Xport necesita los parámetros de URL "host" y "srv". Leer FAQ en línea', + 'mod-rewrite' => 'El módulo Apache Rewrite no está habilitado. Leer FAQ en línea', + 'tpl-no-services-found' => 'No services could be found "%s". Read FAQ online', + 'tpl-no-hosts-found' => 'No hosts could be found "%s". Read FAQ online', + 'no-templates-found' => 'No templates could be found. Read FAQ online', + 'not_authorized' => 'You are not authorized to view this host/service', + 'remote_user_missing' => 'Remote user is missing. Authentication check cancled. Read FAQ online', + 'livestatus_socket_error' => 'Livestatus Socket error: %s (%s) Read FAQ online', + 'not_authorized_for_host_overview' => 'You are not authorized to access this host overview page.', + 'xml-generic_error' => 'XML file "%s" not parsable.

    XML Errors:%s

    ', + 'gd-missing' => 'PHP GD functions are missing. More on www.php.net', +); diff --git a/share/pnp/application/i18n/fr_FR/common.php b/share/pnp/application/i18n/fr_FR/common.php new file mode 100644 index 0000000..3d9b933 --- /dev/null +++ b/share/pnp/application/i18n/fr_FR/common.php @@ -0,0 +1,59 @@ + 'Source de données : %s', + 'host' => 'Machine : %s', + 'service' => 'Service : %s', + 'page' => 'Page : %s', + 'page-basket' => 'Page : Panier', + 'zoom-header' => 'Zoom', + 'status-box-header' => 'État', + 'multisite-box-header' => 'Liens multisite', + 'search-box-header' => 'Recherche', + 'icon-box-header' => 'Actions', + 'basket-box-header' => 'Mon panier', + 'timerange-box-header' => 'Plage de temps', + 'service-box-header' => 'Services', + 'special-templates-box-header' => 'Patrons spécifiques', + 'pages-box-header' => 'Pages', + 'nagios-summary-link-title' => 'Alarmes les plus récentes dans cette plage de temps', + 'nagios-avail-link-title' => 'Disponibilité de Nagios pendant cette plage de temps', + 'timerange-selector-legend' => 'Selectionner une plage de temps', + 'timerange-selector-title' => 'Selectionner une plage de temps', + 'timerange-selector-submit-button' => 'démarrer', + 'timerange-selector-clear-button' => 'effacer', + 'timerange-selector-link' => 'Plage de temps personnalisée', + 'timerange-selector-overview' => 'Overview', + 'start' => 'Début', + 'end' => 'Fin', + 'service-details' => 'Détails du service', + 'service-overview' => 'Aperçu du service sur "%s"', + 'title-pages-link' => 'Voir la page', + 'title-pdf-link' => 'Extraction PDF', + 'title-xml-link' => 'Extraction XML', + 'title-statistics-link' => 'Voir statistiques internes sur PNP', + 'title-calendar-link' => 'Définir une plage de temps', + 'title-special-templates-link' => 'Voir les patrons', + 'title-docs-link' => 'Accèder à la documentation', + 'title-home-link' => 'Accèder aux graphiques', + 'title-color-link' => 'View Color Schemes', + 'docs-home' => 'Accueil', + 'docs-box-header' => 'Menu', + 'docs-header' => 'Version de la documentation %s', + 'back' => 'back', + 'mobile-all-hosts' => 'All Hosts', + 'mobile-search-hosts' => 'Search Hosts', + 'mobile-pages' => 'View Pages', + 'mobile-special-templates' => 'View Special Templates', + 'mobile-statistics' => 'View internal statistics', + 'mobile-go-classic' => 'Classic UI', + 'mobile-submit' => 'Submit', + 'basket-empty' => 'Basket is empty', + 'basket-show' => 'Show basket', + 'basket-clear' => 'Clear basket', + 'basket-remove' => 'Remove %s', + 'basket-add-item' => 'Add this item to my basket', + 'basket-add-service' => 'Add this service to my basket', + 'color-box-header' => 'Colors', + 'color-header' => 'Colors Schemes', +); diff --git a/share/pnp/application/i18n/fr_FR/error.php b/share/pnp/application/i18n/fr_FR/error.php new file mode 100644 index 0000000..2ea5229 --- /dev/null +++ b/share/pnp/application/i18n/fr_FR/error.php @@ -0,0 +1,32 @@ + 'RRDTool non trouvé dans %s. Lire la FAQ', + 'config-not-found' => 'Fichier de config %s non trouvé. Lire la FAQ', + 'perfdata-dir-empty' => 'Répertoire perfdata "%s" vide. Merci de vérifier la configuration de Nagios. Lire la FAQ', + 'host-perfdata-dir-empty' => 'Répertoire perfdata "%s" vide. Merci de vérifier la configuration de Nagios. Lire la FAQ', + 'perfdata-dir-for-host' => 'Répertoire perfdata "%s" du serveur "%s" n\'existe pas. Lire la FAQ', + 'xml-not-found' => 'Fichier XML "%s" non trouvé. Lire la FAQ', + 'get-first-service' => 'Impossible de trouver le premier service du serveur "%s". Lire la FAQ', + 'get-first-host' => 'Impossible de trouver un serveur. Lire la FAQ', + 'xml-structure-mismatch' => 'Structure XML incorrecte. Version trouvé "%d" mais version attendu "%d". Lire la FAQ', + 'save-rrd-image' => 'Échec de la fonction php fopen("%s"). Lire la FAQ', + 'xml-structure-without-version-tag' => 'Structure XML incorrect. Balise de version introuvable dans "%s". Lire la FAQ', + 'template-without-opt' => 'Le template %s ne renvoie pas de tableau $opt[]. Lire la FAQ', + 'template-without-def' => 'Le template %s ne renvoie pas de tableau $def[]. Lire la FAQ', + 'no-data-for-page' => 'Désolé, mais impossible de trouver des données en utilisant le fichier de configuration "%s", Lire la FAQ', + 'page-not-readable' => 'Impossible de lire le fichier de configuration "%s" ou fichier introuvable. Lire la FAQ', + 'auth-pages' => 'Vous n\'êtes pas autorisé de voir "pages" Lire la FAQ', + 'page-config-dir' => 'Pas de fichier de configuration pour page dans "%s" Lire la FAQ', + 'xport-host-service' => 'Le contrôleur Xport nécessite les paramètres "host" et "srv" en paramètres d\'URL. Lire la FAQ', + 'mod-rewrite' => 'Module Apache Rewrite désactivé. Lire la FAQ', + 'tpl-no-services-found' => 'Impossible de trouver des services "%s". Read FAQ online', + 'tpl-no-hosts-found' => 'Impossible de trouver des serveurs "%s". Read FAQ online', + 'no-templates-found' => 'Impossible de trouver des modèles. Read FAQ online', + 'not_authorized' => 'You are not authorized to view this host/service', + 'remote_user_missing' => 'Remote user is missing. Authentication check cancled. Read FAQ online', + 'livestatus_socket_error' => 'Livestatus Socket error: %s (%s) Read FAQ online', + 'not_authorized_for_host_overview' => 'You are not authorized to access this host overview page.', + 'xml-generic_error' => 'XML file "%s" not parsable.

    XML Errors:%s

    ', + 'gd-missing' => 'PHP GD functions are missing. More on www.php.net', +); diff --git a/share/pnp/application/i18n/ru_RU/common.php b/share/pnp/application/i18n/ru_RU/common.php new file mode 100644 index 0000000..b49834c --- /dev/null +++ b/share/pnp/application/i18n/ru_RU/common.php @@ -0,0 +1,59 @@ + 'Источник данных: %s', + 'host' => 'Хост: %s', + 'service' => 'Служба: %s', + 'page' => 'Страница: %s', + 'page-basket' => 'Страница: Мой набор', + 'zoom-header' => 'Детализация', + 'status-box-header' => 'Статус', + 'multisite-box-header' => 'Multisite links', + 'search-box-header' => 'Поиск', + 'icon-box-header' => 'Действия', + 'basket-box-header' => 'Мой набор', + 'timerange-box-header' => 'Интервалы времени', + 'service-box-header' => 'Службы', + 'special-templates-box-header' => 'Специальные шаблоны', + 'pages-box-header' => 'Страницы', + 'nagios-summary-link-title' => 'Последние алерты за данный промежуток', + 'nagios-avail-link-title' => 'Сводка доступности за данный промежуток', + 'timerange-selector-legend' => 'Выберите промежуток', + 'timerange-selector-title' => 'Установка собственного интервала времени', + 'timerange-selector-submit-button' => 'ввести', + 'timerange-selector-clear-button' => 'очистить', + 'timerange-selector-link' => 'Собственный интервал', + 'timerange-selector-overview' => 'Overview', + 'start' => 'Начало', + 'end' => 'Окончание', + 'service-details' => 'Подробности о службе', + 'service-overview' => 'Обзор служб для "%s"', + 'title-pages-link' => 'Обзор страниц', + 'title-pdf-link' => 'Просмотр PDF', + 'title-xml-link' => 'Просмотр XML', + 'title-statistics-link' => 'Просмотр внутренней статистики PNP', + 'title-calendar-link' => 'Установка собственного временного интервала', + 'title-special-templates-link' => 'Просмотр специальных шаблонов', + 'title-docs-link' => 'Просмотреть документацию', + 'title-home-link' => 'Просмотр графиков', + 'title-color-link' => 'View Color Schemes', + 'docs-home' => 'На главную', + 'docs-box-header' => 'Меню', + 'docs-header' => 'Версия документации %s', + 'back' => 'назад', + 'mobile-all-hosts' => 'Все хосты', + 'mobile-search-hosts' => 'Поиск хостов', + 'mobile-pages' => 'Просмотр страниц', + 'mobile-special-templates' => 'Просмотр специальных шаблонов', + 'mobile-statistics' => 'Просмотр внутренней статистики', + 'mobile-go-classic' => 'Классический UI', + 'mobile-submit' => 'Ввести', + 'basket-empty' => 'Корзина пуста', + 'basket-show' => 'Показать корзину', + 'basket-clear' => 'Clear basket', + 'basket-remove' => 'Убрать %s', + 'basket-add-item' => 'Добавить этот элемент в мою корзину', + 'basket-add-service' => 'Добавить эту службу в мою корзину', + 'color-box-header' => 'Colors', + 'color-header' => 'Colors Schemes', +); diff --git a/share/pnp/application/i18n/ru_RU/error.php b/share/pnp/application/i18n/ru_RU/error.php new file mode 100644 index 0000000..989c8d6 --- /dev/null +++ b/share/pnp/application/i18n/ru_RU/error.php @@ -0,0 +1,32 @@ + 'RRDTool не обнаружено в %s. Read FAQ online', + 'config-not-found' => 'Файл конфигурации %s не найден. Read FAQ online', + 'perfdata-dir-empty' => 'Директория с данными производительности "%s" пуста. Пожалуйста, проверьте конфигурацию Nagios. Read FAQ online', + 'host-perfdata-dir-empty' => 'Директория с данными производительности "%s" пуста. Пожалуйста, проверьте конфигурацию Nagios. Read FAQ online', + 'perfdata-dir-for-host' => 'Директория с данными производительности "%s" для хоста "%s" не существует. Read FAQ online', + 'xml-not-found' => 'XML файл "%s" не найден. Read FAQ online', + 'get-first-service' => 'Невозможно определить первую службу для хоста "%s". Read FAQ online', + 'get-first-host' => 'Ни по одному хосту данных не обнаружено. Read FAQ online', + 'xml-structure-mismatch' => 'Несоответствие структуры данных XML. Обнаружена версия "%d", ожидаемая версия - "%d". Read FAQ online', + 'save-rrd-image' => 'Функция php fopen("%s") завершилась неудачей. Read FAQ online', + 'xml-structure-without-version-tag' => 'Несоответствие структуры данных XML. Тэг версии не найден в "%s". Read FAQ online', + 'template-without-opt' => 'Шаблон %s не предоставляет массив $opt[]. Read FAQ online', + 'template-without-def' => 'Шаблон %s не предоставляет массив $def[]. Read FAQ online', + 'no-data-for-page' => 'Извините, не удалось обнаружить никаких данных используя конфигурационный файл "%s", Read FAQ online', + 'page-not-readable' => 'Конфигурационный файл "%s" не может быть прочитан или не существует. Read FAQ online', + 'auth-pages' => 'Вы не авторизованы для просмотра "страниц" Read FAQ online', + 'page-config-dir' => 'Файл конфигурации "страниц" не найден в "%s" Read FAQ online', + 'xport-host-service' => 'Контроллер Xport требует параметры "host" и "srv" в URL. Read FAQ online', + 'mod-rewrite' => 'Модуль Rewrite для Apache не включен. Read FAQ online', + 'tpl-no-services-found' => 'Службы "%s" не найдены. Read FAQ online', + 'tpl-no-hosts-found' => 'Хосты "%s" не найдены. Read FAQ online', + 'no-templates-found' => 'Шаблоны "%s" не найдены. Read FAQ online', + 'not_authorized' => 'Вы не авторизованы для просмотра данного хоста/службы', + 'remote_user_missing' => 'Удалённый пользователь не указан. Проверка аутентификации отменена. Read FAQ online', + 'livestatus_socket_error' => 'Ошибка Livestatus сокета: %s (%s) Read FAQ online', + 'not_authorized_for_host_overview' => 'Вы не авторизованы для доступа к странице обзора хоста.', + 'xml-generic_error' => 'Не удаётся распарсить XML файл "%s".

    Ошибки XML:%s

    ', + 'gd-missing' => 'PHP GD functions are missing. More on www.php.net', +); diff --git a/share/pnp/application/lib/json.php b/share/pnp/application/lib/json.php new file mode 100644 index 0000000..0cddbdd --- /dev/null +++ b/share/pnp/application/lib/json.php @@ -0,0 +1,806 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + */ + function Services_JSON($use = 0) + { + $this->use = $use; + } + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if(function_exists('mb_convert_encoding')) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch(strlen($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = strlen($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, 'encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = substr($str, 0, 1); + $chrs = substr($str, 1, -1); + $utf8 = ''; + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = substr($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) + . chr(hexdec(substr($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= substr($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = substr($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = strlen($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = substr($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = substr($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode($parts[2]); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} + +?> diff --git a/share/pnp/application/lib/jsonwrapper.php b/share/pnp/application/lib/jsonwrapper.php new file mode 100644 index 0000000..29509de --- /dev/null +++ b/share/pnp/application/lib/jsonwrapper.php @@ -0,0 +1,6 @@ + diff --git a/share/pnp/application/lib/jsonwrapper_inner.php b/share/pnp/application/lib/jsonwrapper_inner.php new file mode 100644 index 0000000..e7a0e3f --- /dev/null +++ b/share/pnp/application/lib/jsonwrapper_inner.php @@ -0,0 +1,23 @@ +encode($arg); +} + +function json_decode($arg) +{ + global $services_json; + if (!isset($services_json)) { + $services_json = new Services_JSON(); + } + return $services_json->decode($arg); +} + +?> diff --git a/share/pnp/application/models/auth.php b/share/pnp/application/models/auth.php new file mode 100644 index 0000000..77f28d2 --- /dev/null +++ b/share/pnp/application/models/auth.php @@ -0,0 +1,154 @@ +config = new Config_Model; + $this->config->read_config(); + if($this->config->conf['auth_enabled'] == 1){ + $this->AUTH_ENABLED = TRUE; + $this->socketPath = $this->config->conf['livestatus_socket']; + } + + // Try to get the login of the user + if(isset($_SERVER['REMOTE_USER'])){ + $this->REMOTE_USER = $_SERVER['REMOTE_USER']; + } + if($this->REMOTE_USER === NULL && $this->config->conf['auth_multisite_enabled'] == 1) { + $MSAUTH = new Auth_Multisite_Model($this->config->conf['auth_multisite_htpasswd'], + $this->config->conf['auth_multisite_serials'], + $this->config->conf['auth_multisite_secret'], + $this->config->conf['auth_multisite_login_url']); + $this->REMOTE_USER = $MSAUTH->check(); + if($this->REMOTE_USER !== null) + return; + } + + if($this->AUTH_ENABLED === TRUE && $this->REMOTE_USER === NULL){ + throw new Kohana_exception("error.remote_user_missing"); + } + } + + public function __destruct() { + if($this->SOCKET !== NULL) { + socket_close($this->SOCKET); + $this->SOCKET = NULL; + } + } + + public function connect(){ + $this->getSocketDetails($this->socketPath); + $this->SOCKET = socket_create($this->socketDOMAIN, $this->socketTYPE, $this->socketPROTO); + if($this->SOCKET === FALSE) { + throw new Kohana_exception("error.livestatus_socket_error", socket_strerror(socket_last_error($this->SOCKET)), $this->socketPath); + } + if($this->socketDOMAIN === AF_UNIX){ + $result = @socket_connect($this->SOCKET, $this->socketPATH); + }else{ + $result = @socket_connect($this->SOCKET, $this->socketHOST, $this->socketPORT); + } + if(!$result) { + throw new Kohana_exception("error.livestatus_socket_error", socket_strerror(socket_last_error($this->SOCKET)), $this->socketPath); + } + + } + + private function queryLivestatus($query) { + if($this->SOCKET === NULL) { + $this->connect(); + } + @socket_write($this->SOCKET, $query."\nOutputFormat: json\n\n"); + // Read 16 bytes to get the status code and body size + $read = @socket_read($this->SOCKET,2048); + if(!$read) { + throw new Kohana_exception("error.livestatus_socket_error", socket_strerror(socket_last_error($this->SOCKET))); + } + # print Kohana::debug("read ". $read); + // Catch problem while reading + if($read === false) { + throw new Kohana_exception("error.livestatus_socket_error", socket_strerror(socket_last_error($this->SOCKET))); + } + + // Decode the json response + $obj = json_decode(utf8_encode($read)); + socket_close($this->SOCKET); + $this->SOCKET = NULL; + return $obj; + + } + + public function is_authorized($host = FALSE, $service = NULL){ + if($this->AUTH_ENABLED === FALSE){ + return TRUE; + } + + if($host == "pnp-internal"){ + return TRUE; + } + + if($service === NULL || $service == "_HOST_" || $service == "Host Perfdata"){ + $users = explode(",", $this->config->conf['allowed_for_all_hosts']); + if (in_array($this->REMOTE_USER, $users)) { + return TRUE; + } + $query = "GET hosts\nColumns: name\nFilter: name = $host\nAuthUser: ".$this->REMOTE_USER; + $result = $this->queryLivestatus($query); + }else{ + $users = explode(",", $this->config->conf['allowed_for_all_services']); + if (in_array($this->REMOTE_USER, $users)) { + return TRUE; + } + $query = "GET services\nColumns: host_name description\nFilter: host_name = $host\nFilter: description = $service\nAuthUser: ".$this->REMOTE_USER; + $result = $this->queryLivestatus($query); + } + + if(sizeof($result) > 0){ + return TRUE; + }else{ + return FALSE; + } + } + + + public function getSocketDetails($string=FALSE){ + + if(preg_match('/^unix:(.*)$/',$string,$match) ){ + $this->socketDOMAIN = AF_UNIX; + $this->socketTYPE = SOCK_STREAM; + $this->socketPATH = $match[1]; + $this->socketPROTO = 0; + return; + } + if(preg_match('/^tcp:([a-zA-Z0-9-\.]+):([0-9]+)$/',$string,$match) ){ + $this->socketDOMAIN = AF_INET; + $this->socketTYPE = SOCK_STREAM; + $this->socketHOST = $match[1]; + $this->socketPORT = $match[2]; + $this->socketPROTO = SOL_TCP; + return; + } + # Fallback + if(preg_match('/^\/.*$/',$string,$match) ){ + $this->socketDOMAIN = AF_UNIX; + $this->socketTYPE = SOCK_STREAM; + $this->socketPATH = $string; + $this->socketPROTO = 0; + return; + } + return FALSE; + } +} diff --git a/share/pnp/application/models/auth_multisite.php b/share/pnp/application/models/auth_multisite.php new file mode 100644 index 0000000..d4a3b41 --- /dev/null +++ b/share/pnp/application/models/auth_multisite.php @@ -0,0 +1,111 @@ +htpasswdPath = $htpasswdPath; + $this->serialsPath = $serialsPath; + $this->secretPath = $secretPath; + $this->loginUrl = $loginUrl; + + // When the auth.serial file exists, use this instead of the htpasswd + // for validating the cookie. The structure of the file is equal, so + // the same code can be used. + if(file_exists($this->serialsPath)) { + $this->authFile = 'serial'; + + } elseif(file_exists($this->htpasswdPath)) { + $this->authFile = 'htpasswd'; + + } else { + throw new Kohana_exception("error.auth_multisite_missing_htpasswd"); + } + + if(!file_exists($this->secretPath)) { + $this->redirectToLogin(); + } + } + + private function loadAuthFile($path) { + $creds = array(); + foreach(file($path) AS $line) { + if(strpos($line, ':') !== false) { + list($username, $secret) = explode(':', $line, 2); + $creds[$username] = rtrim($secret); + } + } + return $creds; + } + + private function loadSecret() { + return trim(file_get_contents($this->secretPath)); + } + + private function generateHash($username, $now, $user_secret) { + $secret = $this->loadSecret(); + return md5($username . $now . $user_secret . $secret); + } + + private function checkAuthCookie($cookieName) { + if(!isset($_COOKIE[$cookieName]) || $_COOKIE[$cookieName] == '') { + throw new Exception(); + } + + list($username, $issueTime, $cookieHash) = explode(':', $_COOKIE[$cookieName], 3); + + if($this->authFile == 'htpasswd') + $users = $this->loadAuthFile($this->htpasswdPath); + else + $users = $this->loadAuthFile($this->serialsPath); + + if(!isset($users[$username])) { + throw new Exception(); + } + $user_secret = $users[$username]; + + // Validate the hash + if($cookieHash != $this->generateHash($username, $issueTime, $user_secret)) { + throw new Exception(); + } + + // FIXME: Maybe renew the cookie here too + + return $username; + } + + private function checkAuth() { + // Loop all cookies trying to fetch a valid authentication + // cookie for this installation + foreach(array_keys($_COOKIE) AS $cookieName) { + if(substr($cookieName, 0, 5) != 'auth_') { + continue; + } + try { + $name = $this->checkAuthCookie($cookieName); + return $name; + } catch(Exception $e) {} + } + return ''; + } + + private function redirectToLogin() { + header('Location:' . $this->loginUrl . '?_origtarget=' . $_SERVER['REQUEST_URI']); + } + + public function check() { + $username = $this->checkAuth(); + if($username === '') { + $this->redirectToLogin(); + exit(0); + } + + return $username; + } +} + +?> diff --git a/share/pnp/application/models/config.php b/share/pnp/application/models/config.php new file mode 100644 index 0000000..44e3d12 --- /dev/null +++ b/share/pnp/application/models/config.php @@ -0,0 +1,88 @@ +get('h') != "" ) $conf['graph_height'] = intval($input->get('h')); + if($input->get('w') != "" ) $conf['graph_width'] = intval($input->get('w')); + if($input->get('graph_height') != "" ) $conf['graph_height'] = intval($input->get('graph_height')); + if($input->get('graph_width') != "" ) $conf['graph_width'] = intval($input->get('graph_width')); + $this->conf = $conf; + $this->views = $views; + $this->scheme = $scheme; + } +} diff --git a/share/pnp/application/models/data.php b/share/pnp/application/models/data.php new file mode 100644 index 0000000..38e049e --- /dev/null +++ b/share/pnp/application/models/data.php @@ -0,0 +1,1115 @@ +config = new Config_Model(); + $this->config->read_config(); + $this->auth = new Auth_Model(); + } + + /* + * Get All Special Templates + * + */ + public function getSpecialTemplates(){ + $conf = $this->config->conf; + $templates = array(); + if (is_dir($conf['special_template_dir'])){ + if ($dh = opendir($conf['special_template_dir'])) { + while (($file = readdir($dh)) !== false) { + if ($file == "." || $file == "..") + continue; + if (!preg_match("/(.*)\.php$/", $file, $template)) + continue; + $templates[] = $template[1]; + } + } + } + if(sizeof($templates) > 0){ + sort($templates); + return $templates; + }else{ + return FALSE; + } + } + + public function getFirstSpecialTemplate(){ + $templates = $this->getSpecialTemplates(); + if($templates === FALSE){ + return FALSE; + }else{ + return $templates[0]; + } + } + /* + * + * + */ + public function getHosts() { + $hosts = array(); + $conf = $this->config->conf; + $i = 0; + if (is_dir($conf['rrdbase'])) { + if ($dh = opendir($conf['rrdbase'])) { + while (($file = readdir($dh)) !== false) { + if ($file == "." || $file == ".." || $file == ".pnp-internal") + continue; + + if (is_file($conf['rrdbase'] . "/" . $file) ) + continue; + + if($this->auth->is_authorized($file) === FALSE) + continue; + + $stat = stat($conf['rrdbase'] . "/" . $file); + $age = (time() - $stat['mtime']); + $hosts[$i]['name'] = $file; + $hosts[$i]['sort'] = strtoupper($file); + if ($age < $conf['max_age']) { + $hosts[$i]['state'] = 'active'; + } else { + $hosts[$i]['state'] = 'inactive'; + } + $i++; + } + closedir($dh); + } else { + throw new Kohana_User_Exception('Perfdata Dir', "Can not open $path"); + } + } + if(sizeof($hosts)>0){ + # Obtain a list of columns + foreach ($hosts as $key => $row) { + $sort[$key] = $row['sort']; + } + # Sort the data with volume descending, edition ascending + # Add $data as the last parameter, to sort by the common key + array_multisort($sort, SORT_ASC, $hosts); + }else{ + throw new Kohana_Exception('error.perfdata-dir-empty', $conf['rrdbase'] ); + } + return $hosts; + } + + + /* + * + * + */ + function getRawServices($hostname) { + $services = array (); + $host = array(); + $conf = $this->config->conf; + $i = 0; + $path = $conf['rrdbase'] . $hostname; + if (is_dir($path)) { + if ($dh = opendir($path)) { + while ( ($file = readdir($dh) ) !== false) { + if ($file == "." || $file == "..") + continue; + + if (!preg_match("/(.*)\.xml$/", $file, $servicedesc)) + continue; + + $fullpath = $path . "/" . $file; + $stat = stat("$fullpath"); + $age = (time() - $stat['mtime']); + + $state = "active"; + if ($age > $conf['max_age']) { # 6Stunden + $state = "inactive"; + } + $services[$i]['state'] = $state; + $services[$i]['name'] = $servicedesc[1]; + $i++; + } + } + }else{ + throw new Kohana_Exception('error.perfdata-dir-for-host', $path, $hostname ); + } + if( is_array($services) && sizeof($services) > 0){ + # Obtain a list of columns + foreach ($services as $key => $row) { + $sort[$key] = $row['name']; + } + # Sort the data with volume descending, edition ascending + # Add $data as the last parameter, to sort by the common key + array_multisort($sort, SORT_STRING, $services); + }else{ + throw new Kohana_Exception('error.host-perfdata-dir-empty', $path, $hostname ); + } + return $services; + } + /* + * + * + */ + function getServices($hostname) { + $services = array (); + $host = array(); + $i = 0; + $service_list = $this->getRawServices($hostname); + foreach( $service_list as $s ){ + if(!$this->readXML($hostname, $s['name'], FALSE)){ + continue; + } + if($s['name'] == "_HOST_"){ + // Check authorization + if($this->auth->is_authorized((string) $this->XML->NAGIOS_AUTH_HOSTNAME, "_HOST_") === FALSE) + continue; + + $host[0]['name'] = "_HOST_"; + $host[0]['hostname'] = (string) $this->XML->NAGIOS_HOSTNAME; + $host[0]['state'] = $s['state']; + $host[0]['servicedesc'] = "Host Perfdata"; + $host[0]['is_multi'] = (string) $this->XML->DATASOURCE[0]->IS_MULTI[0]; + }else{ + // Check authorization + if($this->auth->is_authorized((string) $this->XML->NAGIOS_AUTH_HOSTNAME, (string) $this->XML->NAGIOS_AUTH_SERVICEDESC) === FALSE ) + continue; + + $services[$i]['name'] = $s['name']; + // Sorting check_multi + if( (string) $this->XML->NAGIOS_MULTI_PARENT == ""){ + $services[$i]['sort'] = strtoupper($s['name']); + }else{ + $services[$i]['sort'] = strtoupper((string) $this->XML->NAGIOS_MULTI_PARENT); + $services[$i]['sort'] .= (string) $this->XML->DATASOURCE[0]->IS_MULTI[0]; + $services[$i]['sort'] .= strtoupper($s['name']); + } + $services[$i]['state'] = $s['state']; + $services[$i]['hostname'] = (string) $this->XML->NAGIOS_DISP_HOSTNAME; + $services[$i]['servicedesc'] = (string) $this->XML->NAGIOS_DISP_SERVICEDESC; + $services[$i]['is_multi'] = (string) $this->XML->DATASOURCE[0]->IS_MULTI[0]; + } + $i++; + } + #print Kohana::debug($services); + if( is_array($services) && sizeof($services) > 0){ + # Obtain a list of columns + foreach ($services as $key => $row) { + $sort[$key] = $row['sort']; + } + # Sort the data with volume descending, edition ascending + # Add $data as the last parameter, to sort by the common key + array_multisort($sort, SORT_STRING, $services); + } + if(is_array($host) && sizeof($host) > 0 ){ + array_unshift($services, $host[0]); + } + return $services; + } + + /* + * + * + */ + public function getFirstService($hostname) { + $conf = $this->config->conf; + $services = $this->getServices($hostname); + foreach ($services as $srv) { + if ($srv['state'] == "active" ) { + break; + } + } + if(sizeof($srv) == 0){ + throw new Kohana_Exception('error.get-first-service', $hostname ); + } + return $srv['name']; + } + + /* + * + * + */ + public function getFirstHost() { + $conf = $this->config->conf; + $hosts = $this->getHosts(); + foreach ($hosts as $host) { + if ($host['state'] == "active" ) { + break; + } + } + if(sizeof($host) == 0){ + throw new Kohana_Exception('error.get-first-host'); + } + return $host['name']; + } + + /* + * + * + */ + public function readXML ($hostname, $servicedesc, $throw_exception=TRUE){ + $conf = $this->config->conf; + $xmlfile = $conf['rrdbase'].$hostname."/".$servicedesc.".xml"; + $xml = array(); + if (file_exists($xmlfile)) { + libxml_use_internal_errors(TRUE); + libxml_clear_errors(TRUE); + if(! $xml = simplexml_load_file($xmlfile) ){; + if( $throw_exception == TRUE ){ + $errors = '
    '; + foreach(libxml_get_errors() as $error) { + $errors .= $error->message."
    "; + } + throw new Kohana_Exception('error.xml-generic_error',$xmlfile, $errors); + }else{ + return FALSE; + } + } + $this->XML = array(); + $this->MACRO = array(); + $this->MACRO['AUTH_SERVICEDESC'] = ''; + $this->MACRO['AUTH_HOSTNAME'] = ''; + $this->DS = array(); + // Throw excaption without a valid structure version + if(!isset($xml->XML->VERSION) && $throw_exception == TRUE){ + throw new Kohana_Exception('error.xml-structure-without-version-tag',$xmlfile); + } + if(!isset($xml->XML->VERSION) && $throw_exception == FALSE){ + return FALSE; + } + foreach ( $xml as $key=>$val ){ + if(preg_match('/^NAGIOS_(.*)$/', $key, $match)){ + #print $match[1]." => ".$val."\n"; + $key = $match[1]; + $this->MACRO[$key] = (string) $val; + } + } + $i=0; + foreach ( $xml->DATASOURCE as $datasource ){ + foreach ( $datasource as $key=>$val){ + #print "$key => $val\n"; + #$$key[$i] = (string) $val; + $this->DS[$i][$key] = (string) $val; + } + $i++; + } + $this->XML = $xml; + return TRUE; + }else{ + throw new Kohana_Exception('error.xml-not-found', $xmlfile); + } + } + + /* + * + * + */ + public function buildDataStruct ($host = FALSE, $service = FALSE, $view = NULL, $source = NULL){ + if($host === FALSE && $service === FALSE){ + return FALSE; + } + $conf = $this->config->conf; + + /* + * Special templates without Host/Service + */ + if($host == '__special' ){ + // $service contains the template name + $this->includeTemplate($service,'special'); + }else{ + if( $this->readXML($host,$service) == FALSE ){ + throw new Kohana_Exception('error.xml-not-found', "Undefined error"); + return false; + } + $this->includeTemplate($this->DS[0]['TEMPLATE']); + } + if(isset($this->TIMERANGE['type']) && $this->TIMERANGE['type'] == "start-end"){ + $view = intval($view); + $i=0; + foreach( $this->RRD['def'] as $key=>$val){ + if( ! is_null($source) && $source != $key ){ + continue; + } + $tmp_struct = array(); + $tmp_struct['LEVEL'] = $i; + $tmp_struct['VIEW'] = $view; + $tmp_struct['TEMPLATE_FILE'] = $this->TEMPLATE_FILE;; + $tmp_struct['SOURCE'] = $key; + $tmp_struct['RRD_CALL'] = $this->TIMERANGE['cmd'] . " ". $this->RRD['opt'][$key] . " " . $this->RRD['def'][$key]; + $tmp_struct['TIMERANGE'] = $this->TIMERANGE; + $tmp_struct['GRAPH_WIDTH'] = $this->getGraphDimensions('width', $tmp_struct['RRD_CALL']); + $tmp_struct['GRAPH_HEIGHT'] = $this->getGraphDimensions('height', $tmp_struct['RRD_CALL']); + if(isset($this->RRD['ds_name'][$key]) ){ + $tmp_struct['ds_name'] = $this->RRD['ds_name'][$key]; + }elseif(array_key_exists($i, $this->DS)){ + $tmp_struct['ds_name'] = $this->DS[$i]['NAME']; + }else{ + $tmp_struct['ds_name'] = "UNDEF"; + } + $tmp_struct['MACRO'] = $this->MACRO; + if(isset($this->XML->XML->VERSION)){ + $tmp_struct['VERSION'] = pnp::xml_version_check( (string) $this->XML->XML->VERSION); + }else{ + $tmp_struct['VERSION'] = pnp::xml_version_check("0"); + } + $this->addToDataStruct($tmp_struct); + $i++; + } + return; + } + if( $view === ""){ + $v = 0; + foreach($this->config->views as $view_key=>$view_val){ + $i=0; + foreach( $this->RRD['def'] as $key=>$val){ + if( ! is_null($source) && $source != $key ){ + continue; + } + $tmp_struct = array(); + $tmp_struct['LEVEL'] = $i; + $tmp_struct['VIEW'] = $view_key; + $tmp_struct['TEMPLATE_FILE'] = $this->TEMPLATE_FILE;; + $tmp_struct['SOURCE'] = $key; + $tmp_struct['RRD_CALL'] = $this->TIMERANGE[$v]['cmd'] . " " . $this->RRD['opt'][$key] . " " . $this->RRD['def'][$key]; + $tmp_struct['GRAPH_WIDTH'] = $this->getGraphDimensions('width', $tmp_struct['RRD_CALL']); + $tmp_struct['GRAPH_HEIGHT'] = $this->getGraphDimensions('height', $tmp_struct['RRD_CALL']); + if(isset($this->RRD['ds_name'][$key]) ){ + $tmp_struct['ds_name'] = $this->RRD['ds_name'][$key]; + }elseif(array_key_exists($i, $this->DS)){ + $tmp_struct['ds_name'] = $this->DS[$i]['NAME']; + }else{ + $tmp_struct['ds_name'] = "UNDEF"; + } + $tmp_struct['TIMERANGE'] = $this->TIMERANGE[$v]; + $tmp_struct['MACRO'] = $this->MACRO; + if(isset($this->XML->XML->VERSION)){ + $tmp_struct['VERSION'] = pnp::xml_version_check( (string) $this->XML->XML->VERSION); + }else{ + $tmp_struct['VERSION'] = pnp::xml_version_check("0"); + } + $this->addToDataStruct($tmp_struct); + $i++; + } + $v++; + } + }else{ + $view = intval($view); + $i=0; + foreach( $this->RRD['def'] as $key=>$val){ + if( ! is_null($source) && $source != $key ){ + continue; + } + $tmp_struct = array(); + $tmp_struct['LEVEL'] = $i; + $tmp_struct['VIEW'] = $view; + $tmp_struct['TEMPLATE_FILE'] = $this->TEMPLATE_FILE;; + $tmp_struct['SOURCE'] = $key; + $tmp_struct['RRD_CALL'] = $this->TIMERANGE[$view]['cmd'] . " ". $this->RRD['opt'][$key] . " " . $this->RRD['def'][$key]; + $tmp_struct['TIMERANGE'] = $this->TIMERANGE[$view]; + $tmp_struct['GRAPH_WIDTH'] = $this->getGraphDimensions('width', $tmp_struct['RRD_CALL']); + $tmp_struct['GRAPH_HEIGHT'] = $this->getGraphDimensions('height', $tmp_struct['RRD_CALL']); + if(isset($this->RRD['ds_name'][$key]) ){ + $tmp_struct['ds_name'] = $this->RRD['ds_name'][$key]; + }elseif(array_key_exists($i, $this->DS)){ + $tmp_struct['ds_name'] = $this->DS[$i]['NAME']; + }else{ + $tmp_struct['ds_name'] = "UNDEF"; + } + $tmp_struct['MACRO'] = $this->MACRO; + if(isset($this->XML->XML->VERSION)){ + $tmp_struct['VERSION'] = pnp::xml_version_check( (string) $this->XML->XML->VERSION); + }else{ + $tmp_struct['VERSION'] = pnp::xml_version_check("0"); + } + $this->addToDataStruct($tmp_struct); + $i++; + } + } + } + + /* + * + * + */ + private function addToDataStruct ($data=FALSE) { + if($data === FALSE) + return FALSE; + + array_push($this->STRUCT, $data); + } + + /* + * + * + */ + private function includeTemplate($template=FALSE,$type='normal'){ + if($template===FALSE){ + return FALSE; + } + $this->RRD = array(); + /* + * Normal PNP Templates + */ + if($type == 'normal'){ + $template_file = $this->findTemplate( $template ); + $this->TEMPLATE_FILE = $template_file; + $hostname = $this->MACRO['HOSTNAME']; + $servicedesc = $this->MACRO['SERVICEDESC']; + $TIMERANGE = $this->TIMERANGE; + }elseif($type == 'special'){ + $template_file = $this->findTemplate( $template, $type ); + $TIMERANGE = $this->TIMERANGE; + } + $def = FALSE; + $opt = FALSE; + $ds_name = FALSE; + /* + * 0.4.x Template compatibility + */ + foreach($this->DS as $key=>$val ){ + $key++; + foreach(array_keys($val) as $tag){ + ${$tag}[$key] = $val[$tag]; + } + } + foreach($this->MACRO as $key=>$val ){ + ${"NAGIOS_".$key} = $val; + } + if(isset($RRDFILE[1])){ + $rrdfile = $RRDFILE[1]; + } + // Include template + if($template_file == FALSE){ + throw new Kohana_Exception('error.no-templates-found'); + }else{ + ob_start(); + include($template_file); + ob_end_clean(); + } + // Compatibility for very old Templates + if(!is_array($def) && $def != FALSE){ + $tmp[1] = $def; + $def = $tmp; + } + if(!is_array($opt) && $opt != FALSE){ + $tmp[1] = $opt; + $opt = $tmp; + } + if(!is_array($ds_name) && $ds_name != FALSE){ + $tmp[1] = $ds_name; + $ds_name = $tmp; + } + // + if($def != FALSE){ + $this->RRD['def'] = $this->array_reindex($def); + }else{ + throw new Kohana_Exception('error.template-without-def', $template_file); + } + if($opt != FALSE ){ + $this->RRD['opt'] = $this->array_reindex($opt); + }else{ + throw new Kohana_Exception('error.template-without-opt', $template_file); + } + if( $ds_name != FALSE ){ + $this->RRD['ds_name'] = $this->array_reindex($ds_name); + } + return TRUE; + } + + # + # + # + private function getGraphDimensions($search, $command){ + if($search == 'width'){ + if(preg_match_all('/(-w|--width|--width=)\s([0-9]+)\s/i',$command,$match)){ + $value = array_pop($match[2]); + return $value; + }else{ + return $this->config->conf['graph_width']; + } + } + if($search == 'height'){ + if(preg_match_all('/(-h|--height|--height=)\s([0-9]+)\s/i',$command,$match)){ + $value = array_pop($match[2]); + return $value; + }else{ + return $this->config->conf['graph_height']; + } + } + return FALSE; + } + # + # + # + private function array_reindex($data){ + $i=0; + foreach($data as $d){ + $tmp[$i] = $d; + $i++; + } + return $tmp; + } + + /* + * + * + */ + public function findTemplate($template,$type='normal'){ + $conf = $this->config->conf; + /* + * Normal templates + */ + if($type == 'normal'){ + // Build a list of directories to search for templates + $template_dirs = array(); + if(array_key_exists('template_dirs', $this->config->conf)){ + foreach($this->config->conf['template_dirs'] as $dir){ + $template_dirs[] = $dir; + } + } + foreach(Kohana::config('core.template_dirs') as $dir){ + $template_dirs[] = $dir; + } + #throw new Kohana_Exception(print_r($template_dirs,TRUE)); + foreach($template_dirs as $dir){ + $match = $this->findRecursiveTemplate($template,$dir); + if($match != FALSE){ + return $match; + } + } + /* + * Fallback to default templates + */ + foreach($template_dirs as $dir){ + $match = $this->findRecursiveTemplate('default',$dir); + if($match != FALSE){ + return $match; + } + } + return FALSE; + } + /* + * Special Templates + */ + if($type == 'special'){ + if (is_readable($conf['special_template_dir'] . '/' . $template . '.php')) { + $template_file = $conf['special_template_dir'].'/' . $template . '.php'; + }else{ + throw new Kohana_Exception("Special Template '$template' not found"); + } + return $template_file; + } + } + + /* + * + * + */ + function findRecursiveTemplate($template, $dir) { + if(!is_readable($dir)){ + return FALSE; + } + $template_file = ""; + $r_template_file = ""; + $r_template = ""; + $recursive = explode("_", $template); + if($this->config->conf['enable_recursive_template_search'] == 1){ + $i = 0; + foreach ($recursive as $value) { + if ($i == 0) { + $r_template = $value; + } else { + $r_template = $r_template . '_' . $value; + } + $file = $dir . '/' . $r_template . '.php'; + if (is_readable($file)) { + $r_template_file = $file; + } + $i++; + } + if($r_template_file != ""){ + return $r_template_file; + }else{ + return FALSE; + } + }else{ + $file = $dir . '/' . $template . '.php'; + if (is_readable($file)) { + return $file; + }else{ + return FALSE; + } + } + } + + public function getTimeRange($start=FALSE ,$end=FALSE ,$view="") { + if($end != FALSE){ + // we are in a custom timerange + if(!is_numeric($end)){ + $timestamp = strtotime($end); + if(!$timestamp){ + throw new Kohana_User_Exception('Wrong Format', "$end"); + }else{ + $end = $timestamp; + } + } + }else{ + $end = time(); + } + if($start != FALSE ){ + // we are in a custom timerange + if(!is_numeric($start)){ + $timestamp = strtotime($start); + if(!$timestamp){ + throw new Kohana_User_Exception('Wrong Format', "Start -> $start"); + }else{ + $start = $timestamp; + } + } + } + if($start && $end){ + $timerange['title'] = Kohana::lang('common.timerange-selector-link'); + $timerange['start'] = $start; + $timerange['f_start'] = date($this->config->conf['date_fmt'],$start); + $timerange['end'] = $end; + $timerange['f_end'] = date($this->config->conf['date_fmt'],$end); + $timerange['cmd'] = " --start $start --end $end "; + $timerange['type'] = "start-end"; + $this->TIMERANGE = $timerange; + return; + } + + $view=intval( pnp::clean($view) ); + if($view >= sizeof($this->config->views)){ + $view = 1; + } + + if(!$end){ + $end = time(); + }elseif(!is_numeric($end)){ + $timestamp = strtotime($end); + if(!$timestamp){ + throw new Kohana_User_Exception('Wrong Format', "$end"); + }else{ + $end = $timestamp; + } + }else{ + $end = $end; + } + + if(!$start){ + $start = ( $end - $this->config->views[$view]['start']); + }elseif(!is_numeric($start)){ + $timestamp = strtotime($start); + if(!$timestamp){ + throw new Kohana_User_Exception('Wrong Format', "$start"); + }else{ + $start = $timestamp; + } + }else{ + $start = pnp::clean($start); + } + + if($start >= $end){ + //Fixme i18n + throw new Kohana_User_Exception('Wrong Timerange', "start >= end"); + } + + $timerange['title'] = $this->config->views[$view]['title']; + $timerange['start'] = $start; + $timerange['f_start'] = date($this->config->conf['date_fmt'],$start); + $timerange['end'] = $end; + $timerange['f_end'] = date($this->config->conf['date_fmt'],$end); + $timerange['cmd'] = " --start $start --end $end "; + $timerange['type'] = "views"; + for ($i = 0; $i < sizeof($this->config->views); $i++) { + $timerange[$i]['title'] = $this->config->views[$i]['title']; + $timerange[$i]['start'] = $end - $this->config->views[$i]['start']; + $timerange[$i]['f_start'] = date($this->config->conf['date_fmt'],$end - $this->config->views[$i]['start']); + $timerange[$i]['end'] = $end; + $timerange[$i]['f_end'] = date($this->config->conf['date_fmt'],$end); + $timerange[$i]['cmd'] = " --start " . ($end - $this->config->views[$i]['start']) . " --end $end" ; + } + $this->TIMERANGE = $timerange; + } + + public function buildBasketStruct($basket,$view = NULL){ + if(is_array($basket) && sizeof($basket) > 0){ + if($view == ""){ + $views = array_keys($this->config->views); + }else{ + $views = array($view); + } + foreach($views as $view){ + foreach($basket as $item){ + # explode host::service::source + $slices = explode("::",$item); + if(sizeof($slices) == 2) + $this->buildDataStruct($slices[0], $slices[1], $view); + if(sizeof($slices) == 3) + $this->buildDataStruct($slices[0], $slices[1], $view, $slices[2]); + } + # break on custom time ranges + if(isset($this->TIMERANGE['type']) && $this->TIMERANGE['type'] == "start-end"){ + break; + } + } + } + } + + public function buildPageStruct($page,$view){ + $servicelist = array(); + $this->parse_page_cfg($page); + $hosts = $this->getHostsByPage(); + # No regex so we keep the order defined by config + if($this->PAGE_DEF['use_regex'] == 0){ + #Loop through graph definitions + foreach($this->PAGE_GRAPH as $graph){ + $hosts_to_search_for = explode(",", $graph['host_name']); + foreach($hosts_to_search_for as $host){ + if(in_array($host, $hosts)){ + $services = $this->getServices($host); + foreach($services as $service) { + // search for definition + $data = $this->filterServiceByPage($graph,$host,$service); + if($data){ + $servicelist[] = array( 'host' => $host, 'service' => $service['name'], 'source' => $data['source']); + + } + } + } + } + } + }else{ + foreach($hosts as $host){ + $services = $this->getServices($host); + foreach($services as $service) { + // search for definition + $data = $this->filterServiceByPage($this->PAGE_GRAPH,$host,$service); + if($data){ + $servicelist[] = array( 'host' => $host, 'service' => $service['name'], 'source' => $data['source']); + } + } + } + } + #print Kohana::debug($servicelist); + if(sizeof($servicelist) > 0 ){ + foreach($servicelist as $s){ + $this->buildDataStruct($s['host'],$s['service'],$view,$s['source']); + } + }else{ + $this->ERROR = "ERROR: ". Kohana::lang('error.no-data-for-page', $page.".cfg" ); + } + } + + + public function parse_page_cfg($page){ + $page_cfg = $this->config->conf['page_dir'].$page.".cfg"; + if(is_readable($page_cfg)){ + $data = file($page_cfg); + }else{ + throw new Kohana_Exception('error.page-not-readable', $page.".cfg" ); + } + $l = 0; + $line = ""; + $tag = ""; + $inside=0; + $this->PAGE_DEF['page_name'] = 'UNDEF'; + $this->PAGE_DEF['use_regex'] = 0; + $this->PAGE_GRAPH = array(); + $allowed_tags = array("page", "graph"); + foreach($data as $line){ + if(preg_match('/(^#|^;)/',$line)) { + continue; + } + + preg_match('/define\s+(\w+)\W+{/' ,$line, $tag); + if(isset($tag[1]) && in_array($tag[1],$allowed_tags)){ + $inside = 1; + $t = $tag[1]; + $l++; + continue; + } + if(preg_match('/\s?(\w+)\s+([^#]+)(#.*)?$/',$line, $key) && $inside == 1){ + $k=strtolower($key[1]); + $v=$key[2]; + if($t=='page'){ + $this->PAGE_DEF[$k] = trim($v); + }elseif($t=='graph'){ + $this->PAGE_GRAPH[$l][$k] = trim($v); + } + } + if(preg_match('/}/',$line)){ + $inside=0; + $t = ""; + continue; + } + } + } + + /* + * + */ + public function getHostsByPage(){ + $hosts = $this->getHosts(); + $new_hosts = array(); + foreach( $hosts as $host){ + if($host['state'] == "inactive"){ + continue; + } + if($tmp = $this->filterHostByPage($host['name'])){ + $new_hosts[] = $tmp; + } + } + return $new_hosts; + } + /* + * + */ + private function filterHostByPage($host){ + if(isset($this->PAGE_DEF['use_regex']) && $this->PAGE_DEF['use_regex'] == 1){ + // Search Host by regex + foreach( $this->PAGE_GRAPH as $g ){ + if(isset($g['host_name']) && preg_match('/'.$g['host_name'].'/',$host)){ + return $host; + } + } + }else{ + foreach( $this->PAGE_GRAPH as $g ){ + $hosts_to_search_for = explode(",", $g['host_name']); + if(isset($g['host_name']) && in_array($host ,$hosts_to_search_for) ){ + return $host; + } + } + } + return FALSE; + } + + private function filterServiceByPage($g,$host,$service){ + $data = array(); + if(isset($this->PAGE_DEF['use_regex']) && $this->PAGE_DEF['use_regex'] == 1){ + // Search Host by regex + foreach( $this->PAGE_GRAPH as $g ){ + if(isset($g['host_name']) && preg_match('/'.$g['host_name'].'/',$host)){ + if(isset($g['service_desc']) && preg_match('/'.$g['service_desc'].'/',$service['name'])){ + $data['service_desc'] = $g['service_desc']; + $data['host_name'] = $g['host_name']; + $data['source'] = NULL; + // if we only want a single image + if(isset($g['source'])){ + $this->readXML($host,$service['name']); + $this->includeTemplate($this->DS[0]['TEMPLATE']); + $source = intval($g['source']); + if(array_key_exists($source,$this->RRD['def'])){ + $data['source'] = $source; + } + } + return $data; + } + } + } + }else{ + $hosts_to_search_for = explode(",", $g['host_name']); + $services_to_search_for = explode(",", $g['service_desc']); + if(isset($g['host_name']) && in_array($host ,$hosts_to_search_for) ){ + if(isset($g['service_desc']) && in_array($service['name'] ,$services_to_search_for) ){ + $data['service_desc'] = $g['service_desc']; + $data['host_name'] = $g['host_name']; + $data['source'] = NULL; + // if we only want a single image + if(isset($g['source'])){ + $this->readXML($host,$service['name']); + $this->includeTemplate($this->DS[0]['TEMPLATE']); + $source = intval($g['source']); + if(array_key_exists($source,$this->RRD['def'])){ + $data['source'] = $source; + } + } + return $data; + } + } + } + return FALSE; + } + + /* + * + */ + public function getPages() { + $pages = array(); + if (is_dir($this->config->conf['page_dir'])) { + if ($dh = opendir($this->config->conf['page_dir'])) { + while (($file = readdir($dh)) !== false) { + if(preg_match('/(.*)\.cfg$/',basename($file),$page)){ + $pages[] = urlencode($page[1]); + } + } + closedir($dh); + } else { + die("Cannot open directory: $path"); + } + } + if(sizeof($pages)>0){ + + natsort($pages); + }else{ + return FALSE; + } + return $pages; + } + + /* + * + */ + public function getFirstPage(){ + $pages = $this->getPages(); + if(sizeof($pages) > 0 ){ + return urldecode($pages[0]); + }else{ + return FALSE; + } + } + + /* + * + */ + public function getPageDetails($page){ + $this->parse_page_cfg($page); + return $this->PAGE_DEF['page_name']; + } + + /* + * + */ + public function buildXport($host,$service){ + // FIXME add max rows to config + $this->XPORT = " -m 2000"; + $this->XPORT .= " --start=".$this->TIMERANGE['start']; + $this->XPORT .= " --end=".$this->TIMERANGE['end']; + $this->readXML($host,$service); + $count = 0; + $RRAs = array('MIN','MAX','AVERAGE'); + foreach($this->DS as $key=>$value){ + foreach($RRAs as $RRA){ + $this->XPORT .= sprintf(" DEF:%d%s=%s:%d:%s ",$count,$RRA,$value['RRDFILE'],$value['DS'],$RRA); + $this->XPORT .= sprintf(" XPORT:%d%s:%s_%s " ,$count,$RRA,$value['NAME'],$RRA); + } + $count++; + } + } + /* + * + */ + public function xml2csv($string){ + $xml = simplexml_load_string($string); + $csv = "timestamp"; + foreach($xml->meta->legend->entry as $key=>$value){ + $csv .= ";" . $value ; + } + $csv .= "\n"; + foreach($xml->data->row as $key=>$value){ + $csv .= (string) $value->t ; + foreach($value->v as $item){ + $csv .= ";".floatval((string) $item); + } + $csv .= "\n"; + } + return $csv; + } + + /* + * + * Used in Special Templates to gather data + */ + public function tplGetData ($hostname, $servicedesc, $throw_exception=TRUE){ + $conf = $this->config->conf; + $xmlfile = $conf['rrdbase'].$hostname."/".$servicedesc.".xml"; + $data = array(); + if (file_exists($xmlfile)) { + $xml = simplexml_load_file($xmlfile); + // Throw excaption without a valid structure version + if(!isset($xml->XML->VERSION) && $throw_exception == TRUE){ + throw new Kohana_Exception('error.xml-structure-without-version-tag',$xmlfile); + } + if(!isset($xml->XML->VERSION) && $throw_exception == FALSE){ + return FALSE; + } + foreach ( $xml as $key=>$val ){ + if(preg_match('/^NAGIOS_(.*)$/', $key, $match)){ + $key = $match[1]; + $data['MACRO'][$key] = (string) $val; + } + } + $i=0; + foreach ( $xml->DATASOURCE as $datasource ){ + foreach ( $datasource as $key=>$val){ + $data['DS'][$i][$key] = (string) $val; + } + $i++; + } + return $data; + }else{ + throw new Kohana_Exception('error.xml-not-found', $xmlfile); + } + } + /* + * + * Used in Special Templates to gather data + */ + public function tplGetServices ($hostregex=FALSE, $serviceregex = ''){ + if($hostregex === FALSE){ + return FALSE; + } + $hostregex = sprintf("/%s/",$hostregex); + $serviceregex = sprintf("/%s/",$serviceregex); + $hosts = $this->getHosts(); + $new_hosts = array(); + foreach( $hosts as $host){ + if(preg_match($hostregex,$host['name'])){ + $new_hosts[] = $host['name']; + } + } + + if(sizeof($new_hosts) == 0){ + throw new Kohana_Exception('error.tpl-no-hosts-found', $hostregex); + } + + $i = 0; + $new_services = array(); + foreach($new_hosts as $host){ + $services = $this->getRawServices($host); + if(sizeof($services) == 0){ + throw new Kohana_Exception('error.tpl-no-services-found', $serviceregex); + } + foreach($services as $service){ + if(preg_match($serviceregex, $service['name'])){ + $new_services[$i]['hostname'] = $host; + $new_services[$i]['host'] = $host; + $new_services[$i]['service_description'] = $service['name']; + $new_services[$i]['service'] = $service['name']; + $i++; + } + } + } + + if(sizeof($new_services) == 0){ + throw new Kohana_Exception('error.tpl-no-services-found', $serviceregex); + } + + return $new_services; + + } +} diff --git a/share/pnp/application/models/rrdtool.php b/share/pnp/application/models/rrdtool.php new file mode 100644 index 0000000..bca756f --- /dev/null +++ b/share/pnp/application/models/rrdtool.php @@ -0,0 +1,243 @@ +config = new Config_Model(); + $this->config->read_config(); + #print Kohana::debug($this->config->views); + } + + private function rrdtool_execute() { + $descriptorspec = array ( + 0 => array ("pipe","r"), // stdin is a pipe that the child will read from + 1 => array ("pipe","w"), // stdout is a pipe that the child will write to + 2 => array ("pipe","w") // stderr is a pipe that the child will write to + ); + + if(!isset($this->config->conf['rrdtool']) ) + return FALSE; + + if ( !is_executable($this->config->conf['rrdtool']) ) { + $data = "ERROR: ".$this->config->conf['rrdtool']." is not executable by PHP\n\n"; + return $data; + } + + $rrdtool = $this->config->conf['rrdtool'] . " - "; + $command = $this->RRD_CMD; + $process = proc_open($rrdtool, $descriptorspec, $pipes); + $debug = Array(); + $data = ""; + if (is_resource($process)) { + fwrite($pipes[0], $command); + fclose($pipes[0]); + stream_set_timeout($pipes[1],1); + $data = stream_get_contents($pipes[1]); + stream_set_timeout($pipes[2],1); + $stderr = stream_get_contents($pipes[2]); + $stdout_meta = stream_get_meta_data($pipes[1]); + if($stdout_meta['timed_out'] == 1){ + $data = "ERROR: Timeout while reading rrdtool data.\n\n"; + } + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + // Catch STDERR + if($stderr && strlen($stderr) >= 0 ){ + $data = "ERROR: STDERR => ".$stderr."\n\n"; + return $data; + } + // Catch STDOUT < 50 Characters + if($data && strlen($data) < 50 ){ + $data = "ERROR: STDOUT => ".$data."\n\n"; + return $data; + } + }else{ + $data = "ERROR: proc_open(".$rrdtool." ... failed"; + } + return $data; + + } + + public function doImage($RRD_CMD, $out='STDOUT') { + $conf = $this->config->conf; + # construct $command to rrdtool + if(isset($conf['RRD_DAEMON_OPTS']) && $conf['RRD_DAEMON_OPTS'] != '' ){ + $command = " graph --daemon=" . $conf['RRD_DAEMON_OPTS'] . " - "; + }else{ + $command = " graph - "; + } + + $width = 0; + $height = 0; + if ($out == 'PDF'){ + if($conf['pdf_graph_opt']){ + $command .= $conf['pdf_graph_opt']; + } + if (isset($conf['pdf_width']) && is_numeric($conf['pdf_width'])){ + $width = abs($conf['pdf_width']); + } + if (isset($conf['pdf_height']) && is_numeric($conf['pdf_height'])){ + $height = abs($conf['pdf_height']); + } + }else{ + if($conf['graph_opt']){ + $command .= $conf['graph_opt']; + } + if(is_numeric($conf['graph_width'])){ + $width = abs($conf['graph_width']); + } + if(is_numeric($conf['graph_height'])){ + $height = abs($conf['graph_height']); + } + } + + if ($width > 0){ + $command .= " --width=$width"; + } + if ($height > 0){ + $command .= " --height=$height"; + } + if ($height < 81 ){ + $command .= " --only-graph "; + } + + $command .= $RRD_CMD; + + # Force empty vertical label + if( ! preg_match_all('/(-l|--vertical-label)/i',$command,$match)){ + $command .= " --vertical-label=' ' "; + } + + $this->RRD_CMD = $command; + $data = $this->rrdtool_execute(); + if($data){ + return $data; + }else{ + return FALSE; + } + } + + /* + * + */ + public function doXport($RRD_CMD){ + $conf = $this->config->conf; + if(isset($conf['RRD_DAEMON_OPTS']) && $conf['RRD_DAEMON_OPTS'] != '' ){ + $command = " xport --daemon=" . $conf['RRD_DAEMON_OPTS']; + }else{ + $command = " xport "; + } + $command .= $RRD_CMD; + $this->RRD_CMD = $command; + $data = $this->rrdtool_execute(); + $data = preg_replace('/OK.*/','',$data); + if($data){ + return $data; + }else{ + return FALSE; + } + } + + public function streamImage($data = FALSE){ + if ( $data === FALSE ){ + header("Content-type: image/png"); + echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A + /wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kCCAoDKSKZ0rEAAAAZdEVYdENv + bW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADUlEQVQI12NgYGBgAAAABQABXvMqOgAAAABJ + RU5ErkJggg=='); + return; + } + if (preg_match('/^ERROR/', $data)) { + if(preg_match('/NOT_AUTHORIZED/', $data)){ + // TODO: i18n + $data .= "\n\nYou are not authorized to view this Image"; + // Set font size + $font_size = 3; + }else{ + $data .= $this->format_rrd_debug( $this->config->conf['rrdtool'] . $this->RRD_CMD) ; + // Set font size + $font_size = 1.5; + } + $ts=explode("\n",$data); + $width=0; + foreach ($ts as $k=>$string) { + $width=max($width,strlen($string)); + } + + $width = imagefontwidth($font_size)*$width; + if($width <= $this->config->conf['graph_width']+100){ + $width = $this->config->conf['graph_width']+100; + } + $height = imagefontheight($font_size)*count($ts); + if($height <= $this->config->conf['graph_height']+60){ + $height = $this->config->conf['graph_height']+60; + } + $el=imagefontheight($font_size); + $em=imagefontwidth($font_size); + // Create the image pallette + $img = imagecreatetruecolor($width,$height); + // Dark red background + $bg = imagecolorallocate($img, 0xAA, 0x00, 0x00); + imagefilledrectangle($img, 0, 0,$width ,$height , $bg); + // White font color + $color = imagecolorallocate($img, 255, 255, 255); + + foreach ($ts as $k=>$string) { + // Length of the string + $len = strlen($string); + // Y-coordinate of character, X changes, Y is static + $ypos_offset = 5; + $xpos_offset = 5; + // Loop through the string + for($i=0;$i<$len;$i++){ + // Position of the character horizontally + $xpos = $i * $em + $ypos_offset; + $ypos = $k * $el + $xpos_offset; + // Draw character + imagechar($img, $font_size, $xpos, $ypos, $string, $color); + // Remove character from string + $string = substr($string, 1); + } + } + header("Content-type: image/png"); + imagepng($img); + imagedestroy($img); + }else{ + header("Content-type: image/png"); + echo $data; + } + } + + public function saveImage($data = FALSE){ + $img = array(); + $img['file'] = tempnam($this->config->conf['temp'],"PNP"); + if(!$fh = fopen($img['file'],'w') ){ + throw new Kohana_Exception('save-rrd-image', $img['file']); + } + fwrite($fh, $data); + fclose($fh); + if (function_exists('imagecreatefrompng')) { + $image = imagecreatefrompng($img['file']); + imagepng($image, $img['file']); + list ($img['width'], $img['height'], $img['type'], $img['attr']) = getimagesize($img['file']); + }else{ + throw new Kohana_Exception('error.gd-missing'); + } + return $img; + } + + + private function format_rrd_debug($data) { + $data = preg_replace('/(HRULE|VDEF|DEF|CDEF|GPRINT|LINE|AREA|COMMENT)/',"\n\${1}", $data); + return $data; + } +} diff --git a/share/pnp/application/models/system.php b/share/pnp/application/models/system.php new file mode 100644 index 0000000..fa291ad --- /dev/null +++ b/share/pnp/application/models/system.php @@ -0,0 +1,14 @@ + ORD_u) { + $this->error('Illegal character in ASCII85Decode.'); + } + + $chn[$state++] = $ch - ORD_exclmark; + + if ($state == 5) { + $state = 0; + $r = 0; + for ($j = 0; $j < 5; ++$j) + $r = $r * 85 + $chn[$j]; + $out .= chr($r >> 24); + $out .= chr($r >> 16); + $out .= chr($r >> 8); + $out .= chr($r); + } + } + $r = 0; + + if ($state == 1) + $this->error('Illegal length in ASCII85Decode.'); + if ($state == 2) { + $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85; + $out .= chr($r >> 24); + } + else if ($state == 3) { + $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2]+1) * 85 * 85; + $out .= chr($r >> 24); + $out .= chr($r >> 16); + } + else if ($state == 4) { + $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3]+1) * 85 ; + $out .= chr($r >> 24); + $out .= chr($r >> 16); + $out .= chr($r >> 8); + } + + return $out; + } + + function encode($in) { + $this->error("ASCII85 encoding not implemented."); + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/filters/FilterASCII85_FPDI.php b/share/pnp/application/vendor/fpdf/filters/FilterASCII85_FPDI.php new file mode 100644 index 0000000..596de48 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/filters/FilterASCII85_FPDI.php @@ -0,0 +1,33 @@ +fpdi =& $fpdi; + } + + function error($msg) { + $this->fpdi->error($msg); + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/filters/FilterLZW.php b/share/pnp/application/vendor/fpdf/filters/FilterLZW.php new file mode 100644 index 0000000..5867603 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/filters/FilterLZW.php @@ -0,0 +1,154 @@ +error('LZW flavour not supported.'); + } + + $this->initsTable(); + + $this->data = $data; + $this->dataLength = strlen($data); + + // Initialize pointers + $this->bytePointer = 0; + $this->bitPointer = 0; + + $this->nextData = 0; + $this->nextBits = 0; + + $oldCode = 0; + + $string = ''; + $uncompData = ''; + + while (($code = $this->getNextCode()) != 257) { + if ($code == 256) { + $this->initsTable(); + $code = $this->getNextCode(); + + if ($code == 257) { + break; + } + + $uncompData .= $this->sTable[$code]; + $oldCode = $code; + + } else { + + if ($code < $this->tIdx) { + $string = $this->sTable[$code]; + $uncompData .= $string; + + $this->addStringToTable($this->sTable[$oldCode], $string[0]); + $oldCode = $code; + } else { + $string = $this->sTable[$oldCode]; + $string = $string.$string[0]; + $uncompData .= $string; + + $this->addStringToTable($string); + $oldCode = $code; + } + } + } + + return $uncompData; + } + + + /** + * Initialize the string table. + */ + function initsTable() { + $this->sTable = array(); + + for ($i = 0; $i < 256; $i++) + $this->sTable[$i] = chr($i); + + $this->tIdx = 258; + $this->bitsToGet = 9; + } + + /** + * Add a new string to the string table. + */ + function addStringToTable ($oldString, $newString='') { + $string = $oldString.$newString; + + // Add this new String to the table + $this->sTable[$this->tIdx++] = $string; + + if ($this->tIdx == 511) { + $this->bitsToGet = 10; + } else if ($this->tIdx == 1023) { + $this->bitsToGet = 11; + } else if ($this->tIdx == 2047) { + $this->bitsToGet = 12; + } + } + + // Returns the next 9, 10, 11 or 12 bits + function getNextCode() { + if ($this->bytePointer == $this->dataLength) { + return 257; + } + + $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); + $this->nextBits += 8; + + if ($this->nextBits < $this->bitsToGet) { + $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); + $this->nextBits += 8; + } + + $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9]; + $this->nextBits -= $this->bitsToGet; + + return $code; + } + + function encode($in) { + $this->error("LZW encoding not implemented."); + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/filters/FilterLZW_FPDI.php b/share/pnp/application/vendor/fpdf/filters/FilterLZW_FPDI.php new file mode 100644 index 0000000..540c22c --- /dev/null +++ b/share/pnp/application/vendor/fpdf/filters/FilterLZW_FPDI.php @@ -0,0 +1,33 @@ +fpdi =& $fpdi; + } + + function error($msg) { + $this->fpdi->error($msg); + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/font/courier.php b/share/pnp/application/vendor/fpdf/font/courier.php new file mode 100644 index 0000000..4c009f3 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/courier.php @@ -0,0 +1,7 @@ + diff --git a/share/pnp/application/vendor/fpdf/font/helvetica.php b/share/pnp/application/vendor/fpdf/font/helvetica.php new file mode 100644 index 0000000..8fa7683 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/helvetica.php @@ -0,0 +1,15 @@ +278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, + chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667, + 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833, + 'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556, + chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333, + chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667, + chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556, + chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500); +?> diff --git a/share/pnp/application/vendor/fpdf/font/helveticab.php b/share/pnp/application/vendor/fpdf/font/helveticab.php new file mode 100644 index 0000000..a8473c9 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/helveticab.php @@ -0,0 +1,15 @@ +278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, + chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, + 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889, + 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556, + chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333, + chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722, + chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611, + chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556); +?> diff --git a/share/pnp/application/vendor/fpdf/font/helveticabi.php b/share/pnp/application/vendor/fpdf/font/helveticabi.php new file mode 100644 index 0000000..4137953 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/helveticabi.php @@ -0,0 +1,15 @@ +278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, + chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>333,'"'=>474,'#'=>556,'$'=>556,'%'=>889,'&'=>722,'\''=>238,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>333,';'=>333,'<'=>584,'='=>584,'>'=>584,'?'=>611,'@'=>975,'A'=>722, + 'B'=>722,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>556,'K'=>722,'L'=>611,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>584,'_'=>556,'`'=>333,'a'=>556,'b'=>611,'c'=>556,'d'=>611,'e'=>556,'f'=>333,'g'=>611,'h'=>611,'i'=>278,'j'=>278,'k'=>556,'l'=>278,'m'=>889, + 'n'=>611,'o'=>611,'p'=>611,'q'=>611,'r'=>389,'s'=>556,'t'=>333,'u'=>611,'v'=>556,'w'=>778,'x'=>556,'y'=>556,'z'=>500,'{'=>389,'|'=>280,'}'=>389,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>278,chr(131)=>556, + chr(132)=>500,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>278,chr(146)=>278,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>556,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>280,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333, + chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>611,chr(182)=>556,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722, + chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>556,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>611,chr(241)=>611, + chr(242)=>611,chr(243)=>611,chr(244)=>611,chr(245)=>611,chr(246)=>611,chr(247)=>584,chr(248)=>611,chr(249)=>611,chr(250)=>611,chr(251)=>611,chr(252)=>611,chr(253)=>556,chr(254)=>611,chr(255)=>556); +?> diff --git a/share/pnp/application/vendor/fpdf/font/helveticai.php b/share/pnp/application/vendor/fpdf/font/helveticai.php new file mode 100644 index 0000000..d5bb6e0 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/helveticai.php @@ -0,0 +1,15 @@ +278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278, + chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584, + ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667, + 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>722,'I'=>278,'J'=>500,'K'=>667,'L'=>556,'M'=>833,'N'=>722,'O'=>778,'P'=>667,'Q'=>778,'R'=>722,'S'=>667,'T'=>611,'U'=>722,'V'=>667,'W'=>944, + 'X'=>667,'Y'=>667,'Z'=>611,'['=>278,'\\'=>278,']'=>278,'^'=>469,'_'=>556,'`'=>333,'a'=>556,'b'=>556,'c'=>500,'d'=>556,'e'=>556,'f'=>278,'g'=>556,'h'=>556,'i'=>222,'j'=>222,'k'=>500,'l'=>222,'m'=>833, + 'n'=>556,'o'=>556,'p'=>556,'q'=>556,'r'=>333,'s'=>500,'t'=>278,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>500,'{'=>334,'|'=>260,'}'=>334,'~'=>584,chr(127)=>350,chr(128)=>556,chr(129)=>350,chr(130)=>222,chr(131)=>556, + chr(132)=>333,chr(133)=>1000,chr(134)=>556,chr(135)=>556,chr(136)=>333,chr(137)=>1000,chr(138)=>667,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>222,chr(146)=>222,chr(147)=>333,chr(148)=>333,chr(149)=>350,chr(150)=>556,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>500,chr(155)=>333,chr(156)=>944,chr(157)=>350,chr(158)=>500,chr(159)=>667,chr(160)=>278,chr(161)=>333,chr(162)=>556,chr(163)=>556,chr(164)=>556,chr(165)=>556,chr(166)=>260,chr(167)=>556,chr(168)=>333,chr(169)=>737,chr(170)=>370,chr(171)=>556,chr(172)=>584,chr(173)=>333,chr(174)=>737,chr(175)=>333, + chr(176)=>400,chr(177)=>584,chr(178)=>333,chr(179)=>333,chr(180)=>333,chr(181)=>556,chr(182)=>537,chr(183)=>278,chr(184)=>333,chr(185)=>333,chr(186)=>365,chr(187)=>556,chr(188)=>834,chr(189)=>834,chr(190)=>834,chr(191)=>611,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667, + chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>278,chr(205)=>278,chr(206)=>278,chr(207)=>278,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>584,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>667,chr(222)=>667,chr(223)=>611,chr(224)=>556,chr(225)=>556,chr(226)=>556,chr(227)=>556,chr(228)=>556,chr(229)=>556,chr(230)=>889,chr(231)=>500,chr(232)=>556,chr(233)=>556,chr(234)=>556,chr(235)=>556,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>556,chr(241)=>556, + chr(242)=>556,chr(243)=>556,chr(244)=>556,chr(245)=>556,chr(246)=>556,chr(247)=>584,chr(248)=>611,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500); +?> diff --git a/share/pnp/application/vendor/fpdf/font/symbol.php b/share/pnp/application/vendor/fpdf/font/symbol.php new file mode 100644 index 0000000..b556ed8 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/symbol.php @@ -0,0 +1,15 @@ +250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, + chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549, + ','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722, + 'B'=>667,'C'=>722,'D'=>612,'E'=>611,'F'=>763,'G'=>603,'H'=>722,'I'=>333,'J'=>631,'K'=>722,'L'=>686,'M'=>889,'N'=>722,'O'=>722,'P'=>768,'Q'=>741,'R'=>556,'S'=>592,'T'=>611,'U'=>690,'V'=>439,'W'=>768, + 'X'=>645,'Y'=>795,'Z'=>611,'['=>333,'\\'=>863,']'=>333,'^'=>658,'_'=>500,'`'=>500,'a'=>631,'b'=>549,'c'=>549,'d'=>494,'e'=>439,'f'=>521,'g'=>411,'h'=>603,'i'=>329,'j'=>603,'k'=>549,'l'=>549,'m'=>576, + 'n'=>521,'o'=>549,'p'=>549,'q'=>521,'r'=>549,'s'=>603,'t'=>439,'u'=>576,'v'=>713,'w'=>686,'x'=>493,'y'=>686,'z'=>494,'{'=>480,'|'=>200,'}'=>480,'~'=>549,chr(127)=>0,chr(128)=>0,chr(129)=>0,chr(130)=>0,chr(131)=>0, + chr(132)=>0,chr(133)=>0,chr(134)=>0,chr(135)=>0,chr(136)=>0,chr(137)=>0,chr(138)=>0,chr(139)=>0,chr(140)=>0,chr(141)=>0,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0, + chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>750,chr(161)=>620,chr(162)=>247,chr(163)=>549,chr(164)=>167,chr(165)=>713,chr(166)=>500,chr(167)=>753,chr(168)=>753,chr(169)=>753,chr(170)=>753,chr(171)=>1042,chr(172)=>987,chr(173)=>603,chr(174)=>987,chr(175)=>603, + chr(176)=>400,chr(177)=>549,chr(178)=>411,chr(179)=>549,chr(180)=>549,chr(181)=>713,chr(182)=>494,chr(183)=>460,chr(184)=>549,chr(185)=>549,chr(186)=>549,chr(187)=>549,chr(188)=>1000,chr(189)=>603,chr(190)=>1000,chr(191)=>658,chr(192)=>823,chr(193)=>686,chr(194)=>795,chr(195)=>987,chr(196)=>768,chr(197)=>768, + chr(198)=>823,chr(199)=>768,chr(200)=>768,chr(201)=>713,chr(202)=>713,chr(203)=>713,chr(204)=>713,chr(205)=>713,chr(206)=>713,chr(207)=>713,chr(208)=>768,chr(209)=>713,chr(210)=>790,chr(211)=>790,chr(212)=>890,chr(213)=>823,chr(214)=>549,chr(215)=>250,chr(216)=>713,chr(217)=>603,chr(218)=>603,chr(219)=>1042, + chr(220)=>987,chr(221)=>603,chr(222)=>987,chr(223)=>603,chr(224)=>494,chr(225)=>329,chr(226)=>790,chr(227)=>790,chr(228)=>786,chr(229)=>713,chr(230)=>384,chr(231)=>384,chr(232)=>384,chr(233)=>384,chr(234)=>384,chr(235)=>384,chr(236)=>494,chr(237)=>494,chr(238)=>494,chr(239)=>494,chr(240)=>0,chr(241)=>329, + chr(242)=>274,chr(243)=>686,chr(244)=>686,chr(245)=>686,chr(246)=>384,chr(247)=>384,chr(248)=>384,chr(249)=>384,chr(250)=>384,chr(251)=>384,chr(252)=>494,chr(253)=>494,chr(254)=>494,chr(255)=>0); +?> diff --git a/share/pnp/application/vendor/fpdf/font/times.php b/share/pnp/application/vendor/fpdf/font/times.php new file mode 100644 index 0000000..b9be1b2 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/times.php @@ -0,0 +1,15 @@ +250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, + chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>408,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>180,'('=>333,')'=>333,'*'=>500,'+'=>564, + ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>564,'='=>564,'>'=>564,'?'=>444,'@'=>921,'A'=>722, + 'B'=>667,'C'=>667,'D'=>722,'E'=>611,'F'=>556,'G'=>722,'H'=>722,'I'=>333,'J'=>389,'K'=>722,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>556,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>722,'W'=>944, + 'X'=>722,'Y'=>722,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>469,'_'=>500,'`'=>333,'a'=>444,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778, + 'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>333,'s'=>389,'t'=>278,'u'=>500,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>480,'|'=>200,'}'=>480,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500, + chr(132)=>444,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>889,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>444,chr(148)=>444,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>980, + chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>200,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>564,chr(173)=>333,chr(174)=>760,chr(175)=>333, + chr(176)=>400,chr(177)=>564,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>453,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>444,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722, + chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>564,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>722,chr(222)=>556,chr(223)=>500,chr(224)=>444,chr(225)=>444,chr(226)=>444,chr(227)=>444,chr(228)=>444,chr(229)=>444,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500, + chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>564,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>500,chr(254)=>500,chr(255)=>500); +?> diff --git a/share/pnp/application/vendor/fpdf/font/timesb.php b/share/pnp/application/vendor/fpdf/font/timesb.php new file mode 100644 index 0000000..c3eb9fa --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/timesb.php @@ -0,0 +1,15 @@ +250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, + chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>555,'#'=>500,'$'=>500,'%'=>1000,'&'=>833,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570, + ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>930,'A'=>722, + 'B'=>667,'C'=>722,'D'=>722,'E'=>667,'F'=>611,'G'=>778,'H'=>778,'I'=>389,'J'=>500,'K'=>778,'L'=>667,'M'=>944,'N'=>722,'O'=>778,'P'=>611,'Q'=>778,'R'=>722,'S'=>556,'T'=>667,'U'=>722,'V'=>722,'W'=>1000, + 'X'=>722,'Y'=>722,'Z'=>667,'['=>333,'\\'=>278,']'=>333,'^'=>581,'_'=>500,'`'=>333,'a'=>500,'b'=>556,'c'=>444,'d'=>556,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>333,'k'=>556,'l'=>278,'m'=>833, + 'n'=>556,'o'=>500,'p'=>556,'q'=>556,'r'=>444,'s'=>389,'t'=>333,'u'=>556,'v'=>500,'w'=>722,'x'=>500,'y'=>500,'z'=>444,'{'=>394,'|'=>220,'}'=>394,'~'=>520,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500, + chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>1000,chr(141)=>350,chr(142)=>667,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>444,chr(159)=>722,chr(160)=>250,chr(161)=>333,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>300,chr(171)=>500,chr(172)=>570,chr(173)=>333,chr(174)=>747,chr(175)=>333, + chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>556,chr(182)=>540,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>330,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>722,chr(193)=>722,chr(194)=>722,chr(195)=>722,chr(196)=>722,chr(197)=>722, + chr(198)=>1000,chr(199)=>722,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>778,chr(211)=>778,chr(212)=>778,chr(213)=>778,chr(214)=>778,chr(215)=>570,chr(216)=>778,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>722,chr(222)=>611,chr(223)=>556,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556, + chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>500,chr(254)=>556,chr(255)=>500); +?> diff --git a/share/pnp/application/vendor/fpdf/font/timesbi.php b/share/pnp/application/vendor/fpdf/font/timesbi.php new file mode 100644 index 0000000..161f630 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/timesbi.php @@ -0,0 +1,15 @@ +250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, + chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>389,'"'=>555,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>278,'('=>333,')'=>333,'*'=>500,'+'=>570, + ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>570,'='=>570,'>'=>570,'?'=>500,'@'=>832,'A'=>667, + 'B'=>667,'C'=>667,'D'=>722,'E'=>667,'F'=>667,'G'=>722,'H'=>778,'I'=>389,'J'=>500,'K'=>667,'L'=>611,'M'=>889,'N'=>722,'O'=>722,'P'=>611,'Q'=>722,'R'=>667,'S'=>556,'T'=>611,'U'=>722,'V'=>667,'W'=>889, + 'X'=>667,'Y'=>611,'Z'=>611,'['=>333,'\\'=>278,']'=>333,'^'=>570,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>333,'g'=>500,'h'=>556,'i'=>278,'j'=>278,'k'=>500,'l'=>278,'m'=>778, + 'n'=>556,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>556,'v'=>444,'w'=>667,'x'=>500,'y'=>444,'z'=>389,'{'=>348,'|'=>220,'}'=>348,'~'=>570,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500, + chr(132)=>500,chr(133)=>1000,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>556,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>611,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>500,chr(148)=>500,chr(149)=>350,chr(150)=>500,chr(151)=>1000,chr(152)=>333,chr(153)=>1000, + chr(154)=>389,chr(155)=>333,chr(156)=>722,chr(157)=>350,chr(158)=>389,chr(159)=>611,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>220,chr(167)=>500,chr(168)=>333,chr(169)=>747,chr(170)=>266,chr(171)=>500,chr(172)=>606,chr(173)=>333,chr(174)=>747,chr(175)=>333, + chr(176)=>400,chr(177)=>570,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>576,chr(182)=>500,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>300,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>667,chr(193)=>667,chr(194)=>667,chr(195)=>667,chr(196)=>667,chr(197)=>667, + chr(198)=>944,chr(199)=>667,chr(200)=>667,chr(201)=>667,chr(202)=>667,chr(203)=>667,chr(204)=>389,chr(205)=>389,chr(206)=>389,chr(207)=>389,chr(208)=>722,chr(209)=>722,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>570,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>611,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>722,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>556, + chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>570,chr(248)=>500,chr(249)=>556,chr(250)=>556,chr(251)=>556,chr(252)=>556,chr(253)=>444,chr(254)=>500,chr(255)=>444); +?> diff --git a/share/pnp/application/vendor/fpdf/font/timesi.php b/share/pnp/application/vendor/fpdf/font/timesi.php new file mode 100644 index 0000000..de171fd --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/timesi.php @@ -0,0 +1,15 @@ +250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250, + chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>420,'#'=>500,'$'=>500,'%'=>833,'&'=>778,'\''=>214,'('=>333,')'=>333,'*'=>500,'+'=>675, + ','=>250,'-'=>333,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>333,';'=>333,'<'=>675,'='=>675,'>'=>675,'?'=>500,'@'=>920,'A'=>611, + 'B'=>611,'C'=>667,'D'=>722,'E'=>611,'F'=>611,'G'=>722,'H'=>722,'I'=>333,'J'=>444,'K'=>667,'L'=>556,'M'=>833,'N'=>667,'O'=>722,'P'=>611,'Q'=>722,'R'=>611,'S'=>500,'T'=>556,'U'=>722,'V'=>611,'W'=>833, + 'X'=>611,'Y'=>556,'Z'=>556,'['=>389,'\\'=>278,']'=>389,'^'=>422,'_'=>500,'`'=>333,'a'=>500,'b'=>500,'c'=>444,'d'=>500,'e'=>444,'f'=>278,'g'=>500,'h'=>500,'i'=>278,'j'=>278,'k'=>444,'l'=>278,'m'=>722, + 'n'=>500,'o'=>500,'p'=>500,'q'=>500,'r'=>389,'s'=>389,'t'=>278,'u'=>500,'v'=>444,'w'=>667,'x'=>444,'y'=>444,'z'=>389,'{'=>400,'|'=>275,'}'=>400,'~'=>541,chr(127)=>350,chr(128)=>500,chr(129)=>350,chr(130)=>333,chr(131)=>500, + chr(132)=>556,chr(133)=>889,chr(134)=>500,chr(135)=>500,chr(136)=>333,chr(137)=>1000,chr(138)=>500,chr(139)=>333,chr(140)=>944,chr(141)=>350,chr(142)=>556,chr(143)=>350,chr(144)=>350,chr(145)=>333,chr(146)=>333,chr(147)=>556,chr(148)=>556,chr(149)=>350,chr(150)=>500,chr(151)=>889,chr(152)=>333,chr(153)=>980, + chr(154)=>389,chr(155)=>333,chr(156)=>667,chr(157)=>350,chr(158)=>389,chr(159)=>556,chr(160)=>250,chr(161)=>389,chr(162)=>500,chr(163)=>500,chr(164)=>500,chr(165)=>500,chr(166)=>275,chr(167)=>500,chr(168)=>333,chr(169)=>760,chr(170)=>276,chr(171)=>500,chr(172)=>675,chr(173)=>333,chr(174)=>760,chr(175)=>333, + chr(176)=>400,chr(177)=>675,chr(178)=>300,chr(179)=>300,chr(180)=>333,chr(181)=>500,chr(182)=>523,chr(183)=>250,chr(184)=>333,chr(185)=>300,chr(186)=>310,chr(187)=>500,chr(188)=>750,chr(189)=>750,chr(190)=>750,chr(191)=>500,chr(192)=>611,chr(193)=>611,chr(194)=>611,chr(195)=>611,chr(196)=>611,chr(197)=>611, + chr(198)=>889,chr(199)=>667,chr(200)=>611,chr(201)=>611,chr(202)=>611,chr(203)=>611,chr(204)=>333,chr(205)=>333,chr(206)=>333,chr(207)=>333,chr(208)=>722,chr(209)=>667,chr(210)=>722,chr(211)=>722,chr(212)=>722,chr(213)=>722,chr(214)=>722,chr(215)=>675,chr(216)=>722,chr(217)=>722,chr(218)=>722,chr(219)=>722, + chr(220)=>722,chr(221)=>556,chr(222)=>611,chr(223)=>500,chr(224)=>500,chr(225)=>500,chr(226)=>500,chr(227)=>500,chr(228)=>500,chr(229)=>500,chr(230)=>667,chr(231)=>444,chr(232)=>444,chr(233)=>444,chr(234)=>444,chr(235)=>444,chr(236)=>278,chr(237)=>278,chr(238)=>278,chr(239)=>278,chr(240)=>500,chr(241)=>500, + chr(242)=>500,chr(243)=>500,chr(244)=>500,chr(245)=>500,chr(246)=>500,chr(247)=>675,chr(248)=>500,chr(249)=>500,chr(250)=>500,chr(251)=>500,chr(252)=>500,chr(253)=>444,chr(254)=>500,chr(255)=>444); +?> diff --git a/share/pnp/application/vendor/fpdf/font/zapfdingbats.php b/share/pnp/application/vendor/fpdf/font/zapfdingbats.php new file mode 100644 index 0000000..f2bdfd5 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/font/zapfdingbats.php @@ -0,0 +1,15 @@ +0,chr(1)=>0,chr(2)=>0,chr(3)=>0,chr(4)=>0,chr(5)=>0,chr(6)=>0,chr(7)=>0,chr(8)=>0,chr(9)=>0,chr(10)=>0,chr(11)=>0,chr(12)=>0,chr(13)=>0,chr(14)=>0,chr(15)=>0,chr(16)=>0,chr(17)=>0,chr(18)=>0,chr(19)=>0,chr(20)=>0,chr(21)=>0, + chr(22)=>0,chr(23)=>0,chr(24)=>0,chr(25)=>0,chr(26)=>0,chr(27)=>0,chr(28)=>0,chr(29)=>0,chr(30)=>0,chr(31)=>0,' '=>278,'!'=>974,'"'=>961,'#'=>974,'$'=>980,'%'=>719,'&'=>789,'\''=>790,'('=>791,')'=>690,'*'=>960,'+'=>939, + ','=>549,'-'=>855,'.'=>911,'/'=>933,'0'=>911,'1'=>945,'2'=>974,'3'=>755,'4'=>846,'5'=>762,'6'=>761,'7'=>571,'8'=>677,'9'=>763,':'=>760,';'=>759,'<'=>754,'='=>494,'>'=>552,'?'=>537,'@'=>577,'A'=>692, + 'B'=>786,'C'=>788,'D'=>788,'E'=>790,'F'=>793,'G'=>794,'H'=>816,'I'=>823,'J'=>789,'K'=>841,'L'=>823,'M'=>833,'N'=>816,'O'=>831,'P'=>923,'Q'=>744,'R'=>723,'S'=>749,'T'=>790,'U'=>792,'V'=>695,'W'=>776, + 'X'=>768,'Y'=>792,'Z'=>759,'['=>707,'\\'=>708,']'=>682,'^'=>701,'_'=>826,'`'=>815,'a'=>789,'b'=>789,'c'=>707,'d'=>687,'e'=>696,'f'=>689,'g'=>786,'h'=>787,'i'=>713,'j'=>791,'k'=>785,'l'=>791,'m'=>873, + 'n'=>761,'o'=>762,'p'=>762,'q'=>759,'r'=>759,'s'=>892,'t'=>892,'u'=>788,'v'=>784,'w'=>438,'x'=>138,'y'=>277,'z'=>415,'{'=>392,'|'=>392,'}'=>668,'~'=>668,chr(127)=>0,chr(128)=>390,chr(129)=>390,chr(130)=>317,chr(131)=>317, + chr(132)=>276,chr(133)=>276,chr(134)=>509,chr(135)=>509,chr(136)=>410,chr(137)=>410,chr(138)=>234,chr(139)=>234,chr(140)=>334,chr(141)=>334,chr(142)=>0,chr(143)=>0,chr(144)=>0,chr(145)=>0,chr(146)=>0,chr(147)=>0,chr(148)=>0,chr(149)=>0,chr(150)=>0,chr(151)=>0,chr(152)=>0,chr(153)=>0, + chr(154)=>0,chr(155)=>0,chr(156)=>0,chr(157)=>0,chr(158)=>0,chr(159)=>0,chr(160)=>0,chr(161)=>732,chr(162)=>544,chr(163)=>544,chr(164)=>910,chr(165)=>667,chr(166)=>760,chr(167)=>760,chr(168)=>776,chr(169)=>595,chr(170)=>694,chr(171)=>626,chr(172)=>788,chr(173)=>788,chr(174)=>788,chr(175)=>788, + chr(176)=>788,chr(177)=>788,chr(178)=>788,chr(179)=>788,chr(180)=>788,chr(181)=>788,chr(182)=>788,chr(183)=>788,chr(184)=>788,chr(185)=>788,chr(186)=>788,chr(187)=>788,chr(188)=>788,chr(189)=>788,chr(190)=>788,chr(191)=>788,chr(192)=>788,chr(193)=>788,chr(194)=>788,chr(195)=>788,chr(196)=>788,chr(197)=>788, + chr(198)=>788,chr(199)=>788,chr(200)=>788,chr(201)=>788,chr(202)=>788,chr(203)=>788,chr(204)=>788,chr(205)=>788,chr(206)=>788,chr(207)=>788,chr(208)=>788,chr(209)=>788,chr(210)=>788,chr(211)=>788,chr(212)=>894,chr(213)=>838,chr(214)=>1016,chr(215)=>458,chr(216)=>748,chr(217)=>924,chr(218)=>748,chr(219)=>918, + chr(220)=>927,chr(221)=>928,chr(222)=>928,chr(223)=>834,chr(224)=>873,chr(225)=>828,chr(226)=>924,chr(227)=>924,chr(228)=>917,chr(229)=>930,chr(230)=>931,chr(231)=>463,chr(232)=>883,chr(233)=>836,chr(234)=>836,chr(235)=>867,chr(236)=>867,chr(237)=>696,chr(238)=>696,chr(239)=>874,chr(240)=>0,chr(241)=>874, + chr(242)=>760,chr(243)=>946,chr(244)=>771,chr(245)=>865,chr(246)=>771,chr(247)=>888,chr(248)=>967,chr(249)=>888,chr(250)=>831,chr(251)=>873,chr(252)=>927,chr(253)=>970,chr(254)=>918,chr(255)=>0); +?> diff --git a/share/pnp/application/vendor/fpdf/fpdf.php b/share/pnp/application/vendor/fpdf/fpdf.php new file mode 100644 index 0000000..51f5d59 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/fpdf.php @@ -0,0 +1,1732 @@ +_dochecks(); + //Initialization of properties + $this->page=0; + $this->n=2; + $this->buffer=''; + $this->pages=array(); + $this->PageSizes=array(); + $this->state=0; + $this->fonts=array(); + $this->FontFiles=array(); + $this->diffs=array(); + $this->images=array(); + $this->links=array(); + $this->InHeader=false; + $this->InFooter=false; + $this->lasth=0; + $this->FontFamily=''; + $this->FontStyle=''; + $this->FontSizePt=12; + $this->underline=false; + $this->DrawColor='0 G'; + $this->FillColor='0 g'; + $this->TextColor='0 g'; + $this->ColorFlag=false; + $this->ws=0; + //Standard fonts + $this->CoreFonts=array('courier'=>'Courier', 'courierB'=>'Courier-Bold', 'courierI'=>'Courier-Oblique', 'courierBI'=>'Courier-BoldOblique', + 'helvetica'=>'Helvetica', 'helveticaB'=>'Helvetica-Bold', 'helveticaI'=>'Helvetica-Oblique', 'helveticaBI'=>'Helvetica-BoldOblique', + 'times'=>'Times-Roman', 'timesB'=>'Times-Bold', 'timesI'=>'Times-Italic', 'timesBI'=>'Times-BoldItalic', + 'symbol'=>'Symbol', 'zapfdingbats'=>'ZapfDingbats'); + //Scale factor + if($unit=='pt') + $this->k=1; + elseif($unit=='mm') + $this->k=72/25.4; + elseif($unit=='cm') + $this->k=72/2.54; + elseif($unit=='in') + $this->k=72; + else + $this->Error('Incorrect unit: '.$unit); + //Page format + $this->PageFormats=array('a3'=>array(841.89,1190.55), 'a4'=>array(595.28,841.89), 'a5'=>array(420.94,595.28), + 'letter'=>array(612,792), 'legal'=>array(612,1008)); + if(is_string($format)) + $format=$this->_getpageformat($format); + $this->DefPageFormat=$format; + $this->CurPageFormat=$format; + //Page orientation + $orientation=strtolower($orientation); + if($orientation=='p' || $orientation=='portrait') + { + $this->DefOrientation='P'; + $this->w=$this->DefPageFormat[0]; + $this->h=$this->DefPageFormat[1]; + } + elseif($orientation=='l' || $orientation=='landscape') + { + $this->DefOrientation='L'; + $this->w=$this->DefPageFormat[1]; + $this->h=$this->DefPageFormat[0]; + } + else + $this->Error('Incorrect orientation: '.$orientation); + $this->CurOrientation=$this->DefOrientation; + $this->wPt=$this->w*$this->k; + $this->hPt=$this->h*$this->k; + //Page margins (1 cm) + $margin=28.35/$this->k; + $this->SetMargins($margin,$margin); + //Interior cell margin (1 mm) + $this->cMargin=$margin/10; + //Line width (0.2 mm) + $this->LineWidth=.567/$this->k; + //Automatic page break + $this->SetAutoPageBreak(true,2*$margin); + //Full width display mode + $this->SetDisplayMode('fullwidth'); + //Enable compression + $this->SetCompression(true); + //Set default PDF version number + $this->PDFVersion='1.3'; +} + +function SetMargins($left, $top, $right=null) +{ + //Set left, top and right margins + $this->lMargin=$left; + $this->tMargin=$top; + if($right===null) + $right=$left; + $this->rMargin=$right; +} + +function SetLeftMargin($margin) +{ + //Set left margin + $this->lMargin=$margin; + if($this->page>0 && $this->x<$margin) + $this->x=$margin; +} + +function SetTopMargin($margin) +{ + //Set top margin + $this->tMargin=$margin; +} + +function SetRightMargin($margin) +{ + //Set right margin + $this->rMargin=$margin; +} + +function SetAutoPageBreak($auto, $margin=0) +{ + //Set auto page break mode and triggering margin + $this->AutoPageBreak=$auto; + $this->bMargin=$margin; + $this->PageBreakTrigger=$this->h-$margin; +} + +function SetDisplayMode($zoom, $layout='continuous') +{ + //Set display mode in viewer + if($zoom=='fullpage' || $zoom=='fullwidth' || $zoom=='real' || $zoom=='default' || !is_string($zoom)) + $this->ZoomMode=$zoom; + else + $this->Error('Incorrect zoom display mode: '.$zoom); + if($layout=='single' || $layout=='continuous' || $layout=='two' || $layout=='default') + $this->LayoutMode=$layout; + else + $this->Error('Incorrect layout display mode: '.$layout); +} + +function SetCompression($compress) +{ + //Set page compression + if(function_exists('gzcompress')) + $this->compress=$compress; + else + $this->compress=false; +} + +function SetTitle($title, $isUTF8=false) +{ + //Title of document + if($isUTF8) + $title=$this->_UTF8toUTF16($title); + $this->title=$title; +} + +function SetSubject($subject, $isUTF8=false) +{ + //Subject of document + if($isUTF8) + $subject=$this->_UTF8toUTF16($subject); + $this->subject=$subject; +} + +function SetAuthor($author, $isUTF8=false) +{ + //Author of document + if($isUTF8) + $author=$this->_UTF8toUTF16($author); + $this->author=$author; +} + +function SetKeywords($keywords, $isUTF8=false) +{ + //Keywords of document + if($isUTF8) + $keywords=$this->_UTF8toUTF16($keywords); + $this->keywords=$keywords; +} + +function SetCreator($creator, $isUTF8=false) +{ + //Creator of document + if($isUTF8) + $creator=$this->_UTF8toUTF16($creator); + $this->creator=$creator; +} + +function AliasNbPages($alias='{nb}') +{ + //Define an alias for total number of pages + $this->AliasNbPages=$alias; +} + +function Error($msg) +{ + //Fatal error + die('FPDF error: '.$msg); +} + +function Open() +{ + //Begin document + $this->state=1; +} + +function Close() +{ + //Terminate document + if($this->state==3) + return; + if($this->page==0) + $this->AddPage(); + //Page footer + $this->InFooter=true; + $this->Footer(); + $this->InFooter=false; + //Close page + $this->_endpage(); + //Close document + $this->_enddoc(); +} + +function AddPage($orientation='', $format='') +{ + //Start a new page + if($this->state==0) + $this->Open(); + $family=$this->FontFamily; + $style=$this->FontStyle.($this->underline ? 'U' : ''); + $size=$this->FontSizePt; + $lw=$this->LineWidth; + $dc=$this->DrawColor; + $fc=$this->FillColor; + $tc=$this->TextColor; + $cf=$this->ColorFlag; + if($this->page>0) + { + //Page footer + $this->InFooter=true; + $this->Footer(); + $this->InFooter=false; + //Close page + $this->_endpage(); + } + //Start new page + $this->_beginpage($orientation,$format); + //Set line cap style to square + $this->_out('2 J'); + //Set line width + $this->LineWidth=$lw; + $this->_out(sprintf('%.2F w',$lw*$this->k)); + //Set font + if($family) + $this->SetFont($family,$style,$size); + //Set colors + $this->DrawColor=$dc; + if($dc!='0 G') + $this->_out($dc); + $this->FillColor=$fc; + if($fc!='0 g') + $this->_out($fc); + $this->TextColor=$tc; + $this->ColorFlag=$cf; + //Page header + $this->InHeader=true; + $this->Header(); + $this->InHeader=false; + //Restore line width + if($this->LineWidth!=$lw) + { + $this->LineWidth=$lw; + $this->_out(sprintf('%.2F w',$lw*$this->k)); + } + //Restore font + if($family) + $this->SetFont($family,$style,$size); + //Restore colors + if($this->DrawColor!=$dc) + { + $this->DrawColor=$dc; + $this->_out($dc); + } + if($this->FillColor!=$fc) + { + $this->FillColor=$fc; + $this->_out($fc); + } + $this->TextColor=$tc; + $this->ColorFlag=$cf; +} + +function Header() +{ + //To be implemented in your own inherited class +} + +function Footer() +{ + //To be implemented in your own inherited class +} + +function PageNo() +{ + //Get current page number + return $this->page; +} + +function SetDrawColor($r, $g=null, $b=null) +{ + //Set color for all stroking operations + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->DrawColor=sprintf('%.3F G',$r/255); + else + $this->DrawColor=sprintf('%.3F %.3F %.3F RG',$r/255,$g/255,$b/255); + if($this->page>0) + $this->_out($this->DrawColor); +} + +function SetFillColor($r, $g=null, $b=null) +{ + //Set color for all filling operations + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->FillColor=sprintf('%.3F g',$r/255); + else + $this->FillColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); + $this->ColorFlag=($this->FillColor!=$this->TextColor); + if($this->page>0) + $this->_out($this->FillColor); +} + +function SetTextColor($r, $g=null, $b=null) +{ + //Set color for text + if(($r==0 && $g==0 && $b==0) || $g===null) + $this->TextColor=sprintf('%.3F g',$r/255); + else + $this->TextColor=sprintf('%.3F %.3F %.3F rg',$r/255,$g/255,$b/255); + $this->ColorFlag=($this->FillColor!=$this->TextColor); +} + +function GetStringWidth($s) +{ + //Get width of a string in the current font + $s=(string)$s; + $cw=&$this->CurrentFont['cw']; + $w=0; + $l=strlen($s); + for($i=0;$i<$l;$i++) + $w+=$cw[$s[$i]]; + return $w*$this->FontSize/1000; +} + +function SetLineWidth($width) +{ + //Set line width + $this->LineWidth=$width; + if($this->page>0) + $this->_out(sprintf('%.2F w',$width*$this->k)); +} + +function Line($x1, $y1, $x2, $y2) +{ + //Draw a line + $this->_out(sprintf('%.2F %.2F m %.2F %.2F l S',$x1*$this->k,($this->h-$y1)*$this->k,$x2*$this->k,($this->h-$y2)*$this->k)); +} + +function Rect($x, $y, $w, $h, $style='') +{ + //Draw a rectangle + if($style=='F') + $op='f'; + elseif($style=='FD' || $style=='DF') + $op='B'; + else + $op='S'; + $this->_out(sprintf('%.2F %.2F %.2F %.2F re %s',$x*$this->k,($this->h-$y)*$this->k,$w*$this->k,-$h*$this->k,$op)); +} + +function AddFont($family, $style='', $file='') +{ + //Add a TrueType or Type1 font + $family=strtolower($family); + if($file=='') + $file=str_replace(' ','',$family).strtolower($style).'.php'; + if($family=='arial') + $family='helvetica'; + $style=strtoupper($style); + if($style=='IB') + $style='BI'; + $fontkey=$family.$style; + if(isset($this->fonts[$fontkey])) + return; + include($this->_getfontpath().$file); + if(!isset($name)) + $this->Error('Could not include font definition file'); + $i=count($this->fonts)+1; + $this->fonts[$fontkey]=array('i'=>$i, 'type'=>$type, 'name'=>$name, 'desc'=>$desc, 'up'=>$up, 'ut'=>$ut, 'cw'=>$cw, 'enc'=>$enc, 'file'=>$file); + if($diff) + { + //Search existing encodings + $d=0; + $nb=count($this->diffs); + for($i=1;$i<=$nb;$i++) + { + if($this->diffs[$i]==$diff) + { + $d=$i; + break; + } + } + if($d==0) + { + $d=$nb+1; + $this->diffs[$d]=$diff; + } + $this->fonts[$fontkey]['diff']=$d; + } + if($file) + { + if($type=='TrueType') + $this->FontFiles[$file]=array('length1'=>$originalsize); + else + $this->FontFiles[$file]=array('length1'=>$size1, 'length2'=>$size2); + } +} + +function SetFont($family, $style='', $size=0) +{ + //Select a font; size given in points + global $fpdf_charwidths; + + $family=strtolower($family); + if($family=='') + $family=$this->FontFamily; + if($family=='arial') + $family='helvetica'; + elseif($family=='symbol' || $family=='zapfdingbats') + $style=''; + $style=strtoupper($style); + if(strpos($style,'U')!==false) + { + $this->underline=true; + $style=str_replace('U','',$style); + } + else + $this->underline=false; + if($style=='IB') + $style='BI'; + if($size==0) + $size=$this->FontSizePt; + //Test if font is already selected + if($this->FontFamily==$family && $this->FontStyle==$style && $this->FontSizePt==$size) + return; + //Test if used for the first time + $fontkey=$family.$style; + if(!isset($this->fonts[$fontkey])) + { + //Check if one of the standard fonts + if(isset($this->CoreFonts[$fontkey])) + { + if(!isset($fpdf_charwidths[$fontkey])) + { + //Load metric file + $file=$family; + if($family=='times' || $family=='helvetica') + $file.=strtolower($style); + include($this->_getfontpath().$file.'.php'); + if(!isset($fpdf_charwidths[$fontkey])) + $this->Error('Could not include font metric file'); + } + $i=count($this->fonts)+1; + $name=$this->CoreFonts[$fontkey]; + $cw=$fpdf_charwidths[$fontkey]; + $this->fonts[$fontkey]=array('i'=>$i, 'type'=>'core', 'name'=>$name, 'up'=>-100, 'ut'=>50, 'cw'=>$cw); + } + else + $this->Error('Undefined font: '.$family.' '.$style); + } + //Select it + $this->FontFamily=$family; + $this->FontStyle=$style; + $this->FontSizePt=$size; + $this->FontSize=$size/$this->k; + $this->CurrentFont=&$this->fonts[$fontkey]; + if($this->page>0) + $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); +} + +function SetFontSize($size) +{ + //Set font size in points + if($this->FontSizePt==$size) + return; + $this->FontSizePt=$size; + $this->FontSize=$size/$this->k; + if($this->page>0) + $this->_out(sprintf('BT /F%d %.2F Tf ET',$this->CurrentFont['i'],$this->FontSizePt)); +} + +function AddLink() +{ + //Create a new internal link + $n=count($this->links)+1; + $this->links[$n]=array(0, 0); + return $n; +} + +function SetLink($link, $y=0, $page=-1) +{ + //Set destination of internal link + if($y==-1) + $y=$this->y; + if($page==-1) + $page=$this->page; + $this->links[$link]=array($page, $y); +} + +function Link($x, $y, $w, $h, $link) +{ + //Put a link on the page + $this->PageLinks[$this->page][]=array($x*$this->k, $this->hPt-$y*$this->k, $w*$this->k, $h*$this->k, $link); +} + +function Text($x, $y, $txt) +{ + //Output a string + $s=sprintf('BT %.2F %.2F Td (%s) Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escape($txt)); + if($this->underline && $txt!='') + $s.=' '.$this->_dounderline($x,$y,$txt); + if($this->ColorFlag) + $s='q '.$this->TextColor.' '.$s.' Q'; + $this->_out($s); +} + +function AcceptPageBreak() +{ + //Accept automatic page break or not + return $this->AutoPageBreak; +} + +function Cell($w, $h=0, $txt='', $border=0, $ln=0, $align='', $fill=false, $link='') +{ + //Output a cell + $k=$this->k; + if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) + { + //Automatic page break + $x=$this->x; + $ws=$this->ws; + if($ws>0) + { + $this->ws=0; + $this->_out('0 Tw'); + } + $this->AddPage($this->CurOrientation,$this->CurPageFormat); + $this->x=$x; + if($ws>0) + { + $this->ws=$ws; + $this->_out(sprintf('%.3F Tw',$ws*$k)); + } + } + if($w==0) + $w=$this->w-$this->rMargin-$this->x; + $s=''; + if($fill || $border==1) + { + if($fill) + $op=($border==1) ? 'B' : 'f'; + else + $op='S'; + $s=sprintf('%.2F %.2F %.2F %.2F re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op); + } + if(is_string($border)) + { + $x=$this->x; + $y=$this->y; + if(strpos($border,'L')!==false) + $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k); + if(strpos($border,'T')!==false) + $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k); + if(strpos($border,'R')!==false) + $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k); + if(strpos($border,'B')!==false) + $s.=sprintf('%.2F %.2F m %.2F %.2F l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k); + } + if($txt!=='') + { + if($align=='R') + $dx=$w-$this->cMargin-$this->GetStringWidth($txt); + elseif($align=='C') + $dx=($w-$this->GetStringWidth($txt))/2; + else + $dx=$this->cMargin; + if($this->ColorFlag) + $s.='q '.$this->TextColor.' '; + $txt2=str_replace(')','\\)',str_replace('(','\\(',str_replace('\\','\\\\',$txt))); + $s.=sprintf('BT %.2F %.2F Td (%s) Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txt2); + if($this->underline) + $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$txt); + if($this->ColorFlag) + $s.=' Q'; + if($link) + $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$this->GetStringWidth($txt),$this->FontSize,$link); + } + if($s) + $this->_out($s); + $this->lasth=$h; + if($ln>0) + { + //Go to next line + $this->y+=$h; + if($ln==1) + $this->x=$this->lMargin; + } + else + $this->x+=$w; +} + +function MultiCell($w, $h, $txt, $border=0, $align='J', $fill=false) +{ + //Output text with automatic or explicit line breaks + $cw=&$this->CurrentFont['cw']; + if($w==0) + $w=$this->w-$this->rMargin-$this->x; + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + $s=str_replace("\r",'',$txt); + $nb=strlen($s); + if($nb>0 && $s[$nb-1]=="\n") + $nb--; + $b=0; + if($border) + { + if($border==1) + { + $border='LTRB'; + $b='LRT'; + $b2='LR'; + } + else + { + $b2=''; + if(strpos($border,'L')!==false) + $b2.='L'; + if(strpos($border,'R')!==false) + $b2.='R'; + $b=(strpos($border,'T')!==false) ? $b2.'T' : $b2; + } + } + $sep=-1; + $i=0; + $j=0; + $l=0; + $ns=0; + $nl=1; + while($i<$nb) + { + //Get next character + $c=$s[$i]; + if($c=="\n") + { + //Explicit line break + if($this->ws>0) + { + $this->ws=0; + $this->_out('0 Tw'); + } + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); + $i++; + $sep=-1; + $j=$i; + $l=0; + $ns=0; + $nl++; + if($border && $nl==2) + $b=$b2; + continue; + } + if($c==' ') + { + $sep=$i; + $ls=$l; + $ns++; + } + $l+=$cw[$c]; + if($l>$wmax) + { + //Automatic line break + if($sep==-1) + { + if($i==$j) + $i++; + if($this->ws>0) + { + $this->ws=0; + $this->_out('0 Tw'); + } + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); + } + else + { + if($align=='J') + { + $this->ws=($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0; + $this->_out(sprintf('%.3F Tw',$this->ws*$this->k)); + } + $this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill); + $i=$sep+1; + } + $sep=-1; + $j=$i; + $l=0; + $ns=0; + $nl++; + if($border && $nl==2) + $b=$b2; + } + else + $i++; + } + //Last chunk + if($this->ws>0) + { + $this->ws=0; + $this->_out('0 Tw'); + } + if($border && strpos($border,'B')!==false) + $b.='B'; + $this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill); + $this->x=$this->lMargin; +} + +function Write($h, $txt, $link='') +{ + //Output text in flowing mode + $cw=&$this->CurrentFont['cw']; + $w=$this->w-$this->rMargin-$this->x; + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + $s=str_replace("\r",'',$txt); + $nb=strlen($s); + $sep=-1; + $i=0; + $j=0; + $l=0; + $nl=1; + while($i<$nb) + { + //Get next character + $c=$s[$i]; + if($c=="\n") + { + //Explicit line break + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); + $i++; + $sep=-1; + $j=$i; + $l=0; + if($nl==1) + { + $this->x=$this->lMargin; + $w=$this->w-$this->rMargin-$this->x; + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + } + $nl++; + continue; + } + if($c==' ') + $sep=$i; + $l+=$cw[$c]; + if($l>$wmax) + { + //Automatic line break + if($sep==-1) + { + if($this->x>$this->lMargin) + { + //Move to next line + $this->x=$this->lMargin; + $this->y+=$h; + $w=$this->w-$this->rMargin-$this->x; + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + $i++; + $nl++; + continue; + } + if($i==$j) + $i++; + $this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link); + } + else + { + $this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link); + $i=$sep+1; + } + $sep=-1; + $j=$i; + $l=0; + if($nl==1) + { + $this->x=$this->lMargin; + $w=$this->w-$this->rMargin-$this->x; + $wmax=($w-2*$this->cMargin)*1000/$this->FontSize; + } + $nl++; + } + else + $i++; + } + //Last chunk + if($i!=$j) + $this->Cell($l/1000*$this->FontSize,$h,substr($s,$j),0,0,'',0,$link); +} + +function Ln($h=null) +{ + //Line feed; default value is last cell height + $this->x=$this->lMargin; + if($h===null) + $this->y+=$this->lasth; + else + $this->y+=$h; +} + +function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='') +{ + //Put an image on the page + if(!isset($this->images[$file])) + { + //First use of this image, get info + if($type=='') + { + $pos=strrpos($file,'.'); + if(!$pos) + $this->Error('Image file has no extension and no type was specified: '.$file); + $type=substr($file,$pos+1); + } + $type=strtolower($type); + if($type=='jpeg') + $type='jpg'; + $mtd='_parse'.$type; + if(!method_exists($this,$mtd)) + $this->Error('Unsupported image type: '.$type); + $info=$this->$mtd($file); + $info['i']=count($this->images)+1; + $this->images[$file]=$info; + } + else + $info=$this->images[$file]; + //Automatic width and height calculation if needed + if($w==0 && $h==0) + { + //Put image at 72 dpi + $w=$info['w']/$this->k; + $h=$info['h']/$this->k; + } + elseif($w==0) + $w=$h*$info['w']/$info['h']; + elseif($h==0) + $h=$w*$info['h']/$info['w']; + //Flowing mode + if($y===null) + { + if($this->y+$h>$this->PageBreakTrigger && !$this->InHeader && !$this->InFooter && $this->AcceptPageBreak()) + { + //Automatic page break + $x2=$this->x; + $this->AddPage($this->CurOrientation,$this->CurPageFormat); + $this->x=$x2; + } + $y=$this->y; + $this->y+=$h; + } + if($x===null) + $x=$this->x; + $this->_out(sprintf('q %.2F 0 0 %.2F %.2F %.2F cm /I%d Do Q',$w*$this->k,$h*$this->k,$x*$this->k,($this->h-($y+$h))*$this->k,$info['i'])); + if($link) + $this->Link($x,$y,$w,$h,$link); +} + +function GetX() +{ + //Get x position + return $this->x; +} + +function SetX($x) +{ + //Set x position + if($x>=0) + $this->x=$x; + else + $this->x=$this->w+$x; +} + +function GetY() +{ + //Get y position + return $this->y; +} + +function SetY($y) +{ + //Set y position and reset x + $this->x=$this->lMargin; + if($y>=0) + $this->y=$y; + else + $this->y=$this->h+$y; +} + +function SetXY($x, $y) +{ + //Set x and y positions + $this->SetY($y); + $this->SetX($x); +} + +function Output($name='', $dest='') +{ + //Output PDF to some destination + if($this->state<3) + $this->Close(); + $dest=strtoupper($dest); + if($dest=='') + { + if($name=='') + { + $name='doc.pdf'; + $dest='I'; + } + else + $dest='F'; + } + switch($dest) + { + case 'I': + //Send to standard output + if(ob_get_length()) + $this->Error('Some data has already been output, can\'t send PDF file'); + if(php_sapi_name()!='cli') + { + //We send to a browser + header('Content-Type: application/pdf'); + if(headers_sent()) + $this->Error('Some data has already been output, can\'t send PDF file'); + header('Content-Length: '.strlen($this->buffer)); + header('Content-Disposition: inline; filename="'.$name.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); + ini_set('zlib.output_compression','0'); + } + echo $this->buffer; + break; + case 'D': + //Download file + if(ob_get_length()) + $this->Error('Some data has already been output, can\'t send PDF file'); + header('Content-Type: application/x-download'); + if(headers_sent()) + $this->Error('Some data has already been output, can\'t send PDF file'); + header('Content-Length: '.strlen($this->buffer)); + header('Content-Disposition: attachment; filename="'.$name.'"'); + header('Cache-Control: private, max-age=0, must-revalidate'); + header('Pragma: public'); + ini_set('zlib.output_compression','0'); + echo $this->buffer; + break; + case 'F': + //Save to local file + $f=fopen($name,'wb'); + if(!$f) + $this->Error('Unable to create output file: '.$name); + fwrite($f,$this->buffer,strlen($this->buffer)); + fclose($f); + break; + case 'S': + //Return as a string + return $this->buffer; + default: + $this->Error('Incorrect output destination: '.$dest); + } + return ''; +} + +/******************************************************************************* +* * +* Protected methods * +* * +*******************************************************************************/ +function _dochecks() +{ + //Check availability of %F + if(sprintf('%.1F',1.0)!='1.0') + $this->Error('This version of PHP is not supported'); + //Check mbstring overloading + if(ini_get('mbstring.func_overload') & 2) + $this->Error('mbstring overloading must be disabled'); + //Disable runtime magic quotes + if(get_magic_quotes_runtime()) + @set_magic_quotes_runtime(0); +} + +function _getpageformat($format) +{ + $format=strtolower($format); + if(!isset($this->PageFormats[$format])) + $this->Error('Unknown page format: '.$format); + $a=$this->PageFormats[$format]; + return array($a[0]/$this->k, $a[1]/$this->k); +} + +function _getfontpath() +{ + if(!defined('FPDF_FONTPATH') && is_dir(dirname(__FILE__).'/font')) + define('FPDF_FONTPATH',dirname(__FILE__).'/font/'); + return defined('FPDF_FONTPATH') ? FPDF_FONTPATH : ''; +} + +function _beginpage($orientation, $format) +{ + $this->page++; + $this->pages[$this->page]=''; + $this->state=2; + $this->x=$this->lMargin; + $this->y=$this->tMargin; + $this->FontFamily=''; + //Check page size + if($orientation=='') + $orientation=$this->DefOrientation; + else + $orientation=strtoupper($orientation[0]); + if($format=='') + $format=$this->DefPageFormat; + else + { + if(is_string($format)) + $format=$this->_getpageformat($format); + } + if($orientation!=$this->CurOrientation || $format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) + { + //New size + if($orientation=='P') + { + $this->w=$format[0]; + $this->h=$format[1]; + } + else + { + $this->w=$format[1]; + $this->h=$format[0]; + } + $this->wPt=$this->w*$this->k; + $this->hPt=$this->h*$this->k; + $this->PageBreakTrigger=$this->h-$this->bMargin; + $this->CurOrientation=$orientation; + $this->CurPageFormat=$format; + } + if($orientation!=$this->DefOrientation || $format[0]!=$this->DefPageFormat[0] || $format[1]!=$this->DefPageFormat[1]) + $this->PageSizes[$this->page]=array($this->wPt, $this->hPt); +} + +function _endpage() +{ + $this->state=1; +} + +function _escape($s) +{ + //Escape special characters in strings + $s=str_replace('\\','\\\\',$s); + $s=str_replace('(','\\(',$s); + $s=str_replace(')','\\)',$s); + $s=str_replace("\r",'\\r',$s); + return $s; +} + +function _textstring($s) +{ + //Format a text string + return '('.$this->_escape($s).')'; +} + +function _UTF8toUTF16($s) +{ + //Convert UTF-8 to UTF-16BE with BOM + $res="\xFE\xFF"; + $nb=strlen($s); + $i=0; + while($i<$nb) + { + $c1=ord($s[$i++]); + if($c1>=224) + { + //3-byte character + $c2=ord($s[$i++]); + $c3=ord($s[$i++]); + $res.=chr((($c1 & 0x0F)<<4) + (($c2 & 0x3C)>>2)); + $res.=chr((($c2 & 0x03)<<6) + ($c3 & 0x3F)); + } + elseif($c1>=192) + { + //2-byte character + $c2=ord($s[$i++]); + $res.=chr(($c1 & 0x1C)>>2); + $res.=chr((($c1 & 0x03)<<6) + ($c2 & 0x3F)); + } + else + { + //Single-byte character + $res.="\0".chr($c1); + } + } + return $res; +} + +function _dounderline($x, $y, $txt) +{ + //Underline text + $up=$this->CurrentFont['up']; + $ut=$this->CurrentFont['ut']; + $w=$this->GetStringWidth($txt)+$this->ws*substr_count($txt,' '); + return sprintf('%.2F %.2F %.2F %.2F re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt); +} + +function _parsejpg($file) +{ + //Extract info from a JPEG file + $a=GetImageSize($file); + if(!$a) + $this->Error('Missing or incorrect image file: '.$file); + if($a[2]!=2) + $this->Error('Not a JPEG file: '.$file); + if(!isset($a['channels']) || $a['channels']==3) + $colspace='DeviceRGB'; + elseif($a['channels']==4) + $colspace='DeviceCMYK'; + else + $colspace='DeviceGray'; + $bpc=isset($a['bits']) ? $a['bits'] : 8; + //Read whole file + $f=fopen($file,'rb'); + $data=''; + while(!feof($f)) + $data.=fread($f,8192); + fclose($f); + return array('w'=>$a[0], 'h'=>$a[1], 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'DCTDecode', 'data'=>$data); +} + +function _parsepng($file) +{ + //Extract info from a PNG file + $f=fopen($file,'rb'); + if(!$f) + $this->Error('Can\'t open image file: '.$file); + //Check signature + if($this->_readstream($f,8)!=chr(137).'PNG'.chr(13).chr(10).chr(26).chr(10)) + $this->Error('Not a PNG file: '.$file); + //Read header chunk + $this->_readstream($f,4); + if($this->_readstream($f,4)!='IHDR') + $this->Error('Incorrect PNG file: '.$file); + $w=$this->_readint($f); + $h=$this->_readint($f); + $bpc=ord($this->_readstream($f,1)); + if($bpc>8) + $this->Error('16-bit depth not supported: '.$file); + $ct=ord($this->_readstream($f,1)); + if($ct==0) + $colspace='DeviceGray'; + elseif($ct==2) + $colspace='DeviceRGB'; + elseif($ct==3) + $colspace='Indexed'; + else + $this->Error('Alpha channel not supported: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Unknown compression method: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Unknown filter method: '.$file); + if(ord($this->_readstream($f,1))!=0) + $this->Error('Interlacing not supported: '.$file); + $this->_readstream($f,4); + $parms='/DecodeParms <>'; + //Scan chunks looking for palette, transparency and image data + $pal=''; + $trns=''; + $data=''; + do + { + $n=$this->_readint($f); + $type=$this->_readstream($f,4); + if($type=='PLTE') + { + //Read palette + $pal=$this->_readstream($f,$n); + $this->_readstream($f,4); + } + elseif($type=='tRNS') + { + //Read transparency info + $t=$this->_readstream($f,$n); + if($ct==0) + $trns=array(ord(substr($t,1,1))); + elseif($ct==2) + $trns=array(ord(substr($t,1,1)), ord(substr($t,3,1)), ord(substr($t,5,1))); + else + { + $pos=strpos($t,chr(0)); + if($pos!==false) + $trns=array($pos); + } + $this->_readstream($f,4); + } + elseif($type=='IDAT') + { + //Read image data block + $data.=$this->_readstream($f,$n); + $this->_readstream($f,4); + } + elseif($type=='IEND') + break; + else + $this->_readstream($f,$n+4); + } + while($n); + if($colspace=='Indexed' && empty($pal)) + $this->Error('Missing palette in '.$file); + fclose($f); + return array('w'=>$w, 'h'=>$h, 'cs'=>$colspace, 'bpc'=>$bpc, 'f'=>'FlateDecode', 'parms'=>$parms, 'pal'=>$pal, 'trns'=>$trns, 'data'=>$data); +} + +function _readstream($f, $n) +{ + //Read n bytes from stream + $res=''; + while($n>0 && !feof($f)) + { + $s=fread($f,$n); + if($s===false) + $this->Error('Error while reading stream'); + $n-=strlen($s); + $res.=$s; + } + if($n>0) + $this->Error('Unexpected end of stream'); + return $res; +} + +function _readint($f) +{ + //Read a 4-byte integer from stream + $a=unpack('Ni',$this->_readstream($f,4)); + return $a['i']; +} + +function _parsegif($file) +{ + //Extract info from a GIF file (via PNG conversion) + if(!function_exists('imagepng')) + $this->Error('GD extension is required for GIF support'); + if(!function_exists('imagecreatefromgif')) + $this->Error('GD has no GIF read support'); + $im=imagecreatefromgif($file); + if(!$im) + $this->Error('Missing or incorrect image file: '.$file); + imageinterlace($im,0); + $tmp=tempnam('.','gif'); + if(!$tmp) + $this->Error('Unable to create a temporary file'); + if(!imagepng($im,$tmp)) + $this->Error('Error while saving to temporary file'); + imagedestroy($im); + $info=$this->_parsepng($tmp); + unlink($tmp); + return $info; +} + +function _newobj() +{ + //Begin a new object + $this->n++; + $this->offsets[$this->n]=strlen($this->buffer); + $this->_out($this->n.' 0 obj'); +} + +function _putstream($s) +{ + $this->_out('stream'); + $this->_out($s); + $this->_out('endstream'); +} + +function _out($s) +{ + //Add a line to the document + if($this->state==2) + $this->pages[$this->page].=$s."\n"; + else + $this->buffer.=$s."\n"; +} + +function _putpages() +{ + $nb=$this->page; + if(!empty($this->AliasNbPages)) + { + //Replace number of pages + for($n=1;$n<=$nb;$n++) + $this->pages[$n]=str_replace($this->AliasNbPages,$nb,$this->pages[$n]); + } + if($this->DefOrientation=='P') + { + $wPt=$this->DefPageFormat[0]*$this->k; + $hPt=$this->DefPageFormat[1]*$this->k; + } + else + { + $wPt=$this->DefPageFormat[1]*$this->k; + $hPt=$this->DefPageFormat[0]*$this->k; + } + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + for($n=1;$n<=$nb;$n++) + { + //Page + $this->_newobj(); + $this->_out('<_out('/Parent 1 0 R'); + if(isset($this->PageSizes[$n])) + $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$this->PageSizes[$n][0],$this->PageSizes[$n][1])); + $this->_out('/Resources 2 0 R'); + if(isset($this->PageLinks[$n])) + { + //Links + $annots='/Annots ['; + foreach($this->PageLinks[$n] as $pl) + { + $rect=sprintf('%.2F %.2F %.2F %.2F',$pl[0],$pl[1],$pl[0]+$pl[2],$pl[1]-$pl[3]); + $annots.='<_textstring($pl[4]).'>>>>'; + else + { + $l=$this->links[$pl[4]]; + $h=isset($this->PageSizes[$l[0]]) ? $this->PageSizes[$l[0]][1] : $hPt; + $annots.=sprintf('/Dest [%d 0 R /XYZ 0 %.2F null]>>',1+2*$l[0],$h-$l[1]*$this->k); + } + } + $this->_out($annots.']'); + } + $this->_out('/Contents '.($this->n+1).' 0 R>>'); + $this->_out('endobj'); + //Page content + $p=($this->compress) ? gzcompress($this->pages[$n]) : $this->pages[$n]; + $this->_newobj(); + $this->_out('<<'.$filter.'/Length '.strlen($p).'>>'); + $this->_putstream($p); + $this->_out('endobj'); + } + //Pages root + $this->offsets[1]=strlen($this->buffer); + $this->_out('1 0 obj'); + $this->_out('<_out($kids.']'); + $this->_out('/Count '.$nb); + $this->_out(sprintf('/MediaBox [0 0 %.2F %.2F]',$wPt,$hPt)); + $this->_out('>>'); + $this->_out('endobj'); +} + +function _putfonts() +{ + $nf=$this->n; + foreach($this->diffs as $diff) + { + //Encodings + $this->_newobj(); + $this->_out('<>'); + $this->_out('endobj'); + } + foreach($this->FontFiles as $file=>$info) + { + //Font file embedding + $this->_newobj(); + $this->FontFiles[$file]['n']=$this->n; + $font=''; + $f=fopen($this->_getfontpath().$file,'rb',1); + if(!$f) + $this->Error('Font file not found'); + while(!feof($f)) + $font.=fread($f,8192); + fclose($f); + $compressed=(substr($file,-2)=='.z'); + if(!$compressed && isset($info['length2'])) + { + $header=(ord($font[0])==128); + if($header) + { + //Strip first binary header + $font=substr($font,6); + } + if($header && ord($font[$info['length1']])==128) + { + //Strip second binary header + $font=substr($font,0,$info['length1']).substr($font,$info['length1']+6); + } + } + $this->_out('<_out('/Filter /FlateDecode'); + $this->_out('/Length1 '.$info['length1']); + if(isset($info['length2'])) + $this->_out('/Length2 '.$info['length2'].' /Length3 0'); + $this->_out('>>'); + $this->_putstream($font); + $this->_out('endobj'); + } + foreach($this->fonts as $k=>$font) + { + //Font objects + $this->fonts[$k]['n']=$this->n+1; + $type=$font['type']; + $name=$font['name']; + if($type=='core') + { + //Standard font + $this->_newobj(); + $this->_out('<_out('/BaseFont /'.$name); + $this->_out('/Subtype /Type1'); + if($name!='Symbol' && $name!='ZapfDingbats') + $this->_out('/Encoding /WinAnsiEncoding'); + $this->_out('>>'); + $this->_out('endobj'); + } + elseif($type=='Type1' || $type=='TrueType') + { + //Additional Type1 or TrueType font + $this->_newobj(); + $this->_out('<_out('/BaseFont /'.$name); + $this->_out('/Subtype /'.$type); + $this->_out('/FirstChar 32 /LastChar 255'); + $this->_out('/Widths '.($this->n+1).' 0 R'); + $this->_out('/FontDescriptor '.($this->n+2).' 0 R'); + if($font['enc']) + { + if(isset($font['diff'])) + $this->_out('/Encoding '.($nf+$font['diff']).' 0 R'); + else + $this->_out('/Encoding /WinAnsiEncoding'); + } + $this->_out('>>'); + $this->_out('endobj'); + //Widths + $this->_newobj(); + $cw=&$font['cw']; + $s='['; + for($i=32;$i<=255;$i++) + $s.=$cw[chr($i)].' '; + $this->_out($s.']'); + $this->_out('endobj'); + //Descriptor + $this->_newobj(); + $s='<$v) + $s.=' /'.$k.' '.$v; + $file=$font['file']; + if($file) + $s.=' /FontFile'.($type=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0 R'; + $this->_out($s.'>>'); + $this->_out('endobj'); + } + else + { + //Allow for additional types + $mtd='_put'.strtolower($type); + if(!method_exists($this,$mtd)) + $this->Error('Unsupported font type: '.$type); + $this->$mtd($font); + } + } +} + +function _putimages() +{ + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + reset($this->images); + while(list($file,$info)=each($this->images)) + { + $this->_newobj(); + $this->images[$file]['n']=$this->n; + $this->_out('<_out('/Subtype /Image'); + $this->_out('/Width '.$info['w']); + $this->_out('/Height '.$info['h']); + if($info['cs']=='Indexed') + $this->_out('/ColorSpace [/Indexed /DeviceRGB '.(strlen($info['pal'])/3-1).' '.($this->n+1).' 0 R]'); + else + { + $this->_out('/ColorSpace /'.$info['cs']); + if($info['cs']=='DeviceCMYK') + $this->_out('/Decode [1 0 1 0 1 0 1 0]'); + } + $this->_out('/BitsPerComponent '.$info['bpc']); + if(isset($info['f'])) + $this->_out('/Filter /'.$info['f']); + if(isset($info['parms'])) + $this->_out($info['parms']); + if(isset($info['trns']) && is_array($info['trns'])) + { + $trns=''; + for($i=0;$i_out('/Mask ['.$trns.']'); + } + $this->_out('/Length '.strlen($info['data']).'>>'); + $this->_putstream($info['data']); + unset($this->images[$file]['data']); + $this->_out('endobj'); + //Palette + if($info['cs']=='Indexed') + { + $this->_newobj(); + $pal=($this->compress) ? gzcompress($info['pal']) : $info['pal']; + $this->_out('<<'.$filter.'/Length '.strlen($pal).'>>'); + $this->_putstream($pal); + $this->_out('endobj'); + } + } +} + +function _putxobjectdict() +{ + foreach($this->images as $image) + $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); +} + +function _putresourcedict() +{ + $this->_out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]'); + $this->_out('/Font <<'); + foreach($this->fonts as $font) + $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); + $this->_out('>>'); + $this->_out('/XObject <<'); + $this->_putxobjectdict(); + $this->_out('>>'); +} + +function _putresources() +{ + $this->_putfonts(); + $this->_putimages(); + //Resource dictionary + $this->offsets[2]=strlen($this->buffer); + $this->_out('2 0 obj'); + $this->_out('<<'); + $this->_putresourcedict(); + $this->_out('>>'); + $this->_out('endobj'); +} + +function _putinfo() +{ + $this->_out('/Producer '.$this->_textstring('FPDF '.FPDF_VERSION)); + if(!empty($this->title)) + $this->_out('/Title '.$this->_textstring($this->title)); + if(!empty($this->subject)) + $this->_out('/Subject '.$this->_textstring($this->subject)); + if(!empty($this->author)) + $this->_out('/Author '.$this->_textstring($this->author)); + if(!empty($this->keywords)) + $this->_out('/Keywords '.$this->_textstring($this->keywords)); + if(!empty($this->creator)) + $this->_out('/Creator '.$this->_textstring($this->creator)); + $this->_out('/CreationDate '.$this->_textstring('D:'.@date('YmdHis'))); +} + +function _putcatalog() +{ + $this->_out('/Type /Catalog'); + $this->_out('/Pages 1 0 R'); + if($this->ZoomMode=='fullpage') + $this->_out('/OpenAction [3 0 R /Fit]'); + elseif($this->ZoomMode=='fullwidth') + $this->_out('/OpenAction [3 0 R /FitH null]'); + elseif($this->ZoomMode=='real') + $this->_out('/OpenAction [3 0 R /XYZ null null 1]'); + elseif(!is_string($this->ZoomMode)) + $this->_out('/OpenAction [3 0 R /XYZ null null '.($this->ZoomMode/100).']'); + if($this->LayoutMode=='single') + $this->_out('/PageLayout /SinglePage'); + elseif($this->LayoutMode=='continuous') + $this->_out('/PageLayout /OneColumn'); + elseif($this->LayoutMode=='two') + $this->_out('/PageLayout /TwoColumnLeft'); +} + +function _putheader() +{ + $this->_out('%PDF-'.$this->PDFVersion); +} + +function _puttrailer() +{ + $this->_out('/Size '.($this->n+1)); + $this->_out('/Root '.$this->n.' 0 R'); + $this->_out('/Info '.($this->n-1).' 0 R'); +} + +function _enddoc() +{ + $this->_putheader(); + $this->_putpages(); + $this->_putresources(); + //Info + $this->_newobj(); + $this->_out('<<'); + $this->_putinfo(); + $this->_out('>>'); + $this->_out('endobj'); + //Catalog + $this->_newobj(); + $this->_out('<<'); + $this->_putcatalog(); + $this->_out('>>'); + $this->_out('endobj'); + //Cross-ref + $o=strlen($this->buffer); + $this->_out('xref'); + $this->_out('0 '.($this->n+1)); + $this->_out('0000000000 65535 f '); + for($i=1;$i<=$this->n;$i++) + $this->_out(sprintf('%010d 00000 n ',$this->offsets[$i])); + //Trailer + $this->_out('trailer'); + $this->_out('<<'); + $this->_puttrailer(); + $this->_out('>>'); + $this->_out('startxref'); + $this->_out($o); + $this->_out('%%EOF'); + $this->state=3; +} +//End of class +} + +//Handle special IE contype request +if(isset($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT']=='contype') +{ + header('Content-Type: application/pdf'); + exit; +} + +?> diff --git a/share/pnp/application/vendor/fpdf/fpdf_tpl.php b/share/pnp/application/vendor/fpdf/fpdf_tpl.php new file mode 100644 index 0000000..d829ff1 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/fpdf_tpl.php @@ -0,0 +1,409 @@ +page <= 0) + $this->error("You have to add a page to fpdf first!"); + + if ($x == null) + $x = 0; + if ($y == null) + $y = 0; + if ($w == null) + $w = $this->w; + if ($h == null) + $h = $this->h; + + // Save settings + $this->tpl++; + $tpl =& $this->tpls[$this->tpl]; + $tpl = array( + 'o_x' => $this->x, + 'o_y' => $this->y, + 'o_AutoPageBreak' => $this->AutoPageBreak, + 'o_bMargin' => $this->bMargin, + 'o_tMargin' => $this->tMargin, + 'o_lMargin' => $this->lMargin, + 'o_rMargin' => $this->rMargin, + 'o_h' => $this->h, + 'o_w' => $this->w, + 'buffer' => '', + 'x' => $x, + 'y' => $y, + 'w' => $w, + 'h' => $h + ); + + $this->SetAutoPageBreak(false); + + // Define own high and width to calculate possitions correct + $this->h = $h; + $this->w = $w; + + $this->_intpl = true; + $this->SetXY($x+$this->lMargin, $y+$this->tMargin); + $this->SetRightMargin($this->w-$w+$this->rMargin); + + return $this->tpl; + } + + /** + * End Template + * + * This method ends a template and reset initiated variables on beginTemplate. + * + * @return mixed If a template is opened, the ID is returned. If not a false is returned. + */ + function endTemplate() { + if ($this->_intpl) { + $this->_intpl = false; + $tpl =& $this->tpls[$this->tpl]; + $this->SetXY($tpl['o_x'], $tpl['o_y']); + $this->tMargin = $tpl['o_tMargin']; + $this->lMargin = $tpl['o_lMargin']; + $this->rMargin = $tpl['o_rMargin']; + $this->h = $tpl['o_h']; + $this->w = $tpl['o_w']; + $this->SetAutoPageBreak($tpl['o_AutoPageBreak'], $tpl['o_bMargin']); + + return $this->tpl; + } else { + return false; + } + } + + /** + * Use a Template in current Page or other Template + * + * You can use a template in a page or in another template. + * You can give the used template a new size like you use the Image()-method. + * All parameters are optional. The width or height is calculated automaticaly + * if one is given. If no parameter is given the origin size as defined in + * beginTemplate() is used. + * The calculated or used width and height are returned as an array. + * + * @param int $tplidx A valid template-Id + * @param int $_x The x-position + * @param int $_y The y-position + * @param int $_w The new width of the template + * @param int $_h The new height of the template + * @retrun array The height and width of the template + */ + function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0) { + if ($this->page <= 0) + $this->error("You have to add a page to fpdf first!"); + + if (!isset($this->tpls[$tplidx])) + $this->error("Template does not exist!"); + + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['tpls'][$tplidx] =& $this->tpls[$tplidx]; + } + + $tpl =& $this->tpls[$tplidx]; + $w = $tpl['w']; + $h = $tpl['h']; + + if ($_x == null) + $_x = 0; + if ($_y == null) + $_y = 0; + + $_x += $tpl['x']; + $_y += $tpl['y']; + + $wh = $this->getTemplateSize($tplidx, $_w, $_h); + $_w = $wh['w']; + $_h = $wh['h']; + + $tData = array( + 'x' => $this->x, + 'y' => $this->y, + 'w' => $_w, + 'h' => $_h, + 'scaleX' => ($_w/$w), + 'scaleY' => ($_h/$h), + 'tx' => $_x, + 'ty' => ($this->h-$_y-$_h), + 'lty' => ($this->h-$_y-$_h) - ($this->h-$h) * ($_h/$h) + ); + + $this->_out(sprintf("q %.4F 0 0 %.4F %.4F %.4F cm", $tData['scaleX'], $tData['scaleY'], $tData['tx']*$this->k, $tData['ty']*$this->k)); // Translate + $this->_out(sprintf('%s%d Do Q', $this->tplprefix, $tplidx)); + + $this->lastUsedTemplateData = $tData; + + return array("w" => $_w, "h" => $_h); + } + + /** + * Get The calculated Size of a Template + * + * If one size is given, this method calculates the other one. + * + * @param int $tplidx A valid template-Id + * @param int $_w The width of the template + * @param int $_h The height of the template + * @return array The height and width of the template + */ + function getTemplateSize($tplidx, $_w=0, $_h=0) { + if (!$this->tpls[$tplidx]) + return false; + + $tpl =& $this->tpls[$tplidx]; + $w = $tpl['w']; + $h = $tpl['h']; + + if ($_w == 0 and $_h == 0) { + $_w = $w; + $_h = $h; + } + + if($_w==0) + $_w = $_h*$w/$h; + if($_h==0) + $_h = $_w*$h/$w; + + return array("w" => $_w, "h" => $_h); + } + + /** + * See FPDF/TCPDF-Documentation ;-) + */ + function SetFont($family, $style='', $size=0, $fontfile='') { + if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 3) { + $this->Error('More than 3 arguments for the SetFont method are only available in TCPDF.'); + } + /** + * force the resetting of font changes in a template + */ + if ($this->_intpl) + $this->FontFamily = ''; + + parent::SetFont($family, $style, $size, $fontfile); + + $fontkey = $this->FontFamily.$this->FontStyle; + + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['fonts'][$fontkey] =& $this->fonts[$fontkey]; + } else { + $this->_res['page'][$this->page]['fonts'][$fontkey] =& $this->fonts[$fontkey]; + } + } + + /** + * See FPDF/TCPDF-Documentation ;-) + */ + function Image($file, $x, $y, $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) { + if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 7) { + $this->Error('More than 7 arguments for the Image method are only available in TCPDF.'); + } + + parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border); + if ($this->_intpl) { + $this->_res['tpl'][$this->tpl]['images'][$file] =& $this->images[$file]; + } else { + $this->_res['page'][$this->page]['images'][$file] =& $this->images[$file]; + } + } + + /** + * See FPDF-Documentation ;-) + * + * AddPage is not available when you're "in" a template. + */ + function AddPage($orientation='', $format='') { + if ($this->_intpl) + $this->Error('Adding pages in templates isn\'t possible!'); + parent::AddPage($orientation, $format); + } + + /** + * Preserve adding Links in Templates ...won't work + */ + function Link($x, $y, $w, $h, $link, $spaces=0) { + if (!is_subclass_of($this, 'TCPDF') && func_num_args() > 5) { + $this->Error('More than 7 arguments for the Image method are only available in TCPDF.'); + } + + if ($this->_intpl) + $this->Error('Using links in templates aren\'t possible!'); + parent::Link($x, $y, $w, $h, $link, $spaces); + } + + function AddLink() { + if ($this->_intpl) + $this->Error('Adding links in templates aren\'t possible!'); + return parent::AddLink(); + } + + function SetLink($link, $y=0, $page=-1) { + if ($this->_intpl) + $this->Error('Setting links in templates aren\'t possible!'); + parent::SetLink($link, $y, $page); + } + + /** + * Private Method that writes the form xobjects + */ + function _putformxobjects() { + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + reset($this->tpls); + foreach($this->tpls AS $tplidx => $tpl) { + + $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; + $this->_newobj(); + $this->tpls[$tplidx]['n'] = $this->n; + $this->_out('<<'.$filter.'/Type /XObject'); + $this->_out('/Subtype /Form'); + $this->_out('/FormType 1'); + $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', + // llx + $tpl['x'], + // lly + -$tpl['y'], + // urx + ($tpl['w']+$tpl['x'])*$this->k, + // ury + ($tpl['h']-$tpl['y'])*$this->k + )); + + if ($tpl['x'] != 0 || $tpl['y'] != 0) { + $this->_out(sprintf('/Matrix [1 0 0 1 %.5F %.5F]', + -$tpl['x']*$this->k*2, $tpl['y']*$this->k*2 + )); + } + + $this->_out('/Resources '); + + $this->_out('<_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { + $this->_out('/Font <<'); + foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) + $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); + $this->_out('>>'); + } + if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || + isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) + { + $this->_out('/XObject <<'); + if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { + foreach($this->_res['tpl'][$tplidx]['images'] as $image) + $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); + } + if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { + foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) + $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R'); + } + $this->_out('>>'); + } + $this->_out('>>'); + + $this->_out('/Length '.strlen($p).' >>'); + $this->_putstream($p); + $this->_out('endobj'); + } + } + + /** + * Overwritten to add _putformxobjects() after _putimages() + * + */ + function _putimages() { + parent::_putimages(); + $this->_putformxobjects(); + } + + function _putxobjectdict() { + parent::_putxobjectdict(); + + if (count($this->tpls)) { + foreach($this->tpls as $tplidx => $tpl) { + $this->_out(sprintf('%s%d %d 0 R', $this->tplprefix, $tplidx, $tpl['n'])); + } + } + } + + /** + * Private Method + */ + function _out($s) { + if ($this->state==2 && $this->_intpl) { + $this->tpls[$this->tpl]['buffer'] .= $s."\n"; + } else { + parent::_out($s); + } + } +} diff --git a/share/pnp/application/vendor/fpdf/fpdi.php b/share/pnp/application/vendor/fpdf/fpdi.php new file mode 100644 index 0000000..bd47686 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/fpdi.php @@ -0,0 +1,505 @@ +current_filename = $filename; + $fn =& $this->current_filename; + + if (!isset($this->parsers[$fn])) + $this->parsers[$fn] = new fpdi_pdf_parser($fn, $this); + $this->current_parser =& $this->parsers[$fn]; + + return $this->parsers[$fn]->getPageCount(); + } + + /** + * Import a page + * + * @param int $pageno pagenumber + * @return int Index of imported page - to use with fpdf_tpl::useTemplate() + */ + function importPage($pageno, $boxName='/CropBox') { + if ($this->_intpl) { + return $this->error('Please import the desired pages before creating a new template.'); + } + + $fn =& $this->current_filename; + + // check if page already imported + $pageKey = $fn.((int)$pageno).$boxName; + if (isset($this->_importedPages[$pageKey])) + return $this->_importedPages[$pageKey]; + + $parser =& $this->parsers[$fn]; + $parser->setPageno($pageno); + + $this->tpl++; + $this->tpls[$this->tpl] = array(); + $tpl =& $this->tpls[$this->tpl]; + $tpl['parser'] =& $parser; + $tpl['resources'] = $parser->getPageResources(); + $tpl['buffer'] = $parser->getContent(); + + if (!in_array($boxName, $parser->availableBoxes)) + return $this->Error(sprintf('Unknown box: %s', $boxName)); + $pageboxes = $parser->getPageBoxes($pageno); + + /** + * MediaBox + * CropBox: Default -> MediaBox + * BleedBox: Default -> CropBox + * TrimBox: Default -> CropBox + * ArtBox: Default -> CropBox + */ + if (!isset($pageboxes[$boxName]) && ($boxName == '/BleedBox' || $boxName == '/TrimBox' || $boxName == '/ArtBox')) + $boxName = '/CropBox'; + if (!isset($pageboxes[$boxName]) && $boxName == '/CropBox') + $boxName = '/MediaBox'; + + if (!isset($pageboxes[$boxName])) + return false; + $this->lastUsedPageBox = $boxName; + + $box = $pageboxes[$boxName]; + $tpl['box'] = $box; + + // To build an array that can be used by PDF_TPL::useTemplate() + $this->tpls[$this->tpl] = array_merge($this->tpls[$this->tpl],$box); + + // An imported page will start at 0,0 everytime. Translation will be set in _putformxobjects() + $tpl['x'] = 0; + $tpl['y'] = 0; + + $page =& $parser->pages[$parser->pageno]; + + // handle rotated pages + $rotation = $parser->getPageRotation($pageno); + $tpl['_rotationAngle'] = 0; + if (isset($rotation[1]) && ($angle = $rotation[1] % 360) != 0) { + $steps = $angle / 90; + + $_w = $tpl['w']; + $_h = $tpl['h']; + $tpl['w'] = $steps % 2 == 0 ? $_w : $_h; + $tpl['h'] = $steps % 2 == 0 ? $_h : $_w; + + $tpl['_rotationAngle'] = $angle*-1; + } + + $this->_importedPages[$pageKey] = $this->tpl; + + return $this->tpl; + } + + function getLastUsedPageBox() { + return $this->lastUsedPageBox; + } + + function useTemplate($tplidx, $_x=null, $_y=null, $_w=0, $_h=0, $adjustPageSize=false) { + if ($adjustPageSize == true && is_null($_x) && is_null($_y)) { + $size = $this->getTemplateSize($tplidx, $_w, $_h); + $format = array($size['w'], $size['h']); + if ($format[0]!=$this->CurPageFormat[0] || $format[1]!=$this->CurPageFormat[1]) { + $this->w=$format[0]; + $this->h=$format[1]; + $this->wPt=$this->w*$this->k; + $this->hPt=$this->h*$this->k; + $this->PageBreakTrigger=$this->h-$this->bMargin; + $this->CurPageFormat=$format; + $this->PageSizes[$this->page]=array($this->wPt, $this->hPt); + } + } + + $this->_out('q 0 J 1 w 0 j 0 G 0 g'); // reset standard values + $s = parent::useTemplate($tplidx, $_x, $_y, $_w, $_h); + $this->_out('Q'); + return $s; + } + + /** + * Private method, that rebuilds all needed objects of source files + */ + function _putimportedobjects() { + if (is_array($this->parsers) && count($this->parsers) > 0) { + foreach($this->parsers AS $filename => $p) { + $this->current_parser =& $this->parsers[$filename]; + if (isset($this->_obj_stack[$filename]) && is_array($this->_obj_stack[$filename])) { + while(($n = key($this->_obj_stack[$filename])) !== null) { + $nObj = $this->current_parser->pdf_resolve_object($this->current_parser->c,$this->_obj_stack[$filename][$n][1]); + + $this->_newobj($this->_obj_stack[$filename][$n][0]); + + if ($nObj[0] == PDF_TYPE_STREAM) { + $this->pdf_write_value ($nObj); + } else { + $this->pdf_write_value ($nObj[1]); + } + + $this->_out('endobj'); + $this->_obj_stack[$filename][$n] = null; // free memory + unset($this->_obj_stack[$filename][$n]); + reset($this->_obj_stack[$filename]); + } + } + } + } + } + + + /** + * Private Method that writes the form xobjects + */ + function _putformxobjects() { + $filter=($this->compress) ? '/Filter /FlateDecode ' : ''; + reset($this->tpls); + foreach($this->tpls AS $tplidx => $tpl) { + $p=($this->compress) ? gzcompress($tpl['buffer']) : $tpl['buffer']; + $this->_newobj(); + $cN = $this->n; // TCPDF/Protection: rem current "n" + + $this->tpls[$tplidx]['n'] = $this->n; + $this->_out('<<'.$filter.'/Type /XObject'); + $this->_out('/Subtype /Form'); + $this->_out('/FormType 1'); + + $this->_out(sprintf('/BBox [%.2F %.2F %.2F %.2F]', + (isset($tpl['box']['llx']) ? $tpl['box']['llx'] : $tpl['x'])*$this->k, + (isset($tpl['box']['lly']) ? $tpl['box']['lly'] : -$tpl['y'])*$this->k, + (isset($tpl['box']['urx']) ? $tpl['box']['urx'] : $tpl['w'] + $tpl['x'])*$this->k, + (isset($tpl['box']['ury']) ? $tpl['box']['ury'] : $tpl['h']-$tpl['y'])*$this->k + )); + + $c = 1; + $s = 0; + $tx = 0; + $ty = 0; + + if (isset($tpl['box'])) { + $tx = -$tpl['box']['llx']; + $ty = -$tpl['box']['lly']; + + if ($tpl['_rotationAngle'] <> 0) { + $angle = $tpl['_rotationAngle'] * M_PI/180; + $c=cos($angle); + $s=sin($angle); + + switch($tpl['_rotationAngle']) { + case -90: + $tx = -$tpl['box']['lly']; + $ty = $tpl['box']['urx']; + break; + case -180: + $tx = $tpl['box']['urx']; + $ty = $tpl['box']['ury']; + break; + case -270: + $tx = $tpl['box']['ury']; + $ty = 0; + break; + } + } + } else if ($tpl['x'] != 0 || $tpl['y'] != 0) { + $tx = -$tpl['x']*2; + $ty = $tpl['y']*2; + } + + $tx *= $this->k; + $ty *= $this->k; + + if ($c != 1 || $s != 0 || $tx != 0 || $ty != 0) { + $this->_out(sprintf('/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]', + $c, $s, -$s, $c, $tx, $ty + )); + } + + $this->_out('/Resources '); + + if (isset($tpl['resources'])) { + $this->current_parser =& $tpl['parser']; + $this->pdf_write_value($tpl['resources']); // "n" will be changed + } else { + $this->_out('<_res['tpl'][$tplidx]['fonts']) && count($this->_res['tpl'][$tplidx]['fonts'])) { + $this->_out('/Font <<'); + foreach($this->_res['tpl'][$tplidx]['fonts'] as $font) + $this->_out('/F'.$font['i'].' '.$font['n'].' 0 R'); + $this->_out('>>'); + } + if(isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images']) || + isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) + { + $this->_out('/XObject <<'); + if (isset($this->_res['tpl'][$tplidx]['images']) && count($this->_res['tpl'][$tplidx]['images'])) { + foreach($this->_res['tpl'][$tplidx]['images'] as $image) + $this->_out('/I'.$image['i'].' '.$image['n'].' 0 R'); + } + if (isset($this->_res['tpl'][$tplidx]['tpls']) && count($this->_res['tpl'][$tplidx]['tpls'])) { + foreach($this->_res['tpl'][$tplidx]['tpls'] as $i => $tpl) + $this->_out($this->tplprefix.$i.' '.$tpl['n'].' 0 R'); + } + $this->_out('>>'); + } + $this->_out('>>'); + } + + $nN = $this->n; // TCPDF: rem new "n" + $this->n = $cN; // TCPDF: reset to current "n" + $this->_out('/Length '.strlen($p).' >>'); + $this->_putstream($p); + $this->_out('endobj'); + $this->n = $nN; // TCPDF: reset to new "n" + } + + $this->_putimportedobjects(); + } + + /** + * Rewritten to handle existing own defined objects + */ + function _newobj($obj_id=false,$onlynewobj=false) { + if (!$obj_id) { + $obj_id = ++$this->n; + } + + //Begin a new object + if (!$onlynewobj) { + $this->offsets[$obj_id] = is_subclass_of($this, 'TCPDF') ? $this->bufferlen : strlen($this->buffer); + $this->_out($obj_id.' 0 obj'); + $this->_current_obj_id = $obj_id; // for later use with encryption + } + return $obj_id; + } + + /** + * Writes a value + * Needed to rebuild the source document + * + * @param mixed $value A PDF-Value. Structure of values see cases in this method + */ + function pdf_write_value(&$value) + { + if (is_subclass_of($this, 'TCPDF')) { + parent::pdf_write_value($value); + } + + switch ($value[0]) { + + case PDF_TYPE_TOKEN : + $this->_straightOut($value[1] . ' '); + break; + case PDF_TYPE_NUMERIC : + case PDF_TYPE_REAL : + if (is_float($value[1]) && $value[1] != 0) { + $this->_straightOut(rtrim(rtrim(sprintf('%F', $value[1]), '0'), '.') .' '); + } else { + $this->_straightOut($value[1] . ' '); + } + break; + + case PDF_TYPE_ARRAY : + + // An array. Output the proper + // structure and move on. + + $this->_straightOut('['); + for ($i = 0; $i < count($value[1]); $i++) { + $this->pdf_write_value($value[1][$i]); + } + + $this->_out(']'); + break; + + case PDF_TYPE_DICTIONARY : + + // A dictionary. + $this->_straightOut('<<'); + + reset ($value[1]); + + while (list($k, $v) = each($value[1])) { + $this->_straightOut($k . ' '); + $this->pdf_write_value($v); + } + + $this->_straightOut('>>'); + break; + + case PDF_TYPE_OBJREF : + + // An indirect object reference + // Fill the object stack if needed + $cpfn =& $this->current_parser->filename; + + if (!isset($this->_don_obj_stack[$cpfn][$value[1]])) { + $this->_newobj(false,true); + $this->_obj_stack[$cpfn][$value[1]] = array($this->n, $value); + $this->_don_obj_stack[$cpfn][$value[1]] = array($this->n, $value); // Value is maybee obsolete!!! + } + $objid = $this->_don_obj_stack[$cpfn][$value[1]][0]; + + $this->_out($objid.' 0 R'); + break; + + case PDF_TYPE_STRING : + + // A string. + $this->_straightOut('('.$value[1].')'); + + break; + + case PDF_TYPE_STREAM : + + // A stream. First, output the + // stream dictionary, then the + // stream data itself. + $this->pdf_write_value($value[1]); + $this->_out('stream'); + $this->_out($value[2][1]); + $this->_out('endstream'); + break; + case PDF_TYPE_HEX : + $this->_straightOut('<'.$value[1].'>'); + break; + + case PDF_TYPE_BOOLEAN : + $this->_straightOut($value[1] ? 'true ' : 'false '); + break; + + case PDF_TYPE_NULL : + // The null object. + + $this->_straightOut('null '); + break; + } + } + + + /** + * Modified so not each call will add a newline to the output. + */ + function _straightOut($s) { + if (!is_subclass_of($this, 'TCPDF')) { + if($this->state==2) + $this->pages[$this->page] .= $s; + else + $this->buffer .= $s; + } else { + if ($this->state == 2) { + if (isset($this->footerlen[$this->page]) AND ($this->footerlen[$this->page] > 0)) { + // puts data before page footer + $page = substr($this->getPageBuffer($this->page), 0, -$this->footerlen[$this->page]); + $footer = substr($this->getPageBuffer($this->page), -$this->footerlen[$this->page]); + $this->setPageBuffer($this->page, $page.' '.$s."\n".$footer); + } else { + $this->setPageBuffer($this->page, $s, true); + } + } else { + $this->setBuffer($s); + } + } + } + + /** + * rewritten to close opened parsers + * + */ + function _enddoc() { + parent::_enddoc(); + $this->_closeParsers(); + } + + /** + * close all files opened by parsers + */ + function _closeParsers() { + if ($this->state > 2 && count($this->parsers) > 0) { + foreach ($this->parsers as $k => $_){ + $this->parsers[$k]->closeFile(); + $this->parsers[$k] = null; + unset($this->parsers[$k]); + } + return true; + } + return false; + } + +} diff --git a/share/pnp/application/vendor/fpdf/fpdi2tcpdf_bridge.php b/share/pnp/application/vendor/fpdf/fpdi2tcpdf_bridge.php new file mode 100644 index 0000000..008c766 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/fpdi2tcpdf_bridge.php @@ -0,0 +1,171 @@ +PDFVersion; + case 'k': + return $this->k; + default: + // Error handling + $this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name); + } + } + + function __set($name, $value) { + switch ($name) { + case 'PDFVersion': + $this->PDFVersion = $value; + break; + default: + // Error handling + $this->Error('Cannot access protected property '.get_class($this).':$'.$name.' / Undefined property: '.get_class($this).'::$'.$name); + } + } + + /** + * Encryption of imported data by FPDI + * + * @param array $value + */ + function pdf_write_value(&$value) { + switch ($value[0]) { + case PDF_TYPE_STRING : + if ($this->encrypted) { + $value[1] = $this->_unescape($value[1]); + $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]); + $value[1] = $this->_escape($value[1]); + } + break; + + case PDF_TYPE_STREAM : + if ($this->encrypted) { + $value[2][1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[2][1]); + } + break; + + case PDF_TYPE_HEX : + if ($this->encrypted) { + $value[1] = $this->hex2str($value[1]); + $value[1] = $this->_RC4($this->_objectkey($this->_current_obj_id), $value[1]); + + // remake hexstring of encrypted string + $value[1] = $this->str2hex($value[1]); + } + break; + } + } + + /** + * Unescapes a PDF string + * + * @param string $s + * @return string + */ + function _unescape($s) { + $out = ''; + for ($count = 0, $n = strlen($s); $count < $n; $count++) { + if ($s[$count] != '\\' || $count == $n-1) { + $out .= $s[$count]; + } else { + switch ($s[++$count]) { + case ')': + case '(': + case '\\': + $out .= $s[$count]; + break; + case 'f': + $out .= chr(0x0C); + break; + case 'b': + $out .= chr(0x08); + break; + case 't': + $out .= chr(0x09); + break; + case 'r': + $out .= chr(0x0D); + break; + case 'n': + $out .= chr(0x0A); + break; + case "\r": + if ($count != $n-1 && $s[$count+1] == "\n") + $count++; + break; + case "\n": + break; + default: + // Octal-Values + if (ord($s[$count]) >= ord('0') && + ord($s[$count]) <= ord('9')) { + $oct = ''. $s[$count]; + + if (ord($s[$count+1]) >= ord('0') && + ord($s[$count+1]) <= ord('9')) { + $oct .= $s[++$count]; + + if (ord($s[$count+1]) >= ord('0') && + ord($s[$count+1]) <= ord('9')) { + $oct .= $s[++$count]; + } + } + + $out .= chr(octdec($oct)); + } else { + $out .= $s[$count]; + } + } + } + } + return $out; + } + + /** + * Hexadecimal to string + * + * @param string $hex + * @return string + */ + function hex2str($hex) { + return pack('H*', str_replace(array("\r", "\n", ' '), '', $hex)); + } + + /** + * String to hexadecimal + * + * @param string $str + * @return string + */ + function str2hex($str) { + return current(unpack('H*', $str)); + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/fpdi_pdf_parser.php b/share/pnp/application/vendor/fpdf/fpdi_pdf_parser.php new file mode 100644 index 0000000..c5e37f6 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/fpdi_pdf_parser.php @@ -0,0 +1,384 @@ +fpdi =& $fpdi; + + parent::pdf_parser($filename); + + // resolve Pages-Dictonary + $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']); + + // Read pages + $this->read_pages($this->c, $pages, $this->pages); + + // count pages; + $this->page_count = count($this->pages); + } + + /** + * Overwrite parent::error() + * + * @param string $msg Error-Message + */ + function error($msg) { + $this->fpdi->error($msg); + } + + /** + * Get pagecount from sourcefile + * + * @return int + */ + function getPageCount() { + return $this->page_count; + } + + + /** + * Set pageno + * + * @param int $pageno Pagenumber to use + */ + function setPageno($pageno) { + $pageno = ((int) $pageno) - 1; + + if ($pageno < 0 || $pageno >= $this->getPageCount()) { + $this->fpdi->error('Pagenumber is wrong!'); + } + + $this->pageno = $pageno; + } + + /** + * Get page-resources from current page + * + * @return array + */ + function getPageResources() { + return $this->_getPageResources($this->pages[$this->pageno]); + } + + /** + * Get page-resources from /Page + * + * @param array $obj Array of pdf-data + */ + function _getPageResources ($obj) { // $obj = /Page + $obj = $this->pdf_resolve_object($this->c, $obj); + + // If the current object has a resources + // dictionary associated with it, we use + // it. Otherwise, we move back to its + // parent object. + if (isset ($obj[1][1]['/Resources'])) { + $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } else { + if (!isset ($obj[1][1]['/Parent'])) { + return false; + } else { + $res = $this->_getPageResources($obj[1][1]['/Parent']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } + } + } + + + /** + * Get content of current page + * + * If more /Contents is an array, the streams are concated + * + * @return string + */ + function getContent() { + $buffer = ''; + + if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { + $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); + foreach($contents AS $tmp_content) { + $buffer .= $this->_rebuildContentStream($tmp_content).' '; + } + } + + return $buffer; + } + + + /** + * Resolve all content-objects + * + * @param array $content_ref + * @return array + */ + function _getPageContent($content_ref) { + $contents = array(); + + if ($content_ref[0] == PDF_TYPE_OBJREF) { + $content = $this->pdf_resolve_object($this->c, $content_ref); + if ($content[1][0] == PDF_TYPE_ARRAY) { + $contents = $this->_getPageContent($content[1]); + } else { + $contents[] = $content; + } + } else if ($content_ref[0] == PDF_TYPE_ARRAY) { + foreach ($content_ref[1] AS $tmp_content_ref) { + $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref)); + } + } + + return $contents; + } + + + /** + * Rebuild content-streams + * + * @param array $obj + * @return string + */ + function _rebuildContentStream($obj) { + $filters = array(); + + if (isset($obj[1][1]['/Filter'])) { + $_filter = $obj[1][1]['/Filter']; + + if ($_filter[0] == PDF_TYPE_TOKEN) { + $filters[] = $_filter; + } else if ($_filter[0] == PDF_TYPE_ARRAY) { + $filters = $_filter[1]; + } + } + + $stream = $obj[2][1]; + + foreach ($filters AS $_filter) { + switch ($_filter[1]) { + case '/FlateDecode': + if (function_exists('gzuncompress')) { + $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; + } else { + $this->error(sprintf('To handle %s filter, please compile php with zlib support.',$_filter[1])); + } + if ($stream === false) { + $this->error('Error while decompressing stream.'); + } + break; + case '/LZWDecode': + include_once('filters/FilterLZW_FPDI.php'); + $decoder = new FilterLZW_FPDI($this->fpdi); + $stream = $decoder->decode($stream); + break; + case '/ASCII85Decode': + include_once('filters/FilterASCII85_FPDI.php'); + $decoder = new FilterASCII85_FPDI($this->fpdi); + $stream = $decoder->decode($stream); + break; + case null: + $stream = $stream; + break; + default: + $this->error(sprintf('Unsupported Filter: %s',$_filter[1])); + } + } + + return $stream; + } + + + /** + * Get a Box from a page + * Arrayformat is same as used by fpdf_tpl + * + * @param array $page a /Page + * @param string $box_index Type of Box @see $availableBoxes + * @return array + */ + function getPageBox($page, $box_index) { + $page = $this->pdf_resolve_object($this->c,$page); + $box = null; + if (isset($page[1][1][$box_index])) + $box =& $page[1][1][$box_index]; + + if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) { + $tmp_box = $this->pdf_resolve_object($this->c,$box); + $box = $tmp_box[1]; + } + + if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { + $b =& $box[1]; + return array('x' => $b[0][1]/$this->fpdi->k, + 'y' => $b[1][1]/$this->fpdi->k, + 'w' => abs($b[0][1]-$b[2][1])/$this->fpdi->k, + 'h' => abs($b[1][1]-$b[3][1])/$this->fpdi->k, + 'llx' => min($b[0][1], $b[2][1])/$this->fpdi->k, + 'lly' => min($b[1][1], $b[3][1])/$this->fpdi->k, + 'urx' => max($b[0][1], $b[2][1])/$this->fpdi->k, + 'ury' => max($b[1][1], $b[3][1])/$this->fpdi->k, + ); + } else if (!isset ($page[1][1]['/Parent'])) { + return false; + } else { + return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index); + } + } + + function getPageBoxes($pageno) { + return $this->_getPageBoxes($this->pages[$pageno-1]); + } + + /** + * Get all Boxes from /Page + * + * @param array a /Page + * @return array + */ + function _getPageBoxes($page) { + $boxes = array(); + + foreach($this->availableBoxes AS $box) { + if ($_box = $this->getPageBox($page,$box)) { + $boxes[$box] = $_box; + } + } + + return $boxes; + } + + /** + * Get the page rotation by pageno + * + * @param integer $pageno + * @return array + */ + function getPageRotation($pageno) { + return $this->_getPageRotation($this->pages[$pageno-1]); + } + + function _getPageRotation ($obj) { // $obj = /Page + $obj = $this->pdf_resolve_object($this->c, $obj); + if (isset ($obj[1][1]['/Rotate'])) { + $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } else { + if (!isset ($obj[1][1]['/Parent'])) { + return false; + } else { + $res = $this->_getPageRotation($obj[1][1]['/Parent']); + if ($res[0] == PDF_TYPE_OBJECT) + return $res[1]; + return $res; + } + } + } + + /** + * Read all /Page(es) + * + * @param object pdf_context + * @param array /Pages + * @param array the result-array + */ + function read_pages (&$c, &$pages, &$result) { + // Get the kids dictionary + $kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); + + if (!is_array($kids)) + $this->error('Cannot find /Kids in current /Page-Dictionary'); + foreach ($kids[1] as $v) { + $pg = $this->pdf_resolve_object ($c, $v); + if ($pg[1][1]['/Type'][1] === '/Pages') { + // If one of the kids is an embedded + // /Pages array, resolve it as well. + $this->read_pages ($c, $pg, $result); + } else { + $result[] = $pg; + } + } + } + + + + /** + * Get PDF-Version + * + * And reset the PDF Version used in FPDI if needed + */ + function getPDFVersion() { + parent::getPDFVersion(); + $this->fpdi->PDFVersion = max($this->fpdi->PDFVersion, $this->pdfVersion); + } + +} diff --git a/share/pnp/application/vendor/fpdf/license.txt b/share/pnp/application/vendor/fpdf/license.txt new file mode 100644 index 0000000..6107ee4 --- /dev/null +++ b/share/pnp/application/vendor/fpdf/license.txt @@ -0,0 +1,6 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software to use, copy, modify, distribute, sublicense, and/or sell +copies of the software, and to permit persons to whom the software is furnished +to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/pdf_context.php b/share/pnp/application/vendor/fpdf/pdf_context.php new file mode 100644 index 0000000..535636c --- /dev/null +++ b/share/pnp/application/vendor/fpdf/pdf_context.php @@ -0,0 +1,97 @@ +file =& $f; + if (is_string($this->file)) + $this->_mode = 1; + $this->reset(); + } + + // Optionally move the file + // pointer to a new location + // and reset the buffered data + + function reset($pos = null, $l = 100) { + if ($this->_mode == 0) { + if (!is_null ($pos)) { + fseek ($this->file, $pos); + } + + $this->buffer = $l > 0 ? fread($this->file, $l) : ''; + $this->length = strlen($this->buffer); + if ($this->length < $l) + $this->increase_length($l - $this->length); + } else { + $this->buffer = $this->file; + $this->length = strlen($this->buffer); + } + $this->offset = 0; + $this->stack = array(); + } + + // Make sure that there is at least one + // character beyond the current offset in + // the buffer to prevent the tokenizer + // from attempting to access data that does + // not exist + + function ensure_content() { + if ($this->offset >= $this->length - 1) { + return $this->increase_length(); + } else { + return true; + } + } + + // Forcefully read more data into the buffer + + function increase_length($l=100) { + if ($this->_mode == 0 && feof($this->file)) { + return false; + } else if ($this->_mode == 0) { + $totalLength = $this->length + $l; + do { + $this->buffer .= fread($this->file, $totalLength-$this->length); + } while ((($this->length = strlen($this->buffer)) != $totalLength) && !feof($this->file)); + + return true; + } else { + return false; + } + } +} \ No newline at end of file diff --git a/share/pnp/application/vendor/fpdf/pdf_parser.php b/share/pnp/application/vendor/fpdf/pdf_parser.php new file mode 100644 index 0000000..3e65d6b --- /dev/null +++ b/share/pnp/application/vendor/fpdf/pdf_parser.php @@ -0,0 +1,706 @@ +filename = $filename; + + $this->f = @fopen($this->filename, 'rb'); + + if (!$this->f) + $this->error(sprintf('Cannot open %s !', $filename)); + + $this->getPDFVersion(); + + $this->c = new pdf_context($this->f); + + // Read xref-Data + $this->xref = array(); + $this->pdf_read_xref($this->xref, $this->pdf_find_xref()); + + // Check for Encryption + $this->getEncryption(); + + // Read root + $this->pdf_read_root(); + } + + /** + * Close the opened file + */ + function closeFile() { + if (isset($this->f) && is_resource($this->f)) { + fclose($this->f); + unset($this->f); + } + } + + /** + * Print Error and die + * + * @param string $msg Error-Message + */ + function error($msg) { + die('PDF-Parser Error: '.$msg); + } + + /** + * Check Trailer for Encryption + */ + function getEncryption() { + if (isset($this->xref['trailer'][1]['/Encrypt'])) { + $this->error('File is encrypted!'); + } + } + + /** + * Find/Return /Root + * + * @return array + */ + function pdf_find_root() { + if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { + $this->error('Wrong Type of Root-Element! Must be an indirect reference'); + } + + return $this->xref['trailer'][1]['/Root']; + } + + /** + * Read the /Root + */ + function pdf_read_root() { + // read root + $this->root = $this->pdf_resolve_object($this->c, $this->pdf_find_root()); + } + + /** + * Get PDF-Version + * + * And reset the PDF Version used in FPDI if needed + */ + function getPDFVersion() { + fseek($this->f, 0); + preg_match('/\d\.\d/',fread($this->f,16),$m); + if (isset($m[0])) + $this->pdfVersion = $m[0]; + return $this->pdfVersion; + } + + /** + * Find the xref-Table + */ + function pdf_find_xref() { + $toRead = 1500; + + $stat = fseek ($this->f, -$toRead, SEEK_END); + if ($stat === -1) { + fseek ($this->f, 0); + } + $data = fread($this->f, $toRead); + + $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); + $data = substr($data, $pos); + + if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { + $this->error('Unable to find pointer to xref table'); + } + + return (int) $matches[1]; + } + + /** + * Read xref-table + * + * @param array $result Array of xref-table + * @param integer $offset of xref-table + */ + function pdf_read_xref(&$result, $offset) { + + fseek($this->f, $o_pos = $offset-20); // set some bytes backwards to fetch errorious docs + + $data = fread($this->f, 100); + + $xrefPos = strrpos($data, 'xref'); + + if ($xrefPos === false) { + fseek($this->f, $offset); + $c = new pdf_context($this->f); + $xrefStreamObjDec = $this->pdf_read_value($c); + + if (is_array($xrefStreamObjDec) && isset($xrefStreamObjDec[0]) && $xrefStreamObjDec[0] == PDF_TYPE_OBJDEC) { + $this->error(sprintf('This document (%s) probably uses a compression technique which is not supported by the free parser shipped with FPDI.', $this->filename)); + } else { + $this->error('Unable to find xref table.'); + } + } + + if (!isset($result['xref_location'])) { + $result['xref_location'] = $o_pos+$xrefPos; + $result['max_object'] = 0; + } + + $cylces = -1; + $bytesPerCycle = 100; + + fseek($this->f, $o_pos = $o_pos+$xrefPos+4); // set the handle directly after the "xref"-keyword + $data = fread($this->f, $bytesPerCycle); + + while (($trailerPos = strpos($data, 'trailer', max($bytesPerCycle*$cylces++, 0))) === false && !feof($this->f)) { + $data .= fread($this->f, $bytesPerCycle); + } + + if ($trailerPos === false) { + $this->error('Trailer keyword not found after xref table'); + } + + $data = substr($data, 0, $trailerPos); + + // get Line-Ending + preg_match_all("/(\r\n|\n|\r)/", substr($data, 0, 100), $m); // check the first 100 bytes for linebreaks + + $differentLineEndings = count(array_unique($m[0])); + if ($differentLineEndings > 1) { + $lines = preg_split("/(\r\n|\n|\r)/", $data, -1, PREG_SPLIT_NO_EMPTY); + } else { + $lines = explode($m[0][1], $data); + } + + $data = $differentLineEndings = $m = null; + unset($data, $differentLineEndings, $m); + + $linesCount = count($lines); + + $start = 1; + + for ($i = 0; $i < $linesCount; $i++) { + $line = trim($lines[$i]); + if ($line) { + $pieces = explode(' ', $line); + $c = count($pieces); + switch($c) { + case 2: + $start = (int)$pieces[0]; + $end = $start+(int)$pieces[1]; + if ($end > $result['max_object']) + $result['max_object'] = $end; + break; + case 3: + if (!isset($result['xref'][$start])) + $result['xref'][$start] = array(); + + if (!array_key_exists($gen = (int) $pieces[1], $result['xref'][$start])) { + $result['xref'][$start][$gen] = $pieces[2] == 'n' ? (int) $pieces[0] : null; + } + $start++; + break; + default: + $this->error('Unexpected data in xref table'); + } + } + } + + $lines = $pieces = $line = $start = $end = $gen = null; + unset($lines, $pieces, $line, $start, $end, $gen); + + fseek($this->f, $o_pos+$trailerPos+7); + + $c = new pdf_context($this->f); + $trailer = $this->pdf_read_value($c); + + $c = null; + unset($c); + + if (!isset($result['trailer'])) { + $result['trailer'] = $trailer; + } + + if (isset($trailer[1]['/Prev'])) { + $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); + } + + $trailer = null; + unset($trailer); + + return true; + } + + /** + * Reads an Value + * + * @param object $c pdf_context + * @param string $token a Token + * @return mixed + */ + function pdf_read_value(&$c, $token = null) { + if (is_null($token)) { + $token = $this->pdf_read_token($c); + } + + if ($token === false) { + return false; + } + + switch ($token) { + case '<': + // This is a hex string. + // Read the value, then the terminator + + $pos = $c->offset; + + while(1) { + + $match = strpos ($c->buffer, '>', $pos); + + // If you can't find it, try + // reading more data from the stream + + if ($match === false) { + if (!$c->increase_length()) { + return false; + } else { + continue; + } + } + + $result = substr ($c->buffer, $c->offset, $match - $c->offset); + $c->offset = $match + 1; + + return array (PDF_TYPE_HEX, $result); + } + + break; + case '<<': + // This is a dictionary. + + $result = array(); + + // Recurse into this function until we reach + // the end of the dictionary. + while (($key = $this->pdf_read_token($c)) !== '>>') { + if ($key === false) { + return false; + } + + if (($value = $this->pdf_read_value($c)) === false) { + return false; + } + + // Catch missing value + if ($value[0] == PDF_TYPE_TOKEN && $value[1] == '>>') { + $result[$key] = array(PDF_TYPE_NULL); + break; + } + + $result[$key] = $value; + } + + return array (PDF_TYPE_DICTIONARY, $result); + + case '[': + // This is an array. + + $result = array(); + + // Recurse into this function until we reach + // the end of the array. + while (($token = $this->pdf_read_token($c)) !== ']') { + if ($token === false) { + return false; + } + + if (($value = $this->pdf_read_value($c, $token)) === false) { + return false; + } + + $result[] = $value; + } + + return array (PDF_TYPE_ARRAY, $result); + + case '(' : + // This is a string + $pos = $c->offset; + + $openBrackets = 1; + do { + for (; $openBrackets != 0 && $pos < $c->length; $pos++) { + switch (ord($c->buffer[$pos])) { + case 0x28: // '(' + $openBrackets++; + break; + case 0x29: // ')' + $openBrackets--; + break; + case 0x5C: // backslash + $pos++; + } + } + } while($openBrackets != 0 && $c->increase_length()); + + $result = substr($c->buffer, $c->offset, $pos - $c->offset - 1); + $c->offset = $pos; + + return array (PDF_TYPE_STRING, $result); + + case 'stream': + $o_pos = ftell($c->file)-strlen($c->buffer); + $o_offset = $c->offset; + + $c->reset($startpos = $o_pos + $o_offset); + + $e = 0; // ensure line breaks in front of the stream + if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) + $e++; + if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) + $e++; + + if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { + $tmp_c = new pdf_context($this->f); + $tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']); + $length = $tmp_length[1][1]; + } else { + $length = $this->actual_obj[1][1]['/Length'][1]; + } + + if ($length > 0) { + $c->reset($startpos+$e,$length); + $v = $c->buffer; + } else { + $v = ''; + } + $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream") + + return array(PDF_TYPE_STREAM, $v); + + default : + if (is_numeric ($token)) { + // A numeric token. Make sure that + // it is not part of something else. + if (($tok2 = $this->pdf_read_token ($c)) !== false) { + if (is_numeric ($tok2)) { + + // Two numeric tokens in a row. + // In this case, we're probably in + // front of either an object reference + // or an object specification. + // Determine the case and return the data + if (($tok3 = $this->pdf_read_token ($c)) !== false) { + switch ($tok3) { + case 'obj' : + return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); + case 'R' : + return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); + } + // If we get to this point, that numeric value up + // there was just a numeric value. Push the extra + // tokens back into the stack and return the value. + array_push ($c->stack, $tok3); + } + } + + array_push ($c->stack, $tok2); + } + + if ($token === (string)((int)$token)) + return array (PDF_TYPE_NUMERIC, (int)$token); + else + return array (PDF_TYPE_REAL, (float)$token); + } else if ($token == 'true' || $token == 'false') { + return array (PDF_TYPE_BOOLEAN, $token == 'true'); + } else if ($token == 'null') { + return array (PDF_TYPE_NULL); + } else { + // Just a token. Return it. + return array (PDF_TYPE_TOKEN, $token); + } + } + } + + /** + * Resolve an object + * + * @param object $c pdf_context + * @param array $obj_spec The object-data + * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para + */ + function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { + // Exit if we get invalid data + if (!is_array($obj_spec)) { + $ret = false; + return $ret; + } + + if ($obj_spec[0] == PDF_TYPE_OBJREF) { + + // This is a reference, resolve it + if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { + + // Save current file position + // This is needed if you want to resolve + // references while you're reading another object + // (e.g.: if you need to determine the length + // of a stream) + + $old_pos = ftell($c->file); + + // Reposition the file pointer and + // load the object header. + + $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); + + $header = $this->pdf_read_value($c); + + if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { + $this->error("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); + } + + // If we're being asked to store all the information + // about the object, we add the object ID and generation + // number for later use + $result = array(); + $this->actual_obj =& $result; + if ($encapsulate) { + $result = array ( + PDF_TYPE_OBJECT, + 'obj' => $obj_spec[1], + 'gen' => $obj_spec[2] + ); + } + + // Now simply read the object data until + // we encounter an end-of-object marker + while(1) { + $value = $this->pdf_read_value($c); + if ($value === false || count($result) > 4) { + // in this case the parser coudn't find an endobj so we break here + break; + } + + if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { + break; + } + + $result[] = $value; + } + + $c->reset($old_pos); + + if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { + $result[0] = PDF_TYPE_STREAM; + } + + return $result; + } + } else { + return $obj_spec; + } + } + + + + /** + * Reads a token from the file + * + * @param object $c pdf_context + * @return mixed + */ + function pdf_read_token(&$c) + { + // If there is a token available + // on the stack, pop it out and + // return it. + + if (count($c->stack)) { + return array_pop($c->stack); + } + + // Strip away any whitespace + + do { + if (!$c->ensure_content()) { + return false; + } + $c->offset += strspn($c->buffer, " \n\r\t", $c->offset); + } while ($c->offset >= $c->length - 1); + + // Get the first character in the stream + + $char = $c->buffer[$c->offset++]; + + switch ($char) { + + case '[': + case ']': + case '(': + case ')': + + // This is either an array or literal string + // delimiter, Return it + + return $char; + + case '<': + case '>': + + // This could either be a hex string or + // dictionary delimiter. Determine the + // appropriate case and return the token + + if ($c->buffer[$c->offset] == $char) { + if (!$c->ensure_content()) { + return false; + } + $c->offset++; + return $char . $char; + } else { + return $char; + } + + case '%': + + // This is a comment - jump over it! + + $pos = $c->offset; + while(1) { + $match = preg_match("/(\r\n|\r|\n)/", $c->buffer, $m, PREG_OFFSET_CAPTURE, $pos); + if ($match === 0) { + if (!$c->increase_length()) { + return false; + } else { + continue; + } + } + + $c->offset = $m[0][1]+strlen($m[0][0]); + + return $this->pdf_read_token($c); + } + + default: + + // This is "another" type of token (probably + // a dictionary entry or a numeric value) + // Find the end and return it. + + if (!$c->ensure_content()) { + return false; + } + + while(1) { + + // Determine the length of the token + + $pos = strcspn($c->buffer, " %[]<>()\r\n\t/", $c->offset); + + if ($c->offset + $pos <= $c->length - 1) { + break; + } else { + // If the script reaches this point, + // the token may span beyond the end + // of the current buffer. Therefore, + // we increase the size of the buffer + // and try again--just to be safe. + + $c->increase_length(); + } + } + + $result = substr($c->buffer, $c->offset - 1, $pos + 1); + + $c->offset += $pos; + return $result; + } + } +} + +} diff --git a/share/pnp/application/views/basket_box.php b/share/pnp/application/views/basket_box.php new file mode 100644 index 0000000..ea8a72c --- /dev/null +++ b/share/pnp/application/views/basket_box.php @@ -0,0 +1,32 @@ +session->get('basket'); + +echo "
    \n"; +echo "
    \n"; +echo Kohana::lang('common.basket-box-header')."
    \n"; +echo "
    \n"; +echo "
    \n"; +if(is_array($basket) && sizeof($basket) > 0 ){ + foreach($basket as $key=>$item){ + echo "
  • ". + pnp::shorten($item)."
  • \n"; + } +} +if(is_array($basket) && sizeof($basket) > 0 ){ + echo "
    \n"; + echo "\n"; + echo "\n"; + echo "
    \n"; + #echo "\n"; +}else{ + echo "
    ".Kohana::lang('common.basket-empty')."
    \n"; +} +echo "
    \n"; +echo "
    \n"; +echo "

    \n"; +?> +
    diff --git a/share/pnp/application/views/color.php b/share/pnp/application/views/color.php new file mode 100644 index 0000000..d461b8b --- /dev/null +++ b/share/pnp/application/views/color.php @@ -0,0 +1,38 @@ +
    + + +
    +
    +
    + +
    +
    + scheme)) { + foreach( $this->scheme as $key => $colors ){ + print "

    \"" . $key . "\"

      "; + foreach($colors as $color){ + print "
    • " . "
    • \n"; + } + print "
    "; + } + print "

    "; + } ?> +
    +
    +
    + + + + +
    +
    +
    + +
    + +
    +
    diff --git a/share/pnp/application/views/color_box.php b/share/pnp/application/views/color_box.php new file mode 100644 index 0000000..1c4d342 --- /dev/null +++ b/share/pnp/application/views/color_box.php @@ -0,0 +1,15 @@ + +
    +
    + +
    +
    +\n"; +echo "\n"; +echo "\n"; +?> +
    +
    +

    + diff --git a/share/pnp/application/views/debug.php b/share/pnp/application/views/debug.php new file mode 100644 index 0000000..2681d16 --- /dev/null +++ b/share/pnp/application/views/debug.php @@ -0,0 +1,74 @@ +is_authorized === FALSE){ + print "

    Your are not authorized to view this site

    "; + return; +} +?> +
    + + +
    +
    + +
    + +
    +

    $this->data->STRUCT

    +
    +data->STRUCT);?>
    +	
    +
    +
    +

    $this->data->DS

    +
    +data->DS);?>
    +	
    +
    +
    +

    $this->data->MACRO

    +
    +data->MACRO);?>
    +	
    +
    +
    +

    $this->session->get()

    +
    +session->get());?>
    +	
    +
    +
    +
    +
    +
    + + + + + + +
    +
    +
    + + +
    + diff --git a/share/pnp/application/views/docs.php b/share/pnp/application/views/docs.php new file mode 100644 index 0000000..81114bc --- /dev/null +++ b/share/pnp/application/views/docs.php @@ -0,0 +1,31 @@ +
    + + +
    +
    +
    + +
    +
    +content)) { +echo $this->content; +} ?> +
    +
    +
    +
    + + + + +
    +
    +
    + +
    +
    +
    diff --git a/share/pnp/application/views/docs_box.php b/share/pnp/application/views/docs_box.php new file mode 100644 index 0000000..8a24fa7 --- /dev/null +++ b/share/pnp/application/views/docs_box.php @@ -0,0 +1,28 @@ + +
    +
    + +
    +
    +\n"; +echo "\n"; +echo "\n"; +foreach ( $this->doc_language as $lang ){ + echo " \n"; +} +?> +
    +
    +

    +

    +
    + +
    +
    +
    + toc ?> +
    +
    +

    + diff --git a/share/pnp/application/views/graph.php b/share/pnp/application/views/graph.php new file mode 100644 index 0000000..045aa2b --- /dev/null +++ b/share/pnp/application/views/graph.php @@ -0,0 +1,56 @@ +

    + + +
    + +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    diff --git a/share/pnp/application/views/graph_content.php b/share/pnp/application/views/graph_content.php new file mode 100644 index 0000000..337f938 --- /dev/null +++ b/share/pnp/application/views/graph_content.php @@ -0,0 +1,102 @@ + +\n"; + +if($this->is_authorized == FALSE){ + echo "
    \n"; + echo "

    \n"; + echo "Alert: ".Kohana::lang('error.not_authorized')."

    \n"; + echo "
    \n"; + return; +} + +if($this->data->ERROR != NULL){ + echo "
    \n"; + echo "

    \n"; + echo "Alert: ".$this->data->ERROR."

    \n"; + echo "
    \n"; + return; +} +$count = 0; +foreach($this->data->STRUCT as $key=>$value){ + if($value['LEVEL'] == 0){ + echo "Host: ".$value['MACRO']['DISP_HOSTNAME']. " Service: ".$value['MACRO']['DISP_SERVICEDESC']."

    \n"; + echo "".$value['TIMERANGE']['title']. " " .$value['TIMERANGE']['f_start']. " - " . $value['TIMERANGE']['f_end']. "\n"; + $count = 0; + } + if($value['VERSION'] != "valid" && $count == 0){ + $count++; + echo "

    \n"; + echo "
    \n"; + echo "

    ".$value['VERSION']."

    \n"; + echo "
    \n"; + echo "

    \n"; + } + + echo "
    "; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "
    "; + echo Kohana::lang('common.datasource',$value['ds_name']).""; + echo nagios::SummaryLink($value['MACRO']['DISP_HOSTNAME'], + $value['TIMERANGE']['start'], + $value['TIMERANGE']['end']).""; + echo nagios::AvailLink($value['MACRO']['DISP_HOSTNAME'], + $value['MACRO']['DISP_SERVICEDESC'], + $value['TIMERANGE']['start'], + $value['TIMERANGE']['end']).""; + echo pnp::add_to_basket_icon( + $value['MACRO']['HOSTNAME'], + $value['MACRO']['SERVICEDESC'], + $value['SOURCE'] + ); + echo ""; + echo pnp::zoom_icon($value['MACRO']['HOSTNAME'], + $value['MACRO']['SERVICEDESC'], + $value['TIMERANGE']['start'], + $value['TIMERANGE']['end'], + $value['SOURCE'], + $value['VIEW'], + $value['GRAPH_WIDTH'], + $value['GRAPH_HEIGHT'])."
    \n"; + echo "
    \n"; + echo "

    \n"; +} +echo "\n"; +?> + diff --git a/share/pnp/application/views/graph_content_special.php b/share/pnp/application/views/graph_content_special.php new file mode 100644 index 0000000..375520a --- /dev/null +++ b/share/pnp/application/views/graph_content_special.php @@ -0,0 +1,53 @@ + +\n"; +$count = 0; +if($this->data->MACRO['TITLE']) + echo "".$this->data->MACRO['TITLE']."

    \n"; +if($this->data->MACRO['COMMENT']) + echo $this->data->MACRO['COMMENT']."

    \n"; + +foreach($this->data->STRUCT as $key=>$value){ + if($value['LEVEL'] == 0 ){ + echo "".$value['TIMERANGE']['title']. " " .$value['TIMERANGE']['f_start']. " - " . $value['TIMERANGE']['f_end']. "\n"; + $count = 0; + } + echo "

    "; + echo "\n"; + echo "\n"; + echo "\n"; + + echo "
    "; + echo Kohana::lang('common.datasource',$value['ds_name']).""; + echo pnp::zoom_icon_special($this->tpl, + $value['TIMERANGE']['start'], + $value['TIMERANGE']['end'], + $value['SOURCE'], + $value['VIEW'], + $value['GRAPH_WIDTH'], + $value['GRAPH_HEIGHT'])."
    \n"; + echo "
    \n"; + echo "

    \n"; +} +echo "\n"; +?> + diff --git a/share/pnp/application/views/graph_tiny.php b/share/pnp/application/views/graph_tiny.php new file mode 100644 index 0000000..dde26aa --- /dev/null +++ b/share/pnp/application/views/graph_tiny.php @@ -0,0 +1,19 @@ +

    +
    + + + + +
    +
    + + + +
    +
    +
    +
    \ No newline at end of file diff --git a/share/pnp/application/views/header.php b/share/pnp/application/views/header.php new file mode 100644 index 0000000..d4efaa1 --- /dev/null +++ b/share/pnp/application/views/header.php @@ -0,0 +1,4 @@ + +
    + +
    diff --git a/share/pnp/application/views/host_box.php b/share/pnp/application/views/host_box.php new file mode 100644 index 0000000..d612934 --- /dev/null +++ b/share/pnp/application/views/host_box.php @@ -0,0 +1,11 @@ +
    +Status Box
    + +$host['state']))."

    "; +} +} +?> + +
    diff --git a/share/pnp/application/views/icon_box.php b/share/pnp/application/views/icon_box.php new file mode 100644 index 0000000..34d99c1 --- /dev/null +++ b/share/pnp/application/views/icon_box.php @@ -0,0 +1,39 @@ + +
    +
    + +
    +
    + $this->start,'end' => $this->end, 'view' => $this->view), False); +if($this->config->conf['use_calendar']){ + echo ""; +} +if($this->config->conf['use_fpdf'] == 1 && ( $position == "graph" || $position == "special") ){ + echo "\n"; +} +if($this->config->conf['use_fpdf'] == 1 && $position == "basket"){ + echo "\n"; +} +if($this->config->conf['use_fpdf'] == 1 && $position == "page"){ + echo "page.$qsa."\">\n"; +} +if($this->config->conf['show_xml_icon'] == 1 && $position == "graph" && $xml_icon == TRUE){ + $qsa = pnp::addToUri(array(), False); + echo "\n"; +} +if($this->data->getFirstPage() && $this->isAuthorizedFor('pages') ){ + echo "\n"; +} + +echo "\n"; + +if($this->data->getFirstSpecialTemplate() ){ + echo "\n"; +} + +echo "\n"; +?> +
    +

    + diff --git a/share/pnp/application/views/kohana_error_page.php b/share/pnp/application/views/kohana_error_page.php new file mode 100644 index 0000000..490ed62 --- /dev/null +++ b/share/pnp/application/views/kohana_error_page.php @@ -0,0 +1,77 @@ + + + + + + + + +<?php echo $error ?> + + + + + + + + +

    + + +
    +
    +
    + +
    +
    +
    + +

    Please check the documentation for information about the following error.

    +

    + +

    file [line]:

    +

    + + +

    + + +

    + + +

    +
    +
    +
    + +
    + +
    + +
    + +
    +\n"; +echo "\n"; +echo "\n"; +?> +
    + +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + + + diff --git a/share/pnp/application/views/logo_box.php b/share/pnp/application/views/logo_box.php new file mode 100644 index 0000000..fca461f --- /dev/null +++ b/share/pnp/application/views/logo_box.php @@ -0,0 +1,9 @@ + +
    + +
    + + diff --git a/share/pnp/application/views/mobile.php b/share/pnp/application/views/mobile.php new file mode 100644 index 0000000..1c1afdf --- /dev/null +++ b/share/pnp/application/views/mobile.php @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + +
    +
    +

    PNP4Nagios

    +Home +
    + + + + + + + + + +
    +
    +
    + + diff --git a/share/pnp/application/views/mobile_about.php b/share/pnp/application/views/mobile_about.php new file mode 100644 index 0000000..2f8bc29 --- /dev/null +++ b/share/pnp/application/views/mobile_about.php @@ -0,0 +1,3 @@ +
    +PNP4Nagios mobile interface based on jQuery Mobile +
    diff --git a/share/pnp/application/views/mobile_graph.php b/share/pnp/application/views/mobile_graph.php new file mode 100644 index 0000000..87f4193 --- /dev/null +++ b/share/pnp/application/views/mobile_graph.php @@ -0,0 +1,43 @@ +is_authorized == FALSE){ +?> +
    +
      +
    • Alert: 
    • +
    +
    + +
    + +data->STRUCT as $d){ + if($d['VIEW'] > $last_view){ # a new header begins + if($last_view != -1 ){ # close last div + print "
    \n"; + } + printf("
    %s
    \n", $d['TIMERANGE']['title'] ); + printf("
    %s\n", $d['ds_name']); + printf("
    \n", + $d['MACRO']['HOSTNAME'], + $d['MACRO']['SERVICEDESC'], + $d['VIEW'], + $d['SOURCE'] + ); + $last_view++; + }else{ + printf("
    %s
    \n", $d['ds_name']); + printf("
    \n", + $d['MACRO']['HOSTNAME'], + $d['MACRO']['SERVICEDESC'], + $d['VIEW'], + $d['SOURCE'] + ); + } +} +?> +
    + diff --git a/share/pnp/application/views/mobile_graph_special.php b/share/pnp/application/views/mobile_graph_special.php new file mode 100644 index 0000000..c7b4b6d --- /dev/null +++ b/share/pnp/application/views/mobile_graph_special.php @@ -0,0 +1,33 @@ +
    +data->MACRO['TITLE']) + echo "".$this->data->MACRO['TITLE']."

    \n"; +if($this->data->MACRO['COMMENT']) + echo $this->data->MACRO['COMMENT']."

    \n"; + +$last_view = -1; +foreach($this->data->STRUCT as $d){ + if($d['VIEW'] > $last_view){ # a new header begins + if($last_view != -1 ){ # close last div + print "

    \n"; + } + printf("
    %s
    \n", $d['TIMERANGE']['title'] ); + printf("
    %s\n", $d['ds_name']); + printf("
    \n", + $this->tpl, + $d['VIEW'], + $d['SOURCE'] + ); + $last_view++; + }else{ + printf("
    %s
    \n", $d['ds_name']); + printf("
    \n", + $this->tpl, + $d['VIEW'], + $d['SOURCE'] + ); + } +} +?> +
    diff --git a/share/pnp/application/views/mobile_home.php b/share/pnp/application/views/mobile_home.php new file mode 100644 index 0000000..7723a2a --- /dev/null +++ b/share/pnp/application/views/mobile_home.php @@ -0,0 +1,17 @@ +
    + +
    diff --git a/share/pnp/application/views/mobile_host.php b/share/pnp/application/views/mobile_host.php new file mode 100644 index 0000000..9eedbae --- /dev/null +++ b/share/pnp/application/views/mobile_host.php @@ -0,0 +1,30 @@ +is_authorized == FALSE){ +?> +
    +
      +
    • Alert: 
    • +
    +
    + + +
    +
      +$service){ + if($key == 0) + printf("
    • %s
    • \n", $service['hostname'] ); + + printf("
    • %s
    • ", + urlencode($service['hostname']), + urlencode($service['name']), + urlencode($service['hostname']), + urlencode($service['name']), + $service['servicedesc']); +} +?> +
    +
    diff --git a/share/pnp/application/views/mobile_overview.php b/share/pnp/application/views/mobile_overview.php new file mode 100644 index 0000000..e037b75 --- /dev/null +++ b/share/pnp/application/views/mobile_overview.php @@ -0,0 +1,14 @@ +
    +
      +%s\n", strtoupper(substr($host['name'], 0, 1)) ); + } + printf("
    • %s
    • ", $host['name'], $host['name']); + $l = substr($host['name'], 0, 1); +} +?> +
    +
    diff --git a/share/pnp/application/views/mobile_pages.php b/share/pnp/application/views/mobile_pages.php new file mode 100644 index 0000000..cead17f --- /dev/null +++ b/share/pnp/application/views/mobile_pages.php @@ -0,0 +1,10 @@ +
    +
      +data->getPageDetails($page); + printf("
    • %s
    • ", $page, $this->data->PAGE_DEF['page_name']); +} +?> +
    +
    diff --git a/share/pnp/application/views/mobile_search.php b/share/pnp/application/views/mobile_search.php new file mode 100644 index 0000000..e8573d1 --- /dev/null +++ b/share/pnp/application/views/mobile_search.php @@ -0,0 +1,24 @@ +isAuthorizedFor('host_search') ){ ?> + +
    + +
    +
    + + +
    +
    + +
    + + + +
    +
      +result as $host){ + printf("
    • %s
    • ", $host, $host); +} +?> +
    +
    diff --git a/share/pnp/application/views/mobile_special.php b/share/pnp/application/views/mobile_special.php new file mode 100644 index 0000000..786d109 --- /dev/null +++ b/share/pnp/application/views/mobile_special.php @@ -0,0 +1,9 @@ +
    +
      +%s", $template, $template); +} +?> +
    +
    diff --git a/share/pnp/application/views/multisite_box.php b/share/pnp/application/views/multisite_box.php new file mode 100644 index 0000000..13d64de --- /dev/null +++ b/share/pnp/application/views/multisite_box.php @@ -0,0 +1,17 @@ +
    +
    + +
    +
    +Host: ".html::specialchars(pnp::shorten($host))."
    \n"; +} +if(isset($service) && $service != "Host Perfdata"){ + echo "Service: ".html::specialchars(pnp::shorten($service))."\n"; +} +?> +
    +
    +

    + diff --git a/share/pnp/application/views/page.php b/share/pnp/application/views/page.php new file mode 100644 index 0000000..ac285c3 --- /dev/null +++ b/share/pnp/application/views/page.php @@ -0,0 +1,48 @@ +

    + + +
    + +
    +
    + +
    +
    +
    + + + + + + + + + + + + +
    +
    +
    + +
    +
    +
    diff --git a/share/pnp/application/views/pages_box.php b/share/pnp/application/views/pages_box.php new file mode 100644 index 0000000..d2297f4 --- /dev/null +++ b/share/pnp/application/views/pages_box.php @@ -0,0 +1,29 @@ +isAuthorizedFor('pages') ) { ?> +
    +
    + +
    + +session->get('pfilter'); +?> + +
    + " + ?> +
    + +
    +"; + $this->data->getPageDetails($page); + echo "data->PAGE_DEF['page_name']."\">".pnp::shorten($this->data->PAGE_DEF['page_name'])."
    \n"; + echo "\n"; +} +?> +
    +
    +

    + diff --git a/share/pnp/application/views/popup.php b/share/pnp/application/views/popup.php new file mode 100644 index 0000000..1b60236 --- /dev/null +++ b/share/pnp/application/views/popup.php @@ -0,0 +1,10 @@ +\n"; +} +?> +
    +data->STRUCT as $KEY=>$VAL){ + $source = $VAL['SOURCE']; + echo "
    \n"; + echo "\n"; + echo "
    diff --git a/share/pnp/application/views/search_box.php b/share/pnp/application/views/search_box.php new file mode 100644 index 0000000..b15c212 --- /dev/null +++ b/share/pnp/application/views/search_box.php @@ -0,0 +1,22 @@ +isAuthorizedFor('host_search') ){ ?> + + + +

    +
    + +
    +
    + +
    +
    +

    + + diff --git a/share/pnp/application/views/service_box.php b/share/pnp/application/views/service_box.php new file mode 100644 index 0000000..9ea1671 --- /dev/null +++ b/share/pnp/application/views/service_box.php @@ -0,0 +1,36 @@ +isAuthorizedFor('service_links') ) { ?> +

    +
    + +
    + +session->get('sfilter'); +?> + +
    + " + ?> +
    + +
    +\n"; + $path = pnp::addToUri( array('host' => $host, 'srv' => $service['name']) ); + echo pnp::add_to_basket_icon($host, + $service['name']); + + echo ""; + echo pnp::shorten($service['servicedesc']). + "
    \n"; + echo "\n"; +} +?> +
    +
    +

    + diff --git a/share/pnp/application/views/special_templates_box.php b/share/pnp/application/views/special_templates_box.php new file mode 100644 index 0000000..0c7140c --- /dev/null +++ b/share/pnp/application/views/special_templates_box.php @@ -0,0 +1,31 @@ +templates) && $this->isAuthorizedFor('service_links') ) { ?> +

    +
    + +
    + +session->get('spfilter'); +?> + +
    + " + ?> +
    + +
    +templates as $template){ + echo ""; + $path = pnp::addToUri( array('tpl' => $template) ); + echo "". + pnp::shorten($template). + "
    \n"; + echo "
    \n"; +} +?> +
    +
    +

    + diff --git a/share/pnp/application/views/status_box.php b/share/pnp/application/views/status_box.php new file mode 100644 index 0000000..4745c6b --- /dev/null +++ b/share/pnp/application/views/status_box.php @@ -0,0 +1,19 @@ +

    +
    + +
    +
    +Host: ". + html::anchor('graph'. + "?host=".$lhost, + html::specialchars(pnp::shorten($host))."
    ");?> +Service: " . + html::anchor('graph'. + "?host=".$lhost. + "&srv=".$lservice, + html::specialchars(pnp::shorten($service))."
    ");?> +Last Check: $timet
    "?> +
    +
    +

    + diff --git a/share/pnp/application/views/template.php b/share/pnp/application/views/template.php new file mode 100644 index 0000000..0cce888 --- /dev/null +++ b/share/pnp/application/views/template.php @@ -0,0 +1,221 @@ + + + + + + + +<?php if (isset($this->title)) echo html::specialchars($this->title) ?> + + +theme.'/jquery-ui.css') ?> + + + + + + + + + + + + + + + + diff --git a/share/pnp/application/views/timerange_box.php b/share/pnp/application/views/timerange_box.php new file mode 100644 index 0000000..f7cfd79 --- /dev/null +++ b/share/pnp/application/views/timerange_box.php @@ -0,0 +1,26 @@ +\n"; +echo "

    \n"; +echo Kohana::lang('common.timerange-box-header')."\n"; +echo "
    \n"; +echo "
    \n"; +$start = $this->session->get('start',''); +$end = $this->session->get('end',''); +$path = pnp::addToUri(array('start' => $start,'end' => $end)); +if($start && $end){ + echo "".Kohana::lang('common.timerange-selector-link')."
    \n"; +} +if($start && !$end){ + echo "".Kohana::lang('common.timerange-selector-link')."
    \n"; +} + +$path = pnp::addToUri(array('view' => '', 'start' => '', 'end' => '')); +echo "".Kohana::lang('common.timerange-selector-overview')."
    \n"; + +foreach($this->config->views as $key=>$view){ + $path = pnp::addToUri(array('view' => $key, 'start' => '', 'end' => '')); + echo "".$view['title']."
    \n"; +} +echo "
    \n"; +echo "

    \n"; +?> diff --git a/share/pnp/application/views/timerange_select.php b/share/pnp/application/views/timerange_select.php new file mode 100644 index 0000000..86ee344 --- /dev/null +++ b/share/pnp/application/views/timerange_select.php @@ -0,0 +1,37 @@ +config->conf['use_calendar']){ +$start = $this->session->get('start',''); +$end = $this->session->get('end',''); +?> + + +

    + diff --git a/share/pnp/application/views/widget_graph.sample.php b/share/pnp/application/views/widget_graph.sample.php new file mode 100644 index 0000000..24a0d3d --- /dev/null +++ b/share/pnp/application/views/widget_graph.sample.php @@ -0,0 +1,10 @@ + +
    +
    +Title +
    +
    +Content +
    +

    + diff --git a/share/pnp/application/views/widget_menu.sample.php b/share/pnp/application/views/widget_menu.sample.php new file mode 100644 index 0000000..6201301 --- /dev/null +++ b/share/pnp/application/views/widget_menu.sample.php @@ -0,0 +1,10 @@ + +

    +
    +Title +
    +
    +Content +
    +

    + diff --git a/share/pnp/application/views/zoom.php b/share/pnp/application/views/zoom.php new file mode 100644 index 0000000..78394eb --- /dev/null +++ b/share/pnp/application/views/zoom.php @@ -0,0 +1,129 @@ + + + + +theme.'/jquery-ui.css') ?> + + + + + + + + +

    +
    +
    + +
    +
    +

    data->TIMERANGE['f_start']?> --- data->TIMERANGE['f_end']?>

    +
    +url."\" >
    "; +if(!empty($tpl)){ + echo ""; +}else{ + echo ""; +} +$start_down = $this->data->TIMERANGE['start'] - intval(($this->data->TIMERANGE['end'] - $this->data->TIMERANGE['start']) / 2); +$path = pnp::addToUri( array('start' => $start_down)); +printf("\n", + $path, + "Move Start to ".date($this->config->conf['date_fmt'],$start_down), + url::base()."media/images/go-left.png", + 10 +); + +$start_up = $this->data->TIMERANGE['start'] + intval(($this->data->TIMERANGE['end'] - $this->data->TIMERANGE['start']) / 2); +$path = pnp::addToUri( array('start' => $start_up)); +printf("\n", + $path, + "Move Start to ".date($this->config->conf['date_fmt'],$start_up), + url::base()."media/images/go-right.png", + 60 +); + +$path = pnp::addToUri( array('end' => time() )); +printf("\n", + $path, + "Move End to ".date($this->config->conf['date_fmt'],time()), + url::base()."media/images/go-now.png", + 10 +); + +$end_up = $this->data->TIMERANGE['end'] + intval(($this->data->TIMERANGE['end'] - $this->data->TIMERANGE['start']) / 2); +$path = pnp::addToUri( array('end' => $end_up)); +printf("\n", + $path, + "Move End to ".date($this->config->conf['date_fmt'],$end_up), + url::base()."media/images/go-right.png", + 60 +); + +$end_down = $this->data->TIMERANGE['end'] - intval(($this->data->TIMERANGE['end'] - $this->data->TIMERANGE['start']) / 2); +$path = pnp::addToUri( array('end' => $end_down)); +printf("\n", + $path, + "Move End to ".date($this->config->conf['date_fmt'],$end_down), + url::base()."media/images/go-left.png", + 110 +); + + +?> +
    +
    +
    + + + diff --git a/share/pnp/application/views/zoom_header.php b/share/pnp/application/views/zoom_header.php new file mode 100644 index 0000000..43fb810 --- /dev/null +++ b/share/pnp/application/views/zoom_header.php @@ -0,0 +1,4 @@ +function Gzoom (url) { +GzoomWindow = window.open(url, "PNP4Nagios", "width=,height=,location=no,status=no,resizable=yes,scrollbars=yes"); +GzoomWindow.focus(); +} diff --git a/share/pnp/documents/_media/bulk-npcd.png b/share/pnp/documents/_media/bulk-npcd.png new file mode 100644 index 0000000..00e4c26 Binary files /dev/null and b/share/pnp/documents/_media/bulk-npcd.png differ diff --git a/share/pnp/documents/_media/bulk-npcdmod.png b/share/pnp/documents/_media/bulk-npcdmod.png new file mode 100644 index 0000000..56d04c9 Binary files /dev/null and b/share/pnp/documents/_media/bulk-npcdmod.png differ diff --git a/share/pnp/documents/_media/bulk.png b/share/pnp/documents/_media/bulk.png new file mode 100644 index 0000000..2f7f659 Binary files /dev/null and b/share/pnp/documents/_media/bulk.png differ diff --git a/share/pnp/documents/_media/gearman.png b/share/pnp/documents/_media/gearman.png new file mode 100644 index 0000000..c685a99 Binary files /dev/null and b/share/pnp/documents/_media/gearman.png differ diff --git a/share/pnp/documents/_media/mobile-graphs.png b/share/pnp/documents/_media/mobile-graphs.png new file mode 100644 index 0000000..41797b4 Binary files /dev/null and b/share/pnp/documents/_media/mobile-graphs.png differ diff --git a/share/pnp/documents/_media/mobile-home.png b/share/pnp/documents/_media/mobile-home.png new file mode 100644 index 0000000..23208ea Binary files /dev/null and b/share/pnp/documents/_media/mobile-home.png differ diff --git a/share/pnp/documents/_media/mobile-hostlist.png b/share/pnp/documents/_media/mobile-hostlist.png new file mode 100644 index 0000000..3296211 Binary files /dev/null and b/share/pnp/documents/_media/mobile-hostlist.png differ diff --git a/share/pnp/documents/_media/mobile-loading.png b/share/pnp/documents/_media/mobile-loading.png new file mode 100644 index 0000000..7c106ad Binary files /dev/null and b/share/pnp/documents/_media/mobile-loading.png differ diff --git a/share/pnp/documents/_media/mobile-servicelist.png b/share/pnp/documents/_media/mobile-servicelist.png new file mode 100644 index 0000000..5871918 Binary files /dev/null and b/share/pnp/documents/_media/mobile-servicelist.png differ diff --git a/share/pnp/documents/_media/nagiospowered-72x72.png b/share/pnp/documents/_media/nagiospowered-72x72.png new file mode 100644 index 0000000..038f36d Binary files /dev/null and b/share/pnp/documents/_media/nagiospowered-72x72.png differ diff --git a/share/pnp/documents/_media/pnp-preview-05-08-2009.png b/share/pnp/documents/_media/pnp-preview-05-08-2009.png new file mode 100644 index 0000000..6b9a8d8 Binary files /dev/null and b/share/pnp/documents/_media/pnp-preview-05-08-2009.png differ diff --git a/share/pnp/documents/_media/popup.png b/share/pnp/documents/_media/popup.png new file mode 100644 index 0000000..088cf42 Binary files /dev/null and b/share/pnp/documents/_media/popup.png differ diff --git a/share/pnp/documents/_media/srv_info.png b/share/pnp/documents/_media/srv_info.png new file mode 100644 index 0000000..2f9c153 Binary files /dev/null and b/share/pnp/documents/_media/srv_info.png differ diff --git a/share/pnp/documents/_media/synchronous.png b/share/pnp/documents/_media/synchronous.png new file mode 100644 index 0000000..a5574f4 Binary files /dev/null and b/share/pnp/documents/_media/synchronous.png differ diff --git a/share/pnp/documents/de_DE/about.html b/share/pnp/documents/de_DE/about.html new file mode 100644 index 0000000..6d042ee --- /dev/null +++ b/share/pnp/documents/de_DE/about.html @@ -0,0 +1,186 @@ + + + +

    Über PNP

    +
    + +
    + +

    Anforderungen an Plugins

    +
    + +

    + +PNP benötigt zwingend gültige Performancedaten von Nagios-Plugins. +

    + +

    +Was sind also diese Performancedaten? +

    + +

    +Die Ausgabe eines Nagios Plugins darf bis Nagios 2.x maximal eine Zeile betragen. Diese Ausgabe wird, wenn das Plugin Performancedaten liefert, in zwei Teile zerlegt. Als Trennzeichen dient dabei das Pipe “|” Symbol. +

    + +

    +Beispiel check_icmp : + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +daraus ergibt sich der Output auf der linken Seite des Pipe-Symbols + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0%
    + +

    + +und die Performancedaten + +

    +
      rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +Wie man unschwer erkennt, sind die Performancedaten auf die maschinelle Verarbeitung ausgelegt. Das Format ist in den + Developer Guidelines +festgelegt (einen Auszug davon gibt es an dieser Stelle), es soll aber hier noch einmal kurz erläutert werden. + +

    +
      rta=2.687ms;3000.000;5000.000;0;
    +   |    |  |    |         |     | |
    +   |----|--|----|---------|-----|-|----- * Label 
    +        |--|----|---------|-----|-|----- * Aktueller Wert
    +           |----|---------|-----|-|----- Einheit ( UOM = UNIT of Measurement ) 
    +                |---------|-----|-|----- Warning Schwellwert
    +                          |-----|-|----- Critical Schwellwert 
    +                                |-|----- Minimum Wert 
    +                                  |----- Maximum Wert
    +                                  
    + +

    +Mit * gekennzeichnete Werte müssen vorhanden sein. Alle anderen Werte sind optional. +

    + +

    +Mehrere Datenreihen werden durch Leerzeichen getrennt. Die eigentlichen Daten dürfen also keine Leerzeichen enthalten. Soll das Label Leerzeichen enthalten, so müssen diese in einfache Hochkomma eingeschlossen werden. +

    + +
    + +

    Benötigte Software

    +
    +
      +
    • Perl >= 5.x ohne besondere Module
      +
    • +
    • RRDtool ab 1.x; besser 1.2, aber nicht zwingend.
      +Achtung: wird RRDtool ohne Paket-Manager installiert, fehlen anschließend möglicherweise die dejavu-Fonts. Das äußert sich z.B. durch fehlende Schriften in den Grafiken
      +
    • +
    • PHP >= 5.1.6 für das Webfrontend basierend auf Kohana
      +
    • +
    • Nagios >= 2.x oder Icinga
      +
    • +
    • für Kohana muss außerdem das Modul “mod_rewrite” in der Web-Server-Konfiguration aktiviert sein. Einzelheiten sind in der Web-Server-Dokumentation der entsprechenden Distribution nachzulesen.
      +
    • +
    + +
    + +

    Lizenz

    +
    + +

    + +PNP ist unter der GPL 2 lizensiert. +

    + +
    + +

    Download

    +
    + +

    + +Die Entwicklung von PNP wird auf Sourceforge.Net organisiert. PNP ist dort unter dem Projektnamen “PNP4Nagios” registriert. +

    + +

    +Die jeweils aktuelle (stabile) Version findet ihr im Downloadbereich. +

    + +

    +Wer noch aktueller sein möchte, kann auch die jeweils letzte Entwickler-Version benutzen. +

    + +

    +Mit der Version 0.6.x wurde von SVN auf GIT zum Verwalten des Sourcecodes gewechselt. +

    + +

    +Die aktuelle Entwicklung ist jederzeit unter https://github.com/lingej/pnp4nagios einzusehen. Beim Klicken auf pnp4nagios-head.tar.gz wird ein Archiv mit der letzten Version heruntergeladen. +

    + +
    + +

    Support

    +
    + +

    + +VOR dem Stellen von Support-Anfragen sollte sichergestellt werden, dass die unter http://docs.pnp4nagios.org/de/pnp-0.6/verify genannten Punkte geprüft wurden. +

    + +

    +Die Entwickler und Helfer sind im Nagios-Portal unter http://www.nagios-portal.org vertreten. +Dort gibt es einen eigenen Bereich zum Thema PNP.
    + +Bei Support-Anfragen bitte das Betriebssystem und die PNP-Version angeben. Außerdem ist es wichtig, ob PNP aus den Sourcen erstellt oder ein vorgefertigtes Paket verwendet wurde. +

    + +

    +Erfolgreich gelöste Probleme bitte mit einem [solved] in der Betreffzeile des ersten Beitrags kennzeichnen. Auf diese Weise erleichtern wir anderen Benutzern das Finden von Lösungen zu einem Problem. +

    + +

    +Weiterhin können die Mailinglisten auf Sourceforge verwendet werden. Dort ist es jedoch üblich, Fragen auf Englisch zu stellen. +

    + +

    +pnp4nagios-users: Die Users-Liste für allgemeine Fragen zur Konfiguration. +

    + +

    +pnp4nagios-devel: Die Devel-Liste für Anregungen und Fehler Reports. +

    + +

    +pnp4nagios-checkins: Auf der Checkins-Liste werden Änderungen im SVN-Repository automatisch veröffentlicht. +

    + +
    + +

    Datenhaltung

    +
    + +

    + +Die Performance-Daten werden mit Hilfe von RRDtool in sogenannten Round-Robin-Datenbanken gespeichert, die wie ein Ringpuffer funktionieren. Das bedeutet, dass nach einer gewissen Zeit die ältesten Daten “hinten” herausfallen und “vorne” durch neue ersetzt werden. +

    + +

    +Verschiedene Zeitintervalle innerhalb der Datei sorgen für unterschiedliche Auflösungen. In der Standardeinstellung können die Daten für die letzten zwei Tage im Minutenabstand abgelegt werden, für zehn Tage im 5-Minutenabstand, für 90 Tage im 30-Minutenabstand und für 4 Jahre im 6-Stundenabstand. Die Vergrößerung des Intervalls bewirkt, dass auch die Daten über das jeweils größere Intervall hinweg gemittelt werden. Das führt automatisch dazu, dass Spitzen nicht mehr so deutlich zu sehen sind. Das ist kein Fehler von PNP, sondern eine Eigenheit von RRDtool. Dazu gibt es auch einen Artikel im Linux-Magazin. +

    + +

    +Durch die Speicherung in diesem Format ändert sich die Dateigröße nach dem Anlegen nicht mehr. Pro Datenreihe werden ca. 400 KB benötigt. +

    + +

    +Zurück zur Übersicht | PNP-Modi + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/advanced.html b/share/pnp/documents/de_DE/advanced.html new file mode 100644 index 0000000..5293e34 --- /dev/null +++ b/share/pnp/documents/de_DE/advanced.html @@ -0,0 +1,81 @@ + + + +

    Advanced

    +
    + +
    + +

    Verteilte Systeme

    +
    + +

    +Ist Nagios als verteiltes System implementiert, stellt sich die Frage, wo PNP installiert wird. +

    + +

    +Rein technisch ist diese Frage nicht wichtig. PNP kann auf den Slaves sowie auf dem Master-Server installiert sein. Oder nur auf dem Master? +

    + +

    +Wird PNP auf dem Master betrieben, ist jedoch bei der Übergabe der Daten via send_nsca von den Slave-Servern zum Master darauf zu achten, dass auch die Performance-Daten übergeben werden. Weiterhin kommt auf dem Master oft nicht das Original-Check-Command zum Einsatz. +

    + +

    +Damit nun aber PNP auf dem Master noch erkennen kann, welches Check-Command auf den Slaves die Daten ermittelt hat, reagiert process_perfdata.pl auf ein zusätzliches Feld am Ende der Performance-Daten. +

    +
    OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;; [check_icmp]
    + +

    +Findet PNP am Ende der Performance Daten einen in eckigen Klammern eingeschlossenen Text, so wird dieser als Check-Command und somit als PNP-Template verwendet. +

    + +

    +Die Nagios-Dokumentation zu diesem Thema ist hier zu finden. Das in der Doku verwendete Command ist leicht anzupassen. +

    + +

    +Aus +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$'
    +	}
    +
    + +

    +wird +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$ | $SERVICEPERFDATA$ [$SERVICECHECKCOMMAND$]'
    +	}
    +
    + +
    + +

    Das check_multi-Plugin

    +
    + +

    + +Das Plugin check_multi ist eines der ersten Plugins, das die Funktionen von Nagios 3.0 richtig ausschöpft. Check_Multi ist in der Lage, mehrere Nagios-Plugins auszuführen, aber für Nagios als einen Service darzustellen. Die Ausgabe von check_multi erfolgt über mehrere Zeilen, um die Masse an Informationen wieder darstellen zu können. +

    + +

    +Daraus ergaben sich jedoch einige Schwierigkeiten für PNP. PNP muss aus den Performance-Daten wieder die Daten der einzelnen Plugins ermitteln können. Zusammen mit Matthias Flacke, dem Entwickler von check_multi, haben wir jedoch recht schnell eine Möglichkeit gefunden, die Daten wieder sauber den einzelnen Plugins zuzuordnen. +

    + +

    + +

    + +

    +Zurück zur Übersicht | rrdcached-Unterstützung + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/config.html b/share/pnp/documents/de_DE/config.html new file mode 100644 index 0000000..8160faa --- /dev/null +++ b/share/pnp/documents/de_DE/config.html @@ -0,0 +1,423 @@ + + + +

    Konfiguration

    +
    + +

    + +Im Folgenden wird die Konfiguration der bereits erwähnten Arten der Performance-Daten Verarbeitung genauer erklärt. +

    + +

    +Die bevorzugte Methode der PNP-Entwickler ist der “Bulk Mode mit NPCD und npcdmod”. +

    + +
    + +

    Synchronous Mode

    +
    + +

    + +Der Synchronous-Mode ist die einfachste Art, den Datensammler process_perfdata.pl in Nagios zu integrieren. Hierbei wird bei jedem Ereignis ein gesondertes Command process-service-perfdata (bzw. process-host-perfdata) ausgeführt. +

    + +

    +Grundsätzlich ist in der nagios.cfg die Verarbeitung der Performance-Daten zu aktivieren. Bitte beachten Sie, dass diese Direktive wahrscheinlich bereits in der Konfigurationsdatei enthalten ist (Default ist “0”). + +

    +
     process_performance_data=1
    + +

    + +Für jeden Host und jeden Service, für den KEINE Performance-Daten verarbeitet werden sollen, ist die Verarbeitung der Performance-Daten explizit auszuschalten. +

    +
    +define service {
    +   ...
    +   process_perf_data 0
    +   ...
    +}
    +
    + +

    +Weiterhin ist es ab Nagios 3.x möglich, in der nagios.cfg das Exportieren der Environment-Variablen zu deaktivieren. Diese sind jedoch für den Synchronous-Mode zwingend erforderlich. Daher muss + +

    +
    enable_environment_macros=1
    + +

    + +ebenfalls in der nagios.cfg gesetzt sein. +

    + +

    +Zusätzlich wird das Kommando zum Verarbeiten der Performance-Daten in der nagios.cfg angegeben. + +

    +
     service_perfdata_command=process-service-perfdata
    + +

    + +Ab Nagios 3.x ist es durchaus sinnvoll, auch die Verarbeitung der Performance-Daten für Hosts einzuschalten. Nagios 3 führt durch die geänderte Hostcheck-Logik nun auch die Prüfung der Hosts regelmäßig aus. + +

    +
     host_perfdata_command=process-host-perfdata
    + +

    + +Die referenzierten Commands müssen natürlich auch Nagios bekannt gegeben werden. Wie man sieht, sind für den Aufruf von process_perfdata.pl so gut wie keine Optionen nötig. Einzig bei Performance-Daten der Host-Checks ist die Option -d ( DATATYPE ) nötig. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command {
    +       command_name    process-service-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +}
    +
    +define command {
    +       command_name    process-host-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl -d HOSTPERFDATA
    +}
    +
    + +

    +HINWEIS: process_perfdata.pl kann nicht unter Kontrolle des ePN ( embedded Perl Nagios ) gestartet werden. Daher wird das Script explizit mit /usr/bin/perl aufgerufen. Wird ePN nicht verwendet oder wird Nagios 3.x verwendet, kann auf die Angabe von /usr/bin/perl verzichtet werden. +

    + +

    +zurück zur Übersicht | Funktion prüfen +

    + +
    + +

    Bulk Mode

    +
    + +

    + +Der Bulk-Mode ist etwas komplizierter als der Synchronous-Mode, reduziert die Last auf dem Nagios Server jedoch merklich, da nun nicht mehr für jeden Service bzw. Host zusätzlich der Datensammler process_perfdata.pl gestartet werden muss. +

    + +

    +Im Bulk-Mode schreibt Nagios die Daten in einem definierten Format in eine temporäre Datei. Diese Datei wiederum wird periodisch von process_perfdata.pl verarbeitet. Um den Start und den Intervall kümmert sich dabei Nagios selbst. +

    + +

    +Auch hier muss die Verarbeitung der Performance-Daten in der nagios.cfg eingeschaltet werden. + +

    +
     process_performance_data=1
    + +

    + +Zusätzlich werden einige neue Parameter benötigt. +

    +
    +#
    +# Service Performance-Daten
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# Host Performance-Daten ab Nagios 3.x
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    +Achtung: Die Template-Definitionen weichen von denen in der Original-nagios.cfg ab! +

    + +

    +Die Parameter und deren Bedeutung im Einzelnen: + +

    +
      +
    • service_perfdata_file Der Pfad zur temporären Datei, in der die Daten gesammelt werden sollen.
      +
    • +
    • service_perfdata_file_template Das Format der temporären Datei. Hier werden die Daten über Nagios-Macros definiert.
      +
    • +
    • service_perfdata_file_mode Die Option “a” definiert, dass an die Datei angehangen werden soll.
      +
    • +
    • service_perfdata_file_processing_interval Das Intervall beträgt 15 Sekunden
      +
    • +
    • service_perfdata_file_processing_command das Command, das im definierten Intervall aufgerufen werden soll.
      +
    • +
    + +

    + +Die verwendeten Commands müssen Nagios wiederum bekannt gegeben werden. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/service-perfdata
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/host-perfdata
    +}
    +
    +
    + +
    +

    HINWEIS:

    +
    Da process_perfdata.pl nun mehr Daten zu verarbeiten hat als im Default Mode, kommt es natürlich auch zu längeren Laufzeiten. Daher ist der TIMEOUT Wert in der etc/process_perfdata.cfg zu überprüfen und ggf. anzupassen.
    +
    + +
    + +

    +zurück zur Übersicht | Funktion prüfen +

    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + +Die Konfiguration ist identisch mit dem “Bulk Mode”, einzig das verwendete Command ist leicht abgewandelt. +

    + +

    +Auch hier muss die Verarbeitung der Performance-Daten in der nagios.cfg eingeschaltet werden. + +

    +
     process_performance_data=1
    + +

    + +Zusätzlich werden einige neue Parameter benötigt. +

    +
    +#
    +# Service Performance-Daten
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# Host Performance-Daten ab Nagios 3.x
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    +Achtung: Die Template-Definitionen weichen von denen in der Original-nagios.cfg ab! +

    + +

    +Die Parameter und deren Bedeutung im Einzelnen: + +

    +
      +
    • service_perfdata_file Der Pfad zur temporären Datei, in der die Daten gesammelt werden sollen.
      +
    • +
    • service_perfdata_file_template Das Format der temporären Datei. Hier werden die Daten über Nagios-Macros definiert.
      +
    • +
    • service_perfdata_file_mode Die Option “a” definiert, dass an die Datei angehangen werden soll.
      +
    • +
    • service_perfdata_file_processing_interval Das Intervall beträgt 15 Sekunden
      +
    • +
    • service_perfdata_file_processing_command das Command, das im definierten Intervall aufgerufen werden soll.
      +
    • +
    + +

    + +Die verwendeten Commands müssen Nagios wiederum bekannt gegeben werden. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
    +}
    +
    + +

    +Durch die Kommandos wird immer nach Ablauf des über service_perfdata_file_processing_interval eingestellten Intervalls die Datei service-perfdata nach var/spool/ verschoben. Dabei wird das Nagios-Macro $TIMET$ verwendet, an den Dateinamen angehängt, um zu verhindern, dass alte Dateien ungewollt überschrieben werden. Das Macro $TIMET$ enthält den aktuellen Zeitstempel in Unix-Time-Format ( Sekunden seit 1.1.1970 ). +

    + +

    +Somit sammeln sich Dateien im Verzeichnis /usr/local/pnp4nagios/var/spool/, die nun mit Hilfe des NPCD verarbeitet werden. +

    + +

    +NPCD überwacht das Spool-Verzeichnis und übergibt wiederum alle gefundenen Dateien an process_perfdata.pl. Damit ist die Verarbeitung der Performancedaten komplett von Nagios entkoppelt. Wir müssen nur noch den NPCD starten. + +

    +
     /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +Die Option -d veranlasst NPCD im Hintergund als Daemon seinen Dienst zu verrichten. +

    + +

    +Das Init Script für den NPCD wir während der Installation über “make install-init” installiert und kann somit auch für den Start verwendet werden. + +

    +
     /etc/init.d/npcd start
    + +

    + +In der Config-Datei des NPCD, der npcd.cfg, ist vor dem ersten Start zu prüfen, ob die Pfade zum Spool-Verzeichnis und zu process_perfdata.pl richtig gesetzt sind. +

    + +

    +Weitere Informationen zu NPCD findet ihr hier. +

    + +
    + +

    Bulk Mode with NPCD und npcdmod

    +
    + +

    + +Achtung +Beginnend mit Nagios 4 haben sich die internen Strukturen geändert, so dass der Start des Moduls fehlschlägt. Bisher gibt es keine Pläne, Nagios 4 zu unterstützen. Bitte wählen Sie einen der anderen Modi. +

    + +

    + Bei diesem Modus kommt das Eventbroker-Modul npcdmod.o zu Einsatz. Der Datenfluss ist jedoch identisch zum “Bulk Mode mit NPCD”. Die internen Perfdata-Routinen von Nagios, die über die “*_perf_data_*” Optionen in der nagios.cfg konfiguriert werden, kommen NICHT mehr zu Einsatz. Das Modul npcdmod.o kümmert sich um die für PNP nötige Aufbereitung der Daten. +

    + +

    +Vorteil: +

    +
      +
    • Die Perfdata-Routinen innerhalb von Nagios stehen wieder für andere Addons zur Verfügung.
      +
    • +
    • Die Konfiguration reduziert sich.
      +
    • +
    • Die bevorzugte Methode der PNP-Entwickler.
      +
    • +
    + +

    + +Anpassung in der nagios.cfg: +

    +
    +process_performance_data=1
    +broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +
    + +

    +Alle anderen auf dieser Seite gezeigten Optionen dürfen für diesen Modus NICHT mehr verwendet werden. +

    + +

    +Achtung: Wichtig sind in diesem Zusammenhang auch die event_broker_options bei einem von -1 abweichenden Wert. Für PNP müssen die Bits 2 und 3 gesetzt sein (0b01100; siehe auch http://www.nagios-wiki.de/nagios/ndo/eventbroker_optionen). +

    + +

    +Nach dem Neustart von Nagios werden Informationen zum Ladevorgang des Moduls protokolliert. +

    + +

    +Auszug aus den nagios.log + +

    +
    +[1277545053] npcdmod: Copyright (c) 2008-2009 Hendrik Baecker (andurin@process-zero.de) - http://www.pnp4nagios.org
    +[1277545053] npcdmod: /usr/local/pnp4nagios/etc/npcd.cfg initialized
    +[1277545053] npcdmod: spool_dir = '/usr/local/pnp4nagios/var/spool/'.
    +[1277545053] npcdmod: perfdata file '/usr/local/pnp4nagios/var/perfdata.dump'.
    +[1277545053] npcdmod: Ready to run to have some fun!
    +[1277545053] Event broker module '/usr/local/pnp4nagios/lib/npcdmod.o' initialized successfully.
    +
    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +PNP4Nagios kann seit Version 0.6.12 als Gearman-Worker betrieben werden. So sind große verteilte Nagios-Umgebungen auf Basis von mod_gearman realisierbar. Außerdem kann man dadurch Nagios und PNP4Nagios auf unterschiedliche Rechner verteilen. +

    + +

    +Benötigt wird eine fertig eingerichtete mod_gearman Installation wie von Sven Nierlein unter http://labs.consol.de/lang/en/nagios/mod-gearman/ beschrieben. +

    + +

    +In etc/process_perfdata.cfg gibt es einen gearman-Abschnitt: +

    +
     PREFORK = 1
    + GEARMAN_HOST = localhost:4730
    + REQUESTS_PER_CHILD = 10000
    + ENCRYPTION = 1
    + KEY = should_be_changed
    + #KEY_FILE = /usr/local/pnp4nagios/etc/secret.key
    + 
    + +

    +Dort ist mit PREFORK = <n> die Anzahl der zu startenden Kindprozessen anzugeben. +

    + +

    +GEARMAN_HOST = <host>:<port> definiert Rechner und Port, auf dem der gearman-Daemon die Daten bereitstellt. +Über REQUESTS_PER_CHILD = <n> kann die maximal zu verarbeitende Anzahl von Anforderungen pro Prozess eingestellt werden. +

    + +

    +ENCRYPTION = <1|0> stellt ein, ob Verschlüsselung benutzt werden soll. Die Standardeinstellung ist eine aktivierte Verschlüsselung (“1”) und das sollte nur in Ausnahmefällen verändert werden. +Dabei kann entweder über KEY = <Schlüssel> der zu benutzende Schlüssel definiert oder per KEY_FILE = <Schlüsseldatei> der Standort einer Schlüsseldatei angegeben werden. +

    + +

    + +/etc/init.d/pnp_gearman_worker enthält Verweise auf die Perl-Prozedur process_perfdata.pl sowie die Konfigurationsdatei process_perfdata.cfg. +

    + +

    + +Nach dem Start des PNP-Daemons per + +

    +
     /etc/init.d/pnp_gearman_worker start
    + +

    + +werden die Performance-Daten verarbeitet, die über den gearmand-Daemon auf dem Nagios-Rechner zur Verfügung gestellt werden. +

    + +

    +zurück zur Übersicht | Funktion prüfen + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/doc_complete.html b/share/pnp/documents/de_DE/doc_complete.html new file mode 100644 index 0000000..d1ca754 --- /dev/null +++ b/share/pnp/documents/de_DE/doc_complete.html @@ -0,0 +1,3369 @@ + + +
    + + + +

    Neues in PNP 0.6.x

    +
    + +

    +PNP 0.6.x Preview +

    + +

    +Die Arbeit an der Version 0.6.x ist in vollem Gange. +

    + +

    +Mit Version 0.6.x steigen wir von Subversion auf GIT um. Der Sourcecode ist bereits auf Sourceforge erhältlich. +

    + +

    +http://pnp4nagios.git.sourceforge.net +

    + +

    + +Bisher umgesetzte Funktionen: + +

    +
      +
    • Webfrontend basiert auf Kohana
      +
    • +
    • Webfrontend basiert auf jQuery Themes
      +
    • +
    • Javascript-Funktionen über jQuery Plugins
      +
    • +
    • process_perfdata.pl wird in der Lage sein, pro Datenreihe eine eigene RRD-Datenbank zu verwenden.
      +
    • +
    • Installer weiter verbessert. Angabe von Directory-Layouts über --with-layout
      +
    • +
    • RRDtool-Fehler werden als Bild dargestellt. Keine fehlenden Bilder mehr.
      +
    • +
    • PNP-Templates können keine internen Variablen mehr überschreiben.
      +
    • +
    • PNP-Templates der Version 0.4.x können weiter verwendet werden.
      +
    • +
    • PDF-Funktionen neu umgesetzt.
      +
    • +
    • Template default.php optimiert.
      +
    • +
    • Export aus den RRD-Datenbanken im XML,CSV und JSON Format über die RRDtool “xport” Funktion.
      +
    • +
    • Page-Funktionen neu umgesetzt.
      +
    • +
    • Fehlerseiten verweisen auf online FAQ-Artikel.
      +
    • +
    • Mouseover Popup im Nagios-Frontend über jQuery.clueTip Plugin
      +
    • +
    • Volle Unterstützung des rrdcached.
      +
    • +
    + +

    + +zurück zur Übersicht | Anforderungen + +

    + +
    + +
    +
    + + + +

    Über PNP

    +
    + +
    + +

    Anforderungen an Plugins

    +
    + +

    + +PNP benötigt zwingend gültige Performancedaten von Nagios-Plugins. +

    + +

    +Was sind also diese Performancedaten? +

    + +

    +Die Ausgabe eines Nagios Plugins darf bis Nagios 2.x maximal eine Zeile betragen. Diese Ausgabe wird, wenn das Plugin Performancedaten liefert, in zwei Teile zerlegt. Als Trennzeichen dient dabei das Pipe “|” Symbol. +

    + +

    +Beispiel check_icmp : + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +daraus ergibt sich der Output auf der linken Seite des Pipe-Symbols + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0%
    + +

    + +und die Performancedaten + +

    +
      rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +Wie man unschwer erkennt, sind die Performancedaten auf die maschinelle Verarbeitung ausgelegt. Das Format ist in den + Developer Guidelines +festgelegt (einen Auszug davon gibt es an dieser Stelle), es soll aber hier noch einmal kurz erläutert werden. + +

    +
      rta=2.687ms;3000.000;5000.000;0;
    +   |    |  |    |         |     | |
    +   |----|--|----|---------|-----|-|----- * Label 
    +        |--|----|---------|-----|-|----- * Aktueller Wert
    +           |----|---------|-----|-|----- Einheit ( UOM = UNIT of Measurement ) 
    +                |---------|-----|-|----- Warning Schwellwert
    +                          |-----|-|----- Critical Schwellwert 
    +                                |-|----- Minimum Wert 
    +                                  |----- Maximum Wert
    +                                  
    + +

    +Mit * gekennzeichnete Werte müssen vorhanden sein. Alle anderen Werte sind optional. +

    + +

    +Mehrere Datenreihen werden durch Leerzeichen getrennt. Die eigentlichen Daten dürfen also keine Leerzeichen enthalten. Soll das Label Leerzeichen enthalten, so müssen diese in einfache Hochkomma eingeschlossen werden. +

    + +
    + +

    Benötigte Software

    +
    +
      +
    • Perl >= 5.x ohne besondere Module
      +
    • +
    • RRDtool ab 1.x; besser 1.2, aber nicht zwingend.
      +Achtung: wird RRDtool ohne Paket-Manager installiert, fehlen anschließend möglicherweise die dejavu-Fonts. Das äußert sich z.B. durch fehlende Schriften in den Grafiken
      +
    • +
    • PHP >= 5.1.6 für das Webfrontend basierend auf Kohana
      +
    • +
    • Nagios >= 2.x oder Icinga
      +
    • +
    • für Kohana muss außerdem das Modul “mod_rewrite” in der Web-Server-Konfiguration aktiviert sein. Einzelheiten sind in der Web-Server-Dokumentation der entsprechenden Distribution nachzulesen.
      +
    • +
    + +
    + +

    Lizenz

    +
    + +

    + +PNP ist unter der GPL 2 lizensiert. +

    + +
    + +

    Download

    +
    + +

    + +Die Entwicklung von PNP wird auf Sourceforge.Net organisiert. PNP ist dort unter dem Projektnamen “PNP4Nagios” registriert. +

    + +

    +Die jeweils aktuelle (stabile) Version findet ihr im Downloadbereich. +

    + +

    +Wer noch aktueller sein möchte, kann auch die jeweils letzte Entwickler-Version benutzen. +

    + +

    +Mit der Version 0.6.x wurde von SVN auf GIT zum Verwalten des Sourcecodes gewechselt. +

    + +

    +Die aktuelle Entwicklung ist jederzeit unter https://github.com/lingej/pnp4nagios einzusehen. Beim Klicken auf pnp4nagios-head.tar.gz wird ein Archiv mit der letzten Version heruntergeladen. +

    + +
    + +

    Support

    +
    + +

    + +VOR dem Stellen von Support-Anfragen sollte sichergestellt werden, dass die unter http://docs.pnp4nagios.org/de/pnp-0.6/verify genannten Punkte geprüft wurden. +

    + +

    +Die Entwickler und Helfer sind im Nagios-Portal unter http://www.nagios-portal.org vertreten. +Dort gibt es einen eigenen Bereich zum Thema PNP.
    + +Bei Support-Anfragen bitte das Betriebssystem und die PNP-Version angeben. Außerdem ist es wichtig, ob PNP aus den Sourcen erstellt oder ein vorgefertigtes Paket verwendet wurde. +

    + +

    +Erfolgreich gelöste Probleme bitte mit einem [solved] in der Betreffzeile des ersten Beitrags kennzeichnen. Auf diese Weise erleichtern wir anderen Benutzern das Finden von Lösungen zu einem Problem. +

    + +

    +Weiterhin können die Mailinglisten auf Sourceforge verwendet werden. Dort ist es jedoch üblich, Fragen auf Englisch zu stellen. +

    + +

    +pnp4nagios-users: Die Users-Liste für allgemeine Fragen zur Konfiguration. +

    + +

    +pnp4nagios-devel: Die Devel-Liste für Anregungen und Fehler Reports. +

    + +

    +pnp4nagios-checkins: Auf der Checkins-Liste werden Änderungen im SVN-Repository automatisch veröffentlicht. +

    + +
    + +

    Datenhaltung

    +
    + +

    + +Die Performance-Daten werden mit Hilfe von RRDtool in sogenannten Round-Robin-Datenbanken gespeichert, die wie ein Ringpuffer funktionieren. Das bedeutet, dass nach einer gewissen Zeit die ältesten Daten “hinten” herausfallen und “vorne” durch neue ersetzt werden. +

    + +

    +Verschiedene Zeitintervalle innerhalb der Datei sorgen für unterschiedliche Auflösungen. In der Standardeinstellung können die Daten für die letzten zwei Tage im Minutenabstand abgelegt werden, für zehn Tage im 5-Minutenabstand, für 90 Tage im 30-Minutenabstand und für 4 Jahre im 6-Stundenabstand. Die Vergrößerung des Intervalls bewirkt, dass auch die Daten über das jeweils größere Intervall hinweg gemittelt werden. Das führt automatisch dazu, dass Spitzen nicht mehr so deutlich zu sehen sind. Das ist kein Fehler von PNP, sondern eine Eigenheit von RRDtool. Dazu gibt es auch einen Artikel im Linux-Magazin. +

    + +

    +Durch die Speicherung in diesem Format ändert sich die Dateigröße nach dem Anlegen nicht mehr. Pro Datenreihe werden ca. 400 KB benötigt. +

    + +

    +Zurück zur Übersicht | PNP-Modi + +

    + +
    + +
    +
    + + + +

    Die Kunst Daten zu sammeln

    +
    + +

    + +PNP unterstützt mehrere Arten, die Performance-Daten zu verarbeiten. Die einzelnen Modi unterscheiden sich durch ihre Komplexität und die zu erwartende Performance. +

    + +

    +Das folgende Bild zeigt die Verbindungen zwischen Nagios, PNP und RRDtool +

    + +

    +Nagios führt für jeden Host- und jeden Service, dessen Performance-Daten gesammelt werden sollen, einen Befehl aus. Abhängig vom gewählten Modus werden die Daten entweder direkt an ein Perl-Script übergeben oder in temporäre Dateien geschrieben und später verarbeitet. process_perfdata.pl legt die Datei in XML-Dateien ab und speichert sie mit Hilfe von RRDtool in RRD-Dateien.
    + +

    + +

    +Bevor Ihr euch auf einen Modus festlegt, lest euch alles durch und entscheidet selbst, welcher Weg für eure Installation der Beste ist. +

    + +
    + +

    Die Modi im Vergleich

    +
    + +
    + +

    Synchronous Mode

    +
    + +

    + +Der “Sync Mode” ist der einfachste und am leichtesten einzurichten. Nagios ruft für jeden Service (bzw. Host) zusätzlich das Perl-Script process_perfdata.pl auf, um die Daten zu verarbeiten. +

    + +

    +Der sync-Mode funktioniert sehr gut bis ca. 1000 Services in einem Intervall von 5 Minuten. +Dieser Modus belastet aber auch Nagios am meisten, daher ist es auch in kleinen Installationen ratsam, die weiteren Modi zu beachten. +

    + +
    + +

    Bulk Mode

    +
    + +

    +Im Bulk-Mode schreibt Nagios die benötigten Daten in eine temporäre Datei. Nach Ablauf einer definierten Zeit wird die Datei an einem Stück abgearbeitet und gelöscht. +

    + +

    +Die Anzahl der Aufrufe von process_perfdata.pl reduziert sich um ein Vielfaches. Abhängig von der Zeit und den gesammelten Daten werden wesentlich weniger Systemaufrufe ausgeführt. Dafür läuft process_perfdata.pl länger. +

    + +

    +Hinweis +Bei diesem Modus sollte man die Laufzeit von process_perfdata.pl im Auge behalten. So lange, wie process_perfdata.pl zum Verarbeiten der Daten benötigt, so lange kann Nagios keine Checks ausführen. +

    + +

    +Auszug aus var/perfdata.log: + +

    +
    +2007-10-18 12:05:01 [21138] 71 Lines processed
    +2007-10-18 12:05:01 [21138] .../spool/service-perfdata-1192701894-PID-21138 deleted
    +2007-10-18 12:05:01 [21138] PNP exiting (runtime 0.060969s) ...
    +
    + +

    +71 Zeilen wurden in 0,06 Sekunden verarbeitet. Das ist das Datenvolumen bei ca. 2000 Services und der Verarbeitung im 10-Sekunden-Intervall. Wir haben Nagios also genau für 0.06 Sekunden blockiert. +

    + +
    + +

    Bulk Mode mit NPCD

    +
    + +

    + +Dies ist aus Nagios-Sicht die sauberste Art der Verarbeitung. Nagios wird nicht blockiert. +

    + +

    +Nagios benutzt wieder eine temporäre Datei, um die Daten zu speichern, und führt nach Ablauf der Zeit wieder ein Command aus. Jedoch wird die Datei nicht sofort von Process_perfdata.pl verarbeitet, sondern in ein spool-Verzeichnis verschoben. Da das Verschieben einer Datei im gleichen Filesystem so gut wie keine Zeit beansprucht, ist Nagios sofort wieder in der Lage, wichtige Arbeiten auszuführen. +

    + +

    +Der NPCD ( Nagios Performance C Daemon ) überwacht nun das Verzeichnis auf neue Dateien und übergibt diese an process_perfdata.pl. Die Verarbeitung der Performancedaten ist also komplett von Nagios entkoppelt. NPCD wiederum ist in der Lage, zum Verarbeiten der Daten mehrere Threads zu starten. +

    + +
    + +

    Bulk Mode mit npcdmod

    +
    + +

    + +Achtung +Beginnend mit Nagios 4 haben sich die internen Strukturen geändert, so dass der Start des Moduls fehlschlägt. Bisher gibt es keine Pläne Nagios 4 zu unterstützen. Bitte wählen Sie einen der anderen Modi. +

    + +

    +In diesem Szenario kommt npcdmod.o, ein NEB-Modul, zum Einsatz. +Diese Modul reduziert die Konfiguration des “Bulk Mode mit NPCD” auf zwei Zeilen in der nagios.cfg. +

    + +

    +Dieser Modus ist gleichzusetzen mit dem “Bulk Mode mit NPCD”. Es ist auch genau der gleiche Ablauf und die gleiche Performance. +

    + +
    + +

    Gearman Mode

    +
    + +

    + +

    + +

    +PNP4Nagios kann seit Version 0.6.12 als Gearman Worker betrieben werden. So sind große verteilte Nagios Umgebungen auf Basis von mod_gearman realisierbar. +

    + +

    +Benötigt wird eine fertig eingerichtete mod_gearman Installation wie von Sven Nierlein unter http://labs.consol.de/lang/en/nagios/mod-gearman/ beschrieben. +

    + +
    + +

    Die Entscheidung

    +
    + +

    + +Welchen der beschriebenen Wege ihr verwendet, hängt also stark von der Größe der Nagios-Installation ab. +

    + +

    +Die verwendeten Begriffe werden euch aber in der Dokumentation immer wieder über den Weg laufen. +

    + +

    +Zurück zur Übersicht | Installation + +

    + +
    + +
    +
    + + + +

    Upgrade auf Version 0.6.x

    +
    + +

    + +Das Web-Frontend ist komplett neu geschrieben worden und basiert nun auf dem PHP MVC Framework Kohana. Somit ergeben sich grundlegend andere Abhängigkeiten, die dringend vor der Installation geprüft werden müssen. +

    + +

    +Anmerkung: Ein Upgrade läuft zuerst wie eine Neuinstallation. Anschließend sind einige Anpassungen durchzuführen, die weiter unten beschrieben sind. +

    + +

    +PNP 0.4.x wurde ohne weitere Angabe von Optionen beim Aufruf von ./configure unterhalb einer Nagios-Installation unter /usr/local/nagios installiert. +

    + +

    +PNP 0.6.x wird bei Angabe keiner weiteren Optionen unter /usr/local/pnp4nagios installiert, ist also wie Nagios als eigenständige Applikation zu sehen. +

    + +

    +Anmerkung: Es reicht aus, die *.rrd-Dateien vom alten ins neue Verzeichnis zu kopieren. Sie enthalten die eigentlichen Daten. Die *.xml-Dateien werden jedes Mal neu angelegt, wenn Performance-Daten verarbeitet werden, denn sie enthalten lediglich Meta-Informationen. Außerdem hat sich die interne Struktur geändert, so dass sie sowieso nicht nutzbar sind. +

    + +
    + +

    Vergleich der Struktur

    +
    + +

    + +Summary einer Installation von PNP 0.4.14 +

    +
    +./configure
    +...
    +*** Configuration summary for pnp 0.4.14 05-02-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/nagios
    +  HTML Dir:                         /usr/local/nagios/share/pnp
    +  Config Dir:                       /usr/local/nagios/etc/pnp
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/nagios/share/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/nagios/var/spool/perfdata/
    +
    + +

    +Summary einer Installation von 0.6.0 +

    +
    +./configure
    +...
    +*** Configuration summary for pnp4nagios-0.6.0 07-30-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    + +

    +Aus diesen Infos ergeben sich die zu ändernden Parameter und somit die Upgrade-Strategie. +

    + +
    + +

    Anpassungen

    +
    + +

    + +Die Vorlagen der action_url-Definitionen haben sich verändert. Statt ”/nagios/pnp” ist ”/pnp4nagios” einzutragen und statt “index.php” wird nun “graph” benutzt +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    +Ähnliches gilt für die Preview-Popup-Funktion +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    + +Achtung: Es ist kein Fehler, dass die Zeichenketten vor und nach “class” jeweils nur ein Apostroph enthalten. +

    + +

    +Anders als in der 0.4.x Dokumentation vermerkt gelten die Templates für Nagios 2.x und 3.x. Der einzige Unterschied besteht darin, dass die action_url-Direktive in Nagios 2.x nicht in der Service-Definition, sondern in eigenen serviceextinfo-Definitionen verfügbar ist. +

    + +

    +Innerhalb der PHP-Dateien im templates-Verzeichnis müssen alle Variablen vor der ersten Benutzung initialisiert werden, z.B. +

    +
    $lower = ""
    + +

    + +Das gilt auch für Variablen, an die früher “angehängt” werden konnte, ohne sie vorher zu initialisieren. Daher wird aus + +

    +
    foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +nun + +

    +
    +$def[1] = "";
    +foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    +
    + +Konstanten in Template-Dateien funktionieren nicht mehr, so dass diese in Variablen umzuwandeln sind. Aus +

    +
    define("_WARNRULE", '#FFFF00');
    + +

    +wird dann z.B. +

    +
     $WARNRULE = '#FFFF00';
    + +

    +Man sollte daran denken, alle Vorkommen in der Datei zu ändern ;-). +

    + +
    + +

    Upgrade Szenario mit NPCD

    +
    +
      +
    1. Planen des neuen Aufbaus.
      +
    2. +
    3. Testinstallation durchführen und sich mit dem neuen System vertraut machen.
      +
    4. +
    5. Backup erstellen.
      +
    6. +
    7. PNP 0.6.x nach /usr/local/pnp4nagios installieren.
      +
    8. +
    9. make install-config
      +
    10. +
    11. make install-webconf
      +
    12. +
    13. Apache reload.
      +
    14. +
    15. Apache-Config testen.
      +
        +
      1. Aufruf /pnp4nagios muss ein leeres Perfdata-Verzeichnis melden.
        +
      2. +
      +
    16. +
    17. /usr/local/pnp4nagios/etc/npcd.cfg aus der npcd.cfg-sample erstellen.
      +
        +
      1. Pfade überprüfen und ggf. Änderungen der 0.4.x nachziehen.
        +
      2. +
      +
    18. +
    19. Alle Pfade zur neuen Installation in der nagios.cfg anpassen.
      +
    20. +
    21. Alle Pfade in den Command-Definitionen anpassen.
      +
    22. +
    23. npcd über /etc/init.d/npcd stop anhalten.
      +
    24. +
    25. make install-init installiert das neue Init Script für den npcd.
      +
    26. +
    27. Nagios anhalten.
      +
    28. +
    29. /usr/local/nagios/share/perfdata nach /usr/local/pnp4nagios/var/perfdata kopieren. Achtung: Auf Permissions achten.
      +
    30. +
    31. /etc/init.d/npcd start
      +
    32. +
    33. /etc/init.d/nagios start
      +
    34. +
    + +
    + +
    +
    + + + +

    Installation

    +
    + +

    + +Im Folgenden wird die Installation von PNP beschrieben. Dabei wird davon ausgegangen, dass Nagios aus den Sourcen übersetzt und im Verzeichnis /usr/local/nagios installiert wurde.
    + +Achtung: Die Beschreibung bezieht sich auf die Developer-Version PNP 0.6.0.
    + +Bitte vergessen Sie nicht, dass PNP nach der Installation noch konfiguriert werden muss. +

    + +
    + +

    Make und Co

    +
    + +

    + +Die Installation von PNP wird wie bei Nagios auch über Makefiles gesteuert. Dabei wird durch den Aufruf von ./configure das System analysiert und die ermittelten Werte in Makefiles übernommen. +

    + +

    +Als User root wird PNP in /usr/local/src entpackt. + +

    +
    +tar -xvzf pnp4nagios-HEAD.tar.gz
    +cd pnp4nagios
    +
    + +

    +Im Verzeichnis pnp4nagios wird nun ./configure aufgerufen. +

    +
    +./configure
    +
    + +

    + +Hinweis: Ohne weitere Optionen werden als Benutzer und Gruppe “nagios” verwendet. Bei abweichenden Werten sind die Parameter ”--with-nagios-user” und ”--with-nagios-group” zu benutzen. Im Falle von Icinga könnte der Aufruf so aussehen + +

    +
    +./configure --with-nagios-user=icinga --with-nagios-group=icinga
    +
    + +

    +Es laufen einige Zeilen über den Bildschirm. Wichtig ist die Ausgabe zum Schluss. +

    +
    +*** Configuration summary for pnp4nagios-0.6.2 23-12-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.2.12
    +  RRDs Perl Modules:                FOUND (Version 1.2012)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    +
    +  Review the options above for accuracy.  If they look okay,
    +  type 'make all' to compile.
    + +

    +Die angezeigten Pfade sollten nun geprüft werden. Falls die gezeigten Werte nicht passen, kann durch einen erneuten Aufruf von ./configure mit den passenden Optionen Abhilfe geschaffen werden.
    + +ACHTUNG: Nachdem es immer wieder Schwierigkeiten gibt: “Location of rrdtool binary” bedeutet inkl. Namen des Binary! Bei Bedarf kann man das beim ./configure als Parameter angeben: + +

    +
     ./configure --with-rrdtool=/usr/local/rrdtool-1.2.xx/bin/rrdtool
    +
     ./configure --help 
    + +

    + +zeigt, welche Optionen möglich sind.
    +
    + +Ein +

    +
    make all
    + +

    +kompiliert nun die in C geschriebenen Komponenten wie NPCD +

    +
    make install
    + +

    +kopiert alles an die richtige Stelle im Filesystem. Die Pfade wurden ja beim ./configure bereits gezeigt. +

    + +

    +Nach der Installation der Programm- und HTML-Dateien wird mit +

    +
    make install-webconf
    + +

    +eine Konfigurationsdatei in das Konfigurationsverzeichnis des Apache-Web-Servers kopiert. +

    + +

    +Optional kann noch +

    +
    make install-config
    + +

    +aufgerufen werden. Damit werden Config-Files für process_perfdata.pl und npcd nach etc/pnp kopiert. +

    + +

    +Wird das INIT Script für den NPCD benötigt, so sorgt +

    +
    make install-init
    + +

    +für die Installation nach /etc/init.d +

    + +

    +Zusammenfassen lassen sich diese einzelnen Commands durch +

    +
    make fullinstall
    + +

    +Hinweis: Wie oben schon beschrieben wird standardmässig mit den Nagios-Einstellungen installiert. Wird Icinga genutzt, muss in der Datei ”/etc/apache2/conf.d/pnp4nagios.conf” der Pfad zum AuthUserFile angepasst werden (Pfad evtl. je nach Distri anpassen): +

    +
    +#       AuthUserFile /usr/local/nagios/etc/htpasswd.users
    +        AuthUserFile /usr/local/icinga/etc/htpasswd.users
    +
    + +

    +Achtung: Nach dem Kopieren der Konfigurationsdatei für den Web-Server bzw. Ändern des AuthUserFile ist ein Restart des Web-Servers notwendig (service httpd restart bzw. /etc/init.d/apache2 restart). +

    + +
    + +

    Update

    +
    + +

    + +Das Update einer 0.6.x-Version funktioniert (fast) genauso wie die Installation. Bitte beachten Sie, dass Sie beim ”./configure” die gleichen Optionen wie bei der Erstinstallation benutzen! +Bitte prüfen Sie außerdem, ob Sie Änderungen im Verzeichnis share/templates.dist vorgenommen haben. Eigene Templates sollten im Ordner share/templates abgelegt werden.
    + +Achtung: Wenn Sie in der Datei config.php Änderungen vorgenommen haben, sollten Sie diese Datei sichern, bevor sie bei einem “make install-config” überschrieben wird. +

    + +

    +Sie können die Schritte make install-webconf und make install-init überspringen, denn zwischen den 0.6.x-Versionen gab es an dieser Stelle keine Änderungen. +

    + +
    + +

    Die Komponenten

    +
    + +

    + +Nach der Installation sind einige Komponenten von PNP an die passenden Stellen im Dateisystem kopiert worden. +

    + +

    +Im Folgenden sind dies die PHP-Files für das Web-Frontend unter + +

    +
     /usr/local/pnp4nagios/share
    + +

    + +Der Datensammler process_perfdata.pl in + +

    +
     /usr/local/pnp4nagios/libexec
    + +

    + +Beispiel-Config-Files mit der Dateierweiterung -sample in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    + +Die Config-Datei config.php für das Web-Frontend in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    +Zurück zur Übersicht | Konfiguration + +

    + +
    + +
    +
    + + + +

    Konfiguration

    +
    + +

    + +Im Folgenden wird die Konfiguration der bereits erwähnten Arten der Performance-Daten Verarbeitung genauer erklärt. +

    + +

    +Die bevorzugte Methode der PNP-Entwickler ist der “Bulk Mode mit NPCD und npcdmod”. +

    + +
    + +

    Synchronous Mode

    +
    + +

    + +Der Synchronous-Mode ist die einfachste Art, den Datensammler process_perfdata.pl in Nagios zu integrieren. Hierbei wird bei jedem Ereignis ein gesondertes Command process-service-perfdata (bzw. process-host-perfdata) ausgeführt. +

    + +

    +Grundsätzlich ist in der nagios.cfg die Verarbeitung der Performance-Daten zu aktivieren. Bitte beachten Sie, dass diese Direktive wahrscheinlich bereits in der Konfigurationsdatei enthalten ist (Default ist “0”). + +

    +
     process_performance_data=1
    + +

    + +Für jeden Host und jeden Service, für den KEINE Performance-Daten verarbeitet werden sollen, ist die Verarbeitung der Performance-Daten explizit auszuschalten. +

    +
    +define service {
    +   ...
    +   process_perf_data 0
    +   ...
    +}
    +
    + +

    +Weiterhin ist es ab Nagios 3.x möglich, in der nagios.cfg das Exportieren der Environment-Variablen zu deaktivieren. Diese sind jedoch für den Synchronous-Mode zwingend erforderlich. Daher muss + +

    +
    enable_environment_macros=1
    + +

    + +ebenfalls in der nagios.cfg gesetzt sein. +

    + +

    +Zusätzlich wird das Kommando zum Verarbeiten der Performance-Daten in der nagios.cfg angegeben. + +

    +
     service_perfdata_command=process-service-perfdata
    + +

    + +Ab Nagios 3.x ist es durchaus sinnvoll, auch die Verarbeitung der Performance-Daten für Hosts einzuschalten. Nagios 3 führt durch die geänderte Hostcheck-Logik nun auch die Prüfung der Hosts regelmäßig aus. + +

    +
     host_perfdata_command=process-host-perfdata
    + +

    + +Die referenzierten Commands müssen natürlich auch Nagios bekannt gegeben werden. Wie man sieht, sind für den Aufruf von process_perfdata.pl so gut wie keine Optionen nötig. Einzig bei Performance-Daten der Host-Checks ist die Option -d ( DATATYPE ) nötig. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command {
    +       command_name    process-service-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +}
    +
    +define command {
    +       command_name    process-host-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl -d HOSTPERFDATA
    +}
    +
    + +

    +HINWEIS: process_perfdata.pl kann nicht unter Kontrolle des ePN ( embedded Perl Nagios ) gestartet werden. Daher wird das Script explizit mit /usr/bin/perl aufgerufen. Wird ePN nicht verwendet oder wird Nagios 3.x verwendet, kann auf die Angabe von /usr/bin/perl verzichtet werden. +

    + +

    +zurück zur Übersicht | Funktion prüfen +

    + +
    + +

    Bulk Mode

    +
    + +

    + +Der Bulk-Mode ist etwas komplizierter als der Synchronous-Mode, reduziert die Last auf dem Nagios Server jedoch merklich, da nun nicht mehr für jeden Service bzw. Host zusätzlich der Datensammler process_perfdata.pl gestartet werden muss. +

    + +

    +Im Bulk-Mode schreibt Nagios die Daten in einem definierten Format in eine temporäre Datei. Diese Datei wiederum wird periodisch von process_perfdata.pl verarbeitet. Um den Start und den Intervall kümmert sich dabei Nagios selbst. +

    + +

    +Auch hier muss die Verarbeitung der Performance-Daten in der nagios.cfg eingeschaltet werden. + +

    +
     process_performance_data=1
    + +

    + +Zusätzlich werden einige neue Parameter benötigt. +

    +
    +#
    +# Service Performance-Daten
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# Host Performance-Daten ab Nagios 3.x
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    +Achtung: Die Template-Definitionen weichen von denen in der Original-nagios.cfg ab! +

    + +

    +Die Parameter und deren Bedeutung im Einzelnen: + +

    +
      +
    • service_perfdata_file Der Pfad zur temporären Datei, in der die Daten gesammelt werden sollen.
      +
    • +
    • service_perfdata_file_template Das Format der temporären Datei. Hier werden die Daten über Nagios-Macros definiert.
      +
    • +
    • service_perfdata_file_mode Die Option “a” definiert, dass an die Datei angehangen werden soll.
      +
    • +
    • service_perfdata_file_processing_interval Das Intervall beträgt 15 Sekunden
      +
    • +
    • service_perfdata_file_processing_command das Command, das im definierten Intervall aufgerufen werden soll.
      +
    • +
    + +

    + +Die verwendeten Commands müssen Nagios wiederum bekannt gegeben werden. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/service-perfdata
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/host-perfdata
    +}
    +
    +
    + +
    +

    HINWEIS:

    +
    Da process_perfdata.pl nun mehr Daten zu verarbeiten hat als im Default Mode, kommt es natürlich auch zu längeren Laufzeiten. Daher ist der TIMEOUT Wert in der etc/process_perfdata.cfg zu überprüfen und ggf. anzupassen.
    +
    + +
    + +

    +zurück zur Übersicht | Funktion prüfen +

    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + +Die Konfiguration ist identisch mit dem “Bulk Mode”, einzig das verwendete Command ist leicht abgewandelt. +

    + +

    +Auch hier muss die Verarbeitung der Performance-Daten in der nagios.cfg eingeschaltet werden. + +

    +
     process_performance_data=1
    + +

    + +Zusätzlich werden einige neue Parameter benötigt. +

    +
    +#
    +# Service Performance-Daten
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# Host Performance-Daten ab Nagios 3.x
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    +Achtung: Die Template-Definitionen weichen von denen in der Original-nagios.cfg ab! +

    + +

    +Die Parameter und deren Bedeutung im Einzelnen: + +

    +
      +
    • service_perfdata_file Der Pfad zur temporären Datei, in der die Daten gesammelt werden sollen.
      +
    • +
    • service_perfdata_file_template Das Format der temporären Datei. Hier werden die Daten über Nagios-Macros definiert.
      +
    • +
    • service_perfdata_file_mode Die Option “a” definiert, dass an die Datei angehangen werden soll.
      +
    • +
    • service_perfdata_file_processing_interval Das Intervall beträgt 15 Sekunden
      +
    • +
    • service_perfdata_file_processing_command das Command, das im definierten Intervall aufgerufen werden soll.
      +
    • +
    + +

    + +Die verwendeten Commands müssen Nagios wiederum bekannt gegeben werden. Wenn Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die Definitionen in der Datei commands.cfg anpassen. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
    +}
    +
    + +

    +Durch die Kommandos wird immer nach Ablauf des über service_perfdata_file_processing_interval eingestellten Intervalls die Datei service-perfdata nach var/spool/ verschoben. Dabei wird das Nagios-Macro $TIMET$ verwendet, an den Dateinamen angehängt, um zu verhindern, dass alte Dateien ungewollt überschrieben werden. Das Macro $TIMET$ enthält den aktuellen Zeitstempel in Unix-Time-Format ( Sekunden seit 1.1.1970 ). +

    + +

    +Somit sammeln sich Dateien im Verzeichnis /usr/local/pnp4nagios/var/spool/, die nun mit Hilfe des NPCD verarbeitet werden. +

    + +

    +NPCD überwacht das Spool-Verzeichnis und übergibt wiederum alle gefundenen Dateien an process_perfdata.pl. Damit ist die Verarbeitung der Performancedaten komplett von Nagios entkoppelt. Wir müssen nur noch den NPCD starten. + +

    +
     /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +Die Option -d veranlasst NPCD im Hintergund als Daemon seinen Dienst zu verrichten. +

    + +

    +Das Init Script für den NPCD wir während der Installation über “make install-init” installiert und kann somit auch für den Start verwendet werden. + +

    +
     /etc/init.d/npcd start
    + +

    + +In der Config-Datei des NPCD, der npcd.cfg, ist vor dem ersten Start zu prüfen, ob die Pfade zum Spool-Verzeichnis und zu process_perfdata.pl richtig gesetzt sind. +

    + +

    +Weitere Informationen zu NPCD findet ihr hier. +

    + +
    + +

    Bulk Mode with NPCD und npcdmod

    +
    + +

    + +Achtung +Beginnend mit Nagios 4 haben sich die internen Strukturen geändert, so dass der Start des Moduls fehlschlägt. Bisher gibt es keine Pläne, Nagios 4 zu unterstützen. Bitte wählen Sie einen der anderen Modi. +

    + +

    + Bei diesem Modus kommt das Eventbroker-Modul npcdmod.o zu Einsatz. Der Datenfluss ist jedoch identisch zum “Bulk Mode mit NPCD”. Die internen Perfdata-Routinen von Nagios, die über die “*_perf_data_*” Optionen in der nagios.cfg konfiguriert werden, kommen NICHT mehr zu Einsatz. Das Modul npcdmod.o kümmert sich um die für PNP nötige Aufbereitung der Daten. +

    + +

    +Vorteil: +

    +
      +
    • Die Perfdata-Routinen innerhalb von Nagios stehen wieder für andere Addons zur Verfügung.
      +
    • +
    • Die Konfiguration reduziert sich.
      +
    • +
    • Die bevorzugte Methode der PNP-Entwickler.
      +
    • +
    + +

    + +Anpassung in der nagios.cfg: +

    +
    +process_performance_data=1
    +broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +
    + +

    +Alle anderen auf dieser Seite gezeigten Optionen dürfen für diesen Modus NICHT mehr verwendet werden. +

    + +

    +Achtung: Wichtig sind in diesem Zusammenhang auch die event_broker_options bei einem von -1 abweichenden Wert. Für PNP müssen die Bits 2 und 3 gesetzt sein (0b01100; siehe auch http://www.nagios-wiki.de/nagios/ndo/eventbroker_optionen). +

    + +

    +Nach dem Neustart von Nagios werden Informationen zum Ladevorgang des Moduls protokolliert. +

    + +

    +Auszug aus den nagios.log + +

    +
    +[1277545053] npcdmod: Copyright (c) 2008-2009 Hendrik Baecker (andurin@process-zero.de) - http://www.pnp4nagios.org
    +[1277545053] npcdmod: /usr/local/pnp4nagios/etc/npcd.cfg initialized
    +[1277545053] npcdmod: spool_dir = '/usr/local/pnp4nagios/var/spool/'.
    +[1277545053] npcdmod: perfdata file '/usr/local/pnp4nagios/var/perfdata.dump'.
    +[1277545053] npcdmod: Ready to run to have some fun!
    +[1277545053] Event broker module '/usr/local/pnp4nagios/lib/npcdmod.o' initialized successfully.
    +
    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +PNP4Nagios kann seit Version 0.6.12 als Gearman-Worker betrieben werden. So sind große verteilte Nagios-Umgebungen auf Basis von mod_gearman realisierbar. Außerdem kann man dadurch Nagios und PNP4Nagios auf unterschiedliche Rechner verteilen. +

    + +

    +Benötigt wird eine fertig eingerichtete mod_gearman Installation wie von Sven Nierlein unter http://labs.consol.de/lang/en/nagios/mod-gearman/ beschrieben. +

    + +

    +In etc/process_perfdata.cfg gibt es einen gearman-Abschnitt: +

    +
     PREFORK = 1
    + GEARMAN_HOST = localhost:4730
    + REQUESTS_PER_CHILD = 10000
    + ENCRYPTION = 1
    + KEY = should_be_changed
    + #KEY_FILE = /usr/local/pnp4nagios/etc/secret.key
    + 
    + +

    +Dort ist mit PREFORK = <n> die Anzahl der zu startenden Kindprozessen anzugeben. +

    + +

    +GEARMAN_HOST = <host>:<port> definiert Rechner und Port, auf dem der gearman-Daemon die Daten bereitstellt. +Über REQUESTS_PER_CHILD = <n> kann die maximal zu verarbeitende Anzahl von Anforderungen pro Prozess eingestellt werden. +

    + +

    +ENCRYPTION = <1|0> stellt ein, ob Verschlüsselung benutzt werden soll. Die Standardeinstellung ist eine aktivierte Verschlüsselung (“1”) und das sollte nur in Ausnahmefällen verändert werden. +Dabei kann entweder über KEY = <Schlüssel> der zu benutzende Schlüssel definiert oder per KEY_FILE = <Schlüsseldatei> der Standort einer Schlüsseldatei angegeben werden. +

    + +

    + +/etc/init.d/pnp_gearman_worker enthält Verweise auf die Perl-Prozedur process_perfdata.pl sowie die Konfigurationsdatei process_perfdata.cfg. +

    + +

    + +Nach dem Start des PNP-Daemons per + +

    +
     /etc/init.d/pnp_gearman_worker start
    + +

    + +werden die Performance-Daten verarbeitet, die über den gearmand-Daemon auf dem Nagios-Rechner zur Verfügung gestellt werden. +

    + +

    +zurück zur Übersicht | Funktion prüfen + +

    + +
    + +
    +
    + + + +

    Prüfen der Installation

    +
    + +

    + +Wenn bis jetzt alles sauber funktioniert hat, kann PNP zum ersten Mal im Browser aufgerufen werden. +Bei der Installation mit den Standardeinstellungen erfolgt der Aufruf über http://<Servername>/pnp4nagios/. +

    + +

    +Beim ersten Aufruf sieht man die Seite “PNP4Nagios Environment Tests”, die verschiedene Tests von notwendigen Komponenten enthält. Offenkundig sollten alle Tests erfolgreich verlaufen, bevor es weitergehen kann. Bitte beachten Sie die Hinweise auf der Seite.
    + +

    + +

    +Sind alle Tests erfolgreich verlaufen, so kann die Datei pnp4nagios/share/install.php gelöscht oder umbenannt werden. Erst dann ist das Webinterface erreichbar. +

    + +

    +Alternativ kann eine Datei pnp4nagios/share/install.ignore angelegt werden, um den Aufruf des Installers nach weiteren Updates zu ignorieren. +

    + +

    +Ohne weitere Optionen sucht PNP nach RRD- und XML-Dateien in pnp4nagios/var/perfdata/ und zeigt alle Graphen des ersten Hosts in der Übersicht an. +

    + +

    +ACHTUNG: Direkt nach dem (Neu-)Start von Nagios nach dem Aktivieren der Verarbeitung von Performance-Daten wird der Aufruf im Browser zu Fehlermeldungen führen, weil zunächst Performance-Daten gesammelt und in den RRD-Dateien abgelegt werden müssen. Abhängig vom Check-Intervall kann es einige Zeit dauern, bis die ersten Graphen angezeigt werden können. +

    + +
    + +

    Logfile

    +
    + +

    + +Während der Installation wurde durch den Aufruf von make install-config ein Beispiel-Config-File etc/process_perfdata.cfg-sample erzeugt. Die Werte in der sample-Datei entsprechen den Default-Werten, die auch in process_perfdata.pl fest hinterlegt sind, daher ist die process_perfdata.cfg für den Betrieb nicht zwingend notwendig. +

    + +

    +Die Datei process_perfdata.cfg-sample kann somit als Vorlage für die process_perfdata.cfg dienen, die immer dann notwendig ist, wenn vom Standard abweichende Werte eingestellt werden sollen. +

    + +

    +In der process_perfdata.cfg lässt sich das Verhalten von process_perfdata.pl vielfach beeinflussen. +

    + +

    +Die wichtigsten Optionen für die Inbetriebnahme sind LOG_LEVEL und LOG_FILE. Im laufenden Betrieb sollte der Log-Level immer auf 0 gesetzt sein, um die Performance von process_perfdata.pl nicht durch unnötiges Schreiben von Logfiles zu beeinträchtigen. +

    + +

    +Während der Inbetriebnahme sollte man jedoch den LOG_LEVEL auf “2” setzen, um zu sehen, was process_perfdata.pl bei der Verarbeitung der Performance-Daten so alles anstellt. +

    + +

    +Spätestens bei Support Anfragen im Forum oder auf den Mailinglisten werden wir sowohl nach Auszügen aus dem perfdata.log als auch nach der Ausgabe des verify_pnp_config-Scripts fragen. Es empfiehlt sich also, diese Angaben gleich mitzuliefern ;-). +

    + +
    + +

    Was aber wenn nicht ?

    +
    + +

    + +Einige grundlegende Einstellungen sind zu prüfen. +

    + +

    +1. Sind RRD- und XML-Files erzeugt worden ? +

    + +

    +process_perfdata.pl legt für jeden Host unter var/perfdata ein neues Verzeichnis an. In diesem Verzeichnis wird wiederum für jeden Service eine RRD-Datenbank und ein XML-File erstellt. Für den Host-Check lautet der Dateinamen _HOST_.xml bzw. _HOST_.rrd.
    + +Falls Graphen urplötzlich nicht mehr weitergeführt werden, dann hilft vielleicht ein Blick in die betroffene XML-Datei. Dort gibt es u.a. die Tags <RC> und <TXT>. <RC> zeigt den Return-Code des RRDtool-Updates der RRD-Datei, <TXT> eine textuelle Beschreibung.
    + +Allerdings liefern nicht alle Checks Performance-Daten, das gilt u.a. für “check_ping”, die Alternative “check_icmp” dagegen erzeugt Daten (ab Nagios-Plugin-Version 1.4.12 liefert auch check_ping Performance-Daten).
    + +Teilweise muss man zusätzliche Optionen aktivieren, damit Performance-Daten ausgegeben werden. Evtl. kann das auch durch ein Wrapper-Script geändert werden.
    + +In den Detailinformationen zu jedem Host/Service gibt es das Feld “Performance-Data”. Wenn dort keine Daten stehen, dann werden im jeweiligen Verzeichnis keine Dateien erzeugt und PNP kann deshalb auch keine grafischen Auswertungen liefern!
    + +Das folgende Bild zeigt die Informationen zu einem “PING”-Service. Das blaue Feld enthält den vom Plugin gelieferten Text, das rote die Performance-Daten, die Nagios erkannt hat.
    + +Informationen zu "PING" +

    + +

    +2. Hat Nagios process_perfdata.pl aufgerufen ? +

    + +

    +In der Config-Datei für process_perfdata.pl, der etc/process_perfdata.cfg lässt sich der Debug-Level erhöhen. Die Verarbeitung der Daten wird nun in var/perfdata.log bzw. im Syslog protokolliert. +

    + +

    +3. Grafiken werden ohne Text angezeigt ? +

    + +

    +siehe Anforderungen +

    + +

    +4. Einige Graphen werden angezeigt, andere melden den Fehler “parser error: Input is not proper UTF-8” oder etwas ähnliches. Bitte prüfen Sie, ob die Daten “spezielle” Zeichen enthalten, die nicht im ASCII-Zeichensatz vorhanden sind (Umlaute, etc). Versuchen Sie, in process_perfdata.cfg den Wert von XML_ENC auf ISO-8859-1 oder einen anderen passenden Wert zu setzen. Warten Sie, bis die xml-Datei neu erzeugt wurde und probieren Sie es nochmal. +

    + +

    +5. Bei aktiviertem npcdmod-Modul muss der Wert von event_broker_options in der nagios.cfg ggf. angepasst werden. Hinweise gibt es hier. +

    + +

    +6. verify_pnp_config +Das Perl-Script verify_pnp_config.pl ermöglicht die Prüfung von Konfigurationseinstellungen und zeigt, ob Performance-Daten vorhanden sind. +

    + +

    +7. Es scheint zu funktionieren, aber es bleiben einige Dateien Spool-Verzeichnis stehen (/usr/local/pnp4nagios/var/spool/<perfdata_filename>-PID-<process_perfdata_pid>). Wenn process_perdata.pl nicht in das Zielverzeichnis (/usr/local/pnp4nagios/share/perfdata/<host>) schreiben kann, wird es anhalten und die Quelldatei nicht löschen. Das erhöht die Größe des Spool-Verzeichnisses und die Verarbeitung der Performance-Daten verlangsamen. Dieses Problem kann auftreten, wenn Sie Verzeichnisse aus einer vorherigen Installation kopiert und/oder manuell Verzeichnisse angelegt haben und dabei die falschen Benutzer/Berechtigungen verwendet haben. +

    + +

    +zurück zur Übersicht | verify_pnp_config.pl + +

    + +
    + +
    +
    + + + +

    verify_pnp_config

    +
    + +

    + +Bei Problemen kann das Perl-Script verify_pnp_config von http://verify.pnp4nagios.org helfen die aktuelle Nagios/Icinga Konfiguration zu prüfen und entsprechend Hinweise zur Lösung liefern. +

    + +

    +Bei Support Anfragen sollte immer die Ausgabe dieses Scripts mit angegeben werden, da die Entwickler sich so einen besseren Überblick über das verwendete System machen können. +

    + +

    +Feedback, Verbesserungsvorschläge oder Patches bitte per Mail an support@pnp4nagios.org +

    + +
    + +

    Download

    +
    + +

    + +Das Verify Script ist unter http://verify.pnp4nagios.org verfügbar. +

    +
    +wget http://verify.pnp4nagios.org/verify_pnp_config
    +
    + +
    + +

    Test

    +
    + +

    + +Das Verify Script benötigt drei Optionen um die Funktion von PNP4Nagios zu prüfen +

    +
    +lenny:~# perl verify_pnp_config
    +
    +verify_pnp_config -m|--mode=[sync|bulk|bulk+npcd|npcdmod]
    +                 -c|--config=[path to nagios.cfg]
    +                 -p|--pnpcfg=[path to PNP config dir]
    +
    + +

    +Die wichtigste Infos ist der zu prüfende Modus, welcher mit der Option --mode angegeben wird.
    + +Weitere Infos über die einzelnen Modi und deren Konfiguration unter "Welcher Modus ist für mich richtig ?" und "Konfiguration" +

    + +

    +Weiterhin ist der Pfad zur Nagios Config Datei (nagios.cfg) über die Option --config zu übergeben. Auf einem Icinga System ist es entsprechend der Pfad zur icinga.cfg. +

    + +

    +Über --pnpcfg wird der Pfad zum etc Verzeichnis der PNP4Nagios Installation übergeben.
    + +

    + +

    +Beim Aufruf von perl verify_pnp_config werden die verfügbaren Optionen ausgegeben. +

    +
    +lenny:~# perl verify_pnp_config --mode npcdmod --config=/usr/local/nagios/etc/nagios.cfg --pnpcfg=/usr/local/pnp4nagios/etc
    +[INFO]  ========== Starting Environment Checks ============
    +[INFO]  My version is: verify_pnp_config-0.6.14-R.31
    +[INFO]  Reading /usr/local/nagios/etc/nagios.cfg
    +[OK  ]  Running product is 'nagios'
    +[OK  ]  object_cache_file is defined
    +[OK  ]  object_cache_file=/usr/local/nagios/var/objects.cache
    +[INFO]  Reading /usr/local/nagios/var/objects.cache
    +[OK  ]  resource_file is defined
    +[OK  ]  resource_file=/usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/process_perfdata.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/pnp4nagios_release
    +[OK  ]  Found PNP4Nagios version "0.6.14"
    +[OK  ]  Effective User is 'nagios'
    +[OK  ]  User nagios exists with ID '1000'
    +[OK  ]  Effective group is 'nagios'
    +[OK  ]  Group nagios exists with ID '1000'
    +[INFO]  ========== Checking npcdmod Mode Config  ============
    +[OK  ]  process_performance_data is 1 compared with '/1/'
    +[OK  ]  event_broker_options is defined
    +[OK  ]  event_broker_options=-1
    +[OK  ]  event_broker_option bits 2 and 3 enabled (12)
    +[OK  ]  broker_module is defined
    +[OK  ]  broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  npcdmod.o config file is /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg used by npcdmod.o is readable
    +[OK  ]  npcd daemon is running
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg is used by npcd and readable
    +[OK  ]  npcd and npcdmod.o are using the same config file (/usr/local/pnp4nagios/etc/npcd.cfg)
    +[INFO]  Nagios config looks good so far
    +[INFO]  ========== Checking config values ============
    +[INFO]  Reading /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  Script /usr/local/pnp4nagios/libexec/process_perfdata.pl is executable
    +[INFO]  ========== Starting global checks ============
    +[OK  ]  status_file is defined
    +[OK  ]  status_file=/dev/shm/status.dat
    +[INFO]  Reading /dev/shm/status.dat
    +[INFO]  ==== Starting rrdtool checks ====
    +[OK  ]  RRDTOOL is defined
    +[OK  ]  RRDTOOL=/usr/bin/rrdtool
    +[OK  ]  /usr/bin/rrdtool is executable
    +[OK  ]  RRDtool 1.3.1  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>
    +[OK  ]  USE_RRDs is defined
    +[OK  ]  USE_RRDs=1
    +[OK  ]  Perl RRDs modules are loadable
    +[INFO]  ==== Starting directory checks ====
    +[OK  ]  RRDPATH is defined
    +[OK  ]  RRDPATH=/usr/local/pnp4nagios/var/perfdata
    +[OK  ]  Perfdata directory '/usr/local/pnp4nagios/var/perfdata' exists
    +[WARN]  62 hosts/services are not providing performance data
    +[WARN]  'process_perf_data 1' is set for 43 hosts/services which are not providing performance data!
    +[WARN]  'process_perf_data 0' is set for 27 of your hosts/services
    +[OK  ]  'process_perf_data 1' is set for 243 of your hosts/services
    +[INFO]  ==== System sizing ====
    +[OK  ]  269 hosts/service objects defined
    +[INFO]  ==== Check statistics ====
    +[WARN]  Warning: 3, Critical: 0
    +[WARN]  Checks finished...
    +
    + +
    + +

    Performance data

    +
    + +

    +Beginnend mit 0.6.19-R.37 (2013-02-17) akzeptiert das Skript die Option--object (oder -o) gefolgt von einer Zeichenkette, die einen Host und/oder einen Service angibt. Für diese/s Objekt(e) werden die Performance-Daten angegeben (falls vorhanden). Die Daten werden von eckigen Klammern begrenzt, gefolgt vom Wert der Direktive process_performance_data (ppd=n). +

    + +

    +host = Performance-Informationen für den Host host zeigen
    + +;service = Performance-Informationen für Service service zeigen
    + +host;service = Performance-Informationen für Service service auf Host host zeigen +

    + +

    +Die Zeichenketten werden als reguläre Ausdrücke angesehen (Perl-Syntax). + +

    + +
    + +
    +
    + + + +

    Das Nagios Web Frontend

    +
    + +

    + +PNP soll natürlich schnell erreichbar sein. Man möchte nicht lange nach den richtigen Graphen suchen. +

    + +

    +Nagios selbst bietet die Möglichkeit, externe URLs über die sogenannte Extended Info Config einzubinden. +Da es in diesem Bereich eine Änderung zwischen Nagios 2.x und der Version 3.0 gibt, wird anschließend auf beide Versionen getrennt eingegangen. +

    + +
    + +

    Nagios 2.x

    +
    + +

    + +Bis Nagios 2.x erfolgt die Einbindung externer URLs in das Nagios-Web-Interface über die Extended-Info-Objekte. Für PNP verwenden wir die Option action_url, um das PNP-Web-Frontend mit den passenden Optionen aufzurufen. +

    +
    +define serviceextinfo {
    +   name                  srv-pnp
    +   action_url            /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register              0
    +}
    +
    + +

    +Dieses Template kann nun über “use srv-pnp” in der serviceextinfo-Definition verwendet werden. Wenn Sie die Schnellstart-Installationsanleitungen benutzt haben, können Sie beispielsweise in der Datei localhost.cfg die Definitionen wie folgt erweitern: +

    +
    +define serviceextinfo {
    +   use                     srv-pnp   ; Name of service templates to use
    +   host_name               localhost
    +   service_description     load
    +}
    +
    + +
    + +

    Nagios 3.x

    +
    + +

    + +Seit Nagios 3.0 ist die Direktive action_url in die Host- bzw. Service-Definition verschoben worden. Die serviceextinfo- und hostextinfo-Definitionen sind entfallen. Damit wird die Definition der URLs zum PNP-Interface wesentlich vereinfacht. +

    + +

    +Zuerst definieren wir zwei Nagios-Templates. Falls Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die folgenden Zeilen der Datei templates.cfg hinzufügen: +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    +Diese beiden Templates können nun über “use srv-pnp” in der Service-Definition oder “use host-pnp” in der Host-Definition verwendet werden. Wenn Sie die Schnellstart-Installationsanleitungen benutzt haben, können Sie beispielsweise in der Datei localhost.cfg die Definitionen wie folgt erweitern: + +

    +
    define host{
    +        use                     linux-server,host-pnp    ; Name of host templates to use
    +                                                         ; This host definition will inherit all variables that are defined
    +                                                         ; in (or inherited by) the linux-server host template definition.
    +        host_name               localhost
    +        alias                   localhost
    +        address                 127.0.0.1
    +        }
    +
    +
    define service{
    +        use                     local-service,srv-pnp   ; Name of service templates to use
    +        host_name               localhost
    +        service_description     PING
    +        check_command           check_ping!100.0,20%!500.0,60%
    +        }
    +
    + +

    + +Die Links auf die richtigen URLs werden automagisch erstellt. +

    + +
    + +

    Preview Popup

    +
    + +

    + +Außerdem gibt es die Möglichkeit, die Graphen bereits in der Statusübersicht beim Überfahren des “Action Url Icons” mit der Maus einzublenden. +

    + +

    +Ermöglicht wird dies durch die CGI Includes, die es uns erlauben, Javascript-Code an geeigneter Stelle im Seitenkopf der Statusübersicht einzubinden ( status.cgi ). +

    + +

    +In den PNP-Quellen ist die Datei contrib/ssi/status-header.ssi bereits enthalten, die verwendeten URLs müssen aber unter Umständen angepasst werden. Wir gehen hier davon aus, dass PNP über /pnpnagios/index.php erreichbar ist. +

    + +

    +Die besagte Datei muss in das Verzeichnis /usr/local/nagios/share/ssi/ kopiert werden und darf NICHT ausführbar sein. Nagios würde die Datei sonst wirklich wie ein CGI behandeln und ausführen, was aber in diesem Fall zu Fehlern führen würde. Die Apache-Admins mögen bitte “Nagios SSI” nicht mit “Apache SSI” in Verbindung bringen. Beides hat nichts miteinander zu tun. +

    + +

    +Die action_url ist entsprechend anzupassen: +

    +
    +define host {
    +   name       host-pnp
    +   register   0
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +}
    +
    +define service {
    +   name       srv-pnp
    +   register   0
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    +
    + +

    +Nach einem Restart von Nagios (nach Anpassung der Definitionen) sieht das Ergebnis ungefähr so aus:
    + + +

    + +

    +Zurück zur Übersicht | Konfiguration Web-Frontend + +

    + +
    + +
    +
    + + + +

    PNP Web Frontend

    +
    + +

    + +Das Verhalten des PNP-Web-Frontend lässt sich über die Config-Datei etc/config.php beeinflussen. +Diese Datei wird bei Updates von PNP immer wieder überschrieben, da die meisten Pfade und Optionen bereits durch ./configure ermittelt werden. +

    + +

    +Eigene Anpassungen sollten daher in der Datei etc/config_local.php erfolgen. Sollte die Datei noch nicht existieren, kann die config.php als Vorlage verwendet werden. +

    + +
    + +

    etc/pnp/config.php

    +
    + +

    + +Im folgenden die wichtigsten Parameter: +

    + +

    +Der Pfad zum RRDtool-Binary. Wird von ./configure ermittelt. + +

    +
     $conf['rrdtool'] = "/usr/bin/rrdtool";
    +
    + +

    +Höhe und Breite der RRD-Graphen + +

    +
     $conf['graph_width'] = "500";
    + $conf['graph_height'] = "100";
    +
    + +

    + +Bildschirmdimensionen ändern sich, Blattgrößen nicht. Um unterschiedliche Einstellungen zu ermöglichen, können für die Generierung von PDF-Dateien eigene Werte definiert werden. Wenn diese Variablen nicht definiert sind, werden die Werte der Graphen benutzt. +Höhe und Breite der RRD-Graphen bei PDFs + +

    +
     $conf['pdf_width'] = "675";
    + $conf['pdf_height'] = "100";
    +
    + +

    + +Zusätzliche Optionen, die bei jedem Aufruf von RRDTool mit übergeben werden. Beispielsweise --slope-mode, um die Graphen etwas zu glätten. + +

    +
     $conf['graph_opt'] = "";
    +
    + +

    + +Der Pfad zu den von process_perfdata.pl erstellten RRD- und XML-Dateien + +

    +
     $conf['rrdbase'] = "/usr/local/pnp4nagios/var/perfdata/";
    +
    + +

    + +Pfad zu den Config-Files für die Pages. + +

    +
     $conf['page_dir'] = "/usr/local/pnp4nagios/etc/pages/";
    +
    + +

    +Wert in Sekunden, nachdem die PNP-Seiten neu geladen werden sollen. + +

    +
     $conf['refresh'] = "90";
    +
    + +

    + +Maximales Alter der RRD-Files in Sekunden. Nach Erreichen dieses Wertes werden Links zu den Graphen als “inactive” gekennzeichnet. + +

    +
     $conf['max_age'] = 60*60*6;
    +
    + +

    + +Basis-URL zu den Nagios CGIs. + +

    +
     $conf['nagios_base'] = "/nagios/cgi-bin";
    +
    + +

    +Liste von Usern, für die Links zu den Services des aktuellen Hosts angezeigt werden sollen. + +

    +
     $conf['allowed_for_service_links'] = "EVERYONE";
    +
    + +

    +Liste von Usern, für die das Host-Suchfeld angezeigt werden soll. + +

    +
     $conf['allowed_for_host_search'] = "EVERYONE";
    +
    + +

    +Wird PNP nur mit der Angabe eines Hosts ( index.php?host=<myserver> ) aufgerufen, so wird eine Übersicht aller Services angezeigt, wenn der User in dieser Liste enthalten ist. + +

    +
     $conf['allowed_for_host_overview'] = "EVERYONE";
    +
    + +

    +Das Array $views[] legt fest, welche Zeitspannen die RRD-Graphen dargestellen sollen. Der Titel und die Anzahl der Graphen kann somit hier zentral definiert werden. +

    +
    +$views[] = array('title' => 'One Hour',  'start' => (60*60) );
    +$views[] = array('title' => '4 Hours',   'start' => (60*60*4) );
    +$views[] = array('title' => '25 Hours',  'start' => (60*60*25) );
    +$views[] = array('title' => 'One Week',  'start' => (60*60*25*7) );
    +$views[] = array('title' => 'One Month', 'start' => (60*60*24*32) );
    +$views[] = array('title' => 'One Year',  'start' => (60*60*24*380) );
    +
    + +

    +Sie können hier auch weitere Views definieren, sollten aber dabei berücksichtigen, dass im Normalfall ALLE definierten Views angezeigt werden. +

    + +

    +zurück zur Übersicht | Timeranges + +

    + +
    + +
    +
    + + + +

    Timeranges

    +
    + +

    + +In der Übersicht zeigt PNP fünf Zeitbereiche, die frei in der config.php definiert werden können. +

    + +

    +Es gibt aber auch die Möglichkeit, die Zeitbereiche über die URL zu beeinflussen. Dies ist hilfreich, wenn z.B. automatisch PDF-Dokumente erstellt werden sollen +

    + +

    +Die Zeitbereiche werden über die Optionen start und end definiert. +

    + +

    +Beispiel: + +

    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=-1week
    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=2011102322:50:00&end=2011102409:50:00
    + +

    + +Der Startzeitpunkt der Graphen wird somit, ausgehend vom aktuellen Datum, um eine Woche nach hinten verschoben. Der Endzeitpunkt bleibt auf dem aktuellen Zeitstempel. Aber auch end lässt sich über diesen Weg beeinflussen, wobei beide Optionen auch einzeln manipuliert werden dürfen. +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    start end view Ergebnis
    Alle Ansichten enden mit der aktuellen Zeit
    x Alle Ansichten beginnen mit dem angegebenen Datum
    x Alle Ansichten enden mit dem angegebenen Datum
    x x Eine Ansicht zwischen den beiden Zeitangaben
    x Eine Ansicht endet mit der aktuellen Zeit
    x x Eine Ansicht beginnt mit dem angegebenen Datum
    x x Eine Ansicht endet mit dem angegebenen Datum
    + +

    + +Beispiele zur Datumsangabe: + +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Format Beschreibung
    2009W04 4. KW 2009
    1.5.2009 1. Mai 2009
    -1 day Einen Tag zurück
    -3 weeks 3 Wochen zurück
    -1 year Ein Jahr zurück
    yesterday Gestern
    2011102322:50:00 23.10.2011 ab 22:50:00 Uhr
    + +

    + +zurück zur Übersicht | Pages + +

    + +
    + +
    +
    + + + +

    Pages

    +
    + +

    + +„pages“ bieten die Möglichkeit, Grafiken von verschiedenen Hosts/Services auf einer Seite zusammenzufassen. Auf diese Weise können z.B. die Übertragungsraten der Netzwerk-Interfaces aller Tape-Libraries dargestellt werden. Innerhalb der Definitionen sind reguläre Ausdrücke möglich, so dass – entsprechende Namen vorausgesetzt - mit wenig Aufwand viel erreicht werden kann. +Das Verzeichnis, das in config.php durch den Konfigurationseintrag „$conf['page_dir']“ angegeben wurde, enthält ein oder mehrere Dateien mit der Endung „.cfg“. +

    + +

    +Kommentare beginnen mit einem '#' und sind auch innerhalb einer Zeile möglich. +Jede Datei enthält eine „page“-Definition, die neben dem Namen der Seite festlegt, ob die nachfolgenden Grafikdefinitionen reguläre Ausdrücke enthalten.
    + +Die Bezeichnung hinter page_name erscheint in der Liste der verfügbaren Seiten und wird als Titel im Browser angezeigt. +Achtung: “host_name” und “service_desc” beziehen sich auf die Namen der Dateien im perfdata-Ordner, nicht auf die Nagios-Bezeichnungen. Leerzeichen werden durch Unterstriche (“_”) ersetzt. +

    +
    define  page  {
    +        use_regex 1		# 0 = keine regulären Ausdrücke, 1 = reguläre Ausdrücke
    +        page_name Test-Seite	# Beschreibung der Seite
    +}
    + +

    +Danach folgen ein oder mehrere „graph“-Definitionen: +

    +
    define graph {
    +        host_name       host1,host2,host3
    +        service_desc    Current_Load
    +}
    + +

    + +Achtung: Damit die oben gezeigte Liste von Host-Namen funktioniert, muss use_regex 0 gesetzt sein! +

    +
    define graph {
    +        host_name       host4
    +        service_desc    Current_Users
    +}
    + +

    +Und jetzt mit regulären Ausdrücken. Zuerst alle Hosts, deren Name mit „Tape“ beginnen: + +

    +
    define graph {
    +        host_name       ^Tape
    +        service_desc    Traffic
    +}
    + +

    +alle Hosts, deren Namen mit “00” enden + +

    +
    define graph {
    +        host_name       00$
    +        service_desc    Load
    +}
    + +

    +alle Services des localhost, deren Namen ein „a“ oder „o“ enthalten: + +

    +
    define graph {
    +        host_name       localhost
    +        service_desc    a|o
    +}
    + +

    +alle Services, die im Namen nach einem „_“ (mindestens) drei Ziffern haben auf allen Hosts, deren Namen mit „UX“ beginnen: + +

    +
    define graph {
    +        host_name       ^UX
    +        service_desc    _\d{3}
    +}
    + +

    +In einigen Fällen möchten Sie vielleicht die Anzeige auf einen Graphen beschränken. Um dies zu erreichen, können Sie die optionale Direktive “source” benutzen, gefolgt von einer Zahl, die die Position in der RRD-Datei angibt. Die Zählung beginnt ab 0 + +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    PING
    +       source          1
    +}
    + +

    +zurück zur Übersicht | Datenexport + +

    + +
    + +
    +
    + + + +

    Datenexport

    +
    + +

    + +PNP bietet über den xport Controller Zugriff auf die RRD-Daten. Dabei kann das Ausgabeformat gewählt werden. Zur Zeit sind die Formate xml, json und csv realisiert. +

    + +

    +Aufgerufen wird der Controller über die URL + +

    +
    /pnp4nagios/xport/<format>?host=<hostname>&srv=<servicedesc>
    + +

    + +wobei <format> durch das jeweils gewünschte Format zu ersetzen ist. +

    + +

    +Sie können außerdem wget benutzen, um Bilder zu erzeugen und diese in regelmäßigen Reports einzufügen. Ein Beispiel: +

    +
    wget -O image.png 'http://<user>:<pass>@<nagios-server>/pnp4nagios/image?host=<hostname>&srv=<service>&view=2&source=0'
    + +

    +view=<n> begrenzt den Graphen auf die Zeitperiode, die in config.php definiert ist
    + +source=<n> zeigt nur eine Data-Source, wenn mehrere in der RRD-Datei vorhanden sind +

    + +

    +Anstatt view können Sie auch start und/oder end benutzen, um die Zeitspanne anzugeben. Details finden Sie in den "time ranges". +

    + +

    +zurück zur Übersicht | Templates + +

    + +
    + +
    +
    + + + +

    Was sind Templates ?

    +
    + +

    + +PNP benutzt Templates, um das Aussehen der RRD-Graphen zu beeinflussen. +

    + +

    +Dabei bestimmt das verwendete check_command, welches Template zur Darstellung herangezogen wird. Im Folgenden wird beschrieben, wo Templates gespeichert werden und wie die Entscheidung für das “richtige” Template getroffen wird. +

    + +
    + +

    Wann wird welches Template verwendet ?

    +
    + +

    + +Templates werden an zwei Stellen im Dateisystem gespeichert. + +

    +
      +
    • share/templates.dist - für Templates, die im PNP-Paket bereits enthalten sind.
      +
    • +
    • share/templates - für selbst erstellte Templates. Diese werden bei Updates nicht verändert.
      +
    • +
    + +

    + +Weiterhin können seit Version 0.6.5 weitere Template Verzeichnisse in der Config Datei pnp4nagios/etc/config.php hinzugefügt werden. +

    + +

    +Soll der Graph für den Service “http” auf Host “localhost” angezeigt werden, so sucht PNP zuerst nach der XML-Datei perfdata/localhost/http.xml und liest diese ein. Diese XML-Dateien werden automatisch erstellt und enthalten Informationen zum jeweiligen Host und Service. Weiterhin enthält der Kopf Informationen über das Plugin und die Performance-Daten. Im folgenden Beispiel erkennt man anhand des XML-Tags <TEMPLATE>, welches PNP-Template für diesen Graphen verwendet werden soll. +

    + +

    +/localhost/http.xml + +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>2</DS>
    +    <NAME>size</NAME>
    +    <UNIT>B</UNIT>
    +    <ACT>263</ACT>
    +    <WARN></WARN>
    +    <CRIT></CRIT>
    +    <MIN>0</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +PNP hängt .php an und sucht nun nach einem Template mit dem Namen check_http.php in folgender Reihenfolge: + +

    +
      +
    1. templates/check_http.php
      +
    2. +
    3. templates.dist/check_http.php
      +
    4. +
    5. templates/default.php
      +
    6. +
    7. templates.dist/default.php
      +
    8. +
    + +

    + +Das Template default.php nimmt somit eine Sonderstellung ein und wird immer verwendet, wenn vorher kein anderes Template gefunden wird. +

    + +
    + +

    Eigene Templates erstellen

    +
    + +

    + +PNP-Templates sind PHP-Dateien, die zur Laufzeit von PNP über die PHP-Funktion include() eingebunden werden. +Dies bedeutet, dass jeder PHP-Code in Templates interpretiert wird. Daher ist die Manipulation aller Werte über PHP möglich. +

    + +

    +PNP-Templates müssen folgende Eigenschaften besitzen: +

    +
      +
    1. Templates müssen gültigen PHP-Code enthalten.
      +
    2. +
    3. Templates dürfen keine Ausgabe erzeugen.
      +
    4. +
    5. innerhalb der Templates werden die zwei Arrays $opt[] und $def[] gefüllt.
      +
    6. +
    + +

    + +Die beiden PHP-Arrays $opt[] und $def[] zusammen bilden den Aufruf von 'rrdtool graph'. Somit sind alle Optionen möglich, die RRDtool bietet. Die Optionen von RRDtool sind auf der RRDtool Homepage genauestens beschrieben. +

    + +

    +Wenn beide Arrays mehrere Datensätze enthalten, so wird für jeden Datensatz ein Graph erstellt. +

    + +

    +Weiterhin stehen innerhalb der Templates die Daten aus dem zugehörigen XML-File zur Verfügung, die zum Erstellen der Graphen wieder verwendet werden können. +

    + +

    +Am Beispiel des recht einfachen Templates response.php lassen sich die wichtigsten Optionen recht gut beschreiben. +

    +
    <?php
    +#
    +$opt[1] = "--title \"Response Time For $hostname / $servicedesc\" ";
    +#
    +$def[1] =  "DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE " ;
    +$def[1] .= "AREA:var1#00FF00:\"Response Times \" " ;
    +$def[1] .= "LINE1:var1#000000 " ;
    +$def[1] .= "GPRINT:var1:LAST:\"%3.4lg %s$UNIT[1] LAST \" ";
    +$def[1] .= "GPRINT:var1:MAX:\"%3.4lg %s$UNIT[1] MAX \" ";
    +$def[1] .= "GPRINT:var1:AVERAGE:\"%3.4lg %s$UNIT[1] AVERAGE \" ";
    +?>
    + +

    +$opt[1] = ”--title …” setzt RRDtool-Optionen für den ersten Datensatz im Array. Hier ist das der Titel des Graphen. +Wie man sieht, werden eingebettete Anführungszeichen durch einen Backslash (\) maskiert. +Die beiden Variablen $hostname und $servicedesc sind durch den Aufruf von PNP ermittelt worden und stehen nun auch im Template zur Verfügung. +

    + +

    +$def[1] = “DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE ”; definiert, welche Daten aus welchem RRD-File gelesen werden sollen. $RRDFILE[1] enthält den Pfad zur RRD-Datei dieses Services. $DS[1] verweist auf die Datenreihe eins aus der RRD-Datei. +

    + +

    +$def[1] .= “AREA:var1#00FF00:\”Response Times \” ”; durch den Operator ”.=” werden weitere Daten an das Array $def[1] angehängt. Gezeichnet wird eine Fläche (AREA) mit den Daten der Variable var1. Die Farbe wird im HEX-Code #00FF00 definiert. Als Beschriftung wird “Response Times” verwendet. +

    + +

    +$def[1] .= “LINE1:var1#000000 ”; Als Abschluss der eben gezeichneten Fläche wird eine Linie (LINE1) in Schwarz (#000000) gezeichnet. +

    + +

    + +$def[1] .= “GPRINT:var1:LAST:\”%3.4lg %s$UNIT[1] LAST \” ”;
    + +$def[1] .= “GPRINT:var1:MAX:\”%3.4lg %s$UNIT[1] MAX \” ”;
    + +$def[1] .= “GPRINT:var1:AVERAGE:\”%3.4lg %s$UNIT[1] AVERAGE \” ”;
    +

    + +

    +Die drei GPRINT Zeilen bilden die Legende des Graphen. Die aktuellen Werte werden dabei über die printf Syntax formatiert. +

    + +
    + +

    Verfügbare Variablen

    +
    + +

    + +PNP speichert über den Datensammler process_perfdata.pl zur Laufzeit nicht nur Performancedaten, sondern auch weitere von Nagios exportierte Werte. Diese Werte werden in der jeweils für den Service gültigen XML-Datei gespeichert. +

    + +

    +Im ersten Teil der XML-Datei werden die Performancedaten in ihre Einzelteile zerlegt gespeichert. +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +Das Feld <DS> bezeichnet die DataSource und dient der Identifizierung der Datenreihen innerhalb der RRD-Dateien, ist aber auch der Schlüssel der folgenden Arrays. +

    + +

    +Im Array $UNIT[1] ist somit die Einheit der ersten Datenreihe gespeichert. +

    + +

    +Die XML-Datei enthält jedoch noch weitere Informationen. Wird process_perdata.pl im sync-Mode verwendet, so sind alle verfügbaren Makros mit den aktuellen Werten verfügbar. Der folgende Ausschnitt ist jedoch zu Gunsten der Lesbarkeit gekürzt. +

    +
    <NAGIOS>
    +...
    +  <NAGIOS_SERVICENOTIFICATIONID>8418</NAGIOS_SERVICENOTIFICATIONID>
    +  <NAGIOS_SERVICENOTIFICATIONNUMBER>0</NAGIOS_SERVICENOTIFICATIONNUMBER>
    +  <NAGIOS_SERVICEOUTPUT>HTTP OK HTTP/1.1 200 OK - 10087 bytes in 0.125 seconds</NAGIOS_SERVICEOUTPUT>
    +  <NAGIOS_SERVICEPERCENTCHANGE>0.00</NAGIOS_SERVICEPERCENTCHANGE>
    +  <NAGIOS_SERVICEPERFDATA>time=0.124811s;;;0.000000 size=10087B;;;0</NAGIOS_SERVICEPERFDATA>
    +  <NAGIOS_SERVICEPERFDATAFILE></NAGIOS_SERVICEPERFDATAFILE>
    +  <NAGIOS_SERVICEPROBLEMID>0</NAGIOS_SERVICEPROBLEMID>
    +  <NAGIOS_SERVICESTATE>OK</NAGIOS_SERVICESTATE>
    +  <NAGIOS_SERVICESTATEID>0</NAGIOS_SERVICESTATEID>
    +  <NAGIOS_SERVICESTATETYPE>HARD</NAGIOS_SERVICESTATETYPE>
    +  <NAGIOS_SHORTDATETIME>27-12-2007 13:51:23</NAGIOS_SHORTDATETIME>
    +...
    +</NAGIOS>
    + +

    +Die einzelnen XML-Felder sind als Variablen in den PNP-Templates verwendbar, wobei jedes Feld als Variable gleichen Namens verfügbar ist. +

    + +

    +Aus <NAGIOS_SERVICEOUTPUT> wird die Variable $NAGIOS_SERVICEOUTPUT. +

    + +

    +zurück zur Übersicht | Custom Templates + +

    + +
    + +
    +
    + + + +

    Custom Templates

    +
    + +

    + +Wie bereits unter ”Was sind Templates ?” beschrieben, ist die Darstellung der Graphen abhängig vom verwendeten Check-Command. +

    + +

    +Es gibt jedoch Situationen, in denen dieses Verhalten übersteuert werden muss, zum Beispiel dann wenn allgemeingültige Commands definiert wurden. +

    + +

    +PNP, speziell process_perfdata.pl, sucht zur Laufzeit für jedes check_command im Verzeichnis etc/check_commands nach einer Config-Datei (<check_command>.cfg) und liest diese, wenn vorhanden, ein. +Folgende Optionen können darin definiert werden: +

    + +
    + +

    CUSTOM_TEMPLATE

    +
    + +

    +Geht man von folgendem Beispiel einer Nagios command-Definition aus: + +

    +
    +define command {
    +  command_name check_nrpe
    +  command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a "$ARG2$"
    +}
    +
    + +

    +Die Folge wäre, dass immer das Template check_nrpe.php verwendet werden würde, auch wenn auf dem zu überwachenden Server via NRPE ein ganz anderes Plugin aufgerufen wurde. +

    + +

    +Da unser Beispiel-Command check_nrpe lautet, wird nach etc/check_commands/check_nrpe.cfg gesucht. +

    + +

    +Eine Beispiel-Config wird bereits während der Installation mit der Dateierweiterung .cfg-sample in etc/check_commands gespeichert. +

    +
    +# check_command check_nrpe!load!-w 4,4,4 -c 5,5,5
    +# ________0__________|       |       |
    +# ________1__________________|       |
    +# ________2__________________________|
    +#
    +CUSTOM_TEMPLATE = 1
    +
    + +

    +CUSTOM_TEMPLATE = 1 sorgt dafür, dass nur der Inhalt von $ARG1$ als Template-Name verwendet wird. Da in diesem Beispiel $ARG1$ mit dem Wert “load” gefüllt ist, ergibt sich als Template-Name “load.php” +

    + +

    +CUSTOM_TEMPLATE = 0,1 ergibt → “check_nrpe_load.php” +

    + +

    +CUSTOM_TEMPLATE = 1,0 ergibt → “load_check_nrpe.php” +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    DATATYPE

    +
    + +

    + +Über die Option “DATATYPE” kann beeinflusst werden, mit welchem Datentyp die RRD-Datenbank angelegt werden soll. +Default ist in diesem Fall “GAUGE”. Für fortlaufende Werte wird aber hier der Datentyp COUNTER benötigt. +Normalerweise sollten Plugin-Entwickler für Daten von Typ Counter die Einheit “c” verwenden. Dies ist jedoch nicht immer der Fall. +

    + +

    +Alle Datenreihen auf Typ COUNTER einstellen. + +

    +
    DATATYPE = COUNTER
    + +

    +Einzelnen Datenreihen spezielle Datentypen zuweisen + +

    +
    DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER
    + +

    +Weitere Datentypen sind in der RRDTool-Dokumentation unter rrdcreate erklärt. +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    USE_MIN_ON_CREATE und USE_MAX_ON_CREATE

    +
    + +

    + +In einigen wenigen Situationen ist es notwendig, die für RRDTool gültigen Daten zu begrenzen. +

    + +

    +RRD-Datenbanken lassen sich mit definierten Minimum- und Maximum-Werten anlegen. +Weitere Infos unter http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +Berücksichtigen des Maximum-Wertes aus den Performance-Daten + +

    +
    USE_MAX_ON_CREATE = 1
    + +

    +Berücksichtigen des Minimum-Wertes aus den Performance-Daten + +

    +
    USE_MIN_ON_CREATE = 1
    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    RRD_STORAGE_TYPE

    +
    +
    RRD_STORAGE_TYPE = SINGLE
    + +

    + +Die Option RRD_STORAGE_TYPE definiert die Art der Datenhaltung. +

    + +

    +Mögliche Werte sind MULTIPLE und SINGLE +

    + +

    +SINGLE: Eine RRD-Datenbank pro Service +

    + +

    +MULTIPLE: Ein oder mehrere RRD-Datenbanken pro Service. Für jede Datenreihe wird eine eigene RRD-Datenbank erstellt. +

    + +

    +ACHTUNG: Daten werden nicht automatisch migriert!
    + +Ein Konvertierungs-Script finden Sie hier. +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    RRD_HEARTBEAT

    +
    + +

    + +Gültig ab PNP 0.6.1 +

    +
    RRD_HEARTBEAT = 305
    + +

    +Nach <RRD_HEARTBEAT> Sekunden erwartet RRDtool neue Daten. +

    + +

    +Mehr dazu unter http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    Hints on Template Names

    +
    + +

    + +In den meisten Situationen, kann man erwünsche Template Namen relativ einfach, durch die Verwendung geeignter command Objekt Definitionen, erhalten. +

    + +

    +Man betrachte folgendes Beispiel: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load -w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    +Selbst wenn man “CUSTOM_TEMPLATE = 1” benutz, würde man template Namen wie diesen “_usr_lib_nagios_plugins_check_load_-w_4,4,4_-c_5,5,5” erhalten, was höchst unerwünscht ist, insbesondere wegen den darin enthaltenen Parametern. +

    + +

    +Lösung 1: Die Parameter in eigenständige $ARGn$ auslagern +

    + +

    +Eine einfache Lösung ist die Verwendung der folgenden command Objekt Definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +(man beachte das hinzugekommene “!”) +

    + +

    +Dies funktioniert selbst dann, wann $ARG2$ leer bleibt. +

    + +

    +Selbstverständlich müsste man immer noch “CUSTOM_TEMPLATE = 1” setzen. +

    + +

    + +Lösung 2: Den remote executor in der command Objekt Definition verstecken +

    + +

    +Eine andere Lösung ist es, den remote excutor in den jeweiligen command Objekt Definitionen zu verstekcne. +

    + +

    +Anstatt folgender Definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +würde man dies für jeden fern auszuführenden command definieren: + +

    +
    +define command {
    +  command_name check_load_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ /usr/lib/nagios/plugins/check_load $ARG1$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_load_by_ssh!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +Natürlich darf “CUSTOM_TEMPLATE = 1” bei dieser Lösung nicht mehr gesetzt werden. +

    + +

    + +Welche der obigen Lösungen verwendet wird, ist weitgehend Geschmacksache. +

    + +

    +zurück zur Übersicht | PNP in verteilten Umgebungen + +

    + +
    + +
    +
    + + + +

    Advanced

    +
    + +
    + +

    Verteilte Systeme

    +
    + +

    +Ist Nagios als verteiltes System implementiert, stellt sich die Frage, wo PNP installiert wird. +

    + +

    +Rein technisch ist diese Frage nicht wichtig. PNP kann auf den Slaves sowie auf dem Master-Server installiert sein. Oder nur auf dem Master? +

    + +

    +Wird PNP auf dem Master betrieben, ist jedoch bei der Übergabe der Daten via send_nsca von den Slave-Servern zum Master darauf zu achten, dass auch die Performance-Daten übergeben werden. Weiterhin kommt auf dem Master oft nicht das Original-Check-Command zum Einsatz. +

    + +

    +Damit nun aber PNP auf dem Master noch erkennen kann, welches Check-Command auf den Slaves die Daten ermittelt hat, reagiert process_perfdata.pl auf ein zusätzliches Feld am Ende der Performance-Daten. +

    +
    OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;; [check_icmp]
    + +

    +Findet PNP am Ende der Performance Daten einen in eckigen Klammern eingeschlossenen Text, so wird dieser als Check-Command und somit als PNP-Template verwendet. +

    + +

    +Die Nagios-Dokumentation zu diesem Thema ist hier zu finden. Das in der Doku verwendete Command ist leicht anzupassen. +

    + +

    +Aus +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$'
    +	}
    +
    + +

    +wird +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$ | $SERVICEPERFDATA$ [$SERVICECHECKCOMMAND$]'
    +	}
    +
    + +
    + +

    Das check_multi-Plugin

    +
    + +

    + +Das Plugin check_multi ist eines der ersten Plugins, das die Funktionen von Nagios 3.0 richtig ausschöpft. Check_Multi ist in der Lage, mehrere Nagios-Plugins auszuführen, aber für Nagios als einen Service darzustellen. Die Ausgabe von check_multi erfolgt über mehrere Zeilen, um die Masse an Informationen wieder darstellen zu können. +

    + +

    +Daraus ergaben sich jedoch einige Schwierigkeiten für PNP. PNP muss aus den Performance-Daten wieder die Daten der einzelnen Plugins ermitteln können. Zusammen mit Matthias Flacke, dem Entwickler von check_multi, haben wir jedoch recht schnell eine Möglichkeit gefunden, die Daten wieder sauber den einzelnen Plugins zuzuordnen. +

    + +

    + +

    + +

    +Zurück zur Übersicht | rrdcached-Unterstützung + +

    + +
    + +
    +
    + + + +

    RRDtool Cache Daemon

    +
    + +

    + +In großen Installationen wird man über kurz oder lang feststellen, dass die Verarbeitung der Performance-Daten eine recht hohe I/O-Last zur Folge hat. RRDtool muss extrem viele Updates auf Disk schreiben, kann dabei jedoch den Disk-Cache nicht optimal ausnutzen. +

    + +

    +Eine Optimierung stellt das Sammeln und Sortieren der Daten dar. Es ist für das System effektiver, viele Updates im Block in eine RRD-Datenbank zu schreiben. Der Disk-Cache kann dabei effektiver genutzt werden. +

    + +

    +In der aktuellen RRDtool-Version ( SVN trunk 1550+ ) ist der rrdcached enthalten, der genau diese Situation verbessern soll. +

    + +

    +An dieser Stelle möchte ich mich bei Florian octo Forster, Kevin Brintnall und Tobi Oetiker bedanken. Die Entwicklung dieses Daemons wurde vorbildlich auf der rrd-developers Mailingliste koordiniert. +

    + +
    + +

    Arbeitsweise

    +
    + +

    + +Der rrdcached arbeitet als Daemon im Hintergrund und öffnet einen UNIX- oder TCP-Socket, auf dem er auf Anfragen von rrdtool wartet. Aufgrund von Sicherheitsbedenken ist es in neueren Versionen von rrdcached aber nicht mehr möglich absolute Pfadangaben (wie bei pnp4nagios üblich) bei Netzwerkzugriffen zu verwenden, daher ist derzeit nur Nutzung von UNIX-Sockets möglich. +

    + +
    + +

    rrdcached

    +
    + +

    + +Der rrdcached kennt einige wichtige Optionen, die beim Start übergeben werden. +

    + +

    +Option -l definiert den Socket, auf dem der rrdcached Requests annimmt. Der Default-UDP-Port ist 42217, der Default-UNIX-Socket /tmp/rrdcached.sock. +

    +
    +-l unix:/pfad/zum/rrdcached.sock
    +-l /pfad/zum/rrdcached.sock
    +-l 127.0.0.1
    +-l 127.0.0.1:8888
    +
    + +

    +Option -P gibt die für die nachfolgenden Sockets (mit -l spezifiziert) erlaubten Befehle an, welche auf die RRD-Datenbanken angewendet werden können. +

    +
    -P FLUSH,PENDING
    + +

    +Option -s erlaubt es die Gruppenzugehörigkeit der nachfolgenden UNIX-Sockets zu ändern. +

    +
    -s nagios
    + +

    +Option -m setzt die Zugriffsrechte für die nachfolgenden UNIX-Sockets auf die (in oktal) angegebenen Werte. +

    +
    -m 0660
    + +

    +Option -w bestimmt den Intervall in Sekunden, in dem die Daten auf Disk geschrieben werden sollen. +

    +
    -w 1800
    + +

    +Option -z definiert einen Delay, der die über die Option -w definierten Schreibzyklen in einen zufälligen Bereich [0-delay] verteilt, um gleichzeitige Schreibzugriffe zu verhindern. Der Wert der Option -z darf nicht größer gewählt werden als -w. +

    +
    -z 1800
    + +

    +Option -p definiert ein PID File +

    +
    -p /var/run/rrdcached.pid
    + +

    +Option -j definiert den Pfad zu einem Journal-Verzeichnis. Dort werden alle Aufträge protokolliert und ggf. beim nächsten Start nachgefahren, falls der rrdcached-Daemon abstürzt. +

    +
    -j /var/cache/rrdcached
    + +

    +Daraus ergibt sich beispielsweise ein Aufruf von rrdached mit folgenden Parametern +

    +
     rrdcached -w 1800 -z 1800 -p /tmp/rrdcached.pid -j /tmp -s nagios -m 0660 -l unix:/tmp/rrdcached.sock
    + +
    + +

    rrdtool

    +
    + +

    + +RRDtool selbst wird die Existenz des Daemons über die Option --daemon=<socket> mitgeteilt. + +

    +
     rrdtool --daemon=unix:/tmp/rrdcached.sock update ...
    + +

    + +Dies muss natürlich mit den Startoptionen des rrdcached übereinstimmen! +

    + +
    + +

    Integration in PNP

    +
    + +

    + +Da zwei Bestandteile von PNP auf den rrdcached vorbereitet werden müssen, ergeben sich Änderungen in zwei Config-Files. Außerdem muß der User unter welchem der Webserver läuft zur Gruppe unter der Nagios läuft hinzugefügt werden. +

    + +

    +1. Anpassen der process_perfdata.cfg für den Datensammler process_perfdata.pl +

    +
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +RRD_DAEMON_OPTS = unix:/var/run/rrdcached.sock
    +
    + +

    +2. Anpassen der config_local.php (bzw. config.php) für das Webinterface +

    +
    +#
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +# $conf['RRD_DAEMON_OPTS'] = 'unix:/tmp/rrdcached.sock';
    +$conf['RRD_DAEMON_OPTS'] = 'unix:/var/run/rrdcached.sock';
    +
    + +

    +Die passenden Optionen sind bereits in den Beispieldateien enthalten. +

    + +

    +zurück zur Übersicht | migrieren von RRD-Dateien + +

    + +
    + +
    +
    + + + +

    NPCD

    +
    + +

    + +NPCD (Nagios-Perfdata-C-Daemon) wurde geschrieben, um die asynchrone Bearbeitung von Nagios Performance-Daten zu ermöglichen. +

    + +
    + +

    Einleitung

    +
    + +

    + +In großen Nagios-Installationen kann es zu nicht akzeptierbaren Verspätungen seitens der Checks kommen. Das bedeutet, dass Nagios einen Check zum Zeitpunkt x ausführen soll, diesen aber erst y Sekunden später tatsächlich ausführt. +

    + +

    +Wenn man dem Nagios-Daemon mitteilt, dass man nach jedem einzelnen Check auch die Performance-Daten verarbeiten möchte, so geht dies bis zu einem bestimmten Grad gut, ab einer gewissen Anzahl von Checks pro Sekunde allerdings kommt man relativ schnell zu den sog. Latency-Problemen. +

    + +

    +Um die Anzahl der Aktionen pro Check zu verringern, kann man nun PNP im Bulk-Mode verwenden, wobei die Performance-Daten zunächst vom Nagios-Prozess gesammelt und anschließend ebenfalls vom Nagios-Prozess selbst verarbeitet werden. +

    + +

    +Man kann aber auch dem Nagios-Prozess mitteilen, dass die Verarbeitung der Performance-Daten lediglich durch das Verschieben der Dateien in ein Spool-Verzeichnis geschehen soll, welches für den Nagios-Prozess selbst eine sehr schnelle Aktion ist und die Performance nicht nennenswert beeinflusst und somit dem Core mehr Zeit für seine eigentliche Arbeit lässt: weitere Checks ausführen, Alamierungen bereitstellen, etc. +

    + +
    + +

    Wie NPCD arbeitet

    +
    + +

    + +Wie bereits erwähnt, ist die Arbeit der Performance-Daten-Verarbeitung durch das schnelle Verschieben der Datei bereits erledigt, aber das bringt die Performance-Daten noch nicht in die RRD-Datenbank. +

    + +

    +Um den Transport der Performance-Daten-Dateien kümmert sich nun der NPCD-Daemon, unabhängig vom Nagios-Prozess, indem er regelmäßig in das Spool-Verzeichnis guckt und für jede dort gefundene Datei eine Aktion ausführt. +

    + +

    +Nachdem NPCD gestartet wurde, erstellt er sich eine Liste von Dateinamen des Spool-Verzeichnisses und startet für jede gefundene Datei einen Thread zur weiteren Verarbeitung mit Hilfe des perfdata_file_run_cmd und dem optionalen perfdata_file_run_cmd_arg als zusätzlichem Argument. +

    + +

    +Da das Format der Performance-Daten-Dateien dem Format der 'normalen' PNP-Bulk-Modus-Dateien gleicht, kann NPCD nun für jede gefundene Datei also process_perfdata.pl im Bulk Modus aufrufen. +

    + +
    + +

    Vor- und Nachteile

    +
    + +

    + +Pro: +

    +
      +
    • bessere Performance für Nagios
      +
        +
      • aufgrund der vom Nagios-Prozess getrennten Verarbeitung der Performance-Daten hat Nagios mehr Zeit für die wichtigen Dinge
        +
      • +
      +
    • +
    • kein Datenverlust
      +
        +
      • solange Nagios Performance-Daten-Dateien im Spool-Verzeichnis ablegt, gehen keine Daten verloren. Selbst wenn der NPCD mal nicht laufen sollte (Bsp. nach Neustart des Systems), werden die Dateien nach Wiederanlauf in chronologischer Reihenfolge bearbeitet ($TIMET$ Makro beim verschieben ins Spool-Verzeichnis)
        +
      • +
      +
    • +
    + +

    + +Kontra: +

    +
      +
    • Keine Echtzeitverarbeitung der Performance-Daten
      +
        +
      • aufgrund des Rhythmusses, wann Nagios die Performance-Daten-Dateien verschiebt (service_perfdata_file_processing_interval)
        +
      • +
      • nach jedem Lauf durch alle Dateien des Spool-Verzeichnisses wartet NPCD 10 Sekunden lang auf neue Dateien
        +
      • +
      +
    • +
    + +
    + +

    NPCD Config

    +
    + +

    + +NPCD muss zwangsläufig über eine Konfigurationsdatei gesteuert werden. Eine Beispielkonfiguration liegt der PNP-Installation als npcd.cfg-sample bei. +

    + +

    +Nach Umbenennen der -sample Datei zu npcd.cfg kann NPCD nun wie folgt gestartet werden: +

    +
    /usr/local/pnp4nagios/bin/npcd -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +oder + +

    +
    /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +um NPCD im Hintergrund als Daemon laufen zu lassen. +

    + +

    +Hinweis: +Die -sample Datei sollte in jedem Fall in npcd.cfg umbenannt werden, da sie sonst bei einem Update von PNP überschrieben werden könnte. +

    + +
    + +

    npcd.cfg-sample

    +
    + +

    + +Dies sind die essentiellen Konfigurationsdirektiven für NPCD: +

    +
    # Privilege Options
    +user = nagios
    +group = nagios
    +
    +# Logging Options
    +log_type = syslog
    +log_file = /usr/local/pnp4nagios/var/npcd.log
    +max_logfile_size = 10485760
    +log_level=0
    +
    +# Processing Options
    +perfdata_spool_dir = /usr/local/pnp4nagios/var/spool/perfdata/
    +perfdata_file_run_cmd = /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +perfdata_file_run_cmd_args = -b
    +
    +# Thread Options
    +npcd_max_threads=5
    +
    +# greedy options
    +use_load_threshold = 0
    +load_threshold = 10.0
    +
    +# Process Options
    +pid_file=/var/run/npcd.pid
    +
    + +
    + +

    Die Direktiven

    +
    +
      +
    • Privilege-Optionen
      +
        +
      • user <username>
        +
          +
        • NPCD versucht die Userberechtigung zu diesem User zu wechseln.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      • group <groupname>
        +
          +
        • NPCD versucht die Gruppenberechtigung zu dieser Gruppe zu wechseln.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      +
    • +
    • Logging-Optionen
      +
        +
      • log_type <syslog> oder <file>
        +
          +
        • Log-Type, den NPCD zum Loggen verwenden wird
          +
        • +
        • Default: syslog
          +
        • +
        +
      • +
      • log_file </pfad/zu/datei>
        +
          +
        • Falls log_type = file wird diese Logdatei verwendet
          +
        • +
        • Default: /usr/local/pnp4nagios/var/npcd.log
          +
        • +
        +
      • +
      • max_logfile_size <bytes>
        +
          +
        • NPCD wird nach Erreichen der hier angegebenen Dateigröße eigenständig eine Logrotation durchführen
          +
        • +
        • Default: 10485760 = 10 MByte
          +
        • +
        +
      • +
      • log_level <integer>
        +
          +
        • Wie viel soll aufgezeichnet werden, möglich ist:
          +
            +
          • 0 = Kein Log - außer Fehlern
            +
          • +
          • 1 = wenig Log - etwas mehr Aufzeichnen
            +
          • +
          • 2 = Mehr Log (aktuell ALLES)
            +
          • +
          • -1 = DEBUG Mode - Es wird alles aufgezeichnet und die Bearbeitung wird verlangsamt
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      +
    • +
    • Bearbeitungs-Optionen
      +
        +
      • perfdata_spool_dir </path/to/spool/dir/>
        +
          +
        • Das Verzeichnis, in das Nagios die Dateien verschiebt
          +
        • +
        • Default: /usr/local/pnp4nagios/var/spool/
          +
        • +
        +
      • +
      • perfdata_file_run_cmd </path/to/bin/filename>
        +
          +
        • Das Programm, welches Nagios für jede Datei aufrufen soll
          +
        • +
        • Default: /usr/local/pnp4nagios/libexec/process_perfdata.pl
          +
        • +
        +
      • +
      • perfdata_file_run_cmd_args <option>
        +
          +
        • Das Argument, welches optional an perfdata_file_run_cmd angehängt wird
          +
        • +
        • Default: ”-b”
          +
        • +
        • :!: Die Kommandozeile wird nach folgendem Schema aufgebaut:
          <perfdata_file_run_cmd> <perfdata_file_run_cmd_args> <filename_from_perfdata_spool_dir>
          +
          +
        • +
        +
      • +
      +
    • +
    • Thread-Optionen
      +
        +
      • npcd_max_threads <integer value>
        +
          +
        • Anzahl der maximal zu startenden parallelen Threads
          +
        • +
        • Default: 5
          +
        • +
        +
      • +
      +
    • +
    • Greedy-Optionen
      +
        +
      • use_load_threshold <0 oder 1>
        +
          +
        • definiert, ob NPCD bei Erreichen des load_thresholds die Anzahl der Threads begrenzen soll
          +
            +
          • 0 = ausschalten (weitere Threads starten)
            +
          • +
          • 1 = einschalten
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      • load_threshold <float value>
        +
          +
        • wenn use_load_threshold auf 1 gesetzt ist, werden bei Erreichen dieses load limits keine neuen Threads gestartet
          +
        • +
        • Default: 10.0
          +
        • +
        +
      • +
      +
    • +
    • Process-Optionen
      +
        +
      • pid_file </path/to/pid.file>
        +
          +
        • Pfad zum PID File
          +
        • +
        • Default: /var/run/npcd.pid
          +
        • +
        +
      • +
      +
    • +
    + +

    + +zurück zur Übersicht | Wrapper-Script + +

    + +
    + +
    +
    + +

    +check_procs ist ein Beispiel für ein Plugin, das keine Performance-Daten ausgibt: +

    +
    ./check_procs -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'
    + +

    +Mit dem folgenden Wrapper-Script kann das geändert werden +

    + +

    +check_procs.sh + +

    +
    #!/bin/bash
    +LINE=`/usr/local/nagios/libexec/check_procs $*`
    +RC=$?
    +COUNT=`echo $LINE | awk '{print $3}'`
    +PROCS=`expr $COUNT - 1`
    +LINE=`echo $LINE | sed "s/: $COUNT /: $PROCS /"`
    +echo $LINE \| procs=$PROCS
    +exit $RC
    + +

    +Nun wird die Zahl zusammen mit einer Bezeichnung ausgegeben. + +

    +
    ./check_procs.sh -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'| procs=2
    + +
    +
    + + + + + + + +
    2.6. Performance-Daten
    + +

    + +'Bezeichnung'=Wert[UOM];[warn];[crit];[min];[max] +

    + +

    +Anmerkungen: + +

    +
      +
    1. Leerzeichen trennen Listen von Bezeichnung/Werte-Paaren
      +
    2. +
    3. Bezeichnungen können beliebige Zeichen enthalten
      +
    4. +
    5. die Bezeichnung muss in Apostrophe eingeschlossen sein, wenn diese Gleichheitszeichen (=), Apostroph (') oder Leerzeichen ( ) enthält, ansonsten sind die Apostrophe optional
      +
    6. +
    7. die Länge der Bezeichnung ist beliebig, aber idealerweise sind die ersten 19 Zeichen eindeutig (aufgrund einer Beschränkung in RRD). Bitte beachten Sie, dass es eine Längenbegrenzung bei der Menge von Daten gibt, die von NRPE an Nagios geliefert werden kann
      +
    8. +
    9. um ein Apostroph darzustellen, nutzen Sie zwei einzelne Apostrophe
      +
    10. +
    11. warn, crit, min und/oder max können leer sein (z.B. wenn der Schwellwert nicht definiert ist oder wenn min oder max nicht zutreffen). Nachfolgende, nicht gefüllte Semikola können entfallen
      +
    12. +
    13. min und max sind nicht erforderlich, wenn UOM = %
      +
    14. +
    15. Wert, min und max sind aus der Klasse [-0-9.] (Ziffern, Minuszeichen und Dezimalpunkt). Alle müssen das gleiche UOM benutzen
      +
    16. +
    17. warn und crit sind im “Range”-Format (siehe Abschnitt 2.5 der Original-Dokumentation). Alle müssen das gleiche UOM benutzen.
      +
    18. +
    19. UOM (unit of measurement, Maßeinheit) ist eins von:
      +
        +
      • keine Einheit angegeben - angenommen wird eine Zahl (int oder float) von Dingen (z.B. Benutzer, Prozesse, Load)
        +
      • +
      • s - Sekunden (auch us, ms)
        +
      • +
      • % - Prozent
        +
      • +
      • B - Bytes (auch KB, MB, TB; GB?)
        +
      • +
      • c - ein fortlaufender Zähler (z.B. Bytes, die über ein Interface übertragen werden)
        +
      • +
      +
    20. +
    + +

    + +Es bleibt Drittanbietern überlassen, aus den Performance-Daten Graphen zu erzeugen.| +

    + +

    +Quelle: http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN201 + +

    + +
    diff --git a/share/pnp/documents/de_DE/dwnld.html b/share/pnp/documents/de_DE/dwnld.html new file mode 120000 index 0000000..bc99189 --- /dev/null +++ b/share/pnp/documents/de_DE/dwnld.html @@ -0,0 +1 @@ +en_US/dwnld.html \ No newline at end of file diff --git a/share/pnp/documents/de_DE/install.html b/share/pnp/documents/de_DE/install.html new file mode 100644 index 0000000..11b8970 --- /dev/null +++ b/share/pnp/documents/de_DE/install.html @@ -0,0 +1,208 @@ + + + +

    Installation

    +
    + +

    + +Im Folgenden wird die Installation von PNP beschrieben. Dabei wird davon ausgegangen, dass Nagios aus den Sourcen übersetzt und im Verzeichnis /usr/local/nagios installiert wurde.
    + +Achtung: Die Beschreibung bezieht sich auf die Developer-Version PNP 0.6.0.
    + +Bitte vergessen Sie nicht, dass PNP nach der Installation noch konfiguriert werden muss. +

    + +
    + +

    Make und Co

    +
    + +

    + +Die Installation von PNP wird wie bei Nagios auch über Makefiles gesteuert. Dabei wird durch den Aufruf von ./configure das System analysiert und die ermittelten Werte in Makefiles übernommen. +

    + +

    +Als User root wird PNP in /usr/local/src entpackt. + +

    +
    +tar -xvzf pnp4nagios-HEAD.tar.gz
    +cd pnp4nagios
    +
    + +

    +Im Verzeichnis pnp4nagios wird nun ./configure aufgerufen. +

    +
    +./configure
    +
    + +

    + +Hinweis: Ohne weitere Optionen werden als Benutzer und Gruppe “nagios” verwendet. Bei abweichenden Werten sind die Parameter ”--with-nagios-user” und ”--with-nagios-group” zu benutzen. Im Falle von Icinga könnte der Aufruf so aussehen + +

    +
    +./configure --with-nagios-user=icinga --with-nagios-group=icinga
    +
    + +

    +Es laufen einige Zeilen über den Bildschirm. Wichtig ist die Ausgabe zum Schluss. +

    +
    +*** Configuration summary for pnp4nagios-0.6.2 23-12-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.2.12
    +  RRDs Perl Modules:                FOUND (Version 1.2012)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    +
    +  Review the options above for accuracy.  If they look okay,
    +  type 'make all' to compile.
    + +

    +Die angezeigten Pfade sollten nun geprüft werden. Falls die gezeigten Werte nicht passen, kann durch einen erneuten Aufruf von ./configure mit den passenden Optionen Abhilfe geschaffen werden.
    + +ACHTUNG: Nachdem es immer wieder Schwierigkeiten gibt: “Location of rrdtool binary” bedeutet inkl. Namen des Binary! Bei Bedarf kann man das beim ./configure als Parameter angeben: + +

    +
     ./configure --with-rrdtool=/usr/local/rrdtool-1.2.xx/bin/rrdtool
    +
     ./configure --help 
    + +

    + +zeigt, welche Optionen möglich sind.
    +
    + +Ein +

    +
    make all
    + +

    +kompiliert nun die in C geschriebenen Komponenten wie NPCD +

    +
    make install
    + +

    +kopiert alles an die richtige Stelle im Filesystem. Die Pfade wurden ja beim ./configure bereits gezeigt. +

    + +

    +Nach der Installation der Programm- und HTML-Dateien wird mit +

    +
    make install-webconf
    + +

    +eine Konfigurationsdatei in das Konfigurationsverzeichnis des Apache-Web-Servers kopiert. +

    + +

    +Optional kann noch +

    +
    make install-config
    + +

    +aufgerufen werden. Damit werden Config-Files für process_perfdata.pl und npcd nach etc/pnp kopiert. +

    + +

    +Wird das INIT Script für den NPCD benötigt, so sorgt +

    +
    make install-init
    + +

    +für die Installation nach /etc/init.d +

    + +

    +Zusammenfassen lassen sich diese einzelnen Commands durch +

    +
    make fullinstall
    + +

    +Hinweis: Wie oben schon beschrieben wird standardmässig mit den Nagios-Einstellungen installiert. Wird Icinga genutzt, muss in der Datei ”/etc/apache2/conf.d/pnp4nagios.conf” der Pfad zum AuthUserFile angepasst werden (Pfad evtl. je nach Distri anpassen): +

    +
    +#       AuthUserFile /usr/local/nagios/etc/htpasswd.users
    +        AuthUserFile /usr/local/icinga/etc/htpasswd.users
    +
    + +

    +Achtung: Nach dem Kopieren der Konfigurationsdatei für den Web-Server bzw. Ändern des AuthUserFile ist ein Restart des Web-Servers notwendig (service httpd restart bzw. /etc/init.d/apache2 restart). +

    + +
    + +

    Update

    +
    + +

    + +Das Update einer 0.6.x-Version funktioniert (fast) genauso wie die Installation. Bitte beachten Sie, dass Sie beim ”./configure” die gleichen Optionen wie bei der Erstinstallation benutzen! +Bitte prüfen Sie außerdem, ob Sie Änderungen im Verzeichnis share/templates.dist vorgenommen haben. Eigene Templates sollten im Ordner share/templates abgelegt werden.
    + +Achtung: Wenn Sie in der Datei config.php Änderungen vorgenommen haben, sollten Sie diese Datei sichern, bevor sie bei einem “make install-config” überschrieben wird. +

    + +

    +Sie können die Schritte make install-webconf und make install-init überspringen, denn zwischen den 0.6.x-Versionen gab es an dieser Stelle keine Änderungen. +

    + +
    + +

    Die Komponenten

    +
    + +

    + +Nach der Installation sind einige Komponenten von PNP an die passenden Stellen im Dateisystem kopiert worden. +

    + +

    +Im Folgenden sind dies die PHP-Files für das Web-Frontend unter + +

    +
     /usr/local/pnp4nagios/share
    + +

    + +Der Datensammler process_perfdata.pl in + +

    +
     /usr/local/pnp4nagios/libexec
    + +

    + +Beispiel-Config-Files mit der Dateierweiterung -sample in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    + +Die Config-Datei config.php für das Web-Frontend in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    +Zurück zur Übersicht | Konfiguration + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/mobile.html b/share/pnp/documents/de_DE/mobile.html new file mode 100644 index 0000000..4885f57 --- /dev/null +++ b/share/pnp/documents/de_DE/mobile.html @@ -0,0 +1,89 @@ + + + +

    Mobile UI

    +
    + +

    + +Mit PNP4Nagios 0.6.14 ist ein Webinterface für mobile Endgeräte in PNP4Nagios integriert worden. +

    + +

    +Das Design wurde mit jQuery Mobile realisiert und ist somit mit den aktuellen mobilen Browsern kompatibel. Auf der Liste der unterstützten Geräte sind die einzelnen Browser aufgeführt und nach Grad der Unterstützung klassifiziert. +

    + +
    + +

    Landing Page

    +
    + +

    + +Das Webinterface wurde so gestaltet, dass die üblichen Links auf das klassische Interface abgefangen und auf die entsprechende mobile Seite umgeleitet werden. Somit können weiterhin innerhalb der Nagios-Mails Links zu PNP-Graphen eingebunden werden, die je nach Endgerät auf die passende Seite verweisen. + +

    + + + + + + + + + + + + + +
    Classic Mobile
    /pnp4nagios/graph /pnp4nagios/mobile
    /pnp4nagios/graph?host=localhost /pnp4nagios/mobile/host/localhost
    /pnp4nagios/graph?host=localhost&srv=ping /pnp4nagios/mobile/graph/localhost/ping
    + +
    + +

    Browser-Erkennung

    +
    + +

    + +Browser werden anhand ihres “User-Agent”-Strings als mobile Browser erkannt. +Die Erkennung kann in der Datei pnp4nagios/etc/config_local.php beeinflusst werden. +

    +
    +$conf['mobile_devices'] = 'iPhone|iPod|iPad|android';
    +
    + +

    +Die Option 'mobile_devices' beinhaltet einen regulären Ausdruck, welcher mit dem “User Agent” des Browsers verglichen wird. +

    + +

    +Der “User Agent” eines Browsers wird im Webserver-Access-Log protokolliert und sieht für ein iOS-Device in etwa wie folgt aus. +

    +
    +"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"
    +
    + +
    + +

    Screenshots

    +
    + +

    + +Screenshot aufgenommen mit einem iPhone und iOS 4.2 + +

    + + + + + + + + + + +
     Home Screen Homescreen  Loading... Loading …
     Hosts Liste Liste aller Hosts  Liste aller services Liste aller Services eines Hosts
     Graphen Graphen eines Services
    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/modes.html b/share/pnp/documents/de_DE/modes.html new file mode 100644 index 0000000..833104a --- /dev/null +++ b/share/pnp/documents/de_DE/modes.html @@ -0,0 +1,152 @@ + + + +

    Die Kunst Daten zu sammeln

    +
    + +

    + +PNP unterstützt mehrere Arten, die Performance-Daten zu verarbeiten. Die einzelnen Modi unterscheiden sich durch ihre Komplexität und die zu erwartende Performance. +

    + +

    +Das folgende Bild zeigt die Verbindungen zwischen Nagios, PNP und RRDtool +

    + +

    +Nagios führt für jeden Host- und jeden Service, dessen Performance-Daten gesammelt werden sollen, einen Befehl aus. Abhängig vom gewählten Modus werden die Daten entweder direkt an ein Perl-Script übergeben oder in temporäre Dateien geschrieben und später verarbeitet. process_perfdata.pl legt die Datei in XML-Dateien ab und speichert sie mit Hilfe von RRDtool in RRD-Dateien.
    + +

    + +

    +Bevor Ihr euch auf einen Modus festlegt, lest euch alles durch und entscheidet selbst, welcher Weg für eure Installation der Beste ist. +

    + +
    + +

    Die Modi im Vergleich

    +
    + +
    + +

    Synchronous Mode

    +
    + +

    + +Der “Sync Mode” ist der einfachste und am leichtesten einzurichten. Nagios ruft für jeden Service (bzw. Host) zusätzlich das Perl-Script process_perfdata.pl auf, um die Daten zu verarbeiten. +

    + +

    +Der sync-Mode funktioniert sehr gut bis ca. 1000 Services in einem Intervall von 5 Minuten. +Dieser Modus belastet aber auch Nagios am meisten, daher ist es auch in kleinen Installationen ratsam, die weiteren Modi zu beachten. +

    + +
    + +

    Bulk Mode

    +
    + +

    +Im Bulk-Mode schreibt Nagios die benötigten Daten in eine temporäre Datei. Nach Ablauf einer definierten Zeit wird die Datei an einem Stück abgearbeitet und gelöscht. +

    + +

    +Die Anzahl der Aufrufe von process_perfdata.pl reduziert sich um ein Vielfaches. Abhängig von der Zeit und den gesammelten Daten werden wesentlich weniger Systemaufrufe ausgeführt. Dafür läuft process_perfdata.pl länger. +

    + +

    +Hinweis +Bei diesem Modus sollte man die Laufzeit von process_perfdata.pl im Auge behalten. So lange, wie process_perfdata.pl zum Verarbeiten der Daten benötigt, so lange kann Nagios keine Checks ausführen. +

    + +

    +Auszug aus var/perfdata.log: + +

    +
    +2007-10-18 12:05:01 [21138] 71 Lines processed
    +2007-10-18 12:05:01 [21138] .../spool/service-perfdata-1192701894-PID-21138 deleted
    +2007-10-18 12:05:01 [21138] PNP exiting (runtime 0.060969s) ...
    +
    + +

    +71 Zeilen wurden in 0,06 Sekunden verarbeitet. Das ist das Datenvolumen bei ca. 2000 Services und der Verarbeitung im 10-Sekunden-Intervall. Wir haben Nagios also genau für 0.06 Sekunden blockiert. +

    + +
    + +

    Bulk Mode mit NPCD

    +
    + +

    + +Dies ist aus Nagios-Sicht die sauberste Art der Verarbeitung. Nagios wird nicht blockiert. +

    + +

    +Nagios benutzt wieder eine temporäre Datei, um die Daten zu speichern, und führt nach Ablauf der Zeit wieder ein Command aus. Jedoch wird die Datei nicht sofort von Process_perfdata.pl verarbeitet, sondern in ein spool-Verzeichnis verschoben. Da das Verschieben einer Datei im gleichen Filesystem so gut wie keine Zeit beansprucht, ist Nagios sofort wieder in der Lage, wichtige Arbeiten auszuführen. +

    + +

    +Der NPCD ( Nagios Performance C Daemon ) überwacht nun das Verzeichnis auf neue Dateien und übergibt diese an process_perfdata.pl. Die Verarbeitung der Performancedaten ist also komplett von Nagios entkoppelt. NPCD wiederum ist in der Lage, zum Verarbeiten der Daten mehrere Threads zu starten. +

    + +
    + +

    Bulk Mode mit npcdmod

    +
    + +

    + +Achtung +Beginnend mit Nagios 4 haben sich die internen Strukturen geändert, so dass der Start des Moduls fehlschlägt. Bisher gibt es keine Pläne Nagios 4 zu unterstützen. Bitte wählen Sie einen der anderen Modi. +

    + +

    +In diesem Szenario kommt npcdmod.o, ein NEB-Modul, zum Einsatz. +Diese Modul reduziert die Konfiguration des “Bulk Mode mit NPCD” auf zwei Zeilen in der nagios.cfg. +

    + +

    +Dieser Modus ist gleichzusetzen mit dem “Bulk Mode mit NPCD”. Es ist auch genau der gleiche Ablauf und die gleiche Performance. +

    + +
    + +

    Gearman Mode

    +
    + +

    + +

    + +

    +PNP4Nagios kann seit Version 0.6.12 als Gearman Worker betrieben werden. So sind große verteilte Nagios Umgebungen auf Basis von mod_gearman realisierbar. +

    + +

    +Benötigt wird eine fertig eingerichtete mod_gearman Installation wie von Sven Nierlein unter http://labs.consol.de/lang/en/nagios/mod-gearman/ beschrieben. +

    + +
    + +

    Die Entscheidung

    +
    + +

    + +Welchen der beschriebenen Wege ihr verwendet, hängt also stark von der Größe der Nagios-Installation ab. +

    + +

    +Die verwendeten Begriffe werden euch aber in der Dokumentation immer wieder über den Weg laufen. +

    + +

    +Zurück zur Übersicht | Installation + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/new-features.html b/share/pnp/documents/de_DE/new-features.html new file mode 100644 index 0000000..cd7d20d --- /dev/null +++ b/share/pnp/documents/de_DE/new-features.html @@ -0,0 +1,67 @@ + + + +

    Neues in PNP 0.6.x

    +
    + +

    +PNP 0.6.x Preview +

    + +

    +Die Arbeit an der Version 0.6.x ist in vollem Gange. +

    + +

    +Mit Version 0.6.x steigen wir von Subversion auf GIT um. Der Sourcecode ist bereits auf Sourceforge erhältlich. +

    + +

    +http://pnp4nagios.git.sourceforge.net +

    + +

    + +Bisher umgesetzte Funktionen: + +

    +
      +
    • Webfrontend basiert auf Kohana
      +
    • +
    • Webfrontend basiert auf jQuery Themes
      +
    • +
    • Javascript-Funktionen über jQuery Plugins
      +
    • +
    • process_perfdata.pl wird in der Lage sein, pro Datenreihe eine eigene RRD-Datenbank zu verwenden.
      +
    • +
    • Installer weiter verbessert. Angabe von Directory-Layouts über --with-layout
      +
    • +
    • RRDtool-Fehler werden als Bild dargestellt. Keine fehlenden Bilder mehr.
      +
    • +
    • PNP-Templates können keine internen Variablen mehr überschreiben.
      +
    • +
    • PNP-Templates der Version 0.4.x können weiter verwendet werden.
      +
    • +
    • PDF-Funktionen neu umgesetzt.
      +
    • +
    • Template default.php optimiert.
      +
    • +
    • Export aus den RRD-Datenbanken im XML,CSV und JSON Format über die RRDtool “xport” Funktion.
      +
    • +
    • Page-Funktionen neu umgesetzt.
      +
    • +
    • Fehlerseiten verweisen auf online FAQ-Artikel.
      +
    • +
    • Mouseover Popup im Nagios-Frontend über jQuery.clueTip Plugin
      +
    • +
    • Volle Unterstützung des rrdcached.
      +
    • +
    + +

    + +zurück zur Übersicht | Anforderungen + +

    + +
    diff --git a/share/pnp/documents/de_DE/npcd.html b/share/pnp/documents/de_DE/npcd.html new file mode 100644 index 0000000..8d0a79b --- /dev/null +++ b/share/pnp/documents/de_DE/npcd.html @@ -0,0 +1,323 @@ + + + +

    NPCD

    +
    + +

    + +NPCD (Nagios-Perfdata-C-Daemon) wurde geschrieben, um die asynchrone Bearbeitung von Nagios Performance-Daten zu ermöglichen. +

    + +
    + +

    Einleitung

    +
    + +

    + +In großen Nagios-Installationen kann es zu nicht akzeptierbaren Verspätungen seitens der Checks kommen. Das bedeutet, dass Nagios einen Check zum Zeitpunkt x ausführen soll, diesen aber erst y Sekunden später tatsächlich ausführt. +

    + +

    +Wenn man dem Nagios-Daemon mitteilt, dass man nach jedem einzelnen Check auch die Performance-Daten verarbeiten möchte, so geht dies bis zu einem bestimmten Grad gut, ab einer gewissen Anzahl von Checks pro Sekunde allerdings kommt man relativ schnell zu den sog. Latency-Problemen. +

    + +

    +Um die Anzahl der Aktionen pro Check zu verringern, kann man nun PNP im Bulk-Mode verwenden, wobei die Performance-Daten zunächst vom Nagios-Prozess gesammelt und anschließend ebenfalls vom Nagios-Prozess selbst verarbeitet werden. +

    + +

    +Man kann aber auch dem Nagios-Prozess mitteilen, dass die Verarbeitung der Performance-Daten lediglich durch das Verschieben der Dateien in ein Spool-Verzeichnis geschehen soll, welches für den Nagios-Prozess selbst eine sehr schnelle Aktion ist und die Performance nicht nennenswert beeinflusst und somit dem Core mehr Zeit für seine eigentliche Arbeit lässt: weitere Checks ausführen, Alamierungen bereitstellen, etc. +

    + +
    + +

    Wie NPCD arbeitet

    +
    + +

    + +Wie bereits erwähnt, ist die Arbeit der Performance-Daten-Verarbeitung durch das schnelle Verschieben der Datei bereits erledigt, aber das bringt die Performance-Daten noch nicht in die RRD-Datenbank. +

    + +

    +Um den Transport der Performance-Daten-Dateien kümmert sich nun der NPCD-Daemon, unabhängig vom Nagios-Prozess, indem er regelmäßig in das Spool-Verzeichnis guckt und für jede dort gefundene Datei eine Aktion ausführt. +

    + +

    +Nachdem NPCD gestartet wurde, erstellt er sich eine Liste von Dateinamen des Spool-Verzeichnisses und startet für jede gefundene Datei einen Thread zur weiteren Verarbeitung mit Hilfe des perfdata_file_run_cmd und dem optionalen perfdata_file_run_cmd_arg als zusätzlichem Argument. +

    + +

    +Da das Format der Performance-Daten-Dateien dem Format der 'normalen' PNP-Bulk-Modus-Dateien gleicht, kann NPCD nun für jede gefundene Datei also process_perfdata.pl im Bulk Modus aufrufen. +

    + +
    + +

    Vor- und Nachteile

    +
    + +

    + +Pro: +

    +
      +
    • bessere Performance für Nagios
      +
        +
      • aufgrund der vom Nagios-Prozess getrennten Verarbeitung der Performance-Daten hat Nagios mehr Zeit für die wichtigen Dinge
        +
      • +
      +
    • +
    • kein Datenverlust
      +
        +
      • solange Nagios Performance-Daten-Dateien im Spool-Verzeichnis ablegt, gehen keine Daten verloren. Selbst wenn der NPCD mal nicht laufen sollte (Bsp. nach Neustart des Systems), werden die Dateien nach Wiederanlauf in chronologischer Reihenfolge bearbeitet ($TIMET$ Makro beim verschieben ins Spool-Verzeichnis)
        +
      • +
      +
    • +
    + +

    + +Kontra: +

    +
      +
    • Keine Echtzeitverarbeitung der Performance-Daten
      +
        +
      • aufgrund des Rhythmusses, wann Nagios die Performance-Daten-Dateien verschiebt (service_perfdata_file_processing_interval)
        +
      • +
      • nach jedem Lauf durch alle Dateien des Spool-Verzeichnisses wartet NPCD 10 Sekunden lang auf neue Dateien
        +
      • +
      +
    • +
    + +
    + +

    NPCD Config

    +
    + +

    + +NPCD muss zwangsläufig über eine Konfigurationsdatei gesteuert werden. Eine Beispielkonfiguration liegt der PNP-Installation als npcd.cfg-sample bei. +

    + +

    +Nach Umbenennen der -sample Datei zu npcd.cfg kann NPCD nun wie folgt gestartet werden: +

    +
    /usr/local/pnp4nagios/bin/npcd -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +oder + +

    +
    /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +um NPCD im Hintergrund als Daemon laufen zu lassen. +

    + +

    +Hinweis: +Die -sample Datei sollte in jedem Fall in npcd.cfg umbenannt werden, da sie sonst bei einem Update von PNP überschrieben werden könnte. +

    + +
    + +

    npcd.cfg-sample

    +
    + +

    + +Dies sind die essentiellen Konfigurationsdirektiven für NPCD: +

    +
    # Privilege Options
    +user = nagios
    +group = nagios
    +
    +# Logging Options
    +log_type = syslog
    +log_file = /usr/local/pnp4nagios/var/npcd.log
    +max_logfile_size = 10485760
    +log_level=0
    +
    +# Processing Options
    +perfdata_spool_dir = /usr/local/pnp4nagios/var/spool/perfdata/
    +perfdata_file_run_cmd = /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +perfdata_file_run_cmd_args = -b
    +
    +# Thread Options
    +npcd_max_threads=5
    +
    +# greedy options
    +use_load_threshold = 0
    +load_threshold = 10.0
    +
    +# Process Options
    +pid_file=/var/run/npcd.pid
    +
    + +
    + +

    Die Direktiven

    +
    +
      +
    • Privilege-Optionen
      +
        +
      • user <username>
        +
          +
        • NPCD versucht die Userberechtigung zu diesem User zu wechseln.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      • group <groupname>
        +
          +
        • NPCD versucht die Gruppenberechtigung zu dieser Gruppe zu wechseln.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      +
    • +
    • Logging-Optionen
      +
        +
      • log_type <syslog> oder <file>
        +
          +
        • Log-Type, den NPCD zum Loggen verwenden wird
          +
        • +
        • Default: syslog
          +
        • +
        +
      • +
      • log_file </pfad/zu/datei>
        +
          +
        • Falls log_type = file wird diese Logdatei verwendet
          +
        • +
        • Default: /usr/local/pnp4nagios/var/npcd.log
          +
        • +
        +
      • +
      • max_logfile_size <bytes>
        +
          +
        • NPCD wird nach Erreichen der hier angegebenen Dateigröße eigenständig eine Logrotation durchführen
          +
        • +
        • Default: 10485760 = 10 MByte
          +
        • +
        +
      • +
      • log_level <integer>
        +
          +
        • Wie viel soll aufgezeichnet werden, möglich ist:
          +
            +
          • 0 = Kein Log - außer Fehlern
            +
          • +
          • 1 = wenig Log - etwas mehr Aufzeichnen
            +
          • +
          • 2 = Mehr Log (aktuell ALLES)
            +
          • +
          • -1 = DEBUG Mode - Es wird alles aufgezeichnet und die Bearbeitung wird verlangsamt
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      +
    • +
    • Bearbeitungs-Optionen
      +
        +
      • perfdata_spool_dir </path/to/spool/dir/>
        +
          +
        • Das Verzeichnis, in das Nagios die Dateien verschiebt
          +
        • +
        • Default: /usr/local/pnp4nagios/var/spool/
          +
        • +
        +
      • +
      • perfdata_file_run_cmd </path/to/bin/filename>
        +
          +
        • Das Programm, welches Nagios für jede Datei aufrufen soll
          +
        • +
        • Default: /usr/local/pnp4nagios/libexec/process_perfdata.pl
          +
        • +
        +
      • +
      • perfdata_file_run_cmd_args <option>
        +
          +
        • Das Argument, welches optional an perfdata_file_run_cmd angehängt wird
          +
        • +
        • Default: ”-b”
          +
        • +
        • :!: Die Kommandozeile wird nach folgendem Schema aufgebaut:
          <perfdata_file_run_cmd> <perfdata_file_run_cmd_args> <filename_from_perfdata_spool_dir>
          +
          +
        • +
        +
      • +
      +
    • +
    • Thread-Optionen
      +
        +
      • npcd_max_threads <integer value>
        +
          +
        • Anzahl der maximal zu startenden parallelen Threads
          +
        • +
        • Default: 5
          +
        • +
        +
      • +
      +
    • +
    • Greedy-Optionen
      +
        +
      • use_load_threshold <0 oder 1>
        +
          +
        • definiert, ob NPCD bei Erreichen des load_thresholds die Anzahl der Threads begrenzen soll
          +
            +
          • 0 = ausschalten (weitere Threads starten)
            +
          • +
          • 1 = einschalten
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      • load_threshold <float value>
        +
          +
        • wenn use_load_threshold auf 1 gesetzt ist, werden bei Erreichen dieses load limits keine neuen Threads gestartet
          +
        • +
        • Default: 10.0
          +
        • +
        +
      • +
      +
    • +
    • Process-Optionen
      +
        +
      • pid_file </path/to/pid.file>
        +
          +
        • Pfad zum PID File
          +
        • +
        • Default: /var/run/npcd.pid
          +
        • +
        +
      • +
      +
    • +
    + +

    + +zurück zur Übersicht | Wrapper-Script + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/pages.html b/share/pnp/documents/de_DE/pages.html new file mode 100644 index 0000000..b518764 --- /dev/null +++ b/share/pnp/documents/de_DE/pages.html @@ -0,0 +1,93 @@ + + + +

    Pages

    +
    + +

    + +„pages“ bieten die Möglichkeit, Grafiken von verschiedenen Hosts/Services auf einer Seite zusammenzufassen. Auf diese Weise können z.B. die Übertragungsraten der Netzwerk-Interfaces aller Tape-Libraries dargestellt werden. Innerhalb der Definitionen sind reguläre Ausdrücke möglich, so dass – entsprechende Namen vorausgesetzt - mit wenig Aufwand viel erreicht werden kann. +Das Verzeichnis, das in config.php durch den Konfigurationseintrag „$conf['page_dir']“ angegeben wurde, enthält ein oder mehrere Dateien mit der Endung „.cfg“. +

    + +

    +Kommentare beginnen mit einem '#' und sind auch innerhalb einer Zeile möglich. +Jede Datei enthält eine „page“-Definition, die neben dem Namen der Seite festlegt, ob die nachfolgenden Grafikdefinitionen reguläre Ausdrücke enthalten.
    + +Die Bezeichnung hinter page_name erscheint in der Liste der verfügbaren Seiten und wird als Titel im Browser angezeigt. +Achtung: “host_name” und “service_desc” beziehen sich auf die Namen der Dateien im perfdata-Ordner, nicht auf die Nagios-Bezeichnungen. Leerzeichen werden durch Unterstriche (“_”) ersetzt. +

    +
    define  page  {
    +        use_regex 1		# 0 = keine regulären Ausdrücke, 1 = reguläre Ausdrücke
    +        page_name Test-Seite	# Beschreibung der Seite
    +}
    + +

    +Danach folgen ein oder mehrere „graph“-Definitionen: +

    +
    define graph {
    +        host_name       host1,host2,host3
    +        service_desc    Current_Load
    +}
    + +

    + +Achtung: Damit die oben gezeigte Liste von Host-Namen funktioniert, muss use_regex 0 gesetzt sein! +

    +
    define graph {
    +        host_name       host4
    +        service_desc    Current_Users
    +}
    + +

    +Und jetzt mit regulären Ausdrücken. Zuerst alle Hosts, deren Name mit „Tape“ beginnen: + +

    +
    define graph {
    +        host_name       ^Tape
    +        service_desc    Traffic
    +}
    + +

    +alle Hosts, deren Namen mit “00” enden + +

    +
    define graph {
    +        host_name       00$
    +        service_desc    Load
    +}
    + +

    +alle Services des localhost, deren Namen ein „a“ oder „o“ enthalten: + +

    +
    define graph {
    +        host_name       localhost
    +        service_desc    a|o
    +}
    + +

    +alle Services, die im Namen nach einem „_“ (mindestens) drei Ziffern haben auf allen Hosts, deren Namen mit „UX“ beginnen: + +

    +
    define graph {
    +        host_name       ^UX
    +        service_desc    _\d{3}
    +}
    + +

    +In einigen Fällen möchten Sie vielleicht die Anzeige auf einen Graphen beschränken. Um dies zu erreichen, können Sie die optionale Direktive “source” benutzen, gefolgt von einer Zahl, die die Position in der RRD-Datei angibt. Die Zählung beginnt ab 0 + +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    PING
    +       source          1
    +}
    + +

    +zurück zur Übersicht | Datenexport + +

    + +
    diff --git a/share/pnp/documents/de_DE/perfdata_format.html b/share/pnp/documents/de_DE/perfdata_format.html new file mode 100644 index 0000000..7488ebf --- /dev/null +++ b/share/pnp/documents/de_DE/perfdata_format.html @@ -0,0 +1,62 @@ + + + + + + + +
    2.6. Performance-Daten
    + +

    + +'Bezeichnung'=Wert[UOM];[warn];[crit];[min];[max] +

    + +

    +Anmerkungen: + +

    +
      +
    1. Leerzeichen trennen Listen von Bezeichnung/Werte-Paaren
      +
    2. +
    3. Bezeichnungen können beliebige Zeichen enthalten
      +
    4. +
    5. die Bezeichnung muss in Apostrophe eingeschlossen sein, wenn diese Gleichheitszeichen (=), Apostroph (') oder Leerzeichen ( ) enthält, ansonsten sind die Apostrophe optional
      +
    6. +
    7. die Länge der Bezeichnung ist beliebig, aber idealerweise sind die ersten 19 Zeichen eindeutig (aufgrund einer Beschränkung in RRD). Bitte beachten Sie, dass es eine Längenbegrenzung bei der Menge von Daten gibt, die von NRPE an Nagios geliefert werden kann
      +
    8. +
    9. um ein Apostroph darzustellen, nutzen Sie zwei einzelne Apostrophe
      +
    10. +
    11. warn, crit, min und/oder max können leer sein (z.B. wenn der Schwellwert nicht definiert ist oder wenn min oder max nicht zutreffen). Nachfolgende, nicht gefüllte Semikola können entfallen
      +
    12. +
    13. min und max sind nicht erforderlich, wenn UOM = %
      +
    14. +
    15. Wert, min und max sind aus der Klasse [-0-9.] (Ziffern, Minuszeichen und Dezimalpunkt). Alle müssen das gleiche UOM benutzen
      +
    16. +
    17. warn und crit sind im “Range”-Format (siehe Abschnitt 2.5 der Original-Dokumentation). Alle müssen das gleiche UOM benutzen.
      +
    18. +
    19. UOM (unit of measurement, Maßeinheit) ist eins von:
      +
        +
      • keine Einheit angegeben - angenommen wird eine Zahl (int oder float) von Dingen (z.B. Benutzer, Prozesse, Load)
        +
      • +
      • s - Sekunden (auch us, ms)
        +
      • +
      • % - Prozent
        +
      • +
      • B - Bytes (auch KB, MB, TB; GB?)
        +
      • +
      • c - ein fortlaufender Zähler (z.B. Bytes, die über ein Interface übertragen werden)
        +
      • +
      +
    20. +
    + +

    + +Es bleibt Drittanbietern überlassen, aus den Performance-Daten Graphen zu erzeugen.| +

    + +

    +Quelle: http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN201 + +

    diff --git a/share/pnp/documents/de_DE/rrd_convert.html b/share/pnp/documents/de_DE/rrd_convert.html new file mode 100644 index 0000000..682eec6 --- /dev/null +++ b/share/pnp/documents/de_DE/rrd_convert.html @@ -0,0 +1,84 @@ + + + +

    RRD_STORAGE_TYPE = MULTIPLE

    +
    + +

    + +Verfügbar ab PNP 0.6.3 +

    + +

    +Mit PNP-Version 0.6 ist es möglich, die Performance-Daten nicht in einer einzelnen RRD-Datenbank (SINGLE), sondern in mehreren RRD Datenbanken (MULTIPLE) zu speichern. +

    + +

    +Nach dem Anlegen eines RRD-Files ist es nicht mehr möglich, dieses um eine Datasource (DS) zu erweitern. Daraus ergeben sich Probleme für Nagios-Plugins, die im Laufe der Zeit die Anzahl der Datenreihen dynamisch ändern. +

    + +

    +Ein Beispiel wäre check_disk, wenn man pauschal alle verfügbaren Filesysteme in einem Service überwacht. Kommt ein Filesystem hinzu, so kann die RRD-Datenbank nicht mehr aktualisiert werden. Die Struktur der neuen Daten passt einfach nicht mehr zur RRD-Struktur. +

    + +

    +PNP arbeitet per Default mit der Option RRD_STORAGE_TYPE = SINGLE, welche in der process_perfdata.cfg definiert ist. +

    + +

    +Diese Einstellung sollte nicht global verändert werden, da PNP nach der Umstellung auf MULTIPLE sofort beginnt, neue RRD-Files anzulegen. Alte Daten gehen damit sofort verloren! +

    + +

    +Weiterhin ist es im Hinblick auf die Performance nicht sinnvoll, global mit RRD_STORAGE_TYPE = MULTIPLE zu arbeiten. Die Anzahl der RRD-Datenbanken und somit auch der Disk-I/O während der Updates vervielfacht sich. Entsprechend sollte man mit Bedacht wählen, welche Nagios-Check-Commands mit welcher Einstellung behandelt werden sollen. +

    + +

    +Im Abschnitt Custom Templates ist beschrieben, wie die Einstellungen vorgenommen werden können. +

    + +
    + +

    Ein Konverter

    +
    + +

    + +Das Script libexec/rrd_convert.pl dient zum Umschalten des RRD_STORAGE_TYPE auf MULTIPLE und zum gleichzeitigen migrieren der RRD-Datenbanken. +

    + +

    +Maßgeblich ist dabei wie immer bei PNP das Nagios-Check-Command. +

    +
    rrd_convert.pl --check_command=<nagios_check_command> | --list_commands [ --dry-run ] [ --tmp_dir=<temp-dir> ]
    +[[ --no_structure_check ]]
    + +

    +Das Script erwartet über die Option --check-command= das Check-Command, nach dem gesucht werden soll. +

    + +

    +rrd_convert.pl wird nun alle PNP-XML-Dateien nach diesem Command durchsuchen und eine Statistik ausgeben. +

    + +

    +Nach Bestätigung durch den User beginnt das Konvertieren der einzelnen RRD-Datenbanken, wobei der aktuelle Ablauf angezeigt wird. Das Script endet, wenn Sie <ENTER> drücken, also geben Sie bitte einen Buchstaben ein. +

    + +

    +Die Option --dry-run sorgt dafür, dass die RRD-Datenbanken zwar konvertiert, jedoch in /tmp/rrd_convert in separaten Verzeichnissen je Host gespeichert werden. So kann man sich einen Überblick über die zu erwartende Laufzeit und das Datenvolumen verschaffen. +

    + +

    +Wenn Sie das temporäre Verzeichnis ändern möchten, dann können Sie das mit Hilfe der Option --tmp_dir=<alternatives TMP-Directory> tun. + +Ab und zu passt die Anzahl der Datasources in den RRD-Dateien nicht zu der Anzahl in den XML-Dateien. Das passiert z.B. dann, wenn Plugins plötzlich eine andere Zahl von Datenreihen liefern (siehe oben check_disk). Mit der Option --no_structure_check'' werden auch diese RRD-Dateien konvertiert. +

    + +

    +back to contents | NPCD-Details + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/rrdcached.html b/share/pnp/documents/de_DE/rrdcached.html new file mode 100644 index 0000000..131ebf6 --- /dev/null +++ b/share/pnp/documents/de_DE/rrdcached.html @@ -0,0 +1,153 @@ + + + +

    RRDtool Cache Daemon

    +
    + +

    + +In großen Installationen wird man über kurz oder lang feststellen, dass die Verarbeitung der Performance-Daten eine recht hohe I/O-Last zur Folge hat. RRDtool muss extrem viele Updates auf Disk schreiben, kann dabei jedoch den Disk-Cache nicht optimal ausnutzen. +

    + +

    +Eine Optimierung stellt das Sammeln und Sortieren der Daten dar. Es ist für das System effektiver, viele Updates im Block in eine RRD-Datenbank zu schreiben. Der Disk-Cache kann dabei effektiver genutzt werden. +

    + +

    +In der aktuellen RRDtool-Version ( SVN trunk 1550+ ) ist der rrdcached enthalten, der genau diese Situation verbessern soll. +

    + +

    +An dieser Stelle möchte ich mich bei Florian octo Forster, Kevin Brintnall und Tobi Oetiker bedanken. Die Entwicklung dieses Daemons wurde vorbildlich auf der rrd-developers Mailingliste koordiniert. +

    + +
    + +

    Arbeitsweise

    +
    + +

    + +Der rrdcached arbeitet als Daemon im Hintergrund und öffnet einen UNIX- oder TCP-Socket, auf dem er auf Anfragen von rrdtool wartet. Aufgrund von Sicherheitsbedenken ist es in neueren Versionen von rrdcached aber nicht mehr möglich absolute Pfadangaben (wie bei pnp4nagios üblich) bei Netzwerkzugriffen zu verwenden, daher ist derzeit nur Nutzung von UNIX-Sockets möglich. +

    + +
    + +

    rrdcached

    +
    + +

    + +Der rrdcached kennt einige wichtige Optionen, die beim Start übergeben werden. +

    + +

    +Option -l definiert den Socket, auf dem der rrdcached Requests annimmt. Der Default-UDP-Port ist 42217, der Default-UNIX-Socket /tmp/rrdcached.sock. +

    +
    +-l unix:/pfad/zum/rrdcached.sock
    +-l /pfad/zum/rrdcached.sock
    +-l 127.0.0.1
    +-l 127.0.0.1:8888
    +
    + +

    +Option -P gibt die für die nachfolgenden Sockets (mit -l spezifiziert) erlaubten Befehle an, welche auf die RRD-Datenbanken angewendet werden können. +

    +
    -P FLUSH,PENDING
    + +

    +Option -s erlaubt es die Gruppenzugehörigkeit der nachfolgenden UNIX-Sockets zu ändern. +

    +
    -s nagios
    + +

    +Option -m setzt die Zugriffsrechte für die nachfolgenden UNIX-Sockets auf die (in oktal) angegebenen Werte. +

    +
    -m 0660
    + +

    +Option -w bestimmt den Intervall in Sekunden, in dem die Daten auf Disk geschrieben werden sollen. +

    +
    -w 1800
    + +

    +Option -z definiert einen Delay, der die über die Option -w definierten Schreibzyklen in einen zufälligen Bereich [0-delay] verteilt, um gleichzeitige Schreibzugriffe zu verhindern. Der Wert der Option -z darf nicht größer gewählt werden als -w. +

    +
    -z 1800
    + +

    +Option -p definiert ein PID File +

    +
    -p /var/run/rrdcached.pid
    + +

    +Option -j definiert den Pfad zu einem Journal-Verzeichnis. Dort werden alle Aufträge protokolliert und ggf. beim nächsten Start nachgefahren, falls der rrdcached-Daemon abstürzt. +

    +
    -j /var/cache/rrdcached
    + +

    +Daraus ergibt sich beispielsweise ein Aufruf von rrdached mit folgenden Parametern +

    +
     rrdcached -w 1800 -z 1800 -p /tmp/rrdcached.pid -j /tmp -s nagios -m 0660 -l unix:/tmp/rrdcached.sock
    + +
    + +

    rrdtool

    +
    + +

    + +RRDtool selbst wird die Existenz des Daemons über die Option --daemon=<socket> mitgeteilt. + +

    +
     rrdtool --daemon=unix:/tmp/rrdcached.sock update ...
    + +

    + +Dies muss natürlich mit den Startoptionen des rrdcached übereinstimmen! +

    + +
    + +

    Integration in PNP

    +
    + +

    + +Da zwei Bestandteile von PNP auf den rrdcached vorbereitet werden müssen, ergeben sich Änderungen in zwei Config-Files. Außerdem muß der User unter welchem der Webserver läuft zur Gruppe unter der Nagios läuft hinzugefügt werden. +

    + +

    +1. Anpassen der process_perfdata.cfg für den Datensammler process_perfdata.pl +

    +
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +RRD_DAEMON_OPTS = unix:/var/run/rrdcached.sock
    +
    + +

    +2. Anpassen der config_local.php (bzw. config.php) für das Webinterface +

    +
    +#
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +# $conf['RRD_DAEMON_OPTS'] = 'unix:/tmp/rrdcached.sock';
    +$conf['RRD_DAEMON_OPTS'] = 'unix:/var/run/rrdcached.sock';
    +
    + +

    +Die passenden Optionen sind bereits in den Beispieldateien enthalten. +

    + +

    +zurück zur Übersicht | migrieren von RRD-Dateien + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/start.html b/share/pnp/documents/de_DE/start.html new file mode 100644 index 0000000..6e5e38b --- /dev/null +++ b/share/pnp/documents/de_DE/start.html @@ -0,0 +1,199 @@ + + + +

    Dokumentation

    +
    +
    + +
    +
    PNP4Nagios Broker Module npcdmod.o ist nicht kompatibel mit Nagios Core 4.x
    +
    + +
    + +

    + +

    +

    + +

    + +Theme "smoothness" +

    + +

    +PNP ist ein Addon für Nagios, das es ermöglicht, die von Nagios Plugins gelieferten Performancedaten zu analysieren und automatisch in RRD Datenbanken zu speichern. +

    + +

    + +Während der Entwicklung von PNP haben wir Wert auf eine einfache Installation und auf wenig Aufwand im laufenden Betrieb gelegt. Ein Administrator hat besseres zu tun als Graphing Tools zu konfigurieren. +

    + +

    +Um diese Aufgabe zu erfüllen, setzen wir bewusst auf Standards. PNP verarbeitet nur Performancedaten, die sich strikt an die Developer Guidelines für Nagios Plugins halten. Mit dieser Einschränkung wollen wir bewusst die Arbeit der Nagios Plugin Developer honorieren, die sich für die Einhaltung der Richtlinien einsetzen. +

    + +

    +Für alle, die nun noch neugierig sind, steht die folgende Dokumentation bereit, um den Einstieg in PNP zu erleichtern. +

    + +

    +komplette Dokumentation auf "einer" Seite +

    + +
    + +

    Dokumentation

    +
    + + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/timeranges.html b/share/pnp/documents/de_DE/timeranges.html new file mode 100644 index 0000000..f9a6123 --- /dev/null +++ b/share/pnp/documents/de_DE/timeranges.html @@ -0,0 +1,96 @@ + + + +

    Timeranges

    +
    + +

    + +In der Übersicht zeigt PNP fünf Zeitbereiche, die frei in der config.php definiert werden können. +

    + +

    +Es gibt aber auch die Möglichkeit, die Zeitbereiche über die URL zu beeinflussen. Dies ist hilfreich, wenn z.B. automatisch PDF-Dokumente erstellt werden sollen +

    + +

    +Die Zeitbereiche werden über die Optionen start und end definiert. +

    + +

    +Beispiel: + +

    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=-1week
    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=2011102322:50:00&end=2011102409:50:00
    + +

    + +Der Startzeitpunkt der Graphen wird somit, ausgehend vom aktuellen Datum, um eine Woche nach hinten verschoben. Der Endzeitpunkt bleibt auf dem aktuellen Zeitstempel. Aber auch end lässt sich über diesen Weg beeinflussen, wobei beide Optionen auch einzeln manipuliert werden dürfen. +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    start end view Ergebnis
    Alle Ansichten enden mit der aktuellen Zeit
    x Alle Ansichten beginnen mit dem angegebenen Datum
    x Alle Ansichten enden mit dem angegebenen Datum
    x x Eine Ansicht zwischen den beiden Zeitangaben
    x Eine Ansicht endet mit der aktuellen Zeit
    x x Eine Ansicht beginnt mit dem angegebenen Datum
    x x Eine Ansicht endet mit dem angegebenen Datum
    + +

    + +Beispiele zur Datumsangabe: + +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Format Beschreibung
    2009W04 4. KW 2009
    1.5.2009 1. Mai 2009
    -1 day Einen Tag zurück
    -3 weeks 3 Wochen zurück
    -1 year Ein Jahr zurück
    yesterday Gestern
    2011102322:50:00 23.10.2011 ab 22:50:00 Uhr
    + +

    + +zurück zur Übersicht | Pages + +

    + +
    diff --git a/share/pnp/documents/de_DE/tpl.html b/share/pnp/documents/de_DE/tpl.html new file mode 100644 index 0000000..99c6aee --- /dev/null +++ b/share/pnp/documents/de_DE/tpl.html @@ -0,0 +1,243 @@ + + + +

    Was sind Templates ?

    +
    + +

    + +PNP benutzt Templates, um das Aussehen der RRD-Graphen zu beeinflussen. +

    + +

    +Dabei bestimmt das verwendete check_command, welches Template zur Darstellung herangezogen wird. Im Folgenden wird beschrieben, wo Templates gespeichert werden und wie die Entscheidung für das “richtige” Template getroffen wird. +

    + +
    + +

    Wann wird welches Template verwendet ?

    +
    + +

    + +Templates werden an zwei Stellen im Dateisystem gespeichert. + +

    +
      +
    • share/templates.dist - für Templates, die im PNP-Paket bereits enthalten sind.
      +
    • +
    • share/templates - für selbst erstellte Templates. Diese werden bei Updates nicht verändert.
      +
    • +
    + +

    + +Weiterhin können seit Version 0.6.5 weitere Template Verzeichnisse in der Config Datei pnp4nagios/etc/config.php hinzugefügt werden. +

    + +

    +Soll der Graph für den Service “http” auf Host “localhost” angezeigt werden, so sucht PNP zuerst nach der XML-Datei perfdata/localhost/http.xml und liest diese ein. Diese XML-Dateien werden automatisch erstellt und enthalten Informationen zum jeweiligen Host und Service. Weiterhin enthält der Kopf Informationen über das Plugin und die Performance-Daten. Im folgenden Beispiel erkennt man anhand des XML-Tags <TEMPLATE>, welches PNP-Template für diesen Graphen verwendet werden soll. +

    + +

    +/localhost/http.xml + +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>2</DS>
    +    <NAME>size</NAME>
    +    <UNIT>B</UNIT>
    +    <ACT>263</ACT>
    +    <WARN></WARN>
    +    <CRIT></CRIT>
    +    <MIN>0</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +PNP hängt .php an und sucht nun nach einem Template mit dem Namen check_http.php in folgender Reihenfolge: + +

    +
      +
    1. templates/check_http.php
      +
    2. +
    3. templates.dist/check_http.php
      +
    4. +
    5. templates/default.php
      +
    6. +
    7. templates.dist/default.php
      +
    8. +
    + +

    + +Das Template default.php nimmt somit eine Sonderstellung ein und wird immer verwendet, wenn vorher kein anderes Template gefunden wird. +

    + +
    + +

    Eigene Templates erstellen

    +
    + +

    + +PNP-Templates sind PHP-Dateien, die zur Laufzeit von PNP über die PHP-Funktion include() eingebunden werden. +Dies bedeutet, dass jeder PHP-Code in Templates interpretiert wird. Daher ist die Manipulation aller Werte über PHP möglich. +

    + +

    +PNP-Templates müssen folgende Eigenschaften besitzen: +

    +
      +
    1. Templates müssen gültigen PHP-Code enthalten.
      +
    2. +
    3. Templates dürfen keine Ausgabe erzeugen.
      +
    4. +
    5. innerhalb der Templates werden die zwei Arrays $opt[] und $def[] gefüllt.
      +
    6. +
    + +

    + +Die beiden PHP-Arrays $opt[] und $def[] zusammen bilden den Aufruf von 'rrdtool graph'. Somit sind alle Optionen möglich, die RRDtool bietet. Die Optionen von RRDtool sind auf der RRDtool Homepage genauestens beschrieben. +

    + +

    +Wenn beide Arrays mehrere Datensätze enthalten, so wird für jeden Datensatz ein Graph erstellt. +

    + +

    +Weiterhin stehen innerhalb der Templates die Daten aus dem zugehörigen XML-File zur Verfügung, die zum Erstellen der Graphen wieder verwendet werden können. +

    + +

    +Am Beispiel des recht einfachen Templates response.php lassen sich die wichtigsten Optionen recht gut beschreiben. +

    +
    <?php
    +#
    +$opt[1] = "--title \"Response Time For $hostname / $servicedesc\" ";
    +#
    +$def[1] =  "DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE " ;
    +$def[1] .= "AREA:var1#00FF00:\"Response Times \" " ;
    +$def[1] .= "LINE1:var1#000000 " ;
    +$def[1] .= "GPRINT:var1:LAST:\"%3.4lg %s$UNIT[1] LAST \" ";
    +$def[1] .= "GPRINT:var1:MAX:\"%3.4lg %s$UNIT[1] MAX \" ";
    +$def[1] .= "GPRINT:var1:AVERAGE:\"%3.4lg %s$UNIT[1] AVERAGE \" ";
    +?>
    + +

    +$opt[1] = ”--title …” setzt RRDtool-Optionen für den ersten Datensatz im Array. Hier ist das der Titel des Graphen. +Wie man sieht, werden eingebettete Anführungszeichen durch einen Backslash (\) maskiert. +Die beiden Variablen $hostname und $servicedesc sind durch den Aufruf von PNP ermittelt worden und stehen nun auch im Template zur Verfügung. +

    + +

    +$def[1] = “DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE ”; definiert, welche Daten aus welchem RRD-File gelesen werden sollen. $RRDFILE[1] enthält den Pfad zur RRD-Datei dieses Services. $DS[1] verweist auf die Datenreihe eins aus der RRD-Datei. +

    + +

    +$def[1] .= “AREA:var1#00FF00:\”Response Times \” ”; durch den Operator ”.=” werden weitere Daten an das Array $def[1] angehängt. Gezeichnet wird eine Fläche (AREA) mit den Daten der Variable var1. Die Farbe wird im HEX-Code #00FF00 definiert. Als Beschriftung wird “Response Times” verwendet. +

    + +

    +$def[1] .= “LINE1:var1#000000 ”; Als Abschluss der eben gezeichneten Fläche wird eine Linie (LINE1) in Schwarz (#000000) gezeichnet. +

    + +

    + +$def[1] .= “GPRINT:var1:LAST:\”%3.4lg %s$UNIT[1] LAST \” ”;
    + +$def[1] .= “GPRINT:var1:MAX:\”%3.4lg %s$UNIT[1] MAX \” ”;
    + +$def[1] .= “GPRINT:var1:AVERAGE:\”%3.4lg %s$UNIT[1] AVERAGE \” ”;
    +

    + +

    +Die drei GPRINT Zeilen bilden die Legende des Graphen. Die aktuellen Werte werden dabei über die printf Syntax formatiert. +

    + +
    + +

    Verfügbare Variablen

    +
    + +

    + +PNP speichert über den Datensammler process_perfdata.pl zur Laufzeit nicht nur Performancedaten, sondern auch weitere von Nagios exportierte Werte. Diese Werte werden in der jeweils für den Service gültigen XML-Datei gespeichert. +

    + +

    +Im ersten Teil der XML-Datei werden die Performancedaten in ihre Einzelteile zerlegt gespeichert. +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +Das Feld <DS> bezeichnet die DataSource und dient der Identifizierung der Datenreihen innerhalb der RRD-Dateien, ist aber auch der Schlüssel der folgenden Arrays. +

    + +

    +Im Array $UNIT[1] ist somit die Einheit der ersten Datenreihe gespeichert. +

    + +

    +Die XML-Datei enthält jedoch noch weitere Informationen. Wird process_perdata.pl im sync-Mode verwendet, so sind alle verfügbaren Makros mit den aktuellen Werten verfügbar. Der folgende Ausschnitt ist jedoch zu Gunsten der Lesbarkeit gekürzt. +

    +
    <NAGIOS>
    +...
    +  <NAGIOS_SERVICENOTIFICATIONID>8418</NAGIOS_SERVICENOTIFICATIONID>
    +  <NAGIOS_SERVICENOTIFICATIONNUMBER>0</NAGIOS_SERVICENOTIFICATIONNUMBER>
    +  <NAGIOS_SERVICEOUTPUT>HTTP OK HTTP/1.1 200 OK - 10087 bytes in 0.125 seconds</NAGIOS_SERVICEOUTPUT>
    +  <NAGIOS_SERVICEPERCENTCHANGE>0.00</NAGIOS_SERVICEPERCENTCHANGE>
    +  <NAGIOS_SERVICEPERFDATA>time=0.124811s;;;0.000000 size=10087B;;;0</NAGIOS_SERVICEPERFDATA>
    +  <NAGIOS_SERVICEPERFDATAFILE></NAGIOS_SERVICEPERFDATAFILE>
    +  <NAGIOS_SERVICEPROBLEMID>0</NAGIOS_SERVICEPROBLEMID>
    +  <NAGIOS_SERVICESTATE>OK</NAGIOS_SERVICESTATE>
    +  <NAGIOS_SERVICESTATEID>0</NAGIOS_SERVICESTATEID>
    +  <NAGIOS_SERVICESTATETYPE>HARD</NAGIOS_SERVICESTATETYPE>
    +  <NAGIOS_SHORTDATETIME>27-12-2007 13:51:23</NAGIOS_SHORTDATETIME>
    +...
    +</NAGIOS>
    + +

    +Die einzelnen XML-Felder sind als Variablen in den PNP-Templates verwendbar, wobei jedes Feld als Variable gleichen Namens verfügbar ist. +

    + +

    +Aus <NAGIOS_SERVICEOUTPUT> wird die Variable $NAGIOS_SERVICEOUTPUT. +

    + +

    +zurück zur Übersicht | Custom Templates + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/tpl_custom.html b/share/pnp/documents/de_DE/tpl_custom.html new file mode 100644 index 0000000..6be07ef --- /dev/null +++ b/share/pnp/documents/de_DE/tpl_custom.html @@ -0,0 +1,326 @@ + + + +

    Custom Templates

    +
    + +

    + +Wie bereits unter ”Was sind Templates ?” beschrieben, ist die Darstellung der Graphen abhängig vom verwendeten Check-Command. +

    + +

    +Es gibt jedoch Situationen, in denen dieses Verhalten übersteuert werden muss, zum Beispiel dann wenn allgemeingültige Commands definiert wurden. +

    + +

    +PNP, speziell process_perfdata.pl, sucht zur Laufzeit für jedes check_command im Verzeichnis etc/check_commands nach einer Config-Datei (<check_command>.cfg) und liest diese, wenn vorhanden, ein. +Folgende Optionen können darin definiert werden: +

    + +
    + +

    CUSTOM_TEMPLATE

    +
    + +

    +Geht man von folgendem Beispiel einer Nagios command-Definition aus: + +

    +
    +define command {
    +  command_name check_nrpe
    +  command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a "$ARG2$"
    +}
    +
    + +

    +Die Folge wäre, dass immer das Template check_nrpe.php verwendet werden würde, auch wenn auf dem zu überwachenden Server via NRPE ein ganz anderes Plugin aufgerufen wurde. +

    + +

    +Da unser Beispiel-Command check_nrpe lautet, wird nach etc/check_commands/check_nrpe.cfg gesucht. +

    + +

    +Eine Beispiel-Config wird bereits während der Installation mit der Dateierweiterung .cfg-sample in etc/check_commands gespeichert. +

    +
    +# check_command check_nrpe!load!-w 4,4,4 -c 5,5,5
    +# ________0__________|       |       |
    +# ________1__________________|       |
    +# ________2__________________________|
    +#
    +CUSTOM_TEMPLATE = 1
    +
    + +

    +CUSTOM_TEMPLATE = 1 sorgt dafür, dass nur der Inhalt von $ARG1$ als Template-Name verwendet wird. Da in diesem Beispiel $ARG1$ mit dem Wert “load” gefüllt ist, ergibt sich als Template-Name “load.php” +

    + +

    +CUSTOM_TEMPLATE = 0,1 ergibt → “check_nrpe_load.php” +

    + +

    +CUSTOM_TEMPLATE = 1,0 ergibt → “load_check_nrpe.php” +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    DATATYPE

    +
    + +

    + +Über die Option “DATATYPE” kann beeinflusst werden, mit welchem Datentyp die RRD-Datenbank angelegt werden soll. +Default ist in diesem Fall “GAUGE”. Für fortlaufende Werte wird aber hier der Datentyp COUNTER benötigt. +Normalerweise sollten Plugin-Entwickler für Daten von Typ Counter die Einheit “c” verwenden. Dies ist jedoch nicht immer der Fall. +

    + +

    +Alle Datenreihen auf Typ COUNTER einstellen. + +

    +
    DATATYPE = COUNTER
    + +

    +Einzelnen Datenreihen spezielle Datentypen zuweisen + +

    +
    DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER
    + +

    +Weitere Datentypen sind in der RRDTool-Dokumentation unter rrdcreate erklärt. +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    USE_MIN_ON_CREATE und USE_MAX_ON_CREATE

    +
    + +

    + +In einigen wenigen Situationen ist es notwendig, die für RRDTool gültigen Daten zu begrenzen. +

    + +

    +RRD-Datenbanken lassen sich mit definierten Minimum- und Maximum-Werten anlegen. +Weitere Infos unter http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +Berücksichtigen des Maximum-Wertes aus den Performance-Daten + +

    +
    USE_MAX_ON_CREATE = 1
    + +

    +Berücksichtigen des Minimum-Wertes aus den Performance-Daten + +

    +
    USE_MIN_ON_CREATE = 1
    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    RRD_STORAGE_TYPE

    +
    +
    RRD_STORAGE_TYPE = SINGLE
    + +

    + +Die Option RRD_STORAGE_TYPE definiert die Art der Datenhaltung. +

    + +

    +Mögliche Werte sind MULTIPLE und SINGLE +

    + +

    +SINGLE: Eine RRD-Datenbank pro Service +

    + +

    +MULTIPLE: Ein oder mehrere RRD-Datenbanken pro Service. Für jede Datenreihe wird eine eigene RRD-Datenbank erstellt. +

    + +

    +ACHTUNG: Daten werden nicht automatisch migriert!
    + +Ein Konvertierungs-Script finden Sie hier. +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    RRD_HEARTBEAT

    +
    + +

    + +Gültig ab PNP 0.6.1 +

    +
    RRD_HEARTBEAT = 305
    + +

    +Nach <RRD_HEARTBEAT> Sekunden erwartet RRDtool neue Daten. +

    + +

    +Mehr dazu unter http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +Diese Option hat nur Einfluss, wenn die RRD Datenbank neu erstellt wird. +

    + +
    + +

    Hints on Template Names

    +
    + +

    + +In den meisten Situationen, kann man erwünsche Template Namen relativ einfach, durch die Verwendung geeignter command Objekt Definitionen, erhalten. +

    + +

    +Man betrachte folgendes Beispiel: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load -w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    +Selbst wenn man “CUSTOM_TEMPLATE = 1” benutz, würde man template Namen wie diesen “_usr_lib_nagios_plugins_check_load_-w_4,4,4_-c_5,5,5” erhalten, was höchst unerwünscht ist, insbesondere wegen den darin enthaltenen Parametern. +

    + +

    +Lösung 1: Die Parameter in eigenständige $ARGn$ auslagern +

    + +

    +Eine einfache Lösung ist die Verwendung der folgenden command Objekt Definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +(man beachte das hinzugekommene “!”) +

    + +

    +Dies funktioniert selbst dann, wann $ARG2$ leer bleibt. +

    + +

    +Selbstverständlich müsste man immer noch “CUSTOM_TEMPLATE = 1” setzen. +

    + +

    + +Lösung 2: Den remote executor in der command Objekt Definition verstecken +

    + +

    +Eine andere Lösung ist es, den remote excutor in den jeweiligen command Objekt Definitionen zu verstekcne. +

    + +

    +Anstatt folgender Definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +würde man dies für jeden fern auszuführenden command definieren: + +

    +
    +define command {
    +  command_name check_load_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ /usr/lib/nagios/plugins/check_load $ARG1$
    +}
    +
    + +

    + +mit commands wie diesem: + +

    +
    +  …
    +  check_load_by_ssh!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +Natürlich darf “CUSTOM_TEMPLATE = 1” bei dieser Lösung nicht mehr gesetzt werden. +

    + +

    + +Welche der obigen Lösungen verwendet wird, ist weitgehend Geschmacksache. +

    + +

    +zurück zur Übersicht | PNP in verteilten Umgebungen + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/tpl_helper.html b/share/pnp/documents/de_DE/tpl_helper.html new file mode 100644 index 0000000..a6dfe81 --- /dev/null +++ b/share/pnp/documents/de_DE/tpl_helper.html @@ -0,0 +1,246 @@ + + + +

    Template Helper Functions

    +
    + +

    + +Helper-Funktionen sind dazu gedacht, die Templates zu vereinfachen und Fehler abzufangen. +

    + +
    + +

    rrd::def

    +
    + +

    + +string rrd::def ( $vname, $rrdfile, $ds, [ $cf='AVERAGE' ] ) +

    +
    $def = rrd::def('var1', $RRDFILE[0], $DS[0], 'MAX');
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::cdef

    +
    + +

    + +string rrd::cdef ( $vname, $rpn, ) +

    +
    $def = rrd::cdef('var1_bits', 'var1,8,*' );
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::vdef

    +
    + +

    + +string rrd::vdef ( $vname, $rpn, ) +

    +
    $def = rrd::vdef('var1_avg', 'var1,AVERAGE' );
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::line[1-3]

    +
    + +

    + +string rrd::line[1-3] ( $vname, $color, [ $text ], [ $stack ] ) +

    +
    $def .= rrd::line1('var1', #ff00ff );
    + +

    +Eine einfache Linie, ein Pixel breit, ohne Label-Text +

    +
    $def .= rrd::line3('var1', '#ff00ff', 'Load' );
    + +

    +Eine Linie, drei Pixel breit, und dem Label “Load” +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::area

    +
    + +

    + +string rrd::area ( $vname, $color, [ $text ], [ $stack ] ) +

    +
    $def .= rrd::area('var1', '#ff00ff', 'Load' );
    + +

    +Eine Fläche mit dem Label “Load” +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::gprint

    +
    + +

    + +string rrd::gprint ( $vname, $cf, [ $text ] ) +

    +
    $def .= rrd::gprint('var1', 'MAX', '%4.2lf %s Max' );
    +
    $def .= rrd::gprint('var1', array('MIN', 'MAX', 'AVERAGE'), '%4.2lf %s' );
    + +

    +Ist $cf ein Array, so wird automatisch eine Legende formatiert ausgegeben. +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::color

    +
    + +

    + +string rrd::color ( $num [, $num ]) +

    + +

    +Liefert eine Farbe aus der HTML-Farbtabelle. Als zweites (optionales) Argument kann man einen Alpha-Wert angeben, der die Transparenz der Farbe festlegt. +

    + +

    +Beginnend mit PNP 0.6.18 akzeptiert die Funktion ein drittes Argument, das auf Farbschemadefinitionen in config.php verweist (oder in config_local.php, die bei Updates nicht überschrieben wird). Dort finden Sie das Array $scheme[], z.B. +

    +
    $scheme['Reds'] = array (...)
    + +

    +Im Template definieren Sie +

    +
    $schema = $this->config->scheme['Reds']
    +...
    +rrd:color ($key, '', $schema);
    + +

    +Aus diese Weise wählen Sie den Wert von $scheme['Reds'][$key]. Falls $key nicht innerhalb des Arrays liegt oder der Name nicht korrekt ist (case-sensitiv), dann wird die Standardpalette verwendet. +

    + +
    + +

    rrd::gradient

    +
    + +

    + +string rrd::gradient ( $vname, [$start_color], [$end_color], [$label], [$steps], [$lower] ) +

    + +

    +Erzeugt einen Farbverlauf von $start_color nach $end_color +

    +
    $def .= rrd::gradient('var1', '#ff0000', '#ffff00' );
    + +

    + +Beispiel +

    + +
    + +

    rrd::cut

    +
    + +

    + +string rrd::cut ( $text, $length ) +

    +
    $label = rrd::cut($LABEL[0], 18);
    + +

    +Schneidet einen Text auf eine gegebene Länge $length ab oder füllt wenn nötig auf $length auf. +Diese Funktion ist hilfreich, wenn die Legende ausgerichtet werden soll, aber die Länge des Labels nicht bekannt ist. +

    + +
    + +

    rrd::ticker

    +
    + +

    + +string rrd::ticker ( $vname, $warning, $critical, [$fraction], [$opacity], [$color_OK], [$color_WARN], [$color_CRIT] ) +

    + +

    +Erzeugt einen farbigen Balken am oberen Rand des Graphen, der je nach OK, WARNING & CRITICAL unterschiedliche Farben annimmt +

    +
    $def .= rrd::ticker( "var1", $WARN[0], $CRIT[0] );
    + +

    + +Beispiel +

    + +
    + +

    rrd::alerter

    +
    + +

    + +string rrd::alerter ( $vname, $label, $warning, $critical, [$opacity], [$unit], [$color_OK], [$color_WARN], [$color_CRIT], [$line_col] ) +

    + +

    +Erzeugt Areas, die entsprechend der Werte OK, WARNING & CRITICAL unterschiedliche Farben annehmen +

    +
    $def .= rrd::alerter( "var1", $LABEL[0], $WARN[0], $CRIT[0], "FF", $UNIT[0] );
    + +

    +Beispiel +

    + +
    + +

    rrd::alerter_gr

    +
    + +

    + +string rrd::alerter_gr ( $vname, $label, $warning, $critical, [$opacity], [$unit], [$color_OK], [$color_WARN], [$color_CRIT], [$line_col], [$start_color] ) +

    + +

    +Erzeugt Gradienten, die entsprechend der Werte OK, WARNING & CRITICAL unterschiedliche Farben annehmen +

    +
    $def .= rrd::alerter_gr( "var1", $LABEL[0], $WARN[0], $CRIT[0], "FF", $UNIT[0] );
    + +

    +Beispiel + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/tpl_helper_pnp.html b/share/pnp/documents/de_DE/tpl_helper_pnp.html new file mode 100644 index 0000000..52b2ef5 --- /dev/null +++ b/share/pnp/documents/de_DE/tpl_helper_pnp.html @@ -0,0 +1,91 @@ + + + +

    PNP Helper Functions

    +
    + +

    + +PNP-Helper-Funktionen sind dazu gedacht, die Erstellung von Templates zu vereinfachen. Im Gegensatz zu den rrd-Helper-Funktionen rufen sie keine existierenden RRDtool-Funktionen auf. +

    + +
    + +

    pnp::adjust_unit

    +
    + +

    + +(string,number,string,number) pnp::adjust_unit ( $value, $base=1000, $format='%.3lf' ) +

    + +

    +Der Zweck dieser Funktion ist die “Normalisierung” von großen Zahlen. Moderne Festplatten haben Größen von mehreren GB oder TB erreicht und wenn Sie auf Zahlen wie 1521073648234 schauen, dann fangen Sie an, die Ziffern zu zählen, also wäre es schön, diese Zahlen in ein “handliches” Format zu verwandeln. Das Gleiche gilt für Netzwerkverkehr. +

    + +

    +An die Funktion werden bis zu drei Parameter übergeben und in jedem Fall ein Array mit vier Elementen zurückgeliefert. + +

    +
      +
    • Der erste übergebene Parameter ist der Wert (ggf. inklusive die “UOM”)
      +
    • +
    • Der zweite Parameter ist optional (Default “1000”, z.B. für “Traffic”), bzw. “1024” (z.B. Festplattengrößen)
      +
    • +
    • Der dritte Parameter ist optional (Default '%.3lf') und gibt das Format des zurückzugebenden Wertes an
      +
    • +
    +
    $size = pnp::adjust_unit(1521073648234,1024,'%7.3lf');
    + +

    +Bitte beachten Sie, dass “$size” ein Array ist, das aus vier Feldern besteht: +

    +
     $size[0] := "  1.383 T"
    + +

    +enthält den formatierten Wert inkl. der Einheit +

    +
     $size[1] := "1.383"
    + +

    +enthält den formatierten Wert (ohne führende Leerzeichen) +

    +
     $size[2] := "T"
    + +

    +enthält die Einheit +

    +
     $size[3] := "1099511627776"
    + +

    +enthält den Divisor +

    + +

    +Angenommen das Plugin “check_disk” liefert “MB” als UOM, dann können Sie diese Einheit ebenfalls übergeben + +

    +
    $disk = pnp::adjust_unit("1524MB",1024,'%7.3lf');
    + +

    + +liefert als Ergebnis u.a. +$disk[0] := “1.448 GB” +

    + +

    +
    + +“altes” check_disk-Template mit der %s Direktive
    + +

    + +

    +
    + +“neues” check_disk-Template mit pnp::adjust_unit + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/tpl_special.html b/share/pnp/documents/de_DE/tpl_special.html new file mode 100644 index 0000000..7ce7ee9 --- /dev/null +++ b/share/pnp/documents/de_DE/tpl_special.html @@ -0,0 +1,188 @@ + + + +

    Special Templates

    +
    + +

    + +“Special Templates” dienen zum Zusammenfassen von Daten beliebiger Hosts und Services und sind somit nicht direkt mit einem Host oder Service verknüpft. +

    + +

    +Oftmals ist es gewünscht Daten verschiedener Services in einem Graphen darzustellen. Immer wenn die "Pages" nicht genügen, können die Special Templates ins Spiel kommen. +

    + +
    + +

    Grundlagen

    +
    + +

    + +“Special Templates” werden in pnp4nagios/share/templates.special gesucht und müssen die Dateiendung .php besitzen. +

    + +

    +Aufgerufen werden “Special Templates” über den Controller “special” unter + +

    +
    http://<your-nagios-server>/pnp4nagios/special?tpl=<template>
    + +

    + +<template> ist entsprechend durch das jeweilige Template ohne die Dateiendung .php zu ersetzen. +

    + +

    +Ein entsprechender Link erscheint im PNP-Interface, wenn mindestens ein “Special Template” gefunden wurde. +

    + +
    + +

    Beispiel

    +
    + +

    + +Aufgabe ist die Antwortzeiten aller Webserver mit dem Hostnamen websrv01, websrv02 und websrv03 in einem Graphen anzuzeigen. Die Daten sollen aus dem Service “HTTP” stammen. +

    + +

    +Step 1: Anlegen eines Templates “websrv_response_times.php” unter pnp4nagios/share/templates.special +

    + +

    +“Special Templates” beginnen immer mit der Definition des Titels und eines Kommentars. +

    +
    $this->MACRO['TITLE']   = "HTTP Response Times";
    +$this->MACRO['COMMENT'] = "HTTP Response Times for all Cluster Nodes";
    + +

    +Step 2: Eine Liste aller in Frage kommenden Hosts/Services erstellen. PNP stellt hierfür die Funktion tplGetServices() bereit. +

    + +

    +tplGetServices() erwartet zwei Parameter. +

    + +

    +Parameter 1 ist ein regulärer Ausdruck auf den zu suchenden Host, Parameter 2 ist entsprechend ein regulärer Ausdruck für den Service. +

    +
    $services = $this->tplGetServices("websrv","HTTP");
    + +

    +$services enthält nun ein Array aller gefundenen Services. +

    + +

    +Um die Entwicklung der Templates zu erleichtern und Einblick in die Datenstrukturen zu erhalten, kann man Kohana durch Auslösen einer Exception zum Abbrechen der Verarbeitung zwingen. +

    + +

    +Um Einblick in die Daten von $services zu erhalten, genügt die folgende Zeile. +

    +
    throw new Kohana_exception(print_r($services,TRUE));
    + +

    +Ausgabe bei Aufruf von pnp4nagios/special?tpl=websrv_response_times +

    +
    +Array ( 
    +  [0] => Array ( 
    +     [host] => websrv01 
    +     [service] => HTTP 
    +  ) 
    +  [1] => Array ( 
    +     [host] => websrv02
    +     [service] => HTTP 
    +  ) 
    +  [2] => Array ( 
    +     [host] => websrv03
    +     [service] => HTTP 
    +  ) 
    +)
    +
    + +

    +Die Variable $services enthält somit ein Array aller gefundenen Services, in diesem Fall also drei Hosts mit dem Service “HTTP” +

    + +

    +Step 3: Durchlaufen des Array $services und erstellen der Graph-Definitionen. +

    +
    foreach($services as $key=>$val){
    +    $data      = $this->tplGetData($val['host'],$val['service']);
    +    $hostname  = rrd::cut($data['MACRO']['HOSTNAME'], 15);
    +    $def[0]   .= rrd::def("var$key" , $data['DS'][0]['RRDFILE'], $data['DS'][0]['DS'] );
    +    $def[0]   .= rrd::line1("var$key", rrd::color($key), $hostname);
    +    $def[0]   .= rrd::gprint("var$key", array("MAX", "AVERAGE"));
    +}
    + +

    +Die Funktion tplGetData() wird innerhalb der Schleife verwendet, um das jeweilige XML-File einzulesen. Die Daten werden als Array zurückgeliefert und stehen nun in $data zur Verfügung. +

    + +

    +In diesem Beispiel kommen weitere kleine PNP-Helfer zum Einsatz, zu erkennen am Präfix rrd::. +

    + +

    +Die Funktion rrd::cut() schneidet einen String auf eine bestimmte Länge oder füllt auf diese Länge auf. Dies ist hilfreich, um die Legende auszurichten. +

    + +

    +Die Funktion rrd::gprint() erzeugt die Legende unter dem Graphen. +

    + +

    +Die Funktion rrd::color() liefert eine Farbe aus einer fest definierten Farbliste zurück. +

    + +

    +Mehr Informationen zu den PNP-Helper-Funktionen finden Sie hier. + +

    +
    <?php
    +#
    +# Special Template websrv_response_times.php
    +#
    +$this->MACRO['TITLE']   = "HTTP Response Times";
    +$this->MACRO['COMMENT'] = "HTTP Response Times for all Cluster Nodes";
    +#
    +# Get a List of Services by regex 
    +# Option 1 = 'Host Regex'
    +# Option 2 = 'Service Regex'
    +#
    +$services = $this->tplGetServices("websrv","HTTP");
    +#throw new Kohana_exception(print_r($services,TRUE));
    +#
    +# The Datasource Name for Graph 0
    +$ds_name[0] = "Response Times";
    +$opt[0]     = "--title \"Response Times\"";
    +$def[0]     = "";
    +#
    +# Iterate through the list of hosts
    +foreach($services as $key=>$val){
    +    #
    +    # get the data for a given Host/Service
    +    $data = $this->tplGetData($val['host'],$val['service']);
    +    #
    +    # Throw an exception to debug the content of $a
    +    # Just to get Infos about the Array Structure
    +    #
    +    #throw new Kohana_exception(print_r($a,TRUE));
    +    $hostname   = rrd::cut($data['MACRO']['HOSTNAME']);
    +    $def[0]    .= rrd::def("var$key" , $data['DS'][0]['RRDFILE'], $data['DS'][0]['DS'] );
    +    $def[0]    .= rrd::line1("var$key", rrd::color($key), $hostname);
    +    $def[0]    .= rrd::gprint("var$key", array("MAX", "AVERAGE"));
    +}
    +?>
    + +

    +Zurück zur Übersicht + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/upgrade.html b/share/pnp/documents/de_DE/upgrade.html new file mode 100644 index 0000000..37d32b6 --- /dev/null +++ b/share/pnp/documents/de_DE/upgrade.html @@ -0,0 +1,218 @@ + + + +

    Upgrade auf Version 0.6.x

    +
    + +

    + +Das Web-Frontend ist komplett neu geschrieben worden und basiert nun auf dem PHP MVC Framework Kohana. Somit ergeben sich grundlegend andere Abhängigkeiten, die dringend vor der Installation geprüft werden müssen. +

    + +

    +Anmerkung: Ein Upgrade läuft zuerst wie eine Neuinstallation. Anschließend sind einige Anpassungen durchzuführen, die weiter unten beschrieben sind. +

    + +

    +PNP 0.4.x wurde ohne weitere Angabe von Optionen beim Aufruf von ./configure unterhalb einer Nagios-Installation unter /usr/local/nagios installiert. +

    + +

    +PNP 0.6.x wird bei Angabe keiner weiteren Optionen unter /usr/local/pnp4nagios installiert, ist also wie Nagios als eigenständige Applikation zu sehen. +

    + +

    +Anmerkung: Es reicht aus, die *.rrd-Dateien vom alten ins neue Verzeichnis zu kopieren. Sie enthalten die eigentlichen Daten. Die *.xml-Dateien werden jedes Mal neu angelegt, wenn Performance-Daten verarbeitet werden, denn sie enthalten lediglich Meta-Informationen. Außerdem hat sich die interne Struktur geändert, so dass sie sowieso nicht nutzbar sind. +

    + +
    + +

    Vergleich der Struktur

    +
    + +

    + +Summary einer Installation von PNP 0.4.14 +

    +
    +./configure
    +...
    +*** Configuration summary for pnp 0.4.14 05-02-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/nagios
    +  HTML Dir:                         /usr/local/nagios/share/pnp
    +  Config Dir:                       /usr/local/nagios/etc/pnp
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/nagios/share/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/nagios/var/spool/perfdata/
    +
    + +

    +Summary einer Installation von 0.6.0 +

    +
    +./configure
    +...
    +*** Configuration summary for pnp4nagios-0.6.0 07-30-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    + +

    +Aus diesen Infos ergeben sich die zu ändernden Parameter und somit die Upgrade-Strategie. +

    + +
    + +

    Anpassungen

    +
    + +

    + +Die Vorlagen der action_url-Definitionen haben sich verändert. Statt ”/nagios/pnp” ist ”/pnp4nagios” einzutragen und statt “index.php” wird nun “graph” benutzt +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    +Ähnliches gilt für die Preview-Popup-Funktion +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    + +Achtung: Es ist kein Fehler, dass die Zeichenketten vor und nach “class” jeweils nur ein Apostroph enthalten. +

    + +

    +Anders als in der 0.4.x Dokumentation vermerkt gelten die Templates für Nagios 2.x und 3.x. Der einzige Unterschied besteht darin, dass die action_url-Direktive in Nagios 2.x nicht in der Service-Definition, sondern in eigenen serviceextinfo-Definitionen verfügbar ist. +

    + +

    +Innerhalb der PHP-Dateien im templates-Verzeichnis müssen alle Variablen vor der ersten Benutzung initialisiert werden, z.B. +

    +
    $lower = ""
    + +

    + +Das gilt auch für Variablen, an die früher “angehängt” werden konnte, ohne sie vorher zu initialisieren. Daher wird aus + +

    +
    foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +nun + +

    +
    +$def[1] = "";
    +foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    +
    + +Konstanten in Template-Dateien funktionieren nicht mehr, so dass diese in Variablen umzuwandeln sind. Aus +

    +
    define("_WARNRULE", '#FFFF00');
    + +

    +wird dann z.B. +

    +
     $WARNRULE = '#FFFF00';
    + +

    +Man sollte daran denken, alle Vorkommen in der Datei zu ändern ;-). +

    + +
    + +

    Upgrade Szenario mit NPCD

    +
    +
      +
    1. Planen des neuen Aufbaus.
      +
    2. +
    3. Testinstallation durchführen und sich mit dem neuen System vertraut machen.
      +
    4. +
    5. Backup erstellen.
      +
    6. +
    7. PNP 0.6.x nach /usr/local/pnp4nagios installieren.
      +
    8. +
    9. make install-config
      +
    10. +
    11. make install-webconf
      +
    12. +
    13. Apache reload.
      +
    14. +
    15. Apache-Config testen.
      +
        +
      1. Aufruf /pnp4nagios muss ein leeres Perfdata-Verzeichnis melden.
        +
      2. +
      +
    16. +
    17. /usr/local/pnp4nagios/etc/npcd.cfg aus der npcd.cfg-sample erstellen.
      +
        +
      1. Pfade überprüfen und ggf. Änderungen der 0.4.x nachziehen.
        +
      2. +
      +
    18. +
    19. Alle Pfade zur neuen Installation in der nagios.cfg anpassen.
      +
    20. +
    21. Alle Pfade in den Command-Definitionen anpassen.
      +
    22. +
    23. npcd über /etc/init.d/npcd stop anhalten.
      +
    24. +
    25. make install-init installiert das neue Init Script für den npcd.
      +
    26. +
    27. Nagios anhalten.
      +
    28. +
    29. /usr/local/nagios/share/perfdata nach /usr/local/pnp4nagios/var/perfdata kopieren. Achtung: Auf Permissions achten.
      +
    30. +
    31. /etc/init.d/npcd start
      +
    32. +
    33. /etc/init.d/nagios start
      +
    34. +
    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/verify.html b/share/pnp/documents/de_DE/verify.html new file mode 100644 index 0000000..6b8946e --- /dev/null +++ b/share/pnp/documents/de_DE/verify.html @@ -0,0 +1,133 @@ + + + +

    Prüfen der Installation

    +
    + +

    + +Wenn bis jetzt alles sauber funktioniert hat, kann PNP zum ersten Mal im Browser aufgerufen werden. +Bei der Installation mit den Standardeinstellungen erfolgt der Aufruf über http://<Servername>/pnp4nagios/. +

    + +

    +Beim ersten Aufruf sieht man die Seite “PNP4Nagios Environment Tests”, die verschiedene Tests von notwendigen Komponenten enthält. Offenkundig sollten alle Tests erfolgreich verlaufen, bevor es weitergehen kann. Bitte beachten Sie die Hinweise auf der Seite.
    + +

    + +

    +Sind alle Tests erfolgreich verlaufen, so kann die Datei pnp4nagios/share/install.php gelöscht oder umbenannt werden. Erst dann ist das Webinterface erreichbar. +

    + +

    +Alternativ kann eine Datei pnp4nagios/share/install.ignore angelegt werden, um den Aufruf des Installers nach weiteren Updates zu ignorieren. +

    + +

    +Ohne weitere Optionen sucht PNP nach RRD- und XML-Dateien in pnp4nagios/var/perfdata/ und zeigt alle Graphen des ersten Hosts in der Übersicht an. +

    + +

    +ACHTUNG: Direkt nach dem (Neu-)Start von Nagios nach dem Aktivieren der Verarbeitung von Performance-Daten wird der Aufruf im Browser zu Fehlermeldungen führen, weil zunächst Performance-Daten gesammelt und in den RRD-Dateien abgelegt werden müssen. Abhängig vom Check-Intervall kann es einige Zeit dauern, bis die ersten Graphen angezeigt werden können. +

    + +
    + +

    Logfile

    +
    + +

    + +Während der Installation wurde durch den Aufruf von make install-config ein Beispiel-Config-File etc/process_perfdata.cfg-sample erzeugt. Die Werte in der sample-Datei entsprechen den Default-Werten, die auch in process_perfdata.pl fest hinterlegt sind, daher ist die process_perfdata.cfg für den Betrieb nicht zwingend notwendig. +

    + +

    +Die Datei process_perfdata.cfg-sample kann somit als Vorlage für die process_perfdata.cfg dienen, die immer dann notwendig ist, wenn vom Standard abweichende Werte eingestellt werden sollen. +

    + +

    +In der process_perfdata.cfg lässt sich das Verhalten von process_perfdata.pl vielfach beeinflussen. +

    + +

    +Die wichtigsten Optionen für die Inbetriebnahme sind LOG_LEVEL und LOG_FILE. Im laufenden Betrieb sollte der Log-Level immer auf 0 gesetzt sein, um die Performance von process_perfdata.pl nicht durch unnötiges Schreiben von Logfiles zu beeinträchtigen. +

    + +

    +Während der Inbetriebnahme sollte man jedoch den LOG_LEVEL auf “2” setzen, um zu sehen, was process_perfdata.pl bei der Verarbeitung der Performance-Daten so alles anstellt. +

    + +

    +Spätestens bei Support Anfragen im Forum oder auf den Mailinglisten werden wir sowohl nach Auszügen aus dem perfdata.log als auch nach der Ausgabe des verify_pnp_config-Scripts fragen. Es empfiehlt sich also, diese Angaben gleich mitzuliefern ;-). +

    + +
    + +

    Was aber wenn nicht ?

    +
    + +

    + +Einige grundlegende Einstellungen sind zu prüfen. +

    + +

    +1. Sind RRD- und XML-Files erzeugt worden ? +

    + +

    +process_perfdata.pl legt für jeden Host unter var/perfdata ein neues Verzeichnis an. In diesem Verzeichnis wird wiederum für jeden Service eine RRD-Datenbank und ein XML-File erstellt. Für den Host-Check lautet der Dateinamen _HOST_.xml bzw. _HOST_.rrd.
    + +Falls Graphen urplötzlich nicht mehr weitergeführt werden, dann hilft vielleicht ein Blick in die betroffene XML-Datei. Dort gibt es u.a. die Tags <RC> und <TXT>. <RC> zeigt den Return-Code des RRDtool-Updates der RRD-Datei, <TXT> eine textuelle Beschreibung.
    + +Allerdings liefern nicht alle Checks Performance-Daten, das gilt u.a. für “check_ping”, die Alternative “check_icmp” dagegen erzeugt Daten (ab Nagios-Plugin-Version 1.4.12 liefert auch check_ping Performance-Daten).
    + +Teilweise muss man zusätzliche Optionen aktivieren, damit Performance-Daten ausgegeben werden. Evtl. kann das auch durch ein Wrapper-Script geändert werden.
    + +In den Detailinformationen zu jedem Host/Service gibt es das Feld “Performance-Data”. Wenn dort keine Daten stehen, dann werden im jeweiligen Verzeichnis keine Dateien erzeugt und PNP kann deshalb auch keine grafischen Auswertungen liefern!
    + +Das folgende Bild zeigt die Informationen zu einem “PING”-Service. Das blaue Feld enthält den vom Plugin gelieferten Text, das rote die Performance-Daten, die Nagios erkannt hat.
    + +Informationen zu "PING" +

    + +

    +2. Hat Nagios process_perfdata.pl aufgerufen ? +

    + +

    +In der Config-Datei für process_perfdata.pl, der etc/process_perfdata.cfg lässt sich der Debug-Level erhöhen. Die Verarbeitung der Daten wird nun in var/perfdata.log bzw. im Syslog protokolliert. +

    + +

    +3. Grafiken werden ohne Text angezeigt ? +

    + +

    +siehe Anforderungen +

    + +

    +4. Einige Graphen werden angezeigt, andere melden den Fehler “parser error: Input is not proper UTF-8” oder etwas ähnliches. Bitte prüfen Sie, ob die Daten “spezielle” Zeichen enthalten, die nicht im ASCII-Zeichensatz vorhanden sind (Umlaute, etc). Versuchen Sie, in process_perfdata.cfg den Wert von XML_ENC auf ISO-8859-1 oder einen anderen passenden Wert zu setzen. Warten Sie, bis die xml-Datei neu erzeugt wurde und probieren Sie es nochmal. +

    + +

    +5. Bei aktiviertem npcdmod-Modul muss der Wert von event_broker_options in der nagios.cfg ggf. angepasst werden. Hinweise gibt es hier. +

    + +

    +6. verify_pnp_config +Das Perl-Script verify_pnp_config.pl ermöglicht die Prüfung von Konfigurationseinstellungen und zeigt, ob Performance-Daten vorhanden sind. +

    + +

    +7. Es scheint zu funktionieren, aber es bleiben einige Dateien Spool-Verzeichnis stehen (/usr/local/pnp4nagios/var/spool/<perfdata_filename>-PID-<process_perfdata_pid>). Wenn process_perdata.pl nicht in das Zielverzeichnis (/usr/local/pnp4nagios/share/perfdata/<host>) schreiben kann, wird es anhalten und die Quelldatei nicht löschen. Das erhöht die Größe des Spool-Verzeichnisses und die Verarbeitung der Performance-Daten verlangsamen. Dieses Problem kann auftreten, wenn Sie Verzeichnisse aus einer vorherigen Installation kopiert und/oder manuell Verzeichnisse angelegt haben und dabei die falschen Benutzer/Berechtigungen verwendet haben. +

    + +

    +zurück zur Übersicht | verify_pnp_config.pl + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/verify_pnp_config.html b/share/pnp/documents/de_DE/verify_pnp_config.html new file mode 100644 index 0000000..f59d6cd --- /dev/null +++ b/share/pnp/documents/de_DE/verify_pnp_config.html @@ -0,0 +1,153 @@ + + + +

    verify_pnp_config

    +
    + +

    + +Bei Problemen kann das Perl-Script verify_pnp_config von http://verify.pnp4nagios.org helfen die aktuelle Nagios/Icinga Konfiguration zu prüfen und entsprechend Hinweise zur Lösung liefern. +

    + +

    +Bei Support Anfragen sollte immer die Ausgabe dieses Scripts mit angegeben werden, da die Entwickler sich so einen besseren Überblick über das verwendete System machen können. +

    + +

    +Feedback, Verbesserungsvorschläge oder Patches bitte per Mail an support@pnp4nagios.org +

    + +
    + +

    Download

    +
    + +

    + +Das Verify Script ist unter http://verify.pnp4nagios.org verfügbar. +

    +
    +wget http://verify.pnp4nagios.org/verify_pnp_config
    +
    + +
    + +

    Test

    +
    + +

    + +Das Verify Script benötigt drei Optionen um die Funktion von PNP4Nagios zu prüfen +

    +
    +lenny:~# perl verify_pnp_config
    +
    +verify_pnp_config -m|--mode=[sync|bulk|bulk+npcd|npcdmod]
    +                 -c|--config=[path to nagios.cfg]
    +                 -p|--pnpcfg=[path to PNP config dir]
    +
    + +

    +Die wichtigste Infos ist der zu prüfende Modus, welcher mit der Option --mode angegeben wird.
    + +Weitere Infos über die einzelnen Modi und deren Konfiguration unter "Welcher Modus ist für mich richtig ?" und "Konfiguration" +

    + +

    +Weiterhin ist der Pfad zur Nagios Config Datei (nagios.cfg) über die Option --config zu übergeben. Auf einem Icinga System ist es entsprechend der Pfad zur icinga.cfg. +

    + +

    +Über --pnpcfg wird der Pfad zum etc Verzeichnis der PNP4Nagios Installation übergeben.
    + +

    + +

    +Beim Aufruf von perl verify_pnp_config werden die verfügbaren Optionen ausgegeben. +

    +
    +lenny:~# perl verify_pnp_config --mode npcdmod --config=/usr/local/nagios/etc/nagios.cfg --pnpcfg=/usr/local/pnp4nagios/etc
    +[INFO]  ========== Starting Environment Checks ============
    +[INFO]  My version is: verify_pnp_config-0.6.14-R.31
    +[INFO]  Reading /usr/local/nagios/etc/nagios.cfg
    +[OK  ]  Running product is 'nagios'
    +[OK  ]  object_cache_file is defined
    +[OK  ]  object_cache_file=/usr/local/nagios/var/objects.cache
    +[INFO]  Reading /usr/local/nagios/var/objects.cache
    +[OK  ]  resource_file is defined
    +[OK  ]  resource_file=/usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/process_perfdata.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/pnp4nagios_release
    +[OK  ]  Found PNP4Nagios version "0.6.14"
    +[OK  ]  Effective User is 'nagios'
    +[OK  ]  User nagios exists with ID '1000'
    +[OK  ]  Effective group is 'nagios'
    +[OK  ]  Group nagios exists with ID '1000'
    +[INFO]  ========== Checking npcdmod Mode Config  ============
    +[OK  ]  process_performance_data is 1 compared with '/1/'
    +[OK  ]  event_broker_options is defined
    +[OK  ]  event_broker_options=-1
    +[OK  ]  event_broker_option bits 2 and 3 enabled (12)
    +[OK  ]  broker_module is defined
    +[OK  ]  broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  npcdmod.o config file is /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg used by npcdmod.o is readable
    +[OK  ]  npcd daemon is running
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg is used by npcd and readable
    +[OK  ]  npcd and npcdmod.o are using the same config file (/usr/local/pnp4nagios/etc/npcd.cfg)
    +[INFO]  Nagios config looks good so far
    +[INFO]  ========== Checking config values ============
    +[INFO]  Reading /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  Script /usr/local/pnp4nagios/libexec/process_perfdata.pl is executable
    +[INFO]  ========== Starting global checks ============
    +[OK  ]  status_file is defined
    +[OK  ]  status_file=/dev/shm/status.dat
    +[INFO]  Reading /dev/shm/status.dat
    +[INFO]  ==== Starting rrdtool checks ====
    +[OK  ]  RRDTOOL is defined
    +[OK  ]  RRDTOOL=/usr/bin/rrdtool
    +[OK  ]  /usr/bin/rrdtool is executable
    +[OK  ]  RRDtool 1.3.1  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>
    +[OK  ]  USE_RRDs is defined
    +[OK  ]  USE_RRDs=1
    +[OK  ]  Perl RRDs modules are loadable
    +[INFO]  ==== Starting directory checks ====
    +[OK  ]  RRDPATH is defined
    +[OK  ]  RRDPATH=/usr/local/pnp4nagios/var/perfdata
    +[OK  ]  Perfdata directory '/usr/local/pnp4nagios/var/perfdata' exists
    +[WARN]  62 hosts/services are not providing performance data
    +[WARN]  'process_perf_data 1' is set for 43 hosts/services which are not providing performance data!
    +[WARN]  'process_perf_data 0' is set for 27 of your hosts/services
    +[OK  ]  'process_perf_data 1' is set for 243 of your hosts/services
    +[INFO]  ==== System sizing ====
    +[OK  ]  269 hosts/service objects defined
    +[INFO]  ==== Check statistics ====
    +[WARN]  Warning: 3, Critical: 0
    +[WARN]  Checks finished...
    +
    + +
    + +

    Performance data

    +
    + +

    +Beginnend mit 0.6.19-R.37 (2013-02-17) akzeptiert das Skript die Option--object (oder -o) gefolgt von einer Zeichenkette, die einen Host und/oder einen Service angibt. Für diese/s Objekt(e) werden die Performance-Daten angegeben (falls vorhanden). Die Daten werden von eckigen Klammern begrenzt, gefolgt vom Wert der Direktive process_performance_data (ppd=n). +

    + +

    +host = Performance-Informationen für den Host host zeigen
    + +;service = Performance-Informationen für Service service zeigen
    + +host;service = Performance-Informationen für Service service auf Host host zeigen +

    + +

    +Die Zeichenketten werden als reguläre Ausdrücke angesehen (Perl-Syntax). + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/webfe.html b/share/pnp/documents/de_DE/webfe.html new file mode 100644 index 0000000..179e717 --- /dev/null +++ b/share/pnp/documents/de_DE/webfe.html @@ -0,0 +1,149 @@ + + + +

    Das Nagios Web Frontend

    +
    + +

    + +PNP soll natürlich schnell erreichbar sein. Man möchte nicht lange nach den richtigen Graphen suchen. +

    + +

    +Nagios selbst bietet die Möglichkeit, externe URLs über die sogenannte Extended Info Config einzubinden. +Da es in diesem Bereich eine Änderung zwischen Nagios 2.x und der Version 3.0 gibt, wird anschließend auf beide Versionen getrennt eingegangen. +

    + +
    + +

    Nagios 2.x

    +
    + +

    + +Bis Nagios 2.x erfolgt die Einbindung externer URLs in das Nagios-Web-Interface über die Extended-Info-Objekte. Für PNP verwenden wir die Option action_url, um das PNP-Web-Frontend mit den passenden Optionen aufzurufen. +

    +
    +define serviceextinfo {
    +   name                  srv-pnp
    +   action_url            /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register              0
    +}
    +
    + +

    +Dieses Template kann nun über “use srv-pnp” in der serviceextinfo-Definition verwendet werden. Wenn Sie die Schnellstart-Installationsanleitungen benutzt haben, können Sie beispielsweise in der Datei localhost.cfg die Definitionen wie folgt erweitern: +

    +
    +define serviceextinfo {
    +   use                     srv-pnp   ; Name of service templates to use
    +   host_name               localhost
    +   service_description     load
    +}
    +
    + +
    + +

    Nagios 3.x

    +
    + +

    + +Seit Nagios 3.0 ist die Direktive action_url in die Host- bzw. Service-Definition verschoben worden. Die serviceextinfo- und hostextinfo-Definitionen sind entfallen. Damit wird die Definition der URLs zum PNP-Interface wesentlich vereinfacht. +

    + +

    +Zuerst definieren wir zwei Nagios-Templates. Falls Sie die Schnellstart-Installationsanleitungen für Nagios benutzt haben, können Sie die folgenden Zeilen der Datei templates.cfg hinzufügen: +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    +Diese beiden Templates können nun über “use srv-pnp” in der Service-Definition oder “use host-pnp” in der Host-Definition verwendet werden. Wenn Sie die Schnellstart-Installationsanleitungen benutzt haben, können Sie beispielsweise in der Datei localhost.cfg die Definitionen wie folgt erweitern: + +

    +
    define host{
    +        use                     linux-server,host-pnp    ; Name of host templates to use
    +                                                         ; This host definition will inherit all variables that are defined
    +                                                         ; in (or inherited by) the linux-server host template definition.
    +        host_name               localhost
    +        alias                   localhost
    +        address                 127.0.0.1
    +        }
    +
    +
    define service{
    +        use                     local-service,srv-pnp   ; Name of service templates to use
    +        host_name               localhost
    +        service_description     PING
    +        check_command           check_ping!100.0,20%!500.0,60%
    +        }
    +
    + +

    + +Die Links auf die richtigen URLs werden automagisch erstellt. +

    + +
    + +

    Preview Popup

    +
    + +

    + +Außerdem gibt es die Möglichkeit, die Graphen bereits in der Statusübersicht beim Überfahren des “Action Url Icons” mit der Maus einzublenden. +

    + +

    +Ermöglicht wird dies durch die CGI Includes, die es uns erlauben, Javascript-Code an geeigneter Stelle im Seitenkopf der Statusübersicht einzubinden ( status.cgi ). +

    + +

    +In den PNP-Quellen ist die Datei contrib/ssi/status-header.ssi bereits enthalten, die verwendeten URLs müssen aber unter Umständen angepasst werden. Wir gehen hier davon aus, dass PNP über /pnpnagios/index.php erreichbar ist. +

    + +

    +Die besagte Datei muss in das Verzeichnis /usr/local/nagios/share/ssi/ kopiert werden und darf NICHT ausführbar sein. Nagios würde die Datei sonst wirklich wie ein CGI behandeln und ausführen, was aber in diesem Fall zu Fehlern führen würde. Die Apache-Admins mögen bitte “Nagios SSI” nicht mit “Apache SSI” in Verbindung bringen. Beides hat nichts miteinander zu tun. +

    + +

    +Die action_url ist entsprechend anzupassen: +

    +
    +define host {
    +   name       host-pnp
    +   register   0
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +}
    +
    +define service {
    +   name       srv-pnp
    +   register   0
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    +
    + +

    +Nach einem Restart von Nagios (nach Anpassung der Definitionen) sieht das Ergebnis ungefähr so aus:
    + + +

    + +

    +Zurück zur Übersicht | Konfiguration Web-Frontend + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/webfe_cfg.html b/share/pnp/documents/de_DE/webfe_cfg.html new file mode 100644 index 0000000..56a9ec5 --- /dev/null +++ b/share/pnp/documents/de_DE/webfe_cfg.html @@ -0,0 +1,142 @@ + + + +

    PNP Web Frontend

    +
    + +

    + +Das Verhalten des PNP-Web-Frontend lässt sich über die Config-Datei etc/config.php beeinflussen. +Diese Datei wird bei Updates von PNP immer wieder überschrieben, da die meisten Pfade und Optionen bereits durch ./configure ermittelt werden. +

    + +

    +Eigene Anpassungen sollten daher in der Datei etc/config_local.php erfolgen. Sollte die Datei noch nicht existieren, kann die config.php als Vorlage verwendet werden. +

    + +
    + +

    etc/pnp/config.php

    +
    + +

    + +Im folgenden die wichtigsten Parameter: +

    + +

    +Der Pfad zum RRDtool-Binary. Wird von ./configure ermittelt. + +

    +
     $conf['rrdtool'] = "/usr/bin/rrdtool";
    +
    + +

    +Höhe und Breite der RRD-Graphen + +

    +
     $conf['graph_width'] = "500";
    + $conf['graph_height'] = "100";
    +
    + +

    + +Bildschirmdimensionen ändern sich, Blattgrößen nicht. Um unterschiedliche Einstellungen zu ermöglichen, können für die Generierung von PDF-Dateien eigene Werte definiert werden. Wenn diese Variablen nicht definiert sind, werden die Werte der Graphen benutzt. +Höhe und Breite der RRD-Graphen bei PDFs + +

    +
     $conf['pdf_width'] = "675";
    + $conf['pdf_height'] = "100";
    +
    + +

    + +Zusätzliche Optionen, die bei jedem Aufruf von RRDTool mit übergeben werden. Beispielsweise --slope-mode, um die Graphen etwas zu glätten. + +

    +
     $conf['graph_opt'] = "";
    +
    + +

    + +Der Pfad zu den von process_perfdata.pl erstellten RRD- und XML-Dateien + +

    +
     $conf['rrdbase'] = "/usr/local/pnp4nagios/var/perfdata/";
    +
    + +

    + +Pfad zu den Config-Files für die Pages. + +

    +
     $conf['page_dir'] = "/usr/local/pnp4nagios/etc/pages/";
    +
    + +

    +Wert in Sekunden, nachdem die PNP-Seiten neu geladen werden sollen. + +

    +
     $conf['refresh'] = "90";
    +
    + +

    + +Maximales Alter der RRD-Files in Sekunden. Nach Erreichen dieses Wertes werden Links zu den Graphen als “inactive” gekennzeichnet. + +

    +
     $conf['max_age'] = 60*60*6;
    +
    + +

    + +Basis-URL zu den Nagios CGIs. + +

    +
     $conf['nagios_base'] = "/nagios/cgi-bin";
    +
    + +

    +Liste von Usern, für die Links zu den Services des aktuellen Hosts angezeigt werden sollen. + +

    +
     $conf['allowed_for_service_links'] = "EVERYONE";
    +
    + +

    +Liste von Usern, für die das Host-Suchfeld angezeigt werden soll. + +

    +
     $conf['allowed_for_host_search'] = "EVERYONE";
    +
    + +

    +Wird PNP nur mit der Angabe eines Hosts ( index.php?host=<myserver> ) aufgerufen, so wird eine Übersicht aller Services angezeigt, wenn der User in dieser Liste enthalten ist. + +

    +
     $conf['allowed_for_host_overview'] = "EVERYONE";
    +
    + +

    +Das Array $views[] legt fest, welche Zeitspannen die RRD-Graphen dargestellen sollen. Der Titel und die Anzahl der Graphen kann somit hier zentral definiert werden. +

    +
    +$views[] = array('title' => 'One Hour',  'start' => (60*60) );
    +$views[] = array('title' => '4 Hours',   'start' => (60*60*4) );
    +$views[] = array('title' => '25 Hours',  'start' => (60*60*25) );
    +$views[] = array('title' => 'One Week',  'start' => (60*60*25*7) );
    +$views[] = array('title' => 'One Month', 'start' => (60*60*24*32) );
    +$views[] = array('title' => 'One Year',  'start' => (60*60*24*380) );
    +
    + +

    +Sie können hier auch weitere Views definieren, sollten aber dabei berücksichtigen, dass im Normalfall ALLE definierten Views angezeigt werden. +

    + +

    +zurück zur Übersicht | Timeranges + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/de_DE/wrapper.html b/share/pnp/documents/de_DE/wrapper.html new file mode 100644 index 0000000..b6cb42a --- /dev/null +++ b/share/pnp/documents/de_DE/wrapper.html @@ -0,0 +1,30 @@ + +

    +check_procs ist ein Beispiel für ein Plugin, das keine Performance-Daten ausgibt: +

    +
    ./check_procs -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'
    + +

    +Mit dem folgenden Wrapper-Script kann das geändert werden +

    + +

    +check_procs.sh + +

    +
    #!/bin/bash
    +LINE=`/usr/local/nagios/libexec/check_procs $*`
    +RC=$?
    +COUNT=`echo $LINE | awk '{print $3}'`
    +PROCS=`expr $COUNT - 1`
    +LINE=`echo $LINE | sed "s/: $COUNT /: $PROCS /"`
    +echo $LINE \| procs=$PROCS
    +exit $RC
    + +

    +Nun wird die Zahl zusammen mit einer Bezeichnung ausgegeben. + +

    +
    ./check_procs.sh -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'| procs=2
    diff --git a/share/pnp/documents/de_DE/xport.html b/share/pnp/documents/de_DE/xport.html new file mode 100644 index 0000000..08c4f47 --- /dev/null +++ b/share/pnp/documents/de_DE/xport.html @@ -0,0 +1,43 @@ + + + +

    Datenexport

    +
    + +

    + +PNP bietet über den xport Controller Zugriff auf die RRD-Daten. Dabei kann das Ausgabeformat gewählt werden. Zur Zeit sind die Formate xml, json und csv realisiert. +

    + +

    +Aufgerufen wird der Controller über die URL + +

    +
    /pnp4nagios/xport/<format>?host=<hostname>&srv=<servicedesc>
    + +

    + +wobei <format> durch das jeweils gewünschte Format zu ersetzen ist. +

    + +

    +Sie können außerdem wget benutzen, um Bilder zu erzeugen und diese in regelmäßigen Reports einzufügen. Ein Beispiel: +

    +
    wget -O image.png 'http://<user>:<pass>@<nagios-server>/pnp4nagios/image?host=<hostname>&srv=<service>&view=2&source=0'
    + +

    +view=<n> begrenzt den Graphen auf die Zeitperiode, die in config.php definiert ist
    + +source=<n> zeigt nur eine Data-Source, wenn mehrere in der RRD-Datei vorhanden sind +

    + +

    +Anstatt view können Sie auch start und/oder end benutzen, um die Zeitspanne anzugeben. Details finden Sie in den "time ranges". +

    + +

    +zurück zur Übersicht | Templates + +

    + +
    diff --git a/share/pnp/documents/en_US/about.html b/share/pnp/documents/en_US/about.html new file mode 100644 index 0000000..b0c74db --- /dev/null +++ b/share/pnp/documents/en_US/about.html @@ -0,0 +1,186 @@ + + + +

    About PNP

    +
    + +
    + +

    System requirements

    +
    + +

    + +PNP mandatory requires valid performance data of nagios plugins. +

    + +

    +So what is this performance data? +

    + +

    +The output of a nagios plugin up to nagios 2.x is limited to one line. When the plugin produces performance data, it is divided into two parts. The pipe symbol (“|”) is used as a delimiter. +

    + +

    +Example check_icmp : + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +resulting in the text on the left side of the pipe symbol + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0%
    + +

    + +and the performance data + +

    +
      rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +Performance data is designed for automatic processing. The format is specified within the Developer Guidelines (you'll find an excerpt here) but should be exemplified here nonetheless: + +

    +
      rta=2.687ms;3000.000;5000.000;0;
    +   |    |  |    |         |     | |
    +   |----|--|----|---------|-----|-|----- * label 
    +        |--|----|---------|-----|-|----- * current value
    +           |----|---------|-----|-|----- unit ( UOM = UNIT of Measurement ) 
    +                |---------|-----|-|----- warning threshold
    +                          |-----|-|----- critical threshold 
    +                                |-|----- minimum value 
    +                                  |----- maximum value
    +                                  
    + +

    +Value marked with * are mandatory. All other values are optional. +

    + +

    +Several data series are separated by blanks. The actual data must not contains any blanks. If the label contains blanks, it has to be surrounded by single quotes. +

    + +
    + +

    Required Software

    +
    +
      +
    • Perl >= 5.x without additional modules
      +
    • +
    • RRDtool >= 1.x, better 1.2 but not compulsory
      +Attention: installing RRDtool without a packet manager might lead to missing dejavu fonts. If you see graphs without text then this may be the cause.
      +
    • +
    • PHP >= 5.1.6 for the Webfrontend based on Kohana
      +
    • +
    • Nagios >= 2.x or Icinga
      +
    • +
    • Kohana needs the module “mod_rewrite” to be enabled. For details please have a look at the documentation of your web-server specific to your distribution.
      +
    • +
    + +
    + +

    License

    +
    + +

    + +PNP is licensed under GPL 2 +

    + +
    + +

    Download

    +
    + +

    + +Development of PNP is organized using Sourceforge.Net. PNP is registered under “PNP4nagios”. +

    + +

    +The current stable version of 0.6.x can be found in the download area: Sourceforge Download +

    + +

    +Starting with PNP 0.6.x the source code repository was switched from SVN to GIT. +

    + +

    +The current development can be viewed anytime at https://github.com/lingej/pnp4nagios. Clicking on pnp4nagios-head.tar.gz will download an archive containing the latest version. +
    + +

    + +
    + +

    Support

    +
    + +

    + +PRIOR to support questions please make sure that you have verified certain things described under verify your installation.
    +
    + +

    + +

    +The developers and helpers are present on a separate board at http://www.nagios-portal.org and will be informed about new postings in the PNP-section. Postings in english will be answered as well.
    + +After registering as a user please fill in the profile regarding operating system and PNP version used. Please mention if you used a package or compiled the sources. +Please mark successfully solved threads by adding ”[solved]” to the title as it helps other users to find a solution for their problem. +

    + +

    +The mailing lists on Sourceforge can be used to request support (and are limited to english): +

    + +

    +pnp4nagios-users: users list for general questions regarding configuration. Please state your operating system and PNP version +

    + +

    +pnp4nagios-devel: devel list for suggestions and error reports. Please state your operating system and PNP version +

    + +

    +pnp4nagios-checkins: the checkin list automatically contains changes to the SVN repository +

    + +
    + +

    Storage

    +
    + +

    + +Performance data will be stored in Round Robin Databases using RRDtool. That means that after some time the oldest data will be dropped at the “end” and it will be replaced by new values “at the beginning”. +

    + +

    +Various intervals provide for different resolutions. Using the defaults allows to store the data with a resolution of one minute for the last two days, five minutes resolution for ten days, 30 minutes resolution for 90 days and 6 hours resolution for four years. The increasing interval causes averaging of the data which leads to smaller max values. This not an error of PNP. +

    + +

    +Using this storage format the size of the files will stay the same over time. Per datasource you will need approx. 400 KB. +

    + +
    + +

    Statistics and links to Sourceforge

    +
    + +

    + +back to contents | PNP modes + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/advanced.html b/share/pnp/documents/en_US/advanced.html new file mode 100644 index 0000000..33e7737 --- /dev/null +++ b/share/pnp/documents/en_US/advanced.html @@ -0,0 +1,73 @@ + + + +

    Distributed Systems

    +
    + +

    +If Nagios is implemented as a distributed system you have to decide where PNP should be installed. +

    + +

    +From a technical view this question is not important. PNP can be installed on the slave(s) as well as on the master server. Or only on the master? +

    + +

    +If PNP is running on the master you have to make sure that data passed via send_nsca from the slave server(s) contains performance data. Often another check command is used on the master. +

    + +

    +To help PNP on the master to recognize which check command was used on the slave to collect the information process_perfdata.pl responds to an additional field at the end of the performance data. +

    +
    OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;; [check_icmp]
    + +

    +If PNP finds a string enclosed in brackets at the end of performance data it will be recognized as check command and will be used as PNP template. +

    + +

    +Nagios documentation related to this topic can be found +here. The command used in the documentation can be adapted easily. +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$'
    +	}
    +
    + +

    +should be changed to +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$ | $SERVICEPERFDATA$ [$SERVICECHECKCOMMAND$]'
    +	}
    +
    + +
    + +

    check_multi plugin

    +
    + +

    + +The plugin check_multi is one of the first plugins which uses new features of Nagios 3.x. Check_multi can execute multiple Nagios plugins but returns only results like a single service. The output of check_multi comprises of several lines to be able to display the amount of information. +

    + +

    +This results in some difficulties for PNP which has to extract the information of several plugins from the performance data. Together with Matthias Flacke, developer of check_multi, we have found a solution to assign the data to the appropriate plugins. +

    + +

    + +

    + +

    +back to contents | support of rrdcached + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/config.html b/share/pnp/documents/en_US/config.html new file mode 100644 index 0000000..bf48d4d --- /dev/null +++ b/share/pnp/documents/en_US/config.html @@ -0,0 +1,395 @@ + + + +

    Configuration

    +
    + +

    + +The configuration of the already mentioned modes of performance data processing will be described in more detail. +

    + +
    + +

    Synchronous Mode

    +
    + +

    + + The synchronous mode is the simplest way to integrate the data collector process_perfdata.pl into nagios. Every event will trigger an execution of process-service-perfdata. +

    + +

    +Initially you have to enable processing of performance data in nagios.cfg. Please note that this directive might already exist in the config file. Default is “0”. + +

    +
     process_performance_data=1
    + +

    + +Data processing has to be disabled in the definition of every host or service whose performance data should NOT be processed. +

    +
    +define service {
    +   ...
    +   process_perf_data 0
    +   ...
    +}
    +
    + +

    +Since Nagios 3.x it is possible to deactivate the export of environment variables (as part of optimizing the system for maximum performance). Unfortunately this directive has to be enabled to use the synchronous mode. So either you use the default value (which means that the export is enabled) or you define the variable in nagios.cfg +

    +
    enable_environment_macros=1
    + +

    +Additionally the command to process performance data is to be specified in nagios.cfg + +

    +
     service_perfdata_command=process-service-perfdata
    + +

    + +Starting with Nagios 3.0 it may be useful to enable processing of performance data for hosts as well. Due to changed host check logic Nagios 3 now performs regularly scheduled host checks. + +

    +
     host_perfdata_command=process-host-perfdata
    + +

    + +Nagios has to be notified about the referenced commands as well. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +You can see that calling process_perfdata.pl doesn't require any arguments apart from specifing the option -d ( DATATYPE ) if you want to process performance data resulting from host checks. +

    +
    +define command {
    +       command_name    process-service-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +}
    +
    +define command {
    +       command_name    process-host-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl -d HOSTPERFDATA
    +}
    +
    + +

    +Note process_perfdata.pl cannot be started under control of ePN ( embedded Perl Nagios ). Therefore the script is explicitly called using /usr/bin/perl ( or where you perl binary is located ). If you use Nagios 3.x or do not use ePN there is no need to specify /usr/bin/perl. +

    + +
    + +

    Bulk Mode

    +
    + +

    + +Bulk mode is a bit more complicated than the synchronous mode but reduces the load on the nagios server significantly because the data collector process_perfdata.pl is not invoked for every service/host check. +

    + +

    +In bulk mode Nagios writes the data to a temporary file in a defined format. This file is processed by process_perfdata.pl at certain intervals. Nagios will take care for starting and running it periodically. +

    + +

    +Processing of performance data has to be enabled in nagios.cfg + +

    +
     process_performance_data=1
    + +

    + +Additionally some new directives are required +

    +
    +#
    +# service performance data
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# host performance data starting with Nagios 3.0
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    + +Attention: Please note that these template definitions differ from the ones delivered in nagios.cfg! +

    + +

    +The directives and their meaning: + +

    +
      +
    • service_perfdata_file path to the temporary file which should contain the performance data.
      +
    • +
    • service_perfdata_file_template format of the temporary file. Data will be defined using Nagios macros.
      +
    • +
    • service_perfdata_file_mode option “a” specifies that data is to be appended to the file.
      +
    • +
    • service_perfdata_file_processing_interval the interval is 15 seconds
      +
    • +
    • service_perfdata_file_processing_command the command to be called during the interval.
      +
    • +
    + +

    + +The used commands have to be announced to Nagios. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/service-perfdata
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/host-perfdata
    +}
    +
    +
    + +
    +

    NOTE:

    +
    +Because there is more data to process than in synchronous mode process_perfdata.pl will take longer to do this so you should check the TIMEOUT value in etc/process_perfdata.cfg and adjust it appropriately.
    +
    + +
    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + + The configuration is identical to the Bulk Mode except for the used command. +Processing of performance data has to be enabled in nagios.cfg + +

    +
     process_performance_data=1
    + +

    + +Additionally some new directives are required +

    +
    +#
    +# service performance data
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# host performance data starting with Nagios 3.0
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    + +Attention: Please note that these template definitions differ from the ones delivered in nagios.cfg! +

    + +

    +The directives and their meaning: + +

    +
      +
    • service_perfdata_file path to the temporary file which should contain the performance data.
      +
    • +
    • service_perfdata_file_template format of the temporary file. Data will be defined using Nagios macros.
      +
    • +
    • service_perfdata_file_mode option “a” specifies that data is to be appended to the file.
      +
    • +
    • service_perfdata_file_processing_interval the interval is 15 seconds
      +
    • +
    • service_perfdata_file_processing_command the command to be called during the interval.
      +
    • +
    + +

    + +The used commands have to be announced to Nagios. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
    +}
    +
    + +

    +Using these commands the file service-perfdata will be moved to var/spool/ after the interval specified in service_perfdata_file_processing_interval has passed. The Nagios macro $TIMET$ is appended to the filename to avoid overwriting of old files unintentionally. The macro $TIMET$ contains the current timestamp in time_t format (seconds since the UNIX epoch). +

    + +

    +In the directory /usr/local/pnp4nagios/var/spool/ files are gathered to be processed by NPCD. +

    + +

    +NPCD monitors the spool directory and passes the file names to process_perfdata.pl. This way processing of performance data is completely decoupled from nagios. +

    + +

    +Before starting NPCD you have to check the paths to the spool directory and to process_perfdata.pl specified in the config file npcd.cfg. +The only thing that remains is to start NPCD. + +

    +
     /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +The option -d starts NPCD as a daemon in the background. +

    + +
    + +

    Bulk Mode with NPCD and npcdmod

    +
    + +

    + +Attention +Starting with Nagios 4 the internal structures have changed so the start of the module will fail. So far there are no plans to support Nagios 4. Please select any other of the modes. +

    + +

    + This mode uses the event broker module npcdmod.o. The flow of data is identical to “bulk mode with NPCD”. The internal perfdata routines of Nagios activated by the “*_perf_data_*” directives in nagios.cfg are *NOT* used anymore. The module npcdmod.o takes over the task of processing the data required by PNP. +

    + +

    +Pro: +

    +
      +
    • The perfdata routines can now be used for other addons.
      +
    • +
    • The configuration is easier.
      +
    • +
    • It is the preferred mode of the PNP developers.
      +
    • +
    + +

    + +Adjustments in nagios.cfg: +

    +
    +process_performance_data=1
    +broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +
    + +

    +All other directives mentioned on this page must NOT be used. +

    + +

    +Attention: If you have changed the value of event_broker_options from -1 to another value then please note that PNP needs the bits 2 and 3 set (0b01100). Make sure that the resultung value has these bits set because otherwise there will be no performance data to process. +

    + +

    +After restarting Nagios information regarding the start of the module will be logged. +

    + +

    +Excerpt from nagios.log + +

    +
    +[1277545053] npcdmod: Copyright (c) 2008-2009 Hendrik Baecker (andurin@process-zero.de) - http://www.pnp4nagios.org
    +[1277545053] npcdmod: /usr/local/pnp4nagios/etc/npcd.cfg initialized
    +[1277545053] npcdmod: spool_dir = '/usr/local/pnp4nagios/var/spool/'.
    +[1277545053] npcdmod: perfdata file '/usr/local/pnp4nagios/var/perfdata.dump'.
    +[1277545053] npcdmod: Ready to run to have some fun!
    +[1277545053] Event broker module '/usr/local/pnp4nagios/lib/npcdmod.o' initialized successfully.
    +
    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +Since version 0.6.12 PNP4Nagios can be driven as a gearman worker. This way large Nagios environments are possible using mod_gearman. Nagios and PNP4Nagios can be run on different machines. +

    + +

    +You need a mod_gearman environment up and running like described by Sven Nierlein on http://labs.consol.de/lang/en/nagios/mod-gearman/. +

    + +

    +You'll find a section on gearman in etc/process_perfdata.cfg: + +

    +
    PREFORK = 1
    +GEARMAN_HOST = localhost:4730
    +REQUESTS_PER_CHILD = 10000
    +ENCRYPTION = 1
    +KEY = should_be_changed
    +#KEY_FILE = /usr/local/pnp4nagios/etc/secret.key
    + +

    + +Using PREFORK = <n> you specify the number of child processes. +

    + +

    +GEARMAN_HOST = <host>:<port> specifies host and port of the server running the gearman daemon providing the data. +

    + +

    +REQUEST_PER_CHILD = <n> enables you to define the number of requests processed per process. +

    + +

    +ENCRYPTION = <n> specifies whether to use encryption (“1”) or not. Default is an activated encyrption which should be changed only in special cases. You can either use KEY = <key phrase> or 'KEYFILE =<key file> to specify the location of a file containing the key phrase. + +etc/init.d/pnp_gearman_worker start contains links to the perl script process_perfdata.pl and the config file process_perfdata.cfg''. +

    + +

    +After starting the daemon process using + +

    +
     /etc/init.d/pnp_gearmon_worker start
    + +

    + +the performance data will be processed which is provided by the gearmand daemon on the Nagios server. +

    + +

    +back to contents | checking the functionality + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/doc_complete.html b/share/pnp/documents/en_US/doc_complete.html new file mode 100644 index 0000000..e9c2506 --- /dev/null +++ b/share/pnp/documents/en_US/doc_complete.html @@ -0,0 +1,3744 @@ + + +
    + + + +

    New in PNP 0.6.x

    +
    + +

    +PNP 0.6.x Preview +

    + +

    +The work on the new version 0.6.x is in full progress. +

    + +

    +Starting with version 0.6.x we switch from subversion to GIT. The sourcecode is already available on sourceforge. +

    + +

    + +Functions implemented already +

    +
      +
    • Webfrontend based on Kohana
      +
    • +
    • Webfrontend based on jQuery Themes
      +
    • +
    • Javascript-functions using jQuery plugins
      +
    • +
    • process_perfdata.pl will be able to use one RRD database per datasource
      +
    • +
    • improved installer. Specification of directory layouts using --with-layout
      +
    • +
    • RRDtool errors are now displayed as images. no more missing images
      +
    • +
    • PNP templates cannot overwrite internal variables anymore
      +
    • +
    • PNP templates of version 0.4.x can still be used
      +
    • +
    • PDF functions recoded
      +
    • +
    • Template default.php optimized
      +
    • +
    • Export from RRD databases into XML, CSV and JSON format using the RRDtool “xport” function
      +
    • +
    • Page functions recoded
      +
    • +
    • Error pages links to online FAQ
      +
    • +
    • Mouseover Popup in Nagios frontend via jQuery.clueTip plugin
      +
    • +
    • Full support of rrdcached
      +
    • +
    + +

    +back to contents | system requirements + +

    + +
    + +
    +
    + + + +

    About PNP

    +
    + +
    + +

    System requirements

    +
    + +

    + +PNP mandatory requires valid performance data of nagios plugins. +

    + +

    +So what is this performance data? +

    + +

    +The output of a nagios plugin up to nagios 2.x is limited to one line. When the plugin produces performance data, it is divided into two parts. The pipe symbol (“|”) is used as a delimiter. +

    + +

    +Example check_icmp : + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +resulting in the text on the left side of the pipe symbol + +

    +
     OK - 127.0.0.1: rta 2.687ms, lost 0%
    + +

    + +and the performance data + +

    +
      rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;;
    + +

    + +Performance data is designed for automatic processing. The format is specified within the Developer Guidelines (you'll find an excerpt here) but should be exemplified here nonetheless: + +

    +
      rta=2.687ms;3000.000;5000.000;0;
    +   |    |  |    |         |     | |
    +   |----|--|----|---------|-----|-|----- * label 
    +        |--|----|---------|-----|-|----- * current value
    +           |----|---------|-----|-|----- unit ( UOM = UNIT of Measurement ) 
    +                |---------|-----|-|----- warning threshold
    +                          |-----|-|----- critical threshold 
    +                                |-|----- minimum value 
    +                                  |----- maximum value
    +                                  
    + +

    +Value marked with * are mandatory. All other values are optional. +

    + +

    +Several data series are separated by blanks. The actual data must not contains any blanks. If the label contains blanks, it has to be surrounded by single quotes. +

    + +
    + +

    Required Software

    +
    +
      +
    • Perl >= 5.x without additional modules
      +
    • +
    • RRDtool >= 1.x, better 1.2 but not compulsory
      +Attention: installing RRDtool without a packet manager might lead to missing dejavu fonts. If you see graphs without text then this may be the cause.
      +
    • +
    • PHP >= 5.1.6 for the Webfrontend based on Kohana
      +
    • +
    • Nagios >= 2.x or Icinga
      +
    • +
    • Kohana needs the module “mod_rewrite” to be enabled. For details please have a look at the documentation of your web-server specific to your distribution.
      +
    • +
    + +
    + +

    License

    +
    + +

    + +PNP is licensed under GPL 2 +

    + +
    + +

    Download

    +
    + +

    + +Development of PNP is organized using Sourceforge.Net. PNP is registered under “PNP4nagios”. +

    + +

    +The current stable version of 0.6.x can be found in the download area: Sourceforge Download +

    + +

    +Starting with PNP 0.6.x the source code repository was switched from SVN to GIT. +

    + +

    +The current development can be viewed anytime at https://github.com/lingej/pnp4nagios. Clicking on pnp4nagios-head.tar.gz will download an archive containing the latest version. +
    + +

    + +
    + +

    Support

    +
    + +

    + +PRIOR to support questions please make sure that you have verified certain things described under verify your installation.
    +
    + +

    + +

    +The developers and helpers are present on a separate board at http://www.nagios-portal.org and will be informed about new postings in the PNP-section. Postings in english will be answered as well.
    + +After registering as a user please fill in the profile regarding operating system and PNP version used. Please mention if you used a package or compiled the sources. +Please mark successfully solved threads by adding ”[solved]” to the title as it helps other users to find a solution for their problem. +

    + +

    +The mailing lists on Sourceforge can be used to request support (and are limited to english): +

    + +

    +pnp4nagios-users: users list for general questions regarding configuration. Please state your operating system and PNP version +

    + +

    +pnp4nagios-devel: devel list for suggestions and error reports. Please state your operating system and PNP version +

    + +

    +pnp4nagios-checkins: the checkin list automatically contains changes to the SVN repository +

    + +
    + +

    Storage

    +
    + +

    + +Performance data will be stored in Round Robin Databases using RRDtool. That means that after some time the oldest data will be dropped at the “end” and it will be replaced by new values “at the beginning”. +

    + +

    +Various intervals provide for different resolutions. Using the defaults allows to store the data with a resolution of one minute for the last two days, five minutes resolution for ten days, 30 minutes resolution for 90 days and 6 hours resolution for four years. The increasing interval causes averaging of the data which leads to smaller max values. This not an error of PNP. +

    + +

    +Using this storage format the size of the files will stay the same over time. Per datasource you will need approx. 400 KB. +

    + +
    + +

    Statistics and links to Sourceforge

    +
    + +

    + +back to contents | PNP modes + +

    + +
    + +
    +
    + + + +

    The art of collecting data

    +
    + +

    + +PNP supports several modes to process performance data. The modes differ in complexity and the performance to be expected. +

    + +

    +The following image shows the connections between Nagios, PNP and RRDtool
    + +

    + +

    +Nagios invokes a command for every host and every service whose performance data should be processed. Depending on the mode you choose the data will be passed to process_perfdata.pl or will be written to temporary files and processed at a later time. process_perfdata.pl writes the data to XML files and stores them in RRD files using RRDtool.
    + +

    + +

    +Before you choose a mode please read the documentation and decide which way will be the best for installation. +

    + +
    + +

    The modes in comparison

    +
    + +
    + +

    Synchronous Mode

    +
    + +

    + +The “synchronous mode” is the simplest and easiest to set up. Nagios will call the perl script process_perfdata.pl for every service and host, respectively, to process the data. The synchronous mode will work very good up to about 1.000 services in a 5 minute interval. +

    + +
    + +

    Bulk Mode

    +
    + +

    + +In bulk mode Nagios writes the necessary data to a temporary file. After expiration of a defined time the file will be processed in one piece and deleted afterwards. +

    + +

    +The number of calls of process_perfdata.pl will be reduced to a fraction. Depending on time and the amount of collected data there will be much less system calls. Instead, process_perfdata.pl will run longer. +

    + +

    +Note +Using this mode you should keep an eye on the runtime of process_perfdata.pl. While it is running to process data nagios will not execute any checks. +

    + +

    +snippet of var/perfdata.log: + +

    +
    +2007-10-18 12:05:01 [21138] 71 Lines processed
    +2007-10-18 12:05:01 [21138] .../spool/service-perfdata-1192701894-PID-21138 deleted
    +2007-10-18 12:05:01 [21138] PNP exiting (runtime 0.060969s) ...
    +
    + +

    +71 lines were processed in 0.06 seconds. This will be the data volume of about 2000 services und processing using a 10 second interval. It means we blocked nagios for exactly 0.06 seconds. +

    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + +Viewing from Nagios this is the best way of processing because Nagios will not be blocked. +

    + +

    +Nagios again uses a temporary file to store the data and executes a command after expiration of a certain time. Instead of immediate processing by process_perfdata.pl the file is moved to a spool directory. As moving a file inside the same filesystem nearly takes no time nagios is able to execute crucial work immediately. +

    + +

    +The NPCD daemon (Nagios Performance C Daemon) will monitor the directory for new files and will pass the names to process_perfdata.pl. Processing of performance data is decoupled completely from nagios. NPCD itself is able to start multiple thread for processing the data. +

    + +
    + +

    Bulk Mode with npcdmod

    +
    + +

    + +Attention +Starting with Nagios 4 the internal structures have changed so the start of the module will fail. So far there are no plans to support Nagios 4. Please select any other of the modes. +

    + +

    + This scenario includes npcdmod.o, an NEB-module. +This module reduces the configuration of the “Bulk Mode with NPCD” to a mere two lines in nagios.cfg +

    + +

    +This mode is similar to “Bulk Mode with NPCD” and it is exactly the same functionality and the same performance. +

    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +Since version 0.6.12 PNP4Nagios can be driven as a gearman worker. This way large Nagios environments are possible using mod_gearman. Nagios and PNP4Nagios can be run on different machines. +

    + +

    +You need a mod_gearman environment up and running like described by Sven Nierlein on http://labs.consol.de/lang/en/nagios/mod-gearman/. +

    + +
    + +

    The decision

    +
    + +

    +Which mode you choose will depend on the size of your Nagios installation. You will find theses terms throughout the documentation. +

    + +

    +back to contents | installation + +

    + +
    + +
    +
    + + + +

    PNP 0.6.x Downloads

    +
    + +
    + +

    Current stable PNP Version

    +
    + +

    + +Changes can be tracked on pnp4nagios.git.sourceforge.net +

    + +

    +The current Version is pnp4nagios-0.6.22.tar.gz +

    + +
    + +

    Latest Devel Version

    +
    + +

    + + pnp4nagios-head.tar.gz +

    + +

    +This is allways the latest GIT HEAD Version +

    +
    + +

    + +Last Update: Wed Jul 30 06:30:01 CEST 2014 +

    + +
    + +

    ChangeLog

    +
    + +

    + +pnp-0.6.?? ??/??/2013 +

    +
      +
    • Bugfix: Fixed some more XSS issues
      +
    • +
    • Bugfix: Fixed PHP issue while running on PHP 5.6 ( Reported by Sven Nierlein )
      +
    • +
    + +

    + +pnp-0.6.22 04/06/2014 +

    +
      +
    • Bugfix: Fixed livestatus socket parsing ( Pekka Panula )
      +
    • +
    • Bugfix: Update check_mssql_health.php ( Miriam Zenk )
      +
    • +
    • Feature: Add “version=tiny” to got get a stripped down version of graph ( Ricardo Bartels )
      +
    • +
    • feature: Add STDIN Mode to process_perfdata.pl ( Robert Steininger )
      +
    • +
    • Bugfix: XSS issue fixed by Mikael Falkvidd. This issue was detected by Peter Österberg at Hexbit AB in a security assessment of op5 Monitor 6.3 on assignment by op5 AB.
      +
    • +
    + +

    + +pnp-0.6.21 03/24/2013 +

    +
      +
    • Feature: Helper functions rrd::alerter and rrd:alerter_gr both supports treshold detection (Martin Schirrmacher)
      +
    • +
    • Update: jQuery Mobile update to 1.3.0 ( was broken in 0.6.20 )
      +
    • +
    + +

    + +pnp-0.6.20 03/03/2013 +

    +
      +
    • Feature: Support check_mk Multisite Cookie Auth ( Lars Michelsen )
      +
    • +
    • Feature: Allow RRD unknown values ( Simon Meggle )
      +
    • +
    • feature: Interactive delete mode added to check_rrds.pl ( Simon Meggle )
      +
    • +
    • Bugfix: Allow multiple gearman servers ( Craig Barraclough )
      +
    • +
    • Bugfix: Fixed Graph Search ( Stefan Triep )
      +
    • +
    • Update: jQuery update to 1.8.1
      +
    • +
    • Update: jQueryUI update to 1.8.23
      +
    • +
    + +

    + +pnp-0.6.19 09/01/2012 +

    +
      +
    • Feature: Parameter “width” added to popup controller ( Andreas Doehler )
      +
    • +
    • Fix: simplify/improve apache rules ( Christoph Anton Mitterer )
      +
    • +
    • Fix: Check for missing PHP GD functions
      +
    • +
    • Bugfix: socketDOMAIN changed to AF_INET while using livstatus tcp socket ( Rene Koch )
      +
    • +
    + +

    + +pnp-0.6.18 06/28/2012 +

    +
      +
    • Bugfix: Fixed STORAGE_TYPE and CUSTOM_TEMPLATE vars used in custom templates
      +
    • +
    • Bugfix: Blank screen on PHP 5.4 fixed
      +
    • +
    • Feature: Allow multiple gearman job servers
      +
    • +
    • Feature: New helper function rrd::debug()
      +
    • +
    • Feature: New templates check_jmx4perl_*.php
      +
    • +
    + +

    + +pnp-0.6.17 03/25/2012 +

    +
      +
    • Bugfix: Fixed rrd_convert.pl while running with --dry-run
      +
    • +
    • Bugfix: logging.c include missing header files ( Lars Vogdt )
      +
    • +
    • Bugfix: Check if pnp4nagios/etc/rra.cfg is readable
      +
    • +
    • Bugfix: rrd_convert.pl use XML tag TEMPLATE instead of CHECKCOMMAND to selects RRDs ( Sven Velt )
      +
    • +
    • Feature: npcdmod.o increase perfdata buffer and log discarded perfdata ( Birger Schmidt )
      +
    • +
    • Feature: rrd_modify.pl to change number of data sources of an RRD file
      +
    • +
    • Feature: New template check_apachestatus_auto.php
      +
    • +
    • Feature: Implement etc/config.d to place config snippets ( Lars Michelsen )
      +
    • +
    + +

    + +pnp-0.6.16 11/21/2011 +

    +
      +
    • Bugfix: Fixed single quoted check_multi labels (Reported by Matthias Flacke)
      +
    • +
    • Bugfix: Append missing slash to perfdata_spool_dir ( Reported by Juergen-Michael Radtke )
      +
    • +
    • Bugfix: Fixed jQuery-ui multisite theme
      +
    • +
    • Feature: PDF margins are now adjustable via config.php ( Thomas Witzenrath )
      +
    • +
    • Feature: Support for PDF size 'letter' added ( Robert Becht )
      +
    • +
    + +

    + +pnp-0.6.15 09/15/2011 +

    +
      +
    • Bugfix: Fixed Overview link (reported by Stefan Triep)
      +
    • +
    • Bugfix: Fixed zoom popup (reported by Rudolf Labuschagne)
      +
    • +
    • Bugfix: Fixed double urlencode() (reported by Mathias Kettner)
      +
    • +
    • Feature: “Clear basket” button added (suggested by Stefan Triep)
      +
    • +
    • Feature: New helper function “rrd::alerter_gr()” ( committed by Stefan Trip )
      +
    • +
    + +

    + +pnp-0.6.14 08/05/2011 +

    +
      +
    • Feature: Webinterface for mobile devices based on jQuery Mobile
      +( http://jquerymobile.com/ )
      +
    • +
    • Feature: Zoom based on jQuery plugin imgAreaSelect
      +( http://odyniec.net/projects/imgareaselect/ )
      +
    • +
    • Feature: New template check_mssql_health.php
      +
    • +
    • Bugfix: Fixed popups to work under nginx ( Joram Agten )
      +
    • +
    • Bugfix: Helper rrd::vdef() fixed
      +
    • +
    • Update: jQuery update to 1.6.2
      +
    • +
    • Update: jQuery-ui update to 1.8.14
      +
    • +
    + +

    + +pnp-0.6.13 05/19/2011 +

    +
      +
    • Feature: New option --ignore-hosts added to check_pnp_rrds.pl ( by Jochen Bern )
      +
    • +
    • Feature: New options zgraph_width and zgraph_height in config.php ( Mike Liebsch )
      +
    • +
    • Bugfix: rrd_convert.pl: parse_xml_filename() regex fix
      +
    • +
    • Info: Version used by OMD-0.48 OMD
      +
    • +
    + +

    + +pnp-0.6.12 04/22/2011 +

    +
      +
    • Feature: mod_gearman support added
      +
    • +
    • Feature: rrd_convert.pl is now able to convert all RRDs from RRD_STORAGE_TYPE=SINGLE to RRD_STORAGE_TYPE=MULTIPLE
      +
    • +
    • Feature: New template check_gearman.php
      +
    • +
    • Feature: Install process_perfdata.cfg and npcd.cfg by default
      +
    • +
    • Bugfix: rrd_convert.pl is now able to parse xml dumps created by rrdtool 1.4.x
      +
    • +
    • Bugfix: process_perfdata.pl default timeout value set to 15 seconds
      +
    • +
    + +

    + +pnp-0.6.11 01/15/2011 +

    +
      +
    • Bugfix: urldecoding fixed
      +
    • +
    • Bugfix: Zoom in/out is working again ( Reported by Thorben Soehl )
      +
    • +
    • Featue: npcd.cfg - New option perfdata_file_processing_interval used by npcdmod
      +
    • +
    • Info: Version used by OMD-0.46 OMD
      +
    • +
    + +

    + +pnp-0.6.10 12/15/2010 + +

    +
      +
    • Feature: Add RRDTool Option --only-graph if graph height is below 32px to create thumbnails
      +
    • +
    • Feature: RRDTool Option --width and --height is now allowed in templates
      +
    • +
    • Feature: RRDTool DS Type for UOM of “c” changed from COUNTER to DERIVE
      +
    • +
    • Feature: Pass query string from special controller to image controller ( Matthew Garrett )
      +
    • +
    • Feature: Authorisation against mk_livestatus API added
      +
    • +
    • Feature: Sample nginx webserver config added ( by evax@users.sourceforge.net )
      +
    • +
    • Feature: Kohana backport to support PHP 5.1.6 ( Kudos to Andreas Ericsson )
      +
    • +
    • Bugfix: Sort list of special templates
      +
    • +
    • Bugfix: Urlencode hostname and service description ( Reported by Yannick )
      +
    • +
    • Bugfix: corrected warning/critical thresholds in ticker/alerter functions
      +
    • +
    + +

    + +pnp-0.6.7 09/27/2010 + +

    +
      +
    • Bugfix: Page config parser fix (Beau Gunderson)
      +
    • +
    • Bugfix: Zoom window size fixed (Report by Rudolf Labuschagne)
      +
    • +
    • Bugfix: Fixed undefined offset while using 'ds_name' in templates (Reported by Vladimir Bilik)
      +
    • +
    • Bugfix: Npcdmod respects process_perf_data option used in hosts and services definitions ( Reported by Wolfgang Barth )
      +
    • +
    • Template: New Template check_nagiostats.php used with check_nagiostats written by Jochen Bern
      +
    • +
    + +

    + +pnp-0.6.6 08/07/2010 + +

    +
      +
    • Bugfix: Fixed max amount of graphs per template
      +
    • +
    • Bugfix: Autodetect PNP base URL
      +
    • +
    • Bugfix: Too short npcdmod perfdata_template to take perfdata + overhead, increased +1024byte
      +
    • +
    • Bugfix: Ignore files in var/perfdata and check for empty directories
      +
    • +
    • Bugfix: Reducing memory usage while parsing page config (Laurent Freval)
      +
    • +
    + +

    + +pnp-0.6.5 07/09/2010 + +

    +
      +
    • Feature: Special Templates are back tpl_special
      +
    • +
    • Feature: New rrdtool helper functions makes template design easier tpl_helper
      +
    • +
    • Feature: config.php → 'recursive_template_search' is enabled by default
      +
    • +
    • Feature: config.php → 'template_dirs' is now an array of directorys to search for PNP templates
      +
    • +
    + +

    + +pnp-0.6.4 06/03/2010 + +

    +
      +
    • Update: jQuery Update to 1.4.2
      +
    • +
    • Update: jQuery-ui Update to 1.8
      +
    • +
    • Feature: New configure Option --with-base-url
      +
    • +
    • Template: New template check_ntp_time.php (Mathias Kettner)
      +
    • +
    • Feature: New i18n files for fr_FR (Yannig Parre)
      +
    • +
    • Feature: New jQuery Theme 'multisite'
      +
    • +
    + +

    + +pnp-0.6.3 03/16/2010 + +

    +
      +
    • Feature: New helper script libexec/rrd_convert.pl → rrd_convert
      +
    • +
    • Bugfix: Ignore old XML files while building the service list
      +
    • +
    • Template: New template check_hpasm.php
      +
    • +
    • Bugfix: Installer now checks for json_decode()
      +
    • +
    • Workaround: Allow “trailing unfilled semicolons”. Workaround for nsclient++
      +
    • +
    • Template: Updates for check_openmanage.php, check_hp_bladecenter.php and check_dell_baldecenter.php ( Trond Hasle Amundsen )”
      +
    • +
    + +

    + +pnp-0.6.2 12/23/2009 + +

    +
      +
    • Feature: XML_WRITE_DELAY option added to process_perfdata.cfg as suggested by Mathias Kettner
      +
    • +
    • Feature: New template integer.php
      +
    • +
    • Update: FPDI update to 1.3.1
      +
    • +
    • Feature: PNP will now work with lighttpd and php-cgi
      +
    • +
    • Template: check_mk-ps.perf.php added ( by Mathias Kettner )
      +
    • +
    • Feature: PNP will now work without mod_rewrite → webfe
      +
    • +
    • Bugfix: Wrong pdf link used on site 'pages' and 'basket'
      +
    • +
    • Bugfix: Incorrect group permissions on spool directory
      +
    • +
    + +

    + +pnp-0.6.1 11/22/2009 + +

    +
      +
    • Feature: RRD heartbeat per check_command → tpl_custom
      +
    • +
    • Feature: New config.php option pdf_graph_opt
      +
    • +
    • Feature: Recognize the 'background_pdf' option in page definitions → pages
      +
    • +
    • Feature: Recognize the 'source' option in page definitions → pages
      +
    • +
    • Feature: Array $TIMERANGE now available for templates → timeranges
      +
    • +
    • Bugfix: ./configure --sysconfdir no longer ignored
      +
    • +
    • Feature: Store internal runtime statistics on a per minute base
      +
    • +
    • Feature: Added two widgets views/widget_menu.php and views/widget_graph.php
      +
    • +
    + +

    + +pnp-0.6.0 10/30/2009 + +

    +
      +
    • Webfrontend based on Kohana
      +
    • +
    • Webfrontend based on jQuery Themes
      +
    • +
    • Javascript-functions using jQuery plugins
      +
    • +
    • process_perfdata.pl will be able to use one RRD database per datasource
      +
    • +
    • improved installer. Specification of directory layouts using --with-layout
      +
    • +
    • RRDtool errors are now displayed as images. no more missing images
      +
    • +
    • PNP templates cannot overwrite internal variables anymore
      +
    • +
    • PNP templates of version 0.4.x can still be used
      +
    • +
    • PDF functions recoded
      +
    • +
    • Template default.php optimized
      +
    • +
    • Export from RRD databases into XML, CSV and JSON format using the RRDtool “xport” function
      +
    • +
    • Page functions recoded
      +
    • +
    • Error pages links to online FAQ
      +
    • +
    • Mouseover Popup in Nagios frontend via jQuery.clueTip plugin
      +
    • +
    • Full support of rrdcached
      +
    • +
    + +
    + +
    +
    + + + +

    Upgrade to version 0.6.x

    +
    + +

    + +The web-frontend has been completely rewritten and is now based on the PHP MVC framework Kohana. This leads to changed dependencies which must be checked prior to installation. +

    + +

    +Note: At first an upgrade is like a new installation. Afterwards some changes should be made which are described further down. +

    + +

    +Without specifying any options during ./configure PNP 0.4.x was installed below an existing Nagios-Installation at /usr/local/nagios. +

    + +

    +Without specifying any options during ./configure PNP 0.6.x will be installed in a separate directory at /usr/local/pnp4nagios, i.e. it should be viewed as an independent application. +

    + +

    +Note: It is sufficient to copy the *.rrd files from the old to the new location. They contain the data The *.xml files are recreated every time new performance data arrives as they contain meta information. The internal structure of the xml files has changed so you wouldn't be able to use them either way. +

    + +
    + +

    Comparison of the structure

    +
    + +

    + +Summary of a PNP 0.4.14 installation +

    +
    +./configure
    +...
    +*** Configuration summary for pnp 0.4.14 05-02-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/nagios
    +  HTML Dir:                         /usr/local/nagios/share/pnp
    +  Config Dir:                       /usr/local/nagios/etc/pnp
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/nagios/share/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/nagios/var/spool/perfdata/
    +
    + +

    +Summary of a PNP 0.6.0 installation +

    +
    +./configure
    +...
    +*** Configuration summary for pnp4nagios-0.6.0 07-30-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    + +

    +Looking at these lines result in the parameters to be changed and the upgrade strategy. +

    + +
    + +

    Adjustments

    +
    + +

    + +The templates of the action_url definitions have changed. Instead of ”/nagios/pnp” the URL should be ”/pnp4nagios” and instead of “index.php” now “graph” will be used. +

    +
    define host {
    +  name       host-pnp
    +  register   0
    +  action_url /pnp4nagios/graph?host=$HOSTNAME$
    +}
    +
    +define service {
    +  name       srv-pnp
    +  register   0
    +  action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    + +

    +The definitions for the preview popup function are similar + +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    + +Attention: It is not an error that the strings in front and after “class” contain only one quote. +

    + +

    +Other than described in the 0.4.x documentation these templates can be used for Nagios 2.x and 3.x. +

    + +

    +The variables in the files in the templates folder have to be initialised before first use. Example +

    +
    $lower = ""
    + +

    + +Earlier you were able to append to variables which weren't initialised before first use. Example: + +

    +
    foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +Now you have to change that to + +

    +
    +$def[1] = "";
    +foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +
    + +Constants in template files don't work anymore, so that they have to be converted to variables. +

    +
    define("_WARNRULE", '#FFFF00');
    + +

    +may be changed to +

    +
     $WARNRULE = '#FFFF00';
    + +

    +Please keep in mind that all occurrences have to be changed ;-). +

    + +
    + +

    Upgrade scenario using NPCD

    +
    +
      +
    1. planning the new setup
      +
    2. +
    3. perform test installation and acquaint oneself with the new system
      +
    4. +
    5. create backup of the old installation
      +
    6. +
    7. install PNP 0.6.x at /usr/local/pnp4nagios
      +
    8. +
    9. make install-config
      +
    10. +
    11. make install-webconf
      +
    12. +
    13. reload Apache
      +
    14. +
    15. test Apache-config
      +
        +
      1. call of /pnp4nagios has to report an empty perfdata directory
        +
      2. +
      +
    16. +
    17. create /usr/local/pnp4nagios/etc/npcd.cfg from npcd.cfg-sample
      +
        +
      1. check paths and adapt changes from 0.4.x if necessary
        +
      2. +
      +
    18. +
    19. adjust all paths in nagios.cfg to the new PNP installation
      +
    20. +
    21. adjust all paths in the command definitions
      +
    22. +
    23. stop npcd using /etc/init.d/npcd stop
      +
    24. +
    25. make install-init installs the new init script for npcd
      +
    26. +
    27. /etc/init.d/nagios stop
      +
    28. +
    29. copy /usr/local/nagios/share/perfdata to /usr/local/pnp4nagios/var/perfdata. Attention: check the permissions
      +
    30. +
    31. /etc/init.d/npcd start
      +
    32. +
    33. /etc/init.d/nagios start
      +
    34. +
    + +
    + +
    +
    + + + +

    Installation

    +
    + +

    +The installation of PNP will be described in more detail. It is expected that nagios was compiled from source and is located in /usr/local/nagios.
    + +Attention: The description applies to the developer version PNP 0.6.0.
    + +Please note that PNP has to be configured after the installation. +

    + +
    + +

    Make and more

    +
    + +

    +The installation of PNP is controlled by makefiles. The system is analyzed after invocation of ./configure and the detected values are tranferred to makefiles. +

    + +

    +Please unpack PNP as user root: + +

    +
    +tar -xvzf pnp4nagios-HEAD.tar.gz
    +cd pnp4nagios
    +
    + +

    +./configure is to be called from the directory pnp4nagios. +

    +
    +./configure
    +
    + +

    + +Note: Without specifying any options user and group will be “nagios”. If you have different values then please use the parameters ”--with-nagios-user” and ”--with-nagios-group”, respectively. Using Icinga the call might be + +

    +
    +./configure --with-nagios-user=icinga --with-nagios-group=icinga
    +
    + +

    + +Some lines run across the screen. The output at the end is important. +

    +
    +*** Configuration summary for pnp4nagios-0.6.2 23-12-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.2.12
    +  RRDs Perl Modules:                FOUND (Version 1.2012)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    +
    +  Review the options above for accuracy.  If they look okay,
    +  type 'make all' to compile.
    + +

    +The paths shown should be checked. If the displayed values aren't correct you can change them calling ./configure with appropriate options.
    + +Attention: “Location of rrdtool binary” means path including name of binary! If necessary it can be specified using the following syntax: + +

    +
     ./configure --with-rrdtool=/usr/local/rrdtool-1.2.xx/bin/rrdtool
    +
     ./configure --help 
    + +

    + +shows the supported options.
    +
    + +

    + +

    +Invoking +

    +
     make all
    + +

    + +compiles the components like NPCD which are written in C + +

    +
     make install
    + +

    + +copies everything to the right places in the file system. The paths were already shows during ./configure. +

    + +

    +After the installation of the program and HTML files you can copy a sample Apache configuration file to your web-server config directory + +

    +
     make install-webconf
    + +

    + +You can call + +

    +
     make install-config
    + +

    + +optionally. This way config files for process_perfdata.pl and npcd are copied to etc/pnp. +

    + +

    +To install the NPCD Init script call + +

    +
     make install-init
    + +

    + +All these steps are combined in + +

    +
     make fullinstall
    + +

    + +Note: As already stated the Nagios settings will be used per default. If you are using Icinga the file '/etc/apache2/conf.d/pnp4nagios.conf' has to be edited to change the path to AuthUserFile (the path may differ between distributions): + +

    +
    #       AuthUserFile /usr/local/nagios/etc/htpasswd.users
    +        AuthUserFile /usr/local/icinga/etc/htpasswd.users
    + +

    +Attention: After copying the configuration file for the web server you have to restart the web server (service httpd restart or /etc/init.d/apache2 restart, respectively). +

    + +
    + +

    Update

    +
    + +

    + +The update of a 0.6.x version works (nearly) the same way as an installation. Please note that you have to call ./configure with the same options you used during the first installation. +Please check if you changed anything in the folder share/templates.dist. Own templates should be placed in share/templates to avoid being overwritten.
    + +Attention: If you changed config.php then you should save this file before it is overwritten when you execute make install-config. +

    + +

    +You can skip make install-webconf and make install-init because nothing changed between 0.6.x versions. +

    + +
    + +

    The components

    +
    + +

    + +After installation the components of PNP were copied to the appropriate places in the file system. These are +

    + +

    +the PHP-Files for the web-frontend below + +

    +
     /usr/local/pnp4nagios/share
    + +

    + +the data collector process_perfdata.pl in + +

    +
     /usr/local/pnp4nagios/libexec
    + +

    + +sample config files with the suffix -sample in + +

    +
     /usr/local/pnpnagios/etc
    + +

    + +the config file config.php for the web frontend in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    + +back to contents | configuration + +

    + +
    + +
    +
    + + + +

    Configuration

    +
    + +

    + +The configuration of the already mentioned modes of performance data processing will be described in more detail. +

    + +
    + +

    Synchronous Mode

    +
    + +

    + + The synchronous mode is the simplest way to integrate the data collector process_perfdata.pl into nagios. Every event will trigger an execution of process-service-perfdata. +

    + +

    +Initially you have to enable processing of performance data in nagios.cfg. Please note that this directive might already exist in the config file. Default is “0”. + +

    +
     process_performance_data=1
    + +

    + +Data processing has to be disabled in the definition of every host or service whose performance data should NOT be processed. +

    +
    +define service {
    +   ...
    +   process_perf_data 0
    +   ...
    +}
    +
    + +

    +Since Nagios 3.x it is possible to deactivate the export of environment variables (as part of optimizing the system for maximum performance). Unfortunately this directive has to be enabled to use the synchronous mode. So either you use the default value (which means that the export is enabled) or you define the variable in nagios.cfg +

    +
    enable_environment_macros=1
    + +

    +Additionally the command to process performance data is to be specified in nagios.cfg + +

    +
     service_perfdata_command=process-service-perfdata
    + +

    + +Starting with Nagios 3.0 it may be useful to enable processing of performance data for hosts as well. Due to changed host check logic Nagios 3 now performs regularly scheduled host checks. + +

    +
     host_perfdata_command=process-host-perfdata
    + +

    + +Nagios has to be notified about the referenced commands as well. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +You can see that calling process_perfdata.pl doesn't require any arguments apart from specifing the option -d ( DATATYPE ) if you want to process performance data resulting from host checks. +

    +
    +define command {
    +       command_name    process-service-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +}
    +
    +define command {
    +       command_name    process-host-perfdata
    +       command_line    /usr/bin/perl /usr/local/pnp4nagios/libexec/process_perfdata.pl -d HOSTPERFDATA
    +}
    +
    + +

    +Note process_perfdata.pl cannot be started under control of ePN ( embedded Perl Nagios ). Therefore the script is explicitly called using /usr/bin/perl ( or where you perl binary is located ). If you use Nagios 3.x or do not use ePN there is no need to specify /usr/bin/perl. +

    + +
    + +

    Bulk Mode

    +
    + +

    + +Bulk mode is a bit more complicated than the synchronous mode but reduces the load on the nagios server significantly because the data collector process_perfdata.pl is not invoked for every service/host check. +

    + +

    +In bulk mode Nagios writes the data to a temporary file in a defined format. This file is processed by process_perfdata.pl at certain intervals. Nagios will take care for starting and running it periodically. +

    + +

    +Processing of performance data has to be enabled in nagios.cfg + +

    +
     process_performance_data=1
    + +

    + +Additionally some new directives are required +

    +
    +#
    +# service performance data
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# host performance data starting with Nagios 3.0
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    + +Attention: Please note that these template definitions differ from the ones delivered in nagios.cfg! +

    + +

    +The directives and their meaning: + +

    +
      +
    • service_perfdata_file path to the temporary file which should contain the performance data.
      +
    • +
    • service_perfdata_file_template format of the temporary file. Data will be defined using Nagios macros.
      +
    • +
    • service_perfdata_file_mode option “a” specifies that data is to be appended to the file.
      +
    • +
    • service_perfdata_file_processing_interval the interval is 15 seconds
      +
    • +
    • service_perfdata_file_processing_command the command to be called during the interval.
      +
    • +
    + +

    + +The used commands have to be announced to Nagios. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/service-perfdata
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /usr/local/pnp4nagios/libexec/process_perfdata.pl --bulk=/usr/local/pnp4nagios/var/host-perfdata
    +}
    +
    +
    + +
    +

    NOTE:

    +
    +Because there is more data to process than in synchronous mode process_perfdata.pl will take longer to do this so you should check the TIMEOUT value in etc/process_perfdata.cfg and adjust it appropriately.
    +
    + +
    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + + The configuration is identical to the Bulk Mode except for the used command. +Processing of performance data has to be enabled in nagios.cfg + +

    +
     process_performance_data=1
    + +

    + +Additionally some new directives are required +

    +
    +#
    +# service performance data
    +#
    +service_perfdata_file=/usr/local/pnp4nagios/var/service-perfdata
    +service_perfdata_file_template=DATATYPE::SERVICEPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tSERVICEDESC::$SERVICEDESC$\tSERVICEPERFDATA::$SERVICEPERFDATA$\tSERVICECHECKCOMMAND::$SERVICECHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$\tSERVICESTATE::$SERVICESTATE$\tSERVICESTATETYPE::$SERVICESTATETYPE$
    +service_perfdata_file_mode=a
    +service_perfdata_file_processing_interval=15
    +service_perfdata_file_processing_command=process-service-perfdata-file
    +
    +#
    +# host performance data starting with Nagios 3.0
    +# 
    +host_perfdata_file=/usr/local/pnp4nagios/var/host-perfdata
    +host_perfdata_file_template=DATATYPE::HOSTPERFDATA\tTIMET::$TIMET$\tHOSTNAME::$HOSTNAME$\tHOSTPERFDATA::$HOSTPERFDATA$\tHOSTCHECKCOMMAND::$HOSTCHECKCOMMAND$\tHOSTSTATE::$HOSTSTATE$\tHOSTSTATETYPE::$HOSTSTATETYPE$
    +host_perfdata_file_mode=a
    +host_perfdata_file_processing_interval=15
    +host_perfdata_file_processing_command=process-host-perfdata-file
    +
    + +

    + +Attention: Please note that these template definitions differ from the ones delivered in nagios.cfg! +

    + +

    +The directives and their meaning: + +

    +
      +
    • service_perfdata_file path to the temporary file which should contain the performance data.
      +
    • +
    • service_perfdata_file_template format of the temporary file. Data will be defined using Nagios macros.
      +
    • +
    • service_perfdata_file_mode option “a” specifies that data is to be appended to the file.
      +
    • +
    • service_perfdata_file_processing_interval the interval is 15 seconds
      +
    • +
    • service_perfdata_file_processing_command the command to be called during the interval.
      +
    • +
    + +

    + +The used commands have to be announced to Nagios. If you used the quickstart installation guides for Nagios you can modify the definitions in commands.cfg. +

    +
    +define command{
    +       command_name    process-service-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/service-perfdata /usr/local/pnp4nagios/var/spool/service-perfdata.$TIMET$
    +}
    +
    +define command{
    +       command_name    process-host-perfdata-file
    +       command_line    /bin/mv /usr/local/pnp4nagios/var/host-perfdata /usr/local/pnp4nagios/var/spool/host-perfdata.$TIMET$
    +}
    +
    + +

    +Using these commands the file service-perfdata will be moved to var/spool/ after the interval specified in service_perfdata_file_processing_interval has passed. The Nagios macro $TIMET$ is appended to the filename to avoid overwriting of old files unintentionally. The macro $TIMET$ contains the current timestamp in time_t format (seconds since the UNIX epoch). +

    + +

    +In the directory /usr/local/pnp4nagios/var/spool/ files are gathered to be processed by NPCD. +

    + +

    +NPCD monitors the spool directory and passes the file names to process_perfdata.pl. This way processing of performance data is completely decoupled from nagios. +

    + +

    +Before starting NPCD you have to check the paths to the spool directory and to process_perfdata.pl specified in the config file npcd.cfg. +The only thing that remains is to start NPCD. + +

    +
     /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +The option -d starts NPCD as a daemon in the background. +

    + +
    + +

    Bulk Mode with NPCD and npcdmod

    +
    + +

    + +Attention +Starting with Nagios 4 the internal structures have changed so the start of the module will fail. So far there are no plans to support Nagios 4. Please select any other of the modes. +

    + +

    + This mode uses the event broker module npcdmod.o. The flow of data is identical to “bulk mode with NPCD”. The internal perfdata routines of Nagios activated by the “*_perf_data_*” directives in nagios.cfg are *NOT* used anymore. The module npcdmod.o takes over the task of processing the data required by PNP. +

    + +

    +Pro: +

    +
      +
    • The perfdata routines can now be used for other addons.
      +
    • +
    • The configuration is easier.
      +
    • +
    • It is the preferred mode of the PNP developers.
      +
    • +
    + +

    + +Adjustments in nagios.cfg: +

    +
    +process_performance_data=1
    +broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +
    + +

    +All other directives mentioned on this page must NOT be used. +

    + +

    +Attention: If you have changed the value of event_broker_options from -1 to another value then please note that PNP needs the bits 2 and 3 set (0b01100). Make sure that the resultung value has these bits set because otherwise there will be no performance data to process. +

    + +

    +After restarting Nagios information regarding the start of the module will be logged. +

    + +

    +Excerpt from nagios.log + +

    +
    +[1277545053] npcdmod: Copyright (c) 2008-2009 Hendrik Baecker (andurin@process-zero.de) - http://www.pnp4nagios.org
    +[1277545053] npcdmod: /usr/local/pnp4nagios/etc/npcd.cfg initialized
    +[1277545053] npcdmod: spool_dir = '/usr/local/pnp4nagios/var/spool/'.
    +[1277545053] npcdmod: perfdata file '/usr/local/pnp4nagios/var/perfdata.dump'.
    +[1277545053] npcdmod: Ready to run to have some fun!
    +[1277545053] Event broker module '/usr/local/pnp4nagios/lib/npcdmod.o' initialized successfully.
    +
    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +Since version 0.6.12 PNP4Nagios can be driven as a gearman worker. This way large Nagios environments are possible using mod_gearman. Nagios and PNP4Nagios can be run on different machines. +

    + +

    +You need a mod_gearman environment up and running like described by Sven Nierlein on http://labs.consol.de/lang/en/nagios/mod-gearman/. +

    + +

    +You'll find a section on gearman in etc/process_perfdata.cfg: + +

    +
    PREFORK = 1
    +GEARMAN_HOST = localhost:4730
    +REQUESTS_PER_CHILD = 10000
    +ENCRYPTION = 1
    +KEY = should_be_changed
    +#KEY_FILE = /usr/local/pnp4nagios/etc/secret.key
    + +

    + +Using PREFORK = <n> you specify the number of child processes. +

    + +

    +GEARMAN_HOST = <host>:<port> specifies host and port of the server running the gearman daemon providing the data. +

    + +

    +REQUEST_PER_CHILD = <n> enables you to define the number of requests processed per process. +

    + +

    +ENCRYPTION = <n> specifies whether to use encryption (“1”) or not. Default is an activated encyrption which should be changed only in special cases. You can either use KEY = <key phrase> or 'KEYFILE =<key file> to specify the location of a file containing the key phrase. + +etc/init.d/pnp_gearman_worker start contains links to the perl script process_perfdata.pl and the config file process_perfdata.cfg''. +

    + +

    +After starting the daemon process using + +

    +
     /etc/init.d/pnp_gearmon_worker start
    + +

    + +the performance data will be processed which is provided by the gearmand daemon on the Nagios server. +

    + +

    +back to contents | checking the functionality + +

    + +
    + +
    +
    + + + +

    Checking the installation

    +
    + +

    + +If everything went well until now you can try to call PNP using your web browser. +When using the installation with default values PNP should be called using http://<server name>/pnp4nagios/. +The first time you will see a page “PNP4Nagios Environment Tests” which includes different checks of necessary components. Obviously all checks have to be passed successfully before you can proceed. Please follow the instructions given on that page.
    + +

    + +

    +If all tests have passed *successfully* the file pnp4nagios/share/install.php can be deleted or renamed. Not till then the web interface is reachable. +

    + +

    +Alternatively you can create a file called pnp4nagios/share/install.ignore which will prevent the call of the installer after further updates. +

    + +

    +If you receive the message “PHP magic_quotes_gpc is deprecated” then please locate your php.ini and set the value to Off. +

    + +

    +Called without any arguments PNP looks for RRD and XML files in pnp4nagios/var/perfdata and shows all graphs of the first host. +

    + +

    +ATTENTION: Immediately after (re-)starting Nagios after you enabled the processing of performance data you will get error messages in your browser because performance data has to be collected and stored in RRD files. Depending on the check interval you are using you have to wait some time before you can view the first graphs. +

    + +
    + +

    Debug Logfile

    +
    + +

    + +Calling make install-config during installation will create a sample config file etc/process_perfdata.cfg-sample. The values in the sample file will correspond to the defaults used by process_perfdata.pl so normally you do not have a file called process_perfdata.cfg while running the procedure.
    + +However you can influence the way process_perfdata.pl works by changing options which have to be specified in process_perfdata.cfg. +

    + +

    +The most important options launching PNP are LOG_LEVEL and LOG_FILE. We recommend setting the LOG_LEVEL value to “2” so you can track what process_perfdata.pl will do. +Most likely we will ask for excerpts from perfdata.log if you open a support request on the mailing lists as well as the output of the verify_pnp_config script so please provide them ;-). +

    + +

    +During normal operation the debug level should be set to 0 to avoid performance issues due to unnecessary entries in the log file. +

    + +
    + +

    Something went wrong

    +
    + +

    + +Some basic settings should be checked +

    + +

    +1. Have any RRD and XML files been created? +process_perfdata.pl will create a new directory under pnp/perfdata for every host. In this directory an RRD database and an XML file will be created for every service. The host data will be stored in _HOST_.xml and _HOST_.rrd respectively.
    + +If graphing stops out of a sudden then open the appropriate XML file. There are two tags called <RC> and <TXT>. <RC> shows the return code of the RRDtool update and <TXT> a textual description.
    + +Sometimes you have to specify additional options so that performance data is produced. In some cases a wrapper script might help.
    + +However not all checks provide performance data. That applies - among others - to “check_ping” in contrast to “check_icmp” which does provide data (starting with Nagios plugin version 1.4.12 check_ping does provide performance data).
    + +Using the web interface the detail information of hosts/services shows a field “Performance Data”. If it is empty there is no data available so no files are written to the appropriate directory and that is why PNP does not provide you with graphs!
    + +The following image shows the information of a “PING” service. The output of the plugin is surrounded by a blue border, the performance data by a red one.
    + +status information +

    + +

    +2. Has nagios called process_perfdata.pl? +In the config file for process_perfdata.pl (etc/process_perfdata.cfg) you can increase the debug level. Data processing will be logged in var/perfdata.log. +

    + +

    +3. Graphs are shown without text? +Have a look at the requirements. +

    + +

    +4. Some graphs are shown, others report the error “parser error: Input is not proper UTF-8” or something similar. Please check if your data contains “special” characters not present in the ASCII set. Try to set XML_ENC in process_perfdata.cfg to ISO-8859-1 or something appropriate. Wait until the xml file is newly created and retry. +

    + +

    +5. Using the npcdmod module the value of the nagios.cfg directive event_broker_options may have to be adapted if it was modified. You'll find some details here. +

    + +

    +6. You can use the script verify_pnp_config.pl after installation to check your settings and if performance data is present. +

    + +

    +7. Things look OK, but some files are being left in the spool directory (/usr/local/pnp4nagios/var/spool/<perfdata_filename>-PID-<process_perfdata_pid>). If process_perdata.pl is not able to write to the destination directory (/usr/local/pnp4nagios/share/perfdata/<host>), it will stop and not remove the file. That will increase the size of the spool directory and slow down performance data processing. This problem is likely to occur if you have copied directories from a previous installation and/or manually created directories and left them with wrong permissions or wrong ownership. +

    + +

    +back to contents | verify_pnp_config.pl + +

    + +
    + +
    +
    + + + +

    verify_pnp_config

    +
    + +

    + +In case of problems there is a script called verify_pnp_config.pl located on http://verify.pnp4nagios.org. It enables you to check the configuration settings as well as performance data of hosts or services. It can be used prior and during runtime of PNP. +

    + +
    + +

    Download

    +
    +
    +wget http://verify.pnp4nagios.org/verify_pnp_config
    +
    + +
    + +

    Test

    +
    + +

    + +The verify script is located on http://verify.pnp4nagios.org and needs three start options +

    +
      +
    • --mode One of the modes described on modes
      +
    • +
    • --config Location of nagios.cfg or icinga.cfg
      +
    • +
    • --pnpcfg Path to PNP´s etc directory
      +
    • +
    + +

    + +Calling perl verify_pnp_config will show the available options. +

    + +

    +The following is a sample run + +

    +
    +lenny:~# perl verify_pnp_config --mode npcdmod --config=/usr/local/nagios/etc/nagios.cfg --pnpcfg=/usr/local/pnp4nagios/etc
    +[INFO]  ========== Starting Environment Checks ============
    +[INFO]  My version is: verify_pnp_config-0.6.14-R.31
    +[INFO]  Reading /usr/local/nagios/etc/nagios.cfg
    +[OK  ]  Running product is 'nagios'
    +[OK  ]  object_cache_file is defined
    +[OK  ]  object_cache_file=/usr/local/nagios/var/objects.cache
    +[INFO]  Reading /usr/local/nagios/var/objects.cache
    +[OK  ]  resource_file is defined
    +[OK  ]  resource_file=/usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/process_perfdata.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/pnp4nagios_release
    +[OK  ]  Found PNP4Nagios version "0.6.14"
    +[OK  ]  Effective User is 'nagios'
    +[OK  ]  User nagios exists with ID '1000'
    +[OK  ]  Effective group is 'nagios'
    +[OK  ]  Group nagios exists with ID '1000'
    +[INFO]  ========== Checking npcdmod Mode Config  ============
    +[OK  ]  process_performance_data is 1 compared with '/1/'
    +[OK  ]  event_broker_options is defined
    +[OK  ]  event_broker_options=-1
    +[OK  ]  event_broker_option bits 2 and 3 enabled (12)
    +[OK  ]  broker_module is defined
    +[OK  ]  broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  npcdmod.o config file is /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg used by npcdmod.o is readable
    +[OK  ]  npcd daemon is running
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg is used by npcd and readable
    +[OK  ]  npcd and npcdmod.o are using the same config file (/usr/local/pnp4nagios/etc/npcd.cfg)
    +[INFO]  Nagios config looks good so far
    +[INFO]  ========== Checking config values ============
    +[INFO]  Reading /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  Script /usr/local/pnp4nagios/libexec/process_perfdata.pl is executable
    +[INFO]  ========== Starting global checks ============
    +[OK  ]  status_file is defined
    +[OK  ]  status_file=/dev/shm/status.dat
    +[INFO]  Reading /dev/shm/status.dat
    +[INFO]  ==== Starting rrdtool checks ====
    +[OK  ]  RRDTOOL is defined
    +[OK  ]  RRDTOOL=/usr/bin/rrdtool
    +[OK  ]  /usr/bin/rrdtool is executable
    +[OK  ]  RRDtool 1.3.1  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>
    +[OK  ]  USE_RRDs is defined
    +[OK  ]  USE_RRDs=1
    +[OK  ]  Perl RRDs modules are loadable
    +[INFO]  ==== Starting directory checks ====
    +[OK  ]  RRDPATH is defined
    +[OK  ]  RRDPATH=/usr/local/pnp4nagios/var/perfdata
    +[OK  ]  Perfdata directory '/usr/local/pnp4nagios/var/perfdata' exists
    +[WARN]  62 hosts/services are not providing performance data
    +[WARN]  'process_perf_data 1' is set for 43 hosts/services which are not providing performance data!
    +[WARN]  'process_perf_data 0' is set for 27 of your hosts/services
    +[OK  ]  'process_perf_data 1' is set for 243 of your hosts/services
    +[INFO]  ==== System sizing ====
    +[OK  ]  269 hosts/service objects defined
    +[INFO]  ==== Check statistics ====
    +[WARN]  Warning: 3, Critical: 0
    +[WARN]  Checks finished...
    +
    + +
    + +

    Performance data

    +
    + +

    +Starting with 0.6.19-R.37 (2013-02-17) the script will accept the option --object (or -o) followed by a string to specify a host name and/or service description to additionally show performance data (if any) of the object(s) found. The data is enclosed in brackets, followed by the value of the directive process_performance_data (ppd=n). +

    + +

    +host = show performance information for host host
    + +;service = show performance information for service service
    + +host;service = show performance information for service service on host host +

    + +

    +The strings are taken as regular expressions (perl syntax). + +

    + +
    + +
    +
    + + + +

    Nagios web frontend

    +
    + +

    +Of course PNP should be easily accessible. You do not want to search long for the right graph. +

    + +

    +Nagios itself features external URLs using so called extended info configs. Due to changes between Nagios 2.x and Nagios 3.x both versions are described. +

    + +
    + +

    Nagios 2.x

    +
    + +

    + +With Nagios 2.x the integration of external URLs into the nagios web interface is made using Extended Info Objects for services. For PNP we use the directive action_url to call the PNP web frontend with the appropriate options. +

    +
    +define serviceextinfo {
    +   host_name             localhost
    +   service_description   load
    +   action_url            /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    +
    + +

    +You have to specify an additional Extended Info Definition for every service. +

    + +
    + +

    Nagios 3.x

    +
    + +

    + +Since nagios 3.0 the action_url-directive has be moved to the host or service definition. This way the definition of URLs to the PNP-interface has been simplified. The serviceextinfo and hostextinfo definitions are deprecated. +

    + +

    +First two nagios templates are defined. If you used the Nagios quickstart installation guides you can append these lines to templates.cfg: +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    +These two templates can now be included via “use srv-pnp” or “use host-pnp” for services and hosts respectively. If you used the quickstart installation guide you might for example edit the file localhost.cfg and add the template to the host or service definition as follows: +

    +
    define host{
    +        use                     linux-server,host-pnp    ; Name of host templates to use
    +                                                         ; This host definition will inherit all variables that are defined
    +                                                         ; in (or inherited by) the linux-server host template definition.
    +        host_name               localhost
    +        alias                   localhost
    +        address                 127.0.0.1
    +        }
    +
    +
    define service{
    +        use                     local-service,srv-pnp   ; Name of service template to use
    +        host_name               localhost
    +        service_description     PING
    +        check_command           check_ping!100.0,20%!500.0,60%
    +        }
    +
    + +

    + +The links to the correct URLs are created automagically.
    +
    + +

    + +

    +Tips: if you want to open the PNP window in your main frame (on the right of the menu) instead of a new page, just set action_url_target=main in your nagios cgi.cfg +

    + +
    + +

    Popups

    +
    + +

    +You can integrate PNP into Nagios in a way that you have current graphs without clicking any icons. This can be accomplished using the CGI Includes which allow us to include JavaScript code in the status detail view ( status.cgi ). +

    + +

    +Prerequisites: +

    +
      +
    • PNP is installed and running
      +
    • +
    • the file status-header.ssi from the contrib/ssi/ folder of the PNP package was copied to /usr/local/nagios/share/ssi/.
      +Attention: This file must NOT be executable. Otherwise it will be treated as a CGI which will result in an error.
      +*Note to Apache admins*: Apache ssi and Nagios ssi only have a similar name.
      +
    • +
    • the appropriate service definition(s) has/have been modified. Please note that until Nagios 2.x you have to modify the serviceextinfo definition (which is deprecated starting with Nagios 3).
      +
    • +
    + +

    + +Definition: + +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    + +After a restart of Nagios (after modifying the definitions) the result might look like this:
    + + +

    + +

    +back to contents | config options + +

    + +
    + +
    +
    + + + +

    PNP Web Frontend

    +
    + +

    + +The behaviour of the PNP Web-Frontend can be controlled through the config file etc/config.php. This file will be overwritten during updates of PNP as the paths and options are detected during ./configure. +

    + +

    +Own adjustments should be made in etc/config_local.php. If this file does not exist the file config.php can be taken as a guideline. +

    + +
    + +

    etc/config.php

    +
    + +

    + +Following the most important parameters: +

    + +

    +The path to the RRDtool binary. Will be detected by ./configure + +

    +
     $conf['rrdtool'] = "/usr/bin/rrdtool";
    + +

    + +Height and width of the RRD graphs + +

    +
     $conf['graph_width'] = "500";
    + $conf['graph_height'] = "100";
    + +

    + +Screen sizes may vary, pages sizes won't. The following two directives enable you to specify different sizes for the creation of PDFs. If they aren't specified the values of the graph sizes are taken. + +

    +
     $conf['pdf_width'] = "675";
    + $conf['pdf_height'] = "100";
    + +

    + +Additional options passed with every call of RRDTool, for example --slope-mode to smooth the graphs + +

    +
     $conf['graph_opt'] = "";
    + +

    + +The path to the RRD and XML files created by process_perfdata.pl + +

    +
     $conf['rrdbase'] = "/usr/local/pnp4nagios/var/perfdata/";
    + +

    + +The path to the config file for the pages. + +

    +
     $conf['page_dir'] = "/usr/local/pnp4nagios/etc/pages/";
    +
    + +

    +PNP pages will be refreshed every n seconds + +

    +
     $conf['refresh'] = "90";
    +
    + +

    +Max. age of RRD files in seconds. After reaching this value links to the graphs will be marked as inactive + +

    +
     $conf['max_age'] = 60*60*6;
    +
    + +

    + +Base URL to the Nagios CGIs + +

    +
     $conf['nagios_base'] = "/nagios/cgi-bin";
    +
    + +

    + +List of users who are allowed to view links to the services of the current host + +

    +
     $conf['allowed_for_service_links'] = "EVERYONE";
    +
    + +

    +List of users who can view/access the host search field + +

    +
     $conf['allowed_for_host_search'] = "EVERYONE";
    +
    + +

    +If PNP is called with a host only ( index.php?host=<myserver> ), the defined user is shown an overview of all services related to this host + +

    +
     $conf['allowed_for_host_overview'] = "EVERYONE";
    +
    + +

    +The periods of time the RRD graphs will show are determined using the array $views[]. The title and number of graphs can be specified globally in this place +

    +
    +$views[] = array('title' => 'One Hour',  'start' => (60*60) );
    +$views[] = array('title' => '4 Hours',   'start' => (60*60*4) );
    +$views[] = array('title' => '25 Hours',  'start' => (60*60*25) );
    +$views[] = array('title' => 'One Week',  'start' => (60*60*25*7) );
    +$views[] = array('title' => 'One Month', 'start' => (60*60*24*32) );
    +$views[] = array('title' => 'One Year',  'start' => (60*60*24*380) );
    +
    + +

    +You can add more views ($views[5], …) but please keep in mind that under normal circumstances ALL views you defined are shown. +

    + +

    +back to contents | timeranges + +

    + +
    + +
    +
    + + + +

    Timeranges

    +
    + +

    + +In the overview PNP shows five timeranges which can be defined in config.php. +

    + +

    +Additionally you can influence the timeranges via the URL. This can be useful to automatically create PDF documents. The ranges can be defined using the options “start” and “end”. +

    + +

    +Example: + +

    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=-1week
    + +

    + +The graph will start one week prior to the current date and time. It will end at the current timestamp. + +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    start end view result
    all views ending at current timestamp
    x all views starting at defined date
    x all views ending at defined date
    x x one view between the two dates
    x one view ending at current timestamp
    x x one view starting at defined date
    x x one view ending at defined date
    + +

    +Examples of different specifications + +

    + + + + + + + + + + + + + + + + + + + + + + +
    format description
    2009W04 4. week of 2009
    1.5.2009 May, 1st 2009
    -1 day one day back
    -3 weeks 3 weeks back
    -1 year one year back
    yesterday yesterday
    + +

    +back to contents | pages + +

    + +
    + +
    +
    + + + +

    Pages

    +
    + +

    + +“pages” provide the opportunity to collect graphs of different hosts/services on one page. That way - as an example - you can display the traffic rates of all tape libraries. Regular expressions are possible so you can accomplish a lot with only few definitions - provided that you have appropriate names. +The directory specified using “$conf['page_dir']” contains one or more file with the extension ”.cfg”. +

    + +

    +Comments start with a hash-sign (#) and are possible within lines as well. Each file contains a “page” definition which specifies the name of the page and it determines whether the following graph definition contains regular expressions or not.
    + +The description behind page_name appears in the list of available pages and will be used as title of the browser window. Attention: “host_name” and “service_desc” refer to the name of the file in the perfdata directory, not to the definition in Nagios. Blanks are replaced by underscores (_). +

    +
    define page {
    +       use_regex 1		# 0 = use no regular expressions, 1 = use regular expressions
    +       page_name test-page	# page description
    +}
    + +

    +One or more “graph” definitions follow: +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    Current_Load
    +}
    + +

    + +Attention: The list of host name will only work if you use regex 0! +

    +
    define graph {
    +       host_name       host4
    +       service_desc    Current_Users
    +}
    + +

    +And now some definitions with regular expressions. At first all hosts whose names are starting with “Tape”: + +

    +
    define graph {
    +       host_name       ^Tape
    +       service_desc    Traffic
    +}
    + +

    +all hosts whose names are ending with “00”: + +

    +
    define graph {
    +       host_name       00$
    +       service_desc    Load
    +}
    + +

    +all services of localhost whose names contain “a” or “o”, respectively: + +

    +
    define graph {
    +       host_name       localhost
    +       service_desc    a|o
    +}
    + +

    +all services whose names contain an underscore followed by (at least) three digits on all hosts whose names start with “UX”: + +

    +
    define graph {
    +       host_name       ^UX
    +       service_desc    _\d{3}
    +}
    + +

    +In some cases you may want to limit the display to just one graph. To accomplish this you can use the optional directive “source” followed by a number specifying the position within the RRD file starting at 0 + +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    PING
    +       source          1
    +}
    + +

    +back to contents | data export + +

    + +
    + +
    +
    + + + +

    Data export

    +
    + +

    + +PNP provides access to RRD data using the xport controller. The output format can be specified. At the moment the formats xml, json and csv are supported. +

    + +

    +The controller can be called using the URL + +

    +
    /pnp4nagios/xport/<format>?host=<hostname>&srv=<servicedesc>
    + +

    + +whereas <format> has to be replaced with the desired format. +

    + +

    + +You can also use wget to generate images and place them in periodic reports. One example may be: +

    +
    wget -O image.png 'http://<user>:<pass>@<nagios-server>/pnp4nagios/image?host=<hostname>&srv=<service>&view=2&source=0'
    + +

    +view=<n> limits the graph to the timeperiod specified in config.php
    + +source=<n> only shows one data source if you have more than one in your RRD file +

    + +

    +Instead of view you can use start and/or end to specify the time period. For details please look at "time ranges". +

    + +

    +back to contents | templates + +

    + +
    + +
    +
    + + + +

    What are templates?

    +
    + +

    + +PNP uses templates to influence the appearance of RRD graphs. +

    + +

    +The selected check_command determines which template will be used to control the graph. Following will be described where templates are stored and how the decision for the “right” template is made. +

    + +
    + +

    What template will be used when?

    +
    + +

    + +Templates are stored at two places in the file system. + +

    +
      +
    • share/templates.dist - for templates included in the PNP package
      +
    • +
    • share/templates - for custom made templates which are not changed during updates
      +
    • +
    + +

    + +If the graph for the service “http” on host “localhost” should be shown, PNP will look for the XML file perfdata/localhost/http.xml and read its contents. The XML files are created automatically and contain information about the particular host and service. The header contains information about the plugin and the performance data. The XML tag <TEMPLATE> identifies which PNP template will be used for this graph. +

    + +

    +/localhost/http.xml + +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>2</DS>
    +    <NAME>size</NAME>
    +    <UNIT>B</UNIT>
    +    <ACT>263</ACT>
    +    <WARN></WARN>
    +    <CRIT></CRIT>
    +    <MIN>0</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +PNP will append .php to the string and therefore look for a template with the name check_http.php in the following sequence: + +

    +
      +
    1. templates/check_http.php
      +
    2. +
    3. templates.dist/check_http.php
      +
    4. +
    5. templates/default.php
      +
    6. +
    7. templates.dist/default.php
      +
    8. +
    + +

    + +The template default.php takes an exceptional position as it is used every time no other applicable template is found. +

    + +
    + +

    Creating own templates

    +
    + +

    + +PNP templates are PHP files which are included during execution of PNP using the PHP function include(). This means that every PHP code in templates will be interpreted so manipulation of all values is possible. +

    + +

    +PNP template must have the following characteristics: + +

    +
      +
    1. templates must contain valid PHP code.
      +
    2. +
    3. templates must not create any output.
      +
    4. +
    5. the two arrays $opt[] and $def[] have to be filled
      +
    6. +
    + +

    + +These two arrays are used to call 'rrdtool graph' so every option is possible that RRDtool supports. All options of RRDtool are described very thoroughly on the RRDtool Homepage. +

    + +

    +If both arrays contain more than one set of data graphs will be created for every set. +

    + +

    +Inside the templates the data from the related XML files can be used. +

    + +

    +Using the relatively simple template response.php we will describe the most important options. +

    +
    <?php
    +#
    +$opt[1] = "--title \"Response Time For $hostname / $servicedesc\" ";
    +#
    +$def[1] =  "DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE " ;
    +$def[1] .= "AREA:var1#00FF00:\"Response Times \" " ;
    +$def[1] .= "LINE1:var1#000000 " ;
    +$def[1] .= "GPRINT:var1:LAST:\"%3.4lg %s$UNIT[1] LAST \" ";
    +$def[1] .= "GPRINT:var1:MAX:\"%3.4lg %s$UNIT[1] MAX \" ";
    +$def[1] .= "GPRINT:var1:AVERAGE:\"%3.4lg %s$UNIT[1] AVERAGE \" ";
    +?>
    + +

    +Note: as the number (1) and the letter “L” look alike in this listing: the format ”%3.4lg” contains a small letter. +

    + +

    +$opt[1] = ”--title … sets RRDtool options for the first set of data, here the title as you can see. Embedded quotes are masked using a backslash (\). The variables $hostname and $servicedesc were determined through the call of PNP and are available for the template as well. +

    + +

    +$def[1] = “DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE ”; defines which data is to be read from which RRD file. $RRDFILE[1] contains the path to the RRD file of this service. $DS[1] refers to the first data series from the RRD file. +

    + +

    +$def[1] .= “AREA:var1#00FF00:\”Response Times \” ”; the operator ”.=” appends more data to the array $def[1]. An area will be drawn using data from the variable var1. The color is defined in HEX notation #00FF00 (red, green, blue). The label is “Response Times”. +

    + +

    +$def[1] .= “LINE1:var1#000000 ”; As completion of the just drawn area a line (LINE1) will be drawn in black (#000000). +

    + +

    +$def[1] .= “GPRINT:var1:LAST:\”%3.4lg %s$UNIT[1] LAST \” ”;
    + +$def[1] .= “GPRINT:var1:MAX:\”%3.4lg %s$UNIT[1] MAX \” ”;
    + +$def[1] .= “GPRINT:var1:AVERAGE:\”%3.4lg %s$UNIT[1] AVERAGE \” ”;
    +

    + +

    +The three GPRINT lines build up the caption for the graph. The current values are formatted using the printf syntax. +

    + +
    + +

    Available variables

    +
    + +

    + +Using the data collector process_perfdata.pl PNP stores not only performance data but other values exported by Nagios. These values are stored in the XML file associated to the appropriate service. +

    + +

    +In the first part of the XML file the performance data is stored in separate components. +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +....
    +</NAGIOS>
    + +

    +The field <DS> designates the data source and is used to identify the data series of the RRD files and is the key of the following arrays as well. +

    + +

    +The array $UNIT[1] contains the unit of measurement of the first data series. +

    + +

    +The XML file contains other information. When process_perfdata.pl is used in default mode all available macros are at hand with the current values. For the benefit of readability the following lines show only an extract. +

    +
    <NAGIOS>
    +...
    +  <NAGIOS_SERVICENOTIFICATIONID>8418</NAGIOS_SERVICENOTIFICATIONID>
    +  <NAGIOS_SERVICENOTIFICATIONNUMBER>0</NAGIOS_SERVICENOTIFICATIONNUMBER>
    +  <NAGIOS_SERVICEOUTPUT>HTTP OK HTTP/1.1 200 OK - 10087 bytes in 0.125 seconds</NAGIOS_SERVICEOUTPUT>
    +  <NAGIOS_SERVICEPERCENTCHANGE>0.00</NAGIOS_SERVICEPERCENTCHANGE>
    +  <NAGIOS_SERVICEPERFDATA>time=0.124811s;;;0.000000 size=10087B;;;0</NAGIOS_SERVICEPERFDATA>
    +  <NAGIOS_SERVICEPERFDATAFILE></NAGIOS_SERVICEPERFDATAFILE>
    +  <NAGIOS_SERVICEPROBLEMID>0</NAGIOS_SERVICEPROBLEMID>
    +  <NAGIOS_SERVICESTATE>OK</NAGIOS_SERVICESTATE>
    +  <NAGIOS_SERVICESTATEID>0</NAGIOS_SERVICESTATEID>
    +  <NAGIOS_SERVICESTATETYPE>HARD</NAGIOS_SERVICESTATETYPE>
    +  <NAGIOS_SHORTDATETIME>27-12-2007 13:51:23</NAGIOS_SHORTDATETIME>
    +...
    +</NAGIOS>
    + +

    +The various XML fields can be used as variables in the PNP templates. Each field is available as a variable with the same name. +

    + +

    +The value of the field <NAGIOS_SERVICEOUTPUT> is available as the variable $NAGIOS_SERVICEOUTPUT. +

    + +

    +back to contents | custom templates + +

    + +
    + +
    +
    + + + +

    Custom Templates

    +
    + +

    + +As already described under ”What are templates ?” the appearance of graphs depends on the check command used. +

    + +

    +There are situations where this behaviour must be overruled, for example when universal commands have been defined. +

    + +

    +PNP, especially process_perfdata.pl, will search for a config file (<check_command>;.cfg) in the etc/check_commands directory and read its contents (if available). +The following options can be defined in it: +

    + +
    + +

    CUSTOM_TEMPLATE

    +
    + +

    + +Outgoing from the following example of a Nagios command-definition: + +

    +
    +define command {
    +  command_name check_nrpe
    +  command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a "$ARG2$"
    +}
    +
    + +

    +This would lead to a call of the check_nrpe.php template even when the monitored host would use a completely different plugin which is called via NRPE. +

    + +

    +As our example command is called check_nrpe it will be searched for etc/check_commands/check_nrpe.cfg. +

    + +

    +During installation a sample config file with the extension .cfg-sample is copied to etc/check_commands. +

    +
    +# check_command check_nrpe!load!-w 4,4,4 -c 5,5,5
    +# ________0__________|       |       |
    +# ________1__________________|       |
    +# ________2__________________________|
    +#
    +CUSTOM_TEMPLATE = 1
    +
    + +

    +CUSTOM_TEMPLATE = 1 assures that only the contents of $ARG1$ will be used as a template name. As $ARG1$ contains “load” in this example the template name would result in “load.php”. +

    + +

    +CUSTOM_TEMPLATE = 0,1 results in → “check_nrpe_load.php” +

    + +

    +CUSTOM_TEMPLATE = 1,0 results in → “load_check_nrpe.php” +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    DATATYPE

    +
    + +

    + +The option “DATATYPE” controls the datatype which is used during creation of the RRD database. Default is “GAUGE”. For consecutive values the type should be “COUNTER”. Plugin-developers should use the unit “c” for counters but this is not always the case. +

    + +

    +To set all datasources to COUNTER + +

    +
    DATATYPE = COUNTER
    + +

    +Setting datasources to different types + +

    +
    DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER
    + +

    +More datatypes are explained in the RRDTool documentation found at rrdcreate. +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    USE_MIN_ON_CREATE and USE_MAX_ON_CREATE

    +
    + +

    + +In a few situations it might be necessary to limit the values which are valid for RRDTool. +

    + +

    +RRD databases can be created with fixed minimum and maximum values. You will find further details at http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html. +

    + +

    +Account for the maximum value taken from the performance data + +

    +
    USE_MAX_ON_CREATE = 1
    + +

    +Account for the minimum value taken from the performance data + +

    +
    USE_MIN_ON_CREATE = 1
    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    RRD_STORAGE_TYPE

    +
    +
    RRD_STORAGE_TYPE = SINGLE
    + +

    + +The option RRD_STORAGE_TYPE defines the kind of data storage. +

    + +

    +Possible values are MULTIPLE and SINGLE, respectively. +

    + +

    +SINGLE: A RRD database per service +

    + +

    +MULTIPLE: One or more RRD databases per service. Each datasource will be stored in a separate RRD database. +

    + +

    +ATTENTION: The data will not be migrated automatically! +You will find a conversion script here. +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    RRD_HEARTBEAT

    +
    + +

    + +Starting with PNP 0.6.1 +

    +
    RRD_HEARTBEAT = 305
    + +

    +After <RRD_HEARTBEAT> seconds RRDtool expects new data. +

    + +

    +More information at http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    Hints on Template Names

    +
    + +

    + +In most situations, one can easily get desired template names, by using suitable command object definitions. +

    + +

    +Consider the followng example: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load -w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    +Even when using “CUSTOM_TEMPLATE = 1” one would end up in template names like “_usr_lib_nagios_plugins_check_load_-w_4,4,4_-c_5,5,5”, which is highly undesired, especially because of the parameters in it. +

    + +

    +Solution 1: Split parameters into separate $ARGn$ +

    + +

    +A simple solution is to use the following command object definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +(notice the additional “!”) +

    + +

    +This even works, when $ARG2$ is let empty. +

    + +

    +Of course one would still need to set “CUSTOM_TEMPLATE = 1”. +

    + +

    + +Solution 2: Hide the remote executor inside the command object definition +

    + +

    +Another way is to “hide” the remote excutor in the respective command object definitions. +

    + +

    +Instead of defining: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +one would define the following for every command to be remotely executed: + +

    +
    +define command {
    +  command_name check_load_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ /usr/lib/nagios/plugins/check_load $ARG1$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_load_by_ssh!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +Of course one must not set “CUSTOM_TEMPLATE = 1” in this way. +

    + +

    + +Which of above two solutions one follows is largely a matter of taste. +

    + +

    +back to contents | PNP in distributed environments + +

    + +
    + +
    +
    + + + +

    Distributed Systems

    +
    + +

    +If Nagios is implemented as a distributed system you have to decide where PNP should be installed. +

    + +

    +From a technical view this question is not important. PNP can be installed on the slave(s) as well as on the master server. Or only on the master? +

    + +

    +If PNP is running on the master you have to make sure that data passed via send_nsca from the slave server(s) contains performance data. Often another check command is used on the master. +

    + +

    +To help PNP on the master to recognize which check command was used on the slave to collect the information process_perfdata.pl responds to an additional field at the end of the performance data. +

    +
    OK - 127.0.0.1: rta 2.687ms, lost 0% | rta=2.687ms;3000.000;5000.000;0; pl=0%;80;100;; [check_icmp]
    + +

    +If PNP finds a string enclosed in brackets at the end of performance data it will be recognized as check command and will be used as PNP template. +

    + +

    +Nagios documentation related to this topic can be found +here. The command used in the documentation can be adapted easily. +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$'
    +	}
    +
    + +

    +should be changed to +

    +
    +define command{
    +	command_name	submit_check_result
    +	command_line	/usr/local/nagios/libexec/eventhandlers/submit_check_result $HOSTNAME$ '$SERVICEDESC$' $SERVICESTATE$ '$SERVICEOUTPUT$ | $SERVICEPERFDATA$ [$SERVICECHECKCOMMAND$]'
    +	}
    +
    + +
    + +

    check_multi plugin

    +
    + +

    + +The plugin check_multi is one of the first plugins which uses new features of Nagios 3.x. Check_multi can execute multiple Nagios plugins but returns only results like a single service. The output of check_multi comprises of several lines to be able to display the amount of information. +

    + +

    +This results in some difficulties for PNP which has to extract the information of several plugins from the performance data. Together with Matthias Flacke, developer of check_multi, we have found a solution to assign the data to the appropriate plugins. +

    + +

    + +

    + +

    +back to contents | support of rrdcached + +

    + +
    + +
    +
    + + + +

    RRDtool Cache Daemon

    +
    + +

    + +In large installations sooner or later one will recognize that processing the performance data will result in a relatively high I/O load. RRDtool has to do very much disk updates but cannot use the disk cache in an optimal way. +

    + +

    +One improvement is made by collecting and sorting the data. It is more effective to write many updates to an RRD database in one block. The disk cache can be used more effectively that way. +

    + +

    +The current RRDtool ( SVN trunk 1550+ ) contains rrdcached which should improve exactly this situation. +

    + +

    +At this point I'd like to thank Florian octo Forster, Kevin Brintnall and Tobi Oetiker. The development of this daemon has been coordinated exemplary on the rrd-developers mailing list. +

    + +
    + +

    Mode of operation

    +
    + +

    + +The rrdcached is working as a daemon in the background and opens a UNIX or TCP socket to wait for requests of rrdtool. Due to security reasons newer versions of rrdcached cannot use absolute paths for network access anymore so the only possible way are unix sockets. +

    + +
    + +

    rrdcached

    +
    + +

    + +rrdcached recognizes some important options which are passed during startup. +

    + +

    +Option -l defines the socket the daemon will listen for update requests. The default TCP port will be 42217. +

    +
    +-l unix:/path/to/rrdcached.sock
    +-l /path/to/rrdcached.sock
    +-l 127.0.0.1
    +-l 127.0.0.1:8888
    +
    + +

    +Option -P specifies which commands are usable with the RRD data bases + +

    +
    -P FLUSH,PENDING
    + +

    +Option -s allows to change the group ownership of the unix socket +

    +
    -s nagios
    + +

    +Option -m sets the permissions of the unix socket in the usual octal format +

    +
    -m 0660
    + +

    +Option -w specifies the interval (in seconds) the data will be written to disk. +

    +
    -w 1800
    + +

    +Option -z defines a maximum delay which will be used to spread the write cycles over a certain range [0-delay] to avoid parallel write accesses. The value of option -z must not be larger than -w. +

    +
    -z 1800
    + +

    +Option -p defines a PID file +

    +
    -p /var/run/rrdcached.pid
    + +

    +Option -j defines the path to a journaling directory. All requests will be logged there so that they can be processed after a restart in case the daemon crashes. +

    +
    -j /var/cache/rrdcached
    + +

    +These options may result in a call of rrdcached with the following parameters +

    +
     rrdcached -w 1800 -z 1800 -p /tmp/rrdcached.pid -j /tmp  -s nagios -m 0660 -l unix:/tmp/rrdcached.sock
    + +
    + +

    rrdtool

    +
    + +

    + +RRDtool itself will be informed about the daemon using the option --daemon=<socket>. + +

    +
     rrdtool --daemon=unix:/tmp/rrdcached.sock update ...
    + +

    + +Of course this has to correspond with the options of rrdcached! +

    + +
    + +

    Integration into PNP

    +
    + +

    + +Because two components of PNP have to prepared for the use of rrdcached there are changes in two config files. +

    + +

    +1. Adjustment of process_perfdata.cfg for the data collector process_perfdata.pl +

    +
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +RRD_DAEMON_OPTS = unix:/var/run/rrdcached.sock
    +
    + +

    +2. Adjustment of config_local.php (or config.php) for the web interface +

    +
    +#
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +# $conf['RRD_DAEMON_OPTS'] = 'unix:/tmp/rrdcached.sock';
    +$conf['RRD_DAEMON_OPTS'] = 'unix:/var/run/rrdcached.sock';
    +
    + +

    +The sample files contain the relevant options. +

    + +

    +back to contents | migrating RRD files + +

    + +
    + +
    +
    + + + +

    NPCD

    +
    + +

    + +NPCD (Nagios-Perfdata-C-Daemon) was written to provide an asynchronous mode to handle performance data with nagios. +

    + +
    + +

    Introduction

    +
    + +

    + +In large nagios installations, your average check latency may increase to a non-acceptable high value. This means that Nagios should do a check at time x but actually does it y seconds later. +

    + +

    +If you tell the Nagios core that you want to process the performance data after every single check this is doing well for a certain amount of checks but above this limit you will run into latency problems. +

    + +

    +To reduce the number of actions for each check you can use the Bulk Mode which gathers performance data for some time and then lets the Nagios core execute the <host|service>_perfdata_file_processing_command or you can tell Nagios to just move the perfdata_files to a spool directory. +

    + +

    +This move is a very fast action for the Nagios core and the core will be done with the processing of performance data and can continue to do what it should do: execute other checks, sending notifications, and so on. +

    + +
    + +

    How it works

    +
    + +

    + +As mentioned above the Nagios process has finished its work with moving the performance data file to a spool directory but this won't bring the data into the RRD files. +

    + +

    +For this task you can start npcd to have a look at the defined spool directory and start an action for every file which is found. +

    + +

    +After NPCD starts running it will build a list of filenames found in perfdata_spool_dir and starts new threads for every filename and executes the perfdata_file_run_cmd with the optional perfdata_file_run_cmd_arg as an additional argument. +

    + +

    +Since the perfdata files in the spool dir are in the same format as for the 'normal' bulk mode NPCD should execute process_perfdata.pl in Bulk Mode. +

    + +
    + +

    Advantages / Disadvantages

    +
    + +

    + +Pro: +

    +
      +
    • Performance improvements for Nagios
      +
        +
      • because the performance data processing is detached from the Nagios core it has more time for its own work.
        +
      • +
      +
    • +
    • no lost data
      +
        +
      • as long as Nagios writes perfdata files to the spool dir your data won't get lost if NPCD dies or you forgot to start it after a system reboot. NPCD will start with the first file found (they are sorted by the $TIME_T$ macro in chronological order) and update your RRD Files.
        +
      • +
      +
    • +
    + +

    + +Con: +

    +
      +
    • no real time processing of performance data
      +
        +
      • since there is a delay in writing the performance data files by Nagios (service_perfdata_file_processing_interval)
        +
      • +
      • another delay exists within NPCD which waits for up to 10 seconds after each directory scanning
        +
      • +
      +
    • +
    + +
    + +

    NPCD Config

    +
    + +

    + +You have to control NPCD with its own configuration file like the rolled out npcd.cfg-sample file. +

    + +

    +Just rename it to npcd.cfg to start NPCD like this: +

    +
    /usr/local/pnp4nagios/bin/npcd -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +or + +

    +
    /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +to run in Daemon Mode (background). +

    + +

    +Hint: +If you decide to not rename the config file, it might be overwritten by a future update of PNP. +

    + +
    + +

    npcd.cfg-sample

    +
    + +

    + +These are the essential configuration directives for NPCD: +

    +
    # Privilege Options
    +user = nagios
    +group = nagios
    +
    +# Logging Options
    +log_type = syslog
    +log_file = /usr/local/pnp4nagios/var/npcd.log
    +max_logfile_size = 10485760
    +log_level=0
    +
    +# Processing Options
    +perfdata_spool_dir = /usr/local/pnp4nagios/var/spool/
    +perfdata_file_run_cmd = /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +perfdata_file_run_cmd_args = -b
    +
    +# Thread Options
    +npcd_max_threads=5
    +
    +# greedy options
    +use_load_threshold = 0
    +load_threshold = 10.0
    +
    +# Process Options
    +pid_file=/var/run/npcd.pid
    +
    + +
    + +

    The directives

    +
    +
      +
    • Privilege Options
      +
        +
      • user <username>
        +
          +
        • NPCD tries to drop 'root' privileges to switch to this user.
          +
        • +
        • default: nagios
          +
        • +
        +
      • +
      • group <groupname>
        +
          +
        • NPCD tries to drop 'root' privileges to switch to this group.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      +
    • +
    • Logging Options
      +
        +
      • log_type <syslog> or <file>
        +
          +
        • Log type that is uses by NPCD
          +
        • +
        • Default: syslog
          +
        • +
        +
      • +
      • log_file </path/to/filename>
        +
          +
        • if log_type = file this will be the logfile used
          +
        • +
        • Default: /usr/local/pnp4nagios/var/npcd.log
          +
        • +
        +
      • +
      • max_logfile_size <bytes>
        +
          +
        • NPCD will rotate the logfile if the filesize of the current log is above this limit
          +
        • +
        • Default: 10485760 = 10 MByte
          +
        • +
        +
      • +
      • log_level <integer>
        +
          +
        • how much to log, possible values:
          +
            +
          • 0 = No Log - except errors
            +
          • +
          • 1 = small Log - some more output
            +
          • +
          • 2 = more Log (actual ALL log messages)
            +
          • +
          • -1 = DEBUG Mode - ALL Logs and slower processing for debugging purposes
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      +
    • +
    • Processing Options
      +
        +
      • perfdata_spool_dir </path/to/spool/dir/>
        +
          +
        • The directory where the perfdata file should be found
          +
        • +
        • Default: /usr/local/pnp4nagios/var/spool/
          +
        • +
        +
      • +
      • perfdata_file_run_cmd </path/to/bin/filename>
        +
          +
        • This is the script/binary that NPCD will execute
          +
        • +
        • Default: /usr/local/pnp4nagios/libexec/process_perfdata.pl
          +
        • +
        +
      • +
      • perfdata_file_run_cmd_args <option>
        +
          +
        • The argument added to the perfdata_file_run_cmd
          +
        • +
        • Default: ”-b”
          +
        • +
        • :!: The command line will be created like this:
          <perfdata_file_run_cmd> <perfdata_file_run_cmd_args> <filename_from_perfdata_spool_dir>
          +
          +
        • +
        +
      • +
      +
    • +
    • Thread Options
      +
        +
      • npcd_max_threads <integer value>
        +
          +
        • Defines how many parallel threads should be started
          +
        • +
        • Default: 5
          +
        • +
        +
      • +
      +
    • +
    • Greedy Options
      +
        +
      • use_load_threshold <0 or 1>
        +
          +
        • defines if NPCD should _not_ start new threads if your system load is too high
          +
            +
          • 0 = disable
            +
          • +
          • 1 = enable
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      • load_threshold <float value>
        +
          +
        • if use_load_threshold is set to 1 this load limit must not be exceeded
          +
        • +
        • Default: 10.0
          +
        • +
        +
      • +
      +
    • +
    • Process Options
      +
        +
      • pid_file </path/to/pid.file>
        +
          +
        • the path to the PID File
          +
        • +
        • Default: /var/run/npcd.pid
          +
        • +
        +
      • +
      +
    • +
    + +

    + +back to contents | wrapper script + +

    + +
    + +
    +
    + +

    +check_procs is an example for a plugin which doesn't deliver performance data: +

    +
    ./check_procs -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'
    + +

    +This can be changed with the following wrapper script +

    + +

    +check_procs.sh + +

    +
    #!/bin/bash
    +LINE=`/usr/local/nagios/libexec/check_procs $*`
    +RC=$?
    +COUNT=`echo $LINE | awk '{print $3}'`
    +PROCS=`expr $COUNT - 1`
    +LINE=`echo $LINE | sed "s/: $COUNT /: $PROCS /"`
    +echo $LINE \| procs=$PROCS
    +exit $RC
    + +

    +Now you'll get the number together with the required label + +

    +
    ./check_procs.sh -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'| procs=2
    + +
    +
    + +

    +2.6. Performance data +

    + +

    +Performance data is defined by Nagios as “everything after the | of the plugin output” - please refer to Nagios documentation for information on capturing this data to logfiles. However, it is the responsibility of the plugin writer to ensure the performance data is in a “Nagios plugins” format. This is the expected format: +

    + +

    +'label'=value[UOM];[warn];[crit];[min];[max] +

    + +

    +Notes: + +

    +
      +
    1. space separated list of label/value pairs
      +
    2. +
    3. label can contain any characters
      +
    4. +
    5. the single quotes for the label are optional. Required if spaces, = or ' are in the label
      +
    6. +
    7. label length is arbitrary, but ideally the first 19 characters are unique (due to a limitation in RRD). Be aware of a limitation in the amount of data that NRPE returns to Nagios
      +
    8. +
    9. to specify a quote character, use two single quotes
      +
    10. +
    11. warn, crit, min/ or max/ may be null (for example, if the threshold is not defined or min and max do not apply). Trailing unfilled semicolons can be dropped
      +
    12. +
    13. min and max are not required if UOM=%
      +
    14. +
    15. value, min and max in class [-0-9.]. Must all be the same UOM
      +
    16. +
    17. warn and crit are in the range format (see Section 2.5). Must be the same UOM
      +
    18. +
    19. UOM (unit of measurement) is one of:
      +
        +
      • no unit specified - assume a number (int or float) of things (eg, users, processes, load averages)
        +
      • +
      • s - seconds (also us, ms)
        +
      • +
      • % - percentage
        +
      • +
      • B - bytes (also KB, MB, TB, GB?)
        +
      • +
      • c - a continous counter (such as bytes transmitted on an interface)
        +
      • +
      +
    20. +
    + +

    + +It is up to third party programs to convert the Nagios plugins performance data into graphs. +

    + +

    +Origin: http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN201 + +

    + +
    diff --git a/share/pnp/documents/en_US/dwnld.html b/share/pnp/documents/en_US/dwnld.html new file mode 100644 index 0000000..b4aba76 --- /dev/null +++ b/share/pnp/documents/en_US/dwnld.html @@ -0,0 +1,478 @@ + + + +

    PNP 0.6.x Downloads

    +
    + +
    + +

    Current stable PNP Version

    +
    + +

    + +Changes can be tracked on pnp4nagios.git.sourceforge.net +

    + +

    +The current Version is pnp4nagios-0.6.22.tar.gz +

    + +
    + +

    Latest Devel Version

    +
    + +

    + + pnp4nagios-head.tar.gz +

    + +

    +This is allways the latest GIT HEAD Version +

    +
    + +

    + +Last Update: Wed Jul 30 12:30:45 CEST 2014 +

    + +
    + +

    ChangeLog

    +
    + +

    + +pnp-0.6.?? ??/??/2013 +

    + +

    +pnp-0.6.24 07/30/2013 +

    +
      +
    • Bugfix: Fixed some more XSS issues
      +
    • +
    • Bugfix: Fixed PHP issue while running on PHP 5.6 ( Reported by Sven Nierlein )
      +
    • +
    + +

    + +pnp-0.6.22 06/04/2014 +

    +
      +
    • Bugfix: Fixed livestatus socket parsing ( Pekka Panula )
      +
    • +
    • Bugfix: Update check_mssql_health.php ( Miriam Zenk )
      +
    • +
    • Feature: Add “version=tiny” to got get a stripped down version of graph ( Ricardo Bartels )
      +
    • +
    • feature: Add STDIN Mode to process_perfdata.pl ( Robert Steininger )
      +
    • +
    • Bugfix: XSS issue fixed by Mikael Falkvidd. This issue was detected by Peter Österberg at Hexbit AB in a security assessment of op5 Monitor 6.3 on assignment by op5 AB.
      +
    • +
    + +

    + +pnp-0.6.21 03/24/2013 +

    +
      +
    • Feature: Helper functions rrd::alerter and rrd:alerter_gr both supports treshold detection (Martin Schirrmacher)
      +
    • +
    • Update: jQuery Mobile update to 1.3.0 ( was broken in 0.6.20 )
      +
    • +
    + +

    + +pnp-0.6.20 03/03/2013 +

    +
      +
    • Feature: Support check_mk Multisite Cookie Auth ( Lars Michelsen )
      +
    • +
    • Feature: Allow RRD unknown values ( Simon Meggle )
      +
    • +
    • feature: Interactive delete mode added to check_rrds.pl ( Simon Meggle )
      +
    • +
    • Bugfix: Allow multiple gearman servers ( Craig Barraclough )
      +
    • +
    • Bugfix: Fixed Graph Search ( Stefan Triep )
      +
    • +
    • Update: jQuery update to 1.8.1
      +
    • +
    • Update: jQueryUI update to 1.8.23
      +
    • +
    + +

    + +pnp-0.6.19 09/01/2012 +

    +
      +
    • Feature: Parameter “width” added to popup controller ( Andreas Doehler )
      +
    • +
    • Fix: simplify/improve apache rules ( Christoph Anton Mitterer )
      +
    • +
    • Fix: Check for missing PHP GD functions
      +
    • +
    • Bugfix: socketDOMAIN changed to AF_INET while using livstatus tcp socket ( Rene Koch )
      +
    • +
    + +

    + +pnp-0.6.18 06/28/2012 +

    +
      +
    • Bugfix: Fixed STORAGE_TYPE and CUSTOM_TEMPLATE vars used in custom templates
      +
    • +
    • Bugfix: Blank screen on PHP 5.4 fixed
      +
    • +
    • Feature: Allow multiple gearman job servers
      +
    • +
    • Feature: New helper function rrd::debug()
      +
    • +
    • Feature: New templates check_jmx4perl_*.php
      +
    • +
    + +

    + +pnp-0.6.17 03/25/2012 +

    +
      +
    • Bugfix: Fixed rrd_convert.pl while running with --dry-run
      +
    • +
    • Bugfix: logging.c include missing header files ( Lars Vogdt )
      +
    • +
    • Bugfix: Check if pnp4nagios/etc/rra.cfg is readable
      +
    • +
    • Bugfix: rrd_convert.pl use XML tag TEMPLATE instead of CHECKCOMMAND to selects RRDs ( Sven Velt )
      +
    • +
    • Feature: npcdmod.o increase perfdata buffer and log discarded perfdata ( Birger Schmidt )
      +
    • +
    • Feature: rrd_modify.pl to change number of data sources of an RRD file
      +
    • +
    • Feature: New template check_apachestatus_auto.php
      +
    • +
    • Feature: Implement etc/config.d to place config snippets ( Lars Michelsen )
      +
    • +
    + +

    + +pnp-0.6.16 11/21/2011 +

    +
      +
    • Bugfix: Fixed single quoted check_multi labels (Reported by Matthias Flacke)
      +
    • +
    • Bugfix: Append missing slash to perfdata_spool_dir ( Reported by Juergen-Michael Radtke )
      +
    • +
    • Bugfix: Fixed jQuery-ui multisite theme
      +
    • +
    • Feature: PDF margins are now adjustable via config.php ( Thomas Witzenrath )
      +
    • +
    • Feature: Support for PDF size 'letter' added ( Robert Becht )
      +
    • +
    + +

    + +pnp-0.6.15 09/15/2011 +

    +
      +
    • Bugfix: Fixed Overview link (reported by Stefan Triep)
      +
    • +
    • Bugfix: Fixed zoom popup (reported by Rudolf Labuschagne)
      +
    • +
    • Bugfix: Fixed double urlencode() (reported by Mathias Kettner)
      +
    • +
    • Feature: “Clear basket” button added (suggested by Stefan Triep)
      +
    • +
    • Feature: New helper function “rrd::alerter_gr()” ( committed by Stefan Trip )
      +
    • +
    + +

    + +pnp-0.6.14 08/05/2011 +

    +
      +
    • Feature: Webinterface for mobile devices based on jQuery Mobile
      +( http://jquerymobile.com/ )
      +
    • +
    • Feature: Zoom based on jQuery plugin imgAreaSelect
      +( http://odyniec.net/projects/imgareaselect/ )
      +
    • +
    • Feature: New template check_mssql_health.php
      +
    • +
    • Bugfix: Fixed popups to work under nginx ( Joram Agten )
      +
    • +
    • Bugfix: Helper rrd::vdef() fixed
      +
    • +
    • Update: jQuery update to 1.6.2
      +
    • +
    • Update: jQuery-ui update to 1.8.14
      +
    • +
    + +

    + +pnp-0.6.13 05/19/2011 +

    +
      +
    • Feature: New option --ignore-hosts added to check_pnp_rrds.pl ( by Jochen Bern )
      +
    • +
    • Feature: New options zgraph_width and zgraph_height in config.php ( Mike Liebsch )
      +
    • +
    • Bugfix: rrd_convert.pl: parse_xml_filename() regex fix
      +
    • +
    • Info: Version used by OMD-0.48 OMD
      +
    • +
    + +

    + +pnp-0.6.12 04/22/2011 +

    +
      +
    • Feature: mod_gearman support added
      +
    • +
    • Feature: rrd_convert.pl is now able to convert all RRDs from RRD_STORAGE_TYPE=SINGLE to RRD_STORAGE_TYPE=MULTIPLE
      +
    • +
    • Feature: New template check_gearman.php
      +
    • +
    • Feature: Install process_perfdata.cfg and npcd.cfg by default
      +
    • +
    • Bugfix: rrd_convert.pl is now able to parse xml dumps created by rrdtool 1.4.x
      +
    • +
    • Bugfix: process_perfdata.pl default timeout value set to 15 seconds
      +
    • +
    + +

    + +pnp-0.6.11 01/15/2011 +

    +
      +
    • Bugfix: urldecoding fixed
      +
    • +
    • Bugfix: Zoom in/out is working again ( Reported by Thorben Soehl )
      +
    • +
    • Featue: npcd.cfg - New option perfdata_file_processing_interval used by npcdmod
      +
    • +
    • Info: Version used by OMD-0.46 OMD
      +
    • +
    + +

    + +pnp-0.6.10 12/15/2010 + +

    +
      +
    • Feature: Add RRDTool Option --only-graph if graph height is below 32px to create thumbnails
      +
    • +
    • Feature: RRDTool Option --width and --height is now allowed in templates
      +
    • +
    • Feature: RRDTool DS Type for UOM of “c” changed from COUNTER to DERIVE
      +
    • +
    • Feature: Pass query string from special controller to image controller ( Matthew Garrett )
      +
    • +
    • Feature: Authorisation against mk_livestatus API added
      +
    • +
    • Feature: Sample nginx webserver config added ( by evax@users.sourceforge.net )
      +
    • +
    • Feature: Kohana backport to support PHP 5.1.6 ( Kudos to Andreas Ericsson )
      +
    • +
    • Bugfix: Sort list of special templates
      +
    • +
    • Bugfix: Urlencode hostname and service description ( Reported by Yannick )
      +
    • +
    • Bugfix: corrected warning/critical thresholds in ticker/alerter functions
      +
    • +
    + +

    + +pnp-0.6.7 09/27/2010 + +

    +
      +
    • Bugfix: Page config parser fix (Beau Gunderson)
      +
    • +
    • Bugfix: Zoom window size fixed (Report by Rudolf Labuschagne)
      +
    • +
    • Bugfix: Fixed undefined offset while using 'ds_name' in templates (Reported by Vladimir Bilik)
      +
    • +
    • Bugfix: Npcdmod respects process_perf_data option used in hosts and services definitions ( Reported by Wolfgang Barth )
      +
    • +
    • Template: New Template check_nagiostats.php used with check_nagiostats written by Jochen Bern
      +
    • +
    + +

    + +pnp-0.6.6 08/07/2010 + +

    +
      +
    • Bugfix: Fixed max amount of graphs per template
      +
    • +
    • Bugfix: Autodetect PNP base URL
      +
    • +
    • Bugfix: Too short npcdmod perfdata_template to take perfdata + overhead, increased +1024byte
      +
    • +
    • Bugfix: Ignore files in var/perfdata and check for empty directories
      +
    • +
    • Bugfix: Reducing memory usage while parsing page config (Laurent Freval)
      +
    • +
    + +

    + +pnp-0.6.5 07/09/2010 + +

    +
      +
    • Feature: Special Templates are back tpl_special
      +
    • +
    • Feature: New rrdtool helper functions makes template design easier tpl_helper
      +
    • +
    • Feature: config.php → 'recursive_template_search' is enabled by default
      +
    • +
    • Feature: config.php → 'template_dirs' is now an array of directorys to search for PNP templates
      +
    • +
    + +

    + +pnp-0.6.4 06/03/2010 + +

    +
      +
    • Update: jQuery Update to 1.4.2
      +
    • +
    • Update: jQuery-ui Update to 1.8
      +
    • +
    • Feature: New configure Option --with-base-url
      +
    • +
    • Template: New template check_ntp_time.php (Mathias Kettner)
      +
    • +
    • Feature: New i18n files for fr_FR (Yannig Parre)
      +
    • +
    • Feature: New jQuery Theme 'multisite'
      +
    • +
    + +

    + +pnp-0.6.3 03/16/2010 + +

    +
      +
    • Feature: New helper script libexec/rrd_convert.pl → rrd_convert
      +
    • +
    • Bugfix: Ignore old XML files while building the service list
      +
    • +
    • Template: New template check_hpasm.php
      +
    • +
    • Bugfix: Installer now checks for json_decode()
      +
    • +
    • Workaround: Allow “trailing unfilled semicolons”. Workaround for nsclient++
      +
    • +
    • Template: Updates for check_openmanage.php, check_hp_bladecenter.php and check_dell_baldecenter.php ( Trond Hasle Amundsen )”
      +
    • +
    + +

    + +pnp-0.6.2 12/23/2009 + +

    +
      +
    • Feature: XML_WRITE_DELAY option added to process_perfdata.cfg as suggested by Mathias Kettner
      +
    • +
    • Feature: New template integer.php
      +
    • +
    • Update: FPDI update to 1.3.1
      +
    • +
    • Feature: PNP will now work with lighttpd and php-cgi
      +
    • +
    • Template: check_mk-ps.perf.php added ( by Mathias Kettner )
      +
    • +
    • Feature: PNP will now work without mod_rewrite → webfe
      +
    • +
    • Bugfix: Wrong pdf link used on site 'pages' and 'basket'
      +
    • +
    • Bugfix: Incorrect group permissions on spool directory
      +
    • +
    + +

    + +pnp-0.6.1 11/22/2009 + +

    +
      +
    • Feature: RRD heartbeat per check_command → tpl_custom
      +
    • +
    • Feature: New config.php option pdf_graph_opt
      +
    • +
    • Feature: Recognize the 'background_pdf' option in page definitions → pages
      +
    • +
    • Feature: Recognize the 'source' option in page definitions → pages
      +
    • +
    • Feature: Array $TIMERANGE now available for templates → timeranges
      +
    • +
    • Bugfix: ./configure --sysconfdir no longer ignored
      +
    • +
    • Feature: Store internal runtime statistics on a per minute base
      +
    • +
    • Feature: Added two widgets views/widget_menu.php and views/widget_graph.php
      +
    • +
    + +

    + +pnp-0.6.0 10/30/2009 + +

    +
      +
    • Webfrontend based on Kohana
      +
    • +
    • Webfrontend based on jQuery Themes
      +
    • +
    • Javascript-functions using jQuery plugins
      +
    • +
    • process_perfdata.pl will be able to use one RRD database per datasource
      +
    • +
    • improved installer. Specification of directory layouts using --with-layout
      +
    • +
    • RRDtool errors are now displayed as images. no more missing images
      +
    • +
    • PNP templates cannot overwrite internal variables anymore
      +
    • +
    • PNP templates of version 0.4.x can still be used
      +
    • +
    • PDF functions recoded
      +
    • +
    • Template default.php optimized
      +
    • +
    • Export from RRD databases into XML, CSV and JSON format using the RRDtool “xport” function
      +
    • +
    • Page functions recoded
      +
    • +
    • Error pages links to online FAQ
      +
    • +
    • Mouseover Popup in Nagios frontend via jQuery.clueTip plugin
      +
    • +
    • Full support of rrdcached
      +
    • +
    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/install.html b/share/pnp/documents/en_US/install.html new file mode 100644 index 0000000..48b8332 --- /dev/null +++ b/share/pnp/documents/en_US/install.html @@ -0,0 +1,213 @@ + + + +

    Installation

    +
    + +

    +The installation of PNP will be described in more detail. It is expected that nagios was compiled from source and is located in /usr/local/nagios.
    + +Attention: The description applies to the developer version PNP 0.6.0.
    + +Please note that PNP has to be configured after the installation. +

    + +
    + +

    Make and more

    +
    + +

    +The installation of PNP is controlled by makefiles. The system is analyzed after invocation of ./configure and the detected values are tranferred to makefiles. +

    + +

    +Please unpack PNP as user root: + +

    +
    +tar -xvzf pnp4nagios-HEAD.tar.gz
    +cd pnp4nagios
    +
    + +

    +./configure is to be called from the directory pnp4nagios. +

    +
    +./configure
    +
    + +

    + +Note: Without specifying any options user and group will be “nagios”. If you have different values then please use the parameters ”--with-nagios-user” and ”--with-nagios-group”, respectively. Using Icinga the call might be + +

    +
    +./configure --with-nagios-user=icinga --with-nagios-group=icinga
    +
    + +

    + +Some lines run across the screen. The output at the end is important. +

    +
    +*** Configuration summary for pnp4nagios-0.6.2 23-12-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.2.12
    +  RRDs Perl Modules:                FOUND (Version 1.2012)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    +
    +  Review the options above for accuracy.  If they look okay,
    +  type 'make all' to compile.
    + +

    +The paths shown should be checked. If the displayed values aren't correct you can change them calling ./configure with appropriate options.
    + +Attention: “Location of rrdtool binary” means path including name of binary! If necessary it can be specified using the following syntax: + +

    +
     ./configure --with-rrdtool=/usr/local/rrdtool-1.2.xx/bin/rrdtool
    +
     ./configure --help 
    + +

    + +shows the supported options.
    +
    + +

    + +

    +Invoking +

    +
     make all
    + +

    + +compiles the components like NPCD which are written in C + +

    +
     make install
    + +

    + +copies everything to the right places in the file system. The paths were already shows during ./configure. +

    + +

    +After the installation of the program and HTML files you can copy a sample Apache configuration file to your web-server config directory + +

    +
     make install-webconf
    + +

    + +You can call + +

    +
     make install-config
    + +

    + +optionally. This way config files for process_perfdata.pl and npcd are copied to etc/pnp. +

    + +

    +To install the NPCD Init script call + +

    +
     make install-init
    + +

    + +All these steps are combined in + +

    +
     make fullinstall
    + +

    + +Note: As already stated the Nagios settings will be used per default. If you are using Icinga the file '/etc/apache2/conf.d/pnp4nagios.conf' has to be edited to change the path to AuthUserFile (the path may differ between distributions): + +

    +
    #       AuthUserFile /usr/local/nagios/etc/htpasswd.users
    +        AuthUserFile /usr/local/icinga/etc/htpasswd.users
    + +

    +Attention: After copying the configuration file for the web server you have to restart the web server (service httpd restart or /etc/init.d/apache2 restart, respectively). +

    + +
    + +

    Update

    +
    + +

    + +The update of a 0.6.x version works (nearly) the same way as an installation. Please note that you have to call ./configure with the same options you used during the first installation. +Please check if you changed anything in the folder share/templates.dist. Own templates should be placed in share/templates to avoid being overwritten.
    + +Attention: If you changed config.php then you should save this file before it is overwritten when you execute make install-config. +

    + +

    +You can skip make install-webconf and make install-init because nothing changed between 0.6.x versions. +

    + +
    + +

    The components

    +
    + +

    + +After installation the components of PNP were copied to the appropriate places in the file system. These are +

    + +

    +the PHP-Files for the web-frontend below + +

    +
     /usr/local/pnp4nagios/share
    + +

    + +the data collector process_perfdata.pl in + +

    +
     /usr/local/pnp4nagios/libexec
    + +

    + +sample config files with the suffix -sample in + +

    +
     /usr/local/pnpnagios/etc
    + +

    + +the config file config.php for the web frontend in + +

    +
     /usr/local/pnp4nagios/etc
    + +

    + +back to contents | configuration + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/mobile.html b/share/pnp/documents/en_US/mobile.html new file mode 100644 index 0000000..ca29775 --- /dev/null +++ b/share/pnp/documents/en_US/mobile.html @@ -0,0 +1,89 @@ + + + +

    Mobile UI

    +
    + +

    + +Starting with PNP4Nagios 0.6.14 a web interface for mobile devices is integrated into PNP4Nagios. +

    + +

    +The design was realised using jQuery Mobile and hence is compatible to current mobile browsers. The list of the supported devices shows a graded browser support chart. +

    + +
    + +

    Landing Page

    +
    + +

    + +The web interface was designed to intercept the calls to the classical interface and to redirect them to the appropriate mobile page. This way links to PNP graphs inside Nagios mails don't have to be changed and point to the correct page depending on the device type.. + +

    + + + + + + + + + + + + + +
    Classic Mobile
    /pnp4nagios/graph /pnp4nagios/mobile
    /pnp4nagios/graph?host=localhost /pnp4nagios/mobile/host/localhost
    /pnp4nagios/graph?host=localhost&srv=ping /pnp4nagios/mobile/graph/localhost/ping
    + +
    + +

    Browser recognition

    +
    + +

    + +Browsers are recognised as mobile browsers by analysing the “user agent” string. +The recognition can be influenced by changing pnp4nagios/etc/config_local.php. +

    +
    +$conf['mobile_devices'] = 'iPhone|iPod|iPad|android';
    +
    + +

    +The option 'mobile_devices' contains a regular expression which is compared with the “user agent” string of the browser. +

    + +

    +The “user agent” string of a browser is logged in the web server access log. An entry for an iOS device looks similar to the following. +

    +
    +"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"
    +
    + +
    + +

    Screenshots

    +
    + +

    + +Screenshot taken with an iPhone and iOS 4.2 + +

    + + + + + + + + + + +
     Home Screen Homescreen  Loading... Loading …
     Hosts Liste List of all hosts  Liste aller services List of all services of a host
     Graphen Graph of a service
    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/modes.html b/share/pnp/documents/en_US/modes.html new file mode 100644 index 0000000..dd80475 --- /dev/null +++ b/share/pnp/documents/en_US/modes.html @@ -0,0 +1,145 @@ + + + +

    The art of collecting data

    +
    + +

    + +PNP supports several modes to process performance data. The modes differ in complexity and the performance to be expected. +

    + +

    +The following image shows the connections between Nagios, PNP and RRDtool
    + +

    + +

    +Nagios invokes a command for every host and every service whose performance data should be processed. Depending on the mode you choose the data will be passed to process_perfdata.pl or will be written to temporary files and processed at a later time. process_perfdata.pl writes the data to XML files and stores them in RRD files using RRDtool.
    + +

    + +

    +Before you choose a mode please read the documentation and decide which way will be the best for installation. +

    + +
    + +

    The modes in comparison

    +
    + +
    + +

    Synchronous Mode

    +
    + +

    + +The “synchronous mode” is the simplest and easiest to set up. Nagios will call the perl script process_perfdata.pl for every service and host, respectively, to process the data. The synchronous mode will work very good up to about 1.000 services in a 5 minute interval. +

    + +
    + +

    Bulk Mode

    +
    + +

    + +In bulk mode Nagios writes the necessary data to a temporary file. After expiration of a defined time the file will be processed in one piece and deleted afterwards. +

    + +

    +The number of calls of process_perfdata.pl will be reduced to a fraction. Depending on time and the amount of collected data there will be much less system calls. Instead, process_perfdata.pl will run longer. +

    + +

    +Note +Using this mode you should keep an eye on the runtime of process_perfdata.pl. While it is running to process data nagios will not execute any checks. +

    + +

    +snippet of var/perfdata.log: + +

    +
    +2007-10-18 12:05:01 [21138] 71 Lines processed
    +2007-10-18 12:05:01 [21138] .../spool/service-perfdata-1192701894-PID-21138 deleted
    +2007-10-18 12:05:01 [21138] PNP exiting (runtime 0.060969s) ...
    +
    + +

    +71 lines were processed in 0.06 seconds. This will be the data volume of about 2000 services und processing using a 10 second interval. It means we blocked nagios for exactly 0.06 seconds. +

    + +
    + +

    Bulk Mode with NPCD

    +
    + +

    + +Viewing from Nagios this is the best way of processing because Nagios will not be blocked. +

    + +

    +Nagios again uses a temporary file to store the data and executes a command after expiration of a certain time. Instead of immediate processing by process_perfdata.pl the file is moved to a spool directory. As moving a file inside the same filesystem nearly takes no time nagios is able to execute crucial work immediately. +

    + +

    +The NPCD daemon (Nagios Performance C Daemon) will monitor the directory for new files and will pass the names to process_perfdata.pl. Processing of performance data is decoupled completely from nagios. NPCD itself is able to start multiple thread for processing the data. +

    + +
    + +

    Bulk Mode with npcdmod

    +
    + +

    + +Attention +Starting with Nagios 4 the internal structures have changed so the start of the module will fail. So far there are no plans to support Nagios 4. Please select any other of the modes. +

    + +

    + This scenario includes npcdmod.o, an NEB-module. +This module reduces the configuration of the “Bulk Mode with NPCD” to a mere two lines in nagios.cfg +

    + +

    +This mode is similar to “Bulk Mode with NPCD” and it is exactly the same functionality and the same performance. +

    + +
    + +

    Gearman Mode

    +
    + +

    + + +

    + +

    +Since version 0.6.12 PNP4Nagios can be driven as a gearman worker. This way large Nagios environments are possible using mod_gearman. Nagios and PNP4Nagios can be run on different machines. +

    + +

    +You need a mod_gearman environment up and running like described by Sven Nierlein on http://labs.consol.de/lang/en/nagios/mod-gearman/. +

    + +
    + +

    The decision

    +
    + +

    +Which mode you choose will depend on the size of your Nagios installation. You will find theses terms throughout the documentation. +

    + +

    +back to contents | installation + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/new-features.html b/share/pnp/documents/en_US/new-features.html new file mode 100644 index 0000000..915a6bd --- /dev/null +++ b/share/pnp/documents/en_US/new-features.html @@ -0,0 +1,61 @@ + + + +

    New in PNP 0.6.x

    +
    + +

    +PNP 0.6.x Preview +

    + +

    +The work on the new version 0.6.x is in full progress. +

    + +

    +Starting with version 0.6.x we switch from subversion to GIT. The sourcecode is already available on sourceforge. +

    + +

    + +Functions implemented already +

    +
      +
    • Webfrontend based on Kohana
      +
    • +
    • Webfrontend based on jQuery Themes
      +
    • +
    • Javascript-functions using jQuery plugins
      +
    • +
    • process_perfdata.pl will be able to use one RRD database per datasource
      +
    • +
    • improved installer. Specification of directory layouts using --with-layout
      +
    • +
    • RRDtool errors are now displayed as images. no more missing images
      +
    • +
    • PNP templates cannot overwrite internal variables anymore
      +
    • +
    • PNP templates of version 0.4.x can still be used
      +
    • +
    • PDF functions recoded
      +
    • +
    • Template default.php optimized
      +
    • +
    • Export from RRD databases into XML, CSV and JSON format using the RRDtool “xport” function
      +
    • +
    • Page functions recoded
      +
    • +
    • Error pages links to online FAQ
      +
    • +
    • Mouseover Popup in Nagios frontend via jQuery.clueTip plugin
      +
    • +
    • Full support of rrdcached
      +
    • +
    + +

    +back to contents | system requirements + +

    + +
    diff --git a/share/pnp/documents/en_US/npcd.html b/share/pnp/documents/en_US/npcd.html new file mode 100644 index 0000000..7458788 --- /dev/null +++ b/share/pnp/documents/en_US/npcd.html @@ -0,0 +1,323 @@ + + + +

    NPCD

    +
    + +

    + +NPCD (Nagios-Perfdata-C-Daemon) was written to provide an asynchronous mode to handle performance data with nagios. +

    + +
    + +

    Introduction

    +
    + +

    + +In large nagios installations, your average check latency may increase to a non-acceptable high value. This means that Nagios should do a check at time x but actually does it y seconds later. +

    + +

    +If you tell the Nagios core that you want to process the performance data after every single check this is doing well for a certain amount of checks but above this limit you will run into latency problems. +

    + +

    +To reduce the number of actions for each check you can use the Bulk Mode which gathers performance data for some time and then lets the Nagios core execute the <host|service>_perfdata_file_processing_command or you can tell Nagios to just move the perfdata_files to a spool directory. +

    + +

    +This move is a very fast action for the Nagios core and the core will be done with the processing of performance data and can continue to do what it should do: execute other checks, sending notifications, and so on. +

    + +
    + +

    How it works

    +
    + +

    + +As mentioned above the Nagios process has finished its work with moving the performance data file to a spool directory but this won't bring the data into the RRD files. +

    + +

    +For this task you can start npcd to have a look at the defined spool directory and start an action for every file which is found. +

    + +

    +After NPCD starts running it will build a list of filenames found in perfdata_spool_dir and starts new threads for every filename and executes the perfdata_file_run_cmd with the optional perfdata_file_run_cmd_arg as an additional argument. +

    + +

    +Since the perfdata files in the spool dir are in the same format as for the 'normal' bulk mode NPCD should execute process_perfdata.pl in Bulk Mode. +

    + +
    + +

    Advantages / Disadvantages

    +
    + +

    + +Pro: +

    +
      +
    • Performance improvements for Nagios
      +
        +
      • because the performance data processing is detached from the Nagios core it has more time for its own work.
        +
      • +
      +
    • +
    • no lost data
      +
        +
      • as long as Nagios writes perfdata files to the spool dir your data won't get lost if NPCD dies or you forgot to start it after a system reboot. NPCD will start with the first file found (they are sorted by the $TIME_T$ macro in chronological order) and update your RRD Files.
        +
      • +
      +
    • +
    + +

    + +Con: +

    +
      +
    • no real time processing of performance data
      +
        +
      • since there is a delay in writing the performance data files by Nagios (service_perfdata_file_processing_interval)
        +
      • +
      • another delay exists within NPCD which waits for up to 10 seconds after each directory scanning
        +
      • +
      +
    • +
    + +
    + +

    NPCD Config

    +
    + +

    + +You have to control NPCD with its own configuration file like the rolled out npcd.cfg-sample file. +

    + +

    +Just rename it to npcd.cfg to start NPCD like this: +

    +
    /usr/local/pnp4nagios/bin/npcd -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +or + +

    +
    /usr/local/pnp4nagios/bin/npcd -d -f /usr/local/pnp4nagios/etc/npcd.cfg
    + +

    + +to run in Daemon Mode (background). +

    + +

    +Hint: +If you decide to not rename the config file, it might be overwritten by a future update of PNP. +

    + +
    + +

    npcd.cfg-sample

    +
    + +

    + +These are the essential configuration directives for NPCD: +

    +
    # Privilege Options
    +user = nagios
    +group = nagios
    +
    +# Logging Options
    +log_type = syslog
    +log_file = /usr/local/pnp4nagios/var/npcd.log
    +max_logfile_size = 10485760
    +log_level=0
    +
    +# Processing Options
    +perfdata_spool_dir = /usr/local/pnp4nagios/var/spool/
    +perfdata_file_run_cmd = /usr/local/pnp4nagios/libexec/process_perfdata.pl
    +perfdata_file_run_cmd_args = -b
    +
    +# Thread Options
    +npcd_max_threads=5
    +
    +# greedy options
    +use_load_threshold = 0
    +load_threshold = 10.0
    +
    +# Process Options
    +pid_file=/var/run/npcd.pid
    +
    + +
    + +

    The directives

    +
    +
      +
    • Privilege Options
      +
        +
      • user <username>
        +
          +
        • NPCD tries to drop 'root' privileges to switch to this user.
          +
        • +
        • default: nagios
          +
        • +
        +
      • +
      • group <groupname>
        +
          +
        • NPCD tries to drop 'root' privileges to switch to this group.
          +
        • +
        • Default: nagios
          +
        • +
        +
      • +
      +
    • +
    • Logging Options
      +
        +
      • log_type <syslog> or <file>
        +
          +
        • Log type that is uses by NPCD
          +
        • +
        • Default: syslog
          +
        • +
        +
      • +
      • log_file </path/to/filename>
        +
          +
        • if log_type = file this will be the logfile used
          +
        • +
        • Default: /usr/local/pnp4nagios/var/npcd.log
          +
        • +
        +
      • +
      • max_logfile_size <bytes>
        +
          +
        • NPCD will rotate the logfile if the filesize of the current log is above this limit
          +
        • +
        • Default: 10485760 = 10 MByte
          +
        • +
        +
      • +
      • log_level <integer>
        +
          +
        • how much to log, possible values:
          +
            +
          • 0 = No Log - except errors
            +
          • +
          • 1 = small Log - some more output
            +
          • +
          • 2 = more Log (actual ALL log messages)
            +
          • +
          • -1 = DEBUG Mode - ALL Logs and slower processing for debugging purposes
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      +
    • +
    • Processing Options
      +
        +
      • perfdata_spool_dir </path/to/spool/dir/>
        +
          +
        • The directory where the perfdata file should be found
          +
        • +
        • Default: /usr/local/pnp4nagios/var/spool/
          +
        • +
        +
      • +
      • perfdata_file_run_cmd </path/to/bin/filename>
        +
          +
        • This is the script/binary that NPCD will execute
          +
        • +
        • Default: /usr/local/pnp4nagios/libexec/process_perfdata.pl
          +
        • +
        +
      • +
      • perfdata_file_run_cmd_args <option>
        +
          +
        • The argument added to the perfdata_file_run_cmd
          +
        • +
        • Default: ”-b”
          +
        • +
        • :!: The command line will be created like this:
          <perfdata_file_run_cmd> <perfdata_file_run_cmd_args> <filename_from_perfdata_spool_dir>
          +
          +
        • +
        +
      • +
      +
    • +
    • Thread Options
      +
        +
      • npcd_max_threads <integer value>
        +
          +
        • Defines how many parallel threads should be started
          +
        • +
        • Default: 5
          +
        • +
        +
      • +
      +
    • +
    • Greedy Options
      +
        +
      • use_load_threshold <0 or 1>
        +
          +
        • defines if NPCD should _not_ start new threads if your system load is too high
          +
            +
          • 0 = disable
            +
          • +
          • 1 = enable
            +
          • +
          +
        • +
        • Default: 0
          +
        • +
        +
      • +
      • load_threshold <float value>
        +
          +
        • if use_load_threshold is set to 1 this load limit must not be exceeded
          +
        • +
        • Default: 10.0
          +
        • +
        +
      • +
      +
    • +
    • Process Options
      +
        +
      • pid_file </path/to/pid.file>
        +
          +
        • the path to the PID File
          +
        • +
        • Default: /var/run/npcd.pid
          +
        • +
        +
      • +
      +
    • +
    + +

    + +back to contents | wrapper script + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/pages.html b/share/pnp/documents/en_US/pages.html new file mode 100644 index 0000000..17bbc00 --- /dev/null +++ b/share/pnp/documents/en_US/pages.html @@ -0,0 +1,91 @@ + + + +

    Pages

    +
    + +

    + +“pages” provide the opportunity to collect graphs of different hosts/services on one page. That way - as an example - you can display the traffic rates of all tape libraries. Regular expressions are possible so you can accomplish a lot with only few definitions - provided that you have appropriate names. +The directory specified using “$conf['page_dir']” contains one or more file with the extension ”.cfg”. +

    + +

    +Comments start with a hash-sign (#) and are possible within lines as well. Each file contains a “page” definition which specifies the name of the page and it determines whether the following graph definition contains regular expressions or not.
    + +The description behind page_name appears in the list of available pages and will be used as title of the browser window. Attention: “host_name” and “service_desc” refer to the name of the file in the perfdata directory, not to the definition in Nagios. Blanks are replaced by underscores (_). +

    +
    define page {
    +       use_regex 1		# 0 = use no regular expressions, 1 = use regular expressions
    +       page_name test-page	# page description
    +}
    + +

    +One or more “graph” definitions follow: +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    Current_Load
    +}
    + +

    + +Attention: The list of host name will only work if you use regex 0! +

    +
    define graph {
    +       host_name       host4
    +       service_desc    Current_Users
    +}
    + +

    +And now some definitions with regular expressions. At first all hosts whose names are starting with “Tape”: + +

    +
    define graph {
    +       host_name       ^Tape
    +       service_desc    Traffic
    +}
    + +

    +all hosts whose names are ending with “00”: + +

    +
    define graph {
    +       host_name       00$
    +       service_desc    Load
    +}
    + +

    +all services of localhost whose names contain “a” or “o”, respectively: + +

    +
    define graph {
    +       host_name       localhost
    +       service_desc    a|o
    +}
    + +

    +all services whose names contain an underscore followed by (at least) three digits on all hosts whose names start with “UX”: + +

    +
    define graph {
    +       host_name       ^UX
    +       service_desc    _\d{3}
    +}
    + +

    +In some cases you may want to limit the display to just one graph. To accomplish this you can use the optional directive “source” followed by a number specifying the position within the RRD file starting at 0 + +

    +
    define graph {
    +       host_name       host1,host2,host3
    +       service_desc    PING
    +       source          1
    +}
    + +

    +back to contents | data export + +

    + +
    diff --git a/share/pnp/documents/en_US/perfdata_format.html b/share/pnp/documents/en_US/perfdata_format.html new file mode 100644 index 0000000..4dc7025 --- /dev/null +++ b/share/pnp/documents/en_US/perfdata_format.html @@ -0,0 +1,61 @@ + +

    +2.6. Performance data +

    + +

    +Performance data is defined by Nagios as “everything after the | of the plugin output” - please refer to Nagios documentation for information on capturing this data to logfiles. However, it is the responsibility of the plugin writer to ensure the performance data is in a “Nagios plugins” format. This is the expected format: +

    + +

    +'label'=value[UOM];[warn];[crit];[min];[max] +

    + +

    +Notes: + +

    +
      +
    1. space separated list of label/value pairs
      +
    2. +
    3. label can contain any characters
      +
    4. +
    5. the single quotes for the label are optional. Required if spaces, = or ' are in the label
      +
    6. +
    7. label length is arbitrary, but ideally the first 19 characters are unique (due to a limitation in RRD). Be aware of a limitation in the amount of data that NRPE returns to Nagios
      +
    8. +
    9. to specify a quote character, use two single quotes
      +
    10. +
    11. warn, crit, min/ or max/ may be null (for example, if the threshold is not defined or min and max do not apply). Trailing unfilled semicolons can be dropped
      +
    12. +
    13. min and max are not required if UOM=%
      +
    14. +
    15. value, min and max in class [-0-9.]. Must all be the same UOM
      +
    16. +
    17. warn and crit are in the range format (see Section 2.5). Must be the same UOM
      +
    18. +
    19. UOM (unit of measurement) is one of:
      +
        +
      • no unit specified - assume a number (int or float) of things (eg, users, processes, load averages)
        +
      • +
      • s - seconds (also us, ms)
        +
      • +
      • % - percentage
        +
      • +
      • B - bytes (also KB, MB, TB, GB?)
        +
      • +
      • c - a continous counter (such as bytes transmitted on an interface)
        +
      • +
      +
    20. +
    + +

    + +It is up to third party programs to convert the Nagios plugins performance data into graphs. +

    + +

    +Origin: http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN201 + +

    diff --git a/share/pnp/documents/en_US/rrd_convert.html b/share/pnp/documents/en_US/rrd_convert.html new file mode 100644 index 0000000..714ef22 --- /dev/null +++ b/share/pnp/documents/en_US/rrd_convert.html @@ -0,0 +1,88 @@ + + + +

    RRD_STORAGE_TYPE = MULTIPLE

    +
    + +

    + +available starting with PNP 0.6.3 +

    + +

    +Since PNP version 0.6 it is possible to store performance data into multiple RRD databases instead of a single RRD database. +

    + +

    +After creation of an RRD file you cannot alter the number of data sources. This may lead to problems if Nagios plugins change the number of data sources dynamically. +

    + +

    +An example might be check_disk if you monitor all available file systems using one service. If a file system is added the RRD database cannot be updated anymore because the internal would be changed. +

    + +

    +Per default PNP uses the option RRD_STORAGE_TYPE = SINGLE which is defined in process_perfdata.pl and might be changed using the config file process_perfdata.cfg. +This setting should not be changed globally because PNP will start creating new RRD files immediately after changing to MULTIPLE. Old data will get lost! +

    + +

    +Additionally it is not advisable to activate RRD_STORAGE_TYPE = MULTIPLE globally in regard to performance. The number of RRD databases and the disk I/O will increase significantly. That means that you should carefully select which Nagios check commands should be altered. +

    + +

    +The section Custom Templates contains information about how the settings should be altered. +

    + +
    + +

    A converter

    +
    + +

    + +The script libexec/rrd_convert.pl will be used to switch RRD_STORAGE_TYPE to MULTIPLE and to migrate the RRD databases. +

    + +

    +Significant as always with PNP is the Nagios check command. +

    +
    rrd_convert.pl --check_command=<nagios_check_command> | --list_commands [ --dry-run ] [ --tmp_dir=<temp-directory ]
    +[ --no_structure_check ]
    + +

    +You have to specify at least one of ”--check_command” or ”--list_commands”, respectively. +Using the open --check-command= you tell the script which check command should be searched for. +

    + +

    +rrd_convert.pl will now browse all PNP XML files for this command and output some statistics. +

    + +

    +After confirmation from the user the conversion of the appropriate RRD databases will start displaying the progress. Pressing <ENTER> as an answer will terminate the script so please enter a letter. +

    + +

    +If you are unsure then use --list_commands to get a list of the check commands used in the XML files. +

    + +

    +The option --dry-run will convert the RRD databases but they will be stored in /tmp/rrd_convert in separate folders per host instead. This way you'll get a feeling about the runtime and the amount of data. +

    + +

    +If you want to change the temporary directory you can use --tmp_dir=<alternative temp dir>. +

    + +

    +Sometimes the number of datasources in the RRD files doesn't match the number in the XML files. This might happen if a plugin suddenly returns more datasources than usual (like check_disk as mentioned above). Using the option --no_structure_check these RRD files will be converted as well. +

    + +

    +back to contents | NPCD details + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/rrdcached.html b/share/pnp/documents/en_US/rrdcached.html new file mode 100644 index 0000000..0cb66b9 --- /dev/null +++ b/share/pnp/documents/en_US/rrdcached.html @@ -0,0 +1,154 @@ + + + +

    RRDtool Cache Daemon

    +
    + +

    + +In large installations sooner or later one will recognize that processing the performance data will result in a relatively high I/O load. RRDtool has to do very much disk updates but cannot use the disk cache in an optimal way. +

    + +

    +One improvement is made by collecting and sorting the data. It is more effective to write many updates to an RRD database in one block. The disk cache can be used more effectively that way. +

    + +

    +The current RRDtool ( SVN trunk 1550+ ) contains rrdcached which should improve exactly this situation. +

    + +

    +At this point I'd like to thank Florian octo Forster, Kevin Brintnall and Tobi Oetiker. The development of this daemon has been coordinated exemplary on the rrd-developers mailing list. +

    + +
    + +

    Mode of operation

    +
    + +

    + +The rrdcached is working as a daemon in the background and opens a UNIX or TCP socket to wait for requests of rrdtool. Due to security reasons newer versions of rrdcached cannot use absolute paths for network access anymore so the only possible way are unix sockets. +

    + +
    + +

    rrdcached

    +
    + +

    + +rrdcached recognizes some important options which are passed during startup. +

    + +

    +Option -l defines the socket the daemon will listen for update requests. The default TCP port will be 42217. +

    +
    +-l unix:/path/to/rrdcached.sock
    +-l /path/to/rrdcached.sock
    +-l 127.0.0.1
    +-l 127.0.0.1:8888
    +
    + +

    +Option -P specifies which commands are usable with the RRD data bases + +

    +
    -P FLUSH,PENDING
    + +

    +Option -s allows to change the group ownership of the unix socket +

    +
    -s nagios
    + +

    +Option -m sets the permissions of the unix socket in the usual octal format +

    +
    -m 0660
    + +

    +Option -w specifies the interval (in seconds) the data will be written to disk. +

    +
    -w 1800
    + +

    +Option -z defines a maximum delay which will be used to spread the write cycles over a certain range [0-delay] to avoid parallel write accesses. The value of option -z must not be larger than -w. +

    +
    -z 1800
    + +

    +Option -p defines a PID file +

    +
    -p /var/run/rrdcached.pid
    + +

    +Option -j defines the path to a journaling directory. All requests will be logged there so that they can be processed after a restart in case the daemon crashes. +

    +
    -j /var/cache/rrdcached
    + +

    +These options may result in a call of rrdcached with the following parameters +

    +
     rrdcached -w 1800 -z 1800 -p /tmp/rrdcached.pid -j /tmp  -s nagios -m 0660 -l unix:/tmp/rrdcached.sock
    + +
    + +

    rrdtool

    +
    + +

    + +RRDtool itself will be informed about the daemon using the option --daemon=<socket>. + +

    +
     rrdtool --daemon=unix:/tmp/rrdcached.sock update ...
    + +

    + +Of course this has to correspond with the options of rrdcached! +

    + +
    + +

    Integration into PNP

    +
    + +

    + +Because two components of PNP have to prepared for the use of rrdcached there are changes in two config files. +

    + +

    +1. Adjustment of process_perfdata.cfg for the data collector process_perfdata.pl +

    +
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +RRD_DAEMON_OPTS = unix:/var/run/rrdcached.sock
    +
    + +

    +2. Adjustment of config_local.php (or config.php) for the web interface +

    +
    +#
    +# EXPERIMENTAL rrdcached Support
    +# Use only with rrdtool svn revision 1511+
    +#
    +# $conf['RRD_DAEMON_OPTS'] = 'unix:/tmp/rrdcached.sock';
    +$conf['RRD_DAEMON_OPTS'] = 'unix:/var/run/rrdcached.sock';
    +
    + +

    +The sample files contain the relevant options. +

    + +

    +back to contents | migrating RRD files + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/start.html b/share/pnp/documents/en_US/start.html new file mode 100644 index 0000000..5448b40 --- /dev/null +++ b/share/pnp/documents/en_US/start.html @@ -0,0 +1,194 @@ + + + +

    Documentation

    +
    +
    + +
    +
    PNP4Nagios Broker Module npcdmod.o is not compatible with Nagios Core 4.x
    +
    + +
    + +

    +Theme "smoothness" +

    + +

    +PNP is an addon to Nagios which analyzes performance data provided by plugins and stores them automatically into RRD-databases (Round Robin Databases, see RRD Tool). +

    + +

    +During development of PNP we set value on easy installation and little maintenance while running it. An administrator should do other things than configure graphing tools. +

    + +

    +To achieve this task we focused on using standards. PNP only processes performance data built according to the Developer Guidelines for nagios plugins. With this limitation we want to honour the work of Nagios Plugin Developers who stick to the guidelines. +

    + +

    +For all of those who are still curious the following documentation is made which should help to ease the access to PNP. +

    + +

    +complete documentation on "one" page +

    + +
    + +

    Documentation

    +
    + + + + + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/timeranges.html b/share/pnp/documents/en_US/timeranges.html new file mode 100644 index 0000000..8ce035d --- /dev/null +++ b/share/pnp/documents/en_US/timeranges.html @@ -0,0 +1,87 @@ + + + +

    Timeranges

    +
    + +

    + +In the overview PNP shows five timeranges which can be defined in config.php. +

    + +

    +Additionally you can influence the timeranges via the URL. This can be useful to automatically create PDF documents. The ranges can be defined using the options “start” and “end”. +

    + +

    +Example: + +

    +
     pnp4nagios/graph?host=<hostname>&srv=<servicedesc>&start=-1week
    + +

    + +The graph will start one week prior to the current date and time. It will end at the current timestamp. + +

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    start end view result
    all views ending at current timestamp
    x all views starting at defined date
    x all views ending at defined date
    x x one view between the two dates
    x one view ending at current timestamp
    x x one view starting at defined date
    x x one view ending at defined date
    + +

    +Examples of different specifications + +

    + + + + + + + + + + + + + + + + + + + + + + +
    format description
    2009W04 4. week of 2009
    1.5.2009 May, 1st 2009
    -1 day one day back
    -3 weeks 3 weeks back
    -1 year one year back
    yesterday yesterday
    + +

    +back to contents | pages + +

    + +
    diff --git a/share/pnp/documents/en_US/tpl.html b/share/pnp/documents/en_US/tpl.html new file mode 100644 index 0000000..29b45ac --- /dev/null +++ b/share/pnp/documents/en_US/tpl.html @@ -0,0 +1,240 @@ + + + +

    What are templates?

    +
    + +

    + +PNP uses templates to influence the appearance of RRD graphs. +

    + +

    +The selected check_command determines which template will be used to control the graph. Following will be described where templates are stored and how the decision for the “right” template is made. +

    + +
    + +

    What template will be used when?

    +
    + +

    + +Templates are stored at two places in the file system. + +

    +
      +
    • share/templates.dist - for templates included in the PNP package
      +
    • +
    • share/templates - for custom made templates which are not changed during updates
      +
    • +
    + +

    + +If the graph for the service “http” on host “localhost” should be shown, PNP will look for the XML file perfdata/localhost/http.xml and read its contents. The XML files are created automatically and contain information about the particular host and service. The header contains information about the plugin and the performance data. The XML tag <TEMPLATE> identifies which PNP template will be used for this graph. +

    + +

    +/localhost/http.xml + +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>2</DS>
    +    <NAME>size</NAME>
    +    <UNIT>B</UNIT>
    +    <ACT>263</ACT>
    +    <WARN></WARN>
    +    <CRIT></CRIT>
    +    <MIN>0</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +...
    +</NAGIOS>
    + +

    +PNP will append .php to the string and therefore look for a template with the name check_http.php in the following sequence: + +

    +
      +
    1. templates/check_http.php
      +
    2. +
    3. templates.dist/check_http.php
      +
    4. +
    5. templates/default.php
      +
    6. +
    7. templates.dist/default.php
      +
    8. +
    + +

    + +The template default.php takes an exceptional position as it is used every time no other applicable template is found. +

    + +
    + +

    Creating own templates

    +
    + +

    + +PNP templates are PHP files which are included during execution of PNP using the PHP function include(). This means that every PHP code in templates will be interpreted so manipulation of all values is possible. +

    + +

    +PNP template must have the following characteristics: + +

    +
      +
    1. templates must contain valid PHP code.
      +
    2. +
    3. templates must not create any output.
      +
    4. +
    5. the two arrays $opt[] and $def[] have to be filled
      +
    6. +
    + +

    + +These two arrays are used to call 'rrdtool graph' so every option is possible that RRDtool supports. All options of RRDtool are described very thoroughly on the RRDtool Homepage. +

    + +

    +If both arrays contain more than one set of data graphs will be created for every set. +

    + +

    +Inside the templates the data from the related XML files can be used. +

    + +

    +Using the relatively simple template response.php we will describe the most important options. +

    +
    <?php
    +#
    +$opt[1] = "--title \"Response Time For $hostname / $servicedesc\" ";
    +#
    +$def[1] =  "DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE " ;
    +$def[1] .= "AREA:var1#00FF00:\"Response Times \" " ;
    +$def[1] .= "LINE1:var1#000000 " ;
    +$def[1] .= "GPRINT:var1:LAST:\"%3.4lg %s$UNIT[1] LAST \" ";
    +$def[1] .= "GPRINT:var1:MAX:\"%3.4lg %s$UNIT[1] MAX \" ";
    +$def[1] .= "GPRINT:var1:AVERAGE:\"%3.4lg %s$UNIT[1] AVERAGE \" ";
    +?>
    + +

    +Note: as the number (1) and the letter “L” look alike in this listing: the format ”%3.4lg” contains a small letter. +

    + +

    +$opt[1] = ”--title … sets RRDtool options for the first set of data, here the title as you can see. Embedded quotes are masked using a backslash (\). The variables $hostname and $servicedesc were determined through the call of PNP and are available for the template as well. +

    + +

    +$def[1] = “DEF:var1=$RRDFILE[1]:$DS[1]:AVERAGE ”; defines which data is to be read from which RRD file. $RRDFILE[1] contains the path to the RRD file of this service. $DS[1] refers to the first data series from the RRD file. +

    + +

    +$def[1] .= “AREA:var1#00FF00:\”Response Times \” ”; the operator ”.=” appends more data to the array $def[1]. An area will be drawn using data from the variable var1. The color is defined in HEX notation #00FF00 (red, green, blue). The label is “Response Times”. +

    + +

    +$def[1] .= “LINE1:var1#000000 ”; As completion of the just drawn area a line (LINE1) will be drawn in black (#000000). +

    + +

    +$def[1] .= “GPRINT:var1:LAST:\”%3.4lg %s$UNIT[1] LAST \” ”;
    + +$def[1] .= “GPRINT:var1:MAX:\”%3.4lg %s$UNIT[1] MAX \” ”;
    + +$def[1] .= “GPRINT:var1:AVERAGE:\”%3.4lg %s$UNIT[1] AVERAGE \” ”;
    +

    + +

    +The three GPRINT lines build up the caption for the graph. The current values are formatted using the printf syntax. +

    + +
    + +

    Available variables

    +
    + +

    + +Using the data collector process_perfdata.pl PNP stores not only performance data but other values exported by Nagios. These values are stored in the XML file associated to the appropriate service. +

    + +

    +In the first part of the XML file the performance data is stored in separate components. +

    +
    <NAGIOS>
    +  <DATASOURCE>
    +    <TEMPLATE>check_http</TEMPLATE>
    +    <DS>1</DS>
    +    <NAME>time</NAME>
    +    <UNIT>s</UNIT>
    +    <ACT>0.006721</ACT>
    +    <WARN>1.000000</WARN>
    +    <CRIT>2.000000</CRIT>
    +    <MIN>0.000000</MIN>
    +    <MAX></MAX>
    +  </DATASOURCE>
    +....
    +</NAGIOS>
    + +

    +The field <DS> designates the data source and is used to identify the data series of the RRD files and is the key of the following arrays as well. +

    + +

    +The array $UNIT[1] contains the unit of measurement of the first data series. +

    + +

    +The XML file contains other information. When process_perfdata.pl is used in default mode all available macros are at hand with the current values. For the benefit of readability the following lines show only an extract. +

    +
    <NAGIOS>
    +...
    +  <NAGIOS_SERVICENOTIFICATIONID>8418</NAGIOS_SERVICENOTIFICATIONID>
    +  <NAGIOS_SERVICENOTIFICATIONNUMBER>0</NAGIOS_SERVICENOTIFICATIONNUMBER>
    +  <NAGIOS_SERVICEOUTPUT>HTTP OK HTTP/1.1 200 OK - 10087 bytes in 0.125 seconds</NAGIOS_SERVICEOUTPUT>
    +  <NAGIOS_SERVICEPERCENTCHANGE>0.00</NAGIOS_SERVICEPERCENTCHANGE>
    +  <NAGIOS_SERVICEPERFDATA>time=0.124811s;;;0.000000 size=10087B;;;0</NAGIOS_SERVICEPERFDATA>
    +  <NAGIOS_SERVICEPERFDATAFILE></NAGIOS_SERVICEPERFDATAFILE>
    +  <NAGIOS_SERVICEPROBLEMID>0</NAGIOS_SERVICEPROBLEMID>
    +  <NAGIOS_SERVICESTATE>OK</NAGIOS_SERVICESTATE>
    +  <NAGIOS_SERVICESTATEID>0</NAGIOS_SERVICESTATEID>
    +  <NAGIOS_SERVICESTATETYPE>HARD</NAGIOS_SERVICESTATETYPE>
    +  <NAGIOS_SHORTDATETIME>27-12-2007 13:51:23</NAGIOS_SHORTDATETIME>
    +...
    +</NAGIOS>
    + +

    +The various XML fields can be used as variables in the PNP templates. Each field is available as a variable with the same name. +

    + +

    +The value of the field <NAGIOS_SERVICEOUTPUT> is available as the variable $NAGIOS_SERVICEOUTPUT. +

    + +

    +back to contents | custom templates + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/tpl_custom.html b/share/pnp/documents/en_US/tpl_custom.html new file mode 100644 index 0000000..08a1a52 --- /dev/null +++ b/share/pnp/documents/en_US/tpl_custom.html @@ -0,0 +1,323 @@ + + + +

    Custom Templates

    +
    + +

    + +As already described under ”What are templates ?” the appearance of graphs depends on the check command used. +

    + +

    +There are situations where this behaviour must be overruled, for example when universal commands have been defined. +

    + +

    +PNP, especially process_perfdata.pl, will search for a config file (<check_command>;.cfg) in the etc/check_commands directory and read its contents (if available). +The following options can be defined in it: +

    + +
    + +

    CUSTOM_TEMPLATE

    +
    + +

    + +Outgoing from the following example of a Nagios command-definition: + +

    +
    +define command {
    +  command_name check_nrpe
    +  command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -c $ARG1$ -a "$ARG2$"
    +}
    +
    + +

    +This would lead to a call of the check_nrpe.php template even when the monitored host would use a completely different plugin which is called via NRPE. +

    + +

    +As our example command is called check_nrpe it will be searched for etc/check_commands/check_nrpe.cfg. +

    + +

    +During installation a sample config file with the extension .cfg-sample is copied to etc/check_commands. +

    +
    +# check_command check_nrpe!load!-w 4,4,4 -c 5,5,5
    +# ________0__________|       |       |
    +# ________1__________________|       |
    +# ________2__________________________|
    +#
    +CUSTOM_TEMPLATE = 1
    +
    + +

    +CUSTOM_TEMPLATE = 1 assures that only the contents of $ARG1$ will be used as a template name. As $ARG1$ contains “load” in this example the template name would result in “load.php”. +

    + +

    +CUSTOM_TEMPLATE = 0,1 results in → “check_nrpe_load.php” +

    + +

    +CUSTOM_TEMPLATE = 1,0 results in → “load_check_nrpe.php” +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    DATATYPE

    +
    + +

    + +The option “DATATYPE” controls the datatype which is used during creation of the RRD database. Default is “GAUGE”. For consecutive values the type should be “COUNTER”. Plugin-developers should use the unit “c” for counters but this is not always the case. +

    + +

    +To set all datasources to COUNTER + +

    +
    DATATYPE = COUNTER
    + +

    +Setting datasources to different types + +

    +
    DATATYPE = GAUGE,GAUGE,COUNTER,COUNTER
    + +

    +More datatypes are explained in the RRDTool documentation found at rrdcreate. +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    USE_MIN_ON_CREATE and USE_MAX_ON_CREATE

    +
    + +

    + +In a few situations it might be necessary to limit the values which are valid for RRDTool. +

    + +

    +RRD databases can be created with fixed minimum and maximum values. You will find further details at http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html. +

    + +

    +Account for the maximum value taken from the performance data + +

    +
    USE_MAX_ON_CREATE = 1
    + +

    +Account for the minimum value taken from the performance data + +

    +
    USE_MIN_ON_CREATE = 1
    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    RRD_STORAGE_TYPE

    +
    +
    RRD_STORAGE_TYPE = SINGLE
    + +

    + +The option RRD_STORAGE_TYPE defines the kind of data storage. +

    + +

    +Possible values are MULTIPLE and SINGLE, respectively. +

    + +

    +SINGLE: A RRD database per service +

    + +

    +MULTIPLE: One or more RRD databases per service. Each datasource will be stored in a separate RRD database. +

    + +

    +ATTENTION: The data will not be migrated automatically! +You will find a conversion script here. +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    RRD_HEARTBEAT

    +
    + +

    + +Starting with PNP 0.6.1 +

    +
    RRD_HEARTBEAT = 305
    + +

    +After <RRD_HEARTBEAT> seconds RRDtool expects new data. +

    + +

    +More information at http://oss.oetiker.ch/rrdtool/doc/rrdcreate.en.html +

    + +

    +This option has effect only during creation of the RRD database. +

    + +
    + +

    Hints on Template Names

    +
    + +

    + +In most situations, one can easily get desired template names, by using suitable command object definitions. +

    + +

    +Consider the followng example: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load -w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    +Even when using “CUSTOM_TEMPLATE = 1” one would end up in template names like “_usr_lib_nagios_plugins_check_load_-w_4,4,4_-c_5,5,5”, which is highly undesired, especially because of the parameters in it. +

    + +

    +Solution 1: Split parameters into separate $ARGn$ +

    + +

    +A simple solution is to use the following command object definition: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_command check_by_ssh!/usr/lib/nagios/plugins/check_load!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +(notice the additional “!”) +

    + +

    +This even works, when $ARG2$ is let empty. +

    + +

    +Of course one would still need to set “CUSTOM_TEMPLATE = 1”. +

    + +

    + +Solution 2: Hide the remote executor inside the command object definition +

    + +

    +Another way is to “hide” the remote excutor in the respective command object definitions. +

    + +

    +Instead of defining: + +

    +
    +define command {
    +  command_name check_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ $ARG1$ $ARG2$
    +}
    +
    + +

    + +one would define the following for every command to be remotely executed: + +

    +
    +define command {
    +  command_name check_load_by_ssh
    +  command_line /usr/bin/ssh $HOSTADDRESS$ /usr/lib/nagios/plugins/check_load $ARG1$
    +}
    +
    + +

    + +with commands like: + +

    +
    +  …
    +  check_load_by_ssh!-w 4,4,4 -c 5,5,5
    +  …
    +
    + +

    + +Of course one must not set “CUSTOM_TEMPLATE = 1” in this way. +

    + +

    + +Which of above two solutions one follows is largely a matter of taste. +

    + +

    +back to contents | PNP in distributed environments + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/tpl_helper.html b/share/pnp/documents/en_US/tpl_helper.html new file mode 100644 index 0000000..f88eb93 --- /dev/null +++ b/share/pnp/documents/en_US/tpl_helper.html @@ -0,0 +1,247 @@ + + + +

    Template Helper Functions

    +
    + +

    + +Helper functions are meant to simplify the creation of templates and trap errors +

    + +
    + +

    rrd::def

    +
    + +

    + +string rrd::def ( $vname, $rrdfile, $ds, [ $cf='AVERAGE' ] ) +

    +
    $def = rrd::def('var1', $RRDFILE[0], $DS[0], 'MAX');
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::cdef

    +
    + +

    + +string rrd::cdef ( $vname, $rpn, ) +

    +
    $def = rrd::cdef('var1_bits', 'var1,8,*' );
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::vdef

    +
    + +

    + +string rrd::vdef ( $vname, $rpn, ) +

    +
    $def = rrd::vdef('var1_avg', 'var1,AVERAGE' );
    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_data.en.html +

    + +
    + +

    rrd::line[1-3]

    +
    + +

    + +string rrd::line[1-3] ( $vname, $color, [ $text ], [ $stack ] ) +

    +
    $def .= rrd::line1('var1', #ff00ff );
    + +

    +Draws a simple line one pixel wide without label +

    +
    $def .= rrd::line3('var1', '#ff00ff', 'Load' );
    + +

    +Draws a line three pixels wide with label “Load” +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::area

    +
    + +

    + +string rrd::area ( $vname, $color, [ $text ], [ $stack ] ) +

    +
    $def .= rrd::area('var1', '#ff00ff', 'Load' );
    + +

    +Draws an area with label “Load” +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::gprint

    +
    + +

    + +string rrd::gprint ( $vname, $cf, [ $text ] ) +

    +
    $def .= rrd::gprint('var1', 'MAX', '%4.2lf %s Max' );
    +
    $def .= rrd::gprint('var1', array('MIN', 'MAX', 'AVERAGE'), '%4.2lf %s' );
    + +

    +If $cf is an array the legend will be formatted automatically +

    + +

    +http://oss.oetiker.ch/rrdtool/doc/rrdgraph_graph.en.html +

    + +
    + +

    rrd::color

    +
    + +

    + +string rrd::color ( $num [, $num]) +

    + +

    +Returns a color from the HTML color table. The second (optional) argument allows to specify an alpha value used to set the transparency of the selected color. +

    + +

    +Starting with PNP 0.6.18 the function accepts a third argument which refers to colour scheme definitions in config.php (or config_local.php which is update safe). There you can find the array $scheme[], e.g. +

    +
    $scheme['Reds'] = array (...)
    + +

    +Within the template you define +

    +
    $schema = $this->config->scheme['Reds'];
    +...
    +rrd::color ($key, '', $schema);
    + +

    +This way you select the value taken from $scheme['Reds'][$key]. If $key is not within the array or you misspelled the name (case sensitive) then the default colour palette is used. +

    + +
    + +

    rrd::gradient

    +
    + +

    + +string rrd::gradient ( $vname, [$start_color], [$end_color], [$label], [$steps], [$lower] ) +

    + +

    +Creates a color gradient from $start_color to $end_color +

    +
    $def .= rrd::gradient('var1', '#ff0000', '#ffff00' );
    + +

    + +Example +

    + +
    + +

    rrd::cut

    +
    + +

    + +string rrd::cut ( $text, $length ) +

    +
    $label = rrd::cut($LABEL[0], 18);
    + +

    +Cuts a text to a given length $length or fills it up to $length if needed.
    + +This function is helpful if legend needs to be justified but length of label is unknown. +

    + +
    + +

    rrd::ticker

    +
    + +

    + +string rrd::ticker ( $vname, $warning, $critical, [$fraction], [$opacity], [$color_OK], [$color_WARN], [$color_CRIT] ) +

    + +

    +Creates a colorized bar at the top of the chart which shows different colors depending on states OK, WARNING & CRITICAL +

    +
    $def .= rrd::ticker( "var1", $WARN[0], $CRIT[0] );
    + +

    + +Example +

    + +
    + +

    rrd::alerter

    +
    + +

    + +string rrd::alerter ( $vname, $label, $warning, $critical, [$opacity], [$unit], [$color_OK], [$color_WARN], [$color_CRIT], [$line_col] ) +

    + +

    +Creates colorized areas, which show different colors depending on states OK, WARNING & CRITICAL +

    +
    $def .= rrd::alerter( "var1", $LABEL[0], $WARN[0], $CRIT[0], "FF", $UNIT[0] );
    + +

    +Example +

    + +
    + +

    rrd::alerter_gr

    +
    + +

    + +string rrd::alerter_gr ( $vname, $label, $warning, $critical, [$opacity], [$unit], [$color_OK], [$color_WARN], [$color_CRIT], [$line_col], [$start_color] ) +

    + +

    +Creates colorized gradients, which show different colors depending on states OK, WARNING & CRITICAL +

    +
    $def .= rrd::alerter_gr( "var1", $LABEL[0], $WARN[0], $CRIT[0], "FF", $UNIT[0] );
    + +

    +Example + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/tpl_helper_pnp.html b/share/pnp/documents/en_US/tpl_helper_pnp.html new file mode 100644 index 0000000..74bacde --- /dev/null +++ b/share/pnp/documents/en_US/tpl_helper_pnp.html @@ -0,0 +1,90 @@ + + + +

    PNP Helper Functions

    +
    + +

    + +PNP Helper functions are meant to simplify the creation of templates. In contrast to the rrd helper functions they don't call existing RRDtool functions. +

    + +
    + +

    pnp::adjust_unit

    +
    + +

    + +(string,number,string,number) pnp::adjust_unit ( $value, $base=1000, $format='%.3lf' ) +

    + +

    +The purpose of this function is to “normalize” large numbers. Modern hard disks have reached sizes of several GB or TB and looking at numbers like 1521073648234 you begin to count the digits so it would be more convienient to translate the value. The same applies to network traffic. +

    + +

    +The function takes up to three parameters and returns an array with four elements in any case. +

    +
      +
    • The first parameter to be passed is the number (including an “UOM”, if applicable)
      +
    • +
    • The second parameter is optional and defaults to “1000” (e.g. traffic), but might be “1024” (e.g. disk size) as well
      +
    • +
    • The third parameter is optional, defaults to '%.3lf', and specifies the format of the value to be returned
      +
    • +
    +
    $size = pnp::adjust_unit(1521073648234,1024,'%7.3lf');
    + +

    +Please note that “$size” is an array consisting of four fields: +

    +
     $size[0] := "  1.383 T"
    + +

    +contains the formatted value including the unit +

    +
     $size[1] := "1.383"
    + +

    +contains the formatted number +

    +
     $size[2] := "T"
    + +

    +contains the unit +

    +
     $size[3] := "1099511627776"
    + +

    +contains the divisor +

    + +

    +Assuming check_disk returns “MB” as UOM you can append that as well + +

    +
    $disk = pnp::adjust_unit("1524MB",1024,'%7.3lf');
    + +

    + +will result in +$disk[0] := “1.448 GB” +

    + +

    +
    + +“old” check_disk template with %s directive
    + +

    + +

    +
    + +“new” check_disk template with pnp::adjust_unit + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/tpl_special.html b/share/pnp/documents/en_US/tpl_special.html new file mode 100644 index 0000000..958df3c --- /dev/null +++ b/share/pnp/documents/en_US/tpl_special.html @@ -0,0 +1,187 @@ + + + +

    Special templates

    +
    + +

    + +“special templates” (starting with PNP 0.6.5) are used to combine data from arbitrary hosts and services and thus are not connected directly to a host or service. +

    + +

    +Often it is desired to show data from several services in one graph. Every time the "pages" will not be sufficient the special templates may come into play. +

    + +
    + +

    Basics

    +
    + +

    + +“Special templates” will be searched in pnp4nagios/share/templates.special and must have the extension .php. +

    + +

    +They are called via the controller “special” using + +

    +
    http://<your-nagios-server>/pnp4nagios/special?tpl=<template>
    + +

    + +<template> is to be replaced with the particular template without the extension .php. +

    + +

    +An appropriate link will be shown in the PNP interface if at least one “special template” was found. +

    + +
    + +

    Example

    +
    + +

    + +The task is to show the response times of all web servers with hostnames websrv, websrv02, and websrv03 in one graph. The data is provided by the service “HTTP”. +

    + +

    +Step 1: create a template “websrv_response_times.php” in the folder pnp4nagios/share/templates.special +

    + +

    +“Special templates” always start with the definition of a title and a comment. +

    +
    $this->MACRO['TITLE']   = "HTTP Response Times";
    +$this->MACRO['COMMENT'] = "HTTP Response Times for all Cluster Nodes";
    + +

    +Step 2: create a list of all hosts/services which come into question. PNP provides a function tplGetServices() to accomplish this task. +

    + +

    +tplGetServices() expects two parameters. +

    + +

    +Parameter 1 is a regular expression for the host(s), parameter 2 a regular expression for the service(s). +

    +
    $services = $this->tplGetServices("websrv","HTTP");
    + +

    +$services now is an array with all services found. +

    + +

    +To ease template development and to give an insight on the data structures you can force Kohana to stop processing using an exception. +

    + +

    +To show the data of $services you just need the following line: +

    +
    throw new Kohana_exception(print_r($services,TRUE));
    + +

    +Output of pnp4nagios/special?tpl=websrv_response_times +

    +
    +Array ( 
    +  [0] => Array ( 
    +     [host] => websrv01 
    +     [service] => HTTP 
    +  ) 
    +  [1] => Array ( 
    +     [host] => websrv02
    +     [service] => HTTP 
    +  ) 
    +  [2] => Array ( 
    +     [host] => websrv03
    +     [service] => HTTP 
    +  ) 
    +)
    +
    + +

    +The variable $services contains an array with all services found, in this case three hosts with the service “HTTP”. +

    + +

    +Step 3: Iterating the array $services and creating the graph definitions +

    +
    foreach($services as $key=>$val){
    +    $data      = $this->tplGetData($val['host'],$val['service']);
    +    $hostname  = rrd::cut($data['MACRO']['HOSTNAME'], 15);
    +    $def[0]   .= rrd::def("var$key" , $data['DS'][0]['RRDFILE'], $data['DS'][0]['DS'] );
    +    $def[0]   .= rrd::line1("var$key", rrd::color($key), $hostname);
    +    $def[0]   .= rrd::gprint("var$key", array("MAX", "AVERAGE"));
    +}
    + +

    +Inside the loop the function tplGetData is used to read the particular XML file. The data is returned as an array called $data. +

    + +

    +In this example some other little PNP helpers are used recognisable by the extension rrd::. +

    + +

    +The function rrd::cut() cuts a string to a specific length or fills up to this length. This might be helpful to align the legend. +

    + +

    +The function rrd::gprint() creates the legend below the graph. +

    + +

    +The function rrd::color() returns a colour from a predefined list of colours. +

    + +

    +You will find more information on the PNP helpers here. +

    +
    <?php
    +#
    +# Special Template websrv_response_times.php
    +#
    +$this->MACRO['TITLE']   = "HTTP Response Times";
    +$this->MACRO['COMMENT'] = "HTTP Response Times for all Cluster Nodes";
    +#
    +# Get a List of Services by regex 
    +# Option 1 = 'Host Regex'
    +# Option 2 = 'Service Regex'
    +#
    +$services = $this->tplGetServices("websrv","HTTP");
    +#throw new Kohana_exception(print_r($services,TRUE));
    +#
    +# The Datasource Name for Graph 0
    +$ds_name[0] = "Response Times";
    +$opt[0]     = "--title \"Response Times\"";
    +$def[0]     = "";
    +#
    +# Iterate through the list of hosts
    +foreach($services as $key=>$val){
    +    #
    +    # get the data for a given Host/Service
    +    $data = $this->tplGetData($val['host'],$val['service']);
    +    #
    +    # Throw an exception to debug the content of $a
    +    # Just to get Infos about the Array Structure
    +    #
    +    #throw new Kohana_exception(print_r($a,TRUE));
    +    $hostname   = rrd::cut($data['MACRO']['HOSTNAME']);
    +    $def[0]    .= rrd::def("var$key" , $data['DS'][0]['RRDFILE'], $data['DS'][0]['DS'] );
    +    $def[0]    .= rrd::line1("var$key", rrd::color($key), $hostname);
    +    $def[0]    .= rrd::gprint("var$key", array("MAX", "AVERAGE"));
    +}
    +?>
    + +

    +back to contents + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/upgrade.html b/share/pnp/documents/en_US/upgrade.html new file mode 100644 index 0000000..4bbce5b --- /dev/null +++ b/share/pnp/documents/en_US/upgrade.html @@ -0,0 +1,220 @@ + + + +

    Upgrade to version 0.6.x

    +
    + +

    + +The web-frontend has been completely rewritten and is now based on the PHP MVC framework Kohana. This leads to changed dependencies which must be checked prior to installation. +

    + +

    +Note: At first an upgrade is like a new installation. Afterwards some changes should be made which are described further down. +

    + +

    +Without specifying any options during ./configure PNP 0.4.x was installed below an existing Nagios-Installation at /usr/local/nagios. +

    + +

    +Without specifying any options during ./configure PNP 0.6.x will be installed in a separate directory at /usr/local/pnp4nagios, i.e. it should be viewed as an independent application. +

    + +

    +Note: It is sufficient to copy the *.rrd files from the old to the new location. They contain the data The *.xml files are recreated every time new performance data arrives as they contain meta information. The internal structure of the xml files has changed so you wouldn't be able to use them either way. +

    + +
    + +

    Comparison of the structure

    +
    + +

    + +Summary of a PNP 0.4.14 installation +

    +
    +./configure
    +...
    +*** Configuration summary for pnp 0.4.14 05-02-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/nagios
    +  HTML Dir:                         /usr/local/nagios/share/pnp
    +  Config Dir:                       /usr/local/nagios/etc/pnp
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/nagios/share/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/nagios/var/spool/perfdata/
    +
    + +

    +Summary of a PNP 0.6.0 installation +

    +
    +./configure
    +...
    +*** Configuration summary for pnp4nagios-0.6.0 07-30-2009 ***
    +
    +  General Options:
    +  -------------------------         -------------------
    +  Nagios user/group:                nagios nagios
    +  Install directory:                /usr/local/pnp4nagios
    +  HTML Dir:                         /usr/local/pnp4nagios/share
    +  Config Dir:                       /usr/local/pnp4nagios/etc
    +  Location of rrdtool binary:       /usr/bin/rrdtool Version 1.3.1
    +  RRDs Perl Modules:                FOUND (Version 1.3001)
    +  RRD Files stored in:              /usr/local/pnp4nagios/var/perfdata
    +  process_perfdata.pl Logfile:      /usr/local/pnp4nagios/var/perfdata.log
    +  Perfdata files (NPCD) stored in:  /usr/local/pnp4nagios/var/spool
    +
    +  Web Interface Options:  -------------------------         -------------------
    +  HTML URL:                         http://localhost/pnp4nagios/
    +  Apache Config File:               /etc/apache2/conf.d/pnp4nagios.conf
    +
    + +

    +Looking at these lines result in the parameters to be changed and the upgrade strategy. +

    + +
    + +

    Adjustments

    +
    + +

    + +The templates of the action_url definitions have changed. Instead of ”/nagios/pnp” the URL should be ”/pnp4nagios” and instead of “index.php” now “graph” will be used. +

    +
    define host {
    +  name       host-pnp
    +  register   0
    +  action_url /pnp4nagios/graph?host=$HOSTNAME$
    +}
    +
    +define service {
    +  name       srv-pnp
    +  register   0
    +  action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    + +

    +The definitions for the preview popup function are similar + +

    +
    define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    + +

    + +Attention: It is not an error that the strings in front and after “class” contain only one quote. +

    + +

    +Other than described in the 0.4.x documentation these templates can be used for Nagios 2.x and 3.x. +

    + +

    +The variables in the files in the templates folder have to be initialised before first use. Example +

    +
    $lower = ""
    + +

    + +Earlier you were able to append to variables which weren't initialised before first use. Example: + +

    +
    foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +Now you have to change that to + +

    +
    +$def[1] = "";
    +foreach ($DS as $i) {
    +    $def[1] .= "DEF:var$i=$rrdfile:$DS[$i]:AVERAGE " ;
    + +

    + +
    + +Constants in template files don't work anymore, so that they have to be converted to variables. +

    +
    define("_WARNRULE", '#FFFF00');
    + +

    +may be changed to +

    +
     $WARNRULE = '#FFFF00';
    + +

    +Please keep in mind that all occurrences have to be changed ;-). +

    + +
    + +

    Upgrade scenario using NPCD

    +
    +
      +
    1. planning the new setup
      +
    2. +
    3. perform test installation and acquaint oneself with the new system
      +
    4. +
    5. create backup of the old installation
      +
    6. +
    7. install PNP 0.6.x at /usr/local/pnp4nagios
      +
    8. +
    9. make install-config
      +
    10. +
    11. make install-webconf
      +
    12. +
    13. reload Apache
      +
    14. +
    15. test Apache-config
      +
        +
      1. call of /pnp4nagios has to report an empty perfdata directory
        +
      2. +
      +
    16. +
    17. create /usr/local/pnp4nagios/etc/npcd.cfg from npcd.cfg-sample
      +
        +
      1. check paths and adapt changes from 0.4.x if necessary
        +
      2. +
      +
    18. +
    19. adjust all paths in nagios.cfg to the new PNP installation
      +
    20. +
    21. adjust all paths in the command definitions
      +
    22. +
    23. stop npcd using /etc/init.d/npcd stop
      +
    24. +
    25. make install-init installs the new init script for npcd
      +
    26. +
    27. /etc/init.d/nagios stop
      +
    28. +
    29. copy /usr/local/nagios/share/perfdata to /usr/local/pnp4nagios/var/perfdata. Attention: check the permissions
      +
    30. +
    31. /etc/init.d/npcd start
      +
    32. +
    33. /etc/init.d/nagios start
      +
    34. +
    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/verify.html b/share/pnp/documents/en_US/verify.html new file mode 100644 index 0000000..90aa790 --- /dev/null +++ b/share/pnp/documents/en_US/verify.html @@ -0,0 +1,115 @@ + + + +

    Checking the installation

    +
    + +

    + +If everything went well until now you can try to call PNP using your web browser. +When using the installation with default values PNP should be called using http://<server name>/pnp4nagios/. +The first time you will see a page “PNP4Nagios Environment Tests” which includes different checks of necessary components. Obviously all checks have to be passed successfully before you can proceed. Please follow the instructions given on that page.
    + +

    + +

    +If all tests have passed *successfully* the file pnp4nagios/share/install.php can be deleted or renamed. Not till then the web interface is reachable. +

    + +

    +Alternatively you can create a file called pnp4nagios/share/install.ignore which will prevent the call of the installer after further updates. +

    + +

    +If you receive the message “PHP magic_quotes_gpc is deprecated” then please locate your php.ini and set the value to Off. +

    + +

    +Called without any arguments PNP looks for RRD and XML files in pnp4nagios/var/perfdata and shows all graphs of the first host. +

    + +

    +ATTENTION: Immediately after (re-)starting Nagios after you enabled the processing of performance data you will get error messages in your browser because performance data has to be collected and stored in RRD files. Depending on the check interval you are using you have to wait some time before you can view the first graphs. +

    + +
    + +

    Debug Logfile

    +
    + +

    + +Calling make install-config during installation will create a sample config file etc/process_perfdata.cfg-sample. The values in the sample file will correspond to the defaults used by process_perfdata.pl so normally you do not have a file called process_perfdata.cfg while running the procedure.
    + +However you can influence the way process_perfdata.pl works by changing options which have to be specified in process_perfdata.cfg. +

    + +

    +The most important options launching PNP are LOG_LEVEL and LOG_FILE. We recommend setting the LOG_LEVEL value to “2” so you can track what process_perfdata.pl will do. +Most likely we will ask for excerpts from perfdata.log if you open a support request on the mailing lists as well as the output of the verify_pnp_config script so please provide them ;-). +

    + +

    +During normal operation the debug level should be set to 0 to avoid performance issues due to unnecessary entries in the log file. +

    + +
    + +

    Something went wrong

    +
    + +

    + +Some basic settings should be checked +

    + +

    +1. Have any RRD and XML files been created? +process_perfdata.pl will create a new directory under pnp/perfdata for every host. In this directory an RRD database and an XML file will be created for every service. The host data will be stored in _HOST_.xml and _HOST_.rrd respectively.
    + +If graphing stops out of a sudden then open the appropriate XML file. There are two tags called <RC> and <TXT>. <RC> shows the return code of the RRDtool update and <TXT> a textual description.
    + +Sometimes you have to specify additional options so that performance data is produced. In some cases a wrapper script might help.
    + +However not all checks provide performance data. That applies - among others - to “check_ping” in contrast to “check_icmp” which does provide data (starting with Nagios plugin version 1.4.12 check_ping does provide performance data).
    + +Using the web interface the detail information of hosts/services shows a field “Performance Data”. If it is empty there is no data available so no files are written to the appropriate directory and that is why PNP does not provide you with graphs!
    + +The following image shows the information of a “PING” service. The output of the plugin is surrounded by a blue border, the performance data by a red one.
    + +status information +

    + +

    +2. Has nagios called process_perfdata.pl? +In the config file for process_perfdata.pl (etc/process_perfdata.cfg) you can increase the debug level. Data processing will be logged in var/perfdata.log. +

    + +

    +3. Graphs are shown without text? +Have a look at the requirements. +

    + +

    +4. Some graphs are shown, others report the error “parser error: Input is not proper UTF-8” or something similar. Please check if your data contains “special” characters not present in the ASCII set. Try to set XML_ENC in process_perfdata.cfg to ISO-8859-1 or something appropriate. Wait until the xml file is newly created and retry. +

    + +

    +5. Using the npcdmod module the value of the nagios.cfg directive event_broker_options may have to be adapted if it was modified. You'll find some details here. +

    + +

    +6. You can use the script verify_pnp_config.pl after installation to check your settings and if performance data is present. +

    + +

    +7. Things look OK, but some files are being left in the spool directory (/usr/local/pnp4nagios/var/spool/<perfdata_filename>-PID-<process_perfdata_pid>). If process_perdata.pl is not able to write to the destination directory (/usr/local/pnp4nagios/share/perfdata/<host>), it will stop and not remove the file. That will increase the size of the spool directory and slow down performance data processing. This problem is likely to occur if you have copied directories from a previous installation and/or manually created directories and left them with wrong permissions or wrong ownership. +

    + +

    +back to contents | verify_pnp_config.pl + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/verify_pnp_config.html b/share/pnp/documents/en_US/verify_pnp_config.html new file mode 100644 index 0000000..a25f0b3 --- /dev/null +++ b/share/pnp/documents/en_US/verify_pnp_config.html @@ -0,0 +1,132 @@ + + + +

    verify_pnp_config

    +
    + +

    + +In case of problems there is a script called verify_pnp_config.pl located on http://verify.pnp4nagios.org. It enables you to check the configuration settings as well as performance data of hosts or services. It can be used prior and during runtime of PNP. +

    + +
    + +

    Download

    +
    +
    +wget http://verify.pnp4nagios.org/verify_pnp_config
    +
    + +
    + +

    Test

    +
    + +

    + +The verify script is located on http://verify.pnp4nagios.org and needs three start options +

    +
      +
    • --mode One of the modes described on modes
      +
    • +
    • --config Location of nagios.cfg or icinga.cfg
      +
    • +
    • --pnpcfg Path to PNP´s etc directory
      +
    • +
    + +

    + +Calling perl verify_pnp_config will show the available options. +

    + +

    +The following is a sample run + +

    +
    +lenny:~# perl verify_pnp_config --mode npcdmod --config=/usr/local/nagios/etc/nagios.cfg --pnpcfg=/usr/local/pnp4nagios/etc
    +[INFO]  ========== Starting Environment Checks ============
    +[INFO]  My version is: verify_pnp_config-0.6.14-R.31
    +[INFO]  Reading /usr/local/nagios/etc/nagios.cfg
    +[OK  ]  Running product is 'nagios'
    +[OK  ]  object_cache_file is defined
    +[OK  ]  object_cache_file=/usr/local/nagios/var/objects.cache
    +[INFO]  Reading /usr/local/nagios/var/objects.cache
    +[OK  ]  resource_file is defined
    +[OK  ]  resource_file=/usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/nagios/etc/resource.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/process_perfdata.cfg
    +[INFO]  Reading /usr/local/pnp4nagios/etc/pnp4nagios_release
    +[OK  ]  Found PNP4Nagios version "0.6.14"
    +[OK  ]  Effective User is 'nagios'
    +[OK  ]  User nagios exists with ID '1000'
    +[OK  ]  Effective group is 'nagios'
    +[OK  ]  Group nagios exists with ID '1000'
    +[INFO]  ========== Checking npcdmod Mode Config  ============
    +[OK  ]  process_performance_data is 1 compared with '/1/'
    +[OK  ]  event_broker_options is defined
    +[OK  ]  event_broker_options=-1
    +[OK  ]  event_broker_option bits 2 and 3 enabled (12)
    +[OK  ]  broker_module is defined
    +[OK  ]  broker_module=/usr/local/pnp4nagios/lib/npcdmod.o config_file=/usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  npcdmod.o config file is /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg used by npcdmod.o is readable
    +[OK  ]  npcd daemon is running
    +[OK  ]  /usr/local/pnp4nagios/etc/npcd.cfg is used by npcd and readable
    +[OK  ]  npcd and npcdmod.o are using the same config file (/usr/local/pnp4nagios/etc/npcd.cfg)
    +[INFO]  Nagios config looks good so far
    +[INFO]  ========== Checking config values ============
    +[INFO]  Reading /usr/local/pnp4nagios/etc/npcd.cfg
    +[OK  ]  Script /usr/local/pnp4nagios/libexec/process_perfdata.pl is executable
    +[INFO]  ========== Starting global checks ============
    +[OK  ]  status_file is defined
    +[OK  ]  status_file=/dev/shm/status.dat
    +[INFO]  Reading /dev/shm/status.dat
    +[INFO]  ==== Starting rrdtool checks ====
    +[OK  ]  RRDTOOL is defined
    +[OK  ]  RRDTOOL=/usr/bin/rrdtool
    +[OK  ]  /usr/bin/rrdtool is executable
    +[OK  ]  RRDtool 1.3.1  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>
    +[OK  ]  USE_RRDs is defined
    +[OK  ]  USE_RRDs=1
    +[OK  ]  Perl RRDs modules are loadable
    +[INFO]  ==== Starting directory checks ====
    +[OK  ]  RRDPATH is defined
    +[OK  ]  RRDPATH=/usr/local/pnp4nagios/var/perfdata
    +[OK  ]  Perfdata directory '/usr/local/pnp4nagios/var/perfdata' exists
    +[WARN]  62 hosts/services are not providing performance data
    +[WARN]  'process_perf_data 1' is set for 43 hosts/services which are not providing performance data!
    +[WARN]  'process_perf_data 0' is set for 27 of your hosts/services
    +[OK  ]  'process_perf_data 1' is set for 243 of your hosts/services
    +[INFO]  ==== System sizing ====
    +[OK  ]  269 hosts/service objects defined
    +[INFO]  ==== Check statistics ====
    +[WARN]  Warning: 3, Critical: 0
    +[WARN]  Checks finished...
    +
    + +
    + +

    Performance data

    +
    + +

    +Starting with 0.6.19-R.37 (2013-02-17) the script will accept the option --object (or -o) followed by a string to specify a host name and/or service description to additionally show performance data (if any) of the object(s) found. The data is enclosed in brackets, followed by the value of the directive process_performance_data (ppd=n). +

    + +

    +host = show performance information for host host
    + +;service = show performance information for service service
    + +host;service = show performance information for service service on host host +

    + +

    +The strings are taken as regular expressions (perl syntax). + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/webfe.html b/share/pnp/documents/en_US/webfe.html new file mode 100644 index 0000000..36ed83e --- /dev/null +++ b/share/pnp/documents/en_US/webfe.html @@ -0,0 +1,149 @@ + + + +

    Nagios web frontend

    +
    + +

    +Of course PNP should be easily accessible. You do not want to search long for the right graph. +

    + +

    +Nagios itself features external URLs using so called extended info configs. Due to changes between Nagios 2.x and Nagios 3.x both versions are described. +

    + +
    + +

    Nagios 2.x

    +
    + +

    + +With Nagios 2.x the integration of external URLs into the nagios web interface is made using Extended Info Objects for services. For PNP we use the directive action_url to call the PNP web frontend with the appropriate options. +

    +
    +define serviceextinfo {
    +   host_name             localhost
    +   service_description   load
    +   action_url            /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +}
    +
    + +

    +You have to specify an additional Extended Info Definition for every service. +

    + +
    + +

    Nagios 3.x

    +
    + +

    + +Since nagios 3.0 the action_url-directive has be moved to the host or service definition. This way the definition of URLs to the PNP-interface has been simplified. The serviceextinfo and hostextinfo definitions are deprecated. +

    + +

    +First two nagios templates are defined. If you used the Nagios quickstart installation guides you can append these lines to templates.cfg: +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    +These two templates can now be included via “use srv-pnp” or “use host-pnp” for services and hosts respectively. If you used the quickstart installation guide you might for example edit the file localhost.cfg and add the template to the host or service definition as follows: +

    +
    define host{
    +        use                     linux-server,host-pnp    ; Name of host templates to use
    +                                                         ; This host definition will inherit all variables that are defined
    +                                                         ; in (or inherited by) the linux-server host template definition.
    +        host_name               localhost
    +        alias                   localhost
    +        address                 127.0.0.1
    +        }
    +
    +
    define service{
    +        use                     local-service,srv-pnp   ; Name of service template to use
    +        host_name               localhost
    +        service_description     PING
    +        check_command           check_ping!100.0,20%!500.0,60%
    +        }
    +
    + +

    + +The links to the correct URLs are created automagically.
    +
    + +

    + +

    +Tips: if you want to open the PNP window in your main frame (on the right of the menu) instead of a new page, just set action_url_target=main in your nagios cgi.cfg +

    + +
    + +

    Popups

    +
    + +

    +You can integrate PNP into Nagios in a way that you have current graphs without clicking any icons. This can be accomplished using the CGI Includes which allow us to include JavaScript code in the status detail view ( status.cgi ). +

    + +

    +Prerequisites: +

    +
      +
    • PNP is installed and running
      +
    • +
    • the file status-header.ssi from the contrib/ssi/ folder of the PNP package was copied to /usr/local/nagios/share/ssi/.
      +Attention: This file must NOT be executable. Otherwise it will be treated as a CGI which will result in an error.
      +*Note to Apache admins*: Apache ssi and Nagios ssi only have a similar name.
      +
    • +
    • the appropriate service definition(s) has/have been modified. Please note that until Nagios 2.x you have to modify the serviceextinfo definition (which is deprecated starting with Nagios 3).
      +
    • +
    + +

    + +Definition: + +

    +
    +define host {
    +   name       host-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_
    +   register   0
    +}
    +
    +define service {
    +   name       srv-pnp
    +   action_url /pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=$SERVICEDESC$' class='tips' rel='/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=$SERVICEDESC$
    +   register   0
    +}
    +
    + +

    + +After a restart of Nagios (after modifying the definitions) the result might look like this:
    + + +

    + +

    +back to contents | config options + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/webfe_cfg.html b/share/pnp/documents/en_US/webfe_cfg.html new file mode 100644 index 0000000..a1d8704 --- /dev/null +++ b/share/pnp/documents/en_US/webfe_cfg.html @@ -0,0 +1,136 @@ + + + +

    PNP Web Frontend

    +
    + +

    + +The behaviour of the PNP Web-Frontend can be controlled through the config file etc/config.php. This file will be overwritten during updates of PNP as the paths and options are detected during ./configure. +

    + +

    +Own adjustments should be made in etc/config_local.php. If this file does not exist the file config.php can be taken as a guideline. +

    + +
    + +

    etc/config.php

    +
    + +

    + +Following the most important parameters: +

    + +

    +The path to the RRDtool binary. Will be detected by ./configure + +

    +
     $conf['rrdtool'] = "/usr/bin/rrdtool";
    + +

    + +Height and width of the RRD graphs + +

    +
     $conf['graph_width'] = "500";
    + $conf['graph_height'] = "100";
    + +

    + +Screen sizes may vary, pages sizes won't. The following two directives enable you to specify different sizes for the creation of PDFs. If they aren't specified the values of the graph sizes are taken. + +

    +
     $conf['pdf_width'] = "675";
    + $conf['pdf_height'] = "100";
    + +

    + +Additional options passed with every call of RRDTool, for example --slope-mode to smooth the graphs + +

    +
     $conf['graph_opt'] = "";
    + +

    + +The path to the RRD and XML files created by process_perfdata.pl + +

    +
     $conf['rrdbase'] = "/usr/local/pnp4nagios/var/perfdata/";
    + +

    + +The path to the config file for the pages. + +

    +
     $conf['page_dir'] = "/usr/local/pnp4nagios/etc/pages/";
    +
    + +

    +PNP pages will be refreshed every n seconds + +

    +
     $conf['refresh'] = "90";
    +
    + +

    +Max. age of RRD files in seconds. After reaching this value links to the graphs will be marked as inactive + +

    +
     $conf['max_age'] = 60*60*6;
    +
    + +

    + +Base URL to the Nagios CGIs + +

    +
     $conf['nagios_base'] = "/nagios/cgi-bin";
    +
    + +

    + +List of users who are allowed to view links to the services of the current host + +

    +
     $conf['allowed_for_service_links'] = "EVERYONE";
    +
    + +

    +List of users who can view/access the host search field + +

    +
     $conf['allowed_for_host_search'] = "EVERYONE";
    +
    + +

    +If PNP is called with a host only ( index.php?host=<myserver> ), the defined user is shown an overview of all services related to this host + +

    +
     $conf['allowed_for_host_overview'] = "EVERYONE";
    +
    + +

    +The periods of time the RRD graphs will show are determined using the array $views[]. The title and number of graphs can be specified globally in this place +

    +
    +$views[] = array('title' => 'One Hour',  'start' => (60*60) );
    +$views[] = array('title' => '4 Hours',   'start' => (60*60*4) );
    +$views[] = array('title' => '25 Hours',  'start' => (60*60*25) );
    +$views[] = array('title' => 'One Week',  'start' => (60*60*25*7) );
    +$views[] = array('title' => 'One Month', 'start' => (60*60*24*32) );
    +$views[] = array('title' => 'One Year',  'start' => (60*60*24*380) );
    +
    + +

    +You can add more views ($views[5], …) but please keep in mind that under normal circumstances ALL views you defined are shown. +

    + +

    +back to contents | timeranges + +

    + +
    + \ No newline at end of file diff --git a/share/pnp/documents/en_US/wrapper.html b/share/pnp/documents/en_US/wrapper.html new file mode 100644 index 0000000..367e4b1 --- /dev/null +++ b/share/pnp/documents/en_US/wrapper.html @@ -0,0 +1,30 @@ + +

    +check_procs is an example for a plugin which doesn't deliver performance data: +

    +
    ./check_procs -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'
    + +

    +This can be changed with the following wrapper script +

    + +

    +check_procs.sh + +

    +
    #!/bin/bash
    +LINE=`/usr/local/nagios/libexec/check_procs $*`
    +RC=$?
    +COUNT=`echo $LINE | awk '{print $3}'`
    +PROCS=`expr $COUNT - 1`
    +LINE=`echo $LINE | sed "s/: $COUNT /: $PROCS /"`
    +echo $LINE \| procs=$PROCS
    +exit $RC
    + +

    +Now you'll get the number together with the required label + +

    +
    ./check_procs.sh -a ndo2db -w 1: -c 0:
    +PROCS OK: 2 processes with args 'ndo2db'| procs=2
    diff --git a/share/pnp/documents/en_US/xport.html b/share/pnp/documents/en_US/xport.html new file mode 100644 index 0000000..53634ca --- /dev/null +++ b/share/pnp/documents/en_US/xport.html @@ -0,0 +1,44 @@ + + + +

    Data export

    +
    + +

    + +PNP provides access to RRD data using the xport controller. The output format can be specified. At the moment the formats xml, json and csv are supported. +

    + +

    +The controller can be called using the URL + +

    +
    /pnp4nagios/xport/<format>?host=<hostname>&srv=<servicedesc>
    + +

    + +whereas <format> has to be replaced with the desired format. +

    + +

    + +You can also use wget to generate images and place them in periodic reports. One example may be: +

    +
    wget -O image.png 'http://<user>:<pass>@<nagios-server>/pnp4nagios/image?host=<hostname>&srv=<service>&view=2&source=0'
    + +

    +view=<n> limits the graph to the timeperiod specified in config.php
    + +source=<n> only shows one data source if you have more than one in your RRD file +

    + +

    +Instead of view you can use start and/or end to specify the time period. For details please look at "time ranges". +

    + +

    +back to contents | templates + +

    + +
    diff --git a/share/pnp/documents/images/smileys/delete.gif b/share/pnp/documents/images/smileys/delete.gif new file mode 100644 index 0000000..d668348 Binary files /dev/null and b/share/pnp/documents/images/smileys/delete.gif differ diff --git a/share/pnp/documents/images/smileys/fixme.gif b/share/pnp/documents/images/smileys/fixme.gif new file mode 100644 index 0000000..b66ea99 Binary files /dev/null and b/share/pnp/documents/images/smileys/fixme.gif differ diff --git a/share/pnp/documents/images/smileys/icon_arrow.gif b/share/pnp/documents/images/smileys/icon_arrow.gif new file mode 100644 index 0000000..2880055 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_arrow.gif differ diff --git a/share/pnp/documents/images/smileys/icon_biggrin.gif b/share/pnp/documents/images/smileys/icon_biggrin.gif new file mode 100644 index 0000000..d352772 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_biggrin.gif differ diff --git a/share/pnp/documents/images/smileys/icon_confused.gif b/share/pnp/documents/images/smileys/icon_confused.gif new file mode 100644 index 0000000..0c49e06 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_confused.gif differ diff --git a/share/pnp/documents/images/smileys/icon_cool.gif b/share/pnp/documents/images/smileys/icon_cool.gif new file mode 100644 index 0000000..cead030 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_cool.gif differ diff --git a/share/pnp/documents/images/smileys/icon_cry.gif b/share/pnp/documents/images/smileys/icon_cry.gif new file mode 100644 index 0000000..7d54b1f Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_cry.gif differ diff --git a/share/pnp/documents/images/smileys/icon_doubt.gif b/share/pnp/documents/images/smileys/icon_doubt.gif new file mode 100644 index 0000000..fd7903b Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_doubt.gif differ diff --git a/share/pnp/documents/images/smileys/icon_doubt2.gif b/share/pnp/documents/images/smileys/icon_doubt2.gif new file mode 100644 index 0000000..eb4b70b Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_doubt2.gif differ diff --git a/share/pnp/documents/images/smileys/icon_eek.gif b/share/pnp/documents/images/smileys/icon_eek.gif new file mode 100644 index 0000000..5d39781 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_eek.gif differ diff --git a/share/pnp/documents/images/smileys/icon_evil.gif b/share/pnp/documents/images/smileys/icon_evil.gif new file mode 100644 index 0000000..ab1aa8e Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_evil.gif differ diff --git a/share/pnp/documents/images/smileys/icon_exclaim.gif b/share/pnp/documents/images/smileys/icon_exclaim.gif new file mode 100644 index 0000000..6e50e2e Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_exclaim.gif differ diff --git a/share/pnp/documents/images/smileys/icon_frown.gif b/share/pnp/documents/images/smileys/icon_frown.gif new file mode 100644 index 0000000..d2ac78c Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_frown.gif differ diff --git a/share/pnp/documents/images/smileys/icon_fun.gif b/share/pnp/documents/images/smileys/icon_fun.gif new file mode 100644 index 0000000..a8bb8a3 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_fun.gif differ diff --git a/share/pnp/documents/images/smileys/icon_idea.gif b/share/pnp/documents/images/smileys/icon_idea.gif new file mode 100644 index 0000000..a40ae0d Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_idea.gif differ diff --git a/share/pnp/documents/images/smileys/icon_kaddi.gif b/share/pnp/documents/images/smileys/icon_kaddi.gif new file mode 100644 index 0000000..1410f7f Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_kaddi.gif differ diff --git a/share/pnp/documents/images/smileys/icon_lol.gif b/share/pnp/documents/images/smileys/icon_lol.gif new file mode 100644 index 0000000..374ba15 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_lol.gif differ diff --git a/share/pnp/documents/images/smileys/icon_mrgreen.gif b/share/pnp/documents/images/smileys/icon_mrgreen.gif new file mode 100644 index 0000000..b54cd0f Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_mrgreen.gif differ diff --git a/share/pnp/documents/images/smileys/icon_neutral.gif b/share/pnp/documents/images/smileys/icon_neutral.gif new file mode 100644 index 0000000..4f31156 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_neutral.gif differ diff --git a/share/pnp/documents/images/smileys/icon_question.gif b/share/pnp/documents/images/smileys/icon_question.gif new file mode 100644 index 0000000..9d07226 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_question.gif differ diff --git a/share/pnp/documents/images/smileys/icon_razz.gif b/share/pnp/documents/images/smileys/icon_razz.gif new file mode 100644 index 0000000..29da2a2 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_razz.gif differ diff --git a/share/pnp/documents/images/smileys/icon_redface.gif b/share/pnp/documents/images/smileys/icon_redface.gif new file mode 100644 index 0000000..ad76283 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_redface.gif differ diff --git a/share/pnp/documents/images/smileys/icon_rolleyes.gif b/share/pnp/documents/images/smileys/icon_rolleyes.gif new file mode 100644 index 0000000..d7f5f2f Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_rolleyes.gif differ diff --git a/share/pnp/documents/images/smileys/icon_sad.gif b/share/pnp/documents/images/smileys/icon_sad.gif new file mode 100644 index 0000000..d2ac78c Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_sad.gif differ diff --git a/share/pnp/documents/images/smileys/icon_silenced.gif b/share/pnp/documents/images/smileys/icon_silenced.gif new file mode 100644 index 0000000..448399b Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_silenced.gif differ diff --git a/share/pnp/documents/images/smileys/icon_smile.gif b/share/pnp/documents/images/smileys/icon_smile.gif new file mode 100644 index 0000000..7b1f6d3 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_smile.gif differ diff --git a/share/pnp/documents/images/smileys/icon_smile2.gif b/share/pnp/documents/images/smileys/icon_smile2.gif new file mode 100644 index 0000000..769639d Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_smile2.gif differ diff --git a/share/pnp/documents/images/smileys/icon_surprised.gif b/share/pnp/documents/images/smileys/icon_surprised.gif new file mode 100644 index 0000000..cb21424 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_surprised.gif differ diff --git a/share/pnp/documents/images/smileys/icon_twisted.gif b/share/pnp/documents/images/smileys/icon_twisted.gif new file mode 100644 index 0000000..502fe24 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_twisted.gif differ diff --git a/share/pnp/documents/images/smileys/icon_wink.gif b/share/pnp/documents/images/smileys/icon_wink.gif new file mode 100644 index 0000000..d148288 Binary files /dev/null and b/share/pnp/documents/images/smileys/icon_wink.gif differ diff --git a/share/pnp/index.php.in b/share/pnp/index.php.in new file mode 100644 index 0000000..b4cc9ce --- /dev/null +++ b/share/pnp/index.php.in @@ -0,0 +1,148 @@ + + + + + + + + +Installation + + + + + + + +

    PNP4Nagios Environment Tests

    + +

    The following options are determined by "configure". If any of the tests have failed, consult the documentation for more information on how to correct the problem.

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PNP4Nagios Version@PKG_NAME@-@PKG_VERSION@
    Prefix@prefix@
    Configure Arguments./configure @ac_configure_args@
    RRD Storage@PERFDATA_DIR@ is readable.@PERFDATA_DIR@ is not readable.
    RRDtool Binary@RRDTOOL@ is executable by PHP@RRDTOOL@ is not executable by PHP
    PHP GD extensionPassPHP GD extension not available
    PHP function proc_open()PassPHP function proc_open not available/enabled
    PHP zlib extensionPassPHP zlib extension not available
    PHP session extensionPassPHP session extension not available
    PHP JSON extensionPassPHP JSON extension not available
    PHP magic_quotes_gpcOffPHP magic_quotes_gpc is deprecated
    PHP socket extensionPassPHP socket extension not available
    Apache Rewrite ModulePassApache mod_rewrite is not enabled
    Apache Rewrite ModuleNot running within Apache mod_php
    +
    + +

    Kohana Environment Tests

    + +

    The following tests have been run to determine if Kohana will work in your environment. If any of the tests have failed, consult the documentation for more information on how to correct the problem.

    + +
    + + + +=')): ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PHP VersionKohana requires PHP 5.1 or newer, this version is .
    System DirectoryThe configured system directory
    ('')
    does not exist or does not contain required files.
    Application DirectoryThe configured application directory
    ('')
    does not exist or does not contain required files.
    Reflection EnabledPassPHP reflection is either not loaded or not compiled in.
    Iconv Extension LoadedPassThe iconv extension is not loaded.
    Mbstring Not OverloadedThe mbstring extension is overloading PHP's native string functions.Pass
    URI DeterminationPassNeither $_SERVER['REQUEST_URI'] or $_SERVER['PHP_SELF'] is available.
    + +
    + 0): ?> +

    @PKG_NAME@ may not work correctly with your environment. Remove or rename the file on your own risk.

    + +

    Your environment passed all requirements. Remove or rename the file now.

    + +
    + +
    + + + diff --git a/share/pnp/media/css/autocomplete.css b/share/pnp/media/css/autocomplete.css new file mode 100644 index 0000000..d0f1005 --- /dev/null +++ b/share/pnp/media/css/autocomplete.css @@ -0,0 +1,6 @@ +.autocomplete-w1 { background:url(shadow.png) no-repeat bottom right; position:absolute; top:0px; left:0px; margin:6px 0 0 6px; /* IE6 fix: */ _background:none; _margin:1px 0 0 0; } +.autocomplete { border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; } +.autocomplete .selected { background:#F0F0F0; } +.autocomplete div { padding:2px 5px; white-space:nowrap; } +.autocomplete strong { font-weight:normal; color:#3399FF; } + diff --git a/share/pnp/media/css/border-h.gif b/share/pnp/media/css/border-h.gif new file mode 100644 index 0000000..a2aa5b0 Binary files /dev/null and b/share/pnp/media/css/border-h.gif differ diff --git a/share/pnp/media/css/border-v.gif b/share/pnp/media/css/border-v.gif new file mode 100644 index 0000000..4bfd555 Binary files /dev/null and b/share/pnp/media/css/border-v.gif differ diff --git a/share/pnp/media/css/common.css b/share/pnp/media/css/common.css new file mode 100644 index 0000000..c375548 --- /dev/null +++ b/share/pnp/media/css/common.css @@ -0,0 +1,206 @@ +body { + font-family: sans-serif; + font-size: 11px; + margin: 0px; + background-color: #ffffff; + color: #000000; + height: 100%; +} + +table.body { + border-spacing: 0px; +} + +a { + color: #0000cc; +} + +a:hover, a:visited, a:active { + color: #880000; +} + +a.active { color: #88cc00; } + +.gh { + min-height: 150px; +} + + +img.icon { + width: 32px; + height: 32px; +} + +div.graph { + background: url(../images/1x1.gif); +} + +div.right { + width: 260px; + margin-top: 4px; + padding: 4px; +} + +div.left { + padding: 4px 4px 4px 4px; + margin: 4px 4px 4px 0px; +} + +.cb { + clear: both; +} + +.cl { + clear: left; +} + +.cr { + clear: right; +} + +img { + border: none; +} + +input.textbox { + width: 97%; +} + +.b1 { + border: solid #FE880F; + border-width: 1px; +} +.b0 { + border-width: 0px; +} +.w32 { + width: 32%; +} +.w66 { + width: 66%; +} +.w90 { + width: 90%; +} +.w99 { + width: 99%; +} +.w98 { + width: 98%; +} +.w100 { + width: 100%; +} + +.p2 { + padding: 2px; +} +.p4 { + padding: 4px; +} +.multi0 { + padding-left:14px; + background: url(../images/int.gif) no-repeat left; +} +.multi1 { + padding-left:14px; +} +.multi2 { + padding-left:14px; + margin-left:8px; +} +a.active { + background: url(../images/int.gif) no-repeat left; +} +a.inactive { + background: url(../images/int2.gif) no-repeat left; +} +div.header { + margin-top: 2px; + padding: 2px; + background-color: #c5d8d1; +} + +div.pagebody { + display: block; + float: left; + padding: 4px; +} + +div.logo { + padding: 6px; + text-align: center; + vertical-align: center; +} + +ul { + line-height:1.5em; + list-style-type:square; + margin:0 0 0.5em 1.5em; + padding:0; +} + +img.medialeft { + border: 0; + float: left; + margin: 0 1.5em 0 0; +} + +img.mediaright { + border: 0; + float: right; + margin: 0 0 0 1.5em; +} + +h1,h2,h3,h4,h5 { + border-bottom: 1px solid; + clear: left; + margin: 0 0 1em 0; + padding: 0.5em 0 0 0; +} + +/* code blocks by indention */ +pre.code, pre.file { + width: auto !important; + width: 98%; + padding: 0.5em; + border: 1px dashed; + border-left: 3px solid; + overflow: auto; +} + +#basket_items { + list-style-type: none; margin: 0; padding: 0; +} + +#basket_items li { + margin: 0px 2px 2px 2px; height: 16px; +} + +img.ui-datepicker-trigger { + position:relative; + bottom:-6px; +} + +.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } +.ui-timepicker-div dl { text-align: left; } +.ui-timepicker-div dl dt { height: 25px; } +.ui-timepicker-div dl dd { margin: -25px 10px 10px 65px; } +.ui-timepicker-div td { font-size: 90%; } +.ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } + +ul.colorscheme{ + list-style: none; + padding: 2px; + /*margin: 2px auto;*/ +} + +li.colorscheme { + float: left; +} +span.colorscheme { + border: 1px solid #C0C0C0; + display:inline-block; + width: 30px; + height: 30px; +} diff --git a/share/pnp/media/css/images/ajax-loader.png b/share/pnp/media/css/images/ajax-loader.png new file mode 100644 index 0000000..811a2cd Binary files /dev/null and b/share/pnp/media/css/images/ajax-loader.png differ diff --git a/share/pnp/media/css/images/icon-search-black.png b/share/pnp/media/css/images/icon-search-black.png new file mode 100644 index 0000000..5721120 Binary files /dev/null and b/share/pnp/media/css/images/icon-search-black.png differ diff --git a/share/pnp/media/css/images/icons-18-black.png b/share/pnp/media/css/images/icons-18-black.png new file mode 100644 index 0000000..71268bd Binary files /dev/null and b/share/pnp/media/css/images/icons-18-black.png differ diff --git a/share/pnp/media/css/images/icons-18-white.png b/share/pnp/media/css/images/icons-18-white.png new file mode 100644 index 0000000..dadc6af Binary files /dev/null and b/share/pnp/media/css/images/icons-18-white.png differ diff --git a/share/pnp/media/css/images/icons-36-black.png b/share/pnp/media/css/images/icons-36-black.png new file mode 100644 index 0000000..8c35ae3 Binary files /dev/null and b/share/pnp/media/css/images/icons-36-black.png differ diff --git a/share/pnp/media/css/images/icons-36-white.png b/share/pnp/media/css/images/icons-36-white.png new file mode 100644 index 0000000..7e559b8 Binary files /dev/null and b/share/pnp/media/css/images/icons-36-white.png differ diff --git a/share/pnp/media/css/imgareaselect-default.css b/share/pnp/media/css/imgareaselect-default.css new file mode 100644 index 0000000..f4fe341 --- /dev/null +++ b/share/pnp/media/css/imgareaselect-default.css @@ -0,0 +1,41 @@ +/* + * imgAreaSelect default style + */ + +.imgareaselect-border1 { + background: url(border-v.gif) repeat-y left top; +} + +.imgareaselect-border2 { + background: url(border-h.gif) repeat-x left top; +} + +.imgareaselect-border3 { + background: url(border-v.gif) repeat-y right top; +} + +.imgareaselect-border4 { + background: url(border-h.gif) repeat-x left bottom; +} + +.imgareaselect-border1, .imgareaselect-border2, +.imgareaselect-border3, .imgareaselect-border4 { + filter: alpha(opacity=50); + opacity: 0.5; +} + +.imgareaselect-handle { + background-color: #fff; + border: solid 1px #000; + filter: alpha(opacity=50); + opacity: 0.5; +} + +.imgareaselect-outer { + background-color: #000; + filter: alpha(opacity=50); + opacity: 0.5; +} + +.imgareaselect-selection { +} \ No newline at end of file diff --git a/share/pnp/media/css/mobile.css b/share/pnp/media/css/mobile.css new file mode 100644 index 0000000..63f5d07 --- /dev/null +++ b/share/pnp/media/css/mobile.css @@ -0,0 +1,10 @@ +div.timerange { + margin-top: 2px; + padding: 2px; + font-size: 16px; +} +div.datasource { + padding: 2px; + font-size: 14px; +} + diff --git a/share/pnp/media/css/shadow.png b/share/pnp/media/css/shadow.png new file mode 100644 index 0000000..a2561df Binary files /dev/null and b/share/pnp/media/css/shadow.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_flat_0_aaaaaa_40x100.png b/share/pnp/media/css/ui-lightness/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..5b5dab2 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_flat_75_ffffff_40x100.png b/share/pnp/media/css/ui-lightness/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000..ac8b229 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_glass_55_fbf9ee_1x400.png b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000..ad3d634 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_dadada_1x400.png b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000..5a46b47 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_e6e6e6_1x400.png b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000..86c2baa Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_glass_95_fef1ec_1x400.png b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000..4443fdc Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/share/pnp/media/css/ui-lightness/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000..7c9fa6c Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-icons_222222_256x240.png b/share/pnp/media/css/ui-lightness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..ee039dc Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-icons_222222_256x240.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-icons_2e83ff_256x240.png b/share/pnp/media/css/ui-lightness/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000..45e8928 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-icons_2e83ff_256x240.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-icons_454545_256x240.png b/share/pnp/media/css/ui-lightness/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..7ec70d1 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-icons_454545_256x240.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-icons_888888_256x240.png b/share/pnp/media/css/ui-lightness/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000..5ba708c Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-icons_888888_256x240.png differ diff --git a/share/pnp/media/css/ui-lightness/images/ui-icons_cd0a0a_256x240.png b/share/pnp/media/css/ui-lightness/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000..7930a55 Binary files /dev/null and b/share/pnp/media/css/ui-lightness/images/ui-icons_cd0a0a_256x240.png differ diff --git a/share/pnp/media/css/ui-lightness/jquery-ui.css b/share/pnp/media/css/ui-lightness/jquery-ui.css new file mode 100644 index 0000000..ebede8f --- /dev/null +++ b/share/pnp/media/css/ui-lightness/jquery-ui.css @@ -0,0 +1,563 @@ +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/*! + * jQuery UI Resizable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! + * jQuery UI Selectable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/*! + * jQuery UI Accordion 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/*! + * jQuery UI Autocomplete 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.23 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/*! + * jQuery UI Button 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/*! + * jQuery UI Dialog 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/*! + * jQuery UI Slider 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! + * jQuery UI Tabs 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/*! + * jQuery UI Datepicker 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/*! + * jQuery UI Progressbar 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/share/pnp/media/css/ui-multisite/images/contentframe_background.jpg b/share/pnp/media/css/ui-multisite/images/contentframe_background.jpg new file mode 100644 index 0000000..c8f85a1 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/contentframe_background.jpg differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_flat_0_aaaaaa_40x100.png b/share/pnp/media/css/ui-multisite/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100755 index 0000000..5b5dab2 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_flat_75_6da1b8_40x100.png b/share/pnp/media/css/ui-multisite/images/ui-bg_flat_75_6da1b8_40x100.png new file mode 100755 index 0000000..26c1753 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_flat_75_6da1b8_40x100.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_glass_55_fbf9ee_1x400.png b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100755 index 0000000..ad3d634 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_glass_65_88b9ce_1x400.png b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_65_88b9ce_1x400.png new file mode 100755 index 0000000..7e4f13c Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_65_88b9ce_1x400.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_6da1b8_1x400.png b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_6da1b8_1x400.png new file mode 100755 index 0000000..5f6e63e Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_6da1b8_1x400.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_94cde6_1x400.png b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_94cde6_1x400.png new file mode 100755 index 0000000..6615ade Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_glass_75_94cde6_1x400.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_274554_1x100.png b/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_274554_1x100.png new file mode 100755 index 0000000..1514e63 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_274554_1x100.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_6da1b8_1x100.png b/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_6da1b8_1x100.png new file mode 100755 index 0000000..8f1a789 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_highlight-soft_75_6da1b8_1x100.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-bg_inset-soft_95_fef1ec_1x100.png b/share/pnp/media/css/ui-multisite/images/ui-bg_inset-soft_95_fef1ec_1x100.png new file mode 100755 index 0000000..0e05810 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-bg_inset-soft_95_fef1ec_1x100.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-icons_000000_256x240.png b/share/pnp/media/css/ui-multisite/images/ui-icons_000000_256x240.png new file mode 100755 index 0000000..7c211aa Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-icons_000000_256x240.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-icons_222222_256x240.png b/share/pnp/media/css/ui-multisite/images/ui-icons_222222_256x240.png new file mode 100755 index 0000000..b273ff1 Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-icons_222222_256x240.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-icons_2e83ff_256x240.png b/share/pnp/media/css/ui-multisite/images/ui-icons_2e83ff_256x240.png new file mode 100755 index 0000000..09d1cdc Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-icons_2e83ff_256x240.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-icons_454545_256x240.png b/share/pnp/media/css/ui-multisite/images/ui-icons_454545_256x240.png new file mode 100755 index 0000000..59bd45b Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-icons_454545_256x240.png differ diff --git a/share/pnp/media/css/ui-multisite/images/ui-icons_cd0a0a_256x240.png b/share/pnp/media/css/ui-multisite/images/ui-icons_cd0a0a_256x240.png new file mode 100755 index 0000000..2ab019b Binary files /dev/null and b/share/pnp/media/css/ui-multisite/images/ui-icons_cd0a0a_256x240.png differ diff --git a/share/pnp/media/css/ui-multisite/jquery-ui.css b/share/pnp/media/css/ui-multisite/jquery-ui.css new file mode 100644 index 0000000..26c67d6 --- /dev/null +++ b/share/pnp/media/css/ui-multisite/jquery-ui.css @@ -0,0 +1,569 @@ +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +body { + background-attachment:fixed; + background-image:url("images/contentframe_background.jpg"); + background-repeat:repeat; +} + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=6da1b8&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=40697b&fcHeader=fff&iconColorHeader=222222&bgColorContent=6da1b8&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=40697b&fcContent=fff&iconColorContent=222222&bgColorDefault=6da1b8&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=fff&iconColorDefault=000000&bgColorHover=94cde6&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=fff&iconColorHover=454545&bgColorActive=88b9ce&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=40697b&fcActive=fff&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=05_inset_soft.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #40697b; background: #6da1b8 url(images/ui-bg_flat_75_6da1b8_40x100.png) 50% 50% repeat-x; color: #fff; } +.ui-widget-content a { color: #fff; } +.ui-widget-header { border: 1px solid #40697b; background: #6da1b8 url(images/ui-bg_highlight-soft_75_6da1b8_1x100.png) 50% 50% repeat-x; color: #fff; font-weight: bold; } +.ui-widget-header a { color: #fff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #6da1b8 url(images/ui-bg_glass_75_6da1b8_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #fff; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #fff; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #94cde6 url(images/ui-bg_glass_75_94cde6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #fff; } +.ui-state-hover a, .ui-state-hover a:hover { color: #fff; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #40697b; background: #88b9ce url(images/ui-bg_glass_65_88b9ce_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #fff; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #fff; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_inset-soft_95_fef1ec_1x100.png) 50% bottom repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_000000_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! + * jQuery UI Resizable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! + * jQuery UI Selectable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/*! + * jQuery UI Accordion 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/*! + * jQuery UI Autocomplete 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.23 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/*! + * jQuery UI Button 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/*! + * jQuery UI Dialog 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/*! + * jQuery UI Slider 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! + * jQuery UI Tabs 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/*! + * jQuery UI Datepicker 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/*! + * jQuery UI Progressbar 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png b/share/pnp/media/css/ui-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..5b5dab2 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_flat_75_ffffff_40x100.png b/share/pnp/media/css/ui-redmond/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000..ac8b229 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_glass_55_fbf9ee_1x400.png b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000..ad3d634 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_glass_65_ffffff_1x400.png b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_dadada_1x400.png b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000..5a46b47 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_e6e6e6_1x400.png b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000..86c2baa Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_glass_95_fef1ec_1x400.png b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000..4443fdc Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/share/pnp/media/css/ui-redmond/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000..7c9fa6c Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-icons_222222_256x240.png b/share/pnp/media/css/ui-redmond/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..ee039dc Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-icons_222222_256x240.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-icons_2e83ff_256x240.png b/share/pnp/media/css/ui-redmond/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000..45e8928 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-icons_2e83ff_256x240.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-icons_454545_256x240.png b/share/pnp/media/css/ui-redmond/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..7ec70d1 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-icons_454545_256x240.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-icons_888888_256x240.png b/share/pnp/media/css/ui-redmond/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000..5ba708c Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-icons_888888_256x240.png differ diff --git a/share/pnp/media/css/ui-redmond/images/ui-icons_cd0a0a_256x240.png b/share/pnp/media/css/ui-redmond/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000..7930a55 Binary files /dev/null and b/share/pnp/media/css/ui-redmond/images/ui-icons_cd0a0a_256x240.png differ diff --git a/share/pnp/media/css/ui-redmond/jquery-ui.css b/share/pnp/media/css/ui-redmond/jquery-ui.css new file mode 100644 index 0000000..da30a19 --- /dev/null +++ b/share/pnp/media/css/ui-redmond/jquery-ui.css @@ -0,0 +1,563 @@ +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } +.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -khtml-border-top-left-radius: 5px; border-top-left-radius: 5px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -khtml-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -khtml-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; -khtml-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! + * jQuery UI Resizable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! + * jQuery UI Selectable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/*! + * jQuery UI Accordion 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/*! + * jQuery UI Autocomplete 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.23 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/*! + * jQuery UI Button 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/*! + * jQuery UI Dialog 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/*! + * jQuery UI Slider 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! + * jQuery UI Tabs 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/*! + * jQuery UI Datepicker 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/*! + * jQuery UI Progressbar 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..5b5dab2 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000..ac8b229 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000..ad3d634 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_dadada_1x400.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000..5a46b47 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000..86c2baa Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000..4443fdc Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/share/pnp/media/css/ui-smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000..7c9fa6c Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-icons_222222_256x240.png b/share/pnp/media/css/ui-smoothness/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..ee039dc Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-icons_222222_256x240.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-icons_2e83ff_256x240.png b/share/pnp/media/css/ui-smoothness/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000..45e8928 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-icons_2e83ff_256x240.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-icons_454545_256x240.png b/share/pnp/media/css/ui-smoothness/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..7ec70d1 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-icons_454545_256x240.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-icons_888888_256x240.png b/share/pnp/media/css/ui-smoothness/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000..5ba708c Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-icons_888888_256x240.png differ diff --git a/share/pnp/media/css/ui-smoothness/images/ui-icons_cd0a0a_256x240.png b/share/pnp/media/css/ui-smoothness/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000..7930a55 Binary files /dev/null and b/share/pnp/media/css/ui-smoothness/images/ui-icons_cd0a0a_256x240.png differ diff --git a/share/pnp/media/css/ui-smoothness/jquery-ui.css b/share/pnp/media/css/ui-smoothness/jquery-ui.css new file mode 100644 index 0000000..8230384 --- /dev/null +++ b/share/pnp/media/css/ui-smoothness/jquery-ui.css @@ -0,0 +1,563 @@ +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! + * jQuery UI Resizable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/*! + * jQuery UI Selectable 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/*! + * jQuery UI Accordion 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/*! + * jQuery UI Autocomplete 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.23 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/*! + * jQuery UI Button 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/*! + * jQuery UI Dialog 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/*! + * jQuery UI Slider 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/*! + * jQuery UI Tabs 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/*! + * jQuery UI Datepicker 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/*! + * jQuery UI Progressbar 1.8.23 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/share/pnp/media/images/1x1.gif b/share/pnp/media/images/1x1.gif new file mode 100644 index 0000000..f191b28 Binary files /dev/null and b/share/pnp/media/images/1x1.gif differ diff --git a/share/pnp/media/images/add.png b/share/pnp/media/images/add.png new file mode 100644 index 0000000..ade93b9 Binary files /dev/null and b/share/pnp/media/images/add.png differ diff --git a/share/pnp/media/images/back.png b/share/pnp/media/images/back.png new file mode 100644 index 0000000..d0456c0 Binary files /dev/null and b/share/pnp/media/images/back.png differ diff --git a/share/pnp/media/images/calendar.png b/share/pnp/media/images/calendar.png new file mode 100644 index 0000000..22c391f Binary files /dev/null and b/share/pnp/media/images/calendar.png differ diff --git a/share/pnp/media/images/color.png b/share/pnp/media/images/color.png new file mode 100644 index 0000000..c879975 Binary files /dev/null and b/share/pnp/media/images/color.png differ diff --git a/share/pnp/media/images/de_DE.png b/share/pnp/media/images/de_DE.png new file mode 100755 index 0000000..bf04e92 Binary files /dev/null and b/share/pnp/media/images/de_DE.png differ diff --git a/share/pnp/media/images/docs.png b/share/pnp/media/images/docs.png new file mode 100755 index 0000000..c69c6c4 Binary files /dev/null and b/share/pnp/media/images/docs.png differ diff --git a/share/pnp/media/images/en_US.png b/share/pnp/media/images/en_US.png new file mode 100755 index 0000000..767835b Binary files /dev/null and b/share/pnp/media/images/en_US.png differ diff --git a/share/pnp/media/images/favicon.ico b/share/pnp/media/images/favicon.ico new file mode 100644 index 0000000..721b0a0 Binary files /dev/null and b/share/pnp/media/images/favicon.ico differ diff --git a/share/pnp/media/images/go-left.png b/share/pnp/media/images/go-left.png new file mode 100644 index 0000000..9d39e33 Binary files /dev/null and b/share/pnp/media/images/go-left.png differ diff --git a/share/pnp/media/images/go-now.png b/share/pnp/media/images/go-now.png new file mode 100644 index 0000000..91c21df Binary files /dev/null and b/share/pnp/media/images/go-now.png differ diff --git a/share/pnp/media/images/go-right.png b/share/pnp/media/images/go-right.png new file mode 100644 index 0000000..fa609a7 Binary files /dev/null and b/share/pnp/media/images/go-right.png differ diff --git a/share/pnp/media/images/graph.png b/share/pnp/media/images/graph.png new file mode 100644 index 0000000..d009c19 Binary files /dev/null and b/share/pnp/media/images/graph.png differ diff --git a/share/pnp/media/images/home.png b/share/pnp/media/images/home.png new file mode 100755 index 0000000..0a5f1fc Binary files /dev/null and b/share/pnp/media/images/home.png differ diff --git a/share/pnp/media/images/int.gif b/share/pnp/media/images/int.gif new file mode 100644 index 0000000..061dfd1 Binary files /dev/null and b/share/pnp/media/images/int.gif differ diff --git a/share/pnp/media/images/int2.gif b/share/pnp/media/images/int2.gif new file mode 100644 index 0000000..f7315a6 Binary files /dev/null and b/share/pnp/media/images/int2.gif differ diff --git a/share/pnp/media/images/loader.gif b/share/pnp/media/images/loader.gif new file mode 100644 index 0000000..8186b0c Binary files /dev/null and b/share/pnp/media/images/loader.gif differ diff --git a/share/pnp/media/images/notify.gif b/share/pnp/media/images/notify.gif new file mode 100644 index 0000000..17f0b0b Binary files /dev/null and b/share/pnp/media/images/notify.gif differ diff --git a/share/pnp/media/images/pages.png b/share/pnp/media/images/pages.png new file mode 100644 index 0000000..3761e47 Binary files /dev/null and b/share/pnp/media/images/pages.png differ diff --git a/share/pnp/media/images/pdf.png b/share/pnp/media/images/pdf.png new file mode 100644 index 0000000..560840b Binary files /dev/null and b/share/pnp/media/images/pdf.png differ diff --git a/share/pnp/media/images/pnp.png b/share/pnp/media/images/pnp.png new file mode 100644 index 0000000..711deaa Binary files /dev/null and b/share/pnp/media/images/pnp.png differ diff --git a/share/pnp/media/images/remove.png b/share/pnp/media/images/remove.png new file mode 100644 index 0000000..47f4ef3 Binary files /dev/null and b/share/pnp/media/images/remove.png differ diff --git a/share/pnp/media/images/rrdtool.png b/share/pnp/media/images/rrdtool.png new file mode 100644 index 0000000..bd05dac Binary files /dev/null and b/share/pnp/media/images/rrdtool.png differ diff --git a/share/pnp/media/images/special.png b/share/pnp/media/images/special.png new file mode 100755 index 0000000..962e9cc Binary files /dev/null and b/share/pnp/media/images/special.png differ diff --git a/share/pnp/media/images/stats.png b/share/pnp/media/images/stats.png new file mode 100644 index 0000000..cf4f5ef Binary files /dev/null and b/share/pnp/media/images/stats.png differ diff --git a/share/pnp/media/images/trends.gif b/share/pnp/media/images/trends.gif new file mode 100644 index 0000000..29943d2 Binary files /dev/null and b/share/pnp/media/images/trends.gif differ diff --git a/share/pnp/media/images/view-calendar.png b/share/pnp/media/images/view-calendar.png new file mode 100644 index 0000000..18c78c7 Binary files /dev/null and b/share/pnp/media/images/view-calendar.png differ diff --git a/share/pnp/media/images/xml.png b/share/pnp/media/images/xml.png new file mode 100644 index 0000000..b6db627 Binary files /dev/null and b/share/pnp/media/images/xml.png differ diff --git a/share/pnp/media/images/zoom.png b/share/pnp/media/images/zoom.png new file mode 100644 index 0000000..d2b139c Binary files /dev/null and b/share/pnp/media/images/zoom.png differ diff --git a/share/pnp/media/js/jquery-ui-timepicker-addon.js b/share/pnp/media/js/jquery-ui-timepicker-addon.js new file mode 100644 index 0000000..ca506d5 --- /dev/null +++ b/share/pnp/media/js/jquery-ui-timepicker-addon.js @@ -0,0 +1,1276 @@ +/* +* jQuery timepicker addon +* By: Trent Richardson [http://trentrichardson.com] +* Version 0.9.7 +* Last Modified: 10/02/2011 +* +* Copyright 2011 Trent Richardson +* Dual licensed under the MIT and GPL licenses. +* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt +* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt +* +* HERES THE CSS: +* .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } +* .ui-timepicker-div dl { text-align: left; } +* .ui-timepicker-div dl dt { height: 25px; } +* .ui-timepicker-div dl dd { margin: -25px 10px 10px 65px; } +* .ui-timepicker-div td { font-size: 90%; } +* .ui-tpicker-grid-label { background: none; border: none; margin: 0; padding: 0; } +*/ + +(function($) { + +$.extend($.ui, { timepicker: { version: "0.9.7" } }); + +/* Time picker manager. + Use the singleton instance of this class, $.timepicker, to interact with the time picker. + Settings for (groups of) time pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Timepicker() { + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + currentText: 'Now', + closeText: 'Done', + ampm: false, + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'hh:mm tt', + timeSuffix: '', + timeOnlyTitle: 'Choose Time', + timeText: 'Time', + hourText: 'Hour', + minuteText: 'Minute', + secondText: 'Second', + millisecText: 'Millisecond', + timezoneText: 'Time Zone' + }; + this._defaults = { // Global defaults for all the datetime picker instances + showButtonPanel: true, + timeOnly: false, + showHour: true, + showMinute: true, + showSecond: false, + showMillisec: false, + showTimezone: false, + showTime: true, + stepHour: 0.05, + stepMinute: 0.05, + stepSecond: 0.05, + stepMillisec: 0.5, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: '+0000', + hourMin: 0, + minuteMin: 0, + secondMin: 0, + millisecMin: 0, + hourMax: 23, + minuteMax: 59, + secondMax: 59, + millisecMax: 999, + minDateTime: null, + maxDateTime: null, + onSelect: null, + hourGrid: 0, + minuteGrid: 0, + secondGrid: 0, + millisecGrid: 0, + alwaysSetTime: true, + separator: ' ', + altFieldTimeOnly: true, + showTimepicker: true, + timezoneIso8609: false, + timezoneList: null + }; + $.extend(this._defaults, this.regional['']); +} + +$.extend(Timepicker.prototype, { + $input: null, + $altInput: null, + $timeObj: null, + inst: null, + hour_slider: null, + minute_slider: null, + second_slider: null, + millisec_slider: null, + timezone_select: null, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: '+0000', + hourMinOriginal: null, + minuteMinOriginal: null, + secondMinOriginal: null, + millisecMinOriginal: null, + hourMaxOriginal: null, + minuteMaxOriginal: null, + secondMaxOriginal: null, + millisecMaxOriginal: null, + ampm: '', + formattedDate: '', + formattedTime: '', + formattedDateTime: '', + timezoneList: null, + + /* Override the default settings for all instances of the time picker. + @param settings object - the new settings to use as defaults (anonymous object) + @return the manager object */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + //######################################################################## + // Create a new Timepicker instance + //######################################################################## + _newInst: function($input, o) { + var tp_inst = new Timepicker(), + inlineSettings = {}; + + for (var attrName in this._defaults) { + var attrValue = $input.attr('time:' + attrName); + if (attrValue) { + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, { + beforeShow: function(input, dp_inst) { + if ($.isFunction(o.beforeShow)) + o.beforeShow(input, dp_inst, tp_inst); + }, + onChangeMonthYear: function(year, month, dp_inst) { + // Update the time as well : this prevents the time from disappearing from the $input field. + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(o.onChangeMonthYear)) + o.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); + }, + onClose: function(dateText, dp_inst) { + if (tp_inst.timeDefined === true && $input.val() != '') + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(o.onClose)) + o.onClose.call($input[0], dateText, dp_inst, tp_inst); + }, + timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); + }); + tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { return val.toUpperCase() }); + tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { return val.toUpperCase() }); + + if (tp_inst._defaults.timezoneList === null) { + var timezoneList = []; + for (var i = -11; i <= 12; i++) + timezoneList.push((i >= 0 ? '+' : '-') + ('0' + Math.abs(i).toString()).slice(-2) + '00'); + if (tp_inst._defaults.timezoneIso8609) + timezoneList = $.map(timezoneList, function(val) { + return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); + }); + tp_inst._defaults.timezoneList = timezoneList; + } + + tp_inst.hour = tp_inst._defaults.hour; + tp_inst.minute = tp_inst._defaults.minute; + tp_inst.second = tp_inst._defaults.second; + tp_inst.millisec = tp_inst._defaults.millisec; + tp_inst.ampm = ''; + tp_inst.$input = $input; + + if (o.altField) + tp_inst.$altInput = $(o.altField) + .css({ cursor: 'pointer' }) + .focus(function(){ $input.trigger("focus"); }); + + if(tp_inst._defaults.minDate==0 || tp_inst._defaults.minDateTime==0) + { + tp_inst._defaults.minDate=new Date(); + } + if(tp_inst._defaults.maxDate==0 || tp_inst._defaults.maxDateTime==0) + { + tp_inst._defaults.maxDate=new Date(); + } + + // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. + if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) + tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); + if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) + tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); + if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) + tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); + if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) + tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); + return tp_inst; + }, + + //######################################################################## + // add our sliders to the calendar + //######################################################################## + _addTimePicker: function(dp_inst) { + var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? + this.$input.val() + ' ' + this.$altInput.val() : + this.$input.val(); + + this.timeDefined = this._parseTime(currDT); + this._limitMinMaxDateTime(dp_inst, false); + this._injectTimePicker(); + }, + + //######################################################################## + // parse the time string from input value or _setTime + //######################################################################## + _parseTime: function(timeString, withDate) { + var regstr = this._defaults.timeFormat.toString() + .replace(/h{1,2}/ig, '(\\d?\\d)') + .replace(/m{1,2}/ig, '(\\d?\\d)') + .replace(/s{1,2}/ig, '(\\d?\\d)') + .replace(/l{1}/ig, '(\\d?\\d?\\d)') + .replace(/t{1,2}/ig, this._getPatternAmpm()) + .replace(/z{1}/ig, '(z|[-+]\\d\\d:?\\d\\d)?') + .replace(/\s/g, '\\s?') + this._defaults.timeSuffix + '$', + order = this._getFormatPositions(), + ampm = '', + treg; + + if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]); + + if (withDate || !this._defaults.timeOnly) { + // the time should come after x number of characters and a space. + // x = at least the length of text specified by the date format + var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); + // escape special regex characters in the seperator + var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); + regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator.replace(specials, "\\$&") + regstr; + } + + treg = timeString.match(new RegExp(regstr, 'i')); + + if (treg) { + if (order.t !== -1) { + if (treg[order.t] === undefined || treg[order.t].length === 0) { + ampm = ''; + this.ampm = ''; + } else { + ampm = $.inArray(treg[order.t].toUpperCase(), this.amNames) !== -1 ? 'AM' : 'PM'; + this.ampm = this._defaults[ampm == 'AM' ? 'amNames' : 'pmNames'][0]; + } + } + + if (order.h !== -1) { + if (ampm == 'AM' && treg[order.h] == '12') + this.hour = 0; // 12am = 0 hour + else if (ampm == 'PM' && treg[order.h] != '12') + this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12 + else this.hour = Number(treg[order.h]); + } + + if (order.m !== -1) this.minute = Number(treg[order.m]); + if (order.s !== -1) this.second = Number(treg[order.s]); + if (order.l !== -1) this.millisec = Number(treg[order.l]); + if (order.z !== -1 && treg[order.z] !== undefined) { + var tz = treg[order.z].toUpperCase(); + switch (tz.length) { + case 1: // Z + tz = this._defaults.timezoneIso8609 ? 'Z' : '+0000'; + break; + case 5: // +hhmm + if (this._defaults.timezoneIso8609) + tz = tz.substring(1) == '0000' + ? 'Z' + : tz.substring(0, 3) + ':' + tz.substring(3); + break; + case 6: // +hh:mm + if (!this._defaults.timezoneIso8609) + tz = tz == 'Z' || tz.substring(1) == '00:00' + ? '+0000' + : tz.replace(/:/, ''); + else if (tz.substring(1) == '00:00') + tz = 'Z'; + break; + } + this.timezone = tz; + } + + return true; + + } + return false; + }, + + //######################################################################## + // pattern for standard and localized AM/PM markers + //######################################################################## + _getPatternAmpm: function() { + var markers = []; + o = this._defaults; + if (o.amNames) + $.merge(markers, o.amNames); + if (o.pmNames) + $.merge(markers, o.pmNames); + markers = $.map(markers, function(val) { return val.replace(/[.*+?|()\[\]{}\\]/g, '\\$&') }); + return '(' + markers.join('|') + ')?'; + }, + + //######################################################################## + // figure out position of time elements.. cause js cant do named captures + //######################################################################## + _getFormatPositions: function() { + var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|l{1}|t{1,2}|z)/g), + orders = { h: -1, m: -1, s: -1, l: -1, t: -1, z: -1 }; + + if (finds) + for (var i = 0; i < finds.length; i++) + if (orders[finds[i].toString().charAt(0)] == -1) + orders[finds[i].toString().charAt(0)] = i + 1; + + return orders; + }, + + //######################################################################## + // generate and inject html for timepicker into ui datepicker + //######################################################################## + _injectTimePicker: function() { + var $dp = this.inst.dpDiv, + o = this._defaults, + tp_inst = this, + // Added by Peter Medeiros: + // - Figure out what the hour/minute/second max should be based on the step values. + // - Example: if stepMinute is 15, then minMax is 45. + hourMax = (o.hourMax - ((o.hourMax - o.hourMin) % o.stepHour)).toFixed(0), + minMax = (o.minuteMax - ((o.minuteMax - o.minuteMin) % o.stepMinute)).toFixed(0), + secMax = (o.secondMax - ((o.secondMax - o.secondMin) % o.stepSecond)).toFixed(0), + millisecMax = (o.millisecMax - ((o.millisecMax - o.millisecMin) % o.stepMillisec)).toFixed(0), + dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, ''); + + // Prevent displaying twice + //if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) { + if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) { + var noDisplay = ' style="display:none;"', + html = '
    ' + + '
    ' + o.timeText + '
    ' + + '
    ' + + '
    ' + o.hourText + '
    ', + hourGridSize = 0, + minuteGridSize = 0, + secondGridSize = 0, + millisecGridSize = 0, + size; + + // Hours + if (o.showHour && o.hourGrid > 0) { + html += '
    ' + + '
    ' + + '
    '; + + for (var h = o.hourMin; h <= hourMax; h += parseInt(o.hourGrid,10)) { + hourGridSize++; + var tmph = (o.ampm && h > 12) ? h-12 : h; + if (tmph < 10) tmph = '0' + tmph; + if (o.ampm) { + if (h == 0) tmph = 12 +'a'; + else if (h < 12) tmph += 'a'; + else tmph += 'p'; + } + html += ''; + } + + html += '
    ' + tmph + '
    ' + + '
    '; + } else html += '
    '; + + html += '
    ' + o.minuteText + '
    '; + + // Minutes + if (o.showMinute && o.minuteGrid > 0) { + html += '
    ' + + '
    ' + + '
    '; + + for (var m = o.minuteMin; m <= minMax; m += parseInt(o.minuteGrid,10)) { + minuteGridSize++; + html += ''; + } + + html += '
    ' + ((m < 10) ? '0' : '') + m + '
    ' + + '
    '; + } else html += '
    '; + + // Seconds + html += '
    ' + o.secondText + '
    '; + + if (o.showSecond && o.secondGrid > 0) { + html += '
    ' + + '
    ' + + '
    '; + + for (var s = o.secondMin; s <= secMax; s += parseInt(o.secondGrid,10)) { + secondGridSize++; + html += ''; + } + + html += '
    ' + ((s < 10) ? '0' : '') + s + '
    ' + + '
    '; + } else html += '
    '; + + // Milliseconds + html += '
    ' + o.millisecText + '
    '; + + if (o.showMillisec && o.millisecGrid > 0) { + html += '
    ' + + '
    ' + + '
    '; + + for (var l = o.millisecMin; l <= millisecMax; l += parseInt(o.millisecGrid,10)) { + millisecGridSize++; + html += ''; + } + + html += '
    ' + ((l < 10) ? '0' : '') + s + '
    ' + + '
    '; + } else html += '
    '; + + // Timezone + html += '
    ' + o.timezoneText + '
    '; + html += '
    '; + + html += '
    '; + $tp = $(html); + + // if we only want time picker... + if (o.timeOnly === true) { + $tp.prepend( + '
    ' + + '
    ' + o.timeOnlyTitle + '
    ' + + '
    '); + $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); + } + + this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({ + orientation: "horizontal", + value: this.hour, + min: o.hourMin, + max: hourMax, + step: o.stepHour, + slide: function(event, ui) { + tp_inst.hour_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + // Updated by Peter Medeiros: + // - Pass in Event and UI instance into slide function + this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({ + orientation: "horizontal", + value: this.minute, + min: o.minuteMin, + max: minMax, + step: o.stepMinute, + slide: function(event, ui) { + // update the global minute slider instance value with the current slider value + tp_inst.minute_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({ + orientation: "horizontal", + value: this.second, + min: o.secondMin, + max: secMax, + step: o.stepSecond, + slide: function(event, ui) { + tp_inst.second_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.millisec_slider = $tp.find('#ui_tpicker_millisec_'+ dp_id).slider({ + orientation: "horizontal", + value: this.millisec, + min: o.millisecMin, + max: millisecMax, + step: o.stepMillisec, + slide: function(event, ui) { + tp_inst.millisec_slider.slider( "option", "value", ui.value); + tp_inst._onTimeChange(); + } + }); + + this.timezone_select = $tp.find('#ui_tpicker_timezone_'+ dp_id).append('').find("select"); + $.fn.append.apply(this.timezone_select, + $.map(o.timezoneList, function(val, idx) { + return $("