pax_global_header00006660000000000000000000000064141561603550014520gustar00rootroot0000000000000052 comment=770066b4e4fa3d29334a7fad9d1a9280f35f2bf7 powerman-2.3.27/000077500000000000000000000000001415616035500134435ustar00rootroot00000000000000powerman-2.3.27/.github/000077500000000000000000000000001415616035500150035ustar00rootroot00000000000000powerman-2.3.27/.github/workflows/000077500000000000000000000000001415616035500170405ustar00rootroot00000000000000powerman-2.3.27/.github/workflows/main.yml000066400000000000000000000021051415616035500205050ustar00rootroot00000000000000name: ci on: [ pull_request, push ] jobs: build: runs-on: ${{matrix.os}} strategy: matrix: cc: [gcc, clang] os: [ubuntu-latest, ubuntu-18.04] steps: - uses: actions/checkout@v2 - name: Install dependencies run: | sudo apt-get update sudo apt-get install -y \ libsnmp-dev \ libwrap0-dev \ libcurl4-gnutls-dev \ libgenders0-dev \ libjansson-dev \ automake \ autoconf \ pkg-config \ ${{matrix.cc}} - name: Display configuration run: | echo "C compiler:" ${CC} --version env: CC: ${{matrix.cc}} - name: autogen run: ./autogen.sh - name: configure run: | ./configure \ --with-genders \ --with-snmppower \ --with-httppower \ --with-redfishpower \ --with-tcp-wrappers - name: make run: make - name: make check run: make check - name: make distcheck run: make distcheck powerman-2.3.27/.gitignore000066400000000000000000000013671415616035500154420ustar00rootroot00000000000000# http://www.gnu.org/software/automake Makefile.in # http://www.gnu.org/software/autoconf autom4te.cache compile configure aclocal.m4 stamp-h1 aclocal.m4 config.guess config.sub depcomp install-sh ltmain.sh missing ylwrap config.log config.status config.h config.h.in libtool .deps/ .libs/ # Object files *.o *.ko *.obj *.elf # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # autoconf-preprocessed Makefile *.1 *.3 *.5 *.8 *.spec *.pc *.diff *.swp *.tar.gz # Project specific build products plmpower/plmpower powerman/pm powerman/powerman powermand/parse_lex.c powermand/parse_tab.c powermand/parse_tab.h powermand/powermand scripts/powerman test/vpcd powerman-2.3.27/COPYING000066400000000000000000000431311415616035500145000ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. powerman-2.3.27/DISCLAIMER000066400000000000000000000045701415616035500150100ustar00rootroot00000000000000Copyright (C) 2001 The Regents of the University of California. Produced at Lawrence Livermore National Laboratory. Written by Andrew Uselton (uselton2@llnl.gov>. UCRL-CODE-2002-008. This file is part of PowerMan, a remote power management program. For details, see . PowerMan 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. PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. This work was produced at the University of California, Lawrence Livermore National Laboratory (UC LLNL) under contract no. W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy (DOE) and The Regents of the University of California (University) for the operation of UC LLNL. The rights of the Federal Government are reserved under Contract 48 subject to the restrictions agreed upon by the DOE and University as allowed under DOE Acquisition Letter 97-1. DISCLAIMER This work was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the University of California nor any of their employees, makes any warranty, express or implied, or assumes any liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately-owned rights. Reference herein to any specific commercial products, process, or service by trade name, trademark, manufacturer or otherwise does not necessarily constitute or imply its endorsement, recommendation, or favoring by the United States Government or the University of California. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or the University of California, and shall not be used for advertising or product endorsement purposes. powerman-2.3.27/Makefile.am000066400000000000000000000011351415616035500154770ustar00rootroot00000000000000SUBDIRS = \ etc \ man \ scripts \ heartbeat \ liblsd \ libcommon \ powerman \ powermand \ libpowerman \ plmpower \ test if WITH_HTTPPOWER SUBDIRS += httppower endif if WITH_SNMPPOWER SUBDIRS += snmppower endif if WITH_REDFISHPOWER SUBDIRS += redfishpower endif # Create run dir for powerman. Chown will fail if non root - ignore it. install-data-local: -$(top_srcdir)/config/install-sh -m 755 -d \ $(DESTDIR)$(localstatedir)/run -$(top_srcdir)/config/install-sh -o $(RUN_AS_USER) -m 755 -d \ $(DESTDIR)$(localstatedir)/run/powerman EXTRA_DIST = DISCLAIMER examples/powerman_el72.spec powerman-2.3.27/NEWS000066400000000000000000000422611415616035500141470ustar00rootroot00000000000000========================================================================= Release Notes for PowerMan version 2.3.27 14 Dec 2021 ========================================================================= * Add redfish support for Cray r272z30, Cray windom, and Supermicro H12DSG-O-CPU (#55, #47) * CI: Enable github workflow (#59, #58, #57, #56) * Misc fixes (#54, #52, #50, #46) ========================================================================= Release Notes for PowerMan version 2.3.26 18 Feb 2020 ========================================================================= * Log power state changes to syslog (Olaf Faaland, PR #37) * Fix default systemd unit file path for 'make distcheck' ========================================================================= Release Notes for PowerMan version 2.3.25 28 Jan 2019 ========================================================================= * Add etc/rancid-cisco-poe.dev (Daniel Rich, PR #28) * Add etc/openbmc.dev (Albert Chu, PR #33) * Add etc/kvm.dev & etc/kvm-ssh.dev (tisbeok, PR #8) * Fix misinterpretation of error strings in ipmipower.dev. ========================================================================= Release Notes for PowerMan version 2.3.24 23 Oct 2015 ========================================================================= * Don't pacakge /var/run/powerman; let systemd manage it [TOSS-2987] * Cleanup: drop trailing whitespace ========================================================================= Release Notes for PowerMan version 2.3.23 08 Jun 2015 ========================================================================= * Build: silence CC lines, fix AC_LANG_CONFTEST warnings, fix $(EXEEXT) warnings. * Build: install System V init scripts if --with-systemdsystemunitdir is not configured and include both in EXTRA_DIST. * Build: re-enable 'make check' unit tests. * Build: fix some 'make distcheck' issues, but until unit tests are fixed to find *.exp and *.conf files in $(srcdir), this will still fail. * RPM: configure genders, httppower, snmppower, and tcp-wrappers unconditionally; update URL. ========================================================================= Release Notes for PowerMan version 2.3.22 01 Jun 2015 ========================================================================= * Assorted build system fixes to allow 'make distcheck' and Koji builds on RHEL 7 to work. * Note: unit tests temporarily disabled pending rework. [This release was not distributed as it was incomplete for RHEL 7/Koji] ========================================================================= Release Notes for PowerMan version 2.3.21 29 May 2015 ========================================================================= * Added systemd unit file (bacaldwell, gc issue #42) SystemVinit script support is dropped. * Build against -lnetsnmp not -lsnmp (TOSS-2815) * Add raritan-px5523.dev (Daryl Granau, TOSS-2486) ========================================================================= Release Notes for PowerMan version 2.3.20 26 Aug 2014 ========================================================================= * add dist tag to release (TOSS-2667) * Minor automake updates ========================================================================= Release Notes for PowerMan version 2.3.19 25 Aug 2014 ========================================================================= * Added apc8941.dev (TOSS-2658, Tim Randles) ========================================================================= Release Notes for PowerMan version 2.3.18 21 Aug 2014 ========================================================================= * Stop tracking autotools products * Add README.md for github move ========================================================================= Release Notes for PowerMan version 2.3.17 27 Mar 2013 ========================================================================= * Fix powerman-stonith script to handle aliased plugs and add regression testing for it (TOSS-1962) ========================================================================= Release Notes for PowerMan version 2.3.16 04 Oct 2012 ========================================================================= * Fix duplicate node name (issue 35) Pulled in another hostlist fix (Mark Grondona) * Fix powerman stonith OFF should verify plug state (chaos bz 1439) ========================================================================= Release Notes for PowerMan version 2.3.15 05 Sep 2012 ========================================================================= * Added ipmipower-serial.dev [Al Chu] ========================================================================= Release Notes for PowerMan version 2.3.14 10 Aug 2012 ========================================================================= * Fix issue 34: duplicate node name in configuration file Updated hostlist code to the latest which fixes this issue. ========================================================================= Release Notes for PowerMan version 2.3.13 20 Jun 2012 ========================================================================= * Updated appro-gb2.dev per Appro * Add suport for Baytech RPC22 (Olof Johansson) ========================================================================= Release Notes for PowerMan version 2.3.12 13 Jan 2012 ========================================================================= * Add support for Raritan px4316 (chaos bz 1276) * Add support for DLI web power switches III and IV [Gaylord Holder] * Add --single-cmd option to plmpower (issue 7) [Ira Weiny] * Minor documentation updates ========================================================================= Release Notes for PowerMan version 2.3.11 01 Sep 2011 ========================================================================= * Update appro-gb2.dev (chaos bug 1218) * Fix BuildRequires for tcp_wrappers-devel to work on el6/ch5. Packagers: now you must add --with-tcp-wrappers on configure line to enable this feature (before it was enabled if libs were present) * Re-autogen to pull in (new?) bison build dependency on el6/ch5. * Fix --with-feature options to fail if prereqs are missing, not just silently disable the feature. * Fix line number accounting during parse error reporting (issue 3) ========================================================================= Release Notes for PowerMan version 2.3.10 19 Aug 2011 ========================================================================= * Updated appro-greenblade.dev (chaos bug 1218) * Added appro-gb2.dev (chaos bug 1218) * Added sentry_cdu.dev (chaos bug 1218) * Added baytech-rpc18d-nc (issue 5) ========================================================================= Release Notes for PowerMan version 2.3.9 25 Feb 2011 ========================================================================= * Add MIB support to snmppower. * Add eaton-epdu-blue-switched.dev [Paul Anderson]. ========================================================================= Release Notes for PowerMan version 2.3.8 24 Feb 2011 ========================================================================= * Add support for SNMP power controllers via 'snmppower' helper. * Add SNMP dev files for 8-port APC, 8-port Baytech, and 20 port Eaton Revelation PDU. ========================================================================= Release Notes for PowerMan version 2.3.7 04 Nov 2010 ========================================================================= * Add support for APC 7900 revision 3 firmware [Py Watson] * Internal automake cleanup. ========================================================================= Release Notes for PowerMan version 2.3.6 12 Aug 2010 ========================================================================= * Convert several internal buffers from static to dynamic to address overflow in query output [chaos bugzilla 1009] * Add support for Appro Greenblade [Trent D'Hooge]. * Add support for APC 7920 [Manfred Gruber]. * Add Support for ranged beacon on/off device scripts, and beacon support for ipmipower [Al Chu]. ========================================================================= Release Notes for PowerMan version 2.3.5 17 Apr 2009 ========================================================================= * Deprecated undocumented powerman.conf port directive. * Added powerman.conf listen directive to configure which interfaces and ports the server listens on. Make the default localhost:10101. * Add support for HP integrated power control devices [Bjorn Helgaas] * Add support for Sun LOM. * Misc. documentation improvements * Add heartbeat STONITH plugin. ========================================================================= Release Notes for PowerMan version 2.3.4 09 Feb 2009 ========================================================================= * Fix powerman-controlling-powerman config so that status command is fast for large configs again. * Fix "bashfun" device script and add regression test. * Various changes coming from Debian audit [Arnaud Quette]. ========================================================================= Release Notes for PowerMan version 2.3.1 01 Dec 2008 ========================================================================= * Initial powerman client API. * Run the powerman daemon (and all coprocesses) as 'daemon' by default instead of root. To override, set USER=root or other user in /etc/sysconfig/powerman. * New man pages for httppower, plmpower, libpowerman, vpcd. * Include vpcd in the dist. * Various changes coming from Debian audit [Arnaud Quette]. ========================================================================= Release Notes for PowerMan version 2.3 12 Nov 2008 ========================================================================= * Make init script work on Solaris. * IPv6 support. * Include example powerman.conf file (/etc/powerman/powerman.conf.example) * Added support for Cyclades PM20, PM42. ========================================================================= Release Notes for PowerMan version 2.2 27 Aug 2008 ========================================================================= * Send a SIGINT to coprocesses rather than just closing file descriptors during powermand shutdown. This is required to terminate an ssh client running in coprocess mode. * Make it possible to only define the _ranged version of scripts. Scripts are selected using the following precedence: _all, _ranged, singlet. * Drop "soft power status" support. This allowed iceboxes to detect whether a node was powered up or not, independently of plug state. * [ipmipower] Drop _all and singlet version of scripts. * [ilom] Revised Sun Integrated Lights Out Management support to work over ssh and serial. Dropped shared console/serial "ilom-inline" support. * [icebox3] Now supports both v3 and v4 Ice Box. Users of icebox4 should change their device types to icebox3 in powerman.conf. * [plmpower] Added support for controlling Insteon/X10 devices via SmartLabs PLM 2412S. * [hp3488] Added support for modular GPIB-based HP 3488A switch/control unit via gpib-utils project. * [ics8064] Added support for VXI-11-based ICS 8064 16-port relay unit via gpib-utils project. * [powerman] Improved efficiency of powerman-controlling-powerman configurations, when one powerman controls a subset of the plugs of another powerman through the use of _ranged scripts. * Enhanced integrated test suite. Note: tests all pass on AIX now. ========================================================================= Release Notes for PowerMan version 2.1 18 Jun 2008 ========================================================================= * Client overhaul. * [apcpdu3] Fix intermittent query failures. * Fixed off by one bug in server that allowed some delays in dev scripts to take longer than programmed. * Use raw mode in pipe (|&) connections to avoid local tty echo. * Run server in /var/run/powerman rather than /etc/powerman. Create this directory if it doesn't exist. * Enhanced integrated test suite. Note: all tests do not currently pass on AIX. ========================================================================= Release Notes for PowerMan version 2.0 01 Jun 2008 ========================================================================= * Autoconf/automake integration. * Integrated test suite. * Portability to Solaris, AIX, and OS/X. * Support for selecting power control targets using genders (-g option). * Cleanup and refactoring. ========================================================================= Release Notes for PowerMan version 1.0.32 24 Jan 2008 ========================================================================= * Support for new apc firmware (apcpdu3.dev) [Trent D'Hooge] * Added httppower utility for interfacing to power controllers that are exclusively web-based. * Support for Digital Loggers, Inc. power controllers. * Support for APPRO power controller. ========================================================================= Release Notes for PowerMan version 1.0.31 20 Oct 2007 ========================================================================= (Includes changes in 1.0.29 and 1.0.30) * Support SUN ILOM inline with serial console, i.e. device "ilom25" "ilom-inline" "/usr/bin/conman -Q -j ilc25 |&" * Handle config files with embedded carriage returns [Trent D'Hooge and Todd Heer]. * Ipmipower device script tuning [Al Chu]. * Minor build/packaging tweaks for building under mock, etc. ========================================================================= Release Notes for PowerMan version 1.0.28 07 May 2007 ========================================================================= * Increase "cycle" delays from 2s to 4s on all devices that implement cycle as an explicit on,delay,off. ========================================================================= Release Notes for PowerMan version 1.0.27 24 Apr 2007 ========================================================================= * Add heartbeat stonith module. * Fix bug in baytech-rpc28-nc device support that affected plugs > 10. ========================================================================= Release Notes for PowerMan version 1.0.26 21 Dec 2006 ========================================================================= * Support 8-port APC AP7900 and likely AP7901, AP7920, and AP7921. [Martin Petersen] * Work around a bug that causes baytech rpc3's to resturn some plugs as status "unknown" on login timeout/reconnect. * Add ranged power control support for faster power control w/ ipmipower. ========================================================================= Release Notes for PowerMan version 1.0.25 16 Aug 2006 ========================================================================= * Support newer baytech RPC-3 firmware. * Support icebox v4 [Jarod Wilson] ========================================================================= Release Notes for PowerMan version 1.0.24 30 May 2006 ========================================================================= * Telnet state machine now works with Digi terminal server in telnet mode and logs ignored telnet option requests. * Several powerman.conf examples are now included in the RPM doc area. * Handle expansion of suffixed host ranges, e.g. "[00-26]p" [Mark Grondona] * Fix minor memory leaks and unchecked function return values found by Coverity. * New powerman.dev(5) man page documenting device file syntax. * Support serial device baud rates up to 460800 baud if system does. * Minor tweaks to spec file for Fedora Extras [Ben Woodard]. * Fix for broken P0|P1 in Rackable Phantom 4.0 firmware (phantom4.dev). * Add support for IBM BladeCenter chassis (ibmbladecenter.dev) [Robin Goldstone]. * Add support for ComputerBoards CB7050 (cb-7050.dev). * Add support for Cyclades PM10 (cyclades-pm10.dev) [Trent D'Hooge]. ========================================================================= Release Notes for PowerMan version 1.0.23 16 Feb 2006 ========================================================================= * Fix for compilation on Fedora Core 4 [Ben Woodard]. * Spec file changes for Fedora Extras submission [Ben Woodard]. ========================================================================= PowerMan version 1.0.22 12 Oct 2005 ========================================================================= * Bug fix for powerman -T dumps core on x86_64 [Thayne Harbaugh] * Add support for 24-port APC Switched Rack PDU (apcpdu.dev) [Makia Minnich]. powerman-2.3.27/README.md000066400000000000000000000021251415616035500147220ustar00rootroot00000000000000*powerman* is free UNIX/Linux software that controls (remotely and in parallel) switched power distribution units. It was designed for remote power control of Linux systems in a data center or cluster environment, but has been used in other environments such as embedded management appliances, home automation, and high availability service management. *powerman* can be extended to support new devices using an expect-like scripting language. It communicates with devices natively using telnet, raw socket, and serial protocols. It also can drive virtual power control devices via a coprocess interface. The coprocess mechanism has been used to extend *powerman* to communicate with devices using other protocols such as SNMP, IPMI, Insteon, X-10, and VXI-11. *powerman* can control equipment connected using any combination of the above methods and provide unified naming for the equipment and parallel execution of control actions. #### Origin and license Originally written by Andrew Uselton in 2002 for early Linux clusters at LLNL. SPDX-License-Identifier: GPL-2.0-or-later UCRL-CODE-2002-008 powerman-2.3.27/autogen.sh000077500000000000000000000005511415616035500154450ustar00rootroot00000000000000#!/bin/sh echo "Running aclocal ... " aclocal -I config echo "Running libtoolize ... " libtoolize --force --automake --copy echo "Running autoheader ... " autoheader echo "Running automake ... " automake --copy --add-missing echo "Running autoconf ... " autoconf echo "Cleaning up ..." mv aclocal.m4 config/ rm -rf autom4te.cache echo "Now run ./configure." powerman-2.3.27/config/000077500000000000000000000000001415616035500147105ustar00rootroot00000000000000powerman-2.3.27/config/ac_forkpty.m4000066400000000000000000000020221415616035500173070ustar00rootroot00000000000000##***************************************************************************** ## $Id: ac_forkpty.m4,v 1.1.1.1 2003/09/05 16:05:42 achu Exp $ ##***************************************************************************** # AUTHOR: # Albert Chu # # SYNOPSIS: # AC_FORKPTY # # DESCRIPTION: # Check for forkpty # # WARNINGS: # This macro must be placed after AC_PROG_CC or equivalent. ##***************************************************************************** AC_DEFUN([AC_FORKPTY], [ AC_CHECK_FUNC([forkpty], [ac_have_forkpty=yes], [ac_have_forkpty=no]) if test "$ac_have_forkpty" = "no"; then AC_CHECK_LIB([util], [forkpty], [LIBFORKPTY=-lutil], AC_CHECK_LIB([bsd], [forkpty], [LIBFORKPTY=-lbsd])) if test -n "$LIBFORKPTY"; then ac_have_forkpty=yes else ac_have_forkpty=no fi fi if test "$ac_have_forkpty" = "yes"; then AC_DEFINE([HAVE_FORKPTY], [1], [Define if you have forkpty]) AC_CHECK_HEADERS( pty.h util.h ) fi AC_SUBST(LIBFORKPTY) ]) powerman-2.3.27/config/ac_genders.m4000066400000000000000000000014261415616035500172470ustar00rootroot00000000000000# # Add --with-genders configure option (no by default). # If yes, not finding header file or lib is fatal. # Define WITH_GENDERS=1, HAVE_GENDERS_H=1, and HAVE_LIBGENDERS=1 in config.h. # Substitute LIBGENDERS with -lgenders in Makefiles. # AC_DEFUN([AC_GENDERS], [ AC_ARG_WITH([genders], AC_HELP_STRING([--with-genders], [Build genders support for client])) AS_IF([test "x$with_genders" = "xyes"], [ AC_CHECK_HEADERS([genders.h]) X_AC_CHECK_COND_LIB([genders], [genders_handle_create]) AC_DEFINE(WITH_GENDERS, 1, [Define if building genders support for client]) ]) AS_IF([test "x$with_genders" = "xyes" && test "x$ac_cv_header_genders_h" = "xno" -o "x$ac_cv_lib_genders_genders_handle_create" = "xno"], [ AC_MSG_ERROR([could not find genders library]) ]) ]) powerman-2.3.27/config/ac_httppower.m4000066400000000000000000000014151415616035500176520ustar00rootroot00000000000000# # Add --with-httppower configure option (no by default). # If yes, not finding curl header file or lib is fatal. # Define HAVE_CURL_CURL_H=1, and HAVE_LIBCURL=1 in config.h. # Substitute LIBCURL with -lcurl and define WITH_HTTPPOWER=1 in Makefiles. # # AC_DEFUN([AC_HTTPPOWER], [ AC_ARG_WITH([httppower], AC_HELP_STRING([--with-httppower], [Build httppower executable])) AS_IF([test "x$with_httppower" = "xyes"], [ AC_CHECK_HEADERS([curl/curl.h]) X_AC_CHECK_COND_LIB([curl], [curl_easy_setopt]) ]) AS_IF([test "x$with_httppower" = "xyes" && test "x$ac_cv_header_curl_curl_h" = "xno" -o "x$ac_cv_lib_curl_curl_easy_setopt" = "xno"], [ AC_MSG_ERROR([could not find curl library]) ]) AM_CONDITIONAL(WITH_HTTPPOWER, [test "x$with_httppower" = "xyes"]) ]) powerman-2.3.27/config/ac_pkgconfig.m4000066400000000000000000000013761415616035500175730ustar00rootroot00000000000000# Thanks to Arnaud Quette for this bit of m4 AC_DEFUN([AC_PKGCONFIG], [ pkgconfigdir='${libdir}/pkgconfig' AC_MSG_CHECKING(whether to install pkg-config *.pc files) AC_ARG_WITH(pkgconfig-dir, AC_HELP_STRING([--with-pkgconfig-dir=PATH], [where to install pkg-config *.pc files (EPREFIX/lib/pkgconfig)]), [ case "${withval}" in yes|auto) ;; no) pkgconfigdir="" ;; *) pkgconfigdir="${withval}" ;; esac ], ) if test -n "${pkgconfigdir}"; then AC_MSG_RESULT(${pkgconfigdir}) else AC_MSG_RESULT(no) fi AM_CONDITIONAL(WITH_PKG_CONFIG, test -n "${pkgconfigdir}") AC_SUBST(pkgconfigdir) ]) powerman-2.3.27/config/ac_redfishpower.m4000066400000000000000000000017661415616035500203300ustar00rootroot00000000000000# # Add --with-redfishpower configure option (no by default). # If yes, not finding curl or jansson is fatal. # AC_DEFUN([AC_REDFISHPOWER], [ AC_ARG_WITH([redfishpower], AC_HELP_STRING([--with-redfishpower], [Build redfishpower executable])) AS_IF([test "x$with_redfishpower" = "xyes"], [ AC_CHECK_HEADERS([curl/curl.h]) X_AC_CHECK_COND_LIB([curl], [curl_multi_perform]) AC_CHECK_HEADERS([jansson.h]) X_AC_CHECK_COND_LIB([jansson], [json_object]) ]) AS_IF([test "x$with_redfishpower" = "xyes" \ && test "x$ac_cv_header_curl_curl_h" = "xno" \ -o "x$ac_cv_lib_curl_curl_multi_perform" = "xno"], [ AC_MSG_ERROR([could not find curl library]) ]) AS_IF([test "x$with_redfishpower" = "xyes" \ && test "x$ac_cv_header_jansson_h" = "xno" \ -o "x$ac_cv_lib_curl_json_object_set" = "xno"], [ AC_MSG_ERROR([could not find jansson library]) ]) AM_CONDITIONAL(WITH_REDFISHPOWER, [test "x$with_redfishpower" = "xyes"]) ]) powerman-2.3.27/config/ac_runas.m4000066400000000000000000000010141415616035500167410ustar00rootroot00000000000000AC_DEFUN([AC_RUNAS], [ RUN_AS_USER="daemon" AC_MSG_CHECKING(user to run as) AC_ARG_WITH(user, AC_HELP_STRING([--with-user=username], [user for powerman daemon (daemon)]), [ case "${withval}" in yes|no) ;; *) RUN_AS_USER="${withval}" ;; esac], ) AC_DEFINE_UNQUOTED(RUN_AS_USER, "${RUN_AS_USER}", [Powerman daemon user]) AC_MSG_RESULT(${RUN_AS_USER}) AC_SUBST(RUN_AS_USER) ]) powerman-2.3.27/config/ac_snmppower.m4000066400000000000000000000014601415616035500176500ustar00rootroot00000000000000# # Add --with-snmppower configure option (no by default). # If yes, not finding netsnmp header file or lib is fatal. # Define HAVE_NET_SNMP_NET_SNMP_CONFIG_H=1 and HAVE_LIBSNMP=1 in config.h. # Substitute LIBSNMP with -lsnmp and define WITH_SNMPPOWER=1 in Makefiles. # AC_DEFUN([AC_SNMPPOWER], [ AC_ARG_WITH([snmppower], AC_HELP_STRING([--with-snmppower], [Build snmppower executable])) AS_IF([test "x$with_snmppower" = "xyes"], [ AC_CHECK_HEADERS([net-snmp/net-snmp-config.h]) X_AC_CHECK_COND_LIB([netsnmp], [init_snmp]) ]) AS_IF([test "x$with_snmppower" = "xyes" && test "x$ac_cv_header_net_snmp_net_snmp_config_h" = "xno" -o "x$ac_cv_lib_snmp_init_snmp" = "xno"], [ AC_MSG_ERROR([could not find snmp library]) ]) AM_CONDITIONAL(WITH_SNMPPOWER, [test "x$with_snmppower" = "xyes"]) ]) powerman-2.3.27/config/ac_wrap.m4000066400000000000000000000014161415616035500165700ustar00rootroot00000000000000# # Add --with-tcp-wrappers configure option (no by default). # If yes, not finding tcpd.h header file or libwrap is fatal. # Define HAVE_TCP_WRAPPERS=1, HAVE_TCP_H=1, and HAVE_LIBWRAP=1 in config.h. # Substitute LIBWRAP with -lwrap in Makefiles. # AC_DEFUN([AC_WRAP], [ AC_ARG_WITH([tcp-wrappers], AC_HELP_STRING([--with-tcp-wrappers], [Build with tcp wrappers support])) AS_IF([test "x$with_tcp_wrappers" = "xyes"], [ AC_CHECK_HEADERS([tcpd.h]) X_AC_CHECK_COND_LIB([wrap], [hosts_ctl]) AC_DEFINE(HAVE_TCP_WRAPPERS, 1, [Define if building tcp wrappers support]) ]) AS_IF([test "x$with_tcp_wrappers" = "xyes" && test "x$ac_cv_header_tcpd_h" = "xno" -o "x$ac_cv_lib_wrap_hosts_ctl" = "xno"], [ AC_MSG_ERROR([could not find tcp wrappers library]) ]) ]) powerman-2.3.27/config/systemd.m4000066400000000000000000000043451415616035500166500ustar00rootroot00000000000000dnl Probe for systemd libraries and installation paths. dnl dnl Provides the RRA_WITH_SYSTEMD_UNITDIR macro, which adds the dnl --with-systemdsystemunitdir configure flag, sets the systemdsystemunitdir dnl substitution variable, and provides the HAVE_SYSTEMD Automake conditional dnl to use to control whether to install unit files. dnl dnl Provides the RRA_LIB_SYSTEMD_DAEMON_OPTIONAL macro, which sets dnl SYSTEMD_CFLAGS and SYSTEMD_LIBS substitution variables if dnl libsystemd-daemon is available and defines HAVE_SD_NOTIFY. pkg-config dnl support for libsystemd-daemon is required for it to be detected. dnl dnl Depends on the Autoconf macros that come with pkg-config. dnl dnl The canonical version of this file is maintained in the rra-c-util dnl package, available at . dnl dnl Written by Russ Allbery dnl Copyright 2013, 2014 dnl The Board of Trustees of the Leland Stanford Junior University dnl dnl This file is free software; the authors give unlimited permission to copy dnl and/or distribute it, with or without modifications, as long as this dnl notice is preserved. dnl Determine the systemd system unit directory, along with a configure flag dnl to override, and sets @systemdsystemunitdir@. Provides the Automake dnl HAVE_SYSTEMD Automake conditional. AC_DEFUN([RRA_WITH_SYSTEMD_UNITDIR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) AS_IF([test x"$PKG_CONFIG" = x], [PKG_CONFIG=false]) AC_ARG_WITH([systemdsystemunitdir], [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])], [], [with_systemdsystemunitdir=\${prefix}$($PKG_CONFIG --variable=systemdsystemunitdir systemd)]) AS_IF([test x"$with_systemdsystemunitdir" != xno], [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])]) AM_CONDITIONAL([HAVE_SYSTEMD], [test -n "$with_systemdsystemunitdir" -a x"$with_systemdsystemunitdir" != xno])]) dnl Check for libsystemd-daemon and define SYSTEMD_DAEMON_{CFLAGS,LIBS} if it dnl is available. AC_DEFUN([RRA_LIB_SYSTEMD_DAEMON_OPTIONAL], [PKG_CHECK_EXISTS([libsystemd-daemon], [PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon]) AC_DEFINE([HAVE_SD_NOTIFY], 1, [Define if sd_notify is available.])])]) powerman-2.3.27/config/x_ac_check_cond_lib.m4000066400000000000000000000031241415616035500210520ustar00rootroot00000000000000##***************************************************************************** ## $Id: x_ac_check_cond_lib.m4 391 2005-02-10 02:31:11Z dun $ ##***************************************************************************** # AUTHOR: # Chris Dunlap # # SYNOPSIS: # X_AC_CHECK_COND_LIB(library, function) # # DESCRIPTION: # Check whether a program can be linked with to get . # Like AC_CHECK_LIB(), except that if the check succeeds, HAVE_LIB # will be defined and a shell variable LIB containing "-l" # will be substituted via AC_SUBST(). # # In other words, this is just like the default action of AC_CHECK_LIB(), # except that instead of modifying LIBS (which will affect the linking of # all executables), the shell variable LIB is defined so it can be # added to the linking of just those executables needing this library. # Also note that this checks to see if the library is even needed at all. ##***************************************************************************** AC_DEFUN([X_AC_CHECK_COND_LIB], [ AC_CACHE_CHECK( [for $2 in default libs], [x_ac_cv_lib_none_$2], [ AC_LINK_IFELSE( [AC_LANG_CALL([], [$2])], AS_VAR_SET(x_ac_cv_lib_none_$2, yes), AS_VAR_SET(x_ac_cv_lib_none_$2, no) )] ) AS_IF([test AS_VAR_GET(x_ac_cv_lib_none_$2) = no], AC_CHECK_LIB( [$1], [$2], [ AH_CHECK_LIB([$1]) AS_TR_CPP([LIB$1])="-l$1"; AC_SUBST(AS_TR_CPP([LIB$1])) AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_LIB$1])) ] ) )] ) powerman-2.3.27/config/x_ac_expand_install_dirs.m4000066400000000000000000000063721415616035500222020ustar00rootroot00000000000000##***************************************************************************** ## $Id: x_ac_expand_install_dirs.m4 494 2006-05-08 22:59:28Z dun $ ##***************************************************************************** # AUTHOR: # Chris Dunlap # # SYNOPSIS: # X_AC_EXPAND_INSTALL_DIRS # # DESCRIPTION: # Expand the installation directory variables. ##***************************************************************************** AC_DEFUN([X_AC_EXPAND_INSTALL_DIRS], [ AC_MSG_CHECKING([installation directory variables]) _x_ac_expand_install_dirs_prefix="$prefix" test "$prefix" = NONE && prefix="$ac_default_prefix" _x_ac_expand_install_dirs_exec_prefix="$exec_prefix" test "$exec_prefix" = NONE && exec_prefix="$prefix" eval X_PREFIX="$prefix" AC_DEFINE_UNQUOTED([X_PREFIX], ["$X_PREFIX"], [Expansion of the "prefix" installation directory.]) AC_SUBST([X_PREFIX]) eval X_EXEC_PREFIX="$exec_prefix" AC_DEFINE_UNQUOTED([X_EXEC_PREFIX], ["$X_EXEC_PREFIX"], [Expansion of the "exec_prefix" installation directory.]) AC_SUBST([X_EXEC_PREFIX]) eval X_BINDIR="$bindir" AC_DEFINE_UNQUOTED([X_BINDIR], ["$X_BINDIR"], [Expansion of the "bindir" installation directory.]) AC_SUBST([X_BINDIR]) eval X_SBINDIR="$sbindir" AC_DEFINE_UNQUOTED([X_SBINDIR], ["$X_SBINDIR"], [Expansion of the "sbindir" installation directory.]) AC_SUBST([X_SBINDIR]) eval X_LIBEXECDIR="$libexecdir" AC_DEFINE_UNQUOTED([X_LIBEXECDIR], ["$X_LIBEXECDIR"], [Expansion of the "libexecdir" installation directory.]) AC_SUBST([X_LIBEXECDIR]) eval X_DATADIR="$datadir" AC_DEFINE_UNQUOTED([X_DATADIR], ["$X_DATADIR"], [Expansion of the "datadir" installation directory.]) AC_SUBST([X_DATADIR]) eval X_SYSCONFDIR="$sysconfdir" AC_DEFINE_UNQUOTED([X_SYSCONFDIR], ["$X_SYSCONFDIR"], [Expansion of the "sysconfdir" installation directory.]) AC_SUBST([X_SYSCONFDIR]) eval X_SHAREDSTATEDIR="$sharedstatedir" AC_DEFINE_UNQUOTED([X_SHAREDSTATEDIR], ["$X_SHAREDSTATEDIR"], [Expansion of the "sharedstatedir" installation directory.]) AC_SUBST([X_SHAREDSTATEDIR]) eval X_LOCALSTATEDIR="$localstatedir" AC_DEFINE_UNQUOTED([X_LOCALSTATEDIR], ["$X_LOCALSTATEDIR"], [Expansion of the "localstatedir" installation directory.]) AC_SUBST([X_LOCALSTATEDIR]) eval X_LIBDIR="$libdir" AC_DEFINE_UNQUOTED([X_LIBDIR], ["$X_LIBDIR"], [Expansion of the "libdir" installation directory.]) AC_SUBST([X_LIBDIR]) eval X_INCLUDEDIR="$includedir" AC_DEFINE_UNQUOTED([X_INCLUDEDIR], ["$X_INCLUDEDIR"], [Expansion of the "includedir" installation directory.]) AC_SUBST([X_INCLUDEDIR]) eval X_OLDINCLUDEDIR="$oldincludedir" AC_DEFINE_UNQUOTED([X_OLDINCLUDEDIR], ["$X_OLDINCLUDEDIR"], [Expansion of the "oldincludedir" installation directory.]) AC_SUBST([X_OLDINCLUDEDIR]) eval X_INFODIR="$infodir" AC_DEFINE_UNQUOTED([X_INFODIR], ["$X_INFODIR"], [Expansion of the "infodir" installation directory.]) AC_SUBST([X_INFODIR]) eval X_MANDIR="$mandir" AC_DEFINE_UNQUOTED([X_MANDIR], ["$X_MANDIR"], [Expansion of the "mandir" installation directory.]) AC_SUBST([X_MANDIR]) prefix="$_x_ac_expand_install_dirs_prefix" exec_prefix="$_x_ac_expand_install_dirs_exec_prefix" AC_MSG_RESULT([yes]) ]) powerman-2.3.27/configure.ac000066400000000000000000000062201415616035500157310ustar00rootroot00000000000000## # Prologue. ## AC_INIT([powerman], m4_esyscmd([git describe --always | awk '/.*/ {printf "%s",$1; exit}'])) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_SRCDIR([NEWS]) AC_CANONICAL_SYSTEM X_AC_EXPAND_INSTALL_DIRS ## # Automake support. ## AM_INIT_AUTOMAKE([subdir-objects foreign]) AM_SILENT_RULES([yes]) AM_CONFIG_HEADER([config/config.h]) AM_MAINTAINER_MODE ## # Checks for programs. ## AC_PROG_CC if test "$GCC" = yes; then #GCCWARN="-Wall -Werror" GCCWARN="-Wall" AC_SUBST([GCCWARN]) fi AC_PROG_LN_S AC_PROG_MAKE_SET AM_PROG_LEX AC_PROG_YACC AC_PROG_LIBTOOL AM_CONDITIONAL(WITH_GNU_LD, test "$with_gnu_ld" = "yes") ## # ## AC_CHECK_FILES(/dev/ptmx) AC_CHECK_FILES(/dev/ptc) ## # Checks for header files. ## AC_HEADER_STDC AC_CHECK_HEADERS( \ getopt.h \ poll.h \ sys/select.h \ sys/syscall.h \ ) ## # Checks for typedefs, structures, and compiler characteristics. ## AC_C_BIGENDIAN AC_TYPE_UID_T AC_C_CONST AC_CHECK_TYPES(socklen_t, [], [], [#include ]) ## # Check for httppower, genders ## AC_HTTPPOWER AC_REDFISHPOWER AC_SNMPPOWER AC_GENDERS ## # Check for systemd ## RRA_WITH_SYSTEMD_UNITDIR ## # Checks for library functions. ## AC_CHECK_FUNCS( \ getopt_long \ cfmakeraw ) AC_SEARCH_LIBS([bind],[socket]) AC_SEARCH_LIBS([gethostbyaddr],[nsl]) AC_FORKPTY AC_WRAP AC_CHECK_FUNC([poll], AC_DEFINE([HAVE_POLL], [1], [Define if you have poll])) # for list.c, cbuf.c, hostlist.c, and wrappers.c */ AC_DEFINE(WITH_LSD_FATAL_ERROR_FUNC, 1, [Define lsd_fatal_error]) AC_DEFINE(WITH_LSD_NOMEM_ERROR_FUNC, 1, [Define lsd_fatal_error]) # whether to install pkg-config file for API AC_PKGCONFIG # what user to run daemon as AC_RUNAS ## # Epilogue. ## AC_CONFIG_FILES( \ Makefile \ examples/powerman_el72.spec \ libpowerman/Makefile \ libpowerman/libpowerman.pc \ liblsd/Makefile \ libcommon/Makefile \ powerman/Makefile \ powermand/Makefile \ httppower/Makefile \ redfishpower/Makefile \ snmppower/Makefile \ plmpower/Makefile \ etc/Makefile \ scripts/Makefile \ scripts/powerman \ scripts/tmpfiles.d/powerman.conf \ heartbeat/Makefile \ man/Makefile \ man/powerman.1 \ man/libpowerman.3 \ man/powerman.conf.5 \ man/powerman.dev.5 \ man/httppower.8 \ man/redfishpower.8 \ man/plmpower.8 \ man/powermand.8 \ man/vpcd.8 \ test/Makefile \ test/mcr.conf test/sierra.conf \ test/t07.conf \ test/t09.conf \ test/t10.conf \ test/t17.conf \ test/t18.conf \ test/t19.conf \ test/t20.conf \ test/t21.conf \ test/t22.conf \ test/t23.conf \ test/t24.conf \ test/t25.conf \ test/t26.conf \ test/t27.conf \ test/t28.conf \ test/t29.conf \ test/t30.conf \ test/t31.conf \ test/t32.conf \ test/t33.conf \ test/t34.conf \ test/t35.conf \ test/t36.conf \ test/t37.conf \ test/t38.conf \ test/t39.conf \ test/t40.conf \ test/t41.conf \ test/t42.conf \ test/t43.conf \ test/t44.conf \ test/t46.conf \ test/t47.conf \ test/t48.conf \ test/t49.conf \ test/t50.conf \ test/t51.conf \ test/t53.conf \ test/t54.conf \ test/t55.conf \ test/t60.conf \ test/t61.conf \ test/t62.conf \ test/t63.conf \ test/test.conf \ test/test4.conf \ ) AC_OUTPUT powerman-2.3.27/etc/000077500000000000000000000000001415616035500142165ustar00rootroot00000000000000powerman-2.3.27/etc/Makefile.am000066400000000000000000000022661415616035500162600ustar00rootroot00000000000000pkgsysconfdir = $(sysconfdir)/powerman pkgsysconf_DATA = \ powerman.conf.example \ apc7900.dev \ apc7900v3.dev \ apc7920.dev \ apc8941.dev \ apc.dev \ apc-snmp.dev \ apcnew.dev \ apcold.dev \ apcpdu3.dev \ apcpdu.dev \ appro-greenblade.dev \ appro-gb2.dev \ bashfun.dev \ baytech.dev \ baytech-snmp.dev \ baytech-rpc18d-nc.dev \ baytech-rpc22.dev \ baytech-rpc28-nc.dev \ baytech-rpc3-nc.dev \ cb-7050.dev \ cyclades-pm8.dev \ cyclades-pm10.dev \ cyclades-pm20.dev \ cyclades-pm42.dev \ dli.dev \ dli4.dev \ eaton-revelation-snmp.dev \ eaton-epdu-blue-switched.dev \ hp3488.dev \ hpilo.dev \ hpmp.dev \ hpmpblade.dev \ hpmpcell.dev \ hpmpdome.dev \ ibmbladecenter.dev \ icebox.dev \ icebox3.dev \ ics8064.dev \ ilom.dev \ lom.dev \ ipmi.dev \ ipmipower.dev \ ipmipower-serial.dev \ kvm.dev \ kvm-ssh.dev \ openbmc.dev \ redfish-supermicro.dev \ redfishpower-cray-r272z30.dev \ redfishpower-supermicro.dev \ redfishpower-cray-windom.dev \ phantom.dev \ plmpower.dev \ powerman.dev \ rancid-cisco-poe.dev \ raritan-px4316.dev \ raritan-px5523.dev \ sentry_cdu.dev \ swpdu.dev \ vpc.dev \ wti.dev \ wti-rps10.dev EXTRA_DIST = $(pkgsysconf_DATA) powerman-2.3.27/etc/apc-snmp.dev000066400000000000000000000034671415616035500164460ustar00rootroot00000000000000# APC Masterswitch Plus via SNMP (also can drive with apcnew.dev) # Seems to require snmp v1 # Tricky: write 1 for on, 2 for off specification "apc-snmp" { timeout 10 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "snmppower> " send "start_v1 private\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } # PowerNet-MIB::sPDUMasterState.0 script status_all { send "get enterprises.318.1.1.4.2.2.0\n" expect "enterprises.318.1.1.4.2.2.0: (On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]+(On|Off)[[:space:]]*\n" setplugstate "1" $1 off="Off" on="On" setplugstate "2" $2 off="Off" on="On" setplugstate "3" $3 off="Off" on="On" setplugstate "4" $4 off="Off" on="On" setplugstate "5" $5 off="Off" on="On" setplugstate "6" $6 off="Off" on="On" setplugstate "7" $7 off="Off" on="On" setplugstate "8" $8 off="Off" on="On" } # PowerNet-MIB::sPDUOutletControl.sPDUOutletControlTable. # sPDUOutletControlEntry.sPDUOutletCtl. script on { send "set enterprises.318.1.1.4.4.2.1.3.%s i 1\n" expect "enterprises.318.1.1.4.4.2.1.3.[1-8]: 1\n" expect "snmppower> " } script off { send "set enterprises.318.1.1.4.4.2.1.3.%s i 2\n" expect "enterprises.318.1.1.4.4.2.1.3.[1-8]: 2\n" expect "snmppower> " } script cycle { send "set enterprises.318.1.1.4.4.2.1.3.%s i 2\n" expect "enterprises.318.1.1.4.4.2.1.3.[1-8]: 2\n" expect "snmppower> " delay 5 send "set enterprises.318.1.1.4.4.2.1.3.%s i 1\n" expect "enterprises.318.1.1.4.4.2.1.3.[1-8]: 1\n" expect "snmppower> " } } powerman-2.3.27/etc/apc.dev000066400000000000000000000101371415616035500154630ustar00rootroot00000000000000# # $Id$ # # APC MasterSwitch Plus # # Firmware rev may not be the best indicator of whether you need "apc" # or "apcnew" scripts. We have one data point for "apc": # # - Firmware: APP v2.0.0 / AOS v2.5.4 # specification "apc" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\n" expect "User Name : " send "apc\r\n" expect "Password : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " send "1\r\n" # select master switch plus 1 expect "> " } script logout { send "4\r\n" } script status_all { send "\r\n" # refresh foreachplug { expect "([0-9]+)-[^\n]*(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script on_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "3\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "3\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "3\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script cycle_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "3\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Success\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } } powerman-2.3.27/etc/apc7900.dev000066400000000000000000000074401415616035500160060ustar00rootroot00000000000000# # $Id:$ # # Written by Martin K. Petersen # Based upon apcpdc.dev by Trent D'Hooge and Makia Minich # # APC MasterSwitch AP7900 (and most likely AP7901, AP7920 & AP7921) # - Firmware: APP v2.7.3 / AOS v2.7.0 # specification "apc7900" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\rUser Name : " send "apc\r\n" expect "\rPassword : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " send "3\r\n" # outlet control/configuration expect "> " } script logout { send "\033" expect "> " send "\033" expect "> " send "4\r\n" } script status_all { send "\r\n" # refresh foreachplug { expect "([0-9]+)-[^\n]*(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select control outlet expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script on_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script off_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" } script cycle_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } } powerman-2.3.27/etc/apc7900v3.dev000066400000000000000000000074311415616035500162570ustar00rootroot00000000000000# # APC MasterSwitch AP7900 (and most likely AP7901, AP7920 & AP7921) # - Firmware: APP v3.7.0 / AOS v3.7.0 # # Firmware version 3 changes contributed by Py Watson. # specification "apc7900v3" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\rUser Name : " send "apc\r\n" expect "\rPassword : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " send "2\r\n" # outlet management expect "> " send "1\r\n" # Outlet Control/Configuration expect "> " } script logout { send "\033" expect "> " send "\033" expect "> " send "4\r\n" } script status_all { send "\r\n" # refresh foreachplug { expect "([0-9]+)-[^\n]*(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select control outlet expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script on_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } script off_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" } script cycle_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" send "\r\n" expect "> " } } powerman-2.3.27/etc/apc7920.dev000066400000000000000000000032521415616035500160050ustar00rootroot00000000000000# # $Id:$ # Written by Manfred Gruber # # Based upon apc7900.dev by Martin K. Petersen # Based upon apcpdc.dev by Trent D'Hooge and Makia Minich # # APC MasterSwitch AP7920 # - Firmware: APP v3.3.3 / AOS v3.3.4 # specification "apc7920" { timeout 3 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\rUser Name : " send "apc\r\n" expect "\rPassword : " send "apc\r\n" expect "> " } script logout { send "\033" expect "> " send "\033" expect "> " send "4\r\n" } script on { send "1\r\n" # device manager menu expect "> " send "2\r\n" # Outlet Management expect "> " send "1\r\n" # outlet control/configuration expect "> " send "%s\r\n" # Nr Outlet X expect "> " send "1\r\n" # select control outlet expect "> " send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\r\n" expect "> " } script off { send "1\r\n" # device manager menu expect "> " send "2\r\n" # Outlet Management expect "> " send "1\r\n" # outlet control/configuration expect "> " send "%s\r\n" # Nr Outlet X expect "> " send "1\r\n" # select control outlet expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\033" expect "> " send "\r\n" expect "> " } } powerman-2.3.27/etc/apc8941.dev000066400000000000000000000032201415616035500160040ustar00rootroot00000000000000# # Derived from apcpdu3.dev, but updated for new firmware # # - Firmware: rpdu2g v6.0.9 / AOS v6.1.3 # specification "apc8941" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" } script login { expect "snmppower> " send "start_v2c private\n" expect "snmppower> " } script logout { send "finish" expect "snmppower> " } script status { send "get enterprises.318.1.1.26.9.2.3.1.5.%s\n" expect "enterprises.318.1.1.26.9.2.3.1.5.([0-9]+): (1|2)" setplugstate $1 $2 on="2" off="1" expect "snmppower>" } script on { send "set enterprises.318.1.1.26.9.2.4.1.5.%s i 1\n" expect "enterprises.318.1.1.26.9.2.4.1.5.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } script off { send "set enterprises.318.1.1.26.9.2.4.1.5.%s i 2\n" expect "enterprises.318.1.1.26.9.2.4.1.5.[0-9]+: 2\n" expect "snmppower> " } script cycle { send "set enterprises.318.1.1.26.9.2.4.1.5.%s i 2\n" expect "enterprises.318.1.1.26.9.2.4.1.5.[0-9]+: 2\n" expect "snmppower> " delay 5 send "set enterprises.318.1.1.26.9.2.4.1.5.%s i 1\n" expect "enterprises.318.1.1.26.9.2.4.1.5.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } } powerman-2.3.27/etc/apcnew.dev000066400000000000000000000066701415616035500162040ustar00rootroot00000000000000# # $Id$ # # APC MasterSwitch Plus # # Firmware rev may not be the best indicator of whether you need "apc" # or "apcnew" scripts. We have two data points for "apcnew": # # - Firmware: APP v2.2.0 / AOS v3.0.3 # - Firmware: APP v2.0.2 / AOS v2.5.3 # specification "apcnew" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\n" expect "User Name : " send "apc\r\n" expect "Password : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " } script logout { send "\033\r\n" } script status_all { send "\r\n" # refresh foreachplug { expect "([0-9]+)-[^\n]*(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script on_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script cycle_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "8\r\n" # cancel any pending delays expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "Command successfully issued.\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } } powerman-2.3.27/etc/apcold.dev000066400000000000000000000066641415616035500161740ustar00rootroot00000000000000# # $Id:$ # # apparently there is an apc interface older than "apc.dev" # # This talks to: # # Model Number : AP9210 Serial Number : WA9903036579 # Firmware Revision : v1.1.1 Hardware Revision : C4 # Manufacture Date : 01/14/1999 # # specification "apcold" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\n" expect "User Name : " send "apc\r\n" expect "Password : " send "apc\r\n" expect "> " send "1\r\n" # outlet manager menu expect "> " } script logout { send "\033" # ESC back to control console menu expect "> " send "4\r\n" } script status_all { send "9\r\n" # master/pdu control expect "> " send "1\r\n" # control of master pdu foreachplug { expect "([1-8]+):(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " send "\033" # ESC back to master/pdu expect "> " send "\033" # ESC back to outlet manager menu expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" # ESC back to outlet expect "> " send "\033" # ESC back to outlet manager expect "> " } script on_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script off_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } script cycle_all { send "9\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "2\r\n" # immediate off expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "Enter 'YES' to continue or to cancel : " send "YES\r\n" expect "successfully!\r\n" send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "> " } } powerman-2.3.27/etc/apcpdu.dev000066400000000000000000000104511415616035500161730ustar00rootroot00000000000000# # $Id:$ # # Written by Trent D'Hooge and Makia Minich # # Should support the following 24-plug APC Switched Rack PDU models: # AP7930, AP7932 # AP7940, AP7941 # AP7960, AP7961, AP7968, AP7990, AP7991, AP7998 # AP7951, AP7952, AP7953, AP7954 # # - Firmware: APP v2.6.5 / AOS v2.6.4 # specification "apcpdu" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" } script login { expect "\n" expect "\rUser Name : " send "apc\r\n" expect "\rPassword : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " send "3\r\n" # outlet control/configuration expect "to continue..." send "\r\n" expect "> " } script logout { send "\033" expect "> " send "\033" expect "> " send "4\r\n" } script status_all { send "\r\n" # refresh send "\r\n" # to continue... (after plug 22) foreachplug { expect "([0-9])*[^\r\n]*(ON|OFF)\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script on_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script off_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" } script cycle_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } } powerman-2.3.27/etc/apcpdu3.dev000066400000000000000000000101111415616035500162470ustar00rootroot00000000000000# # Derived from apcpdu.dev, but updated for new firmware # # - Firmware: APP v3.3.3 / AOS v3.3.4 # specification "apcpdu3" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" } script login { expect "\n" expect "\rUser Name : " send "apc\r\n" expect "\rPassword : " send "apc\r\n" expect "> " send "1\r\n" # device manager menu expect "> " send "2\r\n" # outlet management expect "> " send "1\r\n" # Outlet Control/Configuration expect "to continue..." send "\r\n" expect "> " } script logout { send "\033" expect "> " send "\033" expect "> " send "4\r\n" } script status_all { send "\r\n" # refresh send "\r\n" # to continue... (after plug 22) foreachplug { expect "([0-9])*[^\r\n]*(ON|OFF)\r\n" setplugstate $1 $2 on="ON" off="OFF" } expect "> " } script on { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script on_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script off { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } script off_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } # If outlet is initially off, "immediate reboot" (4) will leave it off. # This doesn't match PowerMan's semantics for cycle, therefore do explicit # immediate off + immediate on. script cycle { send "%s\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "2\r\n" # immediate off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "1\r\n" # immediate on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" } script cycle_all { send "25\r\n" expect "> " send "1\r\n" # select outlet control expect "> " send "7\r\n" # cancel any pending delays expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "5\r\n" # delayed off expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " delay 4 send "4\r\n" # delayed on expect "to cancel : " send "YES\r\n" expect "to continue..." send "\r\n" expect "> " send "\033" expect "> " send "\033" expect "to continue..." send "\r\n" expect "> " } } powerman-2.3.27/etc/appro-gb2.dev000066400000000000000000000153621415616035500165160ustar00rootroot00000000000000# # GreenBlade Subrack # APPRO Inc. # # appro-gb2.dev,v 1.0 2010/07/19 16:05:34 Francis Lee (kolee@appro.com) # /usr/local/etc/powerman/appro-gb2.dev,v # # sr5110 : Standard 10 Nodes # sr5110_gpu : 5 Nodes with 5 GPU expansions # sr8116 : Standard 16 Nodes # sr8116_gpu : 8 Nodes with 8 GPU expansions # sr8104 : 2U 4 Nodes same as sr8104_gpu # specification "sr5110" { timeout 15.0 plug name { "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" } script ping { send "\r" expect "-iSCB> " } script login { delay 0.5 send "\r" expect "-iSCB> " } script logout { send "exit\r" } script status_all { send "pmnode all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status_beacon_all { send "pmled all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status { send "pmnode %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script status_beacon { send "pmled %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script on { send "power on %s\r" expect "-iSCB> " } script off { send "power off %s\r" expect "-iSCB> " } script cycle { send "power cycle %s\r" expect "-iSCB> " } script beacon_on { send "led on %s\r" expect "-iSCB> " } script beacon_off { send "led off %s\r" expect "-iSCB> " } script reset_all { send "power reset all\r" expect "-iSCB> " } script reset { send "power reset %s\r" expect "-iSCB> " } } specification "sr5110_gpu" { timeout 15.0 plug name { "01" "02" "03" "04" "05" } script ping { send "\r" expect "-iSCB> " } script login { delay 0.5 send "\r" expect "-iSCB> " } script logout { send "exit\r" } script status_all { send "pmnode all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status_beacon_all { send "pmled all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status { send "pmnode %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script status_beacon { send "pmled %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script on { send "power on %s\r" expect "-iSCB> " } script off { send "power off %s\r" expect "-iSCB> " } script cycle { send "power cycle %s\r" expect "-iSCB> " } script beacon_on { send "led on %s\r" expect "-iSCB> " } script beacon_off { send "led off %s\r" expect "-iSCB> " } script reset_all { send "power reset all\r" expect "-iSCB> " } script reset { send "power reset %s\r" expect "-iSCB> " } } specification "sr8116" { timeout 15.0 plug name { "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12" "13" "14" "15" "16" } script ping { send "\r" expect "-iSCB> " } script login { delay 0.5 send "\r" expect "-iSCB> " } script logout { send "exit\r" } script status_all { send "pmnode all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status_beacon_all { send "pmled all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status { send "pmnode %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script status_beacon { send "pmled %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script on { send "power on %s\r" expect "-iSCB> " } script off { send "power off %s\r" expect "-iSCB> " } script cycle { send "power cycle %s\r" expect "-iSCB> " } script beacon_on { send "led on %s\r" expect "-iSCB> " } script beacon_off { send "led off %s\r" expect "-iSCB> " } script reset_all { send "power reset all\r" expect "-iSCB> " } script reset { send "power reset %s\r" expect "-iSCB> " } } specification "sr8116_gpu" { timeout 15.0 plug name { "01" "02" "03" "04" } script ping { send "\r" expect "-iSCB> " } script login { delay 0.5 send "\r" expect "-iSCB> " } script logout { send "exit\r" } script status_all { send "pmnode all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status_beacon_all { send "pmled all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status { send "pmnode %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script status_beacon { send "pmled %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script on { send "power on %s\r" expect "-iSCB> " } script off { send "power off %s\r" expect "-iSCB> " } script cycle { send "power cycle %s\r" expect "-iSCB> " } script beacon_on { send "led on %s\r" expect "-iSCB> " } script beacon_off { send "led off %s\r" expect "-iSCB> " } script reset_all { send "power reset all\r" expect "-iSCB> " } script reset { send "power reset %s\r" expect "-iSCB> " } } specification "sr8104" { timeout 15.0 plug name { "01" "02" "03" "04" } script ping { send "\r" expect "-iSCB> " } script login { delay 0.5 send "\r" expect "-iSCB> " } script logout { send "exit\r" } script status_all { send "pmnode all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status_beacon_all { send "pmled all\r" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "-iSCB> " } script status { send "pmnode %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script status_beacon { send "pmled %s\r" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "-iSCB> " } script on { send "power on %s\r" expect "-iSCB> " } script off { send "power off %s\r" expect "-iSCB> " } script cycle { send "power cycle %s\r" expect "-iSCB> " } script beacon_on { send "led on %s\r" expect "-iSCB> " } script beacon_off { send "led off %s\r" expect "-iSCB> " } script reset_all { send "power reset all\r" expect "-iSCB> " } script reset { send "power reset %s\r" expect "-iSCB> " } } powerman-2.3.27/etc/appro-greenblade.dev000066400000000000000000000124471415616035500201350ustar00rootroot00000000000000# # GreenBlade Subrack # APPRO Inc. # # appro-greenblade.dev,v 1.0 2010/07/19 16:05:34 Francis Lee (kolee@appro.com) # /usr/local/etc/powerman/appro-greenblade.dev,v # # iscb-gb : Standard 10 nodes # iscb-gbgpu : 5 nodes with 5 GPU expansions # iscb-hybrid : 6 nodes with 4 GPU expansions # specification "iscb-gb" { timeout 10.0 plug name { "01" "02" "03" "04" "05" "06" "07" "08" "09" "10" } script ping { send "\r\n" expect "iSCB-[0-9]+:[0-9]> " } script login { send "\r\n" delay 0.5 expect "Password: " send "111111\r\n" expect "iSCB-[0-9]+:[0-9]> " } script logout { send "exit\r\n" expect "ok" #expect "ok\niSCB-[0-9]+:[0-9]> " } script status_all { send "pmnode all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon_all { send "pmled all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status { send "pmnode %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon { send "pmled %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script on { send "on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script off { send "off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script cycle { send "cycle %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_on { send "led on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_off { send "led off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset_all { send "reset all\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset { send "reset %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } } specification "iscb-gbgpu" { timeout 10.0 plug name { "01" "02" "03" "04" "05" } script ping { send "\r\n" expect "iSCB-[0-9]+:[0-9]> " } script login { send "\r\n" delay 0.5 expect "Password: " send "111111\r\n" expect "iSCB-[0-9]+:[0-9]> " } script logout { send "exit\r\n" expect "ok" #expect "ok\niSCB-[0-9]+:[0-9]> " } script status_all { send "pmnode all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon_all { send "pmled all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status { send "pmnode %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon { send "pmled %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script on { send "on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script off { send "off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script cycle { send "cycle %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_on { send "led on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_off { send "led off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset_all { send "reset all\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset { send "reset %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } } specification "iscb-hybrid" { timeout 10.0 plug name { "01" "02" "03" "04" "05" "06" "07" } script ping { send "\r\n" expect "iSCB-[0-9]+:[0-9]> " } script login { send "\r\n" delay 0.5 expect "Password: " send "111111\r\n" expect "iSCB-[0-9]+:[0-9]> " } script logout { send "exit\r\n" expect "ok" #expect "ok\niSCB-[0-9]+:[0-9]> " } script status_all { send "pmnode all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon_all { send "pmled all\r\n" foreachplug { expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" } expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status { send "pmnode %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script status_beacon { send "pmled %s\r\n" expect "node([0-9]+): (on|off|n/a)" setplugstate $1 $2 on="on" off="off" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script on { send "on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script off { send "off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script cycle { send "cycle %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_on { send "led on %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script beacon_off { send "led off %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset_all { send "reset all\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } script reset { send "reset %s\r\n" expect "ok" expect "iSCB-[0-9]+:[0-9]> " } } powerman-2.3.27/etc/bashfun.dev000066400000000000000000000012171415616035500163450ustar00rootroot00000000000000# Here's an example of how to start bash as a coprocess from powerman # and get it to execute commands for you. powerman.conf should contain: # # include "/etc/powerman/bashfun.dev" # device "bf0" "bashfun" "/bin/bash |&" # node "b1" "bf0" "1" # specification "bashfun" { timeout 5 plug name { "1" } script login { send "export PS1='Pm>'\n" expect "Pm>" send "PLUG_STATE=off\n" expect "Pm>" } script status { send "echo $PLUG_STATE\n" expect "(off|on)" setplugstate "1" $1 on="on" off="off" expect "Pm>" } script on { send "PLUG_STATE=on\n" expect "Pm>" } script off { send "PLUG_STATE=off\n" expect "Pm>" } } powerman-2.3.27/etc/baytech-rpc18d-nc.dev000066400000000000000000000027521415616035500200400ustar00rootroot00000000000000# # $Id: baytech-rpc18d-nc.dev 964 2008-06-13 13:40:47Z garlick $ # # Baytech RPC18D-NC # # Default config, then disable confirmation, and disable status menu. # # Firmware version: F3.01 (C) 2000 # # Maybe it is accumulated serial noise or some other issue, but this # model seems to require a little handshake: # send "\r\n" # expect ".*RPC-18>" # before each command to avoid dropping the command. # specification "baytech-rpc18d-nc" { timeout 7 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { send "\r\n" expect ".*RPC-18>" } script logout { send "\r\n" expect ".*RPC-18>" send "exit\r\n" } script status_all { send "\r\n" expect ".*RPC-18>" send "status\r\n" foreachplug { expect "([0-9]+)\)\.*.*: (On|Off)" setplugstate $1 $2 on="On" off="Off" } expect "RPC-18>" } script on { send "\r\n" expect ".*RPC-18>" send "on %s\r\n" expect "RPC-18>" } script on_all { send "\r\n" expect ".*RPC-18>" send "on 0\r\n" expect "RPC-18>" } script off { send "\r\n" expect ".*RPC-18>" send "off %s\r\n" expect "RPC-18>" } script off_all { send "\r\n" expect ".*RPC-18>" send "off 0\r\n" expect "RPC-18>" } script cycle { send "\r\n" expect ".*RPC-18>" send "off %s\r\n" expect "RPC-18>" delay 4 send "on %s\r\n" expect "RPC-18>" } script cycle_all { send "\r\n" expect ".*RPC-18>" send "off 0\r\n" expect "RPC-18>" delay 4 send "on 0\r\n" expect "RPC-18>" } } powerman-2.3.27/etc/baytech-rpc22.dev000066400000000000000000000042231415616035500172640ustar00rootroot00000000000000# # Baytech RPC22-20 # # Default config, then disable confirmation, and disable status menu. # # Firmware version: F1.10 (C) 2000 # # Maybe it is accumulated serial noise or some other issue, but this # model seems to require a little handshake: # send "\r\n" # expect ".*RPC-22>" # before each command to avoid dropping the command. # specification "baytech-rpc22" { timeout 10 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" } script login { send "\r\n" expect ".*RPC-22>" } script logout { send "\r\n" expect ".*RPC-22>" send "exit\r\n" } script status_all { send "\r\n" expect ".*RPC-22>" send "status\r\n" foreachplug { expect "Outlet[ ]+([0-9]+)[^:0-9]+: (On|Off)" setplugstate $1 $2 on="On" off="Off" } expect "RPC-22>" } script on { send "\r\n" expect ".*RPC-22>" send "on %s\r\n" expect "RPC-22>" } script on_all { send "\r\n" expect ".*RPC-22>" send "on 0\r\n" expect "RPC-22>" } script off { send "\r\n" expect ".*RPC-22>" send "off %s\r\n" expect "RPC-22>" } script off_all { send "\r\n" expect ".*RPC-22>" send "off 0\r\n" expect "RPC-22>" } script cycle { send "\r\n" expect ".*RPC-22>" send "off %s\r\n" expect "RPC-22>" delay 2 send "on %s\r\n" expect "RPC-22>" } script cycle_all { send "\r\n" expect ".*RPC-22>" send "off 0\r\n" expect "RPC-22>" delay 2 send "on 0\r\n" expect "RPC-22>" } } powerman-2.3.27/etc/baytech-rpc28-nc.dev000066400000000000000000000031131415616035500176650ustar00rootroot00000000000000# # $Id$ # # Baytech RPC28-30NC # # Default config, then disable confirmation, and disable status menu. # # Firmware version: F3.01 (C) 2000 # # Maybe it is accumulated serial noise or some other issue, but this # model seems to require a little handshake: # send "\r\n" # expect ".*RPC-28[A]*>" # before each command to avoid dropping the command. # specification "baytech-rpc28-nc" { timeout 10 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" } script login { send "\r\n" expect ".*RPC-28[A]*>" } script logout { send "\r\n" expect ".*RPC-28[A]*>" send "exit\r\n" } script status_all { send "\r\n" expect ".*RPC-28[A]*>" send "status\r\n" foreachplug { expect "Outlet[ ]+([0-9]+)[^:0-9]+: (On|Off)" setplugstate $1 $2 on="On" off="Off" } expect "RPC-28[A]*>" } script on { send "\r\n" expect ".*RPC-28[A]*>" send "on %s\r\n" expect "RPC-28[A]*>" } script on_all { send "\r\n" expect ".*RPC-28[A]*>" send "on 0\r\n" expect "RPC-28[A]*>" } script off { send "\r\n" expect ".*RPC-28[A]*>" send "off %s\r\n" expect "RPC-28[A]*>" } script off_all { send "\r\n" expect ".*RPC-28[A]*>" send "off 0\r\n" expect "RPC-28[A]*>" } script cycle { send "\r\n" expect ".*RPC-28[A]*>" send "off %s\r\n" expect "RPC-28[A]*>" delay 4 send "on %s\r\n" expect "RPC-28[A]*>" } script cycle_all { send "\r\n" expect ".*RPC-28[A]*>" send "off 0\r\n" expect "RPC-28[A]*>" delay 4 send "on 0\r\n" expect "RPC-28[A]*>" } } powerman-2.3.27/etc/baytech-rpc3-nc.dev000066400000000000000000000031021415616035500175740ustar00rootroot00000000000000# # $Id$ # # Baytech RPC3-20NC # # Tested the following firmware versions: # RPC3-NC Series (C) 2002 by BayTech F4.00 # RPC-3/4(A)DE Series (C) 2004 BayTech F1.08 # RPC-3/4(A)DE Series (C) 2004 BayTech F1.09 # # Note: # Type ";;;;;" to access "network interface module". # Prompt is not returned until device is ready to accept another commmand. # # Assumes: # Command confirmation : disabled # Status menu : disabled # No access control # No idle timeout # No active restore (causes disconnections) # specification "baytech-rpc3-nc" { timeout 10 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { send "\r\n" expect ">" } script logout { send "exit\r\n" } script status_all { # XXX this works around bug where foreachplug # counter doesn't reset when script restarts after reconnect send "\r\n" expect ">" # XXX end workaround send "status\r\n" foreachplug { expect "Outlet ([0-9]+)[^:0-9]+: (On|Off)" setplugstate $1 $2 on="On" off="Off" } expect ">" } script on { send "on %s\r\n" expect ">" } script on_all { send "on 0\r\n" expect ">" } script off { send "off %s\r\n" expect ">" } script off_all { send "off 0\r\n" expect ">" } # If outlet is initially off, "reboot" will leave it off. # This doesn't match PowerMan's semantics for cycle, so explicitly power # off then on. script cycle { send "off %s\r\n" expect ">" delay 4 send "on %s\r\n" expect ">" } script cycle_all { send "off 0\r\n" expect ">" delay 4 send "on 0\r\n" expect ">" } } powerman-2.3.27/etc/baytech-snmp.dev000066400000000000000000000032571415616035500173170ustar00rootroot00000000000000# Baytech RPC3-NC via SNMP (also can drive with baytech-rpc3-nc.dev) # # Snmp v1 or v2c works. # # N.B. Occasionally snmp agent locks up and must be restarted by telnet or # serial: ;;;;; then Network Interface Module Login, then Unit Reset. # # Example device entry: # device "b" "baytech-snmp" "/usr/sbin/snmppower -h 192.168.1.95|&" specification "baytech-snmp" { timeout 10 # about 5 sec for cycle command plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "snmppower> " send "start_v2c private\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } script status_all { send "get enterprises.4779.1.3.5.5.1.13.2.1\n" expect "enterprises.4779.1.3.5.5.1.13.2.1: (0|1),(0|1),(0|1),(0|1),(0|1),(0|1),(0|1),(0|1)\n" setplugstate "1" $1 off="0" on="1" setplugstate "2" $2 off="0" on="1" setplugstate "3" $3 off="0" on="1" setplugstate "4" $4 off="0" on="1" setplugstate "5" $5 off="0" on="1" setplugstate "6" $6 off="0" on="1" setplugstate "7" $7 off="0" on="1" setplugstate "8" $8 off="0" on="1" expect "snmppower> " } script on { send "set enterprises.4779.1.3.5.3.1.3.1.%s i 1\n" expect "enterprises.4779.1.3.5.3.1.3.1.[1-8]: 1\n" expect "snmppower> " } script off { send "set enterprises.4779.1.3.5.3.1.3.1.%s i 0\n" expect "enterprises.4779.1.3.5.3.1.3.1.[1-8]: 0\n" expect "snmppower> " } script cycle { send "set enterprises.4779.1.3.5.3.1.3.1.%s i 0\n" expect "enterprises.4779.1.3.5.3.1.3.1.[1-8]: 0\n" expect "snmppower> " delay 5 send "set enterprises.4779.1.3.5.3.1.3.1.%s i 1\n" expect "enterprises.4779.1.3.5.3.1.3.1.[1-8]: 1\n" expect "snmppower> " } } powerman-2.3.27/etc/baytech.dev000066400000000000000000000031061415616035500163350ustar00rootroot00000000000000# # $Id$ # # Baytech RPC-3 - old style model (not "NC") # # Tested the following firmware versions: # Revision F 5.00, (C) 2001 # Revision F 5.01, (C) 2001 # Assumes: # 1. command confirmation : disabled (3/configuration, 6/outlets, 2/...) # 2. admin account password : "baytech" (2/manage users, 2/admin, 1/...) # 3. net: prompt for password : enabled (3/configuration, 5/access, 2/...) # Note: prompt is not returned until device is ready to accept another commmand # specification "baytech" { timeout 10 # about 5 sec for cycle command pingperiod 90 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script ping { send "\r\n" expect ">" } script login { expect "\n" expect "Enter password>" send "baytech\r\n" expect "Enter Selection>" send "1\r\n" expect ">" } script logout { send "menu\r\n" expect "Enter Selection>" send "6\r\n" } script status_all { send "status\r\n" expect "Circuit Breaker:[^\n]*\r\n" foreachplug { expect "([0-9]+)[ ]+(On|Off)" setplugstate $1 $2 on="On" off="Off" } expect ">" } script on { send "on %s\r\n" expect ">" } script on_all { send "on 0\r\n" expect ">" } script off { send "off %s\r\n" expect ">" } script off_all { send "off 0\r\n" expect ">" } # If outlet is initially off, "reboot" will leave it off. # This doesn't match PowerMan's semantics for cycle, so explicitly power # off then on. script cycle { send "off %s\r\n" expect ">" delay 4 send "on %s\r\n" expect ">" } script cycle_all { send "off 0\r\n" expect ">" delay 4 send "on 0\r\n" expect ">" } } powerman-2.3.27/etc/cb-7050.dev000066400000000000000000000074511415616035500157020ustar00rootroot00000000000000# # Measurement Computing Corp. CB-7050 digital I/O module # # This is "laboratory quality" power control as it requires wires # connected directly to motherboards and some hand tuning of delay values. # # Ref: CB-7000 DIO User's Manual # # Notes: # - Important note: CB-7050 data lines are not isolated and share a common # ground. Beware of ground loops! # - Wire DI[0-6] to +5V side of reset header # - Wire D0[0-7] (open collector) to +5 side of power switch header. # - Wire the CB-7050 ground to moboard ground (send to reset/power headers). # - CB-7050 is presumed to be at address 01 # - CB-7520 RS-232 to RS-485 converter connects to Cyclades TS at 115000 baud. # - DO lines are "open" (0) at power on. Writing 1 connects the line to gnd. # - DI7 is n.c. on the CB-7050. Although plug 7 can be controlled via D07, # power state will always be "unknown" and on/off are effectively toggles. # - [HDAMA] power on delay = 2s, power off delay = 5s. Tune for your moboard. # - This would be cleaner if we could call status_all from off|on scripts. # - This would be cleaner if we had "whileon|whileoff" (no hard coded delays). # specification "cb7050" { timeout 10.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" } script login { send "$01M\r" # verify module name expect "!017050\r" # model 7050 send "$012\r" # verify conf (type,baud,dfmt) expect "!0140..00\r" # type=40 baud=?? dfmt=00 } script status_all { send "$016\r" # read digital I/O status expect "!..(.)(.)00\r" # $1=DI[4-7] $2=DI[0-3] setplugstate "0" $2 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "1" $2 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "2" $2 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "3" $2 on="8|9|A|B|C|D|E|F" off="0|1|2|3|4|5|6|7" setplugstate "4" $1 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "5" $1 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "6" $1 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "7" $1 # set to unknown } script on { send "$016\r" expect "!..(.)(.)00\r" setplugstate "0" $2 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "1" $2 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "2" $2 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "3" $2 on="8|9|A|B|C|D|E|F" off="0|1|2|3|4|5|6|7" setplugstate "4" $1 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "5" $1 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "6" $1 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "7" $1 off="." # set to off ifoff { send "#01A%s01\r" # 0xA0 | bitnum (set) expect ">\r" delay 4 # XXX: tune me for moboard! send "#01A%s00\r" # 0xA0 | bitnum (clear) expect ">\r" } } script off { send "$016\r" expect "!..(.)(.)00\r" setplugstate "0" $2 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "1" $2 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "2" $2 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "3" $2 on="8|9|A|B|C|D|E|F" off="0|1|2|3|4|5|6|7" setplugstate "4" $1 on="1|3|5|7|9|B|D|F" off="0|2|4|6|8|A|C|E" setplugstate "5" $1 on="2|3|6|7|A|B|E|F" off="0|1|4|5|8|9|C|D" setplugstate "6" $1 on="4|5|6|7|C|D|E|F" off="0|1|2|3|8|9|A|B" setplugstate "7" $1 on="." # set to on ifon { send "#01A%s01\r" # 0xA0 | bitnum (set) expect ">\r" delay 5 # XXX tune me for moboard! send "#01A%s00\r" # 0xA0 | bitnum (clear) expect ">\r" } } # XXX Evil hack - short init* to ground on the module and run pm -f to set # baud rate to 115000 (0A). If beacon isn't shorted, this will just time out. # Power cycle the module after the change. script beacon_on { send "%%0101400A00\r" expect "!01\r" } # # TODO: add support for a CB-7018P at address 02 wired to eight # thermocouples for status_temp support? # } powerman-2.3.27/etc/cyclades-pm10.dev000066400000000000000000000030161415616035500172600ustar00rootroot00000000000000# # Cyclades PM10 # specification "pm10" { timeout 10 pingperiod 60 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" } script login { expect "Username: " send "admin\n" expect "Password: " send "pm8\n" expect "pm>" } script ping { send "\n" expect "pm>" } script status_all { send "status 1-10\n" expect "Users" foreachplug { expect "([0-9]+)[[:space:]]+Unlocked (ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "pm>" } script on { send "on %s\n" expect "Outlet turned on." expect "pm>" } script on_all { send "on 1-10\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script off { send "off %s\n" expect "Outlet turned off." expect "pm>" } script off_all { send "off 1-10\n" foreachplug { expect "Outlet turned off." } expect "pm>" } script cycle { send "off %s\n" expect "Outlet turned off." expect "pm>" delay 4 send "on %s\n" expect "Outlet turned on." expect "pm>" } script cycle_all { send "off 1-10\n" foreachplug { expect "Outlet turned off." } expect "pm>" delay 4 send "on 1-10\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script status_temp_all { send "temperature\n" expect "IPDU #1: Temperature: ([0-9.]+)" setplugstate "1" $1 setplugstate "2" $1 setplugstate "3" $1 setplugstate "4" $1 setplugstate "5" $1 setplugstate "6" $1 setplugstate "7" $1 setplugstate "8" $1 setplugstate "9" $1 setplugstate "10" $1 } } powerman-2.3.27/etc/cyclades-pm20.dev000066400000000000000000000034471415616035500172710ustar00rootroot00000000000000# # Cyclades PM20 # specification "pm20" { timeout 25 pingperiod 60 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" } script login { expect "Username: " send "admin\n" expect "Password: " send "pm8\n" expect "pm>" } script ping { send "\n" expect "pm>" } script status_all { send "status 1-20\n" expect "Users" foreachplug { expect "([0-9]+)[[:space:]]+Unlocked (ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "pm>" } script on { send "on %s\n" expect "Outlet turned on." expect "pm>" } script on_all { send "on 1-20\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script off { send "off %s\n" expect "Outlet turned off." expect "pm>" } script off_all { send "off 1-20\n" foreachplug { expect "Outlet turned off." } expect "pm>" } script cycle { send "off %s\n" expect "Outlet turned off." expect "pm>" delay 4 send "on %s\n" expect "Outlet turned on." expect "pm>" } script cycle_all { send "off 1-20\n" foreachplug { expect "Outlet turned off." } expect "pm>" delay 4 send "on 1-20\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script status_temp_all { send "temperature\n" expect "IPDU #1: Temperature: ([0-9.]+)" setplugstate "1" $1 setplugstate "2" $1 setplugstate "3" $1 setplugstate "4" $1 setplugstate "5" $1 setplugstate "6" $1 setplugstate "7" $1 setplugstate "8" $1 setplugstate "9" $1 setplugstate "10" $1 setplugstate "11" $1 setplugstate "12" $1 setplugstate "13" $1 setplugstate "14" $1 setplugstate "15" $1 setplugstate "16" $1 setplugstate "17" $1 setplugstate "18" $1 setplugstate "19" $1 setplugstate "20" $1 } } powerman-2.3.27/etc/cyclades-pm42.dev000066400000000000000000000027211415616035500172670ustar00rootroot00000000000000# # Cyclades PM42 # specification "pm42" { timeout 10 pingperiod 60 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" } script login { expect "Username: " send "admin\n" expect "Password: " send "pm8\n" expect "pm>" } script ping { send "\n" expect "pm>" } script status_all { send "status 1-42\n" expect "Users" foreachplug { expect "([0-9]+)[[:space:]]+Unlocked (ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "pm>" } script on { send "on %s\n" expect "Outlet turned on." expect "pm>" } script on_all { send "on 1-42\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script off { send "off %s\n" expect "Outlet turned off." expect "pm>" } script off_all { send "off 1-42\n" foreachplug { expect "Outlet turned off." } expect "pm>" } script cycle { send "off %s\n" expect "Outlet turned off." expect "pm>" delay 4 send "on %s\n" expect "Outlet turned on." expect "pm>" } script cycle_all { send "off 1-42\n" foreachplug { expect "Outlet turned off." } expect "pm>" delay 4 send "on 1-42\n" foreachplug { expect "Outlet turned on." } expect "pm>" } } powerman-2.3.27/etc/cyclades-pm8.dev000066400000000000000000000027501415616035500172130ustar00rootroot00000000000000# # Cyclades PM8/PM8i s/w v. 1.0.9a # specification "pm8" { timeout 10 pingperiod 60 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "Username: " send "admin\n" expect "Password: " send "pm8\n" expect "pm>" } script ping { send "\n" expect "pm>" } script status_all { send "status 1-8\n" expect "Users" foreachplug { expect "([0-9]+)[[:space:]]+Unlocked (ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "pm>" } script on { send "on %s\n" expect "Outlet turned on." expect "pm>" } script on_all { send "on 1-8\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script off { send "off %s\n" expect "Outlet turned off." expect "pm>" } script off_all { send "off 1-8\n" foreachplug { expect "Outlet turned off." } expect "pm>" } script cycle { send "off %s\n" expect "Outlet turned off." expect "pm>" delay 4 send "on %s\n" expect "Outlet turned on." expect "pm>" } script cycle_all { send "off 1-8\n" foreachplug { expect "Outlet turned off." } expect "pm>" delay 4 send "on 1-8\n" foreachplug { expect "Outlet turned on." } expect "pm>" } script status_temp_all { send "temperature\n" expect "IPDU #1: Temperature: ([0-9.]+)" setplugstate "1" $1 setplugstate "2" $1 setplugstate "3" $1 setplugstate "4" $1 setplugstate "5" $1 setplugstate "6" $1 setplugstate "7" $1 setplugstate "8" $1 } } powerman-2.3.27/etc/dli.dev000066400000000000000000000023421415616035500154670ustar00rootroot00000000000000# Support for 8-port Digital Loggers, Inc. models: # # www.digital-loggers.com/lpc.html # www.digital-loggers.com/epcr2.html # www.digital-loggers.com/din.html # # Powerman.conf should look something like this: # include "/etc/powerman/dli.dev" # device "lpc" "dli" "/usr/sbin/httppower -u http://192.168.0.100 |&" # node "p[1-8]" "lpc" "[1-8]" # specification "dli" { timeout 30 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "httppower> " send "auth admin:admin\n" expect "httppower> " } script logout { send "quit\n" } script status_all { send "get\n" expect "Controller:" foreachplug { expect "Outlet ([1-8]+)[^O]*(ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "httppower> " } script on { send "post outlet %s=ON\n" expect "httppower> " } script off { send "post outlet %s=OFF\n" expect "httppower> " } script cycle { send "post outlet %s=OFF\n" expect "httppower> " delay 4 send "post outlet %s=ON\n" expect "httppower> " } script cycle_all { foreachplug { send "post outlet %s=OFF\n" expect "httppower> " } delay 4 foreachplug { send "post outlet %s=ON\n" expect "httppower> " } } } powerman-2.3.27/etc/dli4.dev000066400000000000000000000023261415616035500155550ustar00rootroot00000000000000# Support for 8-port Digital Loggers, Inc. web power switch III or IV # # Powerman.conf should look something like this: # include "/etc/powerman/dli4.dev" # device "lpc" "dli4" "/usr/sbin/httppower -u http://192.168.0.100 |&" # node "p[1-8]" "lpc" "[1-8]" # # Thanks to Gaylord Holder for providing info to create this script. # specification "dli4" { timeout 30 plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "httppower> " send "auth admin:1234\n" expect "httppower> " } script logout { send "quit\n" } script status_all { send "get index.htm\n" expect "Controller:" foreachplug { expect "Outlet ([1-8]+)[^O]*(ON|OFF)" setplugstate $1 $2 on="ON" off="OFF" } expect "httppower> " } script on { send "post outlet %s=ON\n" expect "httppower> " } script off { send "post outlet %s=OFF\n" expect "httppower> " } script cycle { send "post outlet %s=OFF\n" expect "httppower> " delay 4 send "post outlet %s=ON\n" expect "httppower> " } script cycle_all { foreachplug { send "post outlet %s=OFF\n" expect "httppower> " } delay 4 foreachplug { send "post outlet %s=ON\n" expect "httppower> " } } } powerman-2.3.27/etc/eaton-epdu-blue-switched.dev000066400000000000000000000045271415616035500215240ustar00rootroot00000000000000# eaton-epdu-blue-switched.dev # Eaton Vertical Mount (0U) Switched ePDUs with Blue and Yellow Local Display # Contributed by Paul Anderson (panderson@sgi.com) # # Example powerman.conf device line: # device "epdu1" "eaton-epdu-blue-switched" "/usr/sbin/snmppower -h epdu1|&" # # N.B. This script requires that you download and install the Eaton ePDU MIB # where net-snmp can find it, e.g.: # /usr/share/snmp/mibs/Pulizzi-Vertical-SW-ePDU.txt # # Download ePDU_MIB_Switched_Blue_Display.zip from: # powerquality.eaton.com/Support/Software-Drivers/Downloads/ePDU-firmware.asp # specification "eaton-epdu-blue-switched" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" } script login { expect "snmppower> " send "start_v2c private\n" expect "snmppower> " send "mib Pulizzi\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } script status { send "get Pulizzi::outlet%sStatus.0\n" expect "Pulizzi::outlet([0-9]+)Status.0: (1|2)\n" setplugstate $1 $2 on="1" off="2" expect "snmppower> " } script on { send "set Pulizzi::outlet%sCommand.0 i 1\n" expect "Pulizzi::outlet[0-9]+Command.0: 1\n" expect "snmppower> " delay 0.3 } script off { send "set Pulizzi::outlet%sCommand.0 i 2\n" expect "Pulizzi::outlet[0-9]+Command.0: 2\n" expect "snmppower> " } script reset { send "set Pulizzi::outlet%sCommand.0 i 3\n" expect "Pulizzi::outlet[0-9]+Command.0: 3\n" expect "snmppower> " delay 0.3 } script cycle { send "set Pulizzi::outlet%sCommand.0 i 2\n" expect "Pulizzi::outlet[0-9]+Command.0: 2\n" expect "snmppower> " delay 5 send "set Pulizzi::outlet%sCommand.0 i 1\n" expect "Pulizzi::outlet[0-9]+Command.0: 1\n" expect "snmppower> " delay 0.3 } } powerman-2.3.27/etc/eaton-revelation-snmp.dev000066400000000000000000000025401415616035500211460ustar00rootroot00000000000000# Eaton PowerWare model PW102MA0U025 via SNMP # Example powerman.conf device line: # device "epdu1" "eaton-revelation-snmp" "/usr/sbin/snmppower -h epdu1|&" specification "eaton-revelation-snmp" { timeout 10 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" } script login { expect "snmppower> " send "start_v2c private\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } script status { send "get enterprises.534.6.6.6.1.2.2.1.3.%s\n" expect "enterprises.534.6.6.6.1.2.2.1.3.([0-9]+): (0|1)" setplugstate $1 $2 on="1" off="0" expect "snmppower> " } script on { send "set enterprises.534.6.6.6.1.2.2.1.3.%s i 1\n" expect "enterprises.534.6.6.6.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } script off { send "set enterprises.534.6.6.6.1.2.2.1.3.%s i 0\n" expect "enterprises.534.6.6.6.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " } script cycle { send "set enterprises.534.6.6.6.1.2.2.1.3.%s i 0\n" expect "enterprises.534.6.6.6.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " delay 5 send "set enterprises.534.6.6.6.1.2.2.1.3.%s i 1\n" expect "enterprises.534.6.6.6.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } } powerman-2.3.27/etc/hp3488.dev000066400000000000000000000013721415616035500156570ustar00rootroot00000000000000# # HP3488 switch/control unit using 'hp3488' utility from gpib-utils project. # # device "hp0" "hp3488" "/usr/bin/hp3488 --shell|&" # # "Plug" names for this device are three digit values consisting of # a single digit slot number (1-5) followed by two digit channel number. # specification "hp3488" { timeout 5 script login { expect "hp3488> " } script logout { send "quit\n" } script status { send "query %s\n" expect "([1-5][0-9]{2}): ([01])\n" setplugstate $1 $2 off="0" on="1" expect "hp3488> " } script on_ranged { send "on %s\n" expect "hp3488> " } script off_ranged { send "off %s\n" expect "hp3488> " } script cycle_ranged { send "off %s\n" expect "hp3488> " delay 4 send "on %s\n" expect "hp3488> " } } powerman-2.3.27/etc/hpilo.dev000066400000000000000000000024741415616035500160400ustar00rootroot00000000000000# HP Integrated Lights-Out management device (iLO) # # (c) Copyright 2009 Hewlett-Packard Development Company, L.P. # Bjorn Helgaas # # 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. # # Example: # device "dl360-001" "hpilo" "dl360-001-ilo.test:23" # node "dl360-001" "dl360-001" # # Tested on: # DL360 (iLO firmware 1.93) # DL320 (iLO firmware 1.42) # BL465c G5 (iLO firmware 1.61) specification "hpilo" { timeout 10 plug name { "1" } script login { expect "Login Name: " send "Admin\r\n" expect "Password: " send "Admin\r\n" expect "hpiLO-> " } script status { send "power\r\n" expect "server power is currently: (On|Off)" setplugstate "1" $1 on="On" off="Off" expect "hpiLO-> " } script on { send "power on\r\n" expect "hpiLO-> " } script off { send "power off\r\n" expect "hpiLO-> " } script reset { send "reset system1\r\n" expect "hpiLO-> " } script status_beacon { send "uid\r\n" expect "The UID light is currently: (On|Off)" setplugstate "1" $1 on="On" off="Off" expect "hpiLO-> " } script beacon_on { send "uid on\r\n" expect "hpiLO-> " } script beacon_off { send "uid off\r\n" expect "hpiLO-> " } } powerman-2.3.27/etc/hpmp.dev000066400000000000000000000025651415616035500156720ustar00rootroot00000000000000# HP Management Processor device (MP) # a.k.a. Integrated Lights-Out HP Integrity # # (c) Copyright 2009 Hewlett-Packard Development Company, L.P. # Bjorn Helgaas # # 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. # # Example: # device "rx3600-001" "hpmp" "rx3600-001-mp.test:23" # node "rx3600-001" "rx3600-001" # # Tested on: # rx3600 (MP firmware F.01.41) # rx1600 (MP firmware E.03.30) # rx1620 (MP firmware E.03.30) specification "hpmp" { timeout 10 plug name { "1" } script login { expect "MP login: " send "Admin\r\n" expect "MP password: " send "Admin\r\n" expect "MP> " send "cm\r\n" expect "MP:CM> " } script status { send "ps\r\n" expect "System Power state[^O]+(On|Off)" setplugstate "1" $1 on="On" off="Off" expect "MP:CM> " } script on { send "pc -on -nc\r\n" expect "MP:CM> " } script off { send "pc -off -nc\r\n" expect "MP:CM> " } script reset { send "rs -nc\r\n" expect "MP:CM> " } script status_beacon { send "loc -nc\r\n" expect "Current -> Locator LED (On|Off)" setplugstate "1" $1 on="On" off="Off" expect "MP:CM> " } script beacon_on { send "loc -on -nc\r\n" expect "MP:CM> " } script beacon_off { send "loc -off -nc\r\n" expect "MP:CM> " } } powerman-2.3.27/etc/hpmpblade.dev000066400000000000000000000024761415616035500166630ustar00rootroot00000000000000# HP Management Processor device (MP) # a.k.a. Integrity Integrated Lights-Out 2 # # (c) Copyright 2009 Hewlett-Packard Development Company, L.P. # Bjorn Helgaas # # 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. # # Example: # device "bl860c-001" "hpmpblade" "bl860c-001-mp.test:23" # node "bl860c-001" "bl860c-001" # # Tested on: # BL860c (MP firmware T.02.16) specification "hpmpblade" { timeout 10 plug name { "1" } script login { expect "login: " send "Admin\r\n" expect "password: " send "Admin\r\n" expect "MP> " send "cm\r\n" expect "MP:CM> " } script status { send "ps\r\n" expect "System Power state[^O]+(On|Off)" setplugstate "1" $1 on="On" off="Off" expect "MP:CM> " } script on { send "pc -on -nc\r\n" expect "MP:CM> " } script off { send "pc -off -nc\r\n" expect "MP:CM> " } script reset { send "rs -nc\r\n" expect "MP:CM> " } script status_beacon { send "loc -nc\r\n" expect "Server Locator UID LED[^O]+(On|Off)" setplugstate "1" $1 on="On" off="Off" expect "MP:CM> " } script beacon_on { send "loc -on -nc\r\n" expect "MP:CM> " } script beacon_off { send "loc -off -nc\r\n" expect "MP:CM> " } } powerman-2.3.27/etc/hpmpcell.dev000066400000000000000000000041001415616035500165150ustar00rootroot00000000000000# HP Management Processor device (MP) for mid-range cellular systems # # (c) Copyright 2009 Hewlett-Packard Development Company, L.P. # Bjorn Helgaas # # 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. # # Example: # device "rx8620-001" "hpmpcell" "rx8620-001-mp.test:23" # node "rx8620-001-p0" "rx8620-001" "0" # # Tested on: # rx8620 (MP firmware A.7.008, A.8.005) # # This handles each partition separately. The "plug" argument to node is the # partition number. # # N.B. This only works on mid-range, e.g., rx7620, rx7640, rx8620, and rx8640. # It doesn't handle Superdome because Superdome uses "P" to select partition, # not "R". It should support PA-RISC systems, e.g., rp7620, rp7640, etc. specification "hpmpcell" { timeout 10 script login { expect "MP login: " send "Admin\r\n" expect "MP password: " send "Admin\r\n" expect "MP> " send "cm\r\n" expect "MP:CM> " } script status { send "pe\r\n" expect "Select Device: " send "r\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "q\r\n" expect "MP:CM> " } script on { send "pe\r\n" expect "Select Device: " send "r\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "on\r\n" expect "MP:CM> " } script off { send "pe\r\n" expect "Select Device: " send "r\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "off\r\n" expect "MP:CM> " } script reset { send "rs\r\n" expect "Select a partition number: " send "%s\r\n" expect "Do you want to reset partition number.*\? " send "y\r\n" expect "MP:CM> " } } powerman-2.3.27/etc/hpmpdome.dev000066400000000000000000000036031415616035500165310ustar00rootroot00000000000000# HP Management Processor device (MP) for high-end cellular systems # # (c) Copyright 2009 Hewlett-Packard Development Company, L.P. # Bjorn Helgaas # # 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. # # Example: # device "sd-001" "hpmpdome" "sd-001-mp.test:23" # node "sd-001-p0" "sd-001" "0" # # Tested on: # SD64B (MP firmware 26.5.1) # # This handles each partition separately. The "plug" argument to node is the # partition number. # # N.B. This only works on Superdomes, not mid-range cellular systems. specification "hpmpdome" { timeout 10 script login { expect "MP login: " send "Admin\r\n" expect "MP password: " send "Admin\r\n" expect "MP> " send "cm\r\n" expect "MP:CM> " } script status { send "pe\r\n" expect "Select Device: " send "p\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "q\r\n" expect "MP:CM> " } script on { send "pe\r\n" expect "Select Device: " send "p\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "on\r\n" expect "MP:CM> " } script off { send "pe\r\n" expect "Select Device: " send "p\r\n" expect "Select a partition number: " send "%s\r\n" expect "The power state is (ON|OFF)" setplugstate $1 on="ON" off="OFF" expect "In what state do you want the power.*\? " send "off\r\n" expect "MP:CM> " } script reset { send "rs\r\n" expect "Select a partition number: " send "%s\r\n" expect "Do you want to reset partition number.*\? " send "y\r\n" expect "MP:CM> " } } powerman-2.3.27/etc/ibmbladecenter.dev000066400000000000000000000022021415616035500176520ustar00rootroot00000000000000# # Originally ibmbladecenter.dev. RJG, 11/17/04 # # Ref: Command-Line Interface Reference Guide for # IBM BladeCenter Management Module, BladeCenter T Management Module, # Advanced Management Module, BladeCenter T Advanced Management Module. # specification "ibmbladecenter" { timeout 15 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { expect "username: " send "USERID\r\n" expect "password: " send "PASSW0RD\r\n" expect "system> " send "telnetcfg -t 0 -T mm[1]\r\n" expect "OK\r\nsystem> " } script logout { send "exit\r\n" } script status { send "power -state -T blade\[%s\]\r\n" expect "(On|Off)\r\nsystem> " setplugstate $1 on="On" off="Off" } script on { send "power -on -T blade\[%s\]\r\n" delay 1 # settling time expect "OK\r\nsystem> " } script off { send "power -off -T blade\[%s\]\r\n" delay 5 # settling time expect "OK\r\nsystem> " } script cycle { send "power -off -T blade\[%s\]\r\n" expect "OK\r\nsystem> " delay 5 # settling time delay 4 send "power -on -T blade\[%s\]\r\n" expect "OK\r\nsystem> " } } powerman-2.3.27/etc/icebox.dev000066400000000000000000000036471415616035500162010ustar00rootroot00000000000000# # $Id$ # # Linux Networx ICE box firmware version 2.x on port 1010. # specification "icebox" { timeout 20 # accomodate 14 sec plus "cycle *" time */ plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" } script login { expect "V2[^\n]*\r\n" send "auth icebox\r\n" expect "OK\r\n" } script logout { send "q\r\n" } script status_all { send "ps *\r\n" expect "N1:([01]) N2:([01]) N3:([01]) N4:([01]) N5:([01]) N6:([01]) N7:([01]) N8:([01]) N9:([01]) N10:([01])[[:space:]]*\r\n" setplugstate "1" $1 off="0" on="1" setplugstate "2" $2 off="0" on="1" setplugstate "3" $3 off="0" on="1" setplugstate "4" $4 off="0" on="1" setplugstate "5" $5 off="0" on="1" setplugstate "6" $6 off="0" on="1" setplugstate "7" $7 off="0" on="1" setplugstate "8" $8 off="0" on="1" setplugstate "9" $9 off="0" on="1" setplugstate "10" $10 off="0" on="1" } script status_temp_all { send "ts *\r\n" expect "N1:([0-9,]+) N2:([0-9,]+) N3:([0-9,]+) N4:([0-9,]+) N5:([0-9,]+) N6:([0-9,]+) N7:([0-9,]+) N8:([0-9,]+) N9:([0-9,]+) N10:([0-9,]+) N11:[0-9,]+ N12:[0-9,]+[[:space:]]*\r\n" setplugstate "1" $1 setplugstate "2" $2 setplugstate "3" $3 setplugstate "4" $4 setplugstate "5" $5 setplugstate "6" $6 setplugstate "7" $7 setplugstate "8" $8 setplugstate "9" $9 setplugstate "10" $10 } script on { send "ph %s\r\n" expect "OK\r\n" delay 0.7 } script on_all { send "ph *\r\n" expect "OK\r\n" delay 7 } script off { send "pl %s\r\n" expect "OK\r\n" delay 0.7 } script off_all { send "pl *\r\n" expect "OK\r\n" delay 7 } script cycle { send "pl %s\r\n" expect "OK\r\n" delay 4 send "ph %s\r\n" expect "OK\r\n" delay 0.7 } script cycle_all { send "pl *\r\n" expect "OK\r\n" delay 9 send "ph *\r\n" expect "OK\r\n" delay 7 } script reset { send "rp %s\r\n" expect "OK\r\n" delay 0.7 } script reset_all { send "rp *\r\n" expect "OK\r\n" delay 7 } } powerman-2.3.27/etc/icebox3.dev000066400000000000000000000061521415616035500162560ustar00rootroot00000000000000# # $Id$ # # Linux Networx ICE Box firmware version 3.x and 4.x on port 1010. # # For 3.0 B70 or better, 2 sec delays in beacon_on/beacon_off can be # commented out. # specification "icebox3" { timeout 20 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" } script login { expect "V[34][^\n]*\r\n" send "auth icebox\r\n" expect "OK\r\n" } script logout { send "q\r\n" } script status_all { send "ps *\r\n" expect "N1:([01]) N2:([01]) N3:([01]) N4:([01]) N5:([01]) N6:([01]) N7:([01]) N8:([01]) N9:([01]) N10:([01])[[:space:]]*\r\n" setplugstate "1" $1 off="0" on="1" setplugstate "2" $2 off="0" on="1" setplugstate "3" $3 off="0" on="1" setplugstate "4" $4 off="0" on="1" setplugstate "5" $5 off="0" on="1" setplugstate "6" $6 off="0" on="1" setplugstate "7" $7 off="0" on="1" setplugstate "8" $8 off="0" on="1" setplugstate "9" $9 off="0" on="1" setplugstate "10" $10 off="0" on="1" } # Assumption: v3 implies that "ts" is deprecated in favor of "is" script status_temp_all { send "is *\r\n" expect "N1:([^ ]+) N2:([^ ]+) N3:([^ ]+) N4:([^ ]+) N5:([^ ]+) N6:([^ ]+) N7:([^ ]+) N8:([^ ]+) N9:([^ ]+) N10:([^ ]+) N11:[^ ]+ N12:[^ ]+[[:space:]]*\r\n" setplugstate "1" $1 setplugstate "2" $2 setplugstate "3" $3 setplugstate "4" $4 setplugstate "5" $5 setplugstate "6" $6 setplugstate "7" $7 setplugstate "8" $8 setplugstate "9" $9 setplugstate "10" $10 } script status_beacon_all { send "be *\r\n" expect "N1:([A-Z]+) N2:([A-Z]+) N3:([A-Z]+) N4:([A-Z]+) N5:([A-Z]+) N6:([A-Z]+) N7:([A-Z]+) N8:([A-Z]+) N9:([A-Z]+) N10:([A-Z]+) N11:[A-Z]+ N12:[A-Z]+[[:space:]]*\r\n" setplugstate "1" $1 off="OFF" on="ON" setplugstate "2" $2 off="OFF" on="ON" setplugstate "3" $3 off="OFF" on="ON" setplugstate "4" $4 off="OFF" on="ON" setplugstate "5" $5 off="OFF" on="ON" setplugstate "6" $6 off="OFF" on="ON" setplugstate "7" $7 off="OFF" on="ON" setplugstate "8" $8 off="OFF" on="ON" setplugstate "9" $9 off="OFF" on="ON" setplugstate "10" $10 off="OFF" on="ON" } script on { send "ph %s\r\n" expect "OK\r\n" delay 0.7 } script on_all { send "ph *\r\n" expect "OK\r\n" delay 7 } script off { send "pl %s\r\n" expect "OK\r\n" delay 0.7 } script off_all { send "pl *\r\n" expect "OK\r\n" delay 7 } script cycle { send "pl %s\r\n" expect "OK\r\n" delay 4 send "ph %s\r\n" expect "OK\r\n" delay 0.7 } script cycle_all { send "pl *\r\n" expect "OK\r\n" delay 9 send "ph *\r\n" expect "OK\r\n" delay 7 } script reset { send "rp %s\r\n" expect "OK\r\n" delay 0.7 } script reset_all { send "rp *\r\n" expect "OK\r\n" delay 7 } script beacon_on { send "be %s on\r\n" expect "OK\r\n" delay 2 } script beacon_off { send "be %s off\r\n" expect "OK\r\n" delay 2 } } powerman-2.3.27/etc/ics8064.dev000066400000000000000000000032441415616035500160210ustar00rootroot00000000000000# # ICS 8064 16-port relay box using 'ics8064' utility from gpib-utils project. # # "/usr/bin/ics8064 --shell|&" # # Remember to run: # ics8064 --comm-timeout=0 # ics8064 --commit-config # specification "ics8064" { timeout 5 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" } script login { expect "ics8064> " } script logout { send "quit\n" } script status_all { send "status\n" expect "([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01]), ([01])\n" setplugstate "1" $1 off="0" on="1" setplugstate "2" $2 off="0" on="1" setplugstate "3" $3 off="0" on="1" setplugstate "4" $4 off="0" on="1" setplugstate "5" $5 off="0" on="1" setplugstate "6" $6 off="0" on="1" setplugstate "7" $7 off="0" on="1" setplugstate "8" $8 off="0" on="1" setplugstate "9" $9 off="0" on="1" setplugstate "10" $10 off="0" on="1" setplugstate "11" $11 off="0" on="1" setplugstate "12" $12 off="0" on="1" setplugstate "13" $13 off="0" on="1" setplugstate "14" $14 off="0" on="1" setplugstate "15" $15 off="0" on="1" setplugstate "16" $16 off="0" on="1" expect "ics8064> " } script on_ranged { send "close %s\n" expect "ics8064> " } script off_ranged { send "open %s\n" expect "ics8064> " } script cycle_ranged { send "open %s\n" expect "ics8064> " delay 4 send "close %s\n" expect "ics8064> " } } powerman-2.3.27/etc/ilom.dev000066400000000000000000000025011415616035500156540ustar00rootroot00000000000000# # Sun Integrated Lights Out Management card # # Verified on: # Sunfire X4140 SP firmware 2.0.2.3 build 29049, SP file system 0.1.16 # Sunfire X4550 SP firmware 2.0.2.5 build 32394, SP file system 0.1.16 # # Examples: # over SER MGT RJ-45 (serial via cyclades) # device "ilom" "ilom" "usr-ts:7016" # over SER MGT RJ-45 (direct serial) # device "ilom" "ilom" "/dev/ttyS1" "9600,8n1" # over NET MGT RJ-45 (network over ssh) # device "ilom" "ilom" "ssh -o StrictHostKeyChecking=no -lroot sol|&" # specification "ilom" { timeout 10 plug name { "1" } # login script handles three cases: # 1) serial port, already logged in # 2) serial port, not logged in # 3) ssh, enter password only script login { send "\n" expect "->|Password:|login: " send "root\n" expect "->|Password: " send "changeme\n" expect "->" } script status { send "show -d properties /SYS\n" expect "(POWERSTATE|power_state)[^Oo]+(On|Off|on|off)" setplugstate "1" $2 on="On|on" off="Off|off" expect "->" } script on { send "start -script /SYS\n" expect "->" } script off { send "stop -script -force /SYS\n" expect "->" } script cycle { send "stop -script -force /SYS\n" expect "->" delay 4 send "start -script /SYS\n" expect "->" } script reset { send "reset -script /SYS\n" expect "->" } } powerman-2.3.27/etc/ipmi.dev000066400000000000000000000024571415616035500156640ustar00rootroot00000000000000# # $Id$ # # IPMI 1.5 in terminal mode # Tested on Intel SE7501WV2 motherboard over serial. # On this motherboard, the System Setup Utility is used to switch # the BMC into terminal mode. # # References: # "IPMI over Cyclades TS2000", M.P. Anand Babu # "IPMI 1.5 Reference Guide", 13.7.8 Terminal Mode ASCII Text Commands (p.175) # http://www.intel.com/design/servers/ipmi/ # http://www.intel.com/design/servers/ipmi/spec.htm # # specification "ipmi" { timeout 10 plug name { "1" } script login { send "\033(" expect "\\[TMODE OK\\]\r\n" send "[SYS PWD -N]\r" # null password/username expect "\\[OK\\]\r\n" } script logout { send "[SYS PWD -X]\r" } script status { send "[SYS HEALTH QUERY]\r" expect "\\[OK PWR:(ON|OFF|SLP|S4|S3|S2|S1).*\\]\r\n" setplugstate "1" $1 on="ON" off="OFF|SLP|S4|S3|S2|S1" } script on { send "[SYS POWER ON]\r" expect "\\[OK\\]\r\n" } script off { send "[SYS POWER OFF]\r" expect "\\[OK\\]\r\n" } script reset { send "[SYS RESET]\r" expect "\\[OK\\]\r\n" } script cycle { send "[SYS POWER OFF]\r" expect "\\[OK\\]\r\n" delay 4 send "[SYS POWER ON]\r" expect "\\[OK\\]\r\n" } script status_temp { send "[SYS HEALTH QUERY]\r" expect "\\[OK PWR:[^ ]* H:.. T:(ok|nc|cr|nr|uf).*\\]\r\n" setplugstate "1" $1 } } powerman-2.3.27/etc/ipmipower-serial.dev000066400000000000000000000031651415616035500202130ustar00rootroot00000000000000# # $Id$ # # This device configuration supports power control via the # 'ipmipower' utility. # # This device file is identical to the ipmipower.dev device file, # except that power control scripts are not ranged. Therefore, power # control operations are passed to ipmipower serially instead of in a # range. # # This device file may be more useful than ipmipower.dev on networks # that do not scale well and require power control operations to be # sent out more slowly. It may also be useful when ipmipower is # executed with the --oem-power-type option. A number of IPMI power # controllable devices may not be able to handle power control # operations quickly and the operations must be slowed down. # # off,delay,on used in place of IPMI cycle to ensure full command # completion before returning to the user. # specification "ipmipowerserial" { timeout 60 script login { expect "ipmipower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+)\n" setplugstate $1 $2 on="on" off="off" } expect "ipmipower> " } script status_beacon_all { send "identify-status\n" foreachnode { expect "([^\n:]+): ([^\n]+)\n" setplugstate $1 $2 on="on" off="off" } expect "ipmipower> " } script on { send "on %s\n" expect "ipmipower> " } script off { send "off %s\n" expect "ipmipower> " } script cycle { send "off %s\n" expect "ipmipower> " delay 5 send "on %s\n" expect "ipmipower> " } script beacon_on { send "identify-on %s\n" expect "ipmipower> " } script beacon_off { send "identify-off %s\n" expect "ipmipower> " } } powerman-2.3.27/etc/ipmipower.dev000066400000000000000000000032141415616035500167310ustar00rootroot00000000000000# # $Id$ # # This device configuration supports power control via the FreeIPMI # 'ipmipower' utility. # # Powerman.conf will typically be setup like this: # # include "/etc/powerman/ipmipower.dev" # device "ipmipower1" "ipmipower" "/usr/sbin/ipmipower -h pnode1 --wait-until-on --wait-until-off |&" # node "node1" "ipmipower1" "pnode1" # # If may also be necessary to configure a username and password for # ipmipower. It may be configured on the command line above or # (recommended) via the FreeIPMI configuration file. # # some IPMI devices require some time for the firmware to # reload/re-settle itself after a power-off. A delay of 5 seconds # seems to work fine pretty well. # # off,delay,on used in place of IPMI cycle to ensure full command # completion before returning to the user. # specification "ipmipower" { timeout 60 script login { expect "ipmipower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "ipmipower> " } script status_beacon_all { send "identify-status\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "ipmipower> " } script on_ranged { send "on %s\n" expect "ipmipower> " } script off_ranged { send "off %s\n" expect "ipmipower> " } script cycle_ranged { send "off %s\n" expect "ipmipower> " delay 5 send "on %s\n" expect "ipmipower> " } script beacon_on_ranged { send "identify-on %s\n" expect "ipmipower> " } script beacon_off_ranged { send "identify-off %s\n" expect "ipmipower> " } } powerman-2.3.27/etc/kvm-ssh.dev000066400000000000000000000022211415616035500163030ustar00rootroot00000000000000###KVM (Kernel-based Virtual Machine) over ssh script### # PowerMan script for controlling virtual machines running on remote KVM (Kernel-based Virtual Machine) hypervisors, e.g. # after setting up passwordless ssh access to hypervisor: # device "hypervisor_hostname/IP_address" "kvm-ssh" "/usr/bin/ssh -o StrictHostKeyChecking=no -a -l username -p 22 hypervisor_hostname/IP_address|&" # node "vm_name" "hypervisor_hostname/IP_address" "vm_name" # specification "kvm-ssh" { timeout 5 script login { expect "#" } script logout { send "exit\n" } script status { send "virsh domstate %s\n" expect "(running|off)" setplugstate $1 off="off" on="running" } script on { send "virsh start %s\n" expect "started|Domain is already active" } script off { send "virsh destroy %s\n" expect "destroyed|domain is not running" } script cycle { #yes, there is a reset command, but it does nothing if the vm is powered off send "virsh destroy %s\n" expect "destroyed|domain is not running" delay 1 send "virsh start %s\n" expect "started|Domain is already active" } } powerman-2.3.27/etc/kvm.dev000066400000000000000000000015751415616035500155230ustar00rootroot00000000000000###KVM (Kernel-based Virtual Machine) script### # PowerMan script for controlling virtual machines running on local KVM (Kernel-based Virtual Machine) hypervisors, e.g. # # device "kvm" "kvm" "/usr/bin/virsh |&" # node "vm_name" "kvm" "vm_name" # specification "kvm" { timeout 5 script login { expect "virsh #" } script logout { send "quit\n" } script status { send "domstate %s\n" expect "(running|off)" setplugstate $1 off="off" on="running" } script on { send "start %s\n" expect "started|Domain is already active" } script off { send "destroy %s\n" expect "destroyed|domain is not running" } script cycle { #yes, there is a reset command, but it does nothing if the vm is powered off send "destroy %s\n" expect "destroyed|domain is not running" delay 1 send "start %s\n" expect "started|Domain is already active" } } powerman-2.3.27/etc/lom.dev000066400000000000000000000022621415616035500155070ustar00rootroot00000000000000# # Sun LOM # # Verified on (only via ssh so far): # Sun v40, Version V2.1.0.16 # # Examples: # over SER MGT RJ-45 (serial via cyclades) # device "lom" "lom" "usr-ts:7016" # over SER MGT RJ-45 (direct serial) # device "lom" "lom" "/dev/ttyS1" "9600,8n1" # over NET MGT RJ-45 (network over ssh) # device "lom" "lom" "ssh -o StrictHostKeyChecking=no -ladmin sol|&" # specification "lom" { timeout 10 plug name { "1" } # login script handles three cases: # 1) serial port, already logged in # 2) serial port, not logged in # 3) ssh, enter password only script login { send "\n" expect "\\$|assword:|login: " send "admin\n" expect "\\$|assword: " send "admin\n" expect "\\$" } script status { send "platform get power state\n" expect "(On|Off)" setplugstate "1" $1 on="On" off="Off" expect "\\$" } script on { send "platform set power state -W -f -q on\n" expect "\\$" delay 3 } script off { send "platform set power state -W -f -q off\n" expect "\\$" delay 3 } script cycle { send "platform set power state -W -f -q off\n" expect "\\$" delay 4 send "platform set power state -W -f -q on\n" expect "\\$" delay 3 } } powerman-2.3.27/etc/openbmc.dev000066400000000000000000000054461415616035500163520ustar00rootroot00000000000000# Support for OpenBMC Rest Interface # # Powerman.conf should look something like this: # include "/etc/powerman/openbmc.dev" # device "openbmc1" "openbmc" "/usr/sbin/httppower -u https://pnode1 -H Content-Type:application/json -c |&" # node "node1" "openbmc1" "pnode1" # # Tested on IBM 8335-GTW w/ firmware ibm-v2.0-0-r46-0-gbed584c. Known issues: # - openbmc's power on/off returns success before the operation has # been completed on the node. The operation typically takes 20-25 # seconds complete. To ensure powerman does not return before the # on/off is completed, we add a delay of 30 seconds. # - httppower can be configured with only one node, so one httppower # co-process is needed for every openbmc node in a cluster. This # can present scalability problems at larger scales. # - There is no background management of up/down status of openbmc # targets. At larger scales, when there will almost always be one # node removed for servicing, and unresponsive target will always # lead to powerman to timeout. # - A longer term solution is being investigated, see: # https://github.com/chaos/powerman/issues/34. # specification "openbmc" { timeout 40 # login uses openbmc default username/password, adjust if necessary script login { expect "httppower> " send "post login {\"data\":[\"root\",\"0penBmc\"]}\n" expect "httppower> " } script logout { send "post logout {\"data\":[]}\n" expect "httppower> " send "quit\n" } script status { send "get xyz/openbmc_project/state/chassis0/attr/CurrentPowerState\n" expect "xyz.openbmc_project.State.Chassis.PowerState.(On|Off)" setplugstate $1 on="On" off="Off" expect "httppower> " } script on { send "put xyz/openbmc_project/state/host0/attr/RequestedHostTransition {\"data\":\"xyz.openbmc_project.State.Host.Transition.On\"}\n" expect "httppower> " delay 30 send "get xyz/openbmc_project/state/chassis0/attr/CurrentPowerState\n" expect "xyz.openbmc_project.State.Chassis.PowerState.On" } # this is a soft power off, hard power off will bring down the bmc script off { send "put xyz/openbmc_project/state/host0/attr/RequestedHostTransition {\"data\":\"xyz.openbmc_project.State.Host.Transition.Off\"}\n" expect "httppower> " delay 30 send "get xyz/openbmc_project/state/chassis0/attr/CurrentPowerState\n" expect "xyz.openbmc_project.State.Chassis.PowerState.Off" } script cycle { send "put xyz/openbmc_project/state/host0/attr/RequestedHostTransition {\"data\":\"xyz.openbmc_project.State.Host.Transition.Reboot\"}\n" expect "httppower> " delay 30 send "get xyz/openbmc_project/state/chassis0/attr/CurrentPowerState\n" expect "xyz.openbmc_project.State.Chassis.PowerState.On" } } powerman-2.3.27/etc/phantom.dev000066400000000000000000000023011415616035500163600ustar00rootroot00000000000000# # Rackable Phantom v3 and v4. # specification "phantom" { timeout 15.0 plug name { "1" } script login { send "\036\035" # enter "shell mode" expect "ok\r" } script status { send "P?" expect "(0|1)\r" setplugstate "1" $1 on="1" off="0" } script on { send "P?" expect "(0|1)\r" setplugstate "1" $1 on="1" off="0" ifoff { send "PT" expect "ok\r" } } script off { send "P?" expect "(0|1)\r" setplugstate "1" $1 on="1" off="0" ifon { send "PT" expect "ok\r" } } script cycle { send "P?" expect "(0|1)\r" setplugstate "1" $1 on="1" off="0" ifon { send "PT" expect "ok\r" delay 4 } send "PT" expect "ok\r" } script beacon_on { send "L1" # LED on expect "ok\r" send "B1" # blink LED expect "ok\r" } script beacon_off { send "L0" # LED off expect "ok\r" send "B0" # unblink LED expect "ok\r" } script status_beacon { send "L?" # get LED status 1=on, 0=off, B=blink expect "(0|1|B)\r" setplugstate "1" $1 on="(B|1)" off="0" } # N.B. phantom 3 requires probe #, phantom 4 ignores it script status_temp { send "T0" # get temp probe 0 expect "([0-9]+)\r" # value is 8-bit Celcius setplugstate "1" $1 } } powerman-2.3.27/etc/plmpower.dev000066400000000000000000000015371415616035500165710ustar00rootroot00000000000000# # Control Insteon/X10 devices via SmartLabs PLM 2412S using the plmpower # utility supplied with powerman, e.g. # # device "plm" "plmpower" "/usr/sbin/plmpower -d /dev/ttyS1 |&" # # Plug names are one of: # - Insteon addresses printed on device xx.xx.xx, e.g. "A4.02.B3" # - X10 address [A-P][1-16], e.g. "G13" # # N.B.: X10 devices will always show power status "unknown". # specification "plmpower" { timeout 10 script login { expect "plmpower> " } script logout { send "quit\n" } script status { send "status %s\n" expect "([^:]+): ([^\n]+)\n" setplugstate $1 $2 off="00" on="[0-9A-F]{2}" expect "plmpower> " } script on { send "on %s\n" expect "plmpower> " } script off { send "off %s\n" expect "plmpower> " } script cycle { send "off %s\n" expect "plmpower> " delay 4 send "on %s\n" expect "plmpower> " } } powerman-2.3.27/etc/powerman.conf.example000066400000000000000000000101561415616035500203520ustar00rootroot00000000000000# Example powerman.conf file - see powerman.conf(1) # Uncomment to enable TCP wrappers #tcpwrappers yes # Uncomment to listen on all ports (default is 127.0.0.1:10101) #listen "0.0.0.0:10101" # Uncomment to set syslog level for power on/off/reset/cycle requests # (default is debug). Accepts the same level strings as logger(1). #plug_log_level "info" # Include device specifications for power controllers #include "/etc/powerman/apc7900.dev" #include "/etc/powerman/apc.dev" #include "/etc/powerman/apcnew.dev" #include "/etc/powerman/apcold.dev" #include "/etc/powerman/apcpdu3.dev" #include "/etc/powerman/apcpdu.dev" #include "/etc/powerman/bashfun.dev" #include "/etc/powerman/baytech.dev" #include "/etc/powerman/baytech-rpc28-nc.dev" #include "/etc/powerman/baytech-rpc3-nc.dev" #include "/etc/powerman/cb-7050.dev" #include "/etc/powerman/cyclades-pm10.dev" #include "/etc/powerman/cyclades-pm20.dev" #include "/etc/powerman/cyclades-pm42.dev" #include "/etc/powerman/cyclades-pm8.dev" #include "/etc/powerman/dli.dev" #include "/etc/powerman/hp3488.dev" #include "/etc/powerman/hpilo.dev" #include "/etc/powerman/hpmpblade.dev" #include "/etc/powerman/hpmpcell.dev" #include "/etc/powerman/hpmp.dev" #include "/etc/powerman/hpmpdome.dev" #include "/etc/powerman/ibmbladecenter.dev" #include "/etc/powerman/icebox3.dev" #include "/etc/powerman/icebox.dev" #include "/etc/powerman/ics8064.dev" #include "/etc/powerman/ilom.dev" #include "/etc/powerman/ipmi.dev" #include "/etc/powerman/ipmipower.dev" #include "/etc/powerman/lom.dev" #include "/etc/powerman/phantom.dev" #include "/etc/powerman/plmpower.dev" #include "/etc/powerman/powerman.dev" #include "/etc/powerman/swpdu.dev" #include "/etc/powerman/wti.dev" #include "/etc/powerman/wti-rps10.dev" # Define devices (instances of power controllers) # - Network-attached devices use the form: # device "name" "type" "host:port" # - Serial-attached devices use the form # device "name" "type" "special file" "flags" # where "flags" specifies baud and parms such as "9600,8n1" # - Devices that are accessed via coprocesses use the form # device "name" "type" "executable-path [args...] |&" # - The "name" field should be unique, and will be referenced in node defs. # - The "type" field should match the quoted string at the beginning of # the device specification. #device "b1" "baytech-rpc28-nc" "cyclades1:7032" #device "b2" "baytech-rpc28-nc" "cyclades1:7016" #device "b3" "baytech-rpc28-nc" "/usr/bin/conman -j -Q b3 |&" #device "b4" "baytech-rpc3-nc" "baytech4:23" #device "lpc" "dli" "/usr/sbin/httppower -u http://192.168.0.100 |&" #device "plm" "plmpower" "/usr/sbin/plmpower -d /dev/ttyS1 |&" #device "wti1" "wti-rps10" "/dev/ttyS0" "9600,8n1" #device "wti2" "wti-rps10" "/dev/ttyS2" "9600,8n1" #device "ipmi1" "ipmipower" "/usr/sbin/ipmipower --wait-until-on --wait-until-off -h py[0-10] |&" # Define nodes (the entities you turn on and off with powerman) # - The longhand form is one line per node like this: # node "node" "device" "plug" # where "node" is the name you will use to refer to the node, # "device" refers to the name you assigned above to the device the # node is plugged into, and "plug" is the (device specific) plug identifier # defined in the "plug name" portion of the device specification or # otherwise following the pattern expected by that device. # - It is possible to use hostranges to map ranges of nodes to ranges # of plugs as follows: # node "noderange" "device" "plugrange" # - And if you just want to assign all the plugs in order, you can drop # the plug range: # node "noderange" "device" #node "t1" "b1" "4" # first four plugs of 'b1' wired backwards #node "t2" "b1" "3" #node "t3" "b1" "2" #node "t4" "b1" "1" #node "t[5-20]" "b1" "[5-20]" #node "t[21-40]" "b2" #node "t[41-60]" "b3" #node "x[1-8]" "lpc" #node "y[0-10]" "ipmi1" "py[0-10]" #node "porchlight" "plm" "A4.02.B3" #node "kitchen" "plm" "A4.97.44" #node "lamp" "plm" "G13" # Aliases can be used to make new names for plugs, or to have one name # refer to redundant power supplies. #node "jimmy-ps1" "wti1" "7" #node "jimmy-ps2" "wti2" "7" #alias "jimmy" "jimmy-ps[1-2]" powerman-2.3.27/etc/powerman.dev000066400000000000000000000020331415616035500165440ustar00rootroot00000000000000# # $Id$ # # PowerMan script for controlling another PowerMan daemon, e.g. # # device "cartman" "powerman" "cartman.llnl.gov:10101" # node "b[1-4]" "cartman" "b[1-4]" # # N.B. master powerman.conf must contain the union of all slave # powerman.conf plugs, or status_all script will not work. # specification "powerman" { timeout 100.0 script login { expect "powerman> " send "exprange\r\n" expect "105 Hostrange expansion ON\r\npowerman> " } script logout { send "quit\r\n" } script status_all { send "status\r\n" foreachplug { expect "303 ([^:]+): (off|on|unknown)\r\n" setplugstate $1 $2 off="off" on="on" } expect "powerman> " } script on_ranged { send "on %s\r\n" expect "powerman> " } script off_ranged { send "off %s\r\n" expect "powerman> " } script cycle_ranged { send "cycle %s\r\n" expect "powerman> " } script reset_ranged { send "reset %s\r\n" expect "powerman> " } } powerman-2.3.27/etc/rancid-cisco-poe.dev000066400000000000000000000026131415616035500200370ustar00rootroot00000000000000# # Control POE on Cisco switches via rancid (http://www.shrubbery.net/rancid/) # # device "cisco-switch" "rancid-cisco-poe" "/usr/lib/rancid/bin/clogin hostname |&" # # Plug names are the device interface name: # node "mydevice" "cisco-switch" "Gi2/0/1" # # The user running the powerman must have a .cloginrc file in its home directory # with an appropriate configuration to allow querying and setting PoE status # specification "rancid-cisco-poe" { timeout 10 script login { expect ".*#" } script logout { send "exit\n" } script status { send "show power inline %s | section (on|off) \n" expect "\r\n([^ ]+) +[^ ]+ +(on|off)" setplugstate $1 $2 off="off" on="on" expect ".*#" } script on { send "conf t\n" expect ".*\\(config\\)#" send "int %s\n" expect ".*\\(config-if\\)#" send "no power inline never\n" expect ".*\\(config-if\\)#" send "end\n" expect ".*#" } script off { send "conf t\n" expect ".*\\(config\\)#" send "int %s\n" expect ".*\\(config-if\\)#" send "power inline never\n" expect ".*\\(config-if\\)#" send "end\n" expect ".*#" } script cycle { send "conf t\n" expect ".*\\(config\\)#" send "int %s\n" expect ".*\\(config-if\\)#" send "power inline never\n" expect ".*\\(config-if\\)#" delay 4 send "no power inline never\n" expect ".*\\(config-if\\)#" send "end\n" expect ".*#" send "off %s\n" expect ".*#" } } powerman-2.3.27/etc/raritan-px4316.dev000066400000000000000000000027211415616035500173230ustar00rootroot00000000000000# Rariton PX 4316 via SNMP # Example powerman.conf device line: # device "r1" "raritan-px4316" "/usr/sbin/snmppower -h r1|&" # specification "raritan-px4316" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" } script login { expect "snmppower> " send "start_v2c private\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } script status { # -1=error, 0=off, 1=on, 2=cycling send "get enterprises.13742.4.1.2.2.1.3.%s\n" expect "enterprises.13742.4.1.2.2.1.3.([0-9]+): (0|1)" setplugstate $1 $2 on="1" off="0" expect "snmppower> " } # This is really watts! script status_temp { send "get enterprises.13742.4.1.2.2.1.7.%s\n" expect "enterprises.13742.4.1.2.2.1.7.([0-9]+) = Gauge32: ([0-9]+)" setplugstate $1 $2 } script on { send "set enterprises.13742.4.1.2.2.1.3.%s i 1\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } script off { send "set enterprises.13742.4.1.2.2.1.3.%s i 0\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " } script cycle { send "set enterprises.13742.4.1.2.2.1.3.%s i 0\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " delay 5 send "set enterprises.13742.4.1.2.2.1.3.%s i 1\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } } powerman-2.3.27/etc/raritan-px5523.dev000066400000000000000000000030251415616035500173220ustar00rootroot00000000000000# Rariton PX 5523 via SNMP # Example powerman.conf device line: # device "r1" "raritan-px5523" "/usr/sbin/snmppower -h r1|&" # specification "raritan-px5523" { timeout 10 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" } script login { expect "snmppower> " send "start_v2c raritan_private\n" expect "snmppower> " } script logout { send "finish\n" expect "snmppower> " } script status { # -1=error, 0=off, 1=on, 2=cycling send "get enterprises.13742.4.1.2.2.1.3.%s\n" expect "enterprises.13742.4.1.2.2.1.3.([0-9]+): (0|1)" setplugstate $1 $2 on="1" off="0" expect "snmppower> " } # This is really watts! script status_temp { send "get enterprises.13742.4.1.2.2.1.7.%s\n" expect "enterprises.13742.4.1.2.2.1.7.([0-9]+) = Gauge32: ([0-9]+)" setplugstate $1 $2 } script on { send "set enterprises.13742.4.1.2.2.1.3.%s i 1\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } script off { send "set enterprises.13742.4.1.2.2.1.3.%s i 0\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " } script cycle { send "set enterprises.13742.4.1.2.2.1.3.%s i 0\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 0\n" expect "snmppower> " delay 5 send "set enterprises.13742.4.1.2.2.1.3.%s i 1\n" expect "enterprises.13742.4.1.2.2.1.3.[0-9]+: 1\n" expect "snmppower> " delay 0.3 } } powerman-2.3.27/etc/redfish-supermicro.dev000066400000000000000000000040221415616035500205260ustar00rootroot00000000000000# Support for Redfish Rest Interface # # Powerman.conf should look something like this: # include "/etc/powerman/redfish-supermicro.dev" # device "redfish1" "redfish-supermicro" "/usr/sbin/httppower -u https://pnode1 -H Content-Type:application/json |&" # node "node1" "redfish1" "pnode1" # # - Set your system's username/password in the login section below # # - This device specification was tested on a Supermicro H12DSG-O-CPU. # # - If using a slightly different model or BMC firmware version, its # possible the URI paths will be different. A good starting point # is to run the following command to discover the correct paths: # # curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems/1 # # - This device specification has been supplanted by # redfishpower-supermicro.dev, which does not require fragile delays # to ensure power operations are complete before the script # returns. Users should migrate to the new one. # specification "redfish-supermicro" { timeout 40 script login { expect "httppower> " send "auth USER:PASS\n" expect "httppower> " } script logout { send "quit\n" } script status { send "get redfish/v1/Systems/1/\n" expect "\"PowerState\":\"(On|Off)\"" setplugstate $1 on="On" off="Off" expect "httppower> " } script on { send "post redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n" expect "httppower> " delay 30 send "get redfish/v1/Systems/1/\n" expect "\"PowerState\":\"On\"" } script off { send "post redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n" expect "httppower> " delay 30 send "get redfish/v1/Systems/1/\n" expect "\"PowerState\":\"Off\"" } script cycle { send "post redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n" expect "httppower> " delay 30 send "get redfish/v1/Systems/1/\n" expect "\"PowerState\":\"On\"" } } powerman-2.3.27/etc/redfishpower-cray-r272z30.dev000066400000000000000000000034761415616035500214140ustar00rootroot00000000000000# Support for Redfish Rest Interface # # Powerman.conf should look something like this: # include "/etc/powerman/redfishpower-cray-r272z30.dev" # device "redfishpower" "redfishpower-cray-r272z30" "/usr/sbin/redfishpower -h pnode[1-2] |&" # node "node1" "redfishpower" "pnode1" # node "node2" "redfishpower" "pnode2" # # - Set your system's username/password in the login section below # # - This device specification was tested on a Cray with Gigabyte R272-Z30. # # - If using a slightly different model or BMC firmware version, its # possible the URI paths will be different. A good starting point # is to run the following command to discover the correct paths: # # curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems # specification "redfishpower-cray-r272z30" { timeout 60 script login { expect "redfishpower> " send "auth USER:PASS\n" expect "redfishpower> " send "setheader Content-Type:application/json\n" expect "redfishpower> " send "setstatpath redfish/v1/Systems/Self\n" expect "redfishpower> " send "setonpath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n" expect "redfishpower> " send "setoffpath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n" expect "redfishpower> " send "setcyclepath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n" expect "redfishpower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "redfishpower> " } script on_ranged { send "on %s\n" expect "redfishpower> " } script off_ranged { send "off %s\n" expect "redfishpower> " } script cycle_ranged { send "cycle %s\n" expect "redfishpower> " } } powerman-2.3.27/etc/redfishpower-cray-windom.dev000066400000000000000000000062431415616035500216530ustar00rootroot00000000000000# Support for Redfish Rest Interface # # Powerman.conf should look something like this: # include "/etc/powerman/redfishpower-cray-windom.dev" # device "redfishpower0" "redfishpower-cray-windom-node0" "/usr/sbin/redfishpower -h pnode[1,3] |&" # device "redfishpower1" "redfishpower-cray-windom-node1" "/usr/sbin/redfishpower -h pnode[2,4] |&" # node "node1" "redfishpower0" "pnode1" # node "node2" "redfishpower1" "pnode2" # node "node3" "redfishpower0" "pnode3" # node "node4" "redfishpower1" "pnode4" # # - Set your system's username/password in the login section below # # - This device specification was tested on a Cray Windom. # # - Two specifications are listed below with a slightly different URI # suffix ("Node0" vs "Node1") depending on the specific node # attached to a blade's service processor. Some experimentation may # be needed to determine which node is attached to which suffix. # # - If using a slightly different model or BMC firmware version, its # possible the URI paths will be different. A good starting point # is to run the following command to discover the correct paths: # # curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems # specification "redfishpower-cray-windom-node0" { timeout 60 script login { expect "redfishpower> " send "auth USER:PASS\n" expect "redfishpower> " send "setheader Content-Type:application/json\n" expect "redfishpower> " send "setstatpath redfish/v1/Systems/Node0\n" expect "redfishpower> " send "setonpath redfish/v1/Systems/Node0/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n" expect "redfishpower> " send "setoffpath redfish/v1/Systems/Node0/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n" expect "redfishpower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "redfishpower> " } script on_ranged { send "on %s\n" expect "redfishpower> " } script off_ranged { send "off %s\n" expect "redfishpower> " } script cycle_ranged { send "on %s\n" expect "redfishpower> " send "off %s\n" expect "redfishpower> " } } specification "redfishpower-cray-windom-node1" { timeout 60 script login { expect "redfishpower> " send "auth USER:PASS\n" expect "redfishpower> " send "setheader Content-Type:application/json\n" expect "redfishpower> " send "setstatpath redfish/v1/Systems/Node1\n" expect "redfishpower> " send "setonpath redfish/v1/Systems/Node1/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n" expect "redfishpower> " send "setoffpath redfish/v1/Systems/Node1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n" expect "redfishpower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "redfishpower> " } script on_ranged { send "on %s\n" expect "redfishpower> " } script off_ranged { send "off %s\n" expect "redfishpower> " } script cycle_ranged { send "on %s\n" expect "redfishpower> " send "off %s\n" expect "redfishpower> " } } powerman-2.3.27/etc/redfishpower-supermicro.dev000066400000000000000000000034521415616035500216110ustar00rootroot00000000000000# Support for Redfish Rest Interface # # Powerman.conf should look something like this: # include "/etc/powerman/redfishpower-supermicro.dev" # device "redfishpower" "redfishpower-supermicro" "/usr/sbin/redfishpower -h pnode[1-2] |&" # node "node1" "redfishpower" "pnode1" # node "node2" "redfishpower" "pnode2" # # - Set your system's username/password in the login section below # # - This device specification was tested on a Supermicro H12DSG-O-CPU. # # - If using a slightly different model or BMC firmware version, its # possible the URI paths will be different. A good starting point # is to run the following command to discover the correct paths: # # curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems/1 # specification "redfishpower-supermicro" { timeout 60 script login { expect "redfishpower> " send "auth USER:PASS\n" expect "redfishpower> " send "setheader Content-Type:application/json\n" expect "redfishpower> " send "setstatpath redfish/v1/Systems/1\n" expect "redfishpower> " send "setonpath redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n" expect "redfishpower> " send "setoffpath redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n" expect "redfishpower> " send "setcyclepath redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n" expect "redfishpower> " } script logout { send "quit\n" } script status_all { send "stat\n" foreachnode { expect "([^\n:]+): ([^\n]+\n)" setplugstate $1 $2 on="^on\n" off="^off\n" } expect "redfishpower> " } script on_ranged { send "on %s\n" expect "redfishpower> " } script off_ranged { send "off %s\n" expect "redfishpower> " } script cycle_ranged { send "cycle %s\n" expect "redfishpower> " } } powerman-2.3.27/etc/sentry_cdu.dev000066400000000000000000000106371415616035500171040ustar00rootroot00000000000000# Sentry Switched CDU Version 6.0r specification "sentry_cdu" { timeout 10 plug name { ".AA1" ".AA2" ".AA3" ".AA4" ".AA5" ".AA6" ".AA7" ".AA8" ".AB1" ".AB2" ".AB3" ".AB4" ".AB5" ".AB6" ".AB7" ".AB8" ".AC1" ".AC2" ".AC3" ".AC4" ".AC5" ".AC6" ".AC7" ".AC8" } script login { expect "Username: " send "admn\r\n" expect "Password: " send "admn\r\n" expect "Switched CDU: " } script logout { send "logout\r\n" } script status_all { send "status\r\n" expect "\.AA1[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA1" $1 on="On" off="Off" expect "\.AA2[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA2" $1 on="On" off="Off" expect "\.AA3[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA3" $1 on="On" off="Off" expect "\.AA4[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA4" $1 on="On" off="Off" expect "\.AA5[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA5" $1 on="On" off="Off" expect "\.AA6[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA6" $1 on="On" off="Off" expect "\.AA7[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA7" $1 on="On" off="Off" expect "\.AA8[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AA8" $1 on="On" off="Off" expect "\.AB1[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB1" $1 on="On" off="Off" expect "\.AB2[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB2" $1 on="On" off="Off" expect "\.AB3[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB3" $1 on="On" off="Off" expect "\.AB4[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB4" $1 on="On" off="Off" expect "\.AB5[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB5" $1 on="On" off="Off" expect "\.AB6[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB6" $1 on="On" off="Off" expect "\.AB7[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB7" $1 on="On" off="Off" expect "\.AB8[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AB8" $1 on="On" off="Off" expect "More \\(Y/es N/o\\):" send "y" expect "y\r\n\r\n" expect "\.AC1[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC1" $1 on="On" off="Off" expect "\.AC2[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC2" $1 on="On" off="Off" expect "\.AC3[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC3" $1 on="On" off="Off" expect "\.AC4[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC4" $1 on="On" off="Off" expect "\.AC5[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC5" $1 on="On" off="Off" expect "\.AC6[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC6" $1 on="On" off="Off" expect "\.AC7[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC7" $1 on="On" off="Off" expect "\.AC8[^\r\n]*(On|Off) *(On|Off) *\r\n" setplugstate ".AC8" $1 on="On" off="Off" expect "Command successful" expect "\r\n\r\nSwitched CDU: " } script on { send "on %s\r\n" expect "Switched CDU: " } script on_all { send "on all\r\n" expect "More \\(Y/es N/o\\):" send "y" expect "y\r\n\r\n" expect "Switched CDU: " } script off { send "off %s\r\n" expect "Switched CDU: " } script off_all { send "off all\r\n" expect "More \\(Y/es N/o\\):" send "y" expect "y\r\n\r\n" expect "Switched CDU: " } script cycle { send "off %s\r\n" expect "Switched CDU: " delay 4 send "on %s\r\n" expect "Switched CDU: " } script cycle_all { send "off all\r\n" expect "More \\(Y/es N/o\\):" send "y" expect "y\r\n\r\n" expect "Switched CDU: " delay 4 send "on all\r\n" expect "More \\(Y/es N/o\\):" send "y" expect "y\r\n\r\n" expect "Switched CDU: " } } powerman-2.3.27/etc/swpdu.dev000066400000000000000000000021731415616035500160630ustar00rootroot00000000000000# # Appro SWPDU # # swpdu.dev,v 1.0 2007/11/07 23:50:34 kolee APPRO # /etc/powerman/swpdu.dev,v # specification "swpdu" { timeout 20.0 plug name { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" "40" "41" "42" "43" "44" "45" "46" "47" "48" } script ping { send "\r\n" expect "swpdu> " } script login { # expect "Password:" # send "111111\r\n" send "\r\n" expect "swpdu> " send "exprange on\r\n" expect "swpdu> " } script logout { send "exprange off\r\n" expect "swpdu> " } script status_all { send "status\r\n" foreachplug { expect "port([0-9]+)[^\n]*(on|off|unknown|^n)" setplugstate $1 $2 on="on" off="off" } expect "swpdu> " } script status { send "status %s\r\n" expect "port([0-9]+)[^\n]*(on|off|unknown|^n)" setplugstate $1 $2 on="on" off="off" expect "swpdu> " } script on { send "on %s\r\n" expect "swpdu> " } script off { send "off %s\r\n" expect "swpdu> " } script cycle { send "cycle %s\r\n" expect "swpdu> " } } powerman-2.3.27/etc/vpc.dev000066400000000000000000000042531415616035500155120ustar00rootroot00000000000000# # $Id$ # specification "vpc" { timeout 5.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script on { send "on %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script on_all { send "on *\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script off { send "off %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script off_all { send "off *\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script cycle { send "off %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " delay 1.0 send "on %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script cycle_all { send "off *\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " delay 1.0 send "on *\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script beacon_on { send "flash %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script beacon_off { send "unflash %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script status_beacon_all { send "beacon *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script status_temp_all { send "temp *\n" foreachplug { expect "plug ([0-9]+): ([0-9]+)\n" setplugstate $1 $2 } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script reset_all { send "reset *\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script reset { send "reset %s\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } powerman-2.3.27/etc/wti-rps10.dev000066400000000000000000000022661415616035500164720ustar00rootroot00000000000000# # $Id$ # # WTI RPS-10 # # Master configured for 9600 baud: # if 9600 - wait 0.5 sec before sending next command # if 2400 - wait 1.5 sec before sending next command # Format of commands is ^X^X^B^X^X^B^X^XPC\r # where P is port number (0-9) and C is command (0,1,T,?) # # N.B. The 0.5 sec delays mentioned in the documentation don't seem to be # needed on my setup... # specification "wti-rps10" { timeout 5 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" } script login { delay 2 } script status { send "\030\030\002\030\030\002\030\030%s?\r" expect "Plug ([0-9]) (On|Off)" setplugstate $1 $2 off="Off" on="On" expect "Complete" } script on { send "\030\030\002\030\030\002\030\030%s1\r" expect "Plug [0-9] On" expect "Complete" } script off { send "\030\030\002\030\030\002\030\030%s0\r" expect "Plug [0-9] Off" expect "Complete" } # The T command is dip switch configurable for 5 or 10 second delay # Shorter delays have to be done in s/w. script cycle { send "\030\030\002\030\030\002\030\030%s0\r" expect "Plug [0-9] Off" expect "Complete" delay 4 send "\030\030\002\030\030\002\030\030%s1\r" expect "Plug [0-9] On" expect "Complete" } } powerman-2.3.27/etc/wti.dev000066400000000000000000000022201415616035500155150ustar00rootroot00000000000000# # $Id$ # # WTI NPS # # Tested the following firmware versions: # v3.02 # Assumes: # 1. password: "wti" (/g general parms, 1 system passwd) # 3. command confirmation: off (/g general parms, 8 command confirmation) # 4. disconnect timeout: set to max (30 min) # Note: prompt is not returned until device is ready to accept another command # specification "wti" { timeout 30 # "/boot *" command takes about 20 sec plug name { "1" "2" "3" "4" "5" "6" "7" "8" } script login { expect "\n" expect "word: " send "wti\r\n" expect "NPS> " } script logout { send "/x\r\n" } script status_all { send "/s\r\n" expect "Default" expect "\\+\r\n" foreachplug { expect " ([0-9]+)[^\n]*(ON|OFF)[^\n]*(ON|OFF)[^\n]*\r\n" setplugstate $1 $2 off="OFF" on="ON" } expect "\\+\r\n" expect "NPS> " } script on { send "/on %s\r\n" expect "NPS> " } script on_all { send "/on *\r\n" expect "NPS> " } script off { send "/off %s\r\n" expect "NPS> " } script off_all { send "/off *\r\n" expect "NPS> " } script cycle { send "/boot %s\r\n" expect "NPS> " } script cycle_all { send "/boot *\r\n" expect "NPS> " } } powerman-2.3.27/examples/000077500000000000000000000000001415616035500152615ustar00rootroot00000000000000powerman-2.3.27/examples/powerman_el72.spec.in000066400000000000000000000073311415616035500212270ustar00rootroot00000000000000Name: @PACKAGE_NAME@ Version: @PACKAGE_VERSION@ Release: 1%{?dist} Summary: PowerMan - centralized power control for clusters License: GPL Group: Applications/System Url: http://github.com/chaos/powerman Source0: %{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: tcp_wrappers-devel BuildRequires: libgenders-devel BuildRequires: curl-devel BuildRequires: net-snmp-devel BuildRequires: systemd %package devel Requires: %{name} = %{version}-%{release} Summary: Headers and libraries for developing applications using PowerMan Group: Development/Libraries %package libs Requires: %{name} = %{version}-%{release} Summary: Libraries for applications using PowerMan Group: System Environment/Libraries %description PowerMan is a tool for manipulating remote power control (RPC) devices from a central location. Several RPC varieties are supported natively by PowerMan and Expect-like configurability simplifies the addition of new devices. %description devel A header file and static library for developing applications using PowerMan. %description libs A shared library for applications using PowerMan. %prep %setup %build %configure \ --with-genders \ --with-httppower \ --with-snmppower \ --with-tcp-wrappers \ --with-systemdsystemunitdir=%{_unitdir} \ --program-prefix=%{?_program_prefix:%{_program_prefix}} make %install rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT %clean rm -rf $RPM_BUILD_ROOT %post /bin/systemctl enable powerman > /dev/null 2>&1 ||: %post libs if [ -x /sbin/ldconfig ]; then /sbin/ldconfig %{_libdir}; fi %preun if [ "$1" = 0 ]; then systemctl stop powerman >/dev/null 2>&1 || : systemctl disable powerman > /dev/null 2>&1 || : fi %postun if [ "$1" -ge 1 ]; then systemctl try-restart powerman >/dev/null 2>&1 || : fi %postun libs if [ -x /sbin/ldconfig ]; then /sbin/ldconfig %{_libdir}; fi %files %defattr(-,root,root,0755) %doc DISCLAIMER %doc COPYING %doc NEWS %doc TODO %{_bindir}/powerman %{_bindir}/pm %{_sbindir}/powermand %{_sbindir}/vpcd %{_sbindir}/httppower %{_sbindir}/snmppower %{_sbindir}/plmpower %dir %config %{_sysconfdir}/powerman %{_sysconfdir}/powerman/*.dev %{_sysconfdir}/powerman/powerman.conf.example %{_mandir}/*1/* %{_mandir}/*5/* %{_mandir}/*8/* %{_libdir}/stonith/plugins/external/powerman %{_unitdir}/powerman.service %{_tmpfilesdir}/powerman.conf %files devel %defattr(-,root,root,0755) %{_includedir}/* %{_libdir}/*.la %{_mandir}/*3/* %{_libdir}/*.a %{_libdir}/*.so %{_libdir}/pkgconfig/* %files libs %defattr(-,root,root,0755) %{_libdir}/*.so.* %changelog * Wed Mar 08 2017 Brian J. Murrell 2.3.25-1 - Move the powerman.spec to the examples dir and rename it to powerman_el72.spec to indicate that this spec is just an example that works on EL7.2 * Fri Oct 23 2015 Jim Garlick 2.3.24-1 - Don't package /var/run/powerman; let systemd manage this directory. * Fri May 29 2015 Jim Garlick 2.3.23-1 - Drop conditional builds as full build works everywhere now, more or less - Drop AIX library handling conditionals (unused?) * Fri May 29 2015 Jim Garlick 2.3.20-1 - Switch to systemd init * Tue Feb 14 2006 Ben Woodard 1.0.22-3 - Changed /usr/bin to bindir - Changed /usr/sbin to sbindir - Added COPYING to list of docs. - Changed /etc/rc.d/init.d/ to initrddir - Changed /usr/man to mandir - Added a fully qualified path to the source file. - Fixed buildroot - Added a patch which should fix a fc4 build problem. * Thu Feb 09 2006 Ben Woodard 1.0.22-2 - changed the buildroot to match fedora guidlines - changed permissions of spec and src files. - added changelog to spec file powerman-2.3.27/heartbeat/000077500000000000000000000000001415616035500154025ustar00rootroot00000000000000powerman-2.3.27/heartbeat/Makefile.am000066400000000000000000000001471415616035500174400ustar00rootroot00000000000000hblibdir = $(libdir)/stonith/plugins/external hblib_SCRIPTS = powerman EXTRA_DIST = $(hblib_SCRIPTS) powerman-2.3.27/heartbeat/powerman000077500000000000000000000051401415616035500171600ustar00rootroot00000000000000#!/bin/bash # # heartbeat STONITH module for powerman # # Usage: powerman-stonith [on|off|reset|status] plug # # $serverhost - host:port of powerman server (required) # $poweroff - set to 1 if 'reset' should simply power off (optional) # $PM_OVERRIDE - (undocumented, for test) override powerman path # $PM_VERBOSE - (undocumented, for test) set to enable verbose debug # (1=stderr, 2=syslog, 3=ha_log) PATH=/bin:/usr/sbin:$PATH export PM_VERBOSE=${PM_VERBOSE:-0} # Logging disabled by default export pm=${PM_OVERRIDE:-pm -h $serverhost} pmlog () { case "$PM_VERBOSE" in 1) echo "powerman-stonith: $*" >&2 ;; 2) logger -t heartbeat "powerman-stonith: $*" ;; 3) ha_logger -t heartbeat "powerman-stonith: $*" ;; esac } # N.B. agent must not exit 0 if the target is still on! (chaos bz 1439) # Heartbeat will retry if we fail (don't retry here) pmoff () { local plug=$1 local state rc $pm -0 $plug rc=$? pmlog "$pm -0 $plug, rc=$rc" if [ $rc == 0 ]; then # for multi-plug aliases, all must be off (jira TOSS-1962) for state in $($pm -qx $plug | awk '{ print $NF }'); do if [ "$state" != "off" ]; then state="unknown" rc=1 break; fi done pmlog "$pm -q $plug, state=$state, rc=$rc" fi return $rc # 0=success } pmon () { local plug=$1 local rc $pm -1 $plug rc=$? pmlog "$pm -1 $plug, rc=$rc" return $rc # 0=success } pmcycle () { local plug=$1 local rc $pm -c $plug rc=$? pmlog "$pm -c $plug, rc=$rc" return $rc # 0=success } case $1 in gethosts) exec $pm -lx ;; on) pmon $2 exit $? ;; off) pmoff $2 exit $? ;; reset) if [ "$poweroff" == "1" ]; then pmoff $2 exit $? else pmcycle $2 exit $? fi ;; status) exec $pm -l >/dev/null ;; getconfignames) echo serverhost echo poweroff exit 0 ;; getinfo-devid|getinfo-devname|getinfo-devdescr) echo "powerman STONITH device" exit 0 ;; getinfo-devurl) echo "http://github.com/chaos/powerman" exit 0 ;; getinfo-xml) cat < host:port of powerman server Specify the host:port of the powerman server, e.g. pmserver:10101 Power off when given reset command For V1 heartbeat which always resets to fence, power off when given the reset command. PMEOL exit 0 ;; *) exit 1 ;; esac powerman-2.3.27/httppower/000077500000000000000000000000001415616035500154775ustar00rootroot00000000000000powerman-2.3.27/httppower/Makefile.am000066400000000000000000000003141415616035500175310ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/libcommon sbin_PROGRAMS = httppower httppower_SOURCES = httppower.c httppower_LDADD = $(top_builddir)/libcommon/libcommon.a $(LIBCURL) $(LIBFORKPTY) powerman-2.3.27/httppower/httppower.c000066400000000000000000000230351415616035500177020ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2007 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #if HAVE_CURL_CURL_H #include #else #error httppower needs curl support! #endif #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "error.h" #include "argv.h" static char *url = NULL; static char *header = NULL; static struct curl_slist *header_list = NULL; static int cookies = 0; static int verbose = 0; static char *userpwd = NULL; static char errbuf[CURL_ERROR_SIZE]; #define OPTIONS "u:H:cv" static struct option longopts[] = { {"url", required_argument, 0, 'u' }, {"header", required_argument, 0, 'H' }, {"cookies", no_argument, 0, 'c' }, {"verbose", no_argument, 0, 'v' }, {0,0,0,0}, }; void help(void) { printf("Valid commands are:\n"); printf(" auth user:passwd\n"); printf(" seturl url\n"); printf(" setheader string\n"); printf(" cookies \n"); printf(" get [url]\n"); printf(" post [url] \n"); printf(" put [url] \n"); } char * _make_url(char *str) { char *myurl = NULL; if (str && url) { myurl = xmalloc(strlen(url) + strlen(str) + 2); sprintf(myurl, "%s/%s", url, str); } else if (str && !url) { myurl = xstrdup(str); } else if (!str && url) { myurl = xstrdup(url); } return myurl; } void post(CURL *h, char **av) { char *myurl = NULL; char *postdata = NULL; char *url_ptr = NULL; if (av[0] && av[1]) { postdata = xstrdup(av[1]); myurl = _make_url(av[0]); url_ptr = myurl; } else if (av[0]) { postdata = xstrdup(av[0]); url_ptr = url; } if (postdata && url_ptr) { curl_easy_setopt(h, CURLOPT_POST, 1); curl_easy_setopt(h, CURLOPT_URL, url_ptr); curl_easy_setopt(h, CURLOPT_POSTFIELDS, postdata); curl_easy_setopt(h, CURLOPT_POSTFIELDSIZE, strlen (postdata)); if (curl_easy_perform(h) != 0) printf("Error: %s\n", errbuf); curl_easy_setopt(h, CURLOPT_URL, ""); curl_easy_setopt(h, CURLOPT_POSTFIELDS, ""); curl_easy_setopt(h, CURLOPT_POSTFIELDSIZE, 0); } else printf("Nothing to post!\n"); if (myurl) xfree(myurl); if (postdata) xfree(postdata); } struct put_cb_data { char *data; int offset; }; size_t put_read_cb(char *buffer, size_t size, size_t nitems, void *userdata) { struct put_cb_data *pcd = userdata; memcpy (buffer, pcd->data + pcd->offset, size); pcd->offset += size; return size; } void put(CURL *h, char **av) { char *myurl = NULL; char *putdata = NULL; struct put_cb_data pcd; char *url_ptr = NULL; if (av[0] && av[1]) { putdata = xstrdup(av[1]); myurl = _make_url(av[0]); url_ptr = myurl; } else if (av[0]) { putdata = xstrdup(av[0]); url_ptr = url; } if (putdata && url_ptr) { curl_easy_setopt(h, CURLOPT_UPLOAD, 1); curl_easy_setopt(h, CURLOPT_URL, url_ptr); curl_easy_setopt(h, CURLOPT_READFUNCTION, put_read_cb); pcd.data = putdata; pcd.offset = 0; curl_easy_setopt(h, CURLOPT_READDATA, &pcd); curl_easy_setopt(h, CURLOPT_INFILESIZE, strlen (putdata)); if (curl_easy_perform(h) != 0) printf("Error: %s\n", errbuf); curl_easy_setopt(h, CURLOPT_URL, ""); curl_easy_setopt(h, CURLOPT_UPLOAD, 0); } else printf("Nothing to put!\n"); if (myurl) xfree(myurl); if (putdata) xfree(putdata); } void get(CURL *h, char **av) { char *myurl = _make_url(av[0]); if (myurl) { curl_easy_setopt(h, CURLOPT_HTTPGET, 1); curl_easy_setopt(h, CURLOPT_URL, myurl); if (curl_easy_perform(h) != 0) printf("Error: %s\n", errbuf); curl_easy_setopt(h, CURLOPT_URL, ""); } else printf("Nothing to get!\n"); if (myurl) xfree(myurl); } void seturl(CURL *h, char **av) { if (av[0] == NULL) { printf("Usage: seturl http://...\n"); return; } if (url) xfree(url); url = xstrdup(av[0]); } void setheader(CURL *h, char **av) { if (header) { xfree(header); curl_slist_free_all(header_list); header = NULL; header_list = NULL; } if (av[0]) { header = xstrdup(av[0]); header_list = curl_slist_append(header_list, header); curl_easy_setopt(h, CURLOPT_HTTPHEADER, header_list); } else { curl_easy_setopt(h, CURLOPT_HTTPHEADER, header_list); } } void cookies_enable(CURL *h, char **av) { if (av[0] == NULL || (strcasecmp (av[0], "enable") && strcasecmp (av[0], "disable"))) { printf("Usage: cookies \n"); return; } if (!strcasecmp (av[0], "enable")) { /* enable cookie engine with empty string, no need to read from a real file */ curl_easy_setopt(h, CURLOPT_COOKIEFILE, ""); } else { curl_easy_setopt(h, CURLOPT_COOKIELIST, "ALL"); curl_easy_setopt(h, CURLOPT_COOKIEFILE, NULL); } } void auth(CURL *h, char **av) { if (av[0] == NULL) { printf("Usage: auth user:passwd\n"); return; } if (userpwd) xfree(userpwd); userpwd = xstrdup(av[0]); curl_easy_setopt(h, CURLOPT_USERPWD, userpwd); curl_easy_setopt(h, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); } int docmd(CURL *h, char **av) { int rc = 0; if (av[0] != NULL) { if (strcmp(av[0], "help") == 0) help(); else if (strcmp(av[0], "quit") == 0) rc = 1; else if (strcmp(av[0], "auth") == 0) auth(h, av + 1); else if (strcmp(av[0], "seturl") == 0) seturl(h, av + 1); else if (strcmp(av[0], "setheader") == 0) setheader(h, av + 1); else if (strcmp(av[0], "cookies") == 0) cookies_enable(h, av + 1); else if (strcmp(av[0], "get") == 0) get(h, av + 1); else if (strcmp(av[0], "post") == 0) post(h, av + 1); else if (strcmp(av[0], "put") == 0) put(h, av + 1); else printf("type \"help\" for a list of commands\n"); } return rc; } void shell(CURL *h) { char buf[128]; char **av; int rc = 0; while (rc == 0) { printf("httppower> "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin)) { av = argv_create(buf, ""); rc = docmd(h, av); argv_destroy(av); } else rc = 1; } } void usage(void) { fprintf(stderr, "Usage: httppower [--url URL] [--header string] [--cookies]\n"); exit(1); } int main(int argc, char *argv[]) { CURL *h; int c; err_init(basename(argv[0])); while ((c = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != EOF) { switch (c) { case 'u': /* --url */ url = xstrdup(optarg); break; case 'H': /* --header */ header = xstrdup(optarg); break; case 'c': /* --cookies */ cookies = 1; break; case 'v': /* --verbose */ verbose = 1; break; default: usage(); break; } } if (optind < argc) usage(); if (curl_global_init(CURL_GLOBAL_ALL) != 0) err_exit(FALSE, "curl_global_init failed"); if ((h = curl_easy_init()) == NULL) err_exit(FALSE, "curl_easy_init failed"); curl_easy_setopt(h, CURLOPT_TIMEOUT, 5); curl_easy_setopt(h, CURLOPT_ERRORBUFFER, errbuf); curl_easy_setopt(h, CURLOPT_FAILONERROR, 1); /* for time being */ curl_easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0L); if (verbose) curl_easy_setopt(h, CURLOPT_VERBOSE, 1L); if (header) { header_list = curl_slist_append(header_list, header); curl_easy_setopt(h, CURLOPT_HTTPHEADER, header_list); } /* enable cookie engine with empty string, no need to read from a real file */ if (cookies) curl_easy_setopt(h, CURLOPT_COOKIEFILE, ""); shell(h); curl_easy_cleanup(h); if (userpwd) xfree(userpwd); if (url) xfree(url); exit(0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/000077500000000000000000000000001415616035500154225ustar00rootroot00000000000000powerman-2.3.27/libcommon/Makefile.am000066400000000000000000000006541415616035500174630ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/liblsd noinst_LIBRARIES = libcommon.a libcommon_a_SOURCES = \ argv.c \ argv.h \ debug.c \ debug.h \ client_proto.h \ error.c \ error.h \ hprintf.c \ hprintf.h \ pluglist.c \ pluglist.h \ powerman.h \ xmalloc.c \ xmalloc.h \ xpoll.c \ xpoll.h \ xpty.c \ xpty.h \ xread.c \ xread.h \ xregex.c \ xregex.h \ xsignal.c \ xsignal.h \ xtime.h \ xtypes.h powerman-2.3.27/libcommon/argv.c000066400000000000000000000064061415616035500165330ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xmalloc.h" #include "argv.h" /* make a copy of the first word in str and advance str past it */ static char *_nextargv(char **strp, char *ignore) { char *str = *strp; char *word; int len; char *cpy = NULL; while (*str && (isspace(*str) || strchr(ignore, *str))) str++; word = str; while (*str && !(isspace(*str) || strchr(ignore, *str))) str++; len = str - word; if (len > 0) { cpy = (char *)xmalloc(len + 1); memcpy(cpy, word, len); cpy[len] = '\0'; } *strp = str; return cpy; } /* return number of space seperated words in str */ static int _sizeargv(char *str, char *ignore) { int count = 0; do { while (*str && (isspace(*str) || strchr(ignore, *str))) str++; if (*str) count++; while (*str && !(isspace(*str) || strchr(ignore, *str))) str++; } while (*str); return count; } int argv_length(char **argv) { int i = 0; while (argv[i] != NULL) i++; return i; } char **argv_append(char **argv, char *s) { int argc = argv_length(argv) + 1; argv = (char **)xrealloc((char *)argv, sizeof(char *) * (argc + 1)); argv[argc - 1] = xstrdup(s); argv[argc] = NULL; return argv; } /* Create a null-terminated argv array given a command line. * Characters in the 'ignore' set are treated like white space. */ char **argv_create(char *cmdline, char *ignore) { int argc = _sizeargv(cmdline, ignore); char **argv = (char **)xmalloc(sizeof(char *) * (argc + 1)); int i; for (i = 0; i < argc; i++) { argv[i] = _nextargv(&cmdline, ignore); assert(argv[i] != NULL); } argv[i] = NULL; return argv; } /* Destroy a null-terminated argv array. */ void argv_destroy(char **argv) { int i; for (i = 0; argv[i] != NULL; i++) xfree((void *)argv[i]); xfree((void *)argv); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/argv.h000066400000000000000000000011471415616035500165350ustar00rootroot00000000000000#ifndef PM_ARGV_H #define PM_ARGV_H /* Create a NULL-terminated argv array suitable for passing to execv() * from 'cmdline' string. Characters in the 'ignore' set are treated as white * space. Caller must free with argv_destroy(). */ char **argv_create(char *cmdline, char *ignore); /* Destroy an argv array created by argv_create. */ void argv_destroy(char **argv); /* Return the number of elements in the argv array (less the NULL terminator). */ int argv_length(char **argv); /* Expand an argv array by one slot and add an entry. */ char **argv_append(char **argv, char *s); #endif /* PM_ARGV_H */ powerman-2.3.27/libcommon/client_proto.h000066400000000000000000000113051415616035500202740ustar00rootroot00000000000000#ifndef PM_CLIENT_PROTO_H #define PM_CLIENT_PROTO_H /* * Line oriented request/response protocol for powerman daemon. * 1. client connects * 2. server sends version string * 3. server sends prompt * 4. client sends command * 5. server sends response (see note under Responses below) * If not quit, goto 3 */ #define CP_LINEMAX 8192 /* max request/response line length */ #define CP_EOL "\r\n" /* line terminator */ #define CP_PROMPT "powerman> " /* prompt */ #define CP_VERSION "001 %s" CP_EOL /* * Requests */ #define CP_HELP "help" #define CP_QUIT "quit" #define CP_RESET "reset %s" #define CP_CYCLE "cycle %s" #define CP_ON "on %s" #define CP_OFF "off %s" #define CP_NODES "nodes" #define CP_DEVICE "device %s" #define CP_DEVICE_ALL "device" #define CP_STATUS "status %s" #define CP_STATUS_ALL "status" #define CP_TEMP "temp %s" #define CP_TEMP_ALL "temp" #define CP_BEACON "beacon %s" #define CP_BEACON_ALL "beacon" #define CP_BEACON_ON "flash %s" #define CP_BEACON_OFF "unflash %s" #define CP_TELEMETRY "telemetry" #define CP_EXPRANGE "exprange" /* * Responses - * 1XX's are successes (indicates end of response) * 2XX's are failures (indicates end of response) * 3XX's are informational messages (more data coming) * Responses can be multi-line. Client knows response is complete when * it reads a 1XX or 2XX line. */ #define CP_IS_SUCCESS(i) ((i) >= 100 && (i) < 200) #define CP_IS_FAILURE(i) ((i) >= 200 && (i) < 300) #define CP_IS_ALLDONE(i) ((i) >= 100 && (i) < 300) /* success 1xx */ #define CP_RSP_QUIT "101 Goodbye" CP_EOL #define CP_RSP_COM_COMPLETE "102 Command completed successfully" CP_EOL #define CP_RSP_QRY_COMPLETE "103 Query complete" CP_EOL #define CP_RSP_TELEMETRY "104 Telemetry %s" CP_EOL #define CP_RSP_EXPRANGE "105 Hostrange expansion %s" CP_EOL /* failure 2xx */ #define CP_ERR_UNKNOWN "201 Unknown command" CP_EOL #define CP_ERR_PARSE "202 Parse error" CP_EOL #define CP_ERR_TOOLONG "203 Command too long" CP_EOL #define CP_ERR_INTERNAL "204 Internal powermand error: %s::%d" CP_EOL #define CP_ERR_HOSTLIST "205 Hostlist error: %s" CP_EOL #define CP_ERR_CLIBUSY "208 Command in progress" CP_EOL #define CP_ERR_NOSUCHNODES "209 No such nodes: %s" CP_EOL #define CP_ERR_COM_COMPLETE "210 Command completed with errors" CP_EOL #define CP_ERR_QRY_COMPLETE "211 Query completed with errors" CP_EOL #define CP_ERR_UNIMPL "213 Command cannot be handled by power control device(s)" CP_EOL /* informational 3xx */ #define CP_INFO_HELP \ "301 nodes - query node list" CP_EOL \ "301 device [] - query power control device status" CP_EOL \ "301 status [] - query power status" CP_EOL \ "301 on - power on" CP_EOL \ "301 off - power off" CP_EOL \ "301 cycle - power cycle" CP_EOL \ "301 reset - hardware reset (if available)" CP_EOL \ "301 temp [] - query temperature (if available)" CP_EOL \ "301 beacon [] - query beacon status (if available)" CP_EOL \ "301 flash - set beacon to ON (if available)" CP_EOL \ "301 unflash - set beacon to OFF (if available)" CP_EOL \ "301 telemetry - toggle telemetry display" CP_EOL \ "301 exprange - toggle host range expansion" CP_EOL \ "301 help - display help" CP_EOL \ "301 quit - logout" CP_EOL #define CP_INFO_STATUS \ "302 on: %s" CP_EOL \ "302 off: %s" CP_EOL \ "302 unknown: %s" CP_EOL #define CP_INFO_XSTATUS "303 %s: %s" CP_EOL #define CP_INFO_DEVICE \ "304 %s: state=%s reconnects=%-3.3d actions=%-3.3d type=%s hosts=%s" CP_EOL #define CP_INFO_TELEMETRY "305 %s" CP_EOL #define CP_INFO_NODES "306 %s" CP_EOL #define CP_INFO_XNODES "307 %s" CP_EOL #define CP_INFO_ACTERROR "308 %s" CP_EOL #endif /* PM_CLIENT_PROTO_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/debug.c000066400000000000000000000074341415616035500166640ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "debug.h" #define DBG_BUFLEN 1024 static unsigned long dbg_channel_mask = 0; static bool dbg_ttyvalid = TRUE; void dbg_notty(void) { dbg_ttyvalid = FALSE; } void dbg_setmask(unsigned long mask) { dbg_channel_mask = mask; } static char *_channel_name(unsigned long channel) { static struct { unsigned long chan; char *desc; } tab[] = DBG_NAME_TAB; int i = 0; while (tab[i].chan != 0) { if (tab[i].chan == channel) break; i++; } return (tab[i].chan == 0 ? "" : tab[i].desc); } static char *_time(void) { time_t now = time(NULL); char *str = ctime(&now); str[strlen(str) - 1] = '\0'; /* lose trailing \n */ return str; } /* * Report message on stdout/syslog if dbg_channel_mask permits. */ void dbg_wrapped(unsigned long channel, const char *fmt, ...) { va_list ap; if ((channel & dbg_channel_mask) == channel) { char buf[DBG_BUFLEN]; va_start(ap, fmt); vsnprintf(buf, DBG_BUFLEN, fmt, ap); /* overflow ignored on purpose */ va_end(ap); if (dbg_ttyvalid) fprintf(stderr, "%s %s: %s\n", _time(), _channel_name(channel), buf); else syslog(LOG_DEBUG, "%s: %s", _channel_name(channel), buf); } } /* * Convert memory to string, turning non-printable character into "C" * representation. * mem (IN) target memory * len (IN) number of characters to convert * RETURN string (caller must free) */ char *dbg_memstr(char *mem, int len) { int i, j; int strsize = len * 4; /* worst case */ char *str = xmalloc(strsize + 1); for (i = j = 0; i < len; i++) { switch (mem[i]) { case '\r': strcpy(&str[j], "\\r"); j += 2; break; case '\n': strcpy(&str[j], "\\n"); j += 2; break; case '\t': strcpy(&str[j], "\\t"); j += 2; break; default: if (isprint(mem[i])) str[j++] = mem[i]; else { sprintf(&str[j], "\\%.3o", mem[i]); j += 4; } break; } assert(j <= strsize || i == len); } str[j] = '\0'; return str; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/debug.h000066400000000000000000000016641415616035500166700ustar00rootroot00000000000000#ifndef PM_DEBUG_H #define PM_DEBUG_H #define DBG_ALWAYS 0x0000 #define DBG_DEVICE 0x0001 #define DBG_POLL 0x0002 #define DBG_CLIENT 0x0004 #define DBG_ACTION 0x0008 #define DBG_MEMORY 0x0010 #define DBG_TELNET 0x0020 #define DBG_NAME_TAB { \ { DBG_DEVICE, "device" }, \ { DBG_POLL, "poll" }, \ { DBG_CLIENT, "client" }, \ { DBG_ACTION, "action" }, \ { DBG_MEMORY, "memory" }, \ { DBG_TELNET, "telnet" }, \ { 0, NULL } \ } void dbg_notty(void); void dbg_setmask(unsigned long mask); void dbg_wrapped(unsigned long channel, const char *fmt, ...); char *dbg_memstr(char *mem, int len); #define dbg(channel, fmt...) dbg_wrapped(channel, fmt) #endif /* PM_DEBUG_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/error.c000066400000000000000000000064721415616035500167300ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "xtypes.h" #include "list.h" #include "error.h" #include "debug.h" #include "xmalloc.h" static char *err_prog = NULL; /* basename of calling program */ static bool err_ttyvalid = TRUE; /* use stderr until told otherwise */ #define ERROR_BUFLEN 1024 /* * Initialize this module with the name of the program. */ void err_init(char *prog) { char *p = strrchr(prog, '/'); /* store only the basename */ err_prog = p ? p + 1 : prog; } /* * Accessor function for syslog_enable. */ void err_notty(void) { err_ttyvalid = FALSE; } /* helper for err, err_exit */ static void _verr(bool errno_valid, const char *fmt, va_list ap) { char buf[ERROR_BUFLEN]; int er = errno; assert(err_prog != NULL); vsnprintf(buf, ERROR_BUFLEN, fmt, ap); /* overflow ignored on purpose */ if (errno_valid) { if (err_ttyvalid) fprintf(stderr, "%s: %s: %s\n", err_prog, buf, strerror(er)); else syslog(LOG_ERR, "%s: %s", buf, strerror(er)); } else { if (err_ttyvalid) fprintf(stderr, "%s: %s\n", err_prog, buf); else syslog(LOG_ERR, "%s", buf); } } /* * Report error message on either stderr or syslog, then exit. */ void err_exit(bool errno_valid, const char *fmt, ...) { va_list ap; va_start(ap, fmt); _verr(errno_valid, fmt, ap); va_end(ap); dbg(DBG_MEMORY, "err_exit: memory not reclaimed: %d\n", xmemory()); exit(1); } /* * Report error message on either stderr or syslog, then return. */ void err(bool errno_valid, const char *fmt, ...) { va_list ap; va_start(ap, fmt); _verr(errno_valid, fmt, ap); va_end(ap); } void lsd_fatal_error(char *file, int line, char *mesg) { err_exit(TRUE, "%s", mesg); } void *lsd_nomem_error(char *file, int line, char *mesg) { err_exit(FALSE, "%s: out of memory", mesg); /*NOTREACHED*/ return NULL; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/error.h000066400000000000000000000005731415616035500167310ustar00rootroot00000000000000#ifndef PM_ERROR_H #define PM_ERROR_H void err_init(char *prog); void err_notty(void); void err_exit(bool errno_valid, const char *fmt, ...); void err(bool errno_valid, const char *fmt, ...); void lsd_fatal_error(char *file, int line, char *mesg); void *lsd_nomem_error(char *file, int line, char *mesg); #endif /* PM_ERROR_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/hprintf.c000066400000000000000000000047021415616035500172430ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xmalloc.h" #include "hprintf.h" #include "xread.h" #define CHUNKSIZE 80 char *hvsprintf(const char *fmt, va_list ap) { int len, size = 0; char *str = NULL; do { va_list vacpy; str = (size == 0) ? xmalloc(CHUNKSIZE) : xrealloc(str, size+CHUNKSIZE); size += CHUNKSIZE; va_copy(vacpy, ap); len = vsnprintf(str, size, fmt, vacpy); /* always null terminates */ va_end(vacpy); } while (len == -1 || len >= size); assert(len == strlen(str)); return str; } char *hsprintf(const char *fmt, ...) { char *str; va_list ap; va_start(ap, fmt); str = hvsprintf(fmt, ap); va_end(ap); return str; } int hfdprintf(int fd, const char *format, ...) { char *str, *p; va_list ap; int n, rc; va_start(ap, format); str = hvsprintf(format, ap); va_end(ap); p = str; n = strlen(p); rc = 0; do { rc = xwrite(fd, str, n); if (rc < 0) return rc; n -= rc; p += rc; } while (n > 0); xfree(str); return n; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/hprintf.h000066400000000000000000000010201415616035500172360ustar00rootroot00000000000000#ifndef PM_HPRINTF_H #define PM_HPRINTF_H /* A vsprintf-like function that allocates the string on the heap and ensures * that no truncation occurs. The caller must Free() the resulting string. */ char *hvsprintf(const char *fmt, va_list ap); /* An sprintf-like function that allocates the string on the heap. * The caller must Free() the resulting string. */ char *hsprintf(const char *fmt, ...); int hfdprintf(int fd, const char *format, ...); #endif /* PM_HPRINTF_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/pluglist.c000066400000000000000000000161101415616035500174300ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "xtypes.h" #include "list.h" #include "xmalloc.h" #include "hostlist.h" #include "pluglist.h" #define PLUGLISTITR_MAGIC 0xfeedfefe #define PLUGLIST_MAGIC 0xfeedb0b struct pluglist_iterator { int magic; ListIterator itr; }; struct pluglist { int magic; List pluglist; bool hardwired; }; static Plug *_create_plug(char *name) { Plug *plug = (Plug *) xmalloc(sizeof(Plug)); assert(name != NULL); plug->name = xstrdup(name); plug->node = NULL; return plug; } static void _destroy_plug(Plug *plug) { assert(plug != NULL); xfree(plug->name); if (plug->node) xfree(plug->node); xfree(plug); } PlugList pluglist_create(List plugnames) { PlugList pl = (PlugList) xmalloc(sizeof(struct pluglist)); pl->magic = PLUGLIST_MAGIC; pl->pluglist = list_create((ListDelF)_destroy_plug); pl->hardwired = FALSE; /* create plug for each element of plugnames list */ if (plugnames) { ListIterator itr; char *name; itr = list_iterator_create(plugnames); while ((name = list_next(itr))) list_append(pl->pluglist, _create_plug(name)); list_iterator_destroy(itr); pl->hardwired = TRUE; } return pl; } void pluglist_destroy(PlugList pl) { assert(pl != NULL); assert(pl->magic == PLUGLIST_MAGIC); pl->magic = 0; list_destroy(pl->pluglist); xfree(pl); } static Plug *_pluglist_find_any(PlugList pl, char *name) { PlugListIterator itr = pluglist_iterator_create(pl); Plug *plug; while ((plug = pluglist_next(itr))) { if (strcmp(plug->name, name) == 0) break; } pluglist_iterator_destroy(itr); return plug; } /* Assign a node name to an existing Plug. * Create Plug if Plug with name doesn't exist and Plugs are not hardwired. */ static pl_err_t _pluglist_map_one(PlugList pl, char *node, char *name) { Plug *plug = _pluglist_find_any(pl, name); pl_err_t res = EPL_SUCCESS; if (plug == NULL) { if (pl->hardwired) { res = EPL_UNKPLUG; goto err; } plug = _create_plug(name); list_push(pl->pluglist, plug); } if (plug->node) { res = EPL_DUPPLUG; goto err; } plug->node = xstrdup(node); err: return res; } /* Assign a node name to the next available plug. */ static pl_err_t _pluglist_map_next(PlugList pl, char *node) { Plug *plug; PlugListIterator pitr; pl_err_t res = EPL_NOPLUGS; pitr = pluglist_iterator_create(pl); while ((plug = pluglist_next(pitr))) { if (plug->node == NULL) { plug->node = xstrdup(node); res = EPL_SUCCESS; break; } } pluglist_iterator_destroy(pitr); return res; } pl_err_t pluglist_map(PlugList pl, char *nodelist, char *pluglist) { pl_err_t res = EPL_SUCCESS; assert(pl != NULL); assert(pl->magic == PLUGLIST_MAGIC); assert(nodelist != NULL); /* If pluglist is omitted we have one of two cases: * 1) hardwired plugs, and we assign node names to existing plugs in order. * 2) no plugs, we create plugs with same names as node names. */ if (pluglist == NULL) { hostlist_t nhl = hostlist_create(nodelist); hostlist_iterator_t nitr = hostlist_iterator_create(nhl); char *node; while ((node = hostlist_next(nitr))) { if (pl->hardwired) res = _pluglist_map_next(pl, node); else res = _pluglist_map_one(pl, node, node); free(node); if (res != EPL_SUCCESS) break; } hostlist_iterator_destroy(nitr); hostlist_destroy(nhl); /* We have a pluglist so we just map plugs to nodes. */ } else { hostlist_t nhl = hostlist_create(nodelist); hostlist_iterator_t nitr = hostlist_iterator_create(nhl); hostlist_t phl = hostlist_create(pluglist); hostlist_iterator_t pitr = hostlist_iterator_create(phl); char *node, *name; while ((node = hostlist_next(nitr))) { name = hostlist_next(pitr); if (name) res = _pluglist_map_one(pl, node, name); else res = EPL_NOPLUGS; free(node); free(name); if (res != EPL_SUCCESS) break; } if (res == EPL_SUCCESS) { char *tmp = hostlist_next(pitr); if (tmp != NULL) res = EPL_NONODES; free(tmp); } hostlist_iterator_destroy(pitr); hostlist_iterator_destroy(nitr); hostlist_destroy(phl); hostlist_destroy(nhl); } return res; } PlugListIterator pluglist_iterator_create(PlugList pl) { PlugListIterator itr = (PlugListIterator)xmalloc(sizeof(struct pluglist_iterator)); itr->magic = PLUGLISTITR_MAGIC; itr->itr = list_iterator_create(pl->pluglist); return itr; } void pluglist_iterator_destroy(PlugListIterator itr) { assert(itr != NULL); assert(itr->magic == PLUGLISTITR_MAGIC); itr->magic = 0; list_iterator_destroy(itr->itr); xfree(itr); } Plug *pluglist_next(PlugListIterator itr) { assert(itr != NULL); assert(itr->magic == PLUGLISTITR_MAGIC); return (Plug *)list_next(itr->itr); } Plug *pluglist_find(PlugList pl, char *name) { Plug *plug; assert(pl != NULL); assert(pl->magic == PLUGLIST_MAGIC); assert(name != NULL); plug = _pluglist_find_any(pl, name); if (plug && plug->node == NULL) plug = NULL; return plug; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/pluglist.h000066400000000000000000000035341415616035500174430ustar00rootroot00000000000000#ifndef PM_PLUGLIST_H #define PM_PLUGLIST_H /* * Pluglists are used to map node names to plug names within a given device * context. */ typedef struct { char *name; /* how the plug is known to the device */ char *node; /* node name */ } Plug; typedef struct pluglist_iterator *PlugListIterator; typedef struct pluglist *PlugList; typedef enum { EPL_SUCCESS, EPL_DUPNODE, EPL_UNKPLUG, EPL_DUPPLUG, EPL_NOPLUGS, EPL_NONODES } pl_err_t; /* Create a PlugList. plugnames may be NULL (indicating plug creation is * deferred until pluglist_map() time), or a hardwired list of plug names. * ('hardwired' means the list of plugnames is fixed at creation time). */ PlugList pluglist_create(List plugnames); /* Destroy a PlugList and its Plugs */ void pluglist_destroy(PlugList pl); /* Assign node names to plugs. nodelist and pluglist are strings in compressed * hostlist format (the degenerate case of which is a single name). pluglist * can be NULL, indicating * - if hardwired plugs, available plugs should be assigned to nodes in order * - else (not hardwired), assume plug names are the same as node names. */ pl_err_t pluglist_map(PlugList pl, char *nodelist, char *pluglist); /* Search PlugList for a Plug with matching plug name. Return pointer to Plug * on success (points to actual list entry), or NULL on search failure. * Only plugs with non-NULL node fields are returned. */ Plug * pluglist_find(PlugList pl, char *name); /* An iterator interface for PlugLists, similar to the iterators in list.h. */ PlugListIterator pluglist_iterator_create(PlugList pl); void pluglist_iterator_destroy(PlugListIterator itr); Plug * pluglist_next(PlugListIterator itr); #endif /* PM_PLUGLIST_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/powerman.h000066400000000000000000000003541415616035500174250ustar00rootroot00000000000000#ifndef PM_POWERMAN_H #define PM_POWERMAN_H #define DAEMON_NAME "powermand" #define DFLT_PORT "10101" #define DFLT_HOSTNAME "127.0.0.1" #endif /* PM_POWERMAN_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xmalloc.c000066400000000000000000000071071415616035500172320ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "error.h" #ifndef NDEBUG static int memory_alloc = 0; #endif /* Review: look into dmalloc */ #define MALLOC_MAGIC 0xf00fbaab #define MALLOC_PAD_SIZE 16 #define MALLOC_PAD_FILL 0x55 #ifndef NDEBUG int xmemory(void) { return memory_alloc; } static int _checkfill(char *buf, unsigned char fill, int size) { while (size-- > 0) if (buf[size] != fill) return 0; return 1; } #endif char *xmalloc(int size) { char *new; int *p; assert(size > 0); p = (int *) malloc(2*sizeof(int) + size + MALLOC_PAD_SIZE); if (p == NULL) err_exit(FALSE, "out of memory"); p[0] = MALLOC_MAGIC; /* magic cookie */ p[1] = size; /* store size in buffer */ #ifndef NDEBUG memory_alloc += size; #endif new = (char *) &p[2]; memset(new, 0, size); memset(new + size, MALLOC_PAD_FILL, MALLOC_PAD_SIZE); return new; } char *xrealloc(char *item , int newsize) { char *new; int *p = (int *)item - 2; int oldsize; assert(item != NULL); assert(newsize > 0); assert(p[0] == MALLOC_MAGIC); oldsize = p[1]; assert(_checkfill(item + oldsize, MALLOC_PAD_FILL, MALLOC_PAD_SIZE)); p = (int *)realloc(p, 2*sizeof(int) + newsize + MALLOC_PAD_SIZE); if (p == NULL) err_exit(FALSE, "out of memory"); assert(p[0] == MALLOC_MAGIC); p[1] = newsize; #ifndef NDEBUG memory_alloc += (newsize - oldsize); #endif new = (char *) &p[2]; if (newsize > oldsize) memset(new + oldsize, 0, newsize - oldsize); memset(new + newsize, MALLOC_PAD_FILL, MALLOC_PAD_SIZE); return new; } void xfree(void *ptr) { if (ptr != NULL) { int *p = (int *) ptr - 2; int size; assert(p[0] == MALLOC_MAGIC); /* magic cookie still there? */ size = p[1]; assert(_checkfill((char*)ptr + size, MALLOC_PAD_FILL, MALLOC_PAD_SIZE)); memset(p, 0, 2*sizeof(int) + size + MALLOC_PAD_SIZE); #ifndef NDEBUG memory_alloc -= size; #endif free(p); } } char *xstrdup(const char *str) { char *cpy; cpy = xmalloc(strlen(str) + 1); strcpy(cpy, str); return cpy; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xmalloc.h000066400000000000000000000004011415616035500172250ustar00rootroot00000000000000#ifndef PM_XMALLOC_H #define PM_XMALLOC_H char *xmalloc(int size); char *xrealloc(char *item, int newsize); void xfree(void *ptr); char *xstrdup(const char *str); int xmemory(void); #endif /* PM_XMALLOC_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xpoll.c000066400000000000000000000161541415616035500167330ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif /* Force select() on darwin as poll() can't be used on devices (e.g. ptys) * FIXME: This should be a configure-time test. */ #if defined(__APPLE__) && defined(HAVE_POLL) #undef HAVE_POLL #endif #include #include #include #include #include #if HAVE_POLL_H #include #endif #if HAVE_SYS_SELECT_H #include #endif #include #include "xtime.h" #include "xtypes.h" #include "xmalloc.h" #include "error.h" #include "xpoll.h" #ifndef MAX #define MAX(x, y) (((x) > (y))? (x) : (y)) #endif #define XPOLLFD_ALLOC_CHUNK 16 #define XPOLLFD_MAGIC 0x56452334 struct xpollfd { int magic; #if HAVE_POLL unsigned int nfds; unsigned int ufds_size; struct pollfd *ufds; #else /* select */ int maxfd; fd_set rset; fd_set wset; #endif }; #if HAVE_POLL static short xflag2flag(short x) { short f = 0; if ((x & XPOLLIN)) f |= POLLIN; if ((x & XPOLLOUT)) f |= POLLOUT; if ((x & XPOLLHUP)) f |= POLLHUP; if ((x & XPOLLERR)) f |= POLLERR; if ((x & XPOLLNVAL)) f |= POLLNVAL; return f; } static short flag2xflag(short f) { short x = 0; if ((f & POLLIN)) x |= XPOLLIN; if ((f & POLLOUT)) x |= XPOLLOUT; if ((f & POLLHUP)) x |= XPOLLHUP; if ((f & POLLERR)) x |= XPOLLERR; if ((f & POLLNVAL)) x |= XPOLLNVAL; return x; } #endif /* a null tv means no timeout (could block forever) */ int xpoll(xpollfd_t pfd, struct timeval *tv) { struct timeval tv_cpy, *tvp = NULL; struct timeval start, end, delta; int n; if (tv) { tv_cpy = *tv; if (gettimeofday(&start, NULL) < 0) err_exit(TRUE, "gettimeofday"); tvp = &tv_cpy; } /* repeat poll if interrupted */ do { #if HAVE_POLL int tv_msec = -1; if (tvp) tv_msec = tvp->tv_sec * 1000 + tvp->tv_usec / 1000; n = poll(pfd->ufds, pfd->nfds, tv_msec); #else n = select(pfd->maxfd + 1, &pfd->rset, &pfd->wset, NULL, tvp); #endif if (n < 0 && errno != EINTR) err_exit(TRUE, "select/poll"); if (n < 0 && tv != NULL) { if (gettimeofday(&end, NULL) < 0) err_exit(TRUE, "gettimeofday"); timersub(&end, &start, &delta); /* delta = end - start */ timersub(tv, &delta, tvp); /* *tvp = tv - delta */ } } while (n < 0); return n; } #if HAVE_POLL static void _grow_pollfd(xpollfd_t pfd, int n) { assert(pfd->magic == XPOLLFD_MAGIC); while (pfd->ufds_size < n) { pfd->ufds_size += XPOLLFD_ALLOC_CHUNK; pfd->ufds = (struct pollfd *)xrealloc((char *)pfd->ufds, sizeof(struct pollfd) * pfd->ufds_size); } } #endif xpollfd_t xpollfd_create(void) { xpollfd_t pfd = (xpollfd_t)xmalloc(sizeof(struct xpollfd)); pfd->magic = XPOLLFD_MAGIC; #if HAVE_POLL pfd->ufds_size += XPOLLFD_ALLOC_CHUNK; pfd->ufds = (struct pollfd *)xmalloc(sizeof(struct pollfd)*pfd->ufds_size); pfd->nfds = 0; #else pfd->maxfd = 0; FD_ZERO(&pfd->rset); FD_ZERO(&pfd->wset); #endif return pfd; } void xpollfd_destroy(xpollfd_t pfd) { assert(pfd->magic == XPOLLFD_MAGIC); pfd->magic = 0; #if HAVE_POLL if (pfd->ufds != NULL) xfree(pfd->ufds); #endif xfree(pfd); } void xpollfd_zero(xpollfd_t pfd) { assert(pfd->magic == XPOLLFD_MAGIC); #if HAVE_POLL pfd->nfds = 0; /*memset(pfd->ufds, 0, sizeof(struct pollfd) * pfd->ufds_size);*/ #else FD_ZERO(&pfd->rset); FD_ZERO(&pfd->wset); pfd->maxfd = 0; #endif } void xpollfd_set(xpollfd_t pfd, int fd, short events) { #if HAVE_POLL int i; assert(pfd->magic == XPOLLFD_MAGIC); for (i = 0; i < pfd->nfds; i++) { if (pfd->ufds[i].fd == fd) { pfd->ufds[i].events |= xflag2flag(events); break; } } if (i == pfd->nfds) { /* not found */ _grow_pollfd(pfd, ++pfd->nfds); pfd->ufds[i].fd = fd; pfd->ufds[i].events = xflag2flag(events); } #else assert(pfd->magic == XPOLLFD_MAGIC); assert(fd < FD_SETSIZE); if (events & XPOLLIN) FD_SET(fd, &pfd->rset); if (events & XPOLLOUT) FD_SET(fd, &pfd->wset); pfd->maxfd = MAX(pfd->maxfd, fd); #endif } char * xpollfd_str(xpollfd_t pfd, char *str, int len) { int i; #if HAVE_POLL int maxfd = -1; #endif assert(pfd->magic == XPOLLFD_MAGIC); #if HAVE_POLL memset(str, '.', len); for (i = 0; i < pfd->nfds; i++) { int fd = pfd->ufds[i].fd; short revents = pfd->ufds[i].revents; if (fd < len - 1) { if (revents) { if (revents & (POLLNVAL | POLLERR | POLLHUP)) str[fd] = 'E'; else if (revents & POLLIN) str[fd] = 'I'; else if (revents & POLLOUT) str[fd] = 'O'; } if (fd > maxfd) maxfd = fd; } } assert(maxfd + 1 < len); str[maxfd + 1] = '\0'; #else for (i = 0; i <= pfd->maxfd; i++) { if (FD_ISSET(i, &pfd->rset)) str[i] = 'I'; else if (FD_ISSET(i, &pfd->wset)) str[i] = 'O'; else str[i] = '.'; } assert(i < len); str[i] = '\0'; #endif return str; } short xpollfd_revents(xpollfd_t pfd, int fd) { short flags = 0; #if HAVE_POLL int i; assert(pfd->magic == XPOLLFD_MAGIC); for (i = 0; i < pfd->nfds; i++) { if (pfd->ufds[i].fd == fd) { flags = flag2xflag(pfd->ufds[i].revents); break; } } #else assert(pfd->magic == XPOLLFD_MAGIC); if (FD_ISSET(fd, &pfd->rset)) flags |= XPOLLIN; if (FD_ISSET(fd, &pfd->wset)) flags |= XPOLLOUT; #endif return flags; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xpoll.h000066400000000000000000000011501415616035500167260ustar00rootroot00000000000000#ifndef PM_XPOLL_H #define PM_XPOLL_H typedef struct xpollfd *xpollfd_t; int xpoll(xpollfd_t pfd, struct timeval *timeout); xpollfd_t xpollfd_create(void); void xpollfd_destroy(xpollfd_t pfd); void xpollfd_zero(xpollfd_t pfd); void xpollfd_set(xpollfd_t pfd, int fd, short events); short xpollfd_revents(xpollfd_t pfd, int fd); char *xpollfd_str(xpollfd_t pfd, char *str, int len); #define XPOLLIN 1 #define XPOLLOUT 2 #define XPOLLHUP 4 #define XPOLLERR 8 #define XPOLLNVAL 16 #endif /* PM_XPOLL_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xpty.c000066400000000000000000000133031415616035500165720ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #if HAVE_PTY_H #include #endif #if HAVE_UTIL_H #include #endif #if ! HAVE_FORKPTY #include #include #include #if HAVE_SYS_SYSCALL_H #include #endif #endif #include #include #include "xtypes.h" #include "xpty.h" #include "error.h" void nonblock_set(int fd) { int flags; flags = fcntl(fd, F_GETFL, 0); if (flags < 0) err_exit(TRUE, "fcntl F_GETFL"); if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) err_exit(TRUE, "fcntl F_SETFL"); } void nonblock_clr(int fd) { int flags; flags = fcntl(fd, F_GETFL, 0); if (flags < 0) err_exit(TRUE, "fcntl F_GETFL"); if (fcntl(fd, F_SETFL, flags & ~(O_NONBLOCK)) < 0) err_exit(TRUE, "fcntl F_SETFL"); } static int tiocmp(struct termios *a, struct termios *b) { if ( memcmp(a->c_cc, b->c_cc, sizeof(a->c_cc)) == 0 && a->c_cc[VTIME] == b->c_cc[VTIME] && a->c_iflag == b->c_iflag && a->c_oflag == b->c_oflag && a->c_cflag == b->c_cflag && a->c_lflag == b->c_lflag) return 1; return 0; } /* tcsetattr returns success if anything succeeds so we must verify * with another tcgetattr. */ static void xtcsetattr(int fd, int flags, struct termios *tio) { struct termios act; if (tcsetattr(fd, flags, tio) < 0) err_exit(TRUE, "tcsetattr"); memset(&act, 0, sizeof(act)); if (tcgetattr(fd, &act) < 0) err_exit(TRUE, "tcgetattr"); if (!tiocmp(tio, &act)) err_exit(FALSE, "tcsetattr failed"); } void xcfmakeraw(int fd) { struct termios tio; if (tcgetattr(fd, &tio) < 0) err_exit(TRUE, "xcfmakeraw: tcgetattr"); #if HAVE_CFMAKERAW && !defined(_AIX) cfmakeraw(&tio); #else /* Stevens: Adv. Prog. in the UNIX Env. 1ed p.345 */ tio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); tio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); tio.c_cflag &= ~(CSIZE | PARENB); tio.c_cflag |= CS8; tio.c_oflag &= ~(OPOST); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; #endif xtcsetattr(fd, TCSANOW, &tio); } pid_t xforkpty(int *amaster, char *name, int len) { pid_t pid; #if HAVE_FORKPTY pid = forkpty(amaster, name, NULL, NULL); if (pid > 0 && name != NULL) { /* XXX forkpty takes no len parameter */ assert(strlen(name) < len); } #else #if HAVE__DEV_PTMX /* solaris style - this code initially borrowed from * http://bugs.mysql.com/bug.php?id=22429 */ int master, slave; char *slave_name; master = open("/dev/ptmx", O_RDWR); if (master < 0) return -1; if (grantpt (master) < 0) { close (master); return -1; } if (unlockpt (master) < 0) { close (master); return -1; } slave_name = ptsname (master); if (slave_name == NULL) { close (master); return -1; } slave = open (slave_name, O_RDWR); if (slave < 0) { close (master); return -1; } if (ioctl (slave, I_PUSH, "ptem") < 0 || ioctl (slave, I_PUSH, "ldterm") < 0) { close (slave); close (master); return -1; } #elif HAVE__DEV_PTC /* aix style */ int master, slave; char *slave_name; master = open("/dev/ptc", O_RDWR); if (master < 0) return -1; if (grantpt (master) < 0) { close (master); return -1; } if (unlockpt (master) < 0) { close (master); return -1; } slave_name = ttyname (master); if (slave_name == NULL) { close (master); return -1; } slave = open (slave_name, O_RDWR); if (slave < 0) { close (master); return -1; } #else #error unknown pty master device path #endif if (amaster) *amaster = master; if (name) strncpy (name, slave_name, len); pid = fork (); switch (pid) { case -1: /* Error */ return -1; case 0: /* Child */ close (master); dup2 (slave, STDIN_FILENO); dup2 (slave, STDOUT_FILENO); dup2 (slave, STDERR_FILENO); return 0; default: /* Parent */ close (slave); break; } #endif return pid; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xpty.h000066400000000000000000000004461415616035500166030ustar00rootroot00000000000000#ifndef PM_XPTY_H #define PM_XPTY_H /* FIXME: these have nothing to do with ptys per se */ void xcfmakeraw(int fd); void nonblock_set(int fd); void nonblock_clr(int fd); pid_t xforkpty(int *amaster, char *name, int len); #endif /* PM_XPTY_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xread.c000066400000000000000000000070041415616035500166720ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "xread.h" #include "xtypes.h" #include "xmalloc.h" #include "error.h" int xread(int fd, char *p, int max) { int n; do { n = read(fd, p, max); } while (n < 0 && errno == EINTR); if (n < 0 && errno != EWOULDBLOCK && errno != ECONNRESET) err_exit(TRUE, "read"); return n; } #define CHUNKSIZE 80 char *xreadstr(int fd) { int size = 0; int len = 0; char *str = NULL; int n; do { if (size - len - 1 <= 0) { str = (size == 0) ? xmalloc(CHUNKSIZE) : xrealloc(str, size + CHUNKSIZE); size += CHUNKSIZE; } //n = xread(fd, str + len, size - len - 1); n = xread(fd, str + len, 1); if (n < 0) err_exit (TRUE, "read"); if (n == 0) err_exit (FALSE, "EOF on read"); len += n; str[len] = '\0'; } while (len < 2 || strcmp(&str[len - 2], "\r\n") != 0); str[len - 2] = '\0'; return str; } int xwrite(int fd, char *p, int max) { int n; do { n = write(fd, p, max); } while (n < 0 && errno == EINTR); if (n < 0 && errno != EAGAIN && errno != ECONNRESET && errno != EPIPE) err_exit(TRUE, "write"); return n; } void xwrite_all(int fd, char *p, int count) { int n; int done = 0; while (done < count) { n = xwrite(fd, p + done, count - done); if (n < 0) err_exit(TRUE, "write"); done += n; } } void xread_all(int fd, char *p, int count) { int n; int done = 0; while (done < count) { n = xread(fd, p + done, count - done); if (n < 0) err_exit(TRUE, "read"); if (n == 0) err_exit(FALSE, "EOF on read"); done += n; } } static void _zap_trailing_whitespace(char *s) { char *p = s + strlen(s) - 1; while (p >= s && isspace(*p)) *p-- = '\0'; } char *xreadline(char *prompt, char *buf, int buflen) { printf("%s", prompt); fflush(stdout); if (fgets(buf, buflen, stdin) == NULL) return NULL; _zap_trailing_whitespace(buf); return buf; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xread.h000066400000000000000000000017671415616035500167110ustar00rootroot00000000000000#ifndef PM_XREAD_H #define PM_XREAD_H /* Read function that handles EINTR internally and terminates on all * other errors except EWOULDBLOCK and ECONNRESET. */ int xread(int fd, char *p, int max); /* Write function that handles EINTR internally and terminates on all * other errors except EPIPE, EWOULDBLOCK, and ECONNRESET. */ int xwrite(int fd, char *p, int max); /* Wrapper for xread that reads exactly count bytes or dies trying */ void xread_all(int fd, char *p, int count); /* Wrapper for xwrite that writes exactly count bytes or dies trying. */ void xwrite_all(int fd, char *p, int count); /* Read a line of input, strip whitespace off the end, and return it. */ char *xreadline(char *prompt, char *buf, int buflen); /* Read a line of data from file descriptor, terminated with \r\n, * which is not returned. Exit on EOF or read error. * Caller must free returned string (null terminated). */ char *xreadstr(int fd); #endif /* PM_XREAD_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xregex.c000066400000000000000000000143101415616035500170670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001-2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "xtypes.h" #include "error.h" #include "xregex.h" #include "xmalloc.h" #define XREGEX_MAGIC 0x3456aaaa struct xregex_struct { int xr_magic; int xr_cflags; regex_t *xr_regex; }; #define XREGEX_MATCH_MAGIC 0x3456aaba struct xregex_match_struct { int xm_magic; int xm_nmatch; regmatch_t *xm_pmatch; char *xm_str; int xm_result; bool xm_used; }; xregex_t xregex_create(void) { xregex_t xrp = (xregex_t)xmalloc(sizeof(struct xregex_struct)); xrp->xr_magic = XREGEX_MAGIC; xrp->xr_regex = NULL; return xrp; } void xregex_destroy(xregex_t xrp) { assert(xrp->xr_magic == XREGEX_MAGIC); if (xrp->xr_regex) { regfree(xrp->xr_regex); xfree(xrp->xr_regex); } xrp->xr_magic = 0; xfree(xrp); } /* Substitute all occurrences of s2 with s3 in s1, * e.g. _str_subst(str, "\\r", "\r") */ static void _str_subst(char *s1, int len, const char *s2, const char *s3) { int s2len = strlen(s2); int s3len = strlen(s3); char *p; while ((p = strstr(s1, s2)) != NULL) { assert(strlen(s1) + (s3len - s2len) + 1 <= len); memmove(p + s3len, p + s2len, strlen(p + s2len) + 1); memcpy(p, s3, s3len); } } void xregex_compile(xregex_t xrp, const char *regex, bool withsub) { char tmpstr[256]; char *cpy; int n; assert(regex != NULL); assert(xrp->xr_magic == XREGEX_MAGIC); assert(xrp->xr_regex == NULL); /* No particular limit is imposed on the length of REs(!). Programs * intended to be portable should not employ REs longer than 256 bytes, as * an implementation can refuse to accept such REs and remain POSIX-com- * pliant. -- regex(7) on RHEL 5 */ if (strlen(regex) > 256) err_exit(FALSE, "refusing to compile regex > 256 bytes"); xrp->xr_regex = (regex_t *)xmalloc(sizeof(regex_t)); xrp->xr_cflags = REG_EXTENDED; if (!withsub) xrp->xr_cflags |= REG_NOSUB; cpy = xstrdup(regex); _str_subst(cpy, strlen(cpy) + 1, "\\r", "\r"); _str_subst(cpy, strlen(cpy) + 1, "\\n", "\n"); n = regcomp(xrp->xr_regex, cpy, xrp->xr_cflags); xfree(cpy); if (n != 0) { regerror(n, xrp->xr_regex, tmpstr, sizeof(tmpstr)); err_exit(FALSE, "regcomp failed: %s", tmpstr); } } bool xregex_exec(xregex_t xrp, const char *s, xregex_match_t xm) { int eflags = REG_NOTEOL; int res; assert(xrp->xr_magic == XREGEX_MAGIC); assert(xrp->xr_regex != NULL); if (xm != NULL) { assert(xm->xm_magic == XREGEX_MATCH_MAGIC); assert(xm->xm_used == FALSE); } res = regexec(xrp->xr_regex, s, xm ? xm->xm_nmatch : 0, xm ? xm->xm_pmatch : NULL, eflags); if (xm != NULL) { xm->xm_result = res; xm->xm_used = TRUE; if (res == 0) { if (xm->xm_str) xfree(xm->xm_str); xm->xm_str = xstrdup(s); } } return res == 0 ? TRUE : FALSE; } xregex_match_t xregex_match_create(int nmatch) { xregex_match_t xm; xm = (xregex_match_t)xmalloc(sizeof(struct xregex_match_struct)); xm->xm_magic = XREGEX_MATCH_MAGIC; xm->xm_nmatch = nmatch + 1; xm->xm_pmatch = (regmatch_t *)xmalloc(sizeof(regmatch_t) * (nmatch + 1)); xm->xm_str = NULL; xm->xm_result = -1; xm->xm_used = FALSE; return xm; } void xregex_match_destroy(xregex_match_t xm) { assert(xm->xm_magic == XREGEX_MATCH_MAGIC); xfree(xm->xm_pmatch); if (xm->xm_str) xfree(xm->xm_str); xm->xm_magic = 0; xfree(xm); } void xregex_match_recycle(xregex_match_t xm) { if (xm->xm_str) { xfree(xm->xm_str); xm->xm_str = NULL; } xm->xm_result = -1; xm->xm_used = FALSE; } char * xregex_match_strdup(xregex_match_t xm) { char *s = NULL; assert(xm->xm_magic == XREGEX_MATCH_MAGIC); assert(xm->xm_used); if (xm->xm_result == 0) { s = (char *)xmalloc(xm->xm_pmatch[0].rm_eo + 1); assert(xm->xm_str != NULL); memcpy(s, xm->xm_str, xm->xm_pmatch[0].rm_eo); s[xm->xm_pmatch[0].rm_eo] = '\0'; } return s; } int xregex_match_strlen(xregex_match_t xm) { assert(xm->xm_magic == XREGEX_MATCH_MAGIC); assert(xm->xm_used); return xm->xm_pmatch[0].rm_eo; } char * xregex_match_sub_strdup(xregex_match_t xm, int i) { char *s = NULL; assert(xm->xm_magic == XREGEX_MATCH_MAGIC); assert(xm->xm_used); if (xm->xm_result == 0 && i >= 0 && i < xm->xm_nmatch && xm->xm_pmatch[i].rm_so != -1) { regmatch_t m = xm->xm_pmatch[i]; assert(xm->xm_str != NULL); assert(m.rm_so < m.rm_eo); s = xmalloc(m.rm_eo - m.rm_so + 1); memcpy(s, xm->xm_str + m.rm_so, m.rm_eo - m.rm_so); s[m.rm_eo - m.rm_so] = '\0'; } return s; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xregex.h000066400000000000000000000036371415616035500171060ustar00rootroot00000000000000#ifndef PM_XREGEX_H #define PM_XREGEX_H /* A compiled regex. */ typedef struct xregex_struct *xregex_t; /* A container for regexec subexpression match results. */ typedef struct xregex_match_struct *xregex_match_t; /* Create/destroy a regex object. */ xregex_t xregex_create(void); void xregex_destroy(xregex_t x); /* Compile a regex defined by 's' into a regex object created with * xregex_create(). 's' may contain the strings "\n" or "\r" in expanded * form and they will be converted into 0xa and 0xd respectively. * If 'withsub' is TRUE, the regex will support subexpression matches. * Program terminates with detailed message on compilation error. */ void xregex_compile(xregex_t x, const char *s, bool withsub); /* Execute a compiled regex against the provided string 's'. * If xm is non-NULL, place match info there. * Returns TRUE on a match. */ bool xregex_exec(xregex_t x, const char *s, xregex_match_t xm); /* Create/destroy/recycle a match result object. * The maximum number of matches is specified at creation in 'nmatch'. * Allow one match for main expression, and an additional match for * each subexpression. */ xregex_match_t xregex_match_create(int nmatch); void xregex_match_destroy(xregex_match_t xm); void xregex_match_recycle(xregex_match_t xm); /* Retrieve a copy of the main/subexpression match specified by 'index', * or NULL if no match. The caller must free result with xfree(). * Index 0 is for the main expression, other indices are for subexpressions. * This function must be called only after xregex_exec(). */ char *xregex_match_sub_strdup(xregex_match_t xm, int index); /* Similar to xregex_match_sub_strdup(xm, 0) but includes unmatched * leading text. Caller must free result with xfree(). */ char *xregex_match_strdup(xregex_match_t xm); /* Strlen of above. */ int xregex_match_strlen(xregex_match_t xm); #endif /* PM_XREGEX_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xsignal.c000066400000000000000000000035651415616035500172440ustar00rootroot00000000000000 /***************************************************************************** * Copyright (C) 2004-2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include "xtypes.h" #include "error.h" #include "xsignal.h" xsigfunc_t *xsignal(int signo, xsigfunc_t *func) { struct sigaction act, oact; int n; act.sa_handler = func; sigemptyset(&act.sa_mask); act.sa_flags = 0; if (signo == SIGALRM) { #ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */ #endif } else { #ifdef SA_RESTART act.sa_flags |= SA_RESTART; /* SVR4, 44BSD */ #endif } n = sigaction(signo, &act, &oact); if (n < 0) err_exit(TRUE, "sigaction"); return (oact.sa_handler); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xsignal.h000066400000000000000000000003061415616035500172370ustar00rootroot00000000000000#ifndef PM_XSIGNAL_H #define PM_XSIGNAL_H typedef void xsigfunc_t(int); xsigfunc_t *xsignal(int signo, xsigfunc_t * func); #endif /* PM_XSIGNAL_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xtime.h000066400000000000000000000030701415616035500167210ustar00rootroot00000000000000/* borrowed from glibc-2.5 */ #ifndef PM_XTIME_H #define PM_XTIME_H #ifndef timeradd # define timeradd(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ if ((result)->tv_usec >= 1000000) \ { \ ++(result)->tv_sec; \ (result)->tv_usec -= 1000000; \ } \ } while (0) #endif #ifndef timersub # define timersub(a, b, result) \ do { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) { \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ } while (0) #endif #endif /* PM_XTIME_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libcommon/xtypes.h000066400000000000000000000002351415616035500171270ustar00rootroot00000000000000#ifndef PM_XTYPES_H #define PM_XTYPES_H #ifdef FALSE #undef FALSE #endif #ifdef TRUE #undef TRUE #endif typedef enum { FALSE = 0, TRUE = 1 } bool; #endif powerman-2.3.27/liblsd/000077500000000000000000000000001415616035500147145ustar00rootroot00000000000000powerman-2.3.27/liblsd/Makefile.am000066400000000000000000000002561415616035500167530ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = noinst_LIBRARIES = liblsd.a liblsd_a_SOURCES = \ hostlist.c \ hostlist.h \ list.c \ list.h \ hash.c \ hash.h \ cbuf.c \ cbuf.h powerman-2.3.27/liblsd/cbuf.c000066400000000000000000001366241415616035500160130ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2002-2005 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***************************************************************************** * Refer to "cbuf.h" for documentation on public functions. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* HAVE_CONFIG_H */ #ifdef WITH_PTHREADS # include #endif /* WITH_PTHREADS */ #include #include #include #include #include #include "cbuf.h" /***************************************************************************** * lsd_fatal_error *****************************************************************************/ #ifdef WITH_LSD_FATAL_ERROR_FUNC # undef lsd_fatal_error extern void lsd_fatal_error (char *file, int line, char *mesg); #else /* !WITH_LSD_FATAL_ERROR_FUNC */ # ifndef lsd_fatal_error # include # include # include # define lsd_fatal_error(file, line, mesg) \ do { \ fprintf (stderr, "ERROR: [%s:%d] %s: %s\n", \ file, line, mesg, strerror (errno)); \ } while (0) # endif /* !lsd_fatal_error */ #endif /* !WITH_LSD_FATAL_ERROR_FUNC */ /***************************************************************************** * lsd_nomem_error *****************************************************************************/ #ifdef WITH_LSD_NOMEM_ERROR_FUNC # undef lsd_nomem_error extern void * lsd_nomem_error (char *file, int line, char *mesg); #else /* !WITH_LSD_NOMEM_ERROR_FUNC */ # ifndef lsd_nomem_error # define lsd_nomem_error(file, line, mesg) (NULL) # endif /* !lsd_nomem_error */ #endif /* !WITH_LSD_NOMEM_ERROR_FUNC */ /***************************************************************************** * Constants *****************************************************************************/ #define CBUF_CHUNK 1000 #define CBUF_MAGIC 0xDEADBEEF #define CBUF_MAGIC_LEN (sizeof (unsigned long)) /***************************************************************************** * Data Types *****************************************************************************/ struct cbuf { #ifndef NDEBUG unsigned long magic; /* cookie for asserting validity */ #endif /* !NDEBUG */ #ifdef WITH_PTHREADS pthread_mutex_t mutex; /* mutex to protect access to cbuf */ #endif /* WITH_PTHREADS */ int alloc; /* num bytes malloc'd/realloc'd */ int minsize; /* min bytes of data to allocate */ int maxsize; /* max bytes of data to allocate */ int size; /* num bytes of data allocated */ int used; /* num bytes of unread data */ cbuf_overwrite_t overwrite; /* overwrite option behavior */ int got_wrap; /* true if data has wrapped */ int i_in; /* index to where data is written in */ int i_out; /* index to where data is read out */ int i_rep; /* index to where data is replayable */ unsigned char *data; /* ptr to circular buffer of data */ }; typedef int (*cbuf_iof) (void *cbuf_data, void *arg, int len); /***************************************************************************** * Prototypes *****************************************************************************/ static int cbuf_find_replay_line (cbuf_t cb, int chars, int *nlines, int *nl); static int cbuf_find_unread_line (cbuf_t cb, int chars, int *nlines); static int cbuf_get_fd (void *dstbuf, int *psrcfd, int len); static int cbuf_get_mem (void *dstbuf, unsigned char **psrcbuf, int len); static int cbuf_put_fd (void *srcbuf, int *pdstfd, int len); static int cbuf_put_mem (void *srcbuf, unsigned char **pdstbuf, int len); static int cbuf_copier (cbuf_t src, cbuf_t dst, int len, int *ndropped); static int cbuf_dropper (cbuf_t cb, int len); static int cbuf_reader (cbuf_t src, int len, cbuf_iof putf, void *dst); static int cbuf_replayer (cbuf_t src, int len, cbuf_iof putf, void *dst); static int cbuf_writer (cbuf_t dst, int len, cbuf_iof getf, void *src, int *ndropped); static int cbuf_grow (cbuf_t cb, int n); static int cbuf_shrink (cbuf_t cb); #ifndef NDEBUG static int cbuf_is_valid (cbuf_t cb); #endif /* !NDEBUG */ /***************************************************************************** * Macros *****************************************************************************/ #ifndef MAX # define MAX(x,y) (((x) >= (y)) ? (x) : (y)) #endif /* !MAX */ #ifndef MIN # define MIN(x,y) (((x) <= (y)) ? (x) : (y)) #endif /* !MIN */ #ifdef WITH_PTHREADS # define cbuf_mutex_init(cb) \ do { \ int e = pthread_mutex_init (&cb->mutex, NULL); \ if (e) { \ errno = e; \ lsd_fatal_error (__FILE__, __LINE__, "cbuf mutex init"); \ abort (); \ } \ } while (0) # define cbuf_mutex_lock(cb) \ do { \ int e = pthread_mutex_lock (&cb->mutex); \ if (e) { \ errno = e; \ lsd_fatal_error (__FILE__, __LINE__, "cbuf mutex lock"); \ abort (); \ } \ } while (0) # define cbuf_mutex_unlock(cb) \ do { \ int e = pthread_mutex_unlock (&cb->mutex); \ if (e) { \ errno = e; \ lsd_fatal_error (__FILE__, __LINE__, "cbuf mutex unlock"); \ abort (); \ } \ } while (0) # define cbuf_mutex_destroy(cb) \ do { \ int e = pthread_mutex_destroy (&cb->mutex); \ if (e) { \ errno = e; \ lsd_fatal_error (__FILE__, __LINE__, "cbuf mutex destroy"); \ abort (); \ } \ } while (0) # ifndef NDEBUG static int cbuf_mutex_is_locked (cbuf_t cb); # endif /* !NDEBUG */ #else /* !WITH_PTHREADS */ # define cbuf_mutex_init(cb) # define cbuf_mutex_lock(cb) # define cbuf_mutex_unlock(cb) # define cbuf_mutex_destroy(cb) # define cbuf_mutex_is_locked(cb) (1) #endif /* !WITH_PTHREADS */ /***************************************************************************** * Functions *****************************************************************************/ cbuf_t cbuf_create (int minsize, int maxsize) { cbuf_t cb; if (minsize <= 0) { errno = EINVAL; return (NULL); } if (!(cb = malloc (sizeof (struct cbuf)))) { errno = ENOMEM; return (lsd_nomem_error (__FILE__, __LINE__, "cbuf struct")); } /* Circular buffer is empty when (i_in == i_out), * so reserve 1 byte for this sentinel. */ cb->alloc = minsize + 1; #ifndef NDEBUG /* Reserve space for the magic cookies used to protect the * cbuf data[] array from underflow and overflow. */ cb->alloc += 2 * CBUF_MAGIC_LEN; #endif /* !NDEBUG */ if (!(cb->data = malloc (cb->alloc))) { free (cb); errno = ENOMEM; return (lsd_nomem_error (__FILE__, __LINE__, "cbuf data")); } cbuf_mutex_init (cb); cb->minsize = minsize; cb->maxsize = (maxsize > minsize) ? maxsize : minsize; cb->size = minsize; cb->used = 0; cb->overwrite = CBUF_WRAP_MANY; cb->got_wrap = 0; cb->i_in = cb->i_out = cb->i_rep = 0; #ifndef NDEBUG /* C is for cookie, that's good enough for me, yeah! * The magic cookies are only defined during DEBUG code. * The first "magic" cookie is at the top of the structure. * Magic cookies are also placed at the top & bottom of the * cbuf data[] array to catch buffer underflow & overflow errors. */ cb->data += CBUF_MAGIC_LEN; /* jump forward past underflow magic */ cb->magic = CBUF_MAGIC; /* * Must use memcpy since overflow cookie may not be word-aligned. */ memcpy (cb->data - CBUF_MAGIC_LEN, (void *) &cb->magic, CBUF_MAGIC_LEN); memcpy (cb->data + cb->size + 1, (void *) &cb->magic, CBUF_MAGIC_LEN); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); cbuf_mutex_unlock (cb); #endif /* !NDEBUG */ return (cb); } void cbuf_destroy (cbuf_t cb) { assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); #ifndef NDEBUG /* The moon sometimes looks like a C, but you can't eat that. * Munch the magic cookies before freeing memory. */ cb->magic = ~CBUF_MAGIC; /* the anti-cookie! */ memcpy (cb->data - CBUF_MAGIC_LEN, (void *) &cb->magic, CBUF_MAGIC_LEN); memcpy (cb->data + cb->size + 1, (void *) &cb->magic, CBUF_MAGIC_LEN); cb->data -= CBUF_MAGIC_LEN; /* jump back to what malloc returned */ #endif /* !NDEBUG */ free (cb->data); cbuf_mutex_unlock (cb); cbuf_mutex_destroy (cb); free (cb); return; } void cbuf_flush (cbuf_t cb) { assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); /* * FIXME: Shrink buffer back to minimum size. */ cb->used = 0; cb->got_wrap = 0; cb->i_in = cb->i_out = cb->i_rep = 0; assert (cbuf_is_valid (cb)); cbuf_mutex_unlock (cb); return; } int cbuf_size (cbuf_t cb) { int size; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); size = cb->maxsize; cbuf_mutex_unlock (cb); return (size); } int cbuf_free (cbuf_t cb) { int nfree; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); nfree = cb->maxsize - cb->used; cbuf_mutex_unlock (cb); return (nfree); } int cbuf_used (cbuf_t cb) { int used; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); used = cb->used; cbuf_mutex_unlock (cb); return (used); } int cbuf_lines_used (cbuf_t cb) { int lines = -1; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); cbuf_find_unread_line (cb, cb->size, &lines); cbuf_mutex_unlock (cb); return (lines); } int cbuf_reused (cbuf_t cb) { /* If (O > R) * n = O - R * else * n = (O - 0) + ((S+1) - R). * (S+1) is used since data[] contains 'size' bytes + a 1-byte sentinel. */ int reused; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); reused = (cb->i_out - cb->i_rep + (cb->size + 1)) % (cb->size + 1); cbuf_mutex_unlock (cb); return (reused); } int cbuf_lines_reused (cbuf_t cb) { int lines = -1; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); cbuf_find_replay_line (cb, cb->size, &lines, NULL); cbuf_mutex_unlock (cb); return (lines); } int cbuf_is_empty (cbuf_t cb) { int used; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); used = cb->used; cbuf_mutex_unlock (cb); return (used == 0); } int cbuf_opt_get (cbuf_t cb, cbuf_opt_t name, int *value) { int rc = 0; assert (cb != NULL); if (value == NULL) { errno = EINVAL; return (-1); } cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); if (name == CBUF_OPT_OVERWRITE) { *value = cb->overwrite; } else { errno = EINVAL; rc = -1; } cbuf_mutex_unlock (cb); return (rc); } int cbuf_opt_set (cbuf_t cb, cbuf_opt_t name, int value) { int rc = 0; assert (cb != NULL); cbuf_mutex_lock (cb); assert (cbuf_is_valid (cb)); if (name == CBUF_OPT_OVERWRITE) { if ( (value == CBUF_NO_DROP) || (value == CBUF_WRAP_ONCE) || (value == CBUF_WRAP_MANY) ) { cb->overwrite = value; } else { errno = EINVAL; rc = -1; } } else { errno = EINVAL; rc = -1; } assert (cbuf_is_valid (cb)); cbuf_mutex_unlock (cb); return (rc); } int cbuf_drop (cbuf_t src, int len) { assert (src != NULL); if (len < -1) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); if (len == -1) { len = src->used; } else { len = MIN (len, src->used); } if (len > 0) { cbuf_dropper (src, len); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (len); } int cbuf_peek (cbuf_t src, void *dstbuf, int len) { int n; assert (src != NULL); if ((dstbuf == NULL) || (len < 0)) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_reader (src, len, (cbuf_iof) cbuf_put_mem, &dstbuf); assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_read (cbuf_t src, void *dstbuf, int len) { int n; assert (src != NULL); if ((dstbuf == NULL) || (len < 0)) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_reader (src, len, (cbuf_iof) cbuf_put_mem, &dstbuf); if (n > 0) { cbuf_dropper (src, n); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_replay (cbuf_t src, void *dstbuf, int len) { int n; assert (src != NULL); if ((dstbuf == NULL) || (len < 0)) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_replayer (src, len, (cbuf_iof) cbuf_put_mem, &dstbuf); assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_rewind (cbuf_t src, int len) { int reused; assert (src != NULL); if (len < -1) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); reused = (src->i_out - src->i_rep + (src->size + 1)) % (src->size + 1); if (len == -1) { len = reused; } else { len = MIN (len, reused); } if (len > 0) { src->used += len; src->i_out = (src->i_out - len + (src->size + 1)) % (src->size + 1); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (len); } int cbuf_write (cbuf_t dst, void *srcbuf, int len, int *ndropped) { int n; assert (dst != NULL); if (ndropped) { *ndropped = 0; } if ((srcbuf == NULL) || (len < 0)) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } cbuf_mutex_lock (dst); assert (cbuf_is_valid (dst)); n = cbuf_writer (dst, len, (cbuf_iof) cbuf_get_mem, &srcbuf, ndropped); assert (cbuf_is_valid (dst)); cbuf_mutex_unlock (dst); return (n); } int cbuf_drop_line (cbuf_t src, int len, int lines) { int n; assert (src != NULL); if ((len < 0) || (lines < -1)) { errno = EINVAL; return (-1); } if (lines == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_find_unread_line (src, len, &lines); if (n > 0) { cbuf_dropper (src, n); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_peek_line (cbuf_t src, char *dstbuf, int len, int lines) { int n, m, l; char *pdst; assert (src != NULL); if ((dstbuf == NULL) || (len < 0) || (lines < -1)) { errno = EINVAL; return (-1); } if (lines == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_find_unread_line (src, len - 1, &lines); if (n > 0) { if (len > 0) { m = MIN (n, len - 1); if (m > 0) { pdst = dstbuf; l = cbuf_reader (src, m, (cbuf_iof) cbuf_put_mem, &pdst); assert (l == m); } assert (m < len); dstbuf[m] = '\0'; } } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_read_line (cbuf_t src, char *dstbuf, int len, int lines) { int n, m, l; char *pdst; assert (src != NULL); if ((dstbuf == NULL) || (len < 0) || (lines < -1)) { errno = EINVAL; return (-1); } if (lines == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_find_unread_line (src, len - 1, &lines); if (n > 0) { if (len > 0) { m = MIN (n, len - 1); if (m > 0) { pdst = dstbuf; l = cbuf_reader (src, m, (cbuf_iof) cbuf_put_mem, &pdst); assert (l == m); } assert (m < len); dstbuf[m] = '\0'; } cbuf_dropper (src, n); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_replay_line (cbuf_t src, char *dstbuf, int len, int lines) { int n, m, l; int nl; char *pdst; assert (src != NULL); if ((dstbuf == NULL) || (len < 0) || (lines < -1)) { errno = EINVAL; return (-1); } if (lines == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_find_replay_line (src, len - 1, &lines, &nl); if (n > 0) { if (len > 0) { assert ((nl == 0) || (nl == 1)); m = MIN (n, len - 1 - nl); m = MAX (m, 0); if (m > 0) { pdst = dstbuf; l = cbuf_replayer (src, m, (cbuf_iof) cbuf_put_mem, &pdst); assert (l == m); } /* Append newline if needed and space allows. */ if ((nl) && (len > 1)) { dstbuf[m++] = '\n'; } assert (m < len); dstbuf[m] = '\0'; n += nl; } } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_rewind_line (cbuf_t src, int len, int lines) { int n; assert (src != NULL); if ((len < 0) || (lines < -1)) { errno = EINVAL; return (-1); } if (lines == 0) { return (0); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); n = cbuf_find_replay_line (src, len, &lines, NULL); if (n > 0) { src->used += n; src->i_out = (src->i_out - n + (src->size + 1)) % (src->size + 1); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_write_line (cbuf_t dst, char *srcbuf, int *ndropped) { int len; int nfree, ncopy, n; int ndrop = 0, d; char *psrc = srcbuf; char *newline = "\n"; assert (dst != NULL); if (ndropped) { *ndropped = 0; } if (srcbuf == NULL) { errno = EINVAL; return (-1); } /* Compute number of bytes to effectively copy to dst cbuf. * Reserve space for the trailing newline if needed. */ len = ncopy = strlen (srcbuf); if ((len == 0) || (srcbuf[len - 1] != '\n')) { len++; } cbuf_mutex_lock (dst); assert (cbuf_is_valid (dst)); /* * Attempt to grow dst cbuf if necessary. */ nfree = dst->size - dst->used; if ((len > nfree) && (dst->size < dst->maxsize)) { nfree += cbuf_grow (dst, len - nfree); } /* Determine if src will fit (or be made to fit) in dst cbuf. */ if (dst->overwrite == CBUF_NO_DROP) { if (len > dst->size - dst->used) { errno = ENOSPC; len = -1; /* cannot return while mutex locked */ } } else if (dst->overwrite == CBUF_WRAP_ONCE) { if (len > dst->size) { errno = ENOSPC; len = -1; /* cannot return while mutex locked */ } } if (len > 0) { /* * Discard data that won't fit in dst cbuf. */ if (len > dst->size) { ndrop += len - dst->size; ncopy -= ndrop; psrc += ndrop; } /* Copy data from src string to dst cbuf. */ if (ncopy > 0) { n = cbuf_writer (dst, ncopy, (cbuf_iof) cbuf_get_mem, &psrc, &d); assert (n == ncopy); ndrop += d; } /* Append newline if needed. */ if (srcbuf[len - 1] != '\n') { n = cbuf_writer (dst, 1, (cbuf_iof) cbuf_get_mem, &newline, &d); assert (n == 1); ndrop += d; } } assert (cbuf_is_valid (dst)); cbuf_mutex_unlock (dst); if (ndropped) { *ndropped = ndrop; } return (len); } int cbuf_peek_to_fd (cbuf_t src, int dstfd, int len) { int n = 0; assert (src != NULL); if ((dstfd < 0) || (len < -1)) { errno = EINVAL; return (-1); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); if (len == -1) { len = src->used; } if (len > 0) { n = cbuf_reader (src, len, (cbuf_iof) cbuf_put_fd, &dstfd); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_read_to_fd (cbuf_t src, int dstfd, int len) { int n = 0; assert (src != NULL); if ((dstfd < 0) || (len < -1)) { errno = EINVAL; return (-1); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); if (len == -1) { len = src->used; } if (len > 0) { n = cbuf_reader (src, len, (cbuf_iof) cbuf_put_fd, &dstfd); if (n > 0) { cbuf_dropper (src, n); } } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_replay_to_fd (cbuf_t src, int dstfd, int len) { int n = 0; assert (src != NULL); if ((dstfd < 0) || (len < -1)) { errno = EINVAL; return (-1); } cbuf_mutex_lock (src); assert (cbuf_is_valid (src)); if (len == -1) { len = src->size - src->used; } if (len > 0) { n = cbuf_replayer (src, len, (cbuf_iof) cbuf_put_fd, &dstfd); } assert (cbuf_is_valid (src)); cbuf_mutex_unlock (src); return (n); } int cbuf_write_from_fd (cbuf_t dst, int srcfd, int len, int *ndropped) { int n = 0; assert (dst != NULL); if (ndropped) { *ndropped = 0; } if ((srcfd < 0) || (len < -1)) { errno = EINVAL; return (-1); } cbuf_mutex_lock (dst); assert (cbuf_is_valid (dst)); if (len == -1) { /* * Try to use all of the free buffer space available for writing. * If it is all in use, try to grab another chunk. */ len = dst->size - dst->used; if (len == 0) { len = CBUF_CHUNK; } } if (len > 0) { n = cbuf_writer (dst, len, (cbuf_iof) cbuf_get_fd, &srcfd, ndropped); } assert (cbuf_is_valid (dst)); cbuf_mutex_unlock (dst); return (n); } int cbuf_copy (cbuf_t src, cbuf_t dst, int len, int *ndropped) { int n = 0; assert (src != NULL); assert (dst != NULL); if (ndropped) { *ndropped = 0; } if (src == dst) { errno = EINVAL; return (-1); } if (len < -1) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } /* Lock cbufs in order of lowest memory address to prevent deadlock. */ if (src < dst) { cbuf_mutex_lock (src); cbuf_mutex_lock (dst); } else { cbuf_mutex_lock (dst); cbuf_mutex_lock (src); } assert (cbuf_is_valid (src)); assert (cbuf_is_valid (dst)); if (len == -1) { len = src->used; } if (len > 0) { n = cbuf_copier (src, dst, len, ndropped); } assert (cbuf_is_valid (src)); assert (cbuf_is_valid (dst)); cbuf_mutex_unlock (src); cbuf_mutex_unlock (dst); return (n); } int cbuf_move (cbuf_t src, cbuf_t dst, int len, int *ndropped) { int n = 0; assert (src != NULL); assert (dst != NULL); if (ndropped) { *ndropped = 0; } if (src == dst) { errno = EINVAL; return (-1); } if (len < -1) { errno = EINVAL; return (-1); } if (len == 0) { return (0); } /* Lock cbufs in order of lowest memory address to prevent deadlock. */ if (src < dst) { cbuf_mutex_lock (src); cbuf_mutex_lock (dst); } else { cbuf_mutex_lock (dst); cbuf_mutex_lock (src); } assert (cbuf_is_valid (src)); assert (cbuf_is_valid (dst)); if (len == -1) { len = src->used; } if (len > 0) { n = cbuf_copier (src, dst, len, ndropped); if (n > 0) { cbuf_dropper (src, n); } } assert (cbuf_is_valid (src)); assert (cbuf_is_valid (dst)); cbuf_mutex_unlock (src); cbuf_mutex_unlock (dst); return (n); } static int cbuf_find_replay_line (cbuf_t cb, int chars, int *nlines, int *nl) { /* Finds the specified number of lines from the replay region of the buffer. * If ([nlines] > 0), returns the number of bytes comprising the line count, * or 0 if this number of lines is not available (ie, all or none). * If ([nlines] == -1), returns the number of bytes comprising the maximum * line count bounded by the number of characters specified by [chars]. * Only complete lines (ie, those terminated by a newline) are counted, * with once exception: the most recent line of replay data is treated * as a complete line regardless of the presence of a terminating newline. * Sets the value-result parameter [nlines] to the number of lines found. * Sets [nl] to '1' if a newline is required to terminate the replay data. */ int i, n, m, l; int lines; assert (cb != NULL); assert (nlines != NULL); assert (*nlines >= -1); assert (cbuf_mutex_is_locked (cb)); n = m = l = 0; lines = *nlines; *nlines = 0; if (nl) { *nl = 0; /* init in case of early return */ } if ((lines == 0) || ((lines <= -1) && (chars <= 0))) { return (0); } if (cb->i_out == cb->i_rep) { return (0); /* no replay data available */ } if (lines > 0) { chars = -1; /* chars parm not used if lines > 0 */ } else { ++chars; /* incr to allow for preceding '\n' */ } /* Since the most recent line of replay data is considered implicitly * terminated, decrement the char count to account for the newline * if one is not present, or increment the line count if one is. * Note: cb->data[(O - 1 + (S+1)) % (S+1)] is the last replayable char. */ if (cb->data[(cb->i_out + cb->size) % (cb->size + 1)] != '\n') { if (nl) { *nl = 1; } --chars; } else { if (lines > 0) { ++lines; } --l; } i = cb->i_out; while (i != cb->i_rep) { i = (i + cb->size) % (cb->size + 1); /* (i - 1 + (S+1)) % (S+1) */ ++n; if (chars > 0) { --chars; } /* Complete lines are identified by a preceding newline. */ if (cb->data[i] == '\n') { if (lines > 0) { --lines; } m = n - 1; /* do not include preceding '\n' */ ++l; } if ((chars == 0) || (lines == 0)) { break; } } /* But the first line written in does not need a preceding newline. */ if ((!cb->got_wrap) && ((chars > 0) || (lines > 0))) { if (lines > 0) { --lines; } m = n; ++l; } if (lines > 0) { return (0); /* all or none, and not enough found */ } *nlines = l; return (m); } static int cbuf_find_unread_line (cbuf_t cb, int chars, int *nlines) { /* Finds the specified number of lines from the unread region of the buffer. * If ([nlines] > 0), returns the number of bytes comprising the line count, * or 0 if this number of lines is not available (ie, all or none). * If ([nlines] == -1), returns the number of bytes comprising the maximum * line count bounded by the number of characters specified by [chars]. * Only complete lines (ie, those terminated by a newline) are counted. * Sets the value-result parameter [nlines] to the number of lines found. */ int i, n, m, l; int lines; assert (cb != NULL); assert (nlines != NULL); assert (*nlines >= -1); assert (cbuf_mutex_is_locked (cb)); n = m = l = 0; lines = *nlines; *nlines = 0; if ((lines == 0) || ((lines <= -1) && (chars <= 0))) { return (0); } if (cb->used == 0) { return (0); /* no unread data available */ } if (lines > 0) { chars = -1; /* chars parm not used if lines > 0 */ } i = cb->i_out; while (i != cb->i_in) { ++n; if (chars > 0) { --chars; } if (cb->data[i] == '\n') { if (lines > 0) { --lines; } m = n; ++l; } if ((chars == 0) || (lines == 0)) { break; } i = (i + 1) % (cb->size + 1); } if (lines > 0) { return (0); /* all or none, and not enough found */ } *nlines = l; return (m); } static int cbuf_get_fd (void *dstbuf, int *psrcfd, int len) { /* Copies data from the file referenced by the file descriptor * pointed at by [psrcfd] into cbuf's [dstbuf]. * Returns the number of bytes read from the fd, 0 on EOF, or -1 on error. */ int n; assert (dstbuf != NULL); assert (psrcfd != NULL); assert (*psrcfd >= 0); assert (len > 0); do { n = read (*psrcfd, dstbuf, len); } while ((n < 0) && (errno == EINTR)); return (n); } static int cbuf_get_mem (void *dstbuf, unsigned char **psrcbuf, int len) { /* Copies data from the buffer pointed at by [psrcbuf] into cbuf's [dstbuf]. * Returns the number of bytes copied. */ assert (dstbuf != NULL); assert (psrcbuf != NULL); assert (*psrcbuf != NULL); assert (len > 0); memcpy (dstbuf, *psrcbuf, len); *psrcbuf += len; return (len); } static int cbuf_put_fd (void *srcbuf, int *pdstfd, int len) { /* Copies data from cbuf's [srcbuf] into the file referenced * by the file descriptor pointed at by [pdstfd]. * Returns the number of bytes written to the fd, or -1 on error. */ int n; assert (srcbuf != NULL); assert (pdstfd != NULL); assert (*pdstfd >= 0); assert (len > 0); do { n = write (*pdstfd, srcbuf, len); } while ((n < 0) && (errno == EINTR)); return (n); } static int cbuf_put_mem (void *srcbuf, unsigned char **pdstbuf, int len) { /* Copies data from cbuf's [srcbuf] into the buffer pointed at by [pdstbuf]. * Returns the number of bytes copied. */ assert (srcbuf != NULL); assert (pdstbuf != NULL); assert (*pdstbuf != NULL); assert (len > 0); memcpy (*pdstbuf, srcbuf, len); *pdstbuf += len; return (len); } static int cbuf_copier (cbuf_t src, cbuf_t dst, int len, int *ndropped) { /* Copies up to [len] bytes from the [src] cbuf into the [dst] cbuf. * Returns the number of bytes copied, or -1 on error (with errno set). * Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten. */ int ncopy, nfree, nleft, nrepl, n; int i_src, i_dst; assert (src != NULL); assert (dst != NULL); assert (len > 0); assert (cbuf_mutex_is_locked (src)); assert (cbuf_mutex_is_locked (dst)); /* Bound len by the number of bytes available. */ len = MIN (len, src->used); if (len == 0) { return (0); } /* Attempt to grow dst cbuf if necessary. */ nfree = dst->size - dst->used; if ((len > nfree) && (dst->size < dst->maxsize)) { nfree += cbuf_grow (dst, len - nfree); } /* Compute number of bytes to effectively copy to dst cbuf. */ if (dst->overwrite == CBUF_NO_DROP) { len = MIN (len, dst->size - dst->used); if (len == 0) { errno = ENOSPC; return (-1); } } else if (dst->overwrite == CBUF_WRAP_ONCE) { len = MIN (len, dst->size); } /* Compute number of bytes that will be overwritten in dst cbuf. */ if (ndropped) { *ndropped = MAX (0, len - dst->size + dst->used); } /* Compute number of bytes to physically copy to dst cbuf. This prevents * copying data that will overwritten if the cbuf wraps multiple times. */ ncopy = len; i_src = src->i_out; i_dst = dst->i_in; if (ncopy > dst->size) { n = ncopy - dst->size; i_src = (i_src + n) % (src->size + 1); ncopy -= n; } /* Copy data from src cbuf to dst cbuf. */ nleft = ncopy; while (nleft > 0) { n = MIN (((src->size + 1) - i_src), ((dst->size + 1) - i_dst)); n = MIN (n, nleft); memcpy (&dst->data[i_dst], &src->data[i_src], n); i_src = (i_src + n) % (src->size + 1); i_dst = (i_dst + n) % (dst->size + 1); nleft -= n; } /* Update dst cbuf metadata. */ if (ncopy > 0) { nrepl = (dst->i_out - dst->i_rep + (dst->size + 1)) % (dst->size + 1); dst->used = MIN (dst->used + ncopy, dst->size); assert (i_dst == (dst->i_in + ncopy) % (dst->size + 1)); dst->i_in = i_dst; if (ncopy > nfree - nrepl) { dst->got_wrap = 1; dst->i_rep = (dst->i_in + 1) % (dst->size + 1); } if (ncopy > nfree) { dst->i_out = dst->i_rep; } } return (len); } static int cbuf_dropper (cbuf_t cb, int len) { /* Discards exactly [len] bytes of unread data from [cb]. * Returns the number of bytes dropped. */ assert (cb != NULL); assert (len > 0); assert (len <= cb->used); assert (cbuf_mutex_is_locked (cb)); cb->used -= len; cb->i_out = (cb->i_out + len) % (cb->size + 1); /* Attempt to shrink cbuf if possible. */ if ((cb->size - cb->used > CBUF_CHUNK) && (cb->size > cb->minsize)) { cbuf_shrink (cb); } /* Don't call me clumsy, don't call me a fool. * When things fall down on me, I'm following the rule. */ return (len); } static int cbuf_reader (cbuf_t src, int len, cbuf_iof putf, void *dst) { /* Reads up to [len] bytes from [src] into the object pointed at by [dst]. * The I/O function [putf] specifies how data is written into [dst]. * Returns the number of bytes read, or -1 on error (with errno set). * Note that [dst] is a value-result parameter and will be "moved forward" * by the number of bytes written into it. */ int nleft, n, m; int i_src; assert (src != NULL); assert (len > 0); assert (putf != NULL); assert (dst != NULL); assert (cbuf_mutex_is_locked (src)); /* Bound len by the number of bytes available. */ len = MIN (len, src->used); if (len == 0) { return (0); } /* Copy data from src cbuf to dst obj. Do the cbuf hokey-pokey and * wrap-around the buffer at most once. Break out if putf() returns * either an ERR or a short count. */ i_src = src->i_out; nleft = len; m = 0; while (nleft > 0) { n = MIN (nleft, (src->size + 1) - i_src); m = putf (&src->data[i_src], dst, n); if (m > 0) { nleft -= m; i_src = (i_src + m) % (src->size + 1); } if (n != m) { break; /* got ERR or "short" putf() */ } } /* Compute number of bytes written to dst obj. */ n = len - nleft; assert ((n >= 0) && (n <= len)); /* * If no data has been written, return the ERR reported by putf(). */ if (n == 0) { return (m); } return (n); } static int cbuf_replayer (cbuf_t src, int len, cbuf_iof putf, void *dst) { /* Replays up to [len] bytes from [src] into the object pointed at by [dst]. * The I/O function [putf] specifies how data is written into [dst]. * Returns the number of bytes replayed, or -1 on error (with errno set). * Note that [dst] is a value-result parameter and will be "moved forward" * by the number of bytes written into it. */ int nleft, n, m; int i_src; assert (src != NULL); assert (len > 0); assert (putf != NULL); assert (dst != NULL); assert (cbuf_mutex_is_locked (src)); /* Bound len by the number of bytes available. */ n = (src->i_out - src->i_rep + (src->size + 1)) % (src->size + 1); len = MIN (len, n); if (len == 0) { return (0); } /* Copy data from src cbuf to dst obj. Do the cbuf hokey-pokey and * wrap-around the buffer at most once. Break out if putf() returns * either an ERR or a short count. */ i_src = (src->i_out - len + (src->size + 1)) % (src->size + 1); nleft = len; m = 0; while (nleft > 0) { n = MIN (nleft, (src->size + 1) - i_src); m = putf (&src->data[i_src], dst, n); if (m > 0) { nleft -= m; i_src = (i_src + m) % (src->size + 1); } if (n != m) { break; /* got ERR or "short" putf() */ } } /* Compute number of bytes written to dst obj. */ n = len - nleft; assert ((n >= 0) && (n <= len)); /* * If no data has been written, return the ERR reported by putf(). */ if (n == 0) { return (m); } return (n); } static int cbuf_writer (cbuf_t dst, int len, cbuf_iof getf, void *src, int *ndropped) { /* Writes up to [len] bytes from the object pointed at by [src] into [dst]. * The I/O function [getf] specifies how data is read from [src]. * Returns the number of bytes written, or -1 on error (with errno set). * Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten. * Note that [src] is a value-result parameter and will be "moved forward" * by the number of bytes read from it. */ int nfree, nleft, nrepl, n, m; int i_dst; assert (dst != NULL); assert (len > 0); assert (getf != NULL); assert (src != NULL); assert (cbuf_mutex_is_locked (dst)); /* Attempt to grow dst cbuf if necessary. */ nfree = dst->size - dst->used; if ((len > nfree) && (dst->size < dst->maxsize)) { nfree += cbuf_grow (dst, len - nfree); } /* Compute number of bytes to write to dst cbuf. */ if (dst->overwrite == CBUF_NO_DROP) { len = MIN (len, dst->size - dst->used); if (len == 0) { errno = ENOSPC; return (-1); } } else if (dst->overwrite == CBUF_WRAP_ONCE) { len = MIN (len, dst->size); } /* Copy data from src obj to dst cbuf. Do the cbuf hokey-pokey and * wrap-around the buffer as needed. Break out if getf() returns * either an EOF/ERR or a short count. */ i_dst = dst->i_in; nleft = len; m = 0; while (nleft > 0) { n = MIN (nleft, (dst->size + 1) - i_dst); m = getf (&dst->data[i_dst], src, n); if (m > 0) { nleft -= m; i_dst = (i_dst + m) % (dst->size + 1); } if (n != m) { break; /* got EOF/ERR or "short" getf() */ } } /* Compute number of bytes written to dst cbuf. */ n = len - nleft; assert ((n >= 0) && (n <= len)); /* * If no data has been written, return the EOF/ERR reported by getf(). */ if (n == 0) { return (m); } /* Update dst cbuf metadata. */ if (n > 0) { nrepl = (dst->i_out - dst->i_rep + (dst->size + 1)) % (dst->size + 1); dst->used = MIN (dst->used + n, dst->size); assert (i_dst == (dst->i_in + n) % (dst->size + 1)); dst->i_in = i_dst; if (n > nfree - nrepl) { dst->got_wrap = 1; dst->i_rep = (dst->i_in + 1) % (dst->size + 1); } if (n > nfree) { dst->i_out = dst->i_rep; } } if (ndropped) { *ndropped = MAX (0, n - nfree); } return (n); } static int cbuf_grow (cbuf_t cb, int n) { /* Attempts to grow the circular buffer [cb] by at least [n] bytes. * Returns the number of bytes by which the buffer has grown (which may be * less-than, equal-to, or greater-than the number of bytes requested). */ unsigned char *data; int size_old, size_meta; int m; assert (cb != NULL); assert (n > 0); assert (cbuf_mutex_is_locked (cb)); if (cb->size == cb->maxsize) { return (0); } size_old = cb->size; size_meta = cb->alloc - cb->size; /* size of sentinel & magic cookies */ assert (size_meta > 0); /* Attempt to grow data buffer by multiples of the chunk-size. */ m = cb->alloc + n; m = m + (CBUF_CHUNK - (m % CBUF_CHUNK)); m = MIN (m, (cb->maxsize + size_meta)); assert (m > cb->alloc); data = cb->data; #ifndef NDEBUG data -= CBUF_MAGIC_LEN; /* jump back to what malloc returned */ #endif /* !NDEBUG */ if (!(data = realloc (data, m))) { /* * XXX: Set flag or somesuch to prevent regrowing when out of memory? */ return (0); /* unable to grow data buffer */ } cb->data = data; cb->alloc = m; cb->size = m - size_meta; #ifndef NDEBUG /* A round cookie with one bite out of it looks like a C. * The underflow cookie will have been copied by realloc() if needed. * But the overflow cookie must be rebaked. * Must use memcpy since overflow cookie may not be word-aligned. */ cb->data += CBUF_MAGIC_LEN; /* jump forward past underflow magic */ memcpy (cb->data + cb->size + 1, (void *) &cb->magic, CBUF_MAGIC_LEN); #endif /* !NDEBUG */ /* The memory containing replay and unread data must be contiguous modulo * the buffer size. Additional memory must be inserted between where * new data is written in (i_in) and where replay data starts (i_rep). * If replay data wraps-around the old buffer, move it to the new end * of the buffer so it wraps-around in the same manner. */ if (cb->i_rep > cb->i_in) { n = (size_old + 1) - cb->i_rep; m = (cb->size + 1) - n; memmove (cb->data + m, cb->data + cb->i_rep, n); if (cb->i_out >= cb->i_rep) { cb->i_out += m - cb->i_rep; } cb->i_rep = m; } assert (cbuf_is_valid (cb)); return (cb->size - size_old); } static int cbuf_shrink (cbuf_t cb) { /* XXX: DOCUMENT ME. */ assert (cb != NULL); assert (cbuf_mutex_is_locked (cb)); assert (cbuf_is_valid (cb)); if (cb->size == cb->minsize) { return (0); } if (cb->size - cb->used <= CBUF_CHUNK) { return (0); } /* FIXME: NOT IMPLEMENTED. */ assert (cbuf_is_valid (cb)); return (0); } #ifndef NDEBUG #ifdef WITH_PTHREADS static int cbuf_mutex_is_locked (cbuf_t cb) { /* Returns true if the mutex is locked; o/w, returns false. */ int rc; assert (cb != NULL); rc = pthread_mutex_trylock (&cb->mutex); return (rc == EBUSY ? 1 : 0); } #endif /* WITH_PTHREADS */ #endif /* !NDEBUG */ #ifndef NDEBUG static int cbuf_is_valid (cbuf_t cb) { /* Validates the data structure. All invariants should be tested here. * Returns true if everything is valid; o/w, aborts due to assertion failure. */ int nfree; assert (cb != NULL); assert (cbuf_mutex_is_locked (cb)); assert (cb->data != NULL); assert (cb->magic == CBUF_MAGIC); /* * Must use memcmp since overflow cookie may not be word-aligned. */ assert (memcmp (cb->data - CBUF_MAGIC_LEN, (void *) &cb->magic, CBUF_MAGIC_LEN) == 0); assert (memcmp (cb->data + cb->size + 1, (void *) &cb->magic, CBUF_MAGIC_LEN) == 0); assert (cb->alloc > 0); assert (cb->alloc > cb->size); assert (cb->size > 0); assert (cb->size >= cb->minsize); assert (cb->size <= cb->maxsize); assert (cb->minsize > 0); assert (cb->maxsize > 0); assert (cb->used >= 0); assert (cb->used <= cb->size); assert (cb->overwrite == CBUF_NO_DROP || cb->overwrite == CBUF_WRAP_ONCE || cb->overwrite == CBUF_WRAP_MANY); assert (cb->got_wrap || !cb->i_rep);/* i_rep = 0 if data has not wrapped */ assert (cb->i_in >= 0); assert (cb->i_in <= cb->size); assert (cb->i_out >= 0); assert (cb->i_out <= cb->size); assert (cb->i_rep >= 0); assert (cb->i_rep <= cb->size); if (cb->i_in >= cb->i_out) { assert ((cb->i_rep > cb->i_in) || (cb->i_rep <= cb->i_out)); } else /* if (cb->in < cb->i_out) */ { assert ((cb->i_rep > cb->i_in) && (cb->i_rep <= cb->i_out)); } nfree = (cb->i_out - cb->i_in - 1 + (cb->size + 1)) % (cb->size + 1); assert (cb->size - cb->used == nfree); return (1); } #endif /* !NDEBUG */ powerman-2.3.27/liblsd/cbuf.h000066400000000000000000000320101415616035500160000ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2002-2005 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #ifndef LSD_CBUF_H #define LSD_CBUF_H /***************************************************************************** * Notes *****************************************************************************/ /* * Cbuf is a circular-buffer capable of dynamically resizing itself. * Unread data in the buffer will be overwritten once the cbuf has * reached its maximum size or is unable to allocate additional memory. * * The CBUF_OPT_OVERWRITE option specifies how unread cbuf data will * be overwritten. If set to CBUF_NO_DROP, unread data will never be * overwritten; writes into the cbuf will return -1 with ENOSPC. If set * to CBUF_WRAP_ONCE, a single write operation will wrap-around the buffer * at most once, and up to cbuf_used() bytes of data may be overwritten. * If set to CBUF_WRAP_MANY, a single write operation will wrap-around the * buffer as many times as needed in order to write all of the data. * * If NDEBUG is not defined, internal debug code will be enabled. This is * intended for development use only and production code should define NDEBUG. * * If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to * find an external lsd_fatal_error(file,line,mesg) function. By default, * lsd_fatal_error(file,line,mesg) is a macro definition that outputs an * error message to stderr. This macro may be redefined to invoke another * routine instead. * * If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to * find an external lsd_nomem_error(file,line,mesg) function. By default, * lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL. * This macro may be redefined to invoke another routine instead. * * If WITH_PTHREADS is defined, these routines will be thread-safe. */ /***************************************************************************** * Data Types *****************************************************************************/ typedef struct cbuf * cbuf_t; /* circular-buffer opaque data type */ typedef enum { /* cbuf option names */ CBUF_OPT_OVERWRITE } cbuf_opt_t; typedef enum { /* CBUF_OPT_OVERWRITE values: */ CBUF_NO_DROP, /* -never drop data, ENOSPC if full */ CBUF_WRAP_ONCE, /* -drop data, wrapping at most once */ CBUF_WRAP_MANY /* -drop data, wrapping as needed */ } cbuf_overwrite_t; /***************************************************************************** * Functions *****************************************************************************/ cbuf_t cbuf_create (int minsize, int maxsize); /* * Creates and returns a new circular buffer, or lsd_nomem_error() on failure. * The buffer is initially allocated to hold [minsize] bytes of data, * but can attempt to grow up to [maxsize] bytes before overwriting data. * Set minsize = maxsize to prevent cbuf from dynamically resizing itself. * The default overwrite option behavior is CBUF_WRAP_MANY. * Abandoning a cbuf without calling cbuf_destroy() will cause a memory leak. */ void cbuf_destroy (cbuf_t cb); /* * Destroys the circular buffer [cb]. */ void cbuf_flush (cbuf_t cb); /* * Flushes all data (including replay data) in [cb]. */ int cbuf_size (cbuf_t cb); /* * Returns the maximum size of the buffer allocated to [cb] * (ie, the number of bytes it can currently hold). */ int cbuf_free (cbuf_t cb); /* * Returns the number of bytes in [cb] available for writing before unread * data is overwritten (assuming the cbuf can resize itself if needed). */ int cbuf_used (cbuf_t cb); /* * Returns the number of bytes in [cb] available for reading. */ int cbuf_lines_used (cbuf_t cb); /* * Returns the number of lines in [cb] available for reading. */ int cbuf_reused (cbuf_t cb); /* * Returns the number of bytes in [cb] available for replaying/rewinding. */ int cbuf_lines_reused (cbuf_t cb); /* * Returns the number of lines in [cb] available for replaying/rewinding. */ int cbuf_is_empty (cbuf_t cb); /* * Returns non-zero if [cb] is empty; o/w, returns zero. */ int cbuf_opt_get (cbuf_t cb, cbuf_opt_t name, int *value); /* * Gets the [name] option for [cb] and sets [value] to the result. * Returns 0 on success, or -1 on error (with errno set). */ int cbuf_opt_set (cbuf_t cb, cbuf_opt_t name, int value); /* * Sets the [name] option for [cb] to [value]. * Returns 0 on success, or -1 on error (with errno set). */ int cbuf_drop (cbuf_t src, int len); /* * Discards up to [len] bytes of unread data from [src]; * if [len] is -1, all unread data will be dropped. * Dropped data is still available via the replay buffer. * Returns the number of bytes dropped, or -1 on error (with errno set). */ int cbuf_peek (cbuf_t src, void *dstbuf, int len); /* * Reads up to [len] bytes of data from the [src] cbuf into [dstbuf], * but does not consume the data read from the cbuf. * The "peek" can be committed to the cbuf via a call to cbuf_drop(), * but the peek+drop combination is not atomic. * Returns the number of bytes read, or -1 on error (with errno set). */ int cbuf_read (cbuf_t src, void *dstbuf, int len); /* * Reads up to [len] bytes of data from the [src] cbuf into [dstbuf]. * Returns the number of bytes read, or -1 on error (with errno set). */ int cbuf_replay (cbuf_t src, void *dstbuf, int len); /* * Replays up to [len] bytes of previously read data from the [src] cbuf * into [dstbuf]. * Returns the number of bytes replayed, or -1 on error (with errno set). */ int cbuf_rewind (cbuf_t src, int len); /* * Rewinds [src] by up to [len] bytes, placing previously read data back in * the unread data buffer; if [len] is -1, all replay data will be rewound. * Returns the number of bytes rewound, or -1 on error (with errno set). */ int cbuf_write (cbuf_t dst, void *srcbuf, int len, int *ndropped); /* * Writes up to [len] bytes of data from [srcbuf] into the [dst] cbuf * according to dst's CBUF_OPT_OVERWRITE behavior. * Returns the number of bytes written, or -1 on error (with errno set). * Sets [ndropped] (if not NULL) to the number of bytes overwritten. */ int cbuf_drop_line (cbuf_t src, int len, int lines); /* * Discards the specified [lines] of data from [src]. If [lines] is -1, * discards the maximum number of lines comprised of up to [len] characters. * Dropped data is still available via the replay buffer. * Returns the number of bytes dropped, or -1 on error (with errno set). * Returns 0 if the number of lines is not available (ie, all or none). */ int cbuf_peek_line (cbuf_t src, char *dstbuf, int len, int lines); /* * Reads the specified [lines] of data from the [src] cbuf into [dstbuf], * but does not consume the data read from the cbuf. If [lines] is -1, * reads the maximum number of lines that [dstbuf] can hold. The buffer * will be NUL-terminated and contain at most ([len] - 1) characters. * The "peek" can be committed to the cbuf via a call to cbuf_drop(), * but the peek+drop combination is not atomic. * Returns strlen of the line(s) on success; truncation occurred if >= [len]. * Returns 0 if the number of lines is not available (ie, all or none). * Returns -1 on error (with errno set). */ int cbuf_read_line (cbuf_t src, char *dstbuf, int len, int lines); /* * Reads the specified [lines] of data from the [src] cbuf into [dstbuf]. * If [lines] is -1, reads the maximum number of lines that [dstbuf] * can hold. The buffer will be NUL-terminated and contain at most * ([len] - 1) characters. * Returns strlen of the line(s) on success; truncation occurred if >= [len], * in which case excess line data is discarded. Returns 0 if the number * of lines is not available (ie, all or none), in which case no data is * consumed. Returns -1 on error (with errno set). */ int cbuf_replay_line (cbuf_t src, char *dstbuf, int len, int lines); /* * Replays the specified [lines] of data from the [src] cbuf into [dstbuf]. * If [lines] is -1, replays the maximum number of lines that [dstbuf] * can hold. A newline will be appended to [dstbuf] if the last (ie, most * recently read) line does not contain a trailing newline. The buffer * will be NUL-terminated and contain at most ([len] - 1) characters. * Returns strlen of the line(s) on success; truncation occurred if >= [len]. * Returns 0 if the number of lines is not available (ie, all or none). * Returns -1 on error (with errno set). */ int cbuf_rewind_line (cbuf_t src, int len, int lines); /* * Rewinds [src] by the specified [lines] of data, placing previously read * data back in the unread data buffer. If [lines] is -1, rewinds the * maximum number of lines comprised of up to [len] characters. * Returns the number of bytes rewound, or -1 on error (with errno set). * Returns 0 if the number of lines is not available (ie, all or none). */ int cbuf_write_line (cbuf_t dst, char *srcbuf, int *ndropped); /* * Writes the entire NUL-terminated [srcbuf] string into the [dst] cbuf * according to dst's CBUF_OPT_OVERWRITE behavior. A newline will be * appended to the cbuf if [srcbuf] does not contain a trailing newline. * Returns the number of bytes written, or -1 or error (with errno set). * Sets [ndropped] (if not NULL) to the number of bytes overwritten. */ int cbuf_peek_to_fd (cbuf_t src, int dstfd, int len); /* * Reads up to [len] bytes of data from the [src] cbuf into the file * referenced by the [dstfd] file descriptor, but does not consume the * data read from the cbuf. If [len] is -1, it will be set to the number * of [src] bytes available for reading. * The "peek" can be committed to the cbuf via a call to cbuf_drop(), * but the peek+drop combination is not atomic. * Returns the number of bytes read, or -1 on error (with errno set). */ int cbuf_read_to_fd (cbuf_t src, int dstfd, int len); /* * Reads up to [len] bytes of data from the [src] cbuf into the file * referenced by the [dstfd] file descriptor. If [len] is -1, it will * be set to the number of [src] bytes available for reading. * Returns the number of bytes read, or -1 on error (with errno set). */ int cbuf_replay_to_fd (cbuf_t src, int dstfd, int len); /* * Replays up to [len] bytes of previously read data from the [src] cbuf into * the file referenced by the [dstfd] file descriptor. If [len] is -1, it * will be set to the maximum number of [src] bytes available for replay. * Returns the number of bytes replayed, or -1 on error (with errno set). */ int cbuf_write_from_fd (cbuf_t dst, int srcfd, int len, int *ndropped); /* * Writes up to [len] bytes of data from the file referenced by the * [srcfd] file descriptor into the [dst] cbuf according to dst's * CBUF_OPT_OVERWRITE behavior. If [len] is -1, it will be set to * an appropriate chunk size. * Returns the number of bytes written, 0 on EOF, or -1 on error (with errno). * Sets [ndropped] (if not NULL) to the number of bytes overwritten. */ int cbuf_copy (cbuf_t src, cbuf_t dst, int len, int *ndropped); /* * Copies up to [len] bytes of data from the [src] cbuf into the [dst] cbuf * according to dst's CBUF_OPT_OVERWRITE behavior. If [len] is -1, * it will be set to the number of [src] bytes available for reading. * Returns the number of bytes copied, or -1 on error (with errno set). * Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten. */ int cbuf_move (cbuf_t src, cbuf_t dst, int len, int *ndropped); /* * Moves up to [len] bytes of data from the [src] cbuf into the [dst] cbuf * according to dst's CBUF_OPT_OVERWRITE behavior. If [len] is -1, * it will be set to the number of [src] bytes available for reading. * Returns the number of bytes moved, or -1 on error (with errno set). * Sets [ndropped] (if not NULL) to the number of [dst] bytes overwritten. */ #endif /* !LSD_CBUF_H */ powerman-2.3.27/liblsd/hash.c000066400000000000000000000264471415616035500160200ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***************************************************************************** * Refer to "hash.h" for documentation on public functions. *****************************************************************************/ #if HAVE_CONFIG_H # include "config.h" #endif /* HAVE_CONFIG_H */ #include #include #include #include #if WITH_PTHREADS #include "thread.h" #else # define lsd_mutex_init(mutex) # define lsd_mutex_lock(mutex) # define lsd_mutex_unlock(mutex) # define lsd_mutex_destroy(mutex) # define lsd_mutex_is_locked(mutex) (1) #endif #include "hash.h" /***************************************************************************** * Constants *****************************************************************************/ #define HASH_ALLOC 256 #define HASH_DEF_SIZE 1213 #define HASH_MAGIC 0xDEADBEEF /***************************************************************************** * Data Types *****************************************************************************/ struct hash_node { struct hash_node *next; /* next node in list */ void *data; /* ptr to hashed item */ const void *hkey; /* ptr to hashed item's key */ }; struct hash { int count; /* number of items in hash table */ int size; /* num slots allocated in hash table */ struct hash_node **table; /* hash table array of node ptrs */ hash_cmp_f cmp_f; /* key comparison function */ hash_del_f del_f; /* item deletion function */ hash_key_f key_f; /* key hash function */ #if WITH_PTHREADS pthread_mutex_t mutex; /* mutex to protect access to hash */ #endif /* WITH_PTHREADS */ #ifndef NDEBUG unsigned int magic; /* sentinel for asserting validity */ #endif /* NDEBUG */ }; /***************************************************************************** * Prototypes *****************************************************************************/ static struct hash_node * hash_node_alloc (void); static void hash_node_free (struct hash_node *node); /***************************************************************************** * Variables *****************************************************************************/ static struct hash_node *hash_free_list = NULL; #if WITH_PTHREADS static pthread_mutex_t hash_free_lock = PTHREAD_MUTEX_INITIALIZER; #endif /* WITH_PTHREADS */ /***************************************************************************** * Macros *****************************************************************************/ #ifdef WITH_LSD_FATAL_ERROR_FUNC # undef lsd_fatal_error extern void lsd_fatal_error (char *file, int line, char *mesg); #else /* !WITH_LSD_FATAL_ERROR_FUNC */ # ifndef lsd_fatal_error # define lsd_fatal_error(file, line, mesg) (abort ()) # endif /* !lsd_fatal_error */ #endif /* !WITH_LSD_FATAL_ERROR_FUNC */ #ifdef WITH_LSD_NOMEM_ERROR_FUNC # undef lsd_nomem_error extern void * lsd_nomem_error (char *file, int line, char *mesg); #else /* !WITH_LSD_NOMEM_ERROR_FUNC */ # ifndef lsd_nomem_error # define lsd_nomem_error(file, line, mesg) (NULL) # endif /* !lsd_nomem_error */ #endif /* !WITH_LSD_NOMEM_ERROR_FUNC */ /***************************************************************************** * Functions *****************************************************************************/ hash_t hash_create (int size, hash_key_f key_f, hash_cmp_f cmp_f, hash_del_f del_f) { hash_t h; if (!cmp_f || !key_f) { errno = EINVAL; return (NULL); } if (size <= 0) { size = HASH_DEF_SIZE; } if (!(h = malloc (sizeof (*h)))) { return (lsd_nomem_error (__FILE__, __LINE__, "hash_create")); } if (!(h->table = calloc (size, sizeof (struct hash_node *)))) { free (h); return (lsd_nomem_error (__FILE__, __LINE__, "hash_create")); } h->count = 0; h->size = size; h->cmp_f = cmp_f; h->del_f = del_f; h->key_f = key_f; lsd_mutex_init (&h->mutex); assert (h->magic = HASH_MAGIC); /* set magic via assert abuse */ return (h); } void hash_destroy (hash_t h) { int i; struct hash_node *p, *q; assert (h != NULL); lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); for (i = 0; i < h->size; i++) { for (p = h->table[i]; p != NULL; p = q) { q = p->next; if (h->del_f) h->del_f (p->data); hash_node_free (p); } } assert (h->magic = ~HASH_MAGIC); /* clear magic via assert abuse */ lsd_mutex_unlock (&h->mutex); lsd_mutex_destroy (&h->mutex); free (h->table); free (h); return; } int hash_is_empty (hash_t h) { int n; assert (h != NULL); lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); n = h->count; lsd_mutex_unlock (&h->mutex); return (n == 0); } int hash_count (hash_t h) { int n; assert (h != NULL); lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); n = h->count; lsd_mutex_unlock (&h->mutex); return (n); } void * hash_find (hash_t h, const void *key) { unsigned int slot; struct hash_node *p; void *data = NULL; assert (h != NULL); if (!key) { errno = EINVAL; return (NULL); } errno = 0; lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); slot = h->key_f (key) % h->size; for (p = h->table[slot]; p != NULL; p = p->next) { if (!h->cmp_f (p->hkey, key)) { data = p->data; break; } } lsd_mutex_unlock (&h->mutex); return (data); } void * hash_insert (hash_t h, const void *key, void *data) { struct hash_node *p; unsigned int slot; assert (h != NULL); if (!key || !data) { errno = EINVAL; return (NULL); } lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); slot = h->key_f (key) % h->size; for (p = h->table[slot]; p != NULL; p = p->next) { if (!h->cmp_f (p->hkey, key)) { errno = EEXIST; data = NULL; goto end; } } if (!(p = hash_node_alloc())) { data = lsd_nomem_error (__FILE__, __LINE__, "hash_insert"); goto end; } p->hkey = key; p->data = data; p->next = h->table[slot]; h->table[slot] = p; h->count++; end: lsd_mutex_unlock (&h->mutex); return (data); } void * hash_remove (hash_t h, const void *key) { struct hash_node **pp; struct hash_node *p; unsigned int slot; void *data = NULL; assert (h != NULL); if (!key) { errno = EINVAL; return (NULL); } errno = 0; lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); slot = h->key_f (key) % h->size; for (pp = &(h->table[slot]); (p = *pp) != NULL; pp = &((*pp)->next)) { if (!h->cmp_f (p->hkey, key)) { data = p->data; *pp = p->next; hash_node_free (p); h->count--; break; } } lsd_mutex_unlock (&h->mutex); return (data); } int hash_delete_if (hash_t h, hash_arg_f arg_f, void *arg) { int i; struct hash_node **pp; struct hash_node *p; int n = 0; assert (h != NULL); if (!arg_f) { errno = EINVAL; return (-1); } lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); for (i = 0; i < h->size; i++) { pp = &(h->table[i]); while ((p = *pp) != NULL) { if (arg_f (p->data, arg) > 0) { if (h->del_f) h->del_f (p->data); *pp = p->next; hash_node_free (p); h->count--; n++; } else { pp = &(p->next); } } } lsd_mutex_unlock (&h->mutex); return (n); } int hash_for_each (hash_t h, hash_arg_f arg_f, void *arg) { int i; struct hash_node *p; int n = 0; assert (h != NULL); if (!arg_f) { errno = EINVAL; return (-1); } lsd_mutex_lock (&h->mutex); assert (h->magic == HASH_MAGIC); for (i = 0; i < h->size; i++) { for (p = h->table[i]; p != NULL; p = p->next) { if (arg_f (p->data, arg) > 0) { n++; } } } lsd_mutex_unlock (&h->mutex); return (n); } /***************************************************************************** * Hash Functions *****************************************************************************/ unsigned int hash_key_string (const char *str) { unsigned char *p; unsigned int hval = 0; const unsigned int multiplier = 31; for (p = (unsigned char *) str; *p != '\0'; p++) { hval += (multiplier * hval) + *p; } return (hval); } /***************************************************************************** * Internal Functions *****************************************************************************/ static struct hash_node * hash_node_alloc (void) { /* Allocates a hash node from the freelist. * Memory is allocated in chunks of HASH_ALLOC. * Returns a ptr to the object, or NULL if memory allocation fails. */ int i; struct hash_node *p = NULL; assert (HASH_ALLOC > 0); lsd_mutex_lock (&hash_free_lock); if (!hash_free_list) { if ((hash_free_list = malloc (HASH_ALLOC * sizeof (*p)))) { for (i = 0; i < HASH_ALLOC - 1; i++) hash_free_list[i].next = &hash_free_list[i+1]; hash_free_list[i].next = NULL; } } if (hash_free_list) { p = hash_free_list; hash_free_list = p->next; } else { errno = ENOMEM; } lsd_mutex_unlock (&hash_free_lock); return (p); } static void hash_node_free (struct hash_node *node) { /* De-allocates the object [node], returning it to the freelist. */ assert (node != NULL); memset (node, 0, sizeof (*node)); lsd_mutex_lock (&hash_free_lock); node->next = hash_free_list; hash_free_list = node; lsd_mutex_unlock (&hash_free_lock); return; } powerman-2.3.27/liblsd/hash.h000066400000000000000000000153171415616035500160170ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #ifndef LSD_HASH_H #define LSD_HASH_H /***************************************************************************** * Notes *****************************************************************************/ /* * If an item's key is modified after insertion, the hash will be unable to * locate it if the new key should hash to a different slot in the table. * * If NDEBUG is not defined, internal debug code will be enabled; this is * intended for development use only. Production code should define NDEBUG. * * If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to * find an external lsd_fatal_error(file,line,mesg) function. By default, * lsd_fatal_error(file,line,mesg) is a macro definition that aborts. * This macro may be redefined to invoke another routine instead. * * If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to * find an external lsd_nomem_error(file,line,mesg) function. By default, * lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL. * This macro may be redefined to invoke another routine instead. * * If WITH_PTHREADS is defined, these routines will be thread-safe. */ /***************************************************************************** * Data Types *****************************************************************************/ typedef struct hash * hash_t; /* * Hash table opaque data type. */ typedef unsigned int (*hash_key_f) (const void *key); /* * Function prototype for the hash function responsible for converting * the data's [key] into an unsigned integer hash value. */ typedef int (*hash_cmp_f) (const void *key1, const void *key2); /* * Function prototype for comparing two keys. * Returns zero if both keys are equal; o/w, returns nonzero. */ typedef void (*hash_del_f) (void *data); /* * Function prototype for de-allocating a data item stored within a hash. * This function is responsible for freeing all memory associated with * the [data] item, including any subordinate items. */ typedef int (*hash_arg_f) (void *data, void *arg); /* * Function prototype for operating on each element in the hash table. * The function will be invoked once for each [data] item in the hash, * with [arg] being passed in as an argument. */ /***************************************************************************** * Functions *****************************************************************************/ hash_t hash_create (int size, hash_key_f key_f, hash_cmp_f cmp_f, hash_del_f del_f); /* * Creates and returns a new hash table on success. * Returns lsd_nomem_error() with errno=ENOMEM if memory allocation fails. * Returns NULL with errno=EINVAL if [keyf] or [cmpf] is not specified. * The [size] is the number of slots in the table; a larger table requires * more memory, but generally provide quicker access times. If set <= 0, * the default size is used. * The [keyf] function converts a key into a hash value. * The [cmpf] function determines whether two keys are equal. * The [delf] function de-allocates memory used by items in the hash; * if set to NULL, memory associated with these items will not be freed * when the hash is destroyed. */ void hash_destroy (hash_t h); /* * Destroys hash table [h]. If a deletion function was specified when the * hash was created, it will be called for each item contained within. * Abadoning a hash without calling hash_destroy() will cause a memory leak. */ int hash_is_empty (hash_t h); /* * Returns non-zero if hash table [h] is empty; o/w, returns zero. */ int hash_count (hash_t h); /* * Returns the number of items in hash table [h]. */ void * hash_find (hash_t h, const void *key); /* * Searches for the item corresponding to [key] in hash table [h]. * Returns a ptr to the found item's data on success. * Returns NULL with errno=0 if no matching item is found. * Returns NULL with errno=EINVAL if [key] is not specified. */ void * hash_insert (hash_t h, const void *key, void *data); /* * Inserts [data] with the corresponding [key] into hash table [h]; * note that it is permissible for [key] to be set equal to [data]. * Returns a ptr to the inserted item's data on success. * Returns NULL with errno=EEXIST if [key] already exists in the hash. * Returns NULL with errno=EINVAL if [key] or [data] is not specified. * Returns lsd_nomem_error() with errno=ENOMEM if memory allocation fails. */ void * hash_remove (hash_t h, const void *key); /* * Removes the item corresponding to [key] from hash table [h]. * Returns a ptr to the removed item's data on success. * Returns NULL with errno=0 if no matching item is found. * Returns NULL with errno=EINVAL if [key] is not specified. */ int hash_delete_if (hash_t h, hash_arg_f argf, void *arg); /* * Conditionally deletes (and de-allocates) items from hash table [h]. * The [argf] function is invoked once for each item in the hash, with * [arg] being passed in as an argument. Items for which [argf] returns * greater-than-zero are deleted. * Returns the number of items deleted. * Returns -1 with errno=EINVAL if [argf] is not specified. */ int hash_for_each (hash_t h, hash_arg_f argf, void *arg); /* * Invokes the [argf] function once for each item in hash table [h], * with [arg] being passed in as an argument. * Returns the number of items for which [argf] returns greater-than-zero. * Returns -1 with errno=EINVAL if [argf] is not specified. */ unsigned int hash_key_string (const char *str); /* * A hash_key_f function that hashes the string [str]. */ #endif /* !LSD_HASH_H */ powerman-2.3.27/liblsd/hostlist.c000066400000000000000000002122251415616035500167350ustar00rootroot00000000000000/*****************************************************************************\ * $Id: hostlist.c 11882 2012-10-03 17:31:41Z grondo $ ***************************************************************************** * Copyright (C) 2002 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Mark Grondona * UCRL-CODE-2002-040. * * This file is part of SLURM, a resource management program. * For details, see . * * SLURM 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. * * SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" # if HAVE_STRING_H # include # endif # if HAVE_PTHREAD_H # include # endif #else /* !HAVE_CONFIG_H */ # include # include #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include "hostlist.h" /* * lsd_fatal_error : fatal error macro */ #ifdef WITH_LSD_FATAL_ERROR_FUNC # undef lsd_fatal_error extern void lsd_fatal_error(char *file, int line, char *mesg); #else /* !WITH_LSD_FATAL_ERROR_FUNC */ # ifndef lsd_fatal_error # define lsd_fatal_error(file, line, mesg) \ do { \ fprintf(stderr, "ERROR: [%s:%d] %s: %s\n", \ file, line, mesg, strerror(errno)); \ } while (0) # endif /* !lsd_fatal_error */ #endif /* !WITH_LSD_FATAL_ERROR_FUNC */ /* * lsd_nomem_error */ #ifdef WITH_LSD_NOMEM_ERROR_FUNC # undef lsd_nomem_error extern void * lsd_nomem_error(char *file, int line, char *mesg); #else /* !WITH_LSD_NOMEM_ERROR_FUNC */ # ifndef lsd_nomem_error # define lsd_nomem_error(file, line, mesg) (NULL) # endif /* !lsd_nomem_error */ #endif /* !WITH_LSD_NOMEM_ERROR_FUNC */ /* * OOM helper function * Automatically call lsd_nomem_error with appropriate args * and set errno to ENOMEM */ #define out_of_memory(mesg) \ do { \ errno = ENOMEM; \ return(lsd_nomem_error(__FILE__, __LINE__, mesg)); \ } while (0) /* * Some constants and tunables: */ /* number of elements to allocate when extending the hostlist array */ #define HOSTLIST_CHUNK 16 /* max host range: anything larger will be assumed to be an error */ #define MAX_RANGE 16384 /* 16K Hosts */ /* max host suffix value */ #define MAX_HOST_SUFFIX 1<<25 /* max number of ranges that will be processed between brackets */ #define MAX_RANGES 10240 /* 10K Ranges */ /* size of internal hostname buffer (+ some slop), hostnames will probably * be truncated if longer than MAXHOSTNAMELEN */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif /* max size of internal hostrange buffer */ #define MAXHOSTRANGELEN 1024 /* ----[ Internal Data Structures ]---- */ /* hostname type: A convenience structure used in parsing single hostnames */ struct hostname_components { char *hostname; /* cache of initialized hostname */ char *prefix; /* hostname prefix */ unsigned long num; /* numeric suffix */ /* string representation of numeric suffix * points into `hostname' */ char *suffix; }; typedef struct hostname_components *hostname_t; /* hostrange type: A single prefix with `hi' and `lo' numeric suffix values */ struct hostrange_components { char *prefix; /* alphanumeric prefix: */ /* beginning (lo) and end (hi) of suffix range */ unsigned long lo, hi; /* width of numeric output format * (pad with zeros up to this width) */ int width; /* If singlehost is 1, `lo' and `hi' are invalid */ unsigned singlehost:1; }; typedef struct hostrange_components *hostrange_t; /* The hostlist type: An array based list of hostrange_t's */ struct hostlist { #ifndef NDEBUG #define HOSTLIST_MAGIC 57005 int magic; #endif #if WITH_PTHREADS pthread_mutex_t mutex; #endif /* WITH_PTHREADS */ /* current number of elements available in array */ int size; /* current number of ranges stored in array */ int nranges; /* current number of hosts stored in hostlist */ int nhosts; /* pointer to hostrange array */ hostrange_t *hr; /* list of iterators */ struct hostlist_iterator *ilist; }; /* a hostset is a wrapper around a hostlist */ struct hostset { hostlist_t hl; }; struct hostlist_iterator { #ifndef NDEBUG int magic; #endif /* hostlist we are traversing */ hostlist_t hl; /* current index of iterator in hl->hr[] */ int idx; /* current hostrange object in list hl, i.e. hl->hr[idx] */ hostrange_t hr; /* current depth we've traversed into range hr */ int depth; /* next ptr for lists of iterators */ struct hostlist_iterator *next; }; /* ---- ---- */ /* ------[ static function prototypes ]------ */ static void _error(char *file, int line, char *mesg, ...); static char * _next_tok(char *, char **); static int _zero_padded(unsigned long, int); static int _width_equiv(unsigned long, int *, unsigned long, int *); static int host_prefix_end(const char *); static hostname_t hostname_create(const char *); static void hostname_destroy(hostname_t); static int hostname_suffix_is_valid(hostname_t); static int hostname_suffix_width(hostname_t); static hostrange_t hostrange_new(void); static hostrange_t hostrange_create_single(const char *); static hostrange_t hostrange_create(char *, unsigned long, unsigned long, int); static unsigned long hostrange_count(hostrange_t); static hostrange_t hostrange_copy(hostrange_t); static void hostrange_destroy(hostrange_t); static hostrange_t hostrange_delete_host(hostrange_t, unsigned long); static int hostrange_cmp(hostrange_t, hostrange_t); static int hostrange_prefix_cmp(hostrange_t, hostrange_t); static int hostrange_within_range(hostrange_t, hostrange_t); static int hostrange_width_combine(hostrange_t, hostrange_t); static int hostrange_empty(hostrange_t); static char * hostrange_pop(hostrange_t); static char * hostrange_shift(hostrange_t); static int hostrange_join(hostrange_t, hostrange_t); static hostrange_t hostrange_intersect(hostrange_t, hostrange_t); static int hostrange_hn_within(hostrange_t, hostname_t); static size_t hostrange_to_string(hostrange_t hr, size_t, char *, char *); static size_t hostrange_numstr(hostrange_t, size_t, char *); static hostlist_t hostlist_new(void); static hostlist_t _hostlist_create_bracketed(const char *, char *, char *); static int hostlist_resize(hostlist_t, size_t); static int hostlist_expand(hostlist_t); static int hostlist_push_range(hostlist_t, hostrange_t); static int hostlist_push_hr(hostlist_t, char *, unsigned long, unsigned long, int); static int hostlist_insert_range(hostlist_t, hostrange_t, int); static void hostlist_delete_range(hostlist_t, int n); static void hostlist_coalesce(hostlist_t hl); static void hostlist_collapse(hostlist_t hl); static hostlist_t _hostlist_create(const char *, char *, char *); static void hostlist_shift_iterators(hostlist_t, int, int, int); static int _attempt_range_join(hostlist_t, int); static int _is_bracket_needed(hostlist_t, int); static hostlist_iterator_t hostlist_iterator_new(void); static void _iterator_advance(hostlist_iterator_t); static void _iterator_advance_range(hostlist_iterator_t); static int hostset_find_host(hostset_t, const char *); /* ------[ macros ]------ */ #ifdef WITH_PTHREADS # define mutex_init(mutex) \ do { \ int e = pthread_mutex_init(mutex, NULL); \ if (e) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "hostlist mutex init:"); \ abort(); \ } \ } while (0) # define mutex_lock(mutex) \ do { \ int e = pthread_mutex_lock(mutex); \ if (e) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "hostlist mutex lock:"); \ abort(); \ } \ } while (0) # define mutex_unlock(mutex) \ do { \ int e = pthread_mutex_unlock(mutex); \ if (e) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "hostlist mutex unlock:"); \ abort(); \ } \ } while (0) # define mutex_destroy(mutex) \ do { \ int e = pthread_mutex_destroy(mutex); \ if (e) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "hostlist mutex destroy:"); \ abort(); \ } \ } while (0) #else /* !WITH_PTHREADS */ # define mutex_init(mutex) # define mutex_lock(mutex) # define mutex_unlock(mutex) # define mutex_destroy(mutex) #endif /* WITH_PTHREADS */ #define LOCK_HOSTLIST(_hl) \ do { \ assert(_hl != NULL); \ mutex_lock(&(_hl)->mutex); \ assert((_hl)->magic == HOSTLIST_MAGIC); \ } while (0) #define UNLOCK_HOSTLIST(_hl) \ do { \ mutex_unlock(&(_hl)->mutex); \ } while (0) #define seterrno_ret(_errno, _rc) \ do { \ errno = _errno; \ return _rc; \ } while (0) /* ------[ Function Definitions ]------ */ /* ----[ general utility functions ]---- */ /* * Varargs capable error reporting via lsd_fatal_error() */ static void _error(char *file, int line, char *msg, ...) { va_list ap; char buf[1024]; int len = 0; va_start(ap, msg); len = vsnprintf(buf, 1024, msg, ap); if ((len < 0) || (len > 1024)) buf[1023] = '\0'; lsd_fatal_error(file, line, buf); va_end(ap); return; } /* * Helper function for host list string parsing routines * Returns a pointer to the next token; additionally advance *str * to the next separator. * * next_tok was taken directly from pdsh courtesy of Jim Garlick. * (with modifications to support bracketed hostlists, i.e.: * xxx[xx,xx,xx] is a single token) * * _next_tok now handles multiple brackets within the same token, * e.g. node[01-30]-[1-2,6]. */ static char * _next_tok(char *sep, char **str) { char *tok; int level = 0; /* push str past any leading separators */ while (**str != '\0' && strchr(sep, **str) != '\0') (*str)++; if (**str == '\0') return NULL; /* assign token ptr */ tok = *str; while ( **str != '\0' && (level != 0 || strchr(sep, **str) == NULL) ) { if ( **str == '[' ) level++; else if ( **str == ']' ) level--; (*str)++; } /* nullify consecutive separators and push str beyond them */ while (**str != '\0' && strchr(sep, **str) != '\0') *(*str)++ = '\0'; return tok; } /* return the number of zeros needed to pad "num" to "width" */ static int _zero_padded(unsigned long num, int width) { int n = 1; while (num /= 10L) n++; return width > n ? width - n : 0; } /* test whether two format `width' parameters are "equivalent" * The width arguments "wn" and "wm" for integers "n" and "m" * are equivalent if: * * o wn == wm OR * * o applying the same format width (either wn or wm) to both of * 'n' and 'm' will not change the zero padding of *either* 'm' nor 'n'. * * If this function returns 1 (or true), the appropriate width value * (either 'wm' or 'wn') will have been adjusted such that both format * widths are equivalent. */ static int _width_equiv(unsigned long n, int *wn, unsigned long m, int *wm) { int npad, nmpad, mpad, mnpad; if (wn == wm) return 1; npad = _zero_padded(n, *wn); nmpad = _zero_padded(n, *wm); mpad = _zero_padded(m, *wm); mnpad = _zero_padded(m, *wn); if (npad != nmpad && mpad != mnpad) return 0; if (npad != nmpad) { if (mpad == mnpad) { *wm = *wn; return 1; } else return 0; } else { /* mpad != mnpad */ if (npad == nmpad) { *wn = *wm; return 1; } else return 0; } /* not reached */ } /* ----[ hostname_t functions ]---- */ /* * return the location of the last char in the hostname prefix */ static int host_prefix_end(const char *hostname) { int idx = strlen(hostname) - 1; while (idx >= 0 && isdigit((char) hostname[idx])) idx--; return idx; } static hostname_t hostname_create_with_suffix (const char *hostname, int idx) { hostname_t hn = NULL; char *p = '\0'; assert(hostname != NULL); if (!(hn = (hostname_t) malloc(sizeof(*hn)))) out_of_memory("hostname create"); if (!(hn->hostname = strdup(hostname))) { free(hn); out_of_memory("hostname create"); } hn->num = 0; hn->prefix = NULL; hn->suffix = NULL; if (idx == strlen(hostname) - 1) { if ((hn->prefix = strdup(hostname)) == NULL) { hostname_destroy(hn); out_of_memory("hostname prefix create"); } return hn; } hn->suffix = hn->hostname + idx + 1; hn->num = strtoul(hn->suffix, &p, 10); if ((*p == '\0') && (hn->num <= MAX_HOST_SUFFIX)) { if (!(hn->prefix = malloc((idx + 2) * sizeof(char)))) { hostname_destroy(hn); out_of_memory("hostname prefix create"); } memcpy(hn->prefix, hostname, idx + 1); hn->prefix[idx + 1] = '\0'; } else { if (!(hn->prefix = strdup(hostname))) { hostname_destroy(hn); out_of_memory("hostname prefix create"); } hn->suffix = NULL; } return hn; } /* * create a hostname_t object from a string hostname */ static hostname_t hostname_create(const char *hostname) { int idx = host_prefix_end (hostname); return hostname_create_with_suffix (hostname, idx); } /* free a hostname object */ static void hostname_destroy(hostname_t hn) { if (hn == NULL) return; hn->suffix = NULL; if (hn->hostname) free(hn->hostname); if (hn->prefix) free(hn->prefix); free(hn); } /* return true if the hostname has a valid numeric suffix */ static int hostname_suffix_is_valid(hostname_t hn) { return hn->suffix != NULL; } /* return the width (in characters) of the numeric part of the hostname */ static int hostname_suffix_width(hostname_t hn) { assert(hn->suffix != NULL); return (int) strlen(hn->suffix); } /* ----[ hostrange_t functions ]---- */ /* allocate a new hostrange object */ static hostrange_t hostrange_new(void) { hostrange_t new = (hostrange_t) malloc(sizeof(*new)); if (!new) out_of_memory("hostrange create"); return new; } /* Create a hostrange_t containing a single host without a valid suffix * hr->prefix will represent the entire hostname. */ static hostrange_t hostrange_create_single(const char *prefix) { hostrange_t new; assert(prefix != NULL); if ((new = hostrange_new()) == NULL) goto error1; if ((new->prefix = strdup(prefix)) == NULL) goto error2; new->singlehost = 1; new->lo = 0L; new->hi = 0L; new->width = 0; return new; error2: free(new); error1: out_of_memory("hostrange create single"); } /* Create a hostrange object with a prefix, hi, lo, and format width */ static hostrange_t hostrange_create(char *prefix, unsigned long lo, unsigned long hi, int width) { hostrange_t new; assert(prefix != NULL); if ((new = hostrange_new()) == NULL) goto error1; if ((new->prefix = strdup(prefix)) == NULL) goto error2; new->lo = lo; new->hi = hi; new->width = width; new->singlehost = 0; return new; error2: free(new); error1: out_of_memory("hostrange create"); } /* Return the number of hosts stored in the hostrange object */ static unsigned long hostrange_count(hostrange_t hr) { assert(hr != NULL); if (hr->singlehost) return 1; else return hr->hi - hr->lo + 1; } /* Copy a hostrange object */ static hostrange_t hostrange_copy(hostrange_t hr) { assert(hr != NULL); if (hr->singlehost) return hostrange_create_single(hr->prefix); else return hostrange_create(hr->prefix, hr->lo, hr->hi, hr->width); } /* free memory allocated by the hostrange object */ static void hostrange_destroy(hostrange_t hr) { if (hr == NULL) return; if (hr->prefix) free(hr->prefix); free(hr); } /* hostrange_delete_host() deletes a specific host from the range. * If the range is split into two, the greater range is returned, * and `hi' of the lesser range is adjusted accordingly. If the * highest or lowest host is deleted from a range, NULL is returned * and the hostrange hr is adjusted properly. */ static hostrange_t hostrange_delete_host(hostrange_t hr, unsigned long n) { hostrange_t new = NULL; assert(hr != NULL); assert(n >= hr->lo && n <= hr->hi); if (n == hr->lo) hr->lo++; else if (n == hr->hi) hr->hi--; else { if (!(new = hostrange_copy(hr))) out_of_memory("hostrange copy"); hr->hi = n - 1; new->lo = n + 1; } return new; } /* hostrange_cmp() is used to sort hostrange objects. It will * sort based on the following (in order): * o result of strcmp on prefixes * o if widths are compatible, then: * sort based on lowest suffix in range * else * sort based on width */ static int hostrange_cmp(hostrange_t h1, hostrange_t h2) { int retval; assert(h1 != NULL); assert(h2 != NULL); if ((retval = hostrange_prefix_cmp(h1, h2)) == 0) retval = hostrange_width_combine(h1, h2) ? h1->lo - h2->lo : h1->width - h2->width; return retval; } /* compare the prefixes of two hostrange objects. * returns: * < 0 if h1 prefix is less than h2 OR h1 == NULL. * * 0 if h1's prefix and h2's prefix match, * UNLESS, either h1 or h2 (NOT both) do not have a valid suffix. * * > 0 if h1's prefix is greater than h2's OR h2 == NULL. */ static int hostrange_prefix_cmp(hostrange_t h1, hostrange_t h2) { int retval; if (h1 == NULL) return 1; if (h2 == NULL) return -1; retval = strcmp(h1->prefix, h2->prefix); return retval == 0 ? h2->singlehost - h1->singlehost : retval; } /* returns true if h1 and h2 would be included in the same bracketed hostlist. * h1 and h2 will be in the same bracketed list iff: * * 1. h1 and h2 have same prefix * 2. neither h1 nor h2 are singlet hosts (i.e. invalid suffix) * * (XXX: Should incompatible widths be placed in the same bracketed list? * There's no good reason not to, except maybe aesthetics) */ static int hostrange_within_range(hostrange_t h1, hostrange_t h2) { if (hostrange_prefix_cmp(h1, h2) == 0) return h1->singlehost || h2->singlehost ? 0 : 1; else return 0; } /* compare two hostrange objects to determine if they are width * compatible, returns: * 1 if widths can safely be combined * 0 if widths cannot be safely combined */ static int hostrange_width_combine(hostrange_t h0, hostrange_t h1) { assert(h0 != NULL); assert(h1 != NULL); return _width_equiv(h0->lo, &h0->width, h1->lo, &h1->width); } /* Return true if hostrange hr contains no hosts, i.e. hi < lo */ static int hostrange_empty(hostrange_t hr) { assert(hr != NULL); return ((hr->hi < hr->lo) || (hr->hi == (unsigned long) -1)); } /* return the string representation of the last host in hostrange hr * and remove that host from the range (i.e. decrement hi if possible) * * Returns NULL if malloc fails OR there are no more hosts left */ static char *hostrange_pop(hostrange_t hr) { size_t size = 0; char *host = NULL; assert(hr != NULL); if (hr->singlehost) { hr->lo++; /* effectively set count == 0 */ host = strdup(hr->prefix); } else if (hostrange_count(hr) > 0) { size = strlen(hr->prefix) + hr->width + 16; if (!(host = (char *) malloc(size * sizeof(char)))) out_of_memory("hostrange pop"); snprintf(host, size, "%s%0*lu", hr->prefix, hr->width, hr->hi--); } return host; } /* Same as hostrange_pop(), but remove host from start of range */ static char *hostrange_shift(hostrange_t hr) { size_t size = 0; char *host = NULL; assert(hr != NULL); if (hr->singlehost) { hr->lo++; if (!(host = strdup(hr->prefix))) out_of_memory("hostrange shift"); } else if (hostrange_count(hr) > 0) { size = strlen(hr->prefix) + hr->width + 16; if (!(host = (char *) malloc(size * sizeof(char)))) out_of_memory("hostrange shift"); snprintf(host, size, "%s%0*lu", hr->prefix, hr->width, hr->lo++); } return host; } /* join two hostrange objects. * * returns: * * -1 if ranges do not overlap (including incompatible zero padding) * 0 if ranges join perfectly * >0 number of hosts that were duplicated in h1 and h2 * * h2 will be coalesced into h1 if rc >= 0 * * it is assumed that h1->lo <= h2->lo, i.e. hr1 <= hr2 * */ static int hostrange_join(hostrange_t h1, hostrange_t h2) { int duplicated = -1; assert(h1 != NULL); assert(h2 != NULL); assert(hostrange_cmp(h1, h2) <= 0); if (hostrange_prefix_cmp(h1, h2) == 0 && hostrange_width_combine(h1, h2)) { if (h1->singlehost && h2->singlehost) { /* matching singlets */ duplicated = 1; } else if (h1->hi == h2->lo - 1) { /* perfect join */ h1->hi = h2->hi; duplicated = 0; } else if (h1->hi >= h2->lo) { /* some duplication */ if (h1->hi < h2->hi) { duplicated = h1->hi - h2->lo + 1; h1->hi = h2->hi; } else duplicated = hostrange_count(h2); } } return duplicated; } /* hostrange intersect returns the intersection (common hosts) * of hostrange objects h1 and h2. If there is no intersection, * NULL is returned. * * It is assumed that h1 <= h2 (i.e. h1->lo <= h2->lo) */ static hostrange_t hostrange_intersect(hostrange_t h1, hostrange_t h2) { hostrange_t new = NULL; assert(h1 != NULL); assert(h2 != NULL); if (h1->singlehost || h2->singlehost) return NULL; assert(hostrange_cmp(h1, h2) <= 0); if ((hostrange_prefix_cmp(h1, h2) == 0) && (h1->hi > h2->lo) && (hostrange_width_combine(h1, h2))) { if (!(new = hostrange_copy(h1))) return NULL; new->lo = h2->lo; new->hi = h2->hi < h1->hi ? h2->hi : h1->hi; } return new; } /* return offset of hn if it is in the hostlist or * -1 if not. */ static int hostrange_hn_within(hostrange_t hr, hostname_t hn) { int len_hr; int len_hn; int width; if (hr->singlehost) { /* * If the current hostrange [hr] is a `singlehost' (no valid * numeric suffix (lo and hi)), then the hostrange [hr] * stores just one host with name == hr->prefix. * * Thus the full hostname in [hn] must match hr->prefix, in * which case we return true. Otherwise, there is no * possibility that [hn] matches [hr]. */ if (strcmp (hn->hostname, hr->prefix) == 0) return 0; else return -1; } /* * Now we know [hr] is not a "singlehost", so hostname * better have a valid numeric suffix, or there is no * way we can match */ if (!hostname_suffix_is_valid (hn)) return -1; len_hn = strlen (hn->prefix); /* * If hostrange and hostname prefixes don't match to at least * the length of the hostname object (which will have the min * possible prefix length), then there is no way the hostname * falls within the range [hr]. */ if (strncmp (hr->prefix, hn->prefix, len_hn) != 0) return -1; /* * Now we know hostrange and hostname prefixes match up to the * length of the hostname prefix. If the hostrange and hostname * prefix lengths do not match (specifically if the hostname prefix * length is less than the hostrange prefix length) and the * hostrange prefix contains trailing digits, then it might be * the case that the hostrange was created by forcing the prefix * to contain digits a la f00[1-2]. So we try adjusting the * hostname with the longer prefix and calling this function * again with the new hostname. (Yes, this is ugly, sorry) */ len_hr = strlen (hr->prefix); width = hostname_suffix_width (hn); if ((len_hn < len_hr) && (width > 1) && (isdigit (hr->prefix [len_hr - 1])) && (hr->prefix [len_hn] == hn->suffix[0]) ) { int rc; /* * Create new hostname object with its prefix offset by one */ hostname_t h = hostname_create_with_suffix (hn->hostname, len_hn); /* * Recursive call :-o */ rc = hostrange_hn_within (hr, h); hostname_destroy (h); return rc; } /* * Finally, check whether [hn], with a valid numeric suffix, * falls within the range of [hr] if [hn] and [hr] prefix are * identical. */ if ((len_hr == len_hn) && (strcmp (hn->prefix, hr->prefix) == 0) && (hn->num <= hr->hi) && (hn->num >= hr->lo)) { int width = hostname_suffix_width (hn); if (!_width_equiv(hr->lo, &hr->width, hn->num, &width)) return -1; return (hn->num - hr->lo); } return -1; } /* copy a string representation of the hostrange hr into buffer buf, * writing at most n chars including NUL termination */ static size_t hostrange_to_string(hostrange_t hr, size_t n, char *buf, char *separator) { unsigned long i; int truncated = 0; int len = 0; char sep = separator == NULL ? ',' : separator[0]; if (n == 0) return 0; if (hr->singlehost) return snprintf(buf, n, "%s", hr->prefix); for (i = hr->lo; i <= hr->hi; i++) { size_t m = (n - len) <= n ? n - len : 0; /* check for < 0 */ int ret = snprintf(buf + len, m, "%s%0*lu", hr->prefix, hr->width, i); if (ret < 0 || ret >= m) { len = n; truncated = 1; break; } len+=ret; buf[len++] = sep; } if (truncated) { buf[n-1] = '\0'; return -1; } else { /* back up over final separator */ buf[--len] = '\0'; return len; } } /* Place the string representation of the numeric part of hostrange into buf * writing at most n chars including NUL termination. */ static size_t hostrange_numstr(hostrange_t hr, size_t n, char *buf) { int len = 0; assert(buf != NULL); if (hr->singlehost || n == 0) return 0; len = snprintf(buf, n, "%0*lu", hr->width, hr->lo); if ((len >= 0) && (len < n) && (hr->lo < hr->hi)) { int len2 = snprintf(buf+len, n-len, "-%0*lu", hr->width, hr->hi); if (len2 < 0) len = -1; else len += len2; } return len; } /* ----[ hostlist functions ]---- */ /* Create a new hostlist object. * Returns an empty hostlist, or NULL if memory allocation fails. */ static hostlist_t hostlist_new(void) { int i; hostlist_t new = (hostlist_t) malloc(sizeof(*new)); if (!new) goto fail1; assert(new->magic = HOSTLIST_MAGIC); mutex_init(&new->mutex); new->hr = (hostrange_t *) malloc(HOSTLIST_CHUNK * sizeof(hostrange_t)); if (!new->hr) goto fail2; /* set entries in hostrange array to NULL */ for (i = 0; i < HOSTLIST_CHUNK; i++) new->hr[i] = NULL; new->size = HOSTLIST_CHUNK; new->nranges = 0; new->nhosts = 0; new->ilist = NULL; return new; fail2: free(new); fail1: out_of_memory("hostlist_create"); } /* Resize the internal array used to store the list of hostrange objects. * * returns 1 for a successful resize, * 0 if call to _realloc fails * * It is assumed that the caller has the hostlist hl locked */ static int hostlist_resize(hostlist_t hl, size_t newsize) { int i; size_t oldsize; assert(hl != NULL); assert(hl->magic == HOSTLIST_MAGIC); oldsize = hl->size; hl->size = newsize; hl->hr = realloc((void *) hl->hr, hl->size*sizeof(hostrange_t)); if (!(hl->hr)) return 0; for (i = oldsize; i < newsize; i++) hl->hr[i] = NULL; return 1; } /* Resize hostlist by one HOSTLIST_CHUNK * Assumes that hostlist hl is locked by caller */ static int hostlist_expand(hostlist_t hl) { if (!hostlist_resize(hl, hl->size + HOSTLIST_CHUNK)) return 0; else return 1; } /* Push a hostrange object onto hostlist hl * Returns the number of hosts successfully pushed onto hl * or -1 if there was an error allocating memory */ static int hostlist_push_range(hostlist_t hl, hostrange_t hr) { hostrange_t tail; int retval; assert(hr != NULL); LOCK_HOSTLIST(hl); tail = (hl->nranges > 0) ? hl->hr[hl->nranges-1] : hl->hr[0]; if (hl->size == hl->nranges && !hostlist_expand(hl)) goto error; if (hl->nranges > 0 && hostrange_prefix_cmp(tail, hr) == 0 && tail->hi == hr->lo - 1 && hostrange_width_combine(tail, hr)) { tail->hi = hr->hi; } else { if ((hl->hr[hl->nranges++] = hostrange_copy(hr)) == NULL) goto error; } retval = hl->nhosts += hostrange_count(hr); UNLOCK_HOSTLIST(hl); return retval; error: UNLOCK_HOSTLIST(hl); return -1; } /* Same as hostlist_push_range() above, but prefix, lo, hi, and width * are passed as args */ static int hostlist_push_hr(hostlist_t hl, char *prefix, unsigned long lo, unsigned long hi, int width) { hostrange_t hr = hostrange_create(prefix, lo, hi, width); int retval = hostlist_push_range(hl, hr); hostrange_destroy(hr); return retval; } /* Insert a range object hr into position n of the hostlist hl * Assumes that hl->mutex is already held by calling process */ static int hostlist_insert_range(hostlist_t hl, hostrange_t hr, int n) { int i; hostrange_t tmp; hostlist_iterator_t hli; assert(hl != NULL); assert(hl->magic == HOSTLIST_MAGIC); assert(hr != NULL); if (n > hl->nranges) return 0; if (hl->size == hl->nranges && !hostlist_expand(hl)) return 0; /* copy new hostrange into slot "n" in array */ tmp = hl->hr[n]; hl->hr[n] = hostrange_copy(hr); /* push remaining hostrange entries up */ for (i = n + 1; i < hl->nranges + 1; i++) { hostrange_t last = hl->hr[i]; hl->hr[i] = tmp; tmp = last; } hl->nranges++; /* adjust hostlist iterators if needed */ for (hli = hl->ilist; hli; hli = hli->next) { if (hli->idx >= n) hli->hr = hli->hl->hr[++hli->idx]; } return 1; } /* Delete the range at position n in the range array * Assumes the hostlist lock is already held. */ static void hostlist_delete_range(hostlist_t hl, int n) { int i; hostrange_t old; assert(hl != NULL); assert(hl->magic == HOSTLIST_MAGIC); assert(n < hl->nranges && n >= 0); old = hl->hr[n]; for (i = n; i < hl->nranges - 1; i++) hl->hr[i] = hl->hr[i + 1]; hl->nranges--; hl->hr[hl->nranges] = NULL; hostlist_shift_iterators(hl, n, 0, 1); /* XXX caller responsible for adjusting nhosts */ /* hl->nhosts -= hostrange_count(old) */ hostrange_destroy(old); } #if WANT_RECKLESS_HOSTRANGE_EXPANSION /* The reckless hostrange expansion function. * See comment in hostlist.h:hostlist_create() for more info on * the different choices for hostlist notation. */ hostlist_t _hostlist_create(const char *hostlist, char *sep, char *r_op) { char *str, *orig; char *tok, *cur; int high, low, fmt = 0; char prefix[256] = ""; int pos = 0; int error = 0; char range_op = r_op[0];/* XXX support > 1 char range ops in future? */ hostlist_t new = hostlist_new(); orig = str = strdup(hostlist); /* return an empty list if an empty string was passed in */ if (str == NULL || strlen(str) == 0) goto done; /* Use hostlist_create_bracketed if we see "[" */ if (strchr(str, '[') != NULL) return _hostlist_create_bracketed(hostlist, sep, r_op); while ((tok = _next_tok(sep, &str)) != NULL) { /* save the current string for error messages */ cur = tok; high = low = 0; /* find end of alpha part * do this by finding last occurence of range_op in str */ pos = strlen(tok) - 1; if (strstr(tok, r_op) != '\0') { while (pos >= 0 && (char) tok[pos] != range_op) pos--; } /* now back up past any digits */ while (pos >= 0 && isdigit((char) tok[--pos])) {;} /* Check for valid x-y range (x must be a digit) * Reset pos if the range is not valid */ if (!isdigit((char) tok[++pos])) pos = strlen(tok) - 1; /* create prefix string * if prefix will be zero length, but prefix already exists * use the previous prefix and fmt */ if ((pos > 0) || (prefix[0] == '\0')) { memcpy(prefix, tok, (size_t) pos * sizeof(char)); prefix[pos] = '\0'; /* push pointer past prefix */ tok += pos; /* count number of digits for ouput fmt */ for (fmt = 0; isdigit(tok[fmt]); ++fmt) {;} if (fmt == 0) error = 1; } else tok += pos; /* get lower bound */ low = strtoul(tok, (char **) &tok, 10); if (*tok == range_op) { /* now get range upper bound */ /* push pointer past range op */ ++tok; /* find length of alpha part */ for (pos = 0; tok[pos] && !isdigit(tok[pos]); ++pos) {;} /* alpha part must match prefix or error * this could mean we've got something like "rtr1-a2" * so just record an error */ if (pos > 0) { if (pos != strlen(prefix) || strncmp(prefix, tok, pos) != 0) error = 1; } if (*tok != '\0') tok += pos; /* make sure we have digits to the end */ for (pos = 0; tok[pos] && isdigit((char) tok[pos]); ++pos) {;} if (pos > 0) { /* we have digits to process */ high = strtoul(tok, (char **) &tok, 10); } else { /* bad boy, no digits */ error = 1; } if ((low > high) || (high - low > MAX_RANGE)) error = 1; } else { /* single value */ high = 0; /* special case, ugh. */ } /* error if: * 1. we are not at end of string * 2. upper bound equals lower bound */ if (*tok != '\0' || high == low) error = 1; if (error) { /* assume this is not a range on any error */ hostlist_push_host(new, cur); } else { if (high < low) high = low; hostlist_push_hr(new, prefix, low, high, fmt); } error = 0; } done: free(orig); return new; } #else /* !WANT_RECKLESS_HOSTRANGE_EXPANSION */ hostlist_t _hostlist_create(const char *hostlist, char *sep, char *r_op) { return _hostlist_create_bracketed(hostlist, sep, r_op); } #endif /* WANT_RECKLESS_HOSTRANGE_EXPANSION */ struct _range { unsigned long lo, hi; int width; }; /* Grab a single range from str * returns 1 if str contained a valid number or range, * 0 if conversion of str to a range failed. */ static int _parse_single_range(const char *str, struct _range *range) { char *p, *q; char *orig = strdup(str); if (!orig) seterrno_ret(ENOMEM, 0); if ((p = strchr(str, '-'))) { *p++ = '\0'; if (*p == '-') /* do NOT allow negative numbers */ goto error; } range->lo = strtoul(str, &q, 10); if (q == str) goto error; range->hi = (p && *p) ? strtoul(p, &q, 10) : range->lo; if (q == p || *q != '\0') goto error; if (range->lo > range->hi) goto error; if (range->hi - range->lo + 1 > MAX_RANGE ) { _error(__FILE__, __LINE__, "Too many hosts in range `%s'", orig); free(orig); seterrno_ret(ERANGE, 0); } free(orig); range->width = strlen(str); return 1; error: _error(__FILE__, __LINE__, "Invalid range: `%s'", orig); free(orig); seterrno_ret(EINVAL, 0); } /* * Convert 'str' containing comma separated digits and ranges into an array * of struct _range types (max 'len' elements). * * Return number of ranges created, or -1 on error. */ static int _parse_range_list(char *str, struct _range *ranges, int len) { char *p; int count = 0; while (str) { if (count == len) return -1; if ((p = strchr(str, ','))) *p++ = '\0'; if (!_parse_single_range(str, &ranges[count++])) return -1; str = p; } return count; } static void _push_range_list(hostlist_t hl, char *pfx, struct _range *rng, int n) { int i; for (i = 0; i < n; i++) { hostlist_push_hr(hl, pfx, rng->lo, rng->hi, rng->width); rng++; } } static void _push_range_list_with_suffix(hostlist_t hl, char *pfx, char *sfx, struct _range *rng, int n) { int i; unsigned long j; for (i = 0; i < n; i++) { for (j = rng->lo; j <= rng->hi; j++) { char host[4096]; hostrange_t hr; snprintf (host, 4096, "%s%0*lu%s", pfx, rng->width, j, sfx); hr = hostrange_create_single (host); hostlist_push_range (hl, hr); /* * hr is copied in hostlist_push_range. Need to free here. */ hostrange_destroy (hr); } rng++; } } /* * Create a hostlist from a string with brackets '[' ']' to aid * detection of ranges and compressed lists */ static hostlist_t _hostlist_create_bracketed(const char *hostlist, char *sep, char *r_op) { hostlist_t new = hostlist_new(); struct _range ranges[MAX_RANGES]; int nr, err; char *p, *tok, *str, *orig; char cur_tok[1024]; if (hostlist == NULL) return new; if (!(orig = str = strdup(hostlist))) { hostlist_destroy(new); return NULL; } while ((tok = _next_tok(sep, &str)) != NULL) { strncpy(cur_tok, tok, 1024); if ((p = strchr(tok, '[')) != NULL) { char *q, *prefix = tok; *p++ = '\0'; if ((q = strchr(p, ']'))) { *q = '\0'; nr = _parse_range_list(p, ranges, MAX_RANGES); if (nr < 0) goto error; if (*(++q) != '\0') _push_range_list_with_suffix (new, prefix, q, ranges, nr); else _push_range_list(new, prefix, ranges, nr); } else hostlist_push_host(new, cur_tok); } else hostlist_push_host(new, cur_tok); } free(orig); return new; error: err = errno; hostlist_destroy(new); free(orig); seterrno_ret(err, NULL); } hostlist_t hostlist_create(const char *str) { return _hostlist_create(str, "\t, ", "-"); } hostlist_t hostlist_copy(const hostlist_t hl) { int i; hostlist_t new; if (hl == NULL) return NULL; LOCK_HOSTLIST(hl); if (!(new = hostlist_new())) goto done; new->nranges = hl->nranges; new->nhosts = hl->nhosts; if (new->nranges > new->size) hostlist_resize(new, new->nranges); for (i = 0; i < hl->nranges; i++) new->hr[i] = hostrange_copy(hl->hr[i]); done: UNLOCK_HOSTLIST(hl); return new; } void hostlist_destroy(hostlist_t hl) { int i; if (hl == NULL) return; LOCK_HOSTLIST(hl); while (hl->ilist) { mutex_unlock(&hl->mutex); hostlist_iterator_destroy(hl->ilist); mutex_lock(&hl->mutex); } for (i = 0; i < hl->nranges; i++) hostrange_destroy(hl->hr[i]); free(hl->hr); assert(hl->magic = 0x1); UNLOCK_HOSTLIST(hl); mutex_destroy(&hl->mutex); free(hl); } int hostlist_push(hostlist_t hl, const char *hosts) { hostlist_t new; int retval; if (hosts == NULL) return 0; new = hostlist_create(hosts); if (!new) return 0; mutex_lock(&new->mutex); retval = new->nhosts; mutex_unlock(&new->mutex); hostlist_push_list(hl, new); hostlist_destroy(new); return retval; } int hostlist_push_host(hostlist_t hl, const char *str) { hostrange_t hr; hostname_t hn; if (str == NULL) return 0; hn = hostname_create(str); if (hostname_suffix_is_valid(hn)) { hr = hostrange_create(hn->prefix, hn->num, hn->num, hostname_suffix_width(hn)); } else hr = hostrange_create_single(str); hostlist_push_range(hl, hr); hostrange_destroy(hr); hostname_destroy(hn); return 1; } int hostlist_push_list(hostlist_t h1, hostlist_t h2) { int i, n = 0; if (h2 == NULL) return 0; LOCK_HOSTLIST(h2); for (i = 0; i < h2->nranges; i++) n += hostlist_push_range(h1, h2->hr[i]); UNLOCK_HOSTLIST(h2); return n; } char *hostlist_pop(hostlist_t hl) { char *host = NULL; LOCK_HOSTLIST(hl); if (hl->nhosts > 0) { hostrange_t hr = hl->hr[hl->nranges - 1]; host = hostrange_pop(hr); hl->nhosts--; if (hostrange_empty(hr)) { hostrange_destroy(hl->hr[--hl->nranges]); hl->hr[hl->nranges] = NULL; } } UNLOCK_HOSTLIST(hl); return host; } /* find all iterators affected by a shift (or deletion) at * hl->hr[idx], depth, with the deletion of n ranges */ static void hostlist_shift_iterators(hostlist_t hl, int idx, int depth, int n) { hostlist_iterator_t i; for (i = hl->ilist; i; i = i->next) { if (n == 0) { if (i->idx == idx && i->depth >= depth) i->depth = i->depth > -1 ? i->depth - 1 : -1; } else { if (i->idx >= idx) { if ((i->idx -= n) >= 0) i->hr = i->hl->hr[i->idx]; else hostlist_iterator_reset(i); } } } } char *hostlist_shift(hostlist_t hl) { char *host = NULL; LOCK_HOSTLIST(hl); if (hl->nhosts > 0) { hostrange_t hr = hl->hr[0]; host = hostrange_shift(hr); hl->nhosts--; if (hostrange_empty(hr)) { hostlist_delete_range(hl, 0); /* hl->nranges--; */ } else hostlist_shift_iterators(hl, 0, 0, 0); } UNLOCK_HOSTLIST(hl); return host; } char *hostlist_pop_range(hostlist_t hl) { int i; char buf[MAXHOSTRANGELEN + 1]; hostlist_t hltmp; hostrange_t tail; LOCK_HOSTLIST(hl); if (hl->nranges < 1 || !(hltmp = hostlist_new())) { UNLOCK_HOSTLIST(hl); return NULL; } i = hl->nranges - 2; tail = hl->hr[hl->nranges - 1]; while (i >= 0 && hostrange_within_range(tail, hl->hr[i])) i--; for (i++; i < hl->nranges; i++) { hostlist_push_range(hltmp, hl->hr[i]); hostrange_destroy(hl->hr[i]); hl->hr[i] = NULL; } hl->nhosts -= hltmp->nhosts; hl->nranges -= hltmp->nranges; UNLOCK_HOSTLIST(hl); hostlist_ranged_string(hltmp, MAXHOSTRANGELEN, buf); hostlist_destroy(hltmp); return strdup(buf); } char *hostlist_shift_range(hostlist_t hl) { int i; char buf[1024]; hostlist_t hltmp = hostlist_new(); if (!hltmp) return NULL; LOCK_HOSTLIST(hl); if (hl->nranges == 0) { hostlist_destroy(hltmp); UNLOCK_HOSTLIST(hl); return NULL; } i = 0; do { hostlist_push_range(hltmp, hl->hr[i]); hostrange_destroy(hl->hr[i]); } while ( (++i < hl->nranges) && hostrange_within_range(hltmp->hr[0], hl->hr[i]) ); hostlist_shift_iterators(hl, i, 0, hltmp->nranges); /* shift rest of ranges back in hl */ for (; i < hl->nranges; i++) { hl->hr[i - hltmp->nranges] = hl->hr[i]; hl->hr[i] = NULL; } hl->nhosts -= hltmp->nhosts; hl->nranges -= hltmp->nranges; UNLOCK_HOSTLIST(hl); hostlist_ranged_string(hltmp, 1024, buf); hostlist_destroy(hltmp); return strdup(buf); } /* XXX: Note: efficiency improvements needed */ int hostlist_delete(hostlist_t hl, const char *hosts) { int n = 0; char *hostname = NULL; hostlist_t hltmp; if (!(hltmp = hostlist_create(hosts))) seterrno_ret(EINVAL, 0); while ((hostname = hostlist_pop(hltmp)) != NULL) { n += hostlist_delete_host(hl, hostname); free(hostname); } hostlist_destroy(hltmp); return n; } /* XXX watch out! poor implementation follows! (fix it at some point) */ int hostlist_delete_host(hostlist_t hl, const char *hostname) { int n = hostlist_find(hl, hostname); if (n >= 0) hostlist_delete_nth(hl, n); return n >= 0 ? 1 : 0; } static char * _hostrange_string(hostrange_t hr, int depth) { char buf[MAXHOSTNAMELEN + 16]; int len = snprintf(buf, MAXHOSTNAMELEN + 15, "%s", hr->prefix); if (!hr->singlehost) snprintf(buf+len, MAXHOSTNAMELEN+15 - len, "%0*lu", hr->width, hr->lo + depth); return strdup(buf); } char * hostlist_nth(hostlist_t hl, int n) { char *host = NULL; int i, count; LOCK_HOSTLIST(hl); count = 0; for (i = 0; i < hl->nranges; i++) { int num_in_range = hostrange_count(hl->hr[i]); if (n <= (num_in_range - 1 + count)) { host = _hostrange_string(hl->hr[i], n - count); break; } else count += num_in_range; } UNLOCK_HOSTLIST(hl); return host; } int hostlist_delete_nth(hostlist_t hl, int n) { int i, count; LOCK_HOSTLIST(hl); assert(n >= 0 && n <= hl->nhosts); count = 0; for (i = 0; i < hl->nranges; i++) { int num_in_range = hostrange_count(hl->hr[i]); hostrange_t hr = hl->hr[i]; if (n <= (num_in_range - 1 + count)) { unsigned long num = hr->lo + n - count; hostrange_t new; if (hr->singlehost) { /* this wasn't a range */ hostlist_delete_range(hl, i); } else if ((new = hostrange_delete_host(hr, num))) { hostlist_insert_range(hl, new, i + 1); hostrange_destroy(new); } else if (hostrange_empty(hr)) hostlist_delete_range(hl, i); goto done; } else count += num_in_range; } done: hl->nhosts--; UNLOCK_HOSTLIST(hl); return 1; } int hostlist_count(hostlist_t hl) { int retval; LOCK_HOSTLIST(hl); retval = hl->nhosts; UNLOCK_HOSTLIST(hl); return retval; } int hostlist_find(hostlist_t hl, const char *hostname) { int i, count, ret = -1; hostname_t hn; if (!hostname) return -1; hn = hostname_create(hostname); LOCK_HOSTLIST(hl); for (i = 0, count = 0; i < hl->nranges; i++) { int offset = hostrange_hn_within(hl->hr[i], hn); if (offset >= 0) { ret = count + offset; break; } else count += hostrange_count(hl->hr[i]); } UNLOCK_HOSTLIST(hl); hostname_destroy(hn); return ret; } /* hostrange compare with void * arguments to allow use with * libc qsort() */ int _cmp(const void *hr1, const void *hr2) { hostrange_t *h1 = (hostrange_t *) hr1; hostrange_t *h2 = (hostrange_t *) hr2; return hostrange_cmp((hostrange_t) * h1, (hostrange_t) * h2); } void hostlist_sort(hostlist_t hl) { hostlist_iterator_t i; LOCK_HOSTLIST(hl); if (hl->nranges <= 1) { UNLOCK_HOSTLIST(hl); return; } qsort(hl->hr, hl->nranges, sizeof(hostrange_t), &_cmp); /* reset all iterators */ for (i = hl->ilist; i; i = i->next) hostlist_iterator_reset(i); UNLOCK_HOSTLIST(hl); hostlist_coalesce(hl); } /* search through hostlist for ranges that can be collapsed * does =not= delete any hosts */ static void hostlist_collapse(hostlist_t hl) { int i; LOCK_HOSTLIST(hl); for (i = hl->nranges - 1; i > 0; i--) { hostrange_t hprev = hl->hr[i - 1]; hostrange_t hnext = hl->hr[i]; if (hostrange_prefix_cmp(hprev, hnext) == 0 && hprev->hi == hnext->lo - 1 && hostrange_width_combine(hprev, hnext)) { hprev->hi = hnext->hi; hostlist_delete_range(hl, i); } } UNLOCK_HOSTLIST(hl); } /* search through hostlist (hl) for intersecting ranges * split up duplicates and coalesce ranges where possible */ static void hostlist_coalesce(hostlist_t hl) { int i, j; hostrange_t new; LOCK_HOSTLIST(hl); for (i = hl->nranges - 1; i > 0; i--) { new = hostrange_intersect(hl->hr[i - 1], hl->hr[i]); if (new) { hostrange_t hprev = hl->hr[i - 1]; hostrange_t hnext = hl->hr[i]; j = i; if (new->hi < hprev->hi) hnext->hi = hprev->hi; hprev->hi = new->lo; hnext->lo = new->hi; if (hostrange_empty(hprev)) hostlist_delete_range(hl, i); while (new->lo <= new->hi) { hostrange_t hr = hostrange_create( new->prefix, new->lo, new->lo, new->width ); if (new->lo > hprev->hi) hostlist_insert_range(hl, hr, j++); if (new->lo < hnext->lo) hostlist_insert_range(hl, hr, j++); hostrange_destroy(hr); new->lo++; } i = hl->nranges; hostrange_destroy(new); } } UNLOCK_HOSTLIST(hl); hostlist_collapse(hl); } /* attempt to join ranges at loc and loc-1 in a hostlist */ /* delete duplicates, return the number of hosts deleted */ /* assumes that the hostlist hl has been locked by caller */ /* returns -1 if no range join occurred */ static int _attempt_range_join(hostlist_t hl, int loc) { int ndup; assert(hl != NULL); assert(hl->magic == HOSTLIST_MAGIC); assert(loc > 0); assert(loc < hl->nranges); ndup = hostrange_join(hl->hr[loc - 1], hl->hr[loc]); if (ndup >= 0) { hostlist_delete_range(hl, loc); hl->nhosts -= ndup; } return ndup; } void hostlist_uniq(hostlist_t hl) { int i = 1; hostlist_iterator_t hli; LOCK_HOSTLIST(hl); if (hl->nranges <= 1) { UNLOCK_HOSTLIST(hl); return; } qsort(hl->hr, hl->nranges, sizeof(hostrange_t), &_cmp); while (i < hl->nranges) { if (_attempt_range_join(hl, i) < 0) /* No range join occurred */ i++; } /* reset all iterators */ for (hli = hl->ilist; hli; hli = hli->next) hostlist_iterator_reset(hli); UNLOCK_HOSTLIST(hl); } ssize_t hostlist_deranged_string(hostlist_t hl, size_t n, char *buf) { int i; int len = 0; int truncated = 0; LOCK_HOSTLIST(hl); for (i = 0; i < hl->nranges; i++) { size_t m = (n - len) <= n ? n - len : 0; int ret = hostrange_to_string(hl->hr[i], m, buf + len, ","); if (ret < 0 || ret > m) { len = n; truncated = 1; break; } len+=ret; buf[len++] = ','; } UNLOCK_HOSTLIST(hl); buf[len > 0 ? --len : 0] = '\0'; if (len == n) truncated = 1; return truncated ? -1 : len; } /* return true if a bracket is needed for the range at i in hostlist hl */ static int _is_bracket_needed(hostlist_t hl, int i) { hostrange_t h1 = hl->hr[i]; hostrange_t h2 = i < hl->nranges - 1 ? hl->hr[i + 1] : NULL; return hostrange_count(h1) > 1 || hostrange_within_range(h1, h2); } /* write the next bracketed hostlist, i.e. prefix[n-m,k,...] * into buf, writing at most n chars including the terminating '\0' * * leaves start pointing to one past last range object in bracketed list, * and returns the number of bytes written into buf. * * Assumes hostlist is locked. */ static int _get_bracketed_list(hostlist_t hl, int *start, const size_t n, char *buf) { hostrange_t *hr = hl->hr; int i = *start; int m, len = 0; int bracket_needed = _is_bracket_needed(hl, i); len = snprintf(buf, n, "%s", hr[i]->prefix); if ((len < 0) || (len > n)) return n; /* truncated, buffer filled */ if (bracket_needed && len < n && len >= 0) buf[len++] = '['; do { m = (n - len) <= n ? n - len : 0; len += hostrange_numstr(hr[i], m, buf + len); if (len >= n) break; if (bracket_needed) /* Only need commas inside brackets */ buf[len++] = ','; } while (++i < hl->nranges && hostrange_within_range(hr[i], hr[i-1])); if (bracket_needed && len < n && len > 0) { /* Add trailing bracket (change trailing "," from above to "]" */ buf[len - 1] = ']'; /* NUL terminate for safety, but do not add terminator to len */ buf[len] = '\0'; } else if (len >= n) { if (n > 0) buf[n-1] = '\0'; } else { /* If len is > 0, NUL terminate (but do not add to len) */ buf[len > 0 ? len : 0] = '\0'; } *start = i; return len; } ssize_t hostlist_ranged_string(hostlist_t hl, size_t n, char *buf) { int i = 0; int len = 0; int truncated = 0; LOCK_HOSTLIST(hl); while (i < hl->nranges && len < n) { len += _get_bracketed_list(hl, &i, n - len, buf + len); if ((len > 0) && (len < n) && (i < hl->nranges)) buf[len++] = ','; } UNLOCK_HOSTLIST(hl); /* NUL terminate */ if (len >= n) { truncated = 1; if (n > 0) buf[n-1] = '\0'; } else buf[len > 0 ? len : 0] = '\0'; return truncated ? -1 : len; } /* ----[ hostlist iterator functions ]---- */ static hostlist_iterator_t hostlist_iterator_new(void) { hostlist_iterator_t i = (hostlist_iterator_t) malloc(sizeof(*i)); if (!i) return NULL; i->hl = NULL; i->hr = NULL; i->idx = 0; i->depth = -1; i->next = i; assert(i->magic = HOSTLIST_MAGIC); return i; } hostlist_iterator_t hostlist_iterator_create(hostlist_t hl) { hostlist_iterator_t i; if (!(i = hostlist_iterator_new())) out_of_memory("hostlist_iterator_create"); LOCK_HOSTLIST(hl); i->hl = hl; i->hr = hl->hr[0]; i->next = hl->ilist; hl->ilist = i; UNLOCK_HOSTLIST(hl); return i; } hostlist_iterator_t hostset_iterator_create(hostset_t set) { return hostlist_iterator_create(set->hl); } void hostlist_iterator_reset(hostlist_iterator_t i) { assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); i->idx = 0; i->hr = i->hl->hr[0]; i->depth = -1; return; } void hostlist_iterator_destroy(hostlist_iterator_t i) { hostlist_iterator_t *pi; if (i == NULL) return; assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); LOCK_HOSTLIST(i->hl); for (pi = &i->hl->ilist; *pi; pi = &(*pi)->next) { assert((*pi)->magic == HOSTLIST_MAGIC); if (*pi == i) { *pi = (*pi)->next; break; } } UNLOCK_HOSTLIST(i->hl); assert(i->magic = 0x1); free(i); } static void _iterator_advance(hostlist_iterator_t i) { assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); if (i->idx > i->hl->nranges - 1) return; if (++(i->depth) > (i->hr->hi - i->hr->lo)) { i->depth = 0; i->hr = i->hl->hr[++i->idx]; } } /* advance iterator to end of current range (meaning within "[" "]") * i.e. advance iterator past all range objects that could be represented * in on bracketed hostlist. */ static void _iterator_advance_range(hostlist_iterator_t i) { int nr, j; hostrange_t *hr; assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); nr = i->hl->nranges; hr = i->hl->hr; j = i->idx; if (++i->depth > 0) { while (++j < nr && hostrange_within_range(i->hr, hr[j])) {;} i->idx = j; i->hr = i->hl->hr[i->idx]; i->depth = 0; } } char *hostlist_next(hostlist_iterator_t i) { char *buf = NULL; char suffix[16]; int len = 0; assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); LOCK_HOSTLIST(i->hl); _iterator_advance(i); if (i->idx > i->hl->nranges - 1) { UNLOCK_HOSTLIST(i->hl); return NULL; } suffix[0] = '\0'; if (!i->hr->singlehost) snprintf (suffix, 15, "%0*lu", i->hr->width, i->hr->lo + i->depth); len = strlen (i->hr->prefix) + strlen (suffix) + 1; if (!(buf = malloc (len))) out_of_memory("hostlist_next"); buf[0] = '\0'; strcat (buf, i->hr->prefix); strcat (buf, suffix); UNLOCK_HOSTLIST(i->hl); return (buf); } char *hostlist_next_range(hostlist_iterator_t i) { char buf[MAXHOSTRANGELEN + 1]; int j; assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); LOCK_HOSTLIST(i->hl); _iterator_advance_range(i); if (i->idx > i->hl->nranges - 1) { UNLOCK_HOSTLIST(i->hl); return NULL; } j = i->idx; _get_bracketed_list(i->hl, &j, MAXHOSTRANGELEN, buf); UNLOCK_HOSTLIST(i->hl); return strdup(buf); } int hostlist_remove(hostlist_iterator_t i) { hostrange_t new; assert(i != NULL); assert(i->magic == HOSTLIST_MAGIC); LOCK_HOSTLIST(i->hl); new = hostrange_delete_host(i->hr, i->hr->lo + i->depth); if (new) { hostlist_insert_range(i->hl, new, i->idx + 1); hostrange_destroy(new); i->hr = i->hl->hr[++i->idx]; i->depth = -1; } else if (hostrange_empty(i->hr)) { hostlist_delete_range(i->hl, i->idx); } else i->depth--; i->hl->nhosts--; UNLOCK_HOSTLIST(i->hl); return 1; } /* ----[ hostset functions ]---- */ hostset_t hostset_create(const char *hostlist) { hostset_t new; if (!(new = (hostset_t) malloc(sizeof(*new)))) goto error1; if (!(new->hl = hostlist_create(hostlist))) goto error2; hostlist_uniq(new->hl); return new; error2: free(new); error1: return NULL; } hostset_t hostset_copy(const hostset_t set) { hostset_t new; if (!(new = (hostset_t) malloc(sizeof(*new)))) goto error1; if (!(new->hl = hostlist_copy(set->hl))) goto error2; return new; error2: free(new); error1: return NULL; } void hostset_destroy(hostset_t set) { if (set == NULL) return; hostlist_destroy(set->hl); free(set); } /* inserts a single range object into a hostset * Assumes that the set->hl lock is already held * Updates hl->nhosts */ static int hostset_insert_range(hostset_t set, hostrange_t hr) { int i = 0; int inserted = 0; int nhosts = 0; int ndups = 0; hostlist_t hl; hl = set->hl; if (hl->size == hl->nranges && !hostlist_expand(hl)) return 0; nhosts = hostrange_count(hr); for (i = 0; i < hl->nranges; i++) { if (hostrange_cmp(hr, hl->hr[i]) <= 0) { if ((ndups = hostrange_join(hr, hl->hr[i])) >= 0) hostlist_delete_range(hl, i); else if (ndups < 0) ndups = 0; hostlist_insert_range(hl, hr, i); /* now attempt to join hr[i] and hr[i-1] */ if (i > 0) { int m; if ((m = _attempt_range_join(hl, i)) > 0) ndups += m; } hl->nhosts += nhosts - ndups; inserted = 1; break; } } if (inserted == 0) { hl->hr[hl->nranges++] = hostrange_copy(hr); hl->nhosts += nhosts; if (hl->nranges > 1) { if ((ndups = _attempt_range_join(hl, hl->nranges - 1)) <= 0) ndups = 0; } } /* * Return the number of unique hosts inserted */ return nhosts - ndups; } int hostset_insert(hostset_t set, const char *hosts) { int i, n = 0; hostlist_t hl = hostlist_create(hosts); if (!hl) return 0; hostlist_uniq(hl); LOCK_HOSTLIST(set->hl); for (i = 0; i < hl->nranges; i++) n += hostset_insert_range(set, hl->hr[i]); UNLOCK_HOSTLIST(set->hl); hostlist_destroy(hl); return n; } /* linear search through N ranges for hostname "host" * */ static int hostset_find_host(hostset_t set, const char *host) { int i; int retval = 0; hostname_t hn; LOCK_HOSTLIST(set->hl); hn = hostname_create(host); for (i = 0; i < set->hl->nranges; i++) { if (hostrange_hn_within(set->hl->hr[i], hn) >= 0) { retval = 1; goto done; } } done: UNLOCK_HOSTLIST(set->hl); hostname_destroy(hn); return retval; } int hostset_within(hostset_t set, const char *hosts) { int nhosts, nfound; hostlist_t hl; char *hostname; assert(set->hl->magic == HOSTLIST_MAGIC); if (!(hl = hostlist_create(hosts))) return (0); nhosts = hostlist_count(hl); nfound = 0; while ((hostname = hostlist_pop(hl)) != NULL) { nfound += hostset_find_host(set, hostname); free(hostname); } hostlist_destroy(hl); return (nhosts == nfound); } int hostset_delete(hostset_t set, const char *hosts) { return hostlist_delete(set->hl, hosts); } int hostset_delete_host(hostset_t set, const char *hostname) { return hostlist_delete_host(set->hl, hostname); } char *hostset_shift(hostset_t set) { return hostlist_shift(set->hl); } char *hostset_pop(hostset_t set) { return hostlist_pop(set->hl); } char *hostset_shift_range(hostset_t set) { return hostlist_shift_range(set->hl); } char *hostset_pop_range(hostset_t set) { return hostlist_pop_range(set->hl); } int hostset_count(hostset_t set) { return hostlist_count(set->hl); } ssize_t hostset_ranged_string(hostset_t set, size_t n, char *buf) { return hostlist_ranged_string(set->hl, n, buf); } ssize_t hostset_deranged_string(hostset_t set, size_t n, char *buf) { return hostlist_deranged_string(set->hl, n, buf); } #if TEST_MAIN int hostlist_nranges(hostlist_t hl) { return hl->nranges; } int hostset_nranges(hostset_t set) { return set->hl->nranges; } /* test iterator functionality on the list of hosts represented * by list */ int iterator_test(char *list) { int j; char buf[1024]; hostlist_t hl = hostlist_create(list); hostset_t set = hostset_create(list); hostlist_iterator_t i = hostlist_iterator_create(hl); hostlist_iterator_t seti = hostset_iterator_create(set); hostlist_iterator_t i2 = hostlist_iterator_create(hl); char *host; hostlist_ranged_string(hl, 1024, buf); printf("iterator_test: hl = `%s' passed in `%s'\n", buf, list); host = hostlist_next(i); printf("first host in list hl = `%s'\n", host); free(host); /* forge ahead three hosts with i2 */ for (j = 0; j < 4; j++) { host = hostlist_next(i2); free(host); } host = hostlist_shift(hl); printf("result of shift(hl) = `%s'\n", host); free(host); host = hostlist_next(i); printf("next host in list hl = `%s'\n", host); free(host); host = hostlist_next(i2); printf("next host for i2 = `%s'\n", host); free(host); hostlist_iterator_destroy(i); hostlist_destroy(hl); hostset_destroy(set); return 1; } int main(int ac, char **av) { char buf[1024000]; int i; char *str; hostlist_t hl1, hl2, hl3; hostset_t set, set1; hostlist_iterator_t iter, iter2; if (!(hl1 = hostlist_create(ac > 1 ? av[1] : NULL))) perror("hostlist_create"); if (!(set = hostset_create(ac > 1 ? av[1] : NULL))) perror("hostlist_create"); hl3 = hostlist_create("f[0-5]"); hostlist_delete(hl3, "f[1-3]"); hostlist_ranged_string(hl3, 102400, buf); printf("after delete = `%s'\n", buf); hostlist_destroy(hl3); for (i = 2; i < ac; i++) { hostlist_push(hl1, av[i]); hostset_insert(set, av[i]); } hostlist_ranged_string(hl1, 102400, buf); printf("ranged = `%s'\n", buf); iterator_test(buf); hostlist_deranged_string(hl1, 10240, buf); printf("deranged = `%s'\n", buf); hostset_ranged_string(set, 1024, buf); printf("hostset = `%s'\n", buf); hostlist_sort(hl1); hostlist_ranged_string(hl1, 1024, buf); printf("sorted = `%s'\n", buf); hostlist_uniq(hl1); hostlist_ranged_string(hl1, 1024, buf); printf("uniqed = `%s'\n", buf); hl2 = hostlist_copy(hl1); printf("pop_range: "); while ((str = hostlist_pop_range(hl2))) { printf("`%s' ", str); free(str); } hostlist_destroy(hl2); printf("\n"); hl2 = hostlist_copy(hl1); printf("shift_range: "); while ((str = hostlist_shift_range(hl2))) { printf("`%s' ", str); free(str); } hostlist_destroy(hl2); printf("\n"); iter = hostset_iterator_create(set); iter2 = hostset_iterator_create(set); hostlist_iterator_destroy(iter2); printf("next: "); while ((str = hostlist_next(iter))) { printf("`%s' ", str); free(str); } printf("\n"); hostlist_iterator_reset(iter); printf("next_range: "); while ((str = hostlist_next_range(iter))) { printf("`%s' ", str); free(str); } printf("\n"); printf("nranges = %d\n", hostset_nranges(set)); hostset_ranged_string(set, 1024, buf); printf("set = %s\n", buf); hostset_destroy(set); hostlist_destroy(hl1); return 0; } #endif /* TEST_MAIN */ /* * vi: tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/liblsd/hostlist.h000066400000000000000000000273101415616035500167410ustar00rootroot00000000000000/*****************************************************************************\ * $Id: hostlist.h 7428 2008-05-23 16:08:31Z grondo $ ***************************************************************************** * Copyright (C) 2002 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Mark Grondona * UCRL-CODE-2002-040. * * This file is part of SLURM, a resource management program. * For details, see . * * SLURM 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. * * SLURM 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 SLURM; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifndef _HOSTLIST_H #define _HOSTLIST_H #include /* Notes: * * If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to * find and external lsd_fatal_error(file,line,mesg) function. By default, * lsd_fatal_error(file,line,mesg) is a macro definition that outputs an * error message to stderr. This macro may be redefined to invoke another * routine instead. e.g.: * * #define lsd_fatal_error(file,line,mesg) \ * error("%s:%s %s\n",file,line,mesg); * * If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to * find an external lsd_nomem_error(file,line,mesg) function. By default, * lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL. * This macro may be redefined to invoke another routine instead. * * If WITH_PTHREADS is defined, these routines will be thread-safe. * */ /* The hostlist opaque data type * * A hostlist is a list of hostnames optimized for a prefixXXXX style * naming convention, where XXXX is a decimal, numeric suffix. */ typedef struct hostlist * hostlist_t; /* A hostset is a special case of a hostlist. It: * * 1. never contains duplicates * 2. is always sorted * (Note: sort occurs first on alphanumeric prefix -- where prefix * matches, numeric suffixes will be sorted *by value*) */ typedef struct hostset * hostset_t; /* The hostlist iterator type (may be used with a hostset as well) * used for non-destructive access to hostlist members. * */ typedef struct hostlist_iterator * hostlist_iterator_t; /* ----[ hostlist_t functions: ]---- */ /* ----[ hostlist creation and destruction ]---- */ /* * hostlist_create(): * * Create a new hostlist from a string representation. * * The string representation (str) may contain one or more hostnames or * bracketed hostlists separated by either `,' or whitespace. A bracketed * hostlist is denoted by a common prefix followed by a list of numeric * ranges contained within brackets: e.g. "tux[0-5,12,20-25]" * * Note: if this module is compiled with WANT_RECKLESS_HOSTRANGE_EXPANSION * defined, a much more loose interpretation of host ranges is used. * Reckless hostrange expansion allows all of the following (in addition to * bracketed hostlists): * * o tux0-5,tux12,tux20-25 * o tux0-tux5,tux12,tux20-tux25 * o tux0-5,12,20-25 * * If str is NULL, and empty hostlist is created and returned. * * If the create fails, hostlist_create() returns NULL. * * The returned hostlist must be freed with hostlist_destroy() * */ hostlist_t hostlist_create(const char *hostlist); /* hostlist_copy(): * * Allocate a copy of a hostlist object. Returned hostlist must be freed * with hostlist_destroy. */ hostlist_t hostlist_copy(const hostlist_t hl); /* hostlist_destroy(): * * Destroy a hostlist object. Frees all memory allocated to the hostlist. */ void hostlist_destroy(hostlist_t hl); /* ----[ hostlist list operations ]---- */ /* hostlist_push(): * * push a string representation of hostnames onto a hostlist. * * The hosts argument may take the same form as in hostlist_create() * * Returns the number of hostnames inserted into the list, * or 0 on failure. */ int hostlist_push(hostlist_t hl, const char *hosts); /* hostlist_push_host(): * * Push a single host onto the hostlist hl. * This function is more efficient than hostlist_push() for a single * hostname, since the argument does not need to be checked for ranges. * * return value is 1 for success, 0 for failure. */ int hostlist_push_host(hostlist_t hl, const char *host); /* hostlist_push_list(): * * Push a hostlist (hl2) onto another list (hl1) * * Returns 1 for success, 0 for failure. * */ int hostlist_push_list(hostlist_t hl1, hostlist_t hl2); /* hostlist_pop(): * * Returns the string representation of the last host pushed onto the list * or NULL if hostlist is empty or there was an error allocating memory. * The host is removed from the hostlist. * * Note: Caller is responsible for freeing the returned memory. */ char * hostlist_pop(hostlist_t hl); char * hostlist_nth(hostlist_t hl, int n); /* hostlist_shift(): * * Returns the string representation of the first host in the hostlist * or NULL if the hostlist is empty or there was an error allocating memory. * The host is removed from the hostlist. * * Note: Caller is responsible for freeing the returned memory. */ char * hostlist_shift(hostlist_t hl); /* hostlist_pop_range(): * * Pop the last bracketed list of hosts of the hostlist hl. * Returns the string representation in bracketed list form. * All hosts associated with the returned list are removed * from hl. * * Caller is responsible for freeing returned memory */ char * hostlist_pop_range(hostlist_t hl); /* hostlist_shift_range(): * * Shift the first bracketed hostlist (improperly: range) off the * hostlist hl. Returns the string representation in bracketed list * form. All hosts associated with the list are removed from the * hostlist. * * Caller is responsible for freeing returned memory. */ char * hostlist_shift_range(hostlist_t hl); /* hostlist_find(): * * Searches hostlist hl for the first host matching hostname * and returns position in list if found. * * Returns -1 if host is not found. * */ int hostlist_find(hostlist_t hl, const char *hostname); /* hostlist_delete(): * * Deletes all hosts in the list represented by `hosts' * * Returns the number of hosts successfully deleted */ int hostlist_delete(hostlist_t hl, const char *hosts); /* hostlist_delete_host(): * * Deletes the first host that matches `hostname' from the hostlist hl. * Note: "hostname" argument cannot contain a range of hosts * (see hostlist_delete() for this functionality.) * * Returns 1 if successful, 0 if hostname is not found in list. */ int hostlist_delete_host(hostlist_t hl, const char *hostname); /* hostlist_delete_nth(): * * Deletes the host from position n in the hostlist. * * Returns 1 if successful 0 on error. * */ int hostlist_delete_nth(hostlist_t hl, int n); /* hostlist_count(): * * Return the number of hosts in hostlist hl. */ int hostlist_count(hostlist_t hl); /* hostlist_is_empty(): return true if hostlist is empty. */ #define hostlist_is_empty(__hl) ( hostlist_count(__hl) == 0 ) /* ----[ Other hostlist operations ]---- */ /* hostlist_sort(): * * Sort the hostlist hl. * */ void hostlist_sort(hostlist_t hl); /* hostlist_uniq(): * * Sort the hostlist hl and remove duplicate entries. * */ void hostlist_uniq(hostlist_t hl); /* ----[ hostlist print functions ]---- */ /* hostlist_ranged_string(): * * Write the string representation of the hostlist hl into buf, * writing at most n chars. Returns the number of bytes written, * or -1 if truncation occurred. * * The result will be NULL terminated. * * hostlist_ranged_string() will write a bracketed hostlist representation * where possible. */ ssize_t hostlist_ranged_string(hostlist_t hl, size_t n, char *buf); ssize_t hostset_ranged_string(hostset_t hs, size_t n, char *buf); /* hostlist_deranged_string(): * * Writes the string representation of the hostlist hl into buf, * writing at most n chars. Returns the number of bytes written, * or -1 if truncation occurred. * * hostlist_deranged_string() will not attempt to write a bracketed * hostlist representation. Every hostname will be explicitly written. */ ssize_t hostlist_deranged_string(hostlist_t hl, size_t n, char *buf); ssize_t hostset_deranged_string(hostset_t hs, size_t n, char *buf); /* ----[ hostlist utility functions ]---- */ /* hostlist_nranges(): * * Return the number of ranges currently held in hostlist hl. */ int hostlist_nranges(hostlist_t hl); /* ----[ hostlist iterator functions ]---- */ /* hostlist_iterator_create(): * * Creates and returns a hostlist iterator used for non destructive * access to a hostlist or hostset. Returns NULL on failure. */ hostlist_iterator_t hostlist_iterator_create(hostlist_t hl); /* hostset_iterator_create(): * * Same as hostlist_iterator_create(), but creates a hostlist_iterator * from a hostset. */ hostlist_iterator_t hostset_iterator_create(hostset_t set); /* hostlist_iterator_destroy(): * * Destroys a hostlist iterator. */ void hostlist_iterator_destroy(hostlist_iterator_t i); /* hostlist_iterator_reset(): * * Reset an iterator to the beginning of the list. */ void hostlist_iterator_reset(hostlist_iterator_t i); /* hostlist_next(): * * Returns a pointer to the next hostname on the hostlist * or NULL at the end of the list * * The caller is responsible for freeing the returned memory. */ char * hostlist_next(hostlist_iterator_t i); /* hostlist_next_range(): * * Returns the next bracketed hostlist or NULL if the iterator i is * at the end of the list. * * The caller is responsible for freeing the returned memory. * */ char * hostlist_next_range(hostlist_iterator_t i); /* hostlist_remove(): * Removes the last host returned by hostlist iterator i * * Returns 1 for success, 0 for failure. */ int hostlist_remove(hostlist_iterator_t i); /* ----[ hostset operations ]---- */ /* hostset_create(): * * Create a new hostset object from a string representation of a list of * hosts. See hostlist_create() for valid hostlist forms. */ hostset_t hostset_create(const char *hostlist); /* hostset_copy(): * * Copy a hostset object. Returned set must be freed with hostset_destroy(). */ hostset_t hostset_copy(hostset_t set); /* hostset_destroy(): */ void hostset_destroy(hostset_t set); /* hostset_insert(): * Add a host or list of hosts into hostset "set." * * Returns number of hosts successfully added to "set" * (insertion of a duplicate is not considered successful) */ int hostset_insert(hostset_t set, const char *hosts); /* hostset_delete(): * Delete a host or list of hosts from hostset "set." * Returns number of hosts deleted from set. */ int hostset_delete(hostset_t set, const char *hosts); /* hostset_within(): * Return 1 if all hosts specified by "hosts" are within the hostset "set" * Retrun 0 if every host in "hosts" is not in the hostset "set" */ int hostset_within(hostset_t set, const char *hosts); /* hostset_shift(): * hostset equivalent to hostlist_shift() */ char * hostset_shift(hostset_t set); /* hostset_shift_range(): * hostset eqivalent to hostlist_shift_range() */ char * hostset_shift_range(hostset_t set); /* hostset_count(): * Count the number of hosts currently in hostset */ int hostset_count(hostset_t set); #endif /* !_HOSTLIST_H */ powerman-2.3.27/liblsd/list.c000066400000000000000000000507021415616035500160370ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001-2002 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***************************************************************************** * Refer to "list.h" for documentation on public functions. *****************************************************************************/ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* HAVE_CONFIG_H */ #ifdef WITH_PTHREADS # include #endif /* WITH_PTHREADS */ #include #include #include #include #include "list.h" /********************* * lsd_fatal_error * *********************/ #ifdef WITH_LSD_FATAL_ERROR_FUNC # undef lsd_fatal_error extern void lsd_fatal_error(char *file, int line, char *mesg); #else /* !WITH_LSD_FATAL_ERROR_FUNC */ # ifndef lsd_fatal_error # include # include # include # define lsd_fatal_error(file, line, mesg) \ do { \ fprintf(stderr, "ERROR: [%s:%d] %s: %s\n", \ file, line, mesg, strerror(errno)); \ } while (0) # endif /* !lsd_fatal_error */ #endif /* !WITH_LSD_FATAL_ERROR_FUNC */ /********************* * lsd_nomem_error * *********************/ #ifdef WITH_LSD_NOMEM_ERROR_FUNC # undef lsd_nomem_error extern void * lsd_nomem_error(char *file, int line, char *mesg); #else /* !WITH_LSD_NOMEM_ERROR_FUNC */ # ifndef lsd_nomem_error # define lsd_nomem_error(file, line, mesg) (NULL) # endif /* !lsd_nomem_error */ #endif /* !WITH_LSD_NOMEM_ERROR_FUNC */ /*************** * Constants * ***************/ #define LIST_ALLOC 32 #define LIST_MAGIC 0xDEADBEEF /**************** * Data Types * ****************/ struct listNode { void *data; /* node's data */ struct listNode *next; /* next node in list */ }; struct listIterator { struct list *list; /* the list being iterated */ struct listNode *pos; /* the next node to be iterated */ struct listNode **prev; /* addr of 'next' ptr to prv It node */ struct listIterator *iNext; /* iterator chain for list_destroy() */ #ifndef NDEBUG unsigned int magic; /* sentinel for asserting validity */ #endif /* !NDEBUG */ }; struct list { struct listNode *head; /* head of the list */ struct listNode **tail; /* addr of last node's 'next' ptr */ struct listIterator *iNext; /* iterator chain for list_destroy() */ ListDelF fDel; /* function to delete node data */ int count; /* number of nodes in list */ #ifdef WITH_PTHREADS pthread_mutex_t mutex; /* mutex to protect access to list */ #endif /* WITH_PTHREADS */ #ifndef NDEBUG unsigned int magic; /* sentinel for asserting validity */ #endif /* !NDEBUG */ }; typedef struct listNode * ListNode; /**************** * Prototypes * ****************/ static void * list_node_create (List l, ListNode *pp, void *x); static void * list_node_destroy (List l, ListNode *pp); static List list_alloc (void); static void list_free (List l); static ListNode list_node_alloc (void); static void list_node_free (ListNode p); static ListIterator list_iterator_alloc (void); static void list_iterator_free (ListIterator i); static void * list_alloc_aux (int size, void *pfreelist); static void list_free_aux (void *x, void *pfreelist); /*************** * Variables * ***************/ static List list_free_lists = NULL; static ListNode list_free_nodes = NULL; static ListIterator list_free_iterators = NULL; #ifdef WITH_PTHREADS static pthread_mutex_t list_free_lock = PTHREAD_MUTEX_INITIALIZER; #endif /* WITH_PTHREADS */ /************ * Macros * ************/ #ifdef WITH_PTHREADS # define list_mutex_init(mutex) \ do { \ int e = pthread_mutex_init(mutex, NULL); \ if (e != 0) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "list mutex init"); \ abort(); \ } \ } while (0) # define list_mutex_lock(mutex) \ do { \ int e = pthread_mutex_lock(mutex); \ if (e != 0) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "list mutex lock"); \ abort(); \ } \ } while (0) # define list_mutex_unlock(mutex) \ do { \ int e = pthread_mutex_unlock(mutex); \ if (e != 0) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "list mutex unlock"); \ abort(); \ } \ } while (0) # define list_mutex_destroy(mutex) \ do { \ int e = pthread_mutex_destroy(mutex); \ if (e != 0) { \ errno = e; \ lsd_fatal_error(__FILE__, __LINE__, "list mutex destroy"); \ abort(); \ } \ } while (0) # ifndef NDEBUG static int list_mutex_is_locked (pthread_mutex_t *mutex); # endif /* !NDEBUG */ #else /* !WITH_PTHREADS */ # define list_mutex_init(mutex) # define list_mutex_lock(mutex) # define list_mutex_unlock(mutex) # define list_mutex_destroy(mutex) # define list_mutex_is_locked(mutex) (1) #endif /* !WITH_PTHREADS */ /*************** * Functions * ***************/ List list_create (ListDelF f) { List l; if (!(l = list_alloc())) return(lsd_nomem_error(__FILE__, __LINE__, "list create")); l->head = NULL; l->tail = &l->head; l->iNext = NULL; l->fDel = f; l->count = 0; list_mutex_init(&l->mutex); assert(l->magic = LIST_MAGIC); /* set magic via assert abuse */ return(l); } void list_destroy (List l) { ListIterator i, iTmp; ListNode p, pTmp; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); i = l->iNext; while (i) { assert(i->magic == LIST_MAGIC); iTmp = i->iNext; assert(i->magic = ~LIST_MAGIC); /* clear magic via assert abuse */ list_iterator_free(i); i = iTmp; } p = l->head; while (p) { pTmp = p->next; if (p->data && l->fDel) l->fDel(p->data); list_node_free(p); p = pTmp; } assert(l->magic = ~LIST_MAGIC); /* clear magic via assert abuse */ list_mutex_unlock(&l->mutex); list_mutex_destroy(&l->mutex); list_free(l); return; } int list_is_empty (List l) { int n; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); n = l->count; list_mutex_unlock(&l->mutex); return(n == 0); } int list_count (List l) { int n; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); n = l->count; list_mutex_unlock(&l->mutex); return(n); } void * list_append (List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, l->tail, x); list_mutex_unlock(&l->mutex); return(v); } void * list_prepend (List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, &l->head, x); list_mutex_unlock(&l->mutex); return(v); } void * list_find_first (List l, ListFindF f, void *key) { ListNode p; void *v = NULL; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); for (p=l->head; p; p=p->next) { if (f(p->data, key)) { v = p->data; break; } } list_mutex_unlock(&l->mutex); return(v); } int list_delete_all (List l, ListFindF f, void *key) { ListNode *pp; void *v; int n = 0; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); pp = &l->head; while (*pp) { if (f((*pp)->data, key)) { if ((v = list_node_destroy(l, pp))) { if (l->fDel) l->fDel(v); n++; } } else { pp = &(*pp)->next; } } list_mutex_unlock(&l->mutex); return(n); } int list_for_each (List l, ListForF f, void *arg) { ListNode p; int n = 0; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); for (p=l->head; p; p=p->next) { n++; if (f(p->data, arg) < 0) { n = -n; break; } } list_mutex_unlock(&l->mutex); return(n); } void list_sort (List l, ListCmpF f) { /* Note: Time complexity O(n^2). */ ListNode *pp, *ppPrev, *ppPos, pTmp; ListIterator i; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); if (l->count > 1) { ppPrev = &l->head; pp = &(*ppPrev)->next; while (*pp) { if (f((*pp)->data, (*ppPrev)->data) < 0) { ppPos = &l->head; while (f((*pp)->data, (*ppPos)->data) >= 0) ppPos = &(*ppPos)->next; pTmp = (*pp)->next; (*pp)->next = *ppPos; *ppPos = *pp; *pp = pTmp; if (ppPrev == ppPos) ppPrev = &(*ppPrev)->next; } else { ppPrev = pp; pp = &(*pp)->next; } } l->tail = pp; for (i=l->iNext; i; i=i->iNext) { assert(i->magic == LIST_MAGIC); i->pos = i->list->head; i->prev = &i->list->head; } } list_mutex_unlock(&l->mutex); return; } void * list_push (List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, &l->head, x); list_mutex_unlock(&l->mutex); return(v); } void * list_pop (List l) { void *v; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_destroy(l, &l->head); list_mutex_unlock(&l->mutex); return(v); } void * list_peek (List l) { void *v; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = (l->head) ? l->head->data : NULL; list_mutex_unlock(&l->mutex); return(v); } void * list_enqueue (List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, l->tail, x); list_mutex_unlock(&l->mutex); return(v); } void * list_dequeue (List l) { void *v; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_destroy(l, &l->head); list_mutex_unlock(&l->mutex); return(v); } ListIterator list_iterator_create (List l) { ListIterator i; assert(l != NULL); if (!(i = list_iterator_alloc())) return(lsd_nomem_error(__FILE__, __LINE__, "list iterator create")); i->list = l; list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); i->pos = l->head; i->prev = &l->head; i->iNext = l->iNext; l->iNext = i; assert(i->magic = LIST_MAGIC); /* set magic via assert abuse */ list_mutex_unlock(&l->mutex); return(i); } void list_iterator_reset (ListIterator i) { assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); i->pos = i->list->head; i->prev = &i->list->head; list_mutex_unlock(&i->list->mutex); return; } void list_iterator_destroy (ListIterator i) { ListIterator *pi; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); for (pi=&i->list->iNext; *pi; pi=&(*pi)->iNext) { assert((*pi)->magic == LIST_MAGIC); if (*pi == i) { *pi = (*pi)->iNext; break; } } list_mutex_unlock(&i->list->mutex); assert(i->magic = ~LIST_MAGIC); /* clear magic via assert abuse */ list_iterator_free(i); return; } void * list_next (ListIterator i) { ListNode p; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); if ((p = i->pos)) i->pos = p->next; if (*i->prev != p) i->prev = &(*i->prev)->next; list_mutex_unlock(&i->list->mutex); return(p ? p->data : NULL); } void * list_insert (ListIterator i, void *x) { void *v; assert(i != NULL); assert(x != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); v = list_node_create(i->list, i->prev, x); list_mutex_unlock(&i->list->mutex); return(v); } void * list_find (ListIterator i, ListFindF f, void *key) { void *v; assert(i != NULL); assert(f != NULL); assert(i->magic == LIST_MAGIC); while ((v=list_next(i)) && !f(v,key)) {;} return(v); } void * list_remove (ListIterator i) { void *v = NULL; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); if (*i->prev != i->pos) v = list_node_destroy(i->list, i->prev); list_mutex_unlock(&i->list->mutex); return(v); } int list_delete (ListIterator i) { void *v; assert(i != NULL); assert(i->magic == LIST_MAGIC); if ((v = list_remove(i))) { if (i->list->fDel) i->list->fDel(v); return(1); } return(0); } static void * list_node_create (List l, ListNode *pp, void *x) { /* Inserts data pointed to by [x] into list [l] after [pp], * the address of the previous node's "next" ptr. * Returns a ptr to data [x], or NULL if insertion fails. * This routine assumes the list is already locked upon entry. */ ListNode p; ListIterator i; assert(l != NULL); assert(l->magic == LIST_MAGIC); assert(list_mutex_is_locked(&l->mutex)); assert(pp != NULL); assert(x != NULL); if (!(p = list_node_alloc())) return(lsd_nomem_error(__FILE__, __LINE__, "list node create")); p->data = x; if (!(p->next = *pp)) l->tail = &p->next; *pp = p; l->count++; for (i=l->iNext; i; i=i->iNext) { assert(i->magic == LIST_MAGIC); if (i->prev == pp) i->prev = &p->next; else if (i->pos == p->next) i->pos = p; assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); } return(x); } static void * list_node_destroy (List l, ListNode *pp) { /* Removes the node pointed to by [*pp] from from list [l], * where [pp] is the address of the previous node's "next" ptr. * Returns the data ptr associated with list item being removed, * or NULL if [*pp] points to the NULL element. * This routine assumes the list is already locked upon entry. */ void *v; ListNode p; ListIterator i; assert(l != NULL); assert(l->magic == LIST_MAGIC); assert(list_mutex_is_locked(&l->mutex)); assert(pp != NULL); if (!(p = *pp)) return(NULL); v = p->data; if (!(*pp = p->next)) l->tail = pp; l->count--; for (i=l->iNext; i; i=i->iNext) { assert(i->magic == LIST_MAGIC); if (i->pos == p) i->pos = p->next, i->prev = pp; else if (i->prev == &p->next) i->prev = pp; assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); } list_node_free(p); return(v); } static List list_alloc (void) { return(list_alloc_aux(sizeof(struct list), &list_free_lists)); } static void list_free (List l) { list_free_aux(l, &list_free_lists); return; } static ListNode list_node_alloc (void) { return(list_alloc_aux(sizeof(struct listNode), &list_free_nodes)); } static void list_node_free (ListNode p) { list_free_aux(p, &list_free_nodes); return; } static ListIterator list_iterator_alloc (void) { return(list_alloc_aux(sizeof(struct listIterator), &list_free_iterators)); } static void list_iterator_free (ListIterator i) { list_free_aux(i, &list_free_iterators); return; } static void * list_alloc_aux (int size, void *pfreelist) { /* Allocates an object of [size] bytes from the freelist [*pfreelist]. * Memory is added to the freelist in chunks of size LIST_ALLOC. * Returns a ptr to the object, or NULL if the memory request fails. */ void **px; void **pfree = pfreelist; void **plast; assert(sizeof(char) == 1); assert(size >= sizeof(void *)); assert(pfreelist != NULL); assert(LIST_ALLOC > 0); list_mutex_lock(&list_free_lock); if (!*pfree) { if ((*pfree = malloc(LIST_ALLOC * size))) { px = *pfree; plast = (void **) ((char *) *pfree + ((LIST_ALLOC - 1) * size)); while (px < plast) *px = (char *) px + size, px = *px; *plast = NULL; } } if ((px = *pfree)) *pfree = *px; else errno = ENOMEM; list_mutex_unlock(&list_free_lock); return(px); } static void list_free_aux (void *x, void *pfreelist) { /* Frees the object [x], returning it to the freelist [*pfreelist]. */ void **px = x; void **pfree = pfreelist; assert(x != NULL); assert(pfreelist != NULL); list_mutex_lock(&list_free_lock); *px = *pfree; *pfree = px; list_mutex_unlock(&list_free_lock); return; } #ifndef NDEBUG #ifdef WITH_PTHREADS static int list_mutex_is_locked (pthread_mutex_t *mutex) { /* Returns true if the mutex is locked; o/w, returns false. */ int rc; assert(mutex != NULL); rc = pthread_mutex_trylock(mutex); return(rc == EBUSY ? 1 : 0); } #endif /* WITH_PTHREADS */ #endif /* !NDEBUG */ powerman-2.3.27/liblsd/list.h000066400000000000000000000214611415616035500160440ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001-2002 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Chris Dunlap . * * This file is from LSD-Tools, the LLNL Software Development Toolbox. * * LSD-Tools 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. * * LSD-Tools 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 LSD-Tools; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *****************************************************************************/ #ifndef LSD_LIST_H #define LSD_LIST_H /*********** * Notes * ***********/ /* * If NDEBUG is not defined, internal debug code will be enabled. This is * intended for development use only and production code should define NDEBUG. * * If WITH_LSD_FATAL_ERROR_FUNC is defined, the linker will expect to * find an external lsd_fatal_error(file,line,mesg) function. By default, * lsd_fatal_error(file,line,mesg) is a macro definition that outputs an * error message to stderr. This macro may be redefined to invoke another * routine instead. * * If WITH_LSD_NOMEM_ERROR_FUNC is defined, the linker will expect to * find an external lsd_nomem_error(file,line,mesg) function. By default, * lsd_nomem_error(file,line,mesg) is a macro definition that returns NULL. * This macro may be redefined to invoke another routine instead. * * If WITH_PTHREADS is defined, these routines will be thread-safe. */ /**************** * Data Types * ****************/ typedef struct list * List; /* * List opaque data type. */ typedef struct listIterator * ListIterator; /* * List Iterator opaque data type. */ typedef void (*ListDelF) (void *x); /* * Function prototype to deallocate data stored in a list. * This function is responsible for freeing all memory associated * with an item, including all subordinate items (if applicable). */ typedef int (*ListCmpF) (void *x, void *y); /* * Function prototype for comparing two items in a list. * Returns less-than-zero if (xy). */ typedef int (*ListFindF) (void *x, void *key); /* * Function prototype for matching items in a list. * Returns non-zero if (x==key); o/w returns zero. */ typedef int (*ListForF) (void *x, void *arg); /* * Function prototype for operating on each item in a list. * Returns less-than-zero on error. */ /******************************* * General-Purpose Functions * *******************************/ List list_create (ListDelF f); /* * Creates and returns a new empty list, or lsd_nomem_error() on failure. * The deletion function [f] is used to deallocate memory used by items * in the list; if this is NULL, memory associated with these items * will not be freed when the list is destroyed. * Note: Abandoning a list without calling list_destroy() will result * in a memory leak. */ void list_destroy (List l); /* * Destroys list [l], freeing memory used for list iterators and the * list itself; if a deletion function was specified when the list * was created, it will be called for each item in the list. */ int list_is_empty (List l); /* * Returns non-zero if list [l] is empty; o/w returns zero. */ int list_count (List l); /* * Returns the number of items in list [l]. */ /*************************** * List Access Functions * ***************************/ void * list_append (List l, void *x); /* * Inserts data [x] at the end of list [l]. * Returns the data's ptr, or lsd_nomem_error() if insertion failed. */ void * list_prepend (List l, void *x); /* * Inserts data [x] at the beginning of list [l]. * Returns the data's ptr, or lsd_nomem_error() if insertion failed. */ void * list_find_first (List l, ListFindF f, void *key); /* * Traverses list [l] using [f] to match each item with [key]. * Returns a ptr to the first item for which the function [f] * returns non-zero, or NULL if no such item is found. * Note: This function differs from list_find() in that it does not require * a list iterator; it should only be used when all list items are known * to be unique (according to the function [f]). */ int list_delete_all (List l, ListFindF f, void *key); /* * Traverses list [l] using [f] to match each item with [key]. * Removes all items from the list for which the function [f] returns * non-zero; if a deletion function was specified when the list was * created, it will be called to deallocate each item being removed. * Returns a count of the number of items removed from the list. */ int list_for_each (List l, ListForF f, void *arg); /* * For each item in list [l], invokes the function [f] with [arg]. * Returns a count of the number of items on which [f] was invoked. * If [f] returns <0 for a given item, the iteration is aborted and the * function returns the negative of that item's position in the list. */ void list_sort (List l, ListCmpF f); /* * Sorts list [l] into ascending order according to the function [f]. * Note: Sorting a list resets all iterators associated with the list. * Note: The sort algorithm is stable. */ /**************************** * Stack Access Functions * ****************************/ void * list_push (List l, void *x); /* * Pushes data [x] onto the top of stack [l]. * Returns the data's ptr, or lsd_nomem_error() if insertion failed. */ void * list_pop (List l); /* * Pops the data item at the top of the stack [l]. * Returns the data's ptr, or NULL if the stack is empty. */ void * list_peek (List l); /* * Peeks at the data item at the top of the stack (or head of the queue) [l]. * Returns the data's ptr, or NULL if the stack (or queue) is empty. * Note: The item is not removed from the list. */ /**************************** * Queue Access Functions * ****************************/ void * list_enqueue (List l, void *x); /* * Enqueues data [x] at the tail of queue [l]. * Returns the data's ptr, or lsd_nomem_error() if insertion failed. */ void * list_dequeue (List l); /* * Dequeues the data item at the head of the queue [l]. * Returns the data's ptr, or NULL if the queue is empty. */ /***************************** * List Iterator Functions * *****************************/ ListIterator list_iterator_create (List l); /* * Creates and returns a list iterator for non-destructively traversing * list [l], or lsd_nomem_error() on failure. */ void list_iterator_reset (ListIterator i); /* * Resets the list iterator [i] to start traversal at the beginning * of the list. */ void list_iterator_destroy (ListIterator i); /* * Destroys the list iterator [i]; list iterators not explicitly destroyed * in this manner will be destroyed when the list is deallocated via * list_destroy(). */ void * list_next (ListIterator i); /* * Returns a ptr to the next item's data, * or NULL once the end of the list is reached. * Example: i=list_iterator_create(i); while ((x=list_next(i))) {...} */ void * list_insert (ListIterator i, void *x); /* * Inserts data [x] immediately before the last item returned via list * iterator [i]; once the list iterator reaches the end of the list, * insertion is made at the list's end. * Returns the data's ptr, or lsd_nomem_error() if insertion failed. */ void * list_find (ListIterator i, ListFindF f, void *key); /* * Traverses the list from the point of the list iterator [i] * using [f] to match each item with [key]. * Returns a ptr to the next item for which the function [f] * returns non-zero, or NULL once the end of the list is reached. * Example: i=list_iterator_reset(i); while ((x=list_find(i,f,k))) {...} */ void * list_remove (ListIterator i); /* * Removes from the list the last item returned via list iterator [i] * and returns the data's ptr. * Note: The client is responsible for freeing the returned data. */ int list_delete (ListIterator i); /* * Removes from the list the last item returned via list iterator [i]; * if a deletion function was specified when the list was created, * it will be called to deallocate the item being removed. * Returns a count of the number of items removed from the list * (ie, '1' if the item was removed, and '0' otherwise). */ #endif /* !LSD_LIST_H */ powerman-2.3.27/libpowerman/000077500000000000000000000000001415616035500157625ustar00rootroot00000000000000powerman-2.3.27/libpowerman/Makefile.am000066400000000000000000000003461415616035500200210ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/libcommon lib_LTLIBRARIES = libpowerman.la libpowerman_la_SOURCES = \ libpowerman.c if WITH_PKG_CONFIG pkgconfig_DATA = libpowerman.pc endif include_HEADERS = libpowerman.h powerman-2.3.27/libpowerman/libpowerman.c000066400000000000000000000413511415616035500204510ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* * libpowerman.c - simple powerman client library */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "client_proto.h" #include "libpowerman.h" #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 64 #endif #ifndef MAXPORTNAMELEN #define MAXPORTNAMELEN 64 #endif #define PMH_MAGIC 0x44445555 struct pm_handle_struct { int pmh_magic; int pmh_fd; }; typedef void (*list_free_t) (void *x); struct list_struct { char * data; struct list_struct *next; list_free_t freefun; }; #define PMI_MAGIC 0x41a452b5 struct pm_node_iterator_struct { int pmi_magic; struct list_struct *pmi_nodes; struct list_struct *pmi_pos; }; static pm_err_t _list_add(struct list_struct **head, char *s, list_free_t freefun); static void _list_free(struct list_struct **head); static int _list_search(struct list_struct *head, char *s); static int _strncmpend(char *s1, char *s2, int len); static char * _strndup(char *s, int len); static void _parse_hostport(char *s, char *host, char *port); static pm_err_t _connect_to_server_tcp(pm_handle_t pmh, char *server, int family); static pm_err_t _parse_response(char *buf, int len, struct list_struct **respp); static pm_err_t _server_recv_response(pm_handle_t pmh, struct list_struct **respp); static pm_err_t _server_send_command(pm_handle_t pmh, char *cmd, char *arg); static pm_err_t _server_command(pm_handle_t pmh, char *cmd, char *arg, struct list_struct **respp); /* Add [s] to the list referenced by [head], registering [freefun] to * be called on [s] when the list is freed. */ static pm_err_t _list_add(struct list_struct **head, char *s, list_free_t freefun) { struct list_struct *new; if (!(new = malloc(sizeof(struct list_struct)))) return PM_ENOMEM; new->data = s; new->next = *head; new->freefun = freefun; *head = new; return PM_ESUCCESS; } /* Free the list referred to by [head]. */ static void _list_free(struct list_struct **head) { struct list_struct *lp, *tmp; for (lp = *head; lp != NULL; lp = tmp) { tmp = lp->next; if (lp->freefun) lp->freefun(lp->data); free(lp); } *head = NULL; } /* Scan the list referenced by [head] looking for an element containing * exactly the string [s], returning true if found. */ static int _list_search(struct list_struct *head, char *s) { struct list_struct *lp; for (lp = head; lp != NULL; lp = lp->next) if (strcmp(lp->data, s) == 0) return 1; return 0; } /* Test if [s2] is a terminating substring of [s1]. */ static int _strncmpend(char *s1, char *s2, int len) { return strncmp(s1 + len - strlen(s2), s2, strlen(s2)); } /* Duplicate string [s] of length [len]. * Result will be NULL terminated. [s] doesn't have to be. */ static char * _strndup(char *s, int len) { char *c; if ((c = (char *)malloc(len + 1))) { memcpy(c, s, len); c[len] = '\0'; } return c; } static void _parse_hostport(char *s, char *host, char *port) { char *p; if (s) snprintf(host, MAXHOSTNAMELEN, "%s", s); else snprintf(host, MAXHOSTNAMELEN, "%s", PM_DFLT_HOST); if ((p = strchr(host, ':'))) { *p++ = '\0'; snprintf(port, MAXPORTNAMELEN, "%s", p); } else snprintf(port, MAXPORTNAMELEN, "%s", PM_DFLT_PORT); } /* Establish connection to powermand [server]. * Connection state is returned in the handle. */ static pm_err_t _connect_to_server_tcp(pm_handle_t pmh, char *server, int family) { struct addrinfo hints, *res, *r; pm_err_t err = PM_ECONNECT; char host[MAXHOSTNAMELEN], port[MAXPORTNAMELEN]; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; _parse_hostport(server, host, port); if (getaddrinfo(host, port, &hints, &res) != 0 || res == NULL) return PM_ENOADDR; for (r = res; r != NULL; r = r->ai_next) { if ((pmh->pmh_fd = socket(r->ai_family, r->ai_socktype, 0)) < 0) continue; if (connect(pmh->pmh_fd, r->ai_addr, r->ai_addrlen) < 0) { close(pmh->pmh_fd); continue; } err = PM_ESUCCESS; break; } freeaddrinfo(res); return err; } /* Parse a server response stored in [buf] of length [len] into * an array of lines stored in [respp] which caller must free. */ static pm_err_t _parse_response(char *buf, int len, struct list_struct **respp) { int i, l = strlen(CP_EOL); char *p, *cpy; struct list_struct *resp = NULL; pm_err_t err = PM_ESUCCESS; p = buf; for (i = 0; i < len - l; i++) { if (strncmp(&buf[i], CP_EOL, l) != 0) continue; if ((cpy = _strndup(p, &buf[i] - p + l)) == NULL) { err = PM_ENOMEM; break; } if ((err = _list_add(&resp, cpy, (list_free_t)free)) != PM_ESUCCESS) break; p = &buf[i + l]; } if (err == PM_ESUCCESS && respp != NULL) *respp = resp; else _list_free(&resp); return err; } /* Scan response from server for return code. */ static pm_err_t _server_retcode(struct list_struct *resp) { int code; pm_err_t err = PM_ESERVERPARSE; /* N.B. there will only be one 1xx or 2xx code in a response */ while (resp != NULL) { if (sscanf(resp->data, "%d ", &code) == 1) { switch (code) { case 1: /* hello */ case 101: /* goodbye */ case 102: /* command completed successfully */ case 103: /* query complete */ case 104: /* telemetry on|off */ case 105: /* hostrange expansion on|off */ err = PM_ESUCCESS; break; case PM_EUNKNOWN: case PM_EPARSE: case PM_ETOOLONG: case PM_EINTERNAL: case PM_EHOSTLIST: case PM_EINPROGRESS: case PM_ENOSUCHNODES: case PM_ECOMMAND: case PM_EQUERY: case PM_EUNIMPL: err = code; break; default: /* 3xx informational (ignore) */ break; } } resp = resp->next; } return err; } /* Read response from server handle [pmh] and store it in * [resp], an array of lines. Caller must free [resp]. */ static pm_err_t _server_recv_response(pm_handle_t pmh, struct list_struct **respp) { int buflen = 0, count = 0, n; char *buf = NULL; pm_err_t err = PM_ESUCCESS; struct list_struct *resp; do { if (buflen - count == 0) { buflen += CP_LINEMAX; buf = buf ? realloc(buf, buflen) : malloc(buflen); if (buf == NULL) { err = PM_ENOMEM; break; } } n = read(pmh->pmh_fd, buf + count, buflen - count); if (n == 0) { err = PM_ESERVEREOF; break; } if (n < 0) { err = PM_ERRNOVALID; break; } count += n; } while (_strncmpend(buf, CP_PROMPT, count) != 0); if (err == PM_ESUCCESS) { err = _parse_response(buf, count, &resp); if (err == PM_ESUCCESS) { err = _server_retcode(resp); if (err == PM_ESUCCESS && respp != NULL) *respp = resp; else _list_free(&resp); } } if (buf != NULL) free(buf); return err; } /* Send command [cmd] with argument [arg] to server handle [pmh]. * [cmd] is treated as a printf format string with [arg] as the * first printf argument (can be NULL). */ static pm_err_t _server_send_command(pm_handle_t pmh, char *cmd, char *arg) { char buf[CP_LINEMAX]; int count, len, n; pm_err_t err = PM_ESUCCESS; snprintf(buf, sizeof(buf), cmd, arg); snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), CP_EOL); count = 0; len = strlen(buf); while (count < len) { n = write(pmh->pmh_fd, buf + count, len - count); if (n < 0) { err = PM_ERRNOVALID; break; } count += n; } return err; } /* Send command [cmd] with argument [arg] to server handle [pmh]. * If [respp] is non-NULL, return list of response lines which * the caller must free. */ static pm_err_t _server_command(pm_handle_t pmh, char *cmd, char *arg, struct list_struct **respp) { pm_err_t err; if ((err = _server_send_command(pmh, cmd, arg)) != PM_ESUCCESS) return err; if ((err = _server_recv_response(pmh, respp)) != PM_ESUCCESS) return err; return PM_ESUCCESS; } pm_err_t pm_connect(char *server, void *arg, pm_handle_t *pmhp, int flags) { pm_handle_t pmh = NULL; pm_err_t err; if (pmhp == NULL) return PM_EBADARG; if ((pmh = (pm_handle_t)malloc(sizeof(struct pm_handle_struct))) == NULL) return PM_ENOMEM; pmh->pmh_magic = PMH_MAGIC; if ((err = _connect_to_server_tcp(pmh, server, (flags & PM_CONN_INET6) ? PF_INET6 : PF_UNSPEC)) != PM_ESUCCESS) { (void)close(pmh->pmh_fd); free(pmh); return err; } if ((err = _server_recv_response(pmh, NULL)) != PM_ESUCCESS) { (void)close(pmh->pmh_fd); free(pmh); return err; } if ((err = _server_command(pmh, CP_EXPRANGE, NULL, NULL)) != PM_ESUCCESS) { (void)close(pmh->pmh_fd); free(pmh); return err; } if (err == PM_ESUCCESS) *pmhp = pmh; else free(pmh); return err; } static pm_err_t _node_iterator_create(pm_node_iterator_t *pmip) { pm_node_iterator_t pmi; if (!(pmi = malloc(sizeof(struct pm_node_iterator_struct)))) return PM_ENOMEM; pmi->pmi_magic = PMI_MAGIC; pmi->pmi_pos = pmi->pmi_nodes = NULL; *pmip = pmi; return PM_ESUCCESS; } void pm_node_iterator_destroy(pm_node_iterator_t pmi) { _list_free(&pmi->pmi_nodes); pmi->pmi_pos = NULL; pmi->pmi_magic = 0; free(pmi); } pm_err_t pm_node_iterator_create(pm_handle_t pmh, pm_node_iterator_t *pmip) { pm_node_iterator_t pmi; struct list_struct *lp, *resp; char *cpy, node[CP_LINEMAX]; pm_err_t err; if (pmh == NULL || pmh->pmh_magic != PMH_MAGIC) return PM_EBADHAND; if ((err = _node_iterator_create(&pmi)) != PM_ESUCCESS) return err; if ((err = _server_command(pmh, CP_NODES, NULL, &resp)) != PM_ESUCCESS) { pm_node_iterator_destroy(pmi); return err; } for (lp = resp; lp != NULL; lp = lp->next) { if (sscanf(lp->data, CP_INFO_XNODES, node) == 1) { if (!(cpy = strdup(node))) { err = PM_ENOMEM; break; } err = _list_add(&pmi->pmi_nodes, cpy, (list_free_t)free); if (err != PM_ESUCCESS) break; } } if (err == PM_ESUCCESS && pmip != NULL) { pm_node_iterator_reset(pmi); *pmip = pmi; } else pm_node_iterator_destroy(pmi); _list_free(&resp); return err; } char * pm_node_next(pm_node_iterator_t pmi) { struct list_struct *cur = pmi->pmi_pos; if (!cur) return NULL; pmi->pmi_pos = pmi->pmi_pos->next; return cur->data; } void pm_node_iterator_reset(pm_node_iterator_t pmi) { pmi->pmi_pos = pmi->pmi_nodes; } /* Disconnect from server handle [pmh] and free the handle. */ void pm_disconnect(pm_handle_t pmh) { if (pmh != NULL && pmh->pmh_magic == PMH_MAGIC) { (void)_server_command(pmh, CP_QUIT, NULL, NULL); /* PM_ESERVEREOF */ (void)close(pmh->pmh_fd); free(pmh); } } /* Query server [pmh] for the power status of [node], and store it * in [statep]. */ pm_err_t pm_node_status(pm_handle_t pmh, char *node, pm_node_state_t *statep) { char offstr[CP_LINEMAX], onstr[CP_LINEMAX]; pm_err_t err; struct list_struct *resp; pm_node_state_t state; if (pmh == NULL || pmh->pmh_magic != PMH_MAGIC) return PM_EBADHAND; if ((err = _server_command(pmh, CP_STATUS, node, &resp)) != PM_ESUCCESS) return err; snprintf(offstr, sizeof(offstr), CP_INFO_XSTATUS, node, "off"); snprintf(onstr, sizeof(onstr), CP_INFO_XSTATUS, node, "on"); if (_list_search(resp, offstr)) state = PM_OFF; else if (_list_search(resp, onstr)) state = PM_ON; else state = PM_UNKNOWN; _list_free(&resp); if (statep) *statep = state; return PM_ESUCCESS; } /* Tell server [pmh] to turn [node] on. */ pm_err_t pm_node_on(pm_handle_t pmh, char *node) { if (pmh == NULL || pmh->pmh_magic != PMH_MAGIC) return PM_EBADHAND; return _server_command(pmh, CP_ON, node, NULL); } /* Tell server [pmh] to turn [node] off. */ pm_err_t pm_node_off(pm_handle_t pmh, char *node) { if (pmh == NULL || pmh->pmh_magic != PMH_MAGIC) return PM_EBADHAND; return _server_command(pmh, CP_OFF, node, NULL); } /* Tell server [pmh] to cycle [node]. */ pm_err_t pm_node_cycle(pm_handle_t pmh, char *node) { if (pmh == NULL || pmh->pmh_magic != PMH_MAGIC) return PM_EBADHAND; return _server_command(pmh, CP_CYCLE, node, NULL); } /* Convert error code to human readable string. */ char * pm_strerror(pm_err_t err, char *str, int len) { switch (err) { case PM_ESUCCESS: strncpy(str, "success", len); break; case PM_ERRNOVALID: strncpy(str, strerror(errno), len); break; case PM_ENOADDR: strncpy(str, "failed to get address info for server", len); break; case PM_ECONNECT: strncpy(str, "connect failed", len); break; case PM_ENOMEM: strncpy(str, "out of memory", len); break; case PM_EBADHAND: strncpy(str, "bad server handle", len); break; case PM_EBADARG: strncpy(str, "bad argument", len); break; case PM_ESERVEREOF: strncpy(str, "received unexpected EOF from server", len); break; case PM_ESERVERPARSE: strncpy(str, "unexpected response from server", len); break; case PM_EUNKNOWN: strncpy(str, "server: unknown command", len); break; case PM_EPARSE: strncpy(str, "server: parse error", len); break; case PM_ETOOLONG: strncpy(str, "server: command too long", len); break; case PM_EINTERNAL: strncpy(str, "server: internal error", len); break; case PM_EHOSTLIST: strncpy(str, "server: hostlist error", len); break; case PM_EINPROGRESS: strncpy(str, "server: command in progress", len); break; case PM_ENOSUCHNODES: strncpy(str, "server: no such nodes", len); break; case PM_ECOMMAND: strncpy(str, "server: command completed with errors", len); break; case PM_EQUERY: strncpy(str, "server: query completed with errors", len); break; case PM_EUNIMPL: strncpy(str, "server: not implemented by device", len); break; } return str; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libpowerman/libpowerman.h000066400000000000000000000072101415616035500204520ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifndef LIBPOWERMAN_H #define LIBPOWERMAN_H #ifdef __cplusplus extern "C" { #endif typedef struct pm_handle_struct *pm_handle_t; typedef struct pm_node_iterator_struct *pm_node_iterator_t; typedef enum { PM_UNKNOWN = 0, PM_OFF = 1, PM_ON = 2, } pm_node_state_t; typedef enum { PM_ESUCCESS = 0, /* success */ PM_ERRNOVALID = 1, /* system call failed, see system errno */ PM_ENOADDR = 2, /* failed to get address info for server */ PM_ECONNECT = 3, /* connect failed */ PM_ENOMEM = 4, /* out of memory */ PM_EBADHAND = 5, /* bad server handle */ PM_EBADARG = 6, /* bad argument */ PM_ESERVEREOF = 7, /* received unexpected EOF from server */ PM_ESERVERPARSE = 8, /* unexpected response from server */ PM_EUNKNOWN = 201, /* server: unknown command (201) */ PM_EPARSE = 202, /* server: parse error (202) */ PM_ETOOLONG = 203, /* server: command too long (203) */ PM_EINTERNAL = 204, /* server: internal error (204) */ PM_EHOSTLIST = 205, /* server: hostlist error (205) */ PM_EINPROGRESS = 208, /* server: command in progress (208) */ PM_ENOSUCHNODES = 209, /* server: no such nodes (209) */ PM_ECOMMAND = 210, /* server: command completed with errors (210) */ PM_EQUERY = 211, /* server: query completed with errors (211) */ PM_EUNIMPL = 213, /* server: not implemented by device (213) */ } pm_err_t; /* flags for pm_connect() */ #define PM_CONN_INET6 1 /* connect using IPv6 only */ #define PM_CONN_COPROC 2 /* unimplemented */ pm_err_t pm_connect(char *server, void *arg, pm_handle_t *pmhp, int flags); void pm_disconnect(pm_handle_t pmh); pm_err_t pm_node_status(pm_handle_t pmh, char *node, pm_node_state_t *statep); pm_err_t pm_node_on(pm_handle_t pmh, char *node); pm_err_t pm_node_off(pm_handle_t pmh, char *node); pm_err_t pm_node_cycle(pm_handle_t pmh, char *node); pm_err_t pm_node_iterator_create(pm_handle_t pmh, pm_node_iterator_t *pmip); char * pm_node_next(pm_node_iterator_t pmi); void pm_node_iterator_reset(pm_node_iterator_t pmi); void pm_node_iterator_destroy(pm_node_iterator_t pmi); char * pm_strerror(pm_err_t err, char *str, int len); #define PM_DFLT_PORT "10101" #define PM_DFLT_HOST "localhost" #ifdef __cplusplus } #endif #endif /* PM_POWERMAN_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/libpowerman/libpowerman.pc.in000066400000000000000000000003671415616035500212400ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpowerman Description: Centralized Power Distribution Unit (PDU) management Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lpowerman Cflags: -I${includedir} powerman-2.3.27/man/000077500000000000000000000000001415616035500142165ustar00rootroot00000000000000powerman-2.3.27/man/Makefile.am000066400000000000000000000005341415616035500162540ustar00rootroot00000000000000man1_MANS = powerman.1 pm.1 man3_MANS = libpowerman.3 man5_MANS = powerman.conf.5 powerman.dev.5 man8_MANS = powermand.8 httppower.8 redfishpower.8 plmpower.8 vpcd.8 pm.1: powerman.1 cp powerman.1 $@ CLEANFILES = pm.1 EXTRA_DIST = \ powerman.1 \ libpowerman.3 \ powerman.conf.5 \ powerman.dev.5 \ powermand.8 \ httppower.8 \ plmpower.8 powerman-2.3.27/man/httppower.8.in000066400000000000000000000041521415616035500167520ustar00rootroot00000000000000.TH httppower 8 "1 December 2008" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME httppower \- communicate with HTTP based power distribution units .SH SYNOPSIS .B httppower .I "[--url URL] [--header string] [--cookies] [--verbose]" .LP .SH DESCRIPTION .B httppower is a helper program for .B powerman which enables it to communicate with HTTP based power distribution units. It is run interactively by the powerman daemon. .SH OPTIONS .TP .I "-u, --url URL" Set the base URL. .TP .I "-H, --header string" Set extra HEADER to use. .TP .I "-c, --cookies" Enable cookies in session. .TP .I "-v, --verbose" Increase output verbosity. .SH INTERACTIVE COMMANDS The following commands are accepted at the httppower> prompt: .TP .I "auth user:pass" Authenticate to the base URL with specified user and password, using ``basic'' HTTP authentication which sends the user and password over the network in plain text. .TP .I "seturl URL" Set the base URL. Overrides the command line option. .TP .I "setheader [string data]" Set extra HEADER to use. Do not specify data to clear. Overrides the command line option. .TP .I "cookies " Enable or disable use of cookies. Overrides the command line option. .TP .I "get [URL-suffix]" Send an HTTP GET to the base URL with the optional URL-suffix appended. .TP .I "post [URL-suffix] " Send an HTTP POST to the base URL with the optional URL-suffix appended, and string data as argument. Typically, the data is key=value pairs (multiple of which can be concatenated with the &-symbol), but there can be exceptions. .TP .I "put [URL-suffix] " Send an HTTP PUT to the base URL with the optional URL-suffix appended, and string data as argument. .SH "FILES" @X_SBINDIR@/httppower .br @X_SYSCONFDIR@/powerman/powerman.conf .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/libpowerman.3.in000066400000000000000000000126541415616035500172360ustar00rootroot00000000000000.TH libpowerman 3 "2 December 2008" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME libpowerman \- PowerMan Client API .SH SYNOPSIS .nf .B #include .sp .BI "pm_err_t pm_connect (char *" server ", void *" arg ", pm_handle_t *" hp , .BI " int " flags ); .sp .BI "void pm_disconnect (pm_handle_t " h ); .sp .BI "pm_err_t pm_node_on (pm_handle_t " h ", char *" node ); .sp .BI "pm_err_t pm_node_off (pm_handle_t " h ", char *" node ); .sp .BI "pm_err_t pm_node_cycle (pm_handle_t " h ", char *" node ); .sp .BI "pm_err_t pm_node_status (pm_handle_t " h ", char *" node , .BI " pm_node_state_t " sp ); .sp .BI "pm_err_t pm_node_iterator_create (pm_handle_t " h , .BI " pm_node_iterator_t *" ip ); .sp .BI "void pm_node_iterator_destroy (pm_node_iterator_t " i ); .sp .BI "char * pm_node_next (pm_node_iterator_t " i ); .sp .BI "void pm_node_iterator_reset (pm_node_iterator_t " i ); .sp .BI "char * pm_strerror (pm_err_t " err ", char * " str ", int " len ); .sp .B cc ... -lpowerman .fi .SH DESCRIPTION The \fBpm_connect\fR() function establishes a connection with \fIserver\fR, a string containing \fIhost[:port]\fR or NULL for defaults; and returns a handle in \fIhp\fR. The \fIarg\fR parameter is currently unused. The \fIflags\fR parameter should be zero or one or more logically-OR'ed flags: .TP .B PM_CONN_INET6 Establish connection to the powerman server using (only) IPv6 protocol. Without this flag, any available address family will be used. .PP The \fBpm_disconnect\fR() function tears down the server connection and frees storage associated with handle \fIh\fR. .PP The \fBpm_node_on\fR(), \fBpm_node_off\fR(), and \fBpm_node_cycle\fR() functions issue on, off, and cycle commands acting on \fInode\fR to the server on handle \fIh\fR. .PP The \fBpm_node_status\fR() function issues a status query acting on \fInode\fR to the server on handle \fIh\fR. The result is resturned in \fIsp\fR which will be one of the values: .TP .B PM_ON Node is powered on. .TP .B PM_OFF Node is powered off. .TP .B PM_UNKNOWN Node state is unknown. Some devices may return this even when the query is successful, for example X10 devices controlled by \fBplmpower\fR. .PP To use the above functions you must know the name of the node you wish to control. Calling \fBpm_node_iterator_create\fR() on handle \fIh\fR returns an iterator \fIip\fR which can be used to walk the list of valid node names. \fBpm_node_next\fR() returns the next node in the list, or NULL when the end of the list is reached. \fBpm_node_iterator_reset\fR() rewinds iterator \fIi\fR to the beginning of the list. Finally, \fBpm_node_iterator_destroy\fR() destroys an iterator and reclaims its storage. .SH RETURN VALUE Most functions have a return type of \fIpm_err_t\fR. \fBpm_strerror\fR() is available to convert an error code \fIerr\fR to a human-readable string using storage \fIstr\fR of length \fIlen\fR passed in by the caller. .SH ERRORS .TP .B PM_ESUCCESS Success. .TP .B PM_ERRNOVALID System call failed, see system errno. .TP .B PM_ENOADDR Failed to get address info for server. .TP .B PM_ECONNECT Connect failed. .TP .B PM_ENOMEM Out of memory. .TP .B PM_EBADHAND Bad server handle. .TP .B PM_EBADARG Bad argument. .TP .B PM_ESERVEREOF Received unexpected EOF from server. .TP .B PM_ESERVERPARSE Received unexpected response from server. .TP .B PM_EUNKNOWN Server responded with ``unknown command''. .TP .B PM_EPARSE Server responded with ``parse error''. .TP .B PM_ETOOLONG Server responded with ``command too long''. .TP .B PM_EINTERNAL Server responed with ``internal error''. .TP .B PM_EHOSTLIST Server responded with ``hostlist error''. .TP .B PM_EINPROGRESS Server responded with ``command in progress''. .TP .B PM_ENOSUCHNODES Server responded with ``no such nodes''. .TP .B PM_ECOMMAND Server responded with ``command completed with errors''. .TP .B PM_EQUERY Server responded with ``query completed with errors''. .TP .B PM_EUNIMPL Server responded with ``not implemented by device''. .SH EXAMPLE This example program queries the list of valid nodes and turns them all on. .PP .nf #include #include #include .sp int main(int argc, char *argv[]) { pm_err_t err; pm_node_state_t s; pm_handle_t h; pm_node_iterator_t i; char ebuf[64], *node; .sp if ((err = pm_connect (NULL, NULL, &h, 0)) != PM_ESUCCESS) { fprintf (stderr, "pm_connect: %s\\n", pm_strerror (err, ebuf, sizeof (ebuf))); exit(1); } .sp if ((err = pm_node_iterator_create (h, &i)) != PM_ESUCCESS) { fprintf (stderr, "pm_node_iterator_create: %s\\n", pm_strerror (err, ebuf, sizeof (ebuf))); exit(1); } while ((node = pm_node_next (i))) { if ((err = pm_node_on (h, node)) != PM_ESUCCESS) { fprintf (stderr, "pm_node_on: %s\\n", pm_strerror (err, ebuf, sizeof(ebuf))); exit (1); } } pm_node_iterator_destroy (i); .sp pm_disconnect (h); exit (0); } .fi .SH "FILES" @X_LIBDIR@/libpowerman.* .br @X_INCLUDEDIR@/libpowerman.h .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/plmpower.8.in000066400000000000000000000050261415616035500165640ustar00rootroot00000000000000.TH plmpower 8 "1 December 2008" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME plmpower \- control Insteon/X10 devices via SmartLabs PLM 2412S .SH SYNOPSIS .B plmpower .I "--device serial-port" .LP .SH DESCRIPTION .B plmpower is a helper program for .B powerman which enables communication with Insteon/X10 devices via SmartLabs Power Line Modem, model 2412S. It is run interactively by the powerman daemon. It can also be useful as a standalone tool for debugging X10/Insteon networks based on the above device. .SH NETWORK SETUP Note the addresses of your Insteon/X10 devices. Plug the PLM into an AC outlet, preferably on the same electrical phase as the devices under control. Devices are available to bridge phases if this is not possible. .LP Attach the PLM's serial port to your computer, and ensure that nothing else is using the serial port such as the system console or getty(8). Run .B plmpower and try the interactive commands below to see if the devices respond reliably. .LP Once everything is working, configure .B powermand to run .B plmpower as a coprocess as described in powerman.conf(5). .SH OPTIONS .TP .I "-d, --device serial-port" Specify the path to the special file connected to the PLM's serial port. .TP .I "-t, --timeout msec" Set the Insteon timeout to the specified number of milliseconds (default 1000). .TP .I "-x, --x10-attempts number" Set the number of times to run every X10 command (default 3). X10 does not provide an ACK/NAK mechanism like Insteon so we cannot be certain that any particular X10 command completed, therefore X10 commands are issued multiple times to increase confidence. .SH INTERACTIVE COMMANDS The following commands are accepted at the plmpower> prompt. Address arguments may be Insteon (e.g. 1A.2B.3C) or X10 (e.g. G12). .TP .I "help" Display help on the available commands. .TP .I "info" Get info about the PLM. .TP .I "reset" Reset the PLM (clears the all-link db). .TP .I "on addr" Turn on device. .TP .I "off addr" Turn off device. .TP .I "status addr" Query status of device (Insteon only). .TP .I "ping addr" Time round trip request/response to device (Insteon only). .SH "FILES" @X_SBINDIR@/plmpower .br @X_SYSCONFDIR@/powerman/powerman.conf .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/powerman.1.in000066400000000000000000000110171415616035500165350ustar00rootroot00000000000000.TH powerman 1 "1 December 2008" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME powerman \- power on/off nodes .SH SYNOPSIS .B pm .I "[-options] -action [targets] [-action [targets] ...]" .SH DESCRIPTION .B powerman provides power management in a data center or compute cluster environment. It performs operations such as power on, power off, and power cycle via remote power controller (RPC) devices. Target hostnames are mapped to plugs on RPC devices in .I powerman.conf(5). .SH OPTIONS .TP .I "-1, --on targets" Power ON targets. .TP .I "-0, --off targets" Power OFF targets. .TP .I "-c, --cycle targets" Power cycle targets. .TP .I "-r, --reset targets" Assert hardware reset for targets (if implemented by RPC). .TP .I "-f, --flash targets" Turn beacon ON for targets (if implemented by RPC). .TP .I "-u, --unflash targets" Turn beacon OFF for targets (if implemented by RPC). .TP .I "-l, --list" List available targets. If possible, output will be compressed into a host range (see TARGET SPECIFICATION below). .TP .I "-q, --query-all" Query plug status of all targets. Status is not cached; each time this option is used, powermand queries the appropriate RPC's. Targets connected to RPC's that could not be contacted (e.g. due to network failure) are reported as status "unknown". If possible, output will be compressed into host ranges. .TP .I "-Q, --query targets" Query plug status of specific targets. .TP .I "-n, --soft-all" Query soft power status of all targets (if implemented by RPC). In this context, a node in the OFF state could be ON at the plug but operating in standby power mode. .TP .I "-N, --soft targets" Query soft power status of specific targets (if implemented by RPC). .TP .I "-b, --beacon-all" Query beacon status of all targets (if implemented by RPC). .TP .I "-B, --beacon targets" Query beacon status of specific targets (if implemented by RPC). .TP .I "-t, --temp-all" Query node temperature of all targets (if implemented by RPC). Temperature information is not interpreted by powerman and is reported as received from the RPC on one line per target, prefixed by target name. .TP .I "-P, --temp targets" Query node temperature of specific targets (if implemented by RPC). .TP .I "-L, --license" Show powerman license information. .TP .I "-h, --server-host host[:port]" Connect to a powerman daemon on non-default host and optionally port. .TP .I "-V, --version" Display the powerman version number and exit. .TP .I "-D, --device" Displays RPC status information. If targets are specified, only RPC's matching the target list are displayed. .TP .I "-T, --telemetry" Causes RPC telemetry information to be displayed as commands are processed. Useful for debugging device scripts. .TP .I "-x, --exprange" Expand host ranges in query responses. .TP .I "-g, --genders" If configured with the genders(3) package, this option tells powerman that targets are genders attributes that map to node names rather than the node names themselves. .SH "TARGET SPECIFICATION" .B powerman target hostnames may be specified as comma separated or space separated hostnames or host ranges. Host ranges are of the general form: prefix[n-m,l-k,...], where n < m and l < k, etc., This form should not be confused with regular expression character classes (also denoted by ``[]''). For example, foo[19] does not represent foo1 or foo9, but rather represents a degenerate range: foo19. .LP This range syntax is meant only as a convenience on clusters with a prefixNN naming convention and specification of ranges should not be considered necessary -- the list foo1,foo9 could be specified as such, or by the range foo[1,9]. .LP Some examples of powerman targets follows: .LP Power on hosts bar,baz,foo01,foo02,...,foo05 powerman --on bar baz foo[01-05] .LP Power on hosts bar,foo7,foo9,foo10 powerman --on bar,foo[7,9-10] .LP Power on foo0,foo4,foo5 powerman --on foo[0,4-5] .LP As a reminder to the reader, some shells will interpret brackets ([ and ]) for pattern matching. Depending on your shell, it may be necessary to enclose ranged lists within quotes. For example, in tcsh, the last example above should be executed as: .nf powerman --on "foo[0,4-5]" .fi .SH "FILES" @X_BINDIR@/powerman .br @X_BINDIR@/pm .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/powerman.conf.5.in000066400000000000000000000050441415616035500174700ustar00rootroot00000000000000.TH powerman.conf 5 "13 January 2012" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME powerman.conf \- configuration file for PowerMan .SH DESCRIPTION The powerman.conf file typically includes one or more of the remote power controller (RPC) device files provided in the /etc/powerman directory; sets a few global options; instantiates RPC devices with unique names, hostnames, and ports; and maps node names to RPC's and plug numbers. .LP Network-attached RPC's are instantiated with device lines of the form: .IP device "name" "type" "host:port" .LP Serial-attached RPC's are instantiated with device lines of the form: .IP device "name" "type" "special file" "flags" .LP where special file is the full path to a tty device, and flags is a serial parameter specification in a form similar to that used by lilo, e.g. "9600,8n1". RPC's that are accessed via coprocesses are instantiated as follows: .IP device "name" "type" "process |&" .LP where process is the full path to a process whose standard output and input will be controlled by powerman, e.g. "/usr/bin/conman -Q -j rpc0 |&". .SH EXAMPLE The following example is a 16-node cluster that uses two 8-plug Baytech RPC-3 remote power controllers. .LP .nf include "/etc/powerman/baytech.dev" # include def for "baytech" RPC tcpwrappers yes # enable TCP wrappers # listen "0.0.0.0:10101" # uncomment to listen on all interfaces # plug_log_level "info" # uncomment to change syslog messages # for plug state changes to level # info (default level is debug) # Alias example - alias can be used in target specifications alias "pengra_service" "pengra[0-1]" alias "pengra_compute" "pengra[2-15]" # Power controller: device [] device "pow0" "baytech" "pow0:23" # instantiate pow0 device "pow1" "baytech" "pow1:23" # instantiate pow1 # Plugs: node [] node "pengra[0-7]" "pow0" "[1-8]" # map pengra0...pengra7 to pow0 plug 1-8 node "pengra[8-15]" "pow1" "[1-8]" # map pengra8...pengra15 to pow1 plug 1-8 .fi .SH "FILES" @X_SYSCONFDIR@/powerman/powerman.conf .br @X_SYSCONFDIR@/powerman/*.dev .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/powerman.dev.5.in000066400000000000000000000165671415616035500173350ustar00rootroot00000000000000.TH powerman.dev 5 "13 January 2012" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME powerman.dev \- PowerMan device specification files .SH DESCRIPTION PowerMan device specifications are rather wierd. For this reason, we suggest that you leave the writing of these scripts to the PowerMan authors. However, if you insist, here is how they work. .LP Note: the authors do not guarantee that the PowerMan specification language will not change, however we are open to taking on maintenance of scripts submitted by PowerMan users. We can't guarantee that we'll be able to test new releases against all devices but we'll do our best not to break anything. NOTE: the best way to help us in this endeavor is to provide a ``simulator'' for your power controller and associated tests in the \fItest\fR subdirectory of the powerman source code. See the examples in that directory. .LP By convention, device scripts are one device per file and are included as needed from a powerman.conf file, like this: .IP .nf include "/etc/powerman/icebox3.dev" .fi .LP A device script is surrounded by an outer block: .IP .nf specification "my_device_name" { # configuration settings # script blocks } .fi .LP The possible configuration settings are: .TP .I "timeout " (optional) device script timeout in seconds - applies to each script, the whole thing, not just a particular "expect". .TP .I "plug name { }" (optional) if plug names are static, they should be defined. Any reference to a plug name in the powerman.conf must match one of the defined plug names. .TP .I "pingperiod " (optional) if a ping script is defined, and pingperiod is nonzero, the ping script will be executed periodically, every seconds. .LP Script blocks have the form: .IP .nf script { # statements } .fi .LP Script blocks should all be grouped together with no config lines in between. Scripts are for performing particular operations such as power on, get power status, etc. The various script names are listed below. Those marked with [%s] are called with a plug name "argument", which can be included in a send statements by including a %s (printf style). Warning: all the send strings are processed with printf and you can cause powermand to segfault if you include any printf tokens other than the appropriate zero or one %s. .TP .I "login" Executed immediately on (re-)connect. If you need to login to the box, do it here. This is also a good place to descend through a first layer of menus. Caveat: % occurring in passwords must be escaped as %%. Caveat: occurs outside of client session so cannot be debugged with -T. A trick when debugging is to move this code into the status script temporarily so you can see what is going on. .TP .I "logout" Executed prior to disconnect. Get device in a state so login script will work (though hopefully disconnecting will do that too). .TP .I "status_all, status[%s]" Obtain plug state for all plugs or only the specified plug. When all plugs of a device are involved in a plug status query, the status_all script, if defined, will be called in preference to the status script; otherwise the status script is called for each plug. .TP .I "on_all, on_range[%s], on[%s]" Power on all plugs, a range of plugs, or the specified plug. .TP .I "off_all, off_range[%s], off[%s]" Power off all plugs, a range of plugs, or the specified plug. .TP .I "cycle_all, cycle_range[%s], cycle[%s]" Power cycle all plugs, a range of plugs, or the specified plug. The intent of this command was to map to the RPC's cycle command; however, device script are increasingly implementing this in terms of a power off/delay/power so the off time can be controlled by the script. .TP .I "status_soft_all, status_soft[%s]" Obtain soft power state for all plugs or only the specified plug. Soft Power refers to the "standby state" of the node. On means the node is powered up. Off means either the node is powered off at the plug or is powered on at the plug and in standby mode. This is really only useful on devices that include both a plug relay and a probe into the node attached to a non-standby power source. .TP .I "status_temp_all, status_temp[%s]" Obtain temperature reading for all plugs or only the specified plug. Temperature is obtained by sampling a thermocouple in the node. Results are reported as a text string - not interpreted by Powerman beyond any regex chopping done by the script. .TP .I "status_beacon_all, status_beacon[%s]" Obtain beacon state for all plugs or only the specified plug. Some RPC's include a way to flash a light on a node. .TP .I "beacon_on[%s]" Flash beacon on the specified plug. .TP .I "beacon_off[%s]" Clear beacon on the specified plug. .TP .I "reset_all, reset_range[%s], reset[%s]" Reset all plugs, a range of plugs, or only the specified plug. Reset refers to signaling a motherboard reset butten header, not a plug cycle. .LP Within a script, the following statements can be used: .TP .I "send " Send to the device. .TP .I "delay " Pause script for seconds. .TP .I "expect " is compiled as a regular expression with regcomp(3). The regular expression is matched against device input. The script blocks until the regex is matched or the device timeout occurs (in which case the script is aborted). Upon matching, any parenthesized expressiones are assigned to variables: $1 for the first match, $2 for the second match, and so on. Warning: some implementations of regex(3) silently fail if the regular expression exceeds available static storage. .TP .I "setplugstate [|] [off=] [on=]" Set the plug state. The first argument, if present, is the literal plug name or a from the previous expect which contains the plug name. If omitted, the plug name is presumed to be the script argument. The off and on strings are compiled regexes, which if matched by the second argument, result in the plug state being set to off or on. Yes we are applying regexes to regmatches! If no off or on strings are provided, state will be unknown. .TP .I "ifoff, ifon" Script statements enclosed in an ifon/ifoff block are conditional executed based on the state of the plug passed in as an argument. Ifon/ifoff blocks can only be used in single plug scripts that take an argument. .TP .I "foreachplug" Script statements enclosed in a foreachplug block are executed iteratively with a %s argument defined for each target plug. Foreachplug blocks can only be used in all plug scripts that take no argument. .LP Script terminals are defined as follows: .TP .I "" decimal number - exponent forms not supported .TP .I "" Text surrounded by double quotes. May contain C style backslash-escaped characters, including three digit octal values, and most common backslash-escaped single character values. .TP .I "" Multiple values separated by white space. .TP .I "" Name of script (see above). .TP .I "" Results of a parenthesized regular expression match are assigned to $1, $2, ... $N. .SH "FILES" @X_SYSCONFDIR@/powerman/*.dev .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/powermand.8.in000066400000000000000000000022241415616035500167100ustar00rootroot00000000000000.TH powermand 8 "13 January 2012" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME powermand \- power control and monitoring daemon .SH SYNOPSIS .B powermand .I "[-options]" .LP .SH DESCRIPTION .B powermand provides power management in a data center or compute cluster environment. .SH OPTIONS .TP .I "-c, --conf filename" Override the default location of the powerman configuration file .I /etc/powerman/powerman.conf. .TP .I "-f, --foreground" Do not daemonize, and send debugging/error messages to stderr instead of syslog. .TP .I "-d, --debug mask" Set mask for debugging output. .TP .I "-h, --help" Provide a synopsis of the command options. .TP .I "-V, --version" Display the powerman version number and exit. .B PowerMan and exit. .SH "FILES" @X_SBINDIR@/powermand .br @X_SYSCONFDIR@/powerman/powerman.conf .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/redfishpower.8.in000066400000000000000000000064551415616035500174270ustar00rootroot00000000000000.TH redfishpower 8 "1 October 2021" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME redfishpower \- communicate with redfish service processors in parallel .SH SYNOPSIS .B redfishpower .I "<--hostname hostname(s) | --hostsfile file> [OPTIONS]" .LP .SH DESCRIPTION .B redfishpower is a helper program for .B powerman which enables it to communicate with redfish service processors in parallel. It is run interactively by the powerman daemon. .SH OPTIONS .TP .I "-h, --hostname hostname(s)" Set legal hostnames that redfishpower can communicate with. Host ranges are acceptable. Note that the maximum number of hosts that can be set simultaneously is limited by the file descriptor limit of the .B select(2) system call. .TP .I "-f, --hostsfile file" Alternate option to .I --hostname, specify a file with all hosts. File shall have one host or hostrange listed per line. .TP .I "-H, --header string" Set extra HEADER to use. .TP .I "-S, --statpath string" Set Redfish path for obtaining power status. Typically is redfish/v1/Systems/1. .TP .I "-O, --onpath string" Set Redfish path for performing power on. Typically is redfish/v1/Systems/1/Actions/ComputerSystem.Reset. .TP .I "-F, --offpath string" Set Redfish path for performing power off. Typically is redfish/v1/Systems/1/Actions/ComputerSystem.Reset. .TP .I "-C, --cyclepath string" Set Redfish path for performing power cycle. Typically is redfish/v1/Systems/1/Actions/ComputerSystem.Reset. .TP .I "-P, --onpostdata string" Set Redfish postdata for performing power on. Typically is {"ResetType":"On"} .TP .I "-G, --offpostdata string" Set Redfish postdata for performing power off. Typically is {"ResetType":"ForceOff"} .TP .I "-D, --cyclepostdata string" Set Redfish postdata for performing power cycle. Typically is {"ResetType":"ForceRestart"} .TP .I "-v, --verbose" Increase output verbosity. .SH INTERACTIVE COMMANDS The following commands are accepted at the redfishpower> prompt: .TP .I "auth user:pass" Authenticate to the base URL with specified user and password, using ``basic'' HTTP authentication which sends the user and password over the network in plain text. .TP .I "setheader [string data]" Set extra HEADER to use. Do not specify data to clear. .TP .I "setstatpath " Set path to obtain power status. .TP .I "setonpath [data]" Set path and optional post data to turn on node. .TP .I "setoffpath [data]" Set path and optional post data to turn off node. .TP .I "setcyclepath [data]" Set path and optional post data to turn cycle node. .TP .I "stat [nodes]" Get power status of all nodes or specified subset of nodes. .TP .I "on [nodes]" Turn on all nodes or specified subset of nodes. Will return "ok" after confirmation "on" has completed. .TP .I "off [nodes]" Turn off all nodes or specified subset of nodes. Will return "ok" after confirmation "off" has completed. .TP .I "cycle [nodes]" Turn off all nodes or specified subset of nodes. .SH "FILES" @X_SBINDIR@/redfishpower .br @X_SYSCONFDIR@/powerman/powerman.conf .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/man/vpcd.8.in000066400000000000000000000040521415616035500156510ustar00rootroot00000000000000.TH vpcd 8 "13 January 2012" "@PACKAGE_NAME@-@PACKAGE_VERSION@" .SH NAME vpcd \- virtual power control daemon .SH SYNOPSIS .B vpcd .I "[--port PORT]" .LP .SH DESCRIPTION .B vpcd is a test program for PowerMan which emulates a remote power control device. It can be run interactively by the powerman daemon, or it can listen on a port of your choosing. .SH OPTIONS .TP .I "-p, --port PORT" Instructs .B vpcd to listen for connections on the specified port instead of using stdin/stdout. Only one connection will be accepted. .SH INTERACTIVE COMMANDS The following commands are available at the vpcd> prompt: .TP .I "login" The login command must br run before any of the other commands will work. No username or password is required. .TP .I "logoff" Return .B vpcd to the initial state. .TP .I "stat PLUG|*" Show the power status of PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "beacon PLUG|*" Show the beacon status of PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "temp PLUG|*" Show the temperature of the node attached to PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "spew COUNT" Print COUNT 80-char lines. This is the basis of a buffer handling test. .TP .I "on PLUG|*" Turn on PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "off PLUG|*" Turn off PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "flash PLUG|*" Light the beacon on PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "unflash PLUG|*" Unlight the beacon on PLUG. If PLUG is ``*'', perform this action on all plugs. .TP .I "reset PLUG|*" Reset the node attached to PLUG. If PLUG is ``*'', perform this action on all plugs. .SH "FILES" @X_SBINDIR@/vpcd .SH "ORIGIN" PowerMan was originally developed by Andrew Uselton on LLNL's Linux clusters. This software is open source and distributed under the terms of the GNU GPL. .SH "SEE ALSO" .BR powerman (1), .BR powermand (8), .BR httppower (8), .BR plmpower (8), .BR vpcd (8), .BR powerman.conf (5), .BR powerman.dev (5). .PP \fBhttp://github.com/chaos/powerman\fR powerman-2.3.27/plmpower/000077500000000000000000000000001415616035500153105ustar00rootroot00000000000000powerman-2.3.27/plmpower/Makefile.am000066400000000000000000000002611415616035500173430ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/libcommon sbin_PROGRAMS = plmpower plmpower_SOURCES = plmpower.c plmpower_LDADD = $(top_builddir)/libcommon/libcommon.a powerman-2.3.27/plmpower/plmpower.c000066400000000000000000000531221415616035500173240ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2007 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* plmpower.c - control Insteon/X10 devices via SmartLabs PLM 2412S */ /* References: * For PLM bits, see "Insteon Modem Developer's Guide", * http://www.smarthome.com/manuals/2412sdevguide.pdf * For general Insteon protocol, see "Insteon: The Details" * http://www.insteon.net/pdf/insteondetails.pdf * For Insteon commands, see "EZBridge Reference Manual", Appendix B. * http://www.simplehomenet.com/Downloads/EZBridge%20Manual.pdf * Also: "Quick Reference Guide for Smarthome Device Manager for INSTEON" * http://www.insteon.net/sdk/files/dm/docs/ */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "error.h" #include "argv.h" #include "xread.h" #include "xtime.h" #include "xpoll.h" /* PLM commands */ #define IM_RECV_STD 0x50 /* plm -> host */ #define IM_RECV_EXT 0x51 #define IM_RECV_X10 0x52 #define IM_RECV_ALL_LINK_COMPLETE 0x53 #define IM_RECV_BUTTON 0x54 #define IM_RECV_RESET 0x55 #define IM_RECV_ALL_LINK_FAIL 0x56 #define IM_RECV_ALL_LINK_REC 0x57 #define IM_RECV_ALL_LINK_STAT 0x58 #define IM_GET_INFO 0x60 /* host -> plm */ #define IM_SEND_ALL_LINK 0x61 #define IM_SEND 0x62 #define IM_SEND_X10 0x63 #define IM_START_ALL_LINK 0x64 #define IM_CANCEL_ALL_LINK 0x65 #define IM_SET_HOST_CATEGORY 0x66 #define IM_RESET 0x67 #define IM_SET_ACK 0x68 #define IM_GET_FIRST_ALL_LINK_REC 0x69 #define IM_GET_NEXT_ALL_LINK_REC 0x6A #define IM_CONFIG_SET 0x6B #define IM_GET_SENDER_ALL_LINK_REC 0x6C #define IM_LED_ON 0x6D #define IM_LED_OFF 0x6E #define IM_MANAGE_ALL_LINK_REC 0x6F #define IM_SET_NACK 0x70 #define IM_SET_ACK2 0x71 #define IM_RF_SLEEP 0x72 #define IM_CONFIG_GET 0x73 /* PLM control bytes */ #define IM_STX 0x02 #define IM_ACK 0x06 #define IM_NAK 0x15 /* PLM config bits */ #define IM_CONFIG_BUTLINK_DISABLE 0x80 #define IM_CONFIG_MONITOR_MODE 0x40 #define IM_CONFIG_AUTOLED_DISABLE 0x20 #define IM_CONFIG_DEADMAN_DISABLE 0x10 #define IM_MAX_RECVLEN 28 /* response to send extended msg */ /* Insteon commands (incomplete) */ #define CMD_GRP_ASSIGN 0x01 #define CMD_GRP_DELETE 0x02 #define CMD_PING 0x10 #define CMD_ON 0x11 #define CMD_ON_FAST 0x12 #define CMD_OFF 0x13 #define CMD_OFF_FAST 0x14 #define CMD_BRIGHT 0x15 #define CMD_DIM 0x16 #define CMD_MAN_START 0x17 #define CMD_MAN_STOP 0x18 #define CMD_STATUS 0x19 /* X10 commands */ #define X10_ALL_UNITS_OFF 0x0 #define X10_ALL_LIGHTS_ON 0x1 #define X10_ON 0x2 #define X10_OFF 0x3 #define X10_DIM 0x4 #define X10_BRIGHT 0x5 #define X10_ALL_LIGHTS_OFF 0x6 #define X10_EXT_CODE 0x7 #define X10_HAIL_REQ 0x8 #define X10_HAIL_ACK 0x9 #define X10_PRESET_DIM 0xa #define X10_PRESET_DIM2 0xb #define X10_EXT_DATA 0xc #define X10_STATUS_ON 0xd #define X10_STATUS_OFF 0xe #define X10_STATUS_REQ 0xf /* X10 encoding of housecode A-P and device code 1-16 */ static const int x10_enc[] = { 0x6, 0xe, 0x2, 0xa, 0x1, 0x9, 0x5, 0xd, 0x7, 0xf, 0x3, 0xb, 0x0, 0x8, 0x4, 0xc }; typedef struct { char h; char m; char l; } insaddr_t; typedef struct { char house; char unit; } x10addr_t; static void usage(void); static int open_serial(char *dev); static int run_cmd(int fd, char *cmd); static void shell(int fd); static void docmd(int fd, char **av, int *quitp); static void help(void); static void plm_reset(int fd); static void plm_info(int fd); static void plm_on(int fd, char *addrstr); static void plm_off(int fd, char *addrstr); static void plm_status(int fd, char *addrstr); static void plm_ping(int fd, char *addrstr); static int str2insaddr(char *s, insaddr_t *ip); static char *insaddr2str(insaddr_t *ip); static int str2x10addr(char *s, x10addr_t *xp); static int wait_until_ready(int fd, int timeout_msec); static int plm_recv(int fd, char cmd, char *recv, int recvlen); static void plm_docmd(int fd, char *send, int sendlen, char *recv, int recvlen); static void plm_send_insteon(int fd, insaddr_t *ip, char cmd1, char cmd2); static int plm_recv_insteon(int fd, insaddr_t *ip, char *cmd1, char *cmd2, int timeout_msec); static void plm_send_x10(int fd, x10addr_t *xp, char cmd); static int testmode = 0; static char test_plug = 0; static unsigned long x10_attempts = 3; static int insteon_tmout = 1000; /* (msec) */ #define OPTIONS "d:Tx:t:S:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static struct option longopts[] = { { "device", required_argument, 0, 'd' }, { "testmode", no_argument, 0, 'T' }, { "x10-attempts", required_argument, 0, 'x' }, { "timeout", required_argument, 0, 't' }, { "single-cmd", required_argument, 0, 'S' }, {0,0,0,0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { char *device = NULL; int c; int fd = -1; char *single_cmd = NULL; err_init(basename(argv[0])); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != EOF) { switch (c) { case 'd': /* --device */ device = optarg; break; case 'T': /* --testmode */ testmode = 1; break; case 't': /* --timeout */ insteon_tmout = strtoul(optarg, NULL, 10); if (insteon_tmout < 1) err_exit(FALSE, "timeout must be >= 1 msec"); break; case 'x': /* --x10-attempts */ x10_attempts = strtoul(optarg, NULL, 10); if (x10_attempts < 1) err_exit(FALSE, "X10 attempts must be >= 1"); break; case 'S': /* --single-cmd */ single_cmd = strdup(optarg); break; default: usage(); break; } } if (optind < argc) usage(); if (!testmode) { if (device == NULL) usage(); fd = open_serial(device); } if (single_cmd) { run_cmd(fd, single_cmd); free(single_cmd); } else shell(fd); if (close(fd) < 0) err_exit(TRUE, "error closing %s", device); exit(0); } static void usage(void) { fprintf(stderr, "Usage: plmpower -d device \n"); exit(1); } /* Open the PLM's serial device [dev], lock it in a manner consistent * with powerman and conman, set baud rate, line discipline, etc, * and return file descriptor. */ static int open_serial(char *dev) { struct termios tio; int fd; fd = open(dev, O_RDWR | O_NOCTTY); if (fd < 0) err_exit(TRUE, "could not open %s", dev); if (lockf(fd, F_TLOCK, 0) < 0) err_exit(TRUE, "could not lock %s", dev); tcgetattr(fd, &tio); tio.c_cflag = B19200 | CS8 | CLOCAL | CREAD; tio.c_iflag = IGNBRK | IGNPAR; tio.c_oflag = ONLRET; tio.c_lflag = 0; tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 1; tcsetattr(fd, TCSANOW, &tio); return fd; } /* Parse the command line into an argv array which is passed to docmd() for * execution against PLM on [fd]. Returns if the user wants to quit. */ static int run_cmd(int fd, char *cmd) { int quit = 0; char **av; av = argv_create(cmd, ""); docmd(fd, av, &quit); argv_destroy(av); return (quit); } /* Prompt the user and run the command entered. * Returns when the user wants to quit. */ static void shell(int fd) { char buf[128]; int quit = 0; while (!quit) { printf("plmpower> "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin)) { quit = run_cmd(fd, buf); } else quit = 1; } } /* Parse argv array [av] and execute any commands against PLM on [fd]. * If the user wants to quit, set [*quitp] to 1. */ static void docmd(int fd, char **av, int *quitp) { if (av[0] != NULL) { if (strcmp(av[0], "help") == 0) { help(); } else if (strcmp(av[0], "quit") == 0) { *quitp = 1; } else if (strcmp(av[0], "info") == 0) { if (testmode) printf("Unavailable in test mode\n"); else plm_info(fd); } else if (strcmp(av[0], "reset") == 0) { if (testmode) printf("Unavailable in test mode\n"); else plm_reset(fd); } else if (strcmp(av[0], "on") == 0) { if (argv_length(av) != 2) printf("Usage: on addr\n"); else plm_on(fd, av[1]); } else if (strcmp(av[0], "off") == 0) { if (argv_length(av) != 2) printf("Usage: off addr\n"); else plm_off(fd, av[1]); } else if (strcmp(av[0], "status") == 0) { if (argv_length(av) != 2) printf("Usage: status addr\n"); else plm_status(fd, av[1]); } else if (strcmp(av[0], "ping") == 0) { if (testmode) printf("Unavailable in test mode\n"); else if (argv_length(av) != 2) printf("Usage: ping addr\n"); else plm_ping(fd, av[1]); } else printf("type \"help\" for a list of commands\n"); } } /* Summarize interactive "shell" commands. */ static void help(void) { printf("Valid commands are:\n"); printf(" info get PLM info\n"); printf(" reset reset the PLM (clears all-link db)\n"); printf(" on addr turn on device\n"); printf(" off addr turn on device\n"); printf(" status addr query status of device\n"); printf(" ping addr time round trip request/response to device\n"); printf("Where addr is Insteon (e.g. 1A.2B.3C) or X10 (e.g. G12)\n"); } /* Send the ON command to [addrstr], either X10 or Insteon, via PLM on [fd]. * If Insteon, retry the command until a response is received. * If X10, send it x10_attempts times whether we need to or not. */ static void plm_on(int fd, char *addrstr) { insaddr_t i; x10addr_t x; char cmd2; if (str2insaddr(addrstr, &i)) { if (testmode) { test_plug = 1; } else { do { plm_send_insteon(fd, &i, CMD_ON_FAST, 0xff); } while (!plm_recv_insteon(fd, &i, NULL, &cmd2, insteon_tmout)); if (cmd2 == 0) err_exit(FALSE, "on command failed"); } } else if (str2x10addr(addrstr, &x)) { if (!testmode) plm_send_x10(fd, &x, X10_ON); } else err(FALSE, "could not parse address"); } /* Send the OFF command to [addrstr], either X10 or Insteon, via PLM on [fd]. * If Insteon, retry the command until a response is received. * If X10, send it x10_attempts times whether we need to or not. */ static void plm_off(int fd, char *addrstr) { insaddr_t i; x10addr_t x; char cmd2; if (str2insaddr(addrstr, &i)) { if (testmode) { test_plug = 0; } else { do { plm_send_insteon(fd, &i, CMD_OFF_FAST, 0); } while (!plm_recv_insteon(fd, &i, NULL, &cmd2, insteon_tmout)); if (cmd2 != 0) err_exit(FALSE, "off command failed"); } } else if (str2x10addr(addrstr, &x)) { if (!testmode) plm_send_x10(fd, &x, X10_OFF); } else err(FALSE, "could not parse address"); } /* Send the Insteon STATUS command to [addrstr] via PLM on [fd] and print * the result on stdout. Retry the command until a response is received. * X10 addresses are accepted here, but we always report status as "unknown". */ static void plm_status(int fd, char *addrstr) { insaddr_t i; x10addr_t x; char cmd2; if (str2insaddr(addrstr, &i)) { if (testmode) { cmd2 = test_plug; } else { do { plm_send_insteon(fd, &i, CMD_STATUS, 0); } while (!plm_recv_insteon(fd, &i, NULL, &cmd2, insteon_tmout)); } printf("%s: %.2hhX\n", addrstr, cmd2); } else if (str2x10addr(addrstr, &x)) printf("%s: unknown\n", addrstr); else err(FALSE, "could not parse address"); } /* Send the Insteon PING command to [addrstr] via PLM on [fd] * and print the round-trip time and number of retries on stdout. * Retry the command until a response is received. */ static void plm_ping(int fd, char *addrstr) { insaddr_t i; x10addr_t x; struct timeval t1, t2, delta; int tries = 0; /* FIXME: make this work more like ping(8). */ if (str2insaddr(addrstr, &i)) { if (gettimeofday(&t1, NULL) < 0) err_exit(TRUE, "gettimeofday"); do { tries++; plm_send_insteon(fd, &i, CMD_PING, 0); } while (!plm_recv_insteon(fd, &i, NULL, NULL, insteon_tmout)); if (gettimeofday(&t2, NULL) < 0) err_exit(TRUE, "gettimeofday"); timersub(&t2, &t1, &delta); printf("PING from %s: retries=%d time=%.2lf ms\n", addrstr, tries - 1, (double)delta.tv_usec / 1000.0 + (double)delta.tv_sec * 1000.0); } else if (str2x10addr(addrstr, &x)) err(FALSE, "ping is only for Insteon devices"); else err(FALSE, "could not parse address"); } /* Convert a string [s] to Insteon address [ip]. * Return 1 on success, 0 on failure. */ static int str2insaddr(char *s, insaddr_t *ip) { if (sscanf(s, "%2hhx.%2hhx.%2hhx", &ip->h, &ip->m, &ip->l) != 3) return 0; return 1; } /* Convert an Insteon address [ip] to string [returned]. * Returns pointer to static data overwritten on each call. */ static char * insaddr2str(insaddr_t *ip) { static char s[64]; snprintf(s, sizeof(s), "%.2hhX.%.2hhX.%.2hhX", ip->h, ip->m, ip->l); return s; } /* Convert a string [s] to X10 address [xp]. * Return 1 on success, 0 on failure. */ static int str2x10addr(char *s, x10addr_t *xp) { unsigned long i; if (isupper(s[0])) s[0] = tolower(s[0]); if (!islower(s[0]) || s[0] > 'p') return 0; xp->house = x10_enc[s[0] - 'a']; i = strtoul(&s[1], NULL, 10) - 1; if (i >= sizeof(x10_enc)/sizeof(int)) return 0; xp->unit = x10_enc[i]; return 1; } /* Wait until PLM on [fd] has data ready for reading or [timeout_msec] expires. * Return value is 1 on data ready, 0 on timeout. */ static int wait_until_ready(int fd, int timeout_msec) { struct timeval tv = { timeout_msec / 1000, (timeout_msec % 1000) * 1000 }; xpollfd_t pfd = xpollfd_create(); int res = 1; xpollfd_set(pfd, fd, XPOLLIN); if (xpoll(pfd, &tv) == 0) res = 0; xpollfd_destroy(pfd); return res; } /* Receive a command or a response from the PLM on [fd] and return it * in [recv] of length [recvlen]. If the a command is received which does * not match [cmd], silently discard it. If a NAK is received instead of STX * indicating the PLM was busy when the last command was sent, return 1, * otherwise return 0. */ static int plm_recv(int fd, char cmd, char *recv, int recvlen) { char b[IM_MAX_RECVLEN]; retry: xread_all(fd, &b[0], 1); if (b[0] == IM_NAK) return 1; else if (b[0] != IM_STX) err_exit(FALSE, "expected IM_STX or IM_NAK, got %.2hhX", b[0]); xread_all(fd, &b[1], 1); if (b[1] != cmd) { switch (b[1]) { case IM_RECV_STD: xread_all(fd, &b[2], 9); break; case IM_RECV_EXT: xread_all(fd, &b[2], 23); break; case IM_RECV_X10: xread_all(fd, &b[2], 2); break; case IM_RECV_ALL_LINK_COMPLETE: xread_all(fd, &b[2], 8); break; case IM_RECV_BUTTON: xread_all(fd, &b[2], 1); break; case IM_RECV_RESET: break; case IM_RECV_ALL_LINK_FAIL: xread_all(fd, &b[2], 5); break; case IM_RECV_ALL_LINK_REC: xread_all(fd, &b[2], 8); break; case IM_RECV_ALL_LINK_STAT: xread_all(fd, &b[2], 1); break; default: err_exit(FALSE, "unexpected command: %.2hhX", b[1]); break; } goto retry; } xread_all(fd, &b[2], recvlen - 2); memcpy(recv, b, recvlen); return 0; } /* Send a command [send] of length [sendlen] to PLM on [fd], then * read the response into [recv] of length [recvlen]. If a NAK is * received, retry the command until it is ACKed. */ static void plm_docmd(int fd, char *send, int sendlen, char *recv, int recvlen) { int nak; do { xwrite_all(fd, send, sendlen); nak = plm_recv(fd, send[1], recv, recvlen); if (!nak && recv[recvlen - 1] == IM_NAK) nak = 1; /* FIXME: retry appropriate here or is command broken? */ if (nak) usleep(1000*100); /* wait 100ms for PLM to become ready */ } while (nak); } /* Send IM_RESET to the PLM on [fd]. */ static void plm_reset(int fd) { char send[2] = { IM_STX, IM_RESET }; char recv[3]; plm_docmd(fd, send, sizeof(send), recv, sizeof(recv)); printf("PLM reset complete\n"); } /* Send IM_GET_INFO to the PLM on [fd] and print the response on stdout. */ static void plm_info(int fd) { insaddr_t i; char send[2] = { IM_STX, IM_GET_INFO }; char recv[9]; plm_docmd(fd, send, sizeof(send), recv, sizeof(recv)); i.h = recv[2]; i.m = recv[3]; i.l = recv[4]; printf("id=%s dev=%.2hhX.%.2hhX vers=%hhd\n", insaddr2str(&i), recv[5], recv[6], recv[7]); } /* Send an Insteon command described by [cmd1] and [cmd2] to address [ip] * using PLM on [fd]. The command will be retried until accepted by the PLM. */ static void plm_send_insteon(int fd, insaddr_t *ip, char cmd1, char cmd2) { char send[8] = { IM_STX, IM_SEND, ip->h, ip->m, ip->l, 3, cmd1, cmd2 }; char recv[9]; plm_docmd(fd, send, sizeof(send), recv, sizeof(recv)); } /* Receive an Insteon command from address [i] into [cmd1] and [cmd2] * via PLM on [fd]. If more than [timeout_msec] milliseconds elapses, * give up and return 0, else return 1. */ static int plm_recv_insteon(int fd, insaddr_t *ip, char *cmd1, char *cmd2, int timeout_msec) { char recv[11]; int nak; do { /* FIXME: timeout is restarted if an unsolicited command is received */ if (!wait_until_ready(fd, timeout_msec)) return 0; nak = plm_recv(fd, IM_RECV_STD, recv, sizeof(recv)); if (nak) err_exit(FALSE, "unexpected NAK while waiting for Insteon packet"); } while (ip->h != recv[2] || ip->m != recv[3] || ip->l != recv[4]); if (cmd1) *cmd1 = recv[9]; if (cmd2) *cmd2 = recv[10]; return 1; } /* Send an X10 command [cmd] to address [xp] via PLM on [fd]. * Repeat the command x10_attempts times for good measure because we will * get no acknowledgement from the device. */ static void plm_send_x10(int fd, x10addr_t *xp, char cmd) { char senda[4] = { IM_STX, IM_SEND_X10, (xp->house << 4) | xp->unit, 0 }; char sendb[4] = { IM_STX, IM_SEND_X10, (xp->house << 4) | cmd, 0x80 }; char recv[5]; int i; for (i = 0; i < x10_attempts; i++) { plm_docmd(fd, senda, sizeof(senda), recv, sizeof(recv)); plm_docmd(fd, sendb, sizeof(sendb), recv, sizeof(recv)); } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powerman/000077500000000000000000000000001415616035500152735ustar00rootroot00000000000000powerman-2.3.27/powerman/Makefile.am000066400000000000000000000005631415616035500173330ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/liblsd -I$(top_srcdir)/libcommon bin_PROGRAMS = powerman pm$(EXEEXT) common_ldadd = \ $(top_builddir)/liblsd/liblsd.a \ $(top_builddir)/libcommon/libcommon.a powerman_SOURCES = powerman.c powerman_LDADD = $(common_ldadd) $(LIBGENDERS) $(LIBFORKPTY) pm_SOURCES = pm$(EXEEXT): powerman rm -f $@ $(LN_S) $< $@ powerman-2.3.27/powerman/powerman.c000066400000000000000000000450061415616035500172740ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #if HAVE_GETOPT_H #include #endif #if HAVE_GENDERS_H #include #endif #include #include #include #include #include #include #include #include #include #include #include "powerman.h" #include "xmalloc.h" #include "xtypes.h" #include "xread.h" #include "error.h" #include "hostlist.h" #include "client_proto.h" #include "debug.h" #include "argv.h" #include "xpty.h" #include "hprintf.h" #include "argv.h" #include "list.h" #define CMD_MAGIC 0x5565aafd typedef struct { int magic; char *fmt; char **argv; char *sendstr; } cmd_t; #if WITH_GENDERS static void _push_genders_hosts(hostlist_t targets, char *s); #endif static int _connect_to_server_tcp(char *host, char *port); static int _connect_to_server_pipe(char *server_path, char *config_path, bool short_circuit_delays); static void _usage(void); static void _license(void); static void _version(void); static int _process_line(int fd); static void _expect(int fd, char *str); static int _process_response(int fd); static void _process_version(int fd); static void _cmd_create(List cl, char *fmt, char *arg, bool prepend); static void _cmd_destroy(cmd_t *cp); static void _cmd_append(cmd_t *cp, char *arg); static void _cmd_prepare(cmd_t *cp, bool genders); static int _cmd_execute(cmd_t *cp, int fd); static void _cmd_print(cmd_t *cp); static char *prog; #define OPTIONS "0:1:c:r:f:u:B:blQ:qP:tD:dTxgh:S:C:YVLZI" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { {"on", required_argument, 0, '1'}, {"off", required_argument, 0, '0'}, {"cycle", required_argument, 0, 'c'}, {"reset", required_argument, 0, 'r'}, {"flash", required_argument, 0, 'f'}, {"unflash", required_argument, 0, 'u'}, {"beacon", required_argument, 0, 'B'}, {"beacon-all", no_argument, 0, 'b'}, {"list", no_argument, 0, 'l'}, {"query", required_argument, 0, 'Q'}, {"query-all", no_argument, 0, 'q'}, {"temp", required_argument, 0, 'P'}, {"temp-all", no_argument, 0, 't'}, {"device", required_argument, 0, 'D'}, {"device-all", no_argument, 0, 'd'}, {"telemetry", no_argument, 0, 'T'}, {"exprange", no_argument, 0, 'x'}, {"genders", no_argument, 0, 'g'}, {"server-host", required_argument, 0, 'h'}, {"server-path", required_argument, 0, 'S'}, {"config-path", required_argument, 0, 'C'}, {"short-circuit-delays", no_argument, 0, 'Y'}, {"version", no_argument, 0, 'V'}, {"license", no_argument, 0, 'L'}, {"dump-cmds", no_argument, 0, 'Z'}, {"ignore-errs", no_argument, 0, 'I'}, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char **argv) { int c; int res = 0; int server_fd; char *p, *port = DFLT_PORT; char *host = DFLT_HOSTNAME; bool genders = FALSE; bool dumpcmds = FALSE; bool ignore_errs = FALSE; char *server_path = NULL; char *config_path = NULL; List commands; /* list-o-cmd_t's */ ListIterator itr; cmd_t *cp; bool short_circuit_delays = FALSE; prog = basename(argv[0]); err_init(prog); commands = list_create((ListDelF)_cmd_destroy); /* Parse options. */ opterr = 0; while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case '1': /* --on */ _cmd_create(commands, CP_ON, optarg, FALSE); break; case '0': /* --off */ _cmd_create(commands, CP_OFF, optarg, FALSE); break; case 'c': /* --cycle */ _cmd_create(commands, CP_CYCLE, optarg, FALSE); break; case 'r': /* --reset */ _cmd_create(commands, CP_RESET, optarg, FALSE); break; case 'l': /* --list */ _cmd_create(commands, CP_NODES, NULL, FALSE); break; case 'Q': /* --query */ _cmd_create(commands, CP_STATUS, optarg, FALSE); break; case 'q': /* --query-all */ _cmd_create(commands, CP_STATUS_ALL, NULL, FALSE); break; case 'f': /* --flash */ _cmd_create(commands, CP_BEACON_ON, optarg, FALSE); break; case 'u': /* --unflash */ _cmd_create(commands, CP_BEACON_OFF, optarg, FALSE); break; case 'B': /* --beacon */ _cmd_create(commands, CP_BEACON, optarg, FALSE); break; case 'b': /* --beacon-all */; _cmd_create(commands, CP_BEACON_ALL, NULL, FALSE); break; case 'P': /* --temp */ _cmd_create(commands, CP_TEMP, optarg, FALSE); break; case 't': /* --temp-all */ _cmd_create(commands, CP_TEMP_ALL, NULL, FALSE); break; case 'D': /* --device */ _cmd_create(commands, CP_DEVICE, optarg, FALSE); break; case 'd': /* --device-all */ _cmd_create(commands, CP_DEVICE_ALL, NULL, FALSE); break; case 'Y': /* --short-circuit-delays */ short_circuit_delays = TRUE; break; case 'h': /* --server-host host[:port] */ if ((p = strchr(optarg, ':'))) { *p++ = '\0'; port = p; } host = optarg; break; case 'L': /* --license */ _license(); /*NOTREACHED*/ break; case 'V': /* --version */ _version(); /*NOTREACHED*/ break; case 'T': /* --telemetry */ _cmd_create(commands, CP_TELEMETRY, NULL, TRUE); break; case 'x': /* --exprange */ _cmd_create(commands, CP_EXPRANGE, NULL, TRUE); break; case 'g': /* --genders */ #if WITH_GENDERS genders = TRUE; #else err_exit(FALSE, "not configured with genders support"); #endif break; case 'S': /* --server-path */ server_path = optarg; break; case 'C': /* --config-path */ config_path = optarg; break; case 'Z': /* --dump-cmds */ dumpcmds = TRUE; break; case 'I': /* --ignore-errs */ ignore_errs = TRUE; break; default: _usage(); /*NOTREACHED*/ break; } } if (list_is_empty(commands)) _usage(); if (short_circuit_delays && !server_path) _usage(); /* For backwards compat with powerman 2.0 and earlier, * additional arguments are more targets for last command. */ if (optind < argc) { cmd_t *last = NULL; itr = list_iterator_create(commands); while ((cp = list_next(itr))) last = cp; list_iterator_destroy(itr); if (last == NULL) _usage(); while (optind < argc) { _cmd_append(last, argv[optind]); optind++; } } /* Prepare commands for processing. */ itr = list_iterator_create(commands); while ((cp = list_next(itr))) _cmd_prepare(cp, genders); list_iterator_destroy(itr); /* Dump commands and exit if requested. */ if (dumpcmds) { itr = list_iterator_create(commands); while ((cp = list_next(itr))) _cmd_print(cp); list_iterator_destroy(itr); exit(0); } /* Establish connection to server and start protocol. */ if (server_path) server_fd = _connect_to_server_pipe(server_path, config_path, short_circuit_delays); else server_fd = _connect_to_server_tcp(host, port); _process_version(server_fd); _expect(server_fd, CP_PROMPT); /* Execute the commands. */ itr = list_iterator_create(commands); while ((cp = list_next(itr))) { res = _cmd_execute(cp, server_fd); if (ignore_errs) res = 0; if (res != 0) break; } list_iterator_destroy(itr); list_destroy(commands); /* Disconnect from server. */ hfdprintf(server_fd, "%s%s", CP_QUIT, CP_EOL); _expect(server_fd, CP_RSP_QUIT); exit(res); } /* Display powerman usage and exit. */ static void _usage(void) { printf("Usage: %s [action] [targets]\n", prog); printf("-1,--on targets Power on targets\n"); printf("-0,--off targets Power off targets\n"); printf("-c,--cycle targets Power cycle targets\n"); printf("-q,--query-all Query power state of all targets\n"); printf("-Q,--query targets Query power state of specific targets\n"); exit(1); } /* Display powerman license and exit. */ static void _license(void) { printf( "Copyright (C) 2001-2008 The Regents of the University of California.\n" "Produced at Lawrence Livermore National Laboratory.\n" "Written by Andrew Uselton .\n" "http://www.llnl.gov/linux/powerman/\n" "UCRL-CODE-2002-008\n\n" "PowerMan is free software; you can redistribute it and/or modify it\n" "under the terms of the GNU General Public License as published by\n" "the Free Software Foundation.\n"); exit(1); } /* Display powerman version and exit. */ static void _version(void) { printf("%s\n", PACKAGE_VERSION); exit(1); } #if WITH_GENDERS static void _push_genders_hosts(hostlist_t targets, char *s) { genders_t g; char **nodes; int len, n, i; if (strlen(s) == 0) return; if (!(g = genders_handle_create())) err_exit(FALSE, "genders_handle_create failed"); if (genders_load_data(g, NULL) < 0) err_exit(FALSE, "genders_load_data: %s", genders_errormsg(g)); if ((len = genders_nodelist_create(g, &nodes)) < 0) err_exit(FALSE, "genders_nodelist_create: %s", genders_errormsg(g)); if ((n = genders_query(g, nodes, len, s)) < 0) err_exit(FALSE, "genders_query: %s", genders_errormsg(g)); genders_handle_destroy(g); if (n == 0) err_exit(FALSE, "genders expression did not match any nodes"); for (i = 0; i < n; i++) { if (!hostlist_push(targets, nodes[i])) err_exit(FALSE, "hostlist error"); } } #endif static void _cmd_create(List cl, char *fmt, char *arg, bool prepend) { cmd_t *cp = (cmd_t *)xmalloc(sizeof(cmd_t)); cp->magic = CMD_MAGIC; cp->fmt = fmt; cp->argv = NULL; cp->sendstr = NULL; if (arg) cp->argv = argv_create(arg, ""); if (prepend) list_prepend(cl, cp); else list_append(cl, cp); } static void _cmd_destroy(cmd_t *cp) { assert(cp->magic == CMD_MAGIC); cp->magic = 0; if (cp->sendstr) xfree(cp->sendstr); if (cp->argv) argv_destroy(cp->argv); xfree(cp); } static void _cmd_append(cmd_t *cp, char *arg) { assert(cp->magic == CMD_MAGIC); if (cp->argv == NULL) { if (!strcmp(cp->fmt, CP_STATUS_ALL)) { cp->fmt = CP_STATUS; cp->argv = argv_create(arg, ""); } else if (!strcmp(cp->fmt, CP_BEACON_ALL)) { cp->fmt = CP_BEACON; cp->argv = argv_create(arg, ""); } else if (!strcmp(cp->fmt, CP_DEVICE_ALL)) { cp->fmt = CP_DEVICE; cp->argv = argv_create(arg, ""); } else if (!strcmp(cp->fmt, CP_TEMP_ALL)) { cp->fmt = CP_TEMP; cp->argv = argv_create(arg, ""); } else err_exit(FALSE, "option takes no arguments"); } else cp->argv = argv_append(cp->argv, arg); } static void _cmd_prepare(cmd_t *cp, bool genders) { char tmpstr[CP_LINEMAX]; hostlist_t hl; int i; assert(cp->magic == CMD_MAGIC); assert(cp->sendstr == NULL); tmpstr[0] = '\0'; if (cp->argv) { hl = hostlist_create(NULL); for (i = 0; i < argv_length(cp->argv); i++) { if (genders) { #if WITH_GENDERS _push_genders_hosts(hl, cp->argv[i]); #endif } else { if (hostlist_push(hl, cp->argv[i]) == 0) err_exit(FALSE, "hostlist error"); } } if (hostlist_ranged_string(hl, sizeof(tmpstr), tmpstr) == -1) err_exit(FALSE, "hostlist error"); hostlist_destroy(hl); } cp->sendstr = hsprintf(cp->fmt, tmpstr); } static int _cmd_execute(cmd_t *cp, int fd) { int res; assert(cp->magic == CMD_MAGIC); assert(cp->sendstr != NULL); hfdprintf(fd, "%s%s", cp->sendstr, CP_EOL); res = _process_response(fd); _expect(fd, CP_PROMPT); return res; } static void _cmd_print(cmd_t *cp) { assert(cp->magic == CMD_MAGIC); assert(cp->sendstr != NULL); printf("%s%s", cp->sendstr, CP_EOL); } static int _connect_to_server_pipe(char *server_path, char *config_path, bool short_circuit_delays) { int saved_stderr; char cmd[128]; char **argv; pid_t pid; int fd; saved_stderr = dup(STDERR_FILENO); if (saved_stderr < 0) err_exit(TRUE, "dup stderr"); snprintf(cmd, sizeof(cmd), "powermand -sf -c %s", config_path); argv = argv_create(cmd, ""); if (short_circuit_delays) argv = argv_append(argv, "-Y"); pid = xforkpty(&fd, NULL, 0); switch (pid) { case -1: err_exit(TRUE, "forkpty error"); case 0: /* child */ if (dup2(saved_stderr, STDERR_FILENO) < 0) err_exit(TRUE, "dup2 stderr"); close(saved_stderr); xcfmakeraw(STDIN_FILENO); execv(server_path, argv); err_exit(TRUE, "exec %s", server_path); default: /* parent */ close(saved_stderr); break; } argv_destroy(argv); return fd; } static int _connect_to_server_tcp(char *host, char *port) { int error, fd = -1; struct addrinfo hints, *res, *r; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((error = getaddrinfo(host, port, &hints, &res)) != 0) err_exit(FALSE, "getaddrinfo %s:%s: %s", host, port, gai_strerror(error)); if (res == NULL) err_exit(FALSE, "no addresses for server %s:%s", host, port); for (r = res; r != NULL; r = r->ai_next) { if ((fd = socket(r->ai_family, r->ai_socktype, 0)) < 0) continue; if (connect(fd, r->ai_addr, r->ai_addrlen) < 0) { close(fd); continue; } break; /* success! */ } if (r == NULL) err_exit(FALSE, "could not connect to address %s:%s", host, port); freeaddrinfo(res); return fd; } /* Return true if response should be suppressed. */ static bool _supress(int num) { if (strtol(CP_RSP_QRY_COMPLETE, NULL, 10) == num) return TRUE; if (strtol(CP_RSP_TELEMETRY, NULL, 10) == num) return TRUE; if (strtol(CP_RSP_EXPRANGE, NULL, 10) == num) return TRUE; return FALSE; } /* Get a line from the socket and display on stdout. * Return the numerical portion of the repsonse. */ static int _process_line(int fd) { char *buf = xreadstr(fd); long int num; num = strtol(buf, NULL, 10); if (num == LONG_MIN || num == LONG_MAX) num = -1; if (strlen(buf) > 4) { if (!_supress(num)) printf("%s\n", buf + 4); } else err_exit(FALSE, "unexpected response from server"); xfree(buf); return num; } /* Read version and warn if it doesn't match the client's. */ static void _process_version(int fd) { char *buf = xreadstr(fd); char *vers = xmalloc (strlen(buf)+1); if (sscanf(buf, CP_VERSION, vers) != 1) err_exit(FALSE, "unexpected response from server"); if (strcmp(vers, PACKAGE_VERSION) != 0) err(FALSE, "warning: server version (%s) != client (%s)", vers, PACKAGE_VERSION); xfree(buf); xfree(vers); } static int _process_response(int fd) { int num; do { num = _process_line(fd); } while (!CP_IS_ALLDONE(num)); return (CP_IS_FAILURE(num) ? num : 0); } /* Read strlen(str) bytes from file descriptor and exit if * it doesn't match 'str'. */ static void _expect(int fd, char *str) { int len = strlen(str); char *buf = xmalloc (len + 1); char *p = buf; int res; do { res = xread(fd, p, len); if (res < 0) err_exit(TRUE, "lost connection with server"); p += res; *p = '\0'; len -= res; } while (strcmp(str, buf) != 0 && len > 0); /* Shouldn't happen. We are not handling the general case of the server * returning the wrong response. Read() loop above may hang in that case. */ if (strcmp(str, buf) != 0) err_exit(FALSE, "unexpected response from server"); xfree (buf); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/000077500000000000000000000000001415616035500154375ustar00rootroot00000000000000powerman-2.3.27/powermand/Makefile.am000066400000000000000000000012111415616035500174660ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/liblsd -I$(top_srcdir)/libcommon sbin_PROGRAMS = powermand powermand_SOURCES = \ arglist.c \ arglist.h \ client.c \ client.h \ daemon.c \ daemon.h \ device.c \ device.h \ device_pipe.c \ device_pipe.h \ device_private.h \ device_serial.c \ device_serial.h \ device_tcp.c \ device_tcp.h \ parse_lex.l \ parse_tab.y \ parse_util.c \ parse_util.h \ powermand.c powermand_LDADD = \ $(top_builddir)/liblsd/liblsd.a \ $(top_builddir)/libcommon/libcommon.a \ $(LIBWRAP) $(LIBFORKPTY) AM_YFLAGS = -d parse_lex.c : parse_tab.h CLEANFILES = parse_lex.c parse_tab.c parse_tab.h powerman-2.3.27/powermand/arglist.c000066400000000000000000000105261415616035500172540ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* Args used to be stored in a List, but gprof showed that very large * configurations spent a lot of time doing linear search of arg list for * each arg->state update. The List was traded for a hash, but as we still * want to iterate through args in the client in order, we keep the hostlist * representation of the nodes in the ArgList, and use it to implement an * 'iterator' interface. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "list.h" #include "xmalloc.h" #include "hostlist.h" #include "hash.h" #include "arglist.h" struct arglist_iterator { hostlist_iterator_t itr; ArgList arglist; }; struct arglist { hash_t args; hostlist_t hl; int refcount; /* free when refcount == 0 */ }; static void _destroy_arg(Arg * arg) { assert(arg != NULL); assert(arg->node != NULL); xfree(arg->node); if (arg->val) xfree(arg->val); xfree(arg); } static Arg *_create_arg(char *node) { Arg *arg = (Arg *) xmalloc(sizeof(Arg)); arg->node = xstrdup(node); arg->state = ST_UNKNOWN; arg->val = NULL; return arg; } ArgList arglist_create(hostlist_t hl) { ArgList new = (ArgList) xmalloc(sizeof(struct arglist)); hostlist_iterator_t itr; char *node; int hash_size; new->refcount = 1; hash_size = hostlist_count(hl); /* reasonable? */ new->args = hash_create(hash_size, (hash_key_f)hash_key_string, (hash_cmp_f)strcmp, (hash_del_f)_destroy_arg); if ((itr = hostlist_iterator_create(hl)) == NULL) { arglist_unlink(new); return NULL; } while ((node = hostlist_next(itr)) != NULL) { Arg *arg = _create_arg(node); hash_insert(new->args, arg->node, arg); free(node); /* hostlist_next strdups returned string */ } hostlist_iterator_destroy(itr); new->hl = hostlist_copy(hl); return new; } void arglist_unlink(ArgList arglist) { if (--arglist->refcount == 0) { hash_destroy(arglist->args); hostlist_destroy(arglist->hl); xfree(arglist); } } ArgList arglist_link(ArgList arglist) { arglist->refcount++; return arglist; } Arg *arglist_find(ArgList arglist, char *node) { Arg *arg = NULL; if (node != NULL) arg = hash_find(arglist->args, node); return arg; } ArgListIterator arglist_iterator_create(ArgList arglist) { ArgListIterator itr = (ArgListIterator)xmalloc(sizeof(struct arglist_iterator)); itr->arglist = arglist; itr->itr = hostlist_iterator_create(arglist->hl); return itr; } void arglist_iterator_destroy(ArgListIterator itr) { hostlist_iterator_destroy(itr->itr); xfree(itr); } Arg *arglist_next(ArgListIterator itr) { Arg *arg = NULL; char *node; node = hostlist_next(itr->itr); if (node != NULL) { arg = hash_find(itr->arglist->args, node); free(node); /* hostlist_next strdups returned string */ } return arg; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/arglist.h000066400000000000000000000026501415616035500172600ustar00rootroot00000000000000/* * The ArgList is used to pass the list of "target nodes" into a device * script, and then to pass the result back to the client. */ #ifndef PM_ARGLIST_H #define PM_ARGLIST_H typedef enum { ST_UNKNOWN, ST_OFF, ST_ON } InterpState; typedef struct { char *node; /* node name (in) */ char *val; /* value as returned by the device (out) */ InterpState state; /* interpreted value, if appropriate (out) */ } Arg; typedef struct arglist_iterator *ArgListIterator; typedef struct arglist *ArgList; /* Create an ArgList with an Arg entry for each node in hl (refcount == 1). */ ArgList arglist_create(hostlist_t hl); /* Do refcount++ in ArgList. */ ArgList arglist_link(ArgList arglist); /* Do refcount-- in ArgList. * If the refcount reaches zero, destroy the Arglist. */ void arglist_unlink(ArgList arglist); /* Search ArgList for an Arg entry that matches node. * Return pointer to Arg on success (points to actual list entry), * or NULL on search failure. */ Arg * arglist_find(ArgList arglist, char *node); /* An iterator interface for ArgLists, similar to the iterators in list.h. */ ArgListIterator arglist_iterator_create(ArgList arglist); void arglist_iterator_destroy(ArgListIterator itr); Arg * arglist_next(ArgListIterator itr); #endif /* PM_ARGLIST_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/client.c000066400000000000000000001052241415616035500170650ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* This is the component of the server that deals with clients. * The client itself is contained in powerman.c. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_TCP_WRAPPERS #include #endif #include #include #include "xtypes.h" #include "xmalloc.h" #include "xpoll.h" #include "xregex.h" #include "hostlist.h" #include "list.h" #include "parse_util.h" #include "client.h" #include "cbuf.h" #include "error.h" #include "client_proto.h" #include "debug.h" #include "pluglist.h" #include "hprintf.h" #include "arglist.h" #include "device_private.h" #include "xpty.h" #include "powerman.h" #ifndef HAVE_SOCKLEN_T typedef int socklen_t; /* socklen_t is uint32_t in Posix.1g */ #endif /* !HAVE_SOCKLEN_T */ #define LISTEN_BACKLOG 5 #define MIN_CLIENT_BUF 1024 #define MAX_CLIENT_BUF 1024*1024 typedef struct { int com; /* script index */ hostlist_t hl; /* target nodes */ int pending; /* count of pending device actions */ bool error; /* cumulative error flag for actions */ ArgList arglist; /* argument for query commands */ } Command; #define CLI_MAGIC 0xdadadada typedef struct { int magic; int fd; /* file desriptor for the socket */ int ofd; /* separate output file descriptor (if used) */ char *ip; /* IP address of the client's host */ unsigned short int port; /* Port of client connection */ char *host; /* host name of client host */ cbuf_t to; /* out buffer */ cbuf_t from; /* in buffer */ Command *cmd; /* command (there can be only one) */ int client_id; /* client identifier */ bool telemetry; /* client wants telemetry debugging info */ bool exprange; /* client wants host ranges expanded */ bool client_quit; /* set true after client quit command */ } Client; /* prototypes for internal functions */ static Command *_create_command(Client * c, int com, char *arg1); static void _destroy_command(Command * cmd); static int _match_client(Client * c, void *key); static Client *_find_client(int client_id); static hostlist_t _hostlist_create_validated(Client * c, char *str); static void _client_query_nodes_reply(Client * c); static void _client_query_device_reply(Client * c, char *arg); static void _client_query_status_reply(Client * c, bool error); static void _client_query_status_reply_nointerp(Client * c, bool error); static void _handle_read(Client * c); static void _handle_write(Client * c); static void _handle_input(Client *c); static char *_strip_whitespace(char *str); static void _parse_input(Client * c, char *input); static void _destroy_client(Client * c); static void _create_client_socket(int fd); static void _create_client_stdio(void); static void _act_finish(int client_id, ActError acterr, const char *fmt, ...); static void _telemetry_printf(int client_id, const char *fmt, ...); #if HAVE_TCP_WRAPPERS /* tcp wrappers support */ extern int hosts_ctl(char *daemon, char *client_name, char *client_addr, char *client_user); int allow_severity = LOG_INFO; /* logging level for accepted reqs */ int deny_severity = LOG_WARNING;/* logging level for rejected reqs */ #endif static int *listen_fds; /* powermand listen sockets */ static int listen_fds_len = 0; /* count of above sockets */ static List cli_clients = NULL; /* list of clients */ static bool one_client = FALSE; /* terminate after first client */ static bool server_done = FALSE;/* true when stdio client exits */ static int cli_id_seq = 1; /* range 1...INT_MAX */ #define _next_cli_id() \ (cli_id_seq < INT_MAX ? cli_id_seq++ : (cli_id_seq = 1, INT_MAX)) #define _internal_error_response(c) \ _client_printf(c, CP_ERR_INTERNAL, __FILE__, __LINE__) #include "hostlist.h" /* * Wrapped hostlist_ranged_string() with internal buffer allocation, * which caller must xfree(). */ #define CHUNKSIZE 80 static char *_xhostlist_ranged_string(hostlist_t hl) { int size = 0; char *str = NULL; do { str = (size == 0) ? xmalloc(CHUNKSIZE) : xrealloc(str, size+CHUNKSIZE); size += CHUNKSIZE; } while (hostlist_ranged_string(hl, size, str) == -1); return str; } /* * printf-like function which writes to the output cbuf. */ static void _client_printf(Client *c, const char *fmt, ...) { char *str = NULL; int written, dropped; va_list ap; va_start(ap, fmt); str = hvsprintf(fmt, ap); va_end(ap); /* Write to the client buffer */ written = cbuf_write(c->to, str, strlen(str), &dropped); if (written < 0) err(TRUE, "_client_printf: cbuf_write returned %d", written); else if (dropped > 0) err(FALSE, "_client_printf: cbuf_write dropped %d chars", dropped); /* Free the tmp string */ xfree(str); } /* * Initialize module. */ void cli_init(void) { /* create cli_clients list */ cli_clients = list_create((ListDelF) _destroy_client); } /* * Finalize module. */ void cli_fini(void) { /* destroy clients */ list_destroy(cli_clients); } /* * Build a hostlist_t from a string, validating each node name against * powerman configuration. If any bogus nodes are found, issue error * response to client and return NULL. */ static hostlist_t _hostlist_create_validated(Client * c, char *str) { hostlist_t hl = NULL; hostlist_t badhl = NULL; hostlist_iterator_t itr = NULL; char *host; bool valid = TRUE; if ((hl = hostlist_create(str)) == NULL) { /* Note: report detailed error since 'str' comes from the user */ if (errno == ERANGE || errno == EINVAL) _client_printf(c, CP_ERR_HOSTLIST, "invalid range"); else _internal_error_response(c); return NULL; } conf_exp_aliases(hl); if ((badhl = hostlist_create(NULL)) == NULL) { /* Note: other hostlist failures not user-induced so OK to be vague */ _internal_error_response(c); return NULL; } if ((itr = hostlist_iterator_create(hl)) == NULL) { _internal_error_response(c); hostlist_destroy(hl); return NULL; } while ((host = hostlist_next(itr)) != NULL) { if (!conf_node_exists(host)) { valid = FALSE; hostlist_push_host(badhl, host); } free(host); /* hostlist_next strdups returned string */ } if (!valid) { char *hosts; hosts = _xhostlist_ranged_string(badhl); _client_printf(c, CP_ERR_NOSUCHNODES, hosts); xfree (hosts); hostlist_iterator_destroy(itr); hostlist_destroy(hl); hostlist_destroy(badhl); return NULL; } hostlist_iterator_destroy(itr); hostlist_destroy(badhl); return hl; } /* * Reply to client request for list of nodes in powerman configuration. */ static void _client_query_nodes_reply(Client * c) { hostlist_t nodes = conf_getnodes(); hostlist_sort(nodes); if (c->exprange) { hostlist_iterator_t itr; char *node; if ((itr = hostlist_iterator_create(nodes)) == NULL) { _internal_error_response(c); return; } while ((node = hostlist_next(itr))) { _client_printf(c, CP_INFO_XNODES, node); free(node); /* hostlist_next strdups returned string */ } hostlist_iterator_destroy(itr); } else { char *hosts = _xhostlist_ranged_string(nodes); _client_printf(c, CP_INFO_NODES, hosts); xfree (hosts); } _client_printf(c, CP_RSP_QRY_COMPLETE); } /* * Helper for _client_query_device_reply() . * Create a hostlist string for the nodes attached to the specified device. * Caller must xfree(). */ static char *_make_pluglist_str(Device * dev) { hostlist_t hl = hostlist_create(NULL); PlugListIterator itr; Plug *plug; char *str = NULL; if (hl) { itr = pluglist_iterator_create(dev->plugs); while ((plug = pluglist_next(itr))) { assert(plug->name != NULL); hostlist_push(hl, plug->node); } pluglist_iterator_destroy(itr); hostlist_sort(hl); str = _xhostlist_ranged_string(hl); hostlist_destroy(hl); } return str; } /* * Helper for _client_query_device_reply. * Return TRUE if hostlist string in 'arg' matches any plugs on device. */ static bool _device_matches_targets(Device *dev, char *arg) { hostlist_t targ = hostlist_create(arg); PlugListIterator itr; Plug *plug; bool res = FALSE; if (targ != NULL) { itr = pluglist_iterator_create(dev->plugs); while ((plug = pluglist_next(itr))) { if (hostlist_find(targ, plug->node) != -1) { res = TRUE; break; } } pluglist_iterator_destroy(itr); hostlist_destroy(targ); } return res; } /* * Reply to client request for list of devices in powerman configuration. */ static void _client_query_device_reply(Client * c, char *arg) { List devs = dev_getdevices(); Device *dev; ListIterator itr; if (devs) { itr = list_iterator_create(devs); while ((dev = list_next(itr))) { char *nodelist; int con = dev->stat_successful_connects; if (arg && !_device_matches_targets(dev, arg)) continue; if ((nodelist = _make_pluglist_str(dev))) { _client_printf(c, CP_INFO_DEVICE, dev->name, dev->connect_state == DEV_CONNECTED ? "connected" : dev->connect_state == DEV_CONNECTING ? "connecting" : "disconnected", con > 0 ? con - 1 : 0, dev->stat_successful_actions, dev->specname, nodelist); xfree (nodelist); } } list_iterator_destroy(itr); } _client_printf(c, CP_RSP_QRY_COMPLETE); } /* * Reply to client request for plug/soft status. */ static void _client_query_status_reply(Client * c, bool error) { Arg *arg; ArgListIterator itr; assert(c->cmd != NULL); if (c->exprange) { itr = arglist_iterator_create(c->cmd->arglist); while ((arg = arglist_next(itr))) { _client_printf(c, CP_INFO_XSTATUS, arg->node, arg->state == ST_ON ? "on" : arg->state == ST_OFF ? "off" : "unknown"); } arglist_iterator_destroy(itr); } else { char *on, *off, *unknown; hostlist_t hl_on, hl_off, hl_unknown; hl_on = hostlist_create(NULL); hl_off = hostlist_create(NULL); hl_unknown = hostlist_create(NULL); itr = arglist_iterator_create(c->cmd->arglist); while ((arg = arglist_next(itr))) { switch (arg->state) { case ST_UNKNOWN: hostlist_push(hl_unknown, arg->node); break; case ST_ON: hostlist_push(hl_on, arg->node); break; case ST_OFF: hostlist_push(hl_off, arg->node); break; } } arglist_iterator_destroy(itr); hostlist_sort(hl_unknown); hostlist_sort(hl_on); hostlist_sort(hl_off); unknown = _xhostlist_ranged_string(hl_unknown); on = _xhostlist_ranged_string(hl_on); off = _xhostlist_ranged_string(hl_off); hostlist_destroy(hl_unknown); hostlist_destroy(hl_on); hostlist_destroy(hl_off); _client_printf(c, CP_INFO_STATUS, on, off, unknown); xfree (unknown); xfree (on); xfree (off); } if (error) _client_printf(c, CP_ERR_QRY_COMPLETE); else _client_printf(c, CP_RSP_QRY_COMPLETE); } /* * Reply to client request for temperature/beacon status. */ static void _client_query_status_reply_nointerp(Client * c, bool error) { Arg *arg; ArgListIterator itr; hostlist_t hl = hostlist_create(NULL); char *tmpstr; assert(c->cmd != NULL); itr = arglist_iterator_create(c->cmd->arglist); while ((arg = arglist_next(itr))) { _client_printf(c, CP_INFO_XSTATUS, arg->node, arg->val); if (!arg->val) hostlist_push(hl, arg->node); } arglist_iterator_destroy(itr); if (!hostlist_is_empty(hl)) { hostlist_sort(hl); tmpstr = _xhostlist_ranged_string(hl); _client_printf(c, CP_INFO_XSTATUS, tmpstr, "unknown"); xfree (tmpstr); } if (error) _client_printf(c, CP_ERR_QRY_COMPLETE); else _client_printf(c, CP_RSP_QRY_COMPLETE); hostlist_destroy(hl); } /* * Create Command. * On error, return an error to the client and NULL to the caller. */ static Command *_create_command(Client * c, int com, char *arg1) { Command *cmd = (Command *) xmalloc(sizeof(Command)); cmd->com = com; cmd->error = FALSE; cmd->pending = 0; cmd->hl = NULL; cmd->arglist = NULL; if (arg1) { /* Note: this can send CP_ERR_HOSTLIST to client */ cmd->hl = _hostlist_create_validated(c, arg1); if (cmd->hl == NULL) { _destroy_command(cmd); cmd = NULL; } } else cmd->hl = hostlist_copy(conf_getnodes()); if (cmd && !dev_check_actions(cmd->com, cmd->hl)) { _destroy_command(cmd); _client_printf(c, CP_ERR_UNIMPL); cmd = NULL; } /* NOTE 1: cmd->arglist has a reference count and can persist after we * unlink from it in _destroy_command(). If client goes away prematurely, * actions that write to arglist will still have valid pointers. * NOTE 2: we create arglist for all actions, rather than just query * actions, because we want to allow 'setplugstate' in any context. */ if (cmd) { cmd->arglist = arglist_create(cmd->hl); if (cmd->arglist == NULL) { _destroy_command(cmd); _internal_error_response(c); cmd = NULL; } } return cmd; } /* * Destroy a Command. */ static void _destroy_command(Command * cmd) { if (cmd->hl) hostlist_destroy(cmd->hl); if (cmd->arglist) arglist_unlink(cmd->arglist); xfree(cmd); } /* helper for _parse_input that deletes leading & trailing whitespace */ static char *_strip_whitespace(char *str) { char *head = str; char *tail = str + strlen(str) - 1; while (*head && isspace(*head)) head++; while (tail > head && isspace(*tail)) *tail-- = '\0'; return head; } /* * Parse a line of input and create a Command (and enqueue device actions) * if needed. */ static void _parse_input(Client * c, char *input) { char *str = _strip_whitespace(input); char arg1[CP_LINEMAX]; Command *cmd = NULL; memset(arg1, 0, CP_LINEMAX); /* NOTE: sscanf is safe because 'str' is guaranteed to be < CP_LINEMAX */ if (strlen(str) >= CP_LINEMAX) { _client_printf(c, CP_ERR_TOOLONG); /* error: too long */ } else if (c->cmd != NULL) { _client_printf(c, CP_ERR_CLIBUSY); /* error: busy */ return; /* no prompt */ } else if (!strncasecmp(str, CP_HELP, strlen(CP_HELP))) { _client_printf(c, CP_INFO_HELP); /* help */ _client_printf(c, CP_RSP_QRY_COMPLETE); } else if (!strncasecmp(str, CP_NODES, strlen(CP_NODES))) { _client_query_nodes_reply(c); /* nodes */ } else if (!strncasecmp(str, CP_TELEMETRY, strlen(CP_TELEMETRY))) { c->telemetry = !c->telemetry; /* telemetry */ _client_printf(c, CP_RSP_TELEMETRY, c->telemetry ? "ON" : "OFF"); } else if (!strncasecmp(str, CP_EXPRANGE, strlen(CP_EXPRANGE))) { c->exprange = !c->exprange; /* exprange */ _client_printf(c, CP_RSP_EXPRANGE, c->exprange ? "ON" : "OFF"); } else if (!strncasecmp(str, CP_QUIT, strlen(CP_QUIT))) { c->client_quit = TRUE; _client_printf(c, CP_RSP_QUIT); /* quit */ _handle_write(c); } else if (sscanf(str, CP_ON, arg1) == 1) { /* on hostlist */ cmd = _create_command(c, PM_POWER_ON, arg1); } else if (sscanf(str, CP_OFF, arg1) == 1) { /* off hostlist */ cmd = _create_command(c, PM_POWER_OFF, arg1); } else if (sscanf(str, CP_CYCLE, arg1) == 1) { /* cycle hostlist */ cmd = _create_command(c, PM_POWER_CYCLE, arg1); } else if (sscanf(str, CP_RESET, arg1) == 1) { /* reset hostlist */ cmd = _create_command(c, PM_RESET, arg1); } else if (sscanf(str, CP_BEACON_ON, arg1) == 1) { /* beacon_on hostlist */ cmd = _create_command(c, PM_BEACON_ON, arg1); } else if (sscanf(str, CP_BEACON_OFF, arg1) == 1) { /* beacon_off hostlist*/ cmd = _create_command(c, PM_BEACON_OFF, arg1); } else if (sscanf(str, CP_STATUS, arg1) == 1) { /* status [hostlist] */ cmd = _create_command(c, PM_STATUS_PLUGS, arg1); } else if (!strncasecmp(str, CP_STATUS_ALL, strlen(CP_STATUS_ALL))) { cmd = _create_command(c, PM_STATUS_PLUGS, NULL); } else if (sscanf(str, CP_TEMP, arg1) == 1) { /* temp [hostlist] */ cmd = _create_command(c, PM_STATUS_TEMP, arg1); } else if (!strncasecmp(str, CP_TEMP_ALL, strlen(CP_TEMP_ALL))) { cmd = _create_command(c, PM_STATUS_TEMP, NULL); } else if (sscanf(str, CP_BEACON, arg1) == 1) { /* beacon [hostlist] */ cmd = _create_command(c, PM_STATUS_BEACON, arg1); } else if (!strncasecmp(str, CP_BEACON_ALL, strlen(CP_BEACON_ALL))) { cmd = _create_command(c, PM_STATUS_BEACON, NULL); } else if (sscanf(str, CP_DEVICE, arg1) == 1) { /* device [hostlist] */ _client_query_device_reply(c, arg1); } else if (!strncasecmp(str, CP_DEVICE_ALL, strlen(CP_DEVICE_ALL))) { _client_query_device_reply(c, NULL); } else { /* error: unknown */ _client_printf(c, CP_ERR_UNKNOWN); } /* enqueue device actions and tie up the client if necessary */ if (cmd) { assert(cmd->hl != NULL); dbg(DBG_CLIENT, "_parse_input: enqueuing actions"); cmd->pending = dev_enqueue_actions(cmd->com, cmd->hl, _act_finish, c->telemetry ? _telemetry_printf : NULL, c->client_id, cmd->arglist); if (cmd->pending == 0) { _client_printf(c, CP_ERR_UNIMPL); _destroy_command(cmd); cmd = NULL; } assert(c->cmd == NULL); c->cmd = cmd; } /* reissue prompt if we didn't queue up any device actions */ if (cmd == NULL && !c->client_quit) _client_printf(c, CP_PROMPT); } /* * Callback for device debugging printfs (sent to client if --telemetry) */ static void _telemetry_printf(int client_id, const char *fmt, ...) { va_list ap; Client *c; char *str; if ((c = _find_client(client_id))) { va_start(ap, fmt); str = hvsprintf(fmt, ap); va_end(ap); _client_printf(c, CP_INFO_TELEMETRY, str); xfree(str); } } static void log_state_change(Client *c) { char *action = NULL; char *hosts; char *with_errors = " with errors"; int level = conf_get_plug_log_level(); if (c->cmd->com == PM_POWER_ON) action = "powered on"; if (c->cmd->com == PM_POWER_OFF) action = "powered off"; if (c->cmd->com == PM_POWER_CYCLE) action = "power cycled"; if (c->cmd->com == PM_RESET) action = "reset"; if (!action) return; hosts = _xhostlist_ranged_string(c->cmd->hl); syslog(level, "%s %s%s", action, hosts, (c->cmd->error == TRUE ? with_errors : "")); xfree(hosts); } /* * Callback for device action completion. */ static void _act_finish(int client_id, ActError acterr, const char *fmt, ...) { va_list ap; Client *c; char *str; /* if client has gone away do nothing */ if (!(c = _find_client(client_id))) return; assert(c->magic == CLI_MAGIC); assert(c->cmd != NULL); /* handle errors immediately */ if (acterr != ACT_ESUCCESS) { va_start(ap, fmt); str = hvsprintf(fmt, ap); va_end(ap); _client_printf(c, CP_INFO_ACTERROR, str); xfree(str); c->cmd->error = TRUE; /* when done say "completed with errors" */ } /* all actions have called back - return response to client */ if (--c->cmd->pending == 0) { log_state_change(c); switch (c->cmd->com) { case PM_STATUS_PLUGS: /* status */ case PM_STATUS_BEACON: /* beacon */ _client_query_status_reply(c, c->cmd->error); break; case PM_STATUS_TEMP: /* temp */ _client_query_status_reply_nointerp(c, c->cmd->error); break; case PM_POWER_ON: /* on */ case PM_POWER_OFF: /* off */ case PM_BEACON_ON: /* flash */ case PM_BEACON_OFF: /* unflash */ case PM_POWER_CYCLE: /* cycle */ case PM_RESET: /* reset */ if (c->cmd->error) _client_printf(c, CP_ERR_COM_COMPLETE); else _client_printf(c, CP_RSP_COM_COMPLETE); break; default: assert(FALSE); _internal_error_response(c); break; } /* clean up and re-prompt */ _destroy_command(c->cmd); c->cmd = NULL; _client_printf(c, CP_PROMPT); } } /* * Destroy a client. */ static void _destroy_client(Client *c) { assert(c->magic == CLI_MAGIC); if (c->fd != NO_FD) { dbg(DBG_CLIENT, "_destroy_client: closing fd %d", c->fd); if (close(c->fd) < 0) err(TRUE, "close fd %d", c->fd); c->fd = NO_FD; } if (c->ofd != NO_FD) { dbg(DBG_CLIENT, "_destroy_client: closing fd %d", c->ofd); if (close(c->ofd) < 0) err(TRUE, "close fd %d", c->ofd); c->ofd = NO_FD; } if (c->to) cbuf_destroy(c->to); if (c->from) cbuf_destroy(c->from); if (c->cmd) _destroy_command(c->cmd); if (c->ip) xfree(c->ip); if (c->host) xfree(c->host); xfree(c); if (one_client) server_done = TRUE; } /* helper for _find_client */ static int _match_client(Client *c, void *key) { return (c->client_id == *(int *) key); } /* * Test if a client still exists (by sequence). */ static Client *_find_client(int seq) { return list_find_first(cli_clients, (ListFindF) _match_client, &seq); } /* * Begin listening for clients on configured listen addresses. * This function leaves listen_fds[] (of size listen_fds_len) initialized * with each element either NO_FD or an open fd we are listening on. */ static void _listen_client(void) { int fd, error, i, opt, count; struct addrinfo hints, *res, *r; char *addr, *host, *port; char *what = "nothing"; int saved_errno = 0; List addrs; ListIterator itr; i = 0; count = 0; saved_errno = 0; addrs = conf_get_listen(); itr = list_iterator_create(addrs); while ((addr = list_next(itr))) { host = addr; if (!(port = strchr(addr, ':'))) err_exit(FALSE, "error parsing listen address: %s", addr); *port++ = '\0'; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; /* N.B.: host=NULL, ai_hints=AI_PASSIVE says "any interface", * while host="0.0.0.0" is IPv4-specific INADDR_ANY. */ if ((error = getaddrinfo(host, port, &hints, &res))) err_exit(FALSE, "getaddrinfo: %s", gai_strerror(error)); if (res == NULL) err_exit(FALSE, "listen address has no addrinfo: %s", addr); /* allocate the listen_fds array */ for (r = res; r != NULL; r = r->ai_next) listen_fds_len++; if (listen_fds == NULL) listen_fds = (int *)xmalloc(sizeof(int) * listen_fds_len); else listen_fds = (int *)xrealloc((char *)listen_fds, sizeof(int) * listen_fds_len); /* bind sockets to addresses */ for (r = res; r != NULL; r = r->ai_next, i++) { assert(i < listen_fds_len); listen_fds[i] = NO_FD; if ((fd = socket(r->ai_family, r->ai_socktype, 0)) < 0) { saved_errno = errno; what = "socket"; continue; } opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { saved_errno = errno; what = "setsockopt"; close(fd); continue; } nonblock_set(fd); if (bind(fd, r->ai_addr, r->ai_addrlen) < 0) { saved_errno = errno; what = "bind"; close(fd); continue; } if (listen(fd, LISTEN_BACKLOG) < 0) { saved_errno = errno; what = "listen"; close(fd); continue; } listen_fds[i] = fd; count++; } freeaddrinfo(res); } list_iterator_destroy(itr); /* FIXME: dodgy error handling here: As we go through the loop(s) we may * encounter errors that are interesting, however we only display the * most recent one, and then only if no bindable addresses were found. */ if (count == 0) { errno = saved_errno; err_exit(TRUE, "%s", what); } dbg(DBG_CLIENT, "listening on %d sockets", count); } static void _create_client_socket(int fd) { Client *c; struct sockaddr_storage addr; socklen_t addr_size = sizeof(addr); char hbuf[64], pbuf[6]; int error; /* create client data structure */ c = (Client *) xmalloc(sizeof(Client)); c->magic = CLI_MAGIC; c->to = NULL; c->from = NULL; c->cmd = NULL; c->client_id = _next_cli_id(); c->telemetry = FALSE; c->exprange = FALSE; c->ofd = NO_FD; c->client_quit = FALSE; c->fd = accept(fd, (struct sockaddr *)&addr, &addr_size); if (c->fd < 0){ /* client died after it initiated connect and before we could accept * Ref. Stevens, UNP p424 */ if (errno == EWOULDBLOCK || errno == ECONNABORTED || errno == EPROTO || errno == EINTR) { _destroy_client(c); err(TRUE, "_create_client: accept"); return; } err_exit(TRUE, "accept"); } if ((error = getnameinfo((struct sockaddr *)&addr, addr_size, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV))) { _destroy_client(c); err(TRUE, "_create_client: getnameinfo: %s", gai_strerror(error)); return; } c->ip = xstrdup(hbuf); c->port = strtoul(pbuf, NULL, 10); if ((error = getnameinfo((struct sockaddr *)&addr, addr_size, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD))) err(FALSE, "_create_client: getnameinfo: %s", gai_strerror(error)); else c->host = xstrdup(hbuf); #if HAVE_TCP_WRAPPERS /* get authorization from tcp wrappers */ if (conf_get_use_tcp_wrappers()) { if (!hosts_ctl(DAEMON_NAME, c->host ? c->host : STRING_UNKNOWN, c->ip, STRING_UNKNOWN)) { err(FALSE, "_create_client: tcp wrappers denies %s:%d", c->host ? c->host : c->ip, c->port); _destroy_client(c); return; } } #endif /* create I/O buffers */ c->to = cbuf_create(MIN_CLIENT_BUF, MAX_CLIENT_BUF); c->from = cbuf_create(MIN_CLIENT_BUF, MAX_CLIENT_BUF); nonblock_set(c->fd); /* append to the list of clients */ list_append(cli_clients, c); dbg(DBG_CLIENT, "connect %s:%d fd %d", c->host ? c->host : c->ip, c->port, c->fd); /* prompt the client */ _client_printf(c, CP_VERSION, PACKAGE_VERSION); _client_printf(c, CP_PROMPT); } static void _create_client_stdio(void) { Client *c; /* create client data structure */ c = (Client *) xmalloc(sizeof(Client)); c->magic = CLI_MAGIC; c->cmd = NULL; c->client_id = _next_cli_id(); c->telemetry = FALSE; c->exprange = FALSE; c->client_quit = FALSE; c->fd = STDIN_FILENO; c->ofd = STDOUT_FILENO; c->host = xstrdup("localhost"); c->ip = xstrdup("127.0.0.1"); /* XXX lies */ c->port = 0; c->to = cbuf_create(MIN_CLIENT_BUF, MAX_CLIENT_BUF); c->from = cbuf_create(MIN_CLIENT_BUF, MAX_CLIENT_BUF); nonblock_set(c->fd); nonblock_set(c->ofd); /* append to the list of clients */ list_append(cli_clients, c); /* prompt the client */ _client_printf(c, CP_VERSION, PACKAGE_VERSION); _client_printf(c, CP_PROMPT); } /* * select(2) read handler for the client */ static void _handle_read(Client * c) { int n; int dropped; assert(c->magic == CLI_MAGIC); n = cbuf_write_from_fd(c->from, c->fd, -1, &dropped); if (n < 0) { c->client_quit = TRUE; err(TRUE, "client read error"); return; } if (n == 0) { c->client_quit = TRUE; err(FALSE, "client read returned EOF"); return; } if (dropped != 0) err(FALSE, "dropped %d bytes of client input", dropped); } /* * select(2) write handler for the client */ static void _handle_write(Client * c) { int n; int ofd = c->ofd != NO_FD ? c->ofd : c->fd; assert(c->magic == CLI_MAGIC); if (c->client_quit) nonblock_clr(ofd); n = cbuf_read_to_fd(c->to, ofd, -1); if (n < 0) { err(TRUE, "write error on client"); c->client_quit = TRUE; } } static void _handle_input(Client *c) { char buf[MAX_CLIENT_BUF]; int len; while ((len = cbuf_read_line(c->from, buf, sizeof(buf), 1)) > 0) _parse_input(c, buf); if (len < 0) err(TRUE, "client cbuf_read_line returned %d", len); } /* * Prep rset/wset/maxfd for the main poll call. */ void cli_pre_poll(xpollfd_t pfd) { ListIterator itr; Client *client; int i; for (i = 0; i < listen_fds_len; i++) { if (listen_fds[i] != NO_FD) assert(listen_fds[i] >= 0); xpollfd_set(pfd, listen_fds[i], XPOLLIN); } itr = list_iterator_create(cli_clients); while ((client = list_next(itr))) { if (client->fd < 0) continue; /* always set read set bits so select will unblock if the * connection is dropped. */ xpollfd_set(pfd, client->fd, XPOLLIN); /* need to be in the write set if we are sending anything */ if (!cbuf_is_empty(client->to)) { if (client->ofd != NO_FD) xpollfd_set(pfd, client->ofd, XPOLLOUT); else xpollfd_set(pfd, client->fd, XPOLLOUT); } } list_iterator_destroy(itr); } /* * Handle any client activity (new connection or read/write). */ void cli_post_poll(xpollfd_t pfd) { ListIterator itr; Client *c; int i; for (i = 0; i < listen_fds_len; i++) { if (listen_fds[i] != NO_FD) if ((xpollfd_revents(pfd, listen_fds[i]) & XPOLLIN)) _create_client_socket(listen_fds[i]); } itr = list_iterator_create(cli_clients); while ((c = list_next(itr))) { if (c->fd != NO_FD) { short flags = xpollfd_revents(pfd, c->fd); if (flags & XPOLLERR) err(FALSE, "client poll: error"); if (flags & XPOLLHUP) err(FALSE, "client poll: hangup"); if (flags & XPOLLNVAL) err(FALSE, "client poll: fd not open"); if (flags & (XPOLLERR | XPOLLHUP | XPOLLNVAL)) goto client_dead; if ((flags & XPOLLIN)) _handle_read(c); if ((flags & XPOLLOUT)) _handle_write(c); } if (c->ofd != NO_FD) { short flags = xpollfd_revents(pfd, c->ofd); if (flags & XPOLLERR) err(FALSE, "client poll: error"); if (flags & XPOLLHUP) err(FALSE, "client poll: hangup"); if (flags & XPOLLNVAL) err(FALSE, "client poll: fd not open"); if (flags & (XPOLLERR | XPOLLHUP | XPOLLNVAL)) goto client_dead; if (c->fd == NO_FD) goto client_dead; if ((flags & XPOLLOUT)) _handle_write(c); } _handle_input(c); if (c->client_quit) goto client_dead; continue; client_dead: list_delete(itr); } list_iterator_destroy(itr); } /* hook so daemonization function can avoid closing our fd */ void cli_listen_fds(int **fdsp, int *lenp) { *fdsp = listen_fds; *lenp = listen_fds_len; } bool cli_server_done(void) { return server_done; } void cli_start(bool use_stdio, bool oc) { if (use_stdio) _create_client_stdio(); else _listen_client(); one_client = oc; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/client.h000066400000000000000000000005321415616035500170660ustar00rootroot00000000000000#ifndef PM_CLIENT_H #define PM_CLIENT_H void cli_init(void); void cli_fini(void); void cli_start(bool use_stdio, bool one_client); void cli_listen_fds(int **fds, int *len); bool cli_server_done(void); void cli_post_poll(xpollfd_t pfd); void cli_pre_poll(xpollfd_t pfd); #endif /* PM_CLIENT_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/daemon.c000066400000000000000000000062721415616035500170550ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "xtypes.h" #include "xsignal.h" #include "error.h" #include "daemon.h" static int in_fdlist(int fd, int *fds, int len) { while (--len >= 0) if (fds[len] == fd) return 1; return 0; } void daemon_init(int *skipfds, int skipfdslen, char *rundir, char *pidfile, char *logname) { int i; FILE *fp; switch (fork()) { case -1: err_exit(TRUE, "fork"); case 0: /* child */ break; default: /* parent */ exit(0); } /* 1st child continues */ /* become session leader */ if (setsid() < 0) err_exit(TRUE, "setsid"); xsignal(SIGHUP, SIG_IGN); switch(fork()) { case -1: err_exit(TRUE, "fork"); case 0: /* child */ break; default: /* parent */ exit(0); } /* 2nd child continues */ /* change working directory */ if (chdir(rundir) < 0) err_exit(TRUE, "chdir %s", rundir); /* clear our file mode creation mask */ umask(0022); /* craete pidfile */ (void)unlink(pidfile); if (!(fp = fopen(pidfile, "w"))) err_exit(TRUE, "fopen %s", pidfile); if (fprintf(fp, "%d\n", (int)getpid()) == EOF) { (void)unlink(pidfile); err_exit(TRUE, "fwrite %s", pidfile); } if (fclose(fp) == EOF) { (void)unlink(pidfile); err_exit(TRUE, "fclose %s", pidfile); } /* close fd's */ for (i = 0; i < 256; i++) { if (!in_fdlist(i, skipfds, skipfdslen)) close(i); /* ignore errors */ } /* Init syslog */ openlog(logname, LOG_NDELAY | LOG_PID, LOG_DAEMON); syslog(LOG_NOTICE, "started"); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/daemon.h000066400000000000000000000003401415616035500170500ustar00rootroot00000000000000#ifndef PM_DAEMON_H #define PM_DAEMON_H void daemon_init(int *skipfds, int skipfdslen, char *rundir, char *pidfile, char *logname); #endif /* PM_DAEMON_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device.c000066400000000000000000001336501415616035500170520ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* Primary entry points to this module are: * * initialization - dev_init() and dev_fini() are called from powermand. * dev_initial_connect(), called one time only after dev_init(), begins * connection establishment to all devices. * * parser - at config file parse time, each device is instantiated by * the dev_create() function, which puts the device on the local 'dev_devices' * list. * * client - calls dev_enqueue_actions() to cause one type of script to * run across possibly multiple devices. This function returns an "action * count", and each time an action completes, a callback is made to the client * which decrements its count. When the count reaches zero, the client knows * this module is all done operating on its behalf and can respond to the * user. * * select - the select/poll loop calls the dev_pre_poll() and dev_post_poll() * functions, the former to make a list of file descriptors which when ready * should unblock select/poll; the latter to move data between device cbufs * and the device file descriptors, to manage timeouts, and to move * device scripts along when new state develops (e.g. data in cbufs). * * FIXME: the Device type is not externally opaque as it ought to be: * - parser creates Device with dev_create() but then initializes lots * of Device fields based on parsed device specification * - client pulls out plug names & stats for --device response */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "list.h" #include "hostlist.h" #include "cbuf.h" #include "xtypes.h" #include "parse_util.h" #include "xpoll.h" #include "xmalloc.h" #include "xregex.h" #include "pluglist.h" #include "device.h" #include "arglist.h" #include "device_private.h" #include "error.h" #include "debug.h" #include "client_proto.h" #include "hprintf.h" #include "xtime.h" /* ExecCtx's are the state for the execution of a block of statements. * They are stacked on the Action (new ExecCtx pushed when executing an * inner block). */ typedef struct { List plugs; /* name(s) used for send "%s" (NULL=all) */ List block; /* List of stmts */ ListIterator stmtitr; /* next stmt in block */ Stmt *cur; /* current stmt */ PlugListIterator plugitr; /* used by foreach */ bool processing; /* flag used by stmts, ifon/ifoff */ } ExecCtx; /* Actions are queued on a device and executed one at a time. Each action * represents a request to run a particular script on a device, for a set of * plugs. Actions can be enqueued by the client or internally (e.g. login). */ #define ACT_MAGIC 0xb00bb000 #define MAX_LEVELS 2 typedef struct { int magic; int com; /* one of the PM_* above */ List exec; /* stack of ExecCtxs (outer block is first) */ ActionCB complete_fun; /* callback for action completion */ VerbosePrintf vpf_fun; /* callback for device telemetry */ int client_id; /* client id so completion can find client */ ActError errnum; /* errno for action */ struct timeval time_stamp; /* time stamp for timeouts */ struct timeval delay_start; /* time stamp for delay completion */ ArgList arglist; /* argument for query actions (list of Arg's) */ } Action; static bool _process_stmt(Device *dev, Action *act, ExecCtx *e, struct timeval *timeout); static bool _process_ifonoff(Device *dev, Action *act, ExecCtx *e); static bool _process_foreach(Device *dev, Action *act, ExecCtx *e); static bool _process_setplugstate(Device * dev, Action *act, ExecCtx *e); static bool _process_expect(Device * dev, Action *act, ExecCtx *e); static bool _process_send(Device * dev, Action *act, ExecCtx *e); static bool _process_delay(Device * dev, Action *act, ExecCtx *e, struct timeval *timeout); static int _match_name(Device * dev, void *key); static bool _handle_read(Device * dev); static bool _handle_write(Device * dev); static void _process_action(Device * dev, struct timeval *timeout); static bool _timeout(struct timeval *timestamp, struct timeval *timeout, struct timeval *timeleft); static int _get_all_script(Device * dev, int com); static int _get_ranged_script(Device * dev, int com); static int _enqueue_actions(Device * dev, int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist); static Action *_create_action(Device * dev, int com, List plugs, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist); static int _enqueue_targetted_actions(Device * dev, int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist); static char *_getregex_buf(cbuf_t b, xregex_t re, xregex_match_t xm); static bool _command_needs_device(Device * dev, hostlist_t hl); static void _enqueue_ping(Device * dev, struct timeval *timeout); static void _enqueue_login(Device *dev); static void _disconnect(Device * dev); static bool _connect(Device * dev); static bool _reconnect(Device * dev, struct timeval *timeout); static bool _time_to_reconnect(Device * dev, struct timeval *timeout); static List dev_devices = NULL; static bool short_circuit_delay = FALSE; static void _dbg_actions(Device * dev) { char tmpstr[1024]; Action *act; ListIterator itr; tmpstr[0] = '\0'; itr = list_iterator_create(dev->acts); while ((act = list_next(itr))) { snprintf(tmpstr + strlen(tmpstr), sizeof(tmpstr) - strlen(tmpstr), "%d,", act->com); } list_iterator_destroy(itr); if (strlen(tmpstr) > 0) tmpstr[strlen(tmpstr) - 1] = '\0'; /* zap trailing comma */ dbg(DBG_ACTION, "%s: %s", dev->name, tmpstr); } static void _memtrans(char *m, int len, char from, char to) { int i; for (i = 0; i < len; i++) { if (m[i] == from) m[i] = to; } } /* * Apply regular expression to the contents of a cbuf_t. * If there is a match, return (and consume) from the beginning * of the buffer to the last character of the match. * NOTE: embedded \0 chars are converted to \377 because libc regex * functions would treat these as string terminators. As a result, * \0 chars cannot be matched explicitly. * b (IN) buffer to apply regex to * re (IN) regular expression * xm (OUT) subexpression matches * RETURN String match (caller must free) or NULL if no match */ static char *_getregex_buf(cbuf_t b, xregex_t re, xregex_match_t xm) { int bytes_peeked, dropped, matchlen; char *str; int maxpeeksize = cbuf_used(b); str = xmalloc(maxpeeksize + 1); bytes_peeked = cbuf_peek(b, str, maxpeeksize); if (bytes_peeked <= 0) { /* FIXME: any -1 handling needed? */ if (bytes_peeked < 0) err(TRUE, "_getregex_buf: cbuf_peek returned %d", bytes_peeked); xfree(str); return NULL; } assert(bytes_peeked <= maxpeeksize); _memtrans(str, bytes_peeked, '\0', '\377'); str[bytes_peeked] = '\0'; if (!xregex_exec(re, str, xm)) { xfree(str); return NULL; } matchlen = xregex_match_strlen(xm); dropped = cbuf_drop(b, matchlen); if (dropped != matchlen) err((dropped < 0), "_getregex_buf: cbuf_drop returned %d", dropped); return str; } static ExecCtx *_create_exec_ctx(Device *dev, List block, List plugs) { ExecCtx *new = (ExecCtx *)xmalloc(sizeof(ExecCtx)); new->stmtitr = list_iterator_create(block); new->cur = list_next(new->stmtitr); new->block = block; new->plugs = plugs; new->plugitr = NULL; new->processing = FALSE; return new; } static void _destroy_exec_ctx(ExecCtx *e) { if (e->stmtitr != NULL) list_iterator_destroy(e->stmtitr); e->stmtitr = NULL; e->cur = NULL; if (e->plugs) list_destroy(e->plugs); e->plugs = NULL; xfree(e); } static void _rewind_action(Action *act) { ExecCtx *e; /* get back to the context for the outer block */ while ((e = list_pop(act->exec))) { if (list_is_empty(act->exec)) { list_push(act->exec, e); break; } _destroy_exec_ctx(e); } /* reset outer block iterator and current pointer */ if (e) { list_iterator_reset(e->stmtitr); e->cur = list_next(e->stmtitr); } } static Action *_create_action(Device * dev, int com, List plugs, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist) { Action *act; ExecCtx *e; dbg(DBG_ACTION, "_create_action: %d", com); act = (Action *) xmalloc(sizeof(Action)); act->magic = ACT_MAGIC; act->com = com; act->complete_fun = complete_fun; act->vpf_fun = vpf_fun; act->client_id = client_id; act->exec = list_create((ListDelF)_destroy_exec_ctx); e = _create_exec_ctx(dev, dev->scripts[act->com], plugs); list_push(act->exec, e); act->errnum = ACT_ESUCCESS; act->arglist = arglist ? arglist_link(arglist) : NULL; timerclear(&act->time_stamp); return act; } static void _destroy_action(Action * act) { assert(act->magic == ACT_MAGIC); act->magic = 0; dbg(DBG_ACTION, "_destroy_action: %d", act->com); if (act->exec) list_destroy(act->exec); act->exec = NULL; if (act->arglist) arglist_unlink(act->arglist); act->arglist = NULL; xfree(act); } /* initialize this module */ void dev_init(bool Sopt) { dev_devices = list_create((ListDelF) dev_destroy); short_circuit_delay = Sopt; } /* tear down this module */ void dev_fini(void) { list_destroy(dev_devices); } /* add a device to the device list (called from config file parser) */ void dev_add(Device * dev) { list_append(dev_devices, dev); } /* * Client needs access to device list to process "devices" query. */ List dev_getdevices(void) { return dev_devices; } /* * Test whether timeout has occurred * time_stamp (IN) * timeout (IN) * timeleft (OUT) if timeout has not occurred, put time left here * RETURN TRUE if (time_stamp + timeout > now) */ static bool _timeout(struct timeval *time_stamp, struct timeval *timeout, struct timeval *timeleft) { struct timeval now; struct timeval limit; bool result = FALSE; /* limit = time_stamp + timeout */ timeradd(time_stamp, timeout, &limit); if (gettimeofday(&now, NULL) < 0) err_exit(TRUE, "gettimeofday"); if (timercmp(&now, &limit, >=)) /* if now >= limit */ result = TRUE; if (result == FALSE) timersub(&limit, &now, timeleft); /* timeleft = limit - now */ else timerclear(timeleft); return result; } /* * If tv is less than timeout, or timeout is zero, set timeout = tv. */ void _update_timeout(struct timeval *timeout, struct timeval *tv) { if (timercmp(tv, timeout, <) || !timerisset(timeout)) *timeout = *tv; } /* * Helper for _reconnect(). * Return TRUE if OK to attempt reconnect. If FALSE, put the time left * in timeout if it is less than timeout or if timeout is zero. */ static bool _time_to_reconnect(Device * dev, struct timeval *timeout) { static int rtab[] = { 1, 2, 4, 8, 15, 30, 60 }; int max_rtab_index = sizeof(rtab) / sizeof(int) - 1; int rix = dev->retry_count - 1; struct timeval timeleft, retry; bool reconnect = TRUE; if (dev->retry_count > 0) { timerclear(&retry); retry.tv_sec = rtab[rix > max_rtab_index ? max_rtab_index : rix]; if (!_timeout(&dev->last_retry, &retry, &timeleft)) reconnect = FALSE; if (timeout && !reconnect) _update_timeout(timeout, &timeleft); } return reconnect; } static bool _connect(Device * dev) { bool connected; assert(dev->connect != NULL); if (gettimeofday(&dev->last_retry, NULL) < 0) err_exit(TRUE, "gettimeofday"); dev->retry_count++; connected = dev->connect(dev); if (connected) _enqueue_login(dev); return connected; } static bool _reconnect(Device *dev, struct timeval *timeout) { bool connected = FALSE; if (dev->connect_state != DEV_NOT_CONNECTED) _disconnect(dev); if (_time_to_reconnect(dev, timeout)) connected = _connect(dev); return connected; } /* helper for dev_check_actions/dev_enqueue_actions */ static bool _command_needs_device(Device * dev, hostlist_t hl) { bool needed = FALSE; PlugListIterator itr; Plug *plug; itr = pluglist_iterator_create(dev->plugs); while ((plug = pluglist_next(itr))) { if (plug->node != NULL && hostlist_find(hl, plug->node) != -1) { needed = TRUE; break; } } pluglist_iterator_destroy(itr); return needed; } /* * Return true if all devices targetted by hostlist implement the * specified action. */ bool dev_check_actions(int com, hostlist_t hl) { Device *dev; ListIterator itr; bool valid = TRUE; assert(hl != NULL); itr = list_iterator_create(dev_devices); while ((dev = list_next(itr))) { if (_command_needs_device(dev, hl)) { if (!dev->scripts[com] && _get_all_script(dev, com) == -1 && _get_ranged_script(dev, com) == -1) { valid = FALSE; break; } } } list_iterator_destroy(itr); return valid; } /* * Translate a command from a client into actions for devices. * Return an action count so the client be notified when all the * actions "check in". */ int dev_enqueue_actions(int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist) { Device *dev; ListIterator itr; int total = 0; itr = list_iterator_create(dev_devices); while ((dev = list_next(itr))) { int count; if (!dev->scripts[com] && _get_all_script(dev, com) == -1 && _get_ranged_script(dev, com) == -1) continue; /* unimplemented script */ if (hl && !_command_needs_device(dev, hl)) continue; /* uninvolved device */ count = _enqueue_actions(dev, com, hl, complete_fun, vpf_fun, client_id, arglist); if (count > 0 && dev->connect_state != DEV_CONNECTED) dev->retry_count = 0; /* expedite retries on this device since */ total += count; /* the user is beating on us... */ } list_iterator_destroy(itr); return total; } static int _enqueue_actions(Device * dev, int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist) { Action *act; int count = 0; switch (com) { case PM_LOG_IN: /* reset script of preempted action so it starts over */ if (!list_is_empty(dev->acts)) { act = list_peek(dev->acts); _rewind_action(act); dbg(DBG_ACTION, "resetting iterator for non-login action"); } act = _create_action(dev, com, NULL, complete_fun, vpf_fun, client_id, arglist); list_prepend(dev->acts, act); count++; break; case PM_LOG_OUT: case PM_PING: act = _create_action(dev, com, NULL, complete_fun, vpf_fun, client_id, arglist); list_append(dev->acts, act); count++; break; case PM_POWER_ON: case PM_POWER_OFF: case PM_BEACON_ON: case PM_BEACON_OFF: case PM_POWER_CYCLE: case PM_RESET: case PM_STATUS_PLUGS: case PM_STATUS_TEMP: case PM_STATUS_BEACON: count += _enqueue_targetted_actions(dev, com, hl, complete_fun, vpf_fun, client_id, arglist); break; default: assert(FALSE); } return count; } /* return "all" version of script if defined else -1 */ static int _get_all_script(Device * dev, int com) { int new = -1; switch (com) { case PM_POWER_ON: if (dev->scripts[PM_POWER_ON_ALL]) new = PM_POWER_ON_ALL; break; case PM_POWER_OFF: if (dev->scripts[PM_POWER_OFF_ALL]) new = PM_POWER_OFF_ALL; break; case PM_POWER_CYCLE: if (dev->scripts[PM_POWER_CYCLE_ALL]) new = PM_POWER_CYCLE_ALL; break; case PM_RESET: if (dev->scripts[PM_RESET_ALL]) new = PM_RESET_ALL; break; case PM_STATUS_PLUGS: if (dev->scripts[PM_STATUS_PLUGS_ALL]) new = PM_STATUS_PLUGS_ALL; break; case PM_STATUS_TEMP: if (dev->scripts[PM_STATUS_TEMP_ALL]) new = PM_STATUS_TEMP_ALL; break; case PM_STATUS_BEACON: if (dev->scripts[PM_STATUS_BEACON_ALL]) new = PM_STATUS_BEACON_ALL; break; default: break; } return new; } /* return "ranged" version of script if defined else -1 */ static int _get_ranged_script(Device * dev, int com) { int new = -1; switch (com) { case PM_POWER_ON: if (dev->scripts[PM_POWER_ON_RANGED]) new = PM_POWER_ON_RANGED; break; case PM_POWER_OFF: if (dev->scripts[PM_POWER_OFF_RANGED]) new = PM_POWER_OFF_RANGED; break; case PM_POWER_CYCLE: if (dev->scripts[PM_POWER_CYCLE_RANGED]) new = PM_POWER_CYCLE_RANGED; break; case PM_RESET: if (dev->scripts[PM_RESET_RANGED]) new = PM_RESET_RANGED; break; case PM_BEACON_ON: if (dev->scripts[PM_BEACON_ON_RANGED]) new = PM_BEACON_ON_RANGED; break; case PM_BEACON_OFF: if (dev->scripts[PM_BEACON_OFF_RANGED]) new = PM_BEACON_OFF_RANGED; break; default: break; } return new; } static bool _is_query_action(int com) { switch (com) { case PM_STATUS_PLUGS: case PM_STATUS_PLUGS_ALL: case PM_STATUS_TEMP: case PM_STATUS_TEMP_ALL: case PM_STATUS_BEACON: case PM_STATUS_BEACON_ALL: return TRUE; default: return FALSE; } /*NOTREACHED*/ } static int _enqueue_targetted_actions(Device * dev, int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist) { List new_acts = list_create((ListDelF) _destroy_action); bool all = TRUE; Plug *plug; PlugListIterator itr; int count = 0; Action *act; List ranged_plugs = NULL; int used_ranged_plugs = 0; assert(hl != NULL); if (!(ranged_plugs = list_create((ListDelF)NULL))) goto cleanup; itr = pluglist_iterator_create(dev->plugs); while ((plug = pluglist_next(itr))) { /* antisocial to gratuitously turn on/off unused plug */ if (plug->node == NULL) { all = FALSE; continue; } /* check if node name for plug matches the target */ if (hostlist_find(hl, plug->node) == -1) { all = FALSE; continue; } if (!list_append(ranged_plugs, plug)) goto cleanup; /* append action to 'new_acts' */ if (dev->scripts[com] != NULL) { /* maybe we only have _ALL... */ List plugs; if (!(plugs = list_create((ListDelF)NULL))) goto cleanup; if (!list_append(plugs, plug)) { list_destroy(plugs); goto cleanup; } act = _create_action(dev, com, plugs, complete_fun, vpf_fun, client_id, arglist); list_append(new_acts, act); } } pluglist_iterator_destroy(itr); /* Try _all version of script. */ if (all || _is_query_action(com)) { int ncom = _get_all_script(dev, com); if (ncom != -1) { act = _create_action(dev, ncom, NULL, complete_fun, vpf_fun, client_id, arglist); list_append(dev->acts, act); count++; } } /* _all didn't work, try _ranged. */ if (count == 0) { int ncom = _get_ranged_script(dev, com); if (ncom != -1) { act = _create_action(dev, ncom, ranged_plugs, complete_fun, vpf_fun, client_id, arglist); list_append(dev->acts, act); used_ranged_plugs++; count++; } } /* _all and _ranged didn't work, try singlet. */ if (count == 0) { while ((act = list_pop(new_acts))) { list_append(dev->acts, act); count++; } } cleanup: list_destroy(new_acts); if (!used_ranged_plugs) list_destroy(ranged_plugs); return count; } /* Called upon success of connect or finish_connect device methods. */ static void _enqueue_login(Device *dev) { _enqueue_actions(dev, PM_LOG_IN, NULL, NULL, NULL, 0, NULL); } static void _disconnect(Device * dev) { Action *act; assert(dev->disconnect != NULL); dev->disconnect(dev); /* empty buffers */ cbuf_flush(dev->from); cbuf_flush(dev->to); /* update state */ dev->connect_state = DEV_NOT_CONNECTED; dev->logged_in = FALSE; /* delete PM_LOG_IN action queued for this device, if any */ if (((act = list_peek(dev->acts)) != NULL) && act->com == PM_LOG_IN) _destroy_action(list_dequeue(dev->acts)); } static void _act_completion(Action *act, Device *dev) { assert(act->complete_fun != NULL); switch (act->errnum) { case ACT_ECONNECTTIMEOUT: act->complete_fun(act->client_id, act->errnum, "%s: connect timeout", dev->name); break; case ACT_ELOGINTIMEOUT: act->complete_fun(act->client_id, act->errnum, "%s: login timeout", dev->name); break; case ACT_EEXPFAIL: act->complete_fun(act->client_id, act->errnum, "%s: action timed out waiting for expected response", dev->name); break; case ACT_EABORT: act->complete_fun(act->client_id, act->errnum, "%s: action aborted due to previous action timeout", dev->name); break; case ACT_ESUCCESS: act->complete_fun(act->client_id, act->errnum, NULL); break; } } /* * Process the script for the current action for this device. * Update timeout and return if one of the script elements stalls. * Start the next action if we complete this one. */ static void _process_action(Device * dev, struct timeval *timeout) { bool stalled = FALSE; Action *act; while ((act = list_peek(dev->acts)) && !stalled) { struct timeval timeleft; ExecCtx *e = list_peek(act->exec); assert(e != NULL); dbg(DBG_ACTION, "_process_action: processing action %d", act->com); _dbg_actions(dev); /* initialize timeout (action is brand new) */ if (!timerisset(&act->time_stamp)) if (gettimeofday(&act->time_stamp, NULL) < 0) err_exit(TRUE, "gettimeofday"); /* timeout exceeded? */ if (_timeout(&act->time_stamp, &dev->timeout, &timeleft)) { if (!(dev->connect_state == DEV_CONNECTED)) act->errnum = ACT_ECONNECTTIMEOUT; else if (!dev->logged_in) { act->errnum = ACT_ELOGINTIMEOUT; } else act->errnum = ACT_EEXPFAIL; if (act->vpf_fun) { static char mem[MAX_DEV_BUF]; int len = cbuf_peek(dev->from, mem, MAX_DEV_BUF); char *memstr = dbg_memstr(mem, len); if (!(dev->connect_state == DEV_CONNECTED)) act->vpf_fun(act->client_id, "connect(%s): timeout", dev->name); else act->vpf_fun(act->client_id, "recv(%s): '%s'", dev->name, memstr); xfree(memstr); } /* not connected but timeout not yet exceeded */ } else if (!(dev->connect_state == DEV_CONNECTED)) { stalled = TRUE; /* not connnected */ /* connected - process statements */ } else { /* If a statement has an inner block to execute, it pushes a new * ExecCtx onto the action's exec stack and returns. We notice * the top of the exec stack has changed and try to exec the next * stmt (now of the new context) and so on. When the inner block * is done, the stack is popped and the "current" stmt is back to * the one that initiated the inner block. */ do { e = list_peek(act->exec); stalled = !_process_stmt(dev, act, e, timeout); } while (e != list_peek(act->exec)); } /* stalled - update timeout for select */ if (stalled) { _update_timeout(timeout, &timeleft); /* most recently attempted stmt completed successfully */ } else if (act->errnum == ACT_ESUCCESS) { e->cur = list_next(e->stmtitr); /* next stmt this block */ if (!e->cur) { /* ...or new block */ ExecCtx *e2 = list_pop(act->exec); assert(e2 == e); _destroy_exec_ctx(e2); e = list_peek(act->exec); } /* completed action successfully! */ if (e == NULL) { if (act->com == PM_LOG_IN) dev->logged_in = TRUE; if (act->complete_fun) _act_completion(act, dev); _destroy_action(list_dequeue(dev->acts)); dev->stat_successful_actions++; } /* most recently attempted stmt completed with error */ } else { ActError res = act->errnum; /* save for ref after _destroy_action */ if (act->complete_fun) _act_completion(act, dev); _destroy_action(list_dequeue(dev->acts)); /* if one action failed, abort the rest in the device queue * in preparation for reconnect. */ while ((act = list_dequeue(dev->acts)) != NULL) { act->errnum = (res == ACT_EEXPFAIL ? ACT_EABORT : res); if (act->complete_fun) _act_completion(act, dev); _destroy_action(act); } /* reconnect/login if expect timed out */ if ((dev->connect_state == DEV_CONNECTED)) { dbg(DBG_DEVICE, "_process_action: disconnecting due to error"); _reconnect(dev, timeout); break; } } } /* while loop */ } bool _process_stmt(Device *dev, Action *act, ExecCtx *e, struct timeval *timeout) { bool finished = 0; switch (e->cur->type) { case STMT_EXPECT: finished = _process_expect(dev, act, e); break; case STMT_SEND: finished = _process_send(dev, act, e); break; case STMT_SETPLUGSTATE: finished = _process_setplugstate(dev, act, e); break; case STMT_DELAY: finished = _process_delay(dev, act, e, timeout); break; case STMT_FOREACHPLUG: case STMT_FOREACHNODE: finished = _process_foreach(dev, act, e); break; case STMT_IFON: case STMT_IFOFF: finished = _process_ifonoff(dev, act, e); break; } return finished; } static bool _process_foreach(Device *dev, Action *act, ExecCtx *e) { bool finished = TRUE; ExecCtx *new; Plug *plug = NULL; /* we store a plug iterator in the ExecCtx */ if (e->plugitr == NULL) e->plugitr = pluglist_iterator_create(dev->plugs); /* Each time the inner block is executed, its argument will be * a new plug name. Pick that up here. */ if (e->cur->type == STMT_FOREACHPLUG) { plug = pluglist_next(e->plugitr); } else if (e->cur->type == STMT_FOREACHNODE) { do { plug = pluglist_next(e->plugitr); } while (plug && plug->node == NULL); } else { assert(0); } /* plug list not exhausted? start a new execution context for this block */ if (plug != NULL) { List plugs; if (!(plugs = list_create((ListDelF)NULL))) goto cleanup; if (!list_append(plugs, plug)) { list_destroy(plugs); goto cleanup; } new = _create_exec_ctx(dev, e->cur->u.foreach.stmts, plugs); list_push(act->exec, new); } else { pluglist_iterator_destroy(e->plugitr); e->plugitr = NULL; } /* we won't be called again if we don't push a new context */ cleanup: return finished; } static bool _process_ifonoff(Device *dev, Action *act, ExecCtx *e) { bool finished = TRUE; if (e->processing) { /* if returning from subblock, we are done */ e->processing = FALSE; } else { InterpState state = ST_UNKNOWN; bool condition = FALSE; ExecCtx *new; if (e->plugs && list_count(e->plugs) > 0) { Plug *plug = list_peek(e->plugs); Arg *arg = arglist_find(act->arglist, plug->node); if (arg) state = arg->state; } if (e->cur->type == STMT_IFON && state == ST_ON) condition = TRUE; else if (e->cur->type == STMT_IFOFF && state == ST_OFF) condition = TRUE; else if (state == ST_UNKNOWN) { act->errnum = ACT_EEXPFAIL; /* FIXME */ } /* condition met? start a new execution context for this block */ if (condition) { List plugs; ListIterator itr; Plug *plug; e->processing = TRUE; /* achu: previous context's plugs could get destroy, * so must copy plugs to a new list. */ if (!(plugs = list_create((ListDelF)NULL))) goto cleanup; if (!(itr = list_iterator_create(e->plugs))) { list_destroy(plugs); goto cleanup; } while ((plug = list_next(itr))) { if (!list_append(plugs, plug)) { list_destroy(plugs); list_iterator_destroy(itr); goto cleanup; } } new = _create_exec_ctx(dev, e->cur->u.ifonoff.stmts, plugs); list_push(act->exec, new); list_iterator_destroy(itr); } } cleanup: return finished; } static bool _process_setplugstate(Device *dev, Action *act, ExecCtx *e) { bool finished = TRUE; char *plug_name = NULL; /* * Usage: setplugstate [plug] status [interps] * plug can be literal plug name, or regex match, or omitted, * (implying target plug name). */ if (e->cur->u.setplugstate.plug_name) /* literal */ plug_name = xstrdup(e->cur->u.setplugstate.plug_name); if (!plug_name) /* regex match */ plug_name = xregex_match_sub_strdup(dev->xmatch, e->cur->u.setplugstate.plug_mp); if (!plug_name && (e->plugs && list_count(e->plugs) > 0)) { Plug *plug = list_peek(e->plugs); if (plug->name) plug_name = xstrdup(plug->name);/* use action target */ } /* if no plug name, do nothing */ if (plug_name) { char *str = xregex_match_sub_strdup(dev->xmatch, e->cur->u.setplugstate.stat_mp); Plug *plug = pluglist_find(dev->plugs, plug_name); if (str && plug && plug->node) { InterpState state = ST_UNKNOWN; ListIterator itr; Interp *i; Arg *arg; itr = list_iterator_create(e->cur->u.setplugstate.interps); while ((i = list_next(itr))) { if (xregex_exec(i->re, str, NULL)) { state = i->state; break; } } list_iterator_destroy(itr); if ((arg = arglist_find(act->arglist, plug->node))) { arg->state = state; if (arg->val) xfree(arg->val); arg->val = xstrdup(str); } } if (str) xfree(str); /* if no match, do nothing */ xfree(plug_name); } return finished; } /* return TRUE if expect is finished */ static bool _process_expect(Device *dev, Action *act, ExecCtx *e) { bool finished = FALSE; char *str; xregex_match_recycle(dev->xmatch); if ((str = _getregex_buf(dev->from, e->cur->u.expect.exp, dev->xmatch))) { if (act->vpf_fun) { char *matchstr = xregex_match_strdup(dev->xmatch); char *memstr = dbg_memstr(matchstr, strlen(matchstr)); act->vpf_fun(act->client_id, "recv(%s): '%s'", dev->name, memstr); xfree(memstr); xfree(matchstr); } xfree(str); finished = TRUE; } return finished; } /* * Wrapped hostlist_ranged_string() with internal buffer allocation, * which caller must xfree(). */ #define CHUNKSIZE 80 static char *_xhostlist_ranged_string(hostlist_t hl) { int size = 0; char *str = NULL; do { str = (size == 0) ? xmalloc(CHUNKSIZE) : xrealloc(str, size+CHUNKSIZE); size += CHUNKSIZE; } while (hostlist_ranged_string(hl, size, str) == -1); return str; } static bool _process_send(Device *dev, Action *act, ExecCtx *e) { bool finished = FALSE; /* first time through? */ if (!e->processing) { int dropped = 0; int written; char *str = NULL; if (e->plugs && list_count(e->plugs) > 0) { if (list_count(e->plugs) > 1) { char *names; ListIterator itr = NULL; hostlist_t hl = NULL; Plug *plug; if (!(hl = hostlist_create(NULL))) { err(TRUE, "_process_send(%s): hostlist_create", dev->name); goto range_cleanup; } if (!(itr = list_iterator_create(e->plugs))) { err(TRUE, "_process_send(%s): list_iterator_create", dev->name); goto range_cleanup; } while ((plug = list_next(itr))) { if (!hostlist_push(hl, plug->name)) { err(TRUE, "_process_send(%s): hostlist_push", dev->name); goto range_cleanup; } } hostlist_sort(hl); names = _xhostlist_ranged_string(hl); str = hsprintf(e->cur->u.send.fmt, names); xfree (names); range_cleanup: if (itr) list_iterator_destroy(itr); if (hl) hostlist_destroy(hl); } else { Plug *plug = list_peek(e->plugs); str = hsprintf(e->cur->u.send.fmt, (plug->name ? plug->name : "[unresolved]")); } } else str = hsprintf(e->cur->u.send.fmt, NULL); if (str) { written = cbuf_write(dev->to, str, strlen(str), &dropped); if (written < 0) err(TRUE, "_process_send(%s): cbuf_write returned %d", dev->name, written); else if (dropped > 0) err(FALSE, "_process_send(%s): buffer overrun, %d dropped", dev->name, dropped); else { char *memstr = dbg_memstr(str, strlen(str)); if (act->vpf_fun) act->vpf_fun(act->client_id, "send(%s): '%s'", dev->name, memstr); xfree(memstr); } assert(written < 0 || (dropped == strlen(str) - written)); } e->processing = TRUE; xfree(str); } if (cbuf_is_empty(dev->to)) { /* finished! */ e->processing = FALSE; finished = TRUE; } return finished; } /* return TRUE if delay is finished */ static bool _process_delay(Device *dev, Action *act, ExecCtx *e, struct timeval *timeout) { bool finished = FALSE; struct timeval delay, timeleft; delay = e->cur->u.delay.tv; /* first time */ if (!e->processing) { if (act->vpf_fun) act->vpf_fun(act->client_id, "delay(%s): %ld.%-6.6ld", dev->name, delay.tv_sec, delay.tv_usec); e->processing = TRUE; if (gettimeofday(&act->delay_start, NULL) < 0) err_exit(TRUE, "gettimeofday"); } /* timeout expired? */ if (short_circuit_delay || _timeout(&act->delay_start, &delay, &timeleft)) { e->processing = FALSE; finished = TRUE; } else _update_timeout(timeout, &timeleft); return finished; } Device *dev_create(const char *name) { Device *dev; int i; dev = (Device *) xmalloc(sizeof(Device)); dev->magic = DEV_MAGIC; dev->name = xstrdup(name); dev->connect_state = DEV_NOT_CONNECTED; dev->fd = NO_FD; dev->acts = list_create((ListDelF) _destroy_action); dev->xmatch = xregex_match_create(MAX_MATCH_POS); dev->data = NULL; timerclear(&dev->timeout); timerclear(&dev->last_retry); timerclear(&dev->last_ping); timerclear(&dev->ping_period); dev->to = cbuf_create(MIN_DEV_BUF, MAX_DEV_BUF); dev->from = cbuf_create(MIN_DEV_BUF, MAX_DEV_BUF); for (i = 0; i < NUM_SCRIPTS; i++) dev->scripts[i] = NULL; dev->plugs = NULL; dev->retry_count = 0; dev->stat_successful_connects = 0; dev->stat_successful_actions = 0; return dev; } /* helper for dev_findbyname */ static int _match_name(Device * dev, void *key) { return (strcmp(dev->name, (char *) key) == 0); } Device *dev_findbyname(char *name) { return list_find_first(dev_devices, (ListFindF) _match_name, name); } void dev_destroy(Device * dev) { int i; assert(dev->magic == DEV_MAGIC); dev->magic = 0; if (dev->connect_state == DEV_CONNECTED) dev->disconnect(dev); xfree(dev->name); xfree(dev->specname); if (dev->data) { assert(dev->destroy != NULL); dev->destroy(dev->data); } list_destroy(dev->acts); if (dev->plugs) pluglist_destroy(dev->plugs); for (i = 0; i < NUM_SCRIPTS; i++) if (dev->scripts[i] != NULL) list_destroy(dev->scripts[i]); cbuf_destroy(dev->to); cbuf_destroy(dev->from); xregex_match_destroy(dev->xmatch); xfree(dev); } static void _enqueue_ping(Device * dev, struct timeval *timeout) { struct timeval timeleft; if (dev->scripts[PM_PING] != NULL && timerisset(&dev->ping_period)) { if (_timeout(&dev->last_ping, &dev->ping_period, &timeleft)) { _enqueue_actions(dev, PM_PING, NULL, NULL, NULL, 0, NULL); if (gettimeofday(&dev->last_ping, NULL) < 0) err_exit(TRUE, "gettimeofday"); dbg(DBG_ACTION, "%s: enqeuuing ping", dev->name); } else _update_timeout(timeout, &timeleft); } } /* * Called prior to the select loop to initiate connects to all devices. */ void dev_initial_connect(void) { Device *dev; ListIterator itr; itr = list_iterator_create(dev_devices); while ((dev = list_next(itr))) { assert(dev->connect_state == DEV_NOT_CONNECTED); _connect(dev); } list_iterator_destroy(itr); } /* * Select says device is ready for reading. */ static bool _handle_read(Device * dev) { int n; int dropped; assert(dev->magic == DEV_MAGIC); n = cbuf_write_from_fd(dev->from, dev->fd, -1, &dropped); if (n < 0) { err(TRUE, "read error on %s", dev->name); goto err; } if (n == 0) { dbg(DBG_DEVICE, "read returned EOF on %s", dev->name); goto err; } if (dropped > 0) err(FALSE, "%s lost %d chars due to buffer wrap", dev->name, dropped); return FALSE; err: return TRUE; } /* * Select says device is ready for writing. */ static bool _handle_write(Device * dev) { int n; assert(dev->magic == DEV_MAGIC); n = cbuf_read_to_fd(dev->to, dev->fd, -1); if (n < 0) { err(TRUE, "write error on %s", dev->name); goto err; } if (n == 0) { err(FALSE, "write sent no data on %s", dev->name); goto err; } return FALSE; err: return TRUE; } /* One of the poll bits is set for the device - handle it! */ static bool _handle_ready_device(Device *dev, short flags) { assert(dev->connect_state != DEV_NOT_CONNECTED); assert(dev->fd != NO_FD); /* error cases (won't get here with select - only poll) */ if (flags & XPOLLHUP) { err(FALSE, "%s: poll: hangup", dev->name); goto ioerr; } if (flags & XPOLLERR) { err(FALSE, "%s: poll: error", dev->name); goto ioerr; } if (flags & XPOLLNVAL) { err(FALSE, "%s: poll: fd not open", dev->name); goto ioerr; } /* ready for writing */ if (flags & XPOLLOUT) { if (dev->connect_state == DEV_CONNECTING) { assert(dev->finish_connect != NULL); if (!dev->finish_connect(dev)) goto ioerr; if (dev->connect_state == DEV_CONNECTED) _enqueue_login(dev); /* enqueue login if connected */ goto success; /* don't want to test read bit */ } else { assert(dev->connect_state == DEV_CONNECTED); if (_handle_write(dev)) goto ioerr; } } /* ready for reading */ if (flags & XPOLLIN) { if (_handle_read(dev)) goto ioerr; if (dev->preprocess != NULL) dev->preprocess(dev); /* preprocess input, e.g. telnet escapes */ } success: return FALSE; ioerr: return TRUE; } /* * Called before poll to ready pfd. */ void dev_pre_poll(xpollfd_t pfd) { Device *dev; ListIterator itr; itr = list_iterator_create(dev_devices); while ((dev = list_next(itr))) { short flags = 0; if (dev->fd < 0) continue; /* always set read set bits so select will unblock if the * connection is dropped. */ flags |= XPOLLIN; /* need to be in the write set if we are sending anything */ if (dev->connect_state == DEV_CONNECTED) { if (!cbuf_is_empty(dev->to)) flags |= XPOLLOUT; } /* descriptor will become writable after a connect */ if (dev->connect_state == DEV_CONNECTING) flags |= XPOLLOUT; xpollfd_set(pfd, dev->fd, flags); } list_iterator_destroy(itr); } /* * Called after select to process ready file descriptors, timeouts, etc. */ void dev_post_poll(xpollfd_t pfd, struct timeval *timeout) { Device *dev; ListIterator itr; itr = list_iterator_create(dev_devices); while ((dev = list_next(itr))) { short flags = dev->fd != NO_FD ? xpollfd_revents(pfd, dev->fd) : 0; bool ioerr = FALSE; /* A device is "ready", e.g. it can be read/written or has an error */ if (flags) ioerr = _handle_ready_device(dev, flags); /* Either initiate reconnect or recalculate timeout (for backoff) * so poll will unblock then. If successful, _reconnect() * will enqueue a login action which will need processing below. */ if (ioerr || dev->connect_state == DEV_NOT_CONNECTED) _reconnect(dev, timeout); /* can update dev->connect_state */ /* If we are periodically "pinging" this device, we may need to * enqueue a ping action, or update the timeout so poll will * unblock when it is time to enqueue one. */ if (dev->connect_state == DEV_CONNECTED) _enqueue_ping(dev, timeout); /* If any actions are enqueued, process them. This is state machine * activity and I/O to/from cbufs, not device I/O. Update timeout so * poll will unblock to handle non-responsive devices, or processing * of scripted delays. Note that we are not necessarily connected * to the device - users may enqueue actions on an unconnected device, * which expedites a reconnect; if the reconnect then times out, * we have to time out the actions (e.g. tell the user). */ _process_action(dev, timeout); } list_iterator_destroy(itr); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device.h000066400000000000000000000004521415616035500170500ustar00rootroot00000000000000#ifndef PM_DEVICE_H #define PM_DEVICE_H void dev_init(bool short_circuit_delay); void dev_fini(void); void dev_initial_connect(void); void dev_pre_poll(xpollfd_t pfd); void dev_post_poll(xpollfd_t pfd, struct timeval *tv); #endif /* PM_DEVICE_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_pipe.c000066400000000000000000000107711415616035500200650ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* * Implement connect/disconnect device methods for pipes. * Well it started out as a pipe, now actually it's a "coprocess" on a pty. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "hostlist.h" #include "list.h" #include "cbuf.h" #include "xtypes.h" #include "parse_util.h" #include "xmalloc.h" #include "xpoll.h" #include "pluglist.h" #include "arglist.h" #include "xregex.h" #include "device_private.h" #include "device_pipe.h" #include "error.h" #include "debug.h" #include "argv.h" #include "xpty.h" typedef struct { char **argv; pid_t cpid; } PipeDev; /* Create "pipe device" data struct. * cmdline would normally look something like "/usr/bin/conman -j -Q bay0 |&" * (Korn shell style "coprocess" syntax) */ void *pipe_create(char *cmdline, char *flags) { PipeDev *pd = (PipeDev *)xmalloc(sizeof(PipeDev)); pd->argv = argv_create(cmdline, "|&"); pd->cpid = -1; return (void *)pd; } /* Destroy pipe device data struct. */ void pipe_destroy(void *data) { PipeDev *pd = (PipeDev *)data; argv_destroy(pd->argv); xfree(pd); } /* Start the coprocess using forkpty(3). */ bool pipe_connect(Device * dev) { int fd; pid_t pid; PipeDev *pd = (PipeDev *)dev->data; char ptyname[64]; assert(dev->connect_state == DEV_NOT_CONNECTED); assert(dev->fd == NO_FD); pid = xforkpty(&fd, ptyname, sizeof(ptyname)); if (pid < 0) { err_exit(TRUE, "_pipe_connect(%s): forkpty error", dev->name); } else if (pid == 0) { /* child */ xcfmakeraw(STDIN_FILENO); execv(pd->argv[0], pd->argv); err_exit(TRUE, "exec %s", pd->argv[0]); } else { /* parent */ nonblock_set(fd); dev->fd = fd; dev->connect_state = DEV_CONNECTED; dev->stat_successful_connects++; pd->cpid = pid; err(FALSE, "_pipe_connect(%s): opened on %s", dev->name, ptyname); } return (dev->connect_state == DEV_CONNECTED); } /* * Close down the pipes/pty. */ void pipe_disconnect(Device * dev) { PipeDev *pd = (PipeDev *)dev->data; assert(dev->connect_state == DEV_CONNECTED); dbg(DBG_DEVICE, "_pipe_disconnect: %s on fd %d", dev->name, dev->fd); if (dev->fd >= 0) { if (close(dev->fd) < 0) err(TRUE, "_pipe_disconnect: %s close fd %d", dev->name, dev->fd); dev->fd = NO_FD; } /* reap child */ if (pd->cpid > 0) { int wstat; kill(pd->cpid, SIGTERM); /* ignore errors */ if (waitpid(pd->cpid, &wstat, 0) < 0) err(TRUE, "_pipe_disconnect(%s): wait", dev->name); if (WIFEXITED(wstat)) { err(FALSE, "_pipe_disconnect(%s): %s exited with status %d", dev->name, pd->argv[0], WEXITSTATUS(wstat)); } else if (WIFSIGNALED(wstat)) { err(FALSE, "_pipe_disconnect(%s): %s terminated with signal %d", dev->name, pd->argv[0], WTERMSIG(wstat)); } else { err(FALSE, "_pipe_disconnect(%s): %s terminated", dev->name, pd->argv[0]); } pd->cpid = -1; } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_pipe.h000066400000000000000000000004241415616035500200640ustar00rootroot00000000000000#ifndef PM_DEVICE_PIPE_H #define PM_DEVICE_PIPE_H bool pipe_connect(Device * dev); void pipe_disconnect(Device * dev); void *pipe_create(char *cmdline, char *flags); void pipe_destroy(void *data); #endif /* PM_DEVICE_PIPE_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_private.h000066400000000000000000000116221415616035500206030ustar00rootroot00000000000000#ifndef PM_DEVICE_PRIVATE_H #define PM_DEVICE_PRIVATE_H #define NO_FD (-1) /* Indices into script array */ #define PM_LOG_IN 0 #define PM_LOG_OUT 1 #define PM_STATUS_PLUGS 2 #define PM_STATUS_PLUGS_ALL 3 /*4*/ /*5*/ #define PM_PING 6 #define PM_POWER_ON 7 #define PM_POWER_ON_RANGED 8 #define PM_POWER_ON_ALL 9 #define PM_POWER_OFF 10 #define PM_POWER_OFF_RANGED 11 #define PM_POWER_OFF_ALL 12 #define PM_POWER_CYCLE 13 #define PM_POWER_CYCLE_RANGED 14 #define PM_POWER_CYCLE_ALL 15 #define PM_RESET 16 #define PM_RESET_RANGED 17 #define PM_RESET_ALL 18 #define PM_STATUS_TEMP 19 #define PM_STATUS_TEMP_ALL 20 #define PM_STATUS_BEACON 21 #define PM_STATUS_BEACON_ALL 22 #define PM_BEACON_ON 23 #define PM_BEACON_ON_RANGED 24 #define PM_BEACON_OFF 25 #define PM_BEACON_OFF_RANGED 26 #define PM_RESOLVE 27 #define NUM_SCRIPTS 28 /* count of scripts above */ #define MAX_MATCH_POS 20 #define INTERP_MAGIC 0x13434550 typedef struct { int magic; InterpState state; char *str; xregex_t re; } Interp; /* * A Script is a list of Stmts. */ typedef enum { STMT_SEND, STMT_EXPECT, STMT_SETPLUGSTATE, STMT_DELAY, STMT_FOREACHPLUG, STMT_FOREACHNODE, STMT_IFOFF, STMT_IFON, } StmtType; typedef struct { StmtType type; union { struct { /* SEND */ char *fmt; /* printf(fmt, ...) style format string */ } send; struct { /* EXPECT */ xregex_t exp; /* compiled regex */ } expect; struct { /* SETPLUGSTATE (regexs refer to prev expect) */ char *plug_name; /* plug name if literally specified */ int plug_mp; /* regex subexp match pos of plug name if not */ int stat_mp; /* regex subexp match pos of plug status */ List interps; /* list of possible interpretations */ } setplugstate; struct { /* DELAY */ struct timeval tv; /* delay at this point in the script */ } delay; struct { /* FOREACHPLUG | FOREACHNODE */ List stmts; /* list of statements to exec in a loop */ } foreach; struct { /* IFON | IFOFF */ List stmts; /* list of statements to exec conditionally */ } ifonoff; } u; } Stmt; typedef List Script; /* * Device */ typedef enum { DEV_NOT_CONNECTED, DEV_CONNECTING, DEV_CONNECTED } ConnectState; #define DEV_MAGIC 0xbeefb111 typedef struct _device { int magic; char *name; /* name of device */ char *specname; /* name of specification, e.g. "icebox3" */ ConnectState connect_state; /* is device connected/open? */ bool logged_in; /* TRUE if login script has run successfully */ xregex_match_t xmatch; /* cache regex matches for future $N ref */ int fd; /* socket, serial device, or pty */ List acts; /* queue of Actions */ struct timeval timeout; /* configurable device timeout */ cbuf_t to; /* buffer -> device */ cbuf_t from; /* buffer <- device */ PlugList plugs; /* list of Plugs (node name <-> plug name) */ Script scripts[NUM_SCRIPTS]; /* array of scripts */ struct timeval last_retry; /* time of last reconnect retry */ int retry_count; /* number of retries attempted */ struct timeval last_ping; /* time of last ping (if any) */ struct timeval ping_period; /* configurable ping period (0.0 = none) */ int stat_successful_connects; int stat_successful_actions; /* network (e.g. tcp/serial)-specific methods */ bool (*connect)(struct _device *dev); bool (*finish_connect)(struct _device *dev); void (*preprocess)(struct _device *dev); void (*disconnect)(struct _device *dev); void (*destroy)(void *data); void *data; } Device; typedef enum { ACT_ESUCCESS, ACT_EEXPFAIL, ACT_EABORT, ACT_ECONNECTTIMEOUT, ACT_ELOGINTIMEOUT } ActError; typedef void (*ActionCB) (int client_id, ActError acterr, const char *fmt, ...); typedef void (*VerbosePrintf) (int client_id, const char *fmt, ...); #define MIN_DEV_BUF 1024 #define MAX_DEV_BUF 1024*64 void dev_add(Device * dev); int dev_enqueue_actions(int com, hostlist_t hl, ActionCB complete_fun, VerbosePrintf vpf_fun, int client_id, ArgList arglist); bool dev_check_actions(int com, hostlist_t hl); Device *dev_create(const char *name); void dev_destroy(Device * dev); Device *dev_findbyname(char *name); List dev_getdevices(void); #endif /* PM_DEVICE_PRIVATE_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_serial.c000066400000000000000000000163031415616035500204040ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2003 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* * Implement connect/disconnect device methods for serial devices. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "xtypes.h" #include "cbuf.h" #include "hostlist.h" #include "list.h" #include "parse_util.h" #include "xpoll.h" #include "xmalloc.h" #include "pluglist.h" #include "arglist.h" #include "xregex.h" #include "device_private.h" #include "device_serial.h" #include "error.h" #include "debug.h" #include "xpty.h" typedef struct { char *special; char *flags; } SerialDev; typedef struct { int baud; speed_t bconst; } baudmap_t; static baudmap_t baudmap[] = { {300, B300}, {1200, B1200}, {2400, B2400}, {4800, B4800}, {9600, B9600}, {19200, B19200}, {38400, B38400}, #ifdef B57600 {57600, B57600}, #endif #ifdef B115200 {115200,B115200}, #endif #ifdef B230400 {230400,B230400}, #endif #ifdef B460800 {460800,B460800}, #endif }; void *serial_create(char *special, char *flags) { SerialDev *ser = (SerialDev *)xmalloc(sizeof(SerialDev)); ser->special = xstrdup(special); ser->flags = xstrdup(flags); return (void *)ser; } void serial_destroy(void *data) { SerialDev *ser = (SerialDev *)data; if (ser->special) xfree(ser->special); if (ser->flags) xfree(ser->flags); xfree(ser); } /* Set up serial port: 0 on success, <0 on error */ static int _serial_setup(char *devname, int fd, int baud, int databits, char parity, int stopbits) { int res; struct termios tio; int i; res = tcgetattr(fd, &tio); if (res < 0) { err(TRUE, "%s: error getting serial attributes", devname); return -1; } res = -1; for (i = 0; i < sizeof(baudmap)/sizeof(baudmap_t); i++) { if (baudmap[i].baud == baud) { if ((res = cfsetispeed(&tio, baudmap[i].bconst)) == 0) res = cfsetospeed(&tio, baudmap[i].bconst); break; } } if (res < 0) { err(FALSE, "%s: error setting baud rate to %d", devname, baud); return -1; } switch (databits) { case 7: tio.c_cflag &= ~CSIZE; tio.c_cflag |= CS7; break; case 8: tio.c_cflag &= ~CSIZE; tio.c_cflag |= CS8; break; default: err(FALSE, "%s: error setting data bits to %d", devname, databits); return -1; } switch (stopbits) { case 1: tio.c_cflag &= ~CSTOPB; break; case 2: tio.c_cflag |= CSTOPB; break; default: err(FALSE, "%s: error setting stop bits to %d", devname, stopbits); return -1; } switch (parity) { case 'n': case 'N': tio.c_cflag &= ~PARENB; break; case 'e': case 'E': tio.c_cflag |= PARENB; tio.c_cflag &= ~PARODD; break; case 'o': case 'O': tio.c_cflag |= PARENB; tio.c_cflag |= PARODD; break; default: err(FALSE, "%s: error setting parity to %c", devname, parity); return -1; } tio.c_oflag &= ~OPOST; /* turn off post-processing of output */ tio.c_iflag = tio.c_lflag = 0; if (tcsetattr(fd, TCSANOW, &tio) < 0) { err(TRUE, "%s: error setting serial attributes", devname); return -1; } return 0; } /* * Open the special file associated with this device. */ bool serial_connect(Device * dev) { SerialDev *ser; int baud = 9600, databits = 8, stopbits = 1; char parity = 'N'; int res; int n; assert(dev->magic == DEV_MAGIC); assert(dev->connect_state == DEV_NOT_CONNECTED); assert(dev->fd == NO_FD); ser = (SerialDev *)dev->data; dev->fd = open(ser->special, O_RDWR | O_NONBLOCK | O_NOCTTY); if (dev->fd < 0) { err(TRUE, "_serial_connect(%s): open %s", dev->name, ser->special); goto out; } if (!isatty(dev->fd)) { err(FALSE, "_serial_connect(%s): not a tty", dev->name); goto out; } /* [lifted from conman] According to the UNIX Programming FAQ v1.37 * * (Section 3.6: How to Handle a Serial Port or Modem), * systems seem to differ as to whether a nonblocking * open on a tty will affect subsequent read()s. * Play it safe and be explicit! */ nonblock_set(dev->fd); /* Conman takes an fcntl F_WRLCK on serial devices. * Powerman should respect conman's locks and vice-versa. */ if (lockf(dev->fd, F_TLOCK, 0) < 0) { err(TRUE, "_serial_connect(%s): could not lock device\n", dev->name); goto out; } /* parse the serial flags and set up port accordingly */ n = sscanf(ser->flags, "%d,%d%c%d", &baud, &databits, &parity, &stopbits); assert(n >= 0 && n <= 4); /* 0-4 matches OK (defaults if no match) */ res = _serial_setup(dev->name, dev->fd, baud, databits, parity, stopbits); if (res < 0) goto out; dev->connect_state = DEV_CONNECTED; dev->stat_successful_connects++; err(FALSE, "_serial_connect(%s): opened", dev->name); return TRUE; out: if (dev->fd >= 0) { if (close(dev->fd) < 0) err(TRUE, "_serial_connect(%s): close", dev->name); dev->fd = NO_FD; } return FALSE; } /* * Close the special file associated with this device. */ void serial_disconnect(Device * dev) { assert(dev->connect_state == DEV_CONNECTED); dbg(DBG_DEVICE, "_serial_disconnect: %s on fd %d", dev->name, dev->fd); /* close device if open */ if (dev->fd >= 0) { if (close(dev->fd) < 0) err(TRUE, "_serial_disconnect(%s): close", dev->name); dev->fd = NO_FD; } err(FALSE, "_serial_disconnect(%s): closed", dev->name); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_serial.h000066400000000000000000000004421415616035500204060ustar00rootroot00000000000000#ifndef PM_DEVICE_SERIAL_H #define PM_DEVICE_SERIAL_H bool serial_connect(Device * dev); void serial_disconnect(Device * dev); void *serial_create(char *special, char *flags); void serial_destroy(void *data); #endif /* PM_DEVICE_SERIAL_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_tcp.c000066400000000000000000000331111415616035500177070ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* * Implement connect/disconnect/preprocess methods for tcp/telnet devices. * * NOTE: we always do telnet when we are doing tcp. If there ever is a telnet * device that requires some proactive option negotiation, or a non-telnet * device that manages to confuse the telnet state machine, we could easily * implement a 'notelnet' flag. Right now it seems innocuous to leave the * telnet machine running. */ #if HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #include #include #include #include #include #include #include #include #include #define TELOPTS #define TELCMDS #include #include #include "list.h" #include "hostlist.h" #include "cbuf.h" #include "xtypes.h" #include "parse_util.h" #include "xmalloc.h" #include "xpoll.h" #include "pluglist.h" #include "arglist.h" #include "xregex.h" #include "device_private.h" #include "error.h" #include "debug.h" #include "device_tcp.h" #include "xpty.h" #ifndef HAVE_SOCKLEN_T typedef int socklen_t; /* socklen_t is uint32_t in Posix.1g */ #endif /* !HAVE_SOCKLEN_T */ typedef enum { TELNET_NONE, TELNET_CMD, TELNET_OPT } TelnetState; typedef struct { char *host; char *port; TelnetState tstate; /* state of telnet processing */ unsigned char tcmd; /* buffered telnet command */ bool quiet; /* don't report idle timeout messages */ struct addrinfo *addrs; struct addrinfo *cur; } TcpDev; static void _telnet_init(Device *dev); static void _telnet_preprocess(Device * dev); static void _parse_options(TcpDev *tcp, char *flags) { char *tmp = xstrdup(flags); char *opt = strtok(tmp, ","); while (opt) { if (strcmp(opt, "quiet") == 0) tcp->quiet = TRUE; else err_exit(FALSE, "bad device option: %s\n", opt); opt = strtok(NULL, ","); } xfree(tmp); } void *tcp_create(char *host, char *port, char *flags) { TcpDev *tcp = (TcpDev *)xmalloc(sizeof(TcpDev)); struct addrinfo hints; int error; tcp->host = xstrdup(host); tcp->port = xstrdup(port); tcp->tstate = TELNET_NONE; tcp->tcmd = 0; tcp->quiet = FALSE; if (flags) _parse_options(tcp, flags); /* Store a list of possible addresses/families to connect to * in the tcp->addrs linked list. */ memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((error = getaddrinfo(tcp->host, tcp->port, &hints, &tcp->addrs)) != 0) err_exit(FALSE, "getaddrinfo %s:%s: %s", tcp->host, tcp->port, gai_strerror(error)); if (tcp->addrs == NULL) err_exit(FALSE, "no addresses for server %s:%s", tcp->host, tcp->port); tcp->cur = tcp->addrs; return (void *)tcp; } void tcp_destroy(void *data) { TcpDev *tcp = (TcpDev *)data; if (tcp->host) xfree(tcp->host); if (tcp->port) xfree(tcp->port); if (tcp->addrs) freeaddrinfo(tcp->addrs); xfree(tcp); } /* After a successful connect, perform some management on * the connection. Returns TRUE on success, FALSE on error. */ static bool tcp_finish_connect_one(Device *dev) { int rc; int error = 0; socklen_t len = sizeof(error); rc = getsockopt(dev->fd, SOL_SOCKET, SO_ERROR, &error, &len); /* * If an error occurred, Berkeley-derived implementations * return 0 with the pending error in 'error'. But Solaris * returns -1 with the pending error in 'errno'. -dun */ if (rc < 0) error = errno; if (! error) { dev->connect_state = DEV_CONNECTED; dev->stat_successful_connects++; _telnet_init(dev); return TRUE; } return FALSE; } /* Obtain a socket for the specified address and attempt to connect it. * Return TRUE on completion or connection in progress, FALSE on error. */ static bool tcp_connect_one(Device *dev, struct addrinfo *addr) { TcpDev *tcp = (TcpDev *)dev->data; int opt; assert(tcp->cur != NULL); if ((dev->fd = socket(addr->ai_family, addr->ai_socktype, 0)) < 0) return FALSE; opt = 1; if (setsockopt(dev->fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { close(dev->fd); return FALSE; } nonblock_set(dev->fd); if (connect(dev->fd, addr->ai_addr, addr->ai_addrlen) >= 0) return tcp_finish_connect_one(dev); else if (errno == EINPROGRESS) return TRUE; close(dev->fd); return FALSE; } /* * Continue TCP connect when fd unblocks. * Return FALSE on error, which triggers timed retry of tcp_connect(). * Return TRUE if connected or still connecting (on the next address). */ bool tcp_finish_connect(Device * dev) { TcpDev *tcp; assert(dev->magic == DEV_MAGIC); assert(dev->connect_state == DEV_CONNECTING); tcp = (TcpDev *)dev->data; if (!tcp_finish_connect_one(dev)) { tcp->cur = tcp->cur->ai_next; while (tcp->cur && !tcp_connect_one(dev, tcp->cur)) tcp->cur = tcp->cur->ai_next; if (tcp->cur == NULL) dev->connect_state = DEV_NOT_CONNECTED; } switch(dev->connect_state) { case DEV_NOT_CONNECTED: err(FALSE, "tcp_finish_connect(%s): connection refused", dev->name); break; case DEV_CONNECTED: if (!tcp->quiet) err(FALSE, "tcp_finish_connect(%s): connected", dev->name); break; case DEV_CONNECTING: if (!tcp->quiet) err(FALSE, "tcp_finish_connect(%s): connecting", dev->name); break; } return (dev->connect_state != DEV_NOT_CONNECTED); } /* * Initiate a non-blocking TCP connect. tcp_finish_connect() will try to * finish the job when the main poll() loop unblocks again, unless we * finish here. */ bool tcp_connect(Device * dev) { TcpDev *tcp; assert(dev->magic == DEV_MAGIC); assert(dev->connect_state == DEV_NOT_CONNECTED); assert(dev->fd == NO_FD); tcp = (TcpDev *)dev->data; dev->connect_state = DEV_CONNECTING; while (tcp->cur && !tcp_connect_one(dev, tcp->cur)) tcp->cur = tcp->cur->ai_next; if (tcp->cur == NULL) dev->connect_state = DEV_NOT_CONNECTED; switch(dev->connect_state) { case DEV_NOT_CONNECTED: err(FALSE, "tcp_connect(%s): connection refused", dev->name); break; case DEV_CONNECTED: if (!tcp->quiet) err(FALSE, "tcp_connect(%s): connected", dev->name); break; case DEV_CONNECTING: if (!tcp->quiet) err(FALSE, "tcp_connect(%s): connecting", dev->name); break; } return (dev->connect_state == DEV_CONNECTED); } /* * Close the socket associated with this device. */ void tcp_disconnect(Device * dev) { TcpDev *tcp; assert(dev->magic == DEV_MAGIC); assert(dev->connect_state == DEV_CONNECTING || dev->connect_state == DEV_CONNECTED); tcp = (TcpDev *)dev->data; dbg(DBG_DEVICE, "tcp_disconnect: %s on fd %d", dev->name, dev->fd); /* close socket if open */ if (dev->fd >= 0) { if (close(dev->fd) < 0) err(TRUE, "tcp_disconnect: %s close fd %d", dev->name, dev->fd); dev->fd = NO_FD; } if (!tcp->quiet) err(FALSE, "tcp_disconnect(%s): disconnected", dev->name); } void tcp_preprocess(Device *dev) { _telnet_preprocess(dev); } static void _telnet_sendopt(Device *dev, int cmd, int opt) { unsigned char str[] = { IAC, cmd, opt }; int n; dbg(DBG_TELNET, "%s: _telnet_sendopt: %s %s", dev->name, TELCMD_OK(cmd) ? TELCMD(cmd) : "", TELOPT_OK(opt) ? TELOPT(opt) : ""); n = cbuf_write(dev->to, str, 3, NULL); if (n < 3) err((n < 0), "_telnet_sendopt: cbuf_write returned %d", n); } #if 0 static void _telnet_sendcmd(Device *dev, unsigned char cmd) { unsigned char str[] = { IAC, cmd }; int n; dbg(DBG_TELNET, "%s: _telnet_sendcmd: %s", dev->name, TELCMD_OK(cmd) ? TELCMD(cmd) : ""); n = cbuf_write(dev->to, str, 2, NULL); if (n < 2) err((n < 0), "_telnet_sendcmd: cbuf_write returned %d", n); } #endif static void _telnet_recvcmd(Device *dev, int cmd) { dbg(DBG_TELNET, "%s: _telnet_recvcmd: %s", dev->name, TELCMD_OK(cmd) ? TELCMD(cmd) : ""); } static void _telnet_recvopt(Device *dev, int cmd, int opt) { TcpDev *tcp = (TcpDev *)dev->data; dbg(DBG_TELNET, "%s: _telnet_recvopt: %s %s", dev->name, TELCMD_OK(cmd) ? TELCMD(cmd) : "", TELOPT_OK(opt) ? TELOPT(opt) : ""); switch (cmd) { case DO: switch (opt) { case TELOPT_SGA: /* rfc 858 - suppress go ahead*/ case TELOPT_TM: /* rfc 860 - timing mark */ _telnet_sendopt(dev, WILL, opt); break; case TELOPT_TTYPE: /* rfc 1091 - terminal type */ case TELOPT_NAWS: /* rfc 1073 - window size */ /* next three added for gnat powerman/634 - jg */ case TELOPT_NEW_ENVIRON: /* environment variables */ case TELOPT_XDISPLOC: /* X display location */ case TELOPT_TSPEED: /* terminal speed */ /* next two added for newer baytechs - jg */ case TELOPT_ECHO: /* echo */ case TELOPT_LFLOW: /* remote flow control */ /* next one added for cyclades ts - jg */ case TELOPT_BINARY: /* 8-bit data path */ _telnet_sendopt(dev, WONT, opt); break; default: if (!tcp->quiet) err(0, "%s: _telnet_recvopt: ignoring %s %s", dev->name, TELCMD_OK(cmd) ? TELCMD(cmd) : "", TELOPT_OK(opt) ? TELOPT(opt) : ""); break; } break; default: break; } } /* * Called just after a connect so we can perform any option requests. */ static void _telnet_init(Device * dev) { TcpDev *tcp = (TcpDev *)dev->data; tcp->tstate = TELNET_NONE; tcp->tcmd = 0; #if 0 _telnet_sendopt(dev, DONT, TELOPT_NAWS); _telnet_sendopt(dev, DONT, TELOPT_TTYPE); _telnet_sendopt(dev, DONT, TELOPT_ECHO); #endif } /* * Telnet state machine. This is called when new data has arrived in the * input buffer. We get to look first to process any telnet escapes. * Except for a little bit of state stored in the dev->u.tcp union, * we do all the processing now. */ static void _telnet_preprocess(Device * dev) { static unsigned char peek[MAX_DEV_BUF]; static unsigned char device[MAX_DEV_BUF]; TcpDev *tcp = (TcpDev *)dev->data; int len, i, k; len = cbuf_peek(dev->from, peek, MAX_DEV_BUF); for (i = 0, k = 0; i < len; i++) { switch (tcp->tstate) { case TELNET_NONE: if (peek[i] == IAC) tcp->tstate = TELNET_CMD; else device[k++] = peek[i]; break; case TELNET_CMD: switch (peek[i]) { case IAC: /* escaped IAC */ device[k++] = peek[i]; tcp->tstate = TELNET_NONE; break; case DONT: /* option commands - one more byte coming */ case DO: case WILL: case WONT: tcp->tcmd = peek[i]; tcp->tstate = TELNET_OPT; break; default: /* single char commands - process immediately */ _telnet_recvcmd(dev, peek[i]); tcp->tstate = TELNET_NONE; break; } break; case TELNET_OPT: /* option char - process stored command */ _telnet_recvopt(dev, tcp->tcmd, peek[i]); tcp->tstate = TELNET_NONE; break; } } /* rewrite buffers if anything changed */ if (k < len) { int n; n = cbuf_drop(dev->from, len); if (n < len) err((n < 0), "_telnet_preprocess: cbuf_drop returned %d", n); n = cbuf_write(dev->from, device, k, NULL); if (n < k) err((n < 0), "_telnet_preprocess: cbuf_write returned %d", n); } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/device_tcp.h000066400000000000000000000005411415616035500177150ustar00rootroot00000000000000#ifndef PM_DEVICE_TCP_H #define PM_DEVICE_TCP_H bool tcp_finish_connect(Device * dev); bool tcp_connect(Device * dev); void tcp_disconnect(Device * dev); void tcp_preprocess(Device * dev); void *tcp_create(char *host, char *port, char *flags); void tcp_destroy(void *data); #endif /* PM_DEVICE_TCP_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/parse_lex.l000066400000000000000000000156201415616035500176020ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001-2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton (uselton2@llnl.gov> * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ %x lex_incl lex_str %{ #if HAVE_CONFIG_H #include "config.h" #endif /* N.B. must define YYSTYPE before including parse_tab.h or type will be int. */ #define YYSTYPE char * extern YYSTYPE yylval; #include #include #include #include "hostlist.h" #include "parse_tab.h" #include "xtypes.h" #include "list.h" #include "xmalloc.h" #include "error.h" #include "parse_util.h" extern void yyerror(); #define MAX_INCLUDE_DEPTH 10 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; static int linenum[MAX_INCLUDE_DEPTH]; static char *filename[MAX_INCLUDE_DEPTH]; static int include_stack_ptr = 0; static char string_buf[8192]; static char *string_buf_ptr; static List line_ptrs; %} /* Lex Options */ %option nounput %% %{ /* yyin gets initialized in parse.y */ %} #[^\n]*\n { linenum[include_stack_ptr]++; } [ \t\r]+ { /* Eat up white space */ } [\n] { linenum[include_stack_ptr]++; } ([0-9]+)|([0-9]+"."[0-9]*)|("."[0-9]+) { yylval = yytext; return TOK_NUMERIC_VAL; } \$ { return TOK_MATCHPOS; } \" { string_buf_ptr = string_buf; BEGIN(lex_str); } { \" { /* end of string */ int len; BEGIN(INITIAL); *string_buf_ptr = '\0'; len = strlen(string_buf); yylval = xmalloc(len + 1); list_append(line_ptrs, yylval); strncpy(yylval, string_buf, len); yylval[len] = '\0'; return TOK_STRING_VAL; } "\\a" { *string_buf_ptr++ = '\a'; } "\\b" { *string_buf_ptr++ = '\b'; } "\\e" { *string_buf_ptr++ = '\e'; } "\\f" { *string_buf_ptr++ = '\f'; } "\\n" { *string_buf_ptr++ = '\n'; } "\\r" { *string_buf_ptr++ = '\r'; } "\\t" { *string_buf_ptr++ = '\t'; } "\\v" { *string_buf_ptr++ = '\v'; } "\n" { yyerror(); } \\[0-9][0-9][0-9] { *string_buf_ptr++ = strtol(&yytext[1], NULL, 8); } \\(.|\n) { *string_buf_ptr++ = yytext[1]; } [^\\\n\"]+ { char *yptr = yytext; while ( *yptr ) *string_buf_ptr++ = *yptr++; } } listen return TOK_LISTEN; tcpwrappers return TOK_TCP_WRAPPERS; plug_log_level return TOK_PLUG_LOG_LEVEL; timeout return TOK_DEV_TIMEOUT; pingperiod return TOK_PING_PERIOD; specification return TOK_SPEC; expect return TOK_EXPECT; setplugstate return TOK_SETPLUGSTATE; foreachnode return TOK_FOREACHNODE; foreachplug return TOK_FOREACHPLUG; ifoff return TOK_IFOFF; ifon return TOK_IFON; send return TOK_SEND; delay return TOK_DELAY; login return TOK_LOGIN; logout return TOK_LOGOUT; status return TOK_STATUS; status_all return TOK_STATUS_ALL; on return TOK_ON; on_ranged return TOK_ON_RANGED; on_all return TOK_ON_ALL; off return TOK_OFF; off_ranged return TOK_OFF_RANGED; off_all return TOK_OFF_ALL; cycle return TOK_CYCLE; cycle_ranged return TOK_CYCLE_RANGED; cycle_all return TOK_CYCLE_ALL; reset return TOK_RESET; reset_ranged return TOK_RESET_RANGED; reset_all return TOK_RESET_ALL; ping return TOK_PING; status_temp return TOK_STATUS_TEMP; status_temp_all return TOK_STATUS_TEMP_ALL; status_beacon return TOK_STATUS_BEACON; status_beacon_all return TOK_STATUS_BEACON_ALL; beacon_on return TOK_BEACON_ON; beacon_on_ranged return TOK_BEACON_ON_RANGED; beacon_off return TOK_BEACON_OFF; beacon_off_ranged return TOK_BEACON_OFF_RANGED; device return TOK_DEVICE; plug[ \t]+name return TOK_PLUG_NAME; node return TOK_NODE; yes return TOK_YES; no return TOK_NO; \{ return TOK_BEGIN; \} return TOK_END; = return TOK_EQUALS; script return TOK_SCRIPT; alias return TOK_ALIAS; include BEGIN(lex_incl); [ \t]* { /* eat white space */ } [\n] { linenum[include_stack_ptr]++; } [^ \t\n]+ { /* got include file name */ int len; len = strlen(yytext); yytext[len - 1] = '\0'; if ( include_stack_ptr >= MAX_INCLUDE_DEPTH - 1 ) err_exit(FALSE, "Includes nested too deeply" ); include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; linenum[include_stack_ptr] = 1; yyin = fopen( yytext + 1, "r" ); if ( yyin == NULL ) err_exit(TRUE, "%s", yytext + 1); filename[include_stack_ptr] = xstrdup(yytext + 1); yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) ); BEGIN(INITIAL); } <> { if (include_stack_ptr == 0) { yyterminate(); } else { /* do I need an fclose(yyin); here? */ yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( include_stack[--include_stack_ptr] ); } } . { return TOK_UNRECOGNIZED; } %% /* provide yywrap() to avoid need to link to -lfl */ int yywrap() { return 1; } int scanner_line(void) { return linenum[include_stack_ptr]; } void scanner_line_destroy(char *ptr) { xfree(ptr); } char * scanner_file(void) { return filename[include_stack_ptr]; } void scanner_init(char *filename0) { int i; for (i = 0; i < MAX_INCLUDE_DEPTH; i++) { linenum[i] = 1; filename[i] = NULL; } filename[0] = xstrdup(filename0); line_ptrs = list_create((ListDelF)scanner_line_destroy); } void scanner_fini(void) { int i; for (i = 0; i < MAX_INCLUDE_DEPTH; i++) { if (filename[i] != NULL) xfree(filename[i]); } list_destroy(line_ptrs); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/parse_tab.y000066400000000000000000000602071415616035500175760ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001-2002 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton (uselton2@llnl.gov> * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ %{ #if HAVE_CONFIG_H #include "config.h" #endif #define YYSTYPE char * /* The generic type returned by all parse matches */ #undef YYDEBUG /* no debug code plese */ #include #include #include #include #include /* for HUGE_VAL and trunc */ #include #include #include #include #include #include #include #include "list.h" #include "cbuf.h" #include "hostlist.h" #include "xtypes.h" #include "xmalloc.h" #include "xpoll.h" #include "xregex.h" #include "pluglist.h" #include "arglist.h" #include "device_private.h" #include "device_serial.h" #include "device_pipe.h" #include "device_tcp.h" #include "parse_util.h" #include "error.h" /* * A PreScript is a list of PreStmts. */ #define PRESTMT_MAGIC 0x89786756 typedef struct { int magic; StmtType type; /* delay/expect/send */ char *str; /* expect string, send fmt, setplugstate plug */ struct timeval tv; /* delay value */ int mp1; /* setplugstate plug match position */ int mp2; /* setplugstate state match position */ List prestmts; /* subblock */ List interps; /* interpretations for setplugstate */ } PreStmt; typedef List PreScript; /* * Unprocessed Protocol (used during parsing). * This data will be copied for each instantiation of a device. */ typedef struct { char *name; /* specification name, e.g. "icebox" */ struct timeval timeout; /* timeout for this device */ struct timeval ping_period; /* ping period for this device 0.0 = none */ List plugs; /* list of plug names (e.g. "1" thru "10") */ PreScript prescripts[NUM_SCRIPTS]; /* array of PreScripts */ } Spec; /* script may be NULL if undefined */ /* powerman.conf */ static void makeNode(char *nodestr, char *devstr, char *plugstr); static void makeAlias(char *namestr, char *hostsstr); static Stmt *makeStmt(PreStmt *p); static void destroyStmt(Stmt *stmt); static void makeDevice(char *devstr, char *specstr, char *hoststr, char *portstr); /* device config */ static PreStmt *makePreStmt(StmtType type, char *str, char *tvstr, char *mp1str, char *mp2str, List prestmts, List interps); static void destroyPreStmt(PreStmt *p); static Spec *makeSpec(char *name); static Spec *findSpec(char *name); static int matchSpec(Spec * spec, void *key); static void destroySpec(Spec * spec); static void _clear_current_spec(void); static void makeScript(int com, List stmts); static void destroyInterp(Interp *i); static Interp *makeInterp(InterpState state, char *str); static List copyInterpList(List ilist); /* utility functions */ static void _errormsg(char *msg); static void _warnmsg(char *msg); static long _strtolong(char *str); static double _strtodouble(char *str); static void _doubletotv(struct timeval *tv, double val); extern int yylex(); void yyerror(); static List device_specs = NULL; /* list of Spec's */ static Spec current_spec; /* Holds a Spec as it is built */ %} /* script names */ %token TOK_LOGIN TOK_LOGOUT TOK_STATUS TOK_STATUS_ALL %token TOK_STATUS_TEMP TOK_STATUS_TEMP_ALL %token TOK_STATUS_BEACON TOK_STATUS_BEACON_ALL %token TOK_BEACON_ON TOK_BEACON_ON_RANGED TOK_BEACON_OFF TOK_BEACON_OFF_RANGED %token TOK_ON TOK_ON_RANGED TOK_ON_ALL TOK_OFF TOK_OFF_RANGED TOK_OFF_ALL %token TOK_CYCLE TOK_CYCLE_RANGED TOK_CYCLE_ALL %token TOK_RESET TOK_RESET_RANGED TOK_RESET_ALL TOK_PING TOK_SPEC /* script statements */ %token TOK_EXPECT TOK_SETPLUGSTATE TOK_SEND TOK_DELAY %token TOK_FOREACHPLUG TOK_FOREACHNODE TOK_IFOFF TOK_IFON /* other device configuration stuff */ %token TOK_OFF_STRING TOK_ON_STRING %token TOK_MAX_PLUG_COUNT TOK_TIMEOUT TOK_DEV_TIMEOUT TOK_PING_PERIOD %token TOK_PLUG_NAME TOK_SCRIPT /* powerman.conf stuff */ %token TOK_DEVICE TOK_NODE TOK_ALIAS TOK_TCP_WRAPPERS TOK_LISTEN TOK_PLUG_LOG_LEVEL /* general */ %token TOK_MATCHPOS TOK_STRING_VAL TOK_NUMERIC_VAL TOK_YES TOK_NO %token TOK_BEGIN TOK_END TOK_UNRECOGNIZED TOK_EQUALS %% /* Grammar Rules for the powerman.conf config file */ configuration_file : config_list ; /**************************************************************/ /* config_list */ /**************************************************************/ config_list : config_list config_item | config_item | ; config_item : listen | TCP_wrappers | plug_log_level | device | node | alias | spec ; TCP_wrappers : TOK_TCP_WRAPPERS { _warnmsg("'tcpwrappers' without yes|no"); conf_set_use_tcp_wrappers(TRUE); } | TOK_TCP_WRAPPERS TOK_YES { conf_set_use_tcp_wrappers(TRUE); } | TOK_TCP_WRAPPERS TOK_NO { conf_set_use_tcp_wrappers(FALSE); } ; plug_log_level : TOK_PLUG_LOG_LEVEL TOK_STRING_VAL { conf_set_plug_log_level($2); } ; listen : TOK_LISTEN TOK_STRING_VAL { conf_add_listen($2); } ; device : TOK_DEVICE TOK_STRING_VAL TOK_STRING_VAL TOK_STRING_VAL TOK_STRING_VAL { makeDevice($2, $3, $4, $5); } | TOK_DEVICE TOK_STRING_VAL TOK_STRING_VAL TOK_STRING_VAL { makeDevice($2, $3, $4, NULL); } ; node : TOK_NODE TOK_STRING_VAL TOK_STRING_VAL TOK_STRING_VAL { makeNode($2, $3, $4); } | TOK_NODE TOK_STRING_VAL TOK_STRING_VAL { makeNode($2, $3, NULL); } ; alias : TOK_ALIAS TOK_STRING_VAL TOK_STRING_VAL { makeAlias($2, $3); } ; /**************************************************************/ /* specifications */ /**************************************************************/ spec : TOK_SPEC TOK_STRING_VAL TOK_BEGIN spec_item_list TOK_END { makeSpec($2); } ; spec_item_list : spec_item_list spec_item | spec_item ; spec_item : spec_timeout | spec_ping_period | spec_plug_list | spec_script_list ; spec_timeout : TOK_DEV_TIMEOUT TOK_NUMERIC_VAL { _doubletotv(¤t_spec.timeout, _strtodouble($2)); } ; spec_ping_period: TOK_PING_PERIOD TOK_NUMERIC_VAL { _doubletotv(¤t_spec.ping_period, _strtodouble($2)); } ; string_list : string_list TOK_STRING_VAL { list_append((List)$1, xstrdup($2)); $$ = $1; } | TOK_STRING_VAL { $$ = (char *)list_create((ListDelF)xfree); list_append((List)$$, xstrdup($1)); } ; spec_plug_list : TOK_PLUG_NAME TOK_BEGIN string_list TOK_END { if (current_spec.plugs != NULL) _errormsg("duplicate plug list"); current_spec.plugs = (List)$3; } ; spec_script_list : spec_script_list spec_script | spec_script ; spec_script : TOK_SCRIPT TOK_LOGIN stmt_block { makeScript(PM_LOG_IN, (List)$3); } | TOK_SCRIPT TOK_LOGOUT stmt_block { makeScript(PM_LOG_OUT, (List)$3); } | TOK_SCRIPT TOK_STATUS stmt_block { makeScript(PM_STATUS_PLUGS, (List)$3); } | TOK_SCRIPT TOK_STATUS_ALL stmt_block { makeScript(PM_STATUS_PLUGS_ALL, (List)$3); } | TOK_SCRIPT TOK_STATUS_TEMP stmt_block { makeScript(PM_STATUS_TEMP, (List)$3); } | TOK_SCRIPT TOK_STATUS_TEMP_ALL stmt_block { makeScript(PM_STATUS_TEMP_ALL, (List)$3); } | TOK_SCRIPT TOK_STATUS_BEACON stmt_block { makeScript(PM_STATUS_BEACON, (List)$3); } | TOK_SCRIPT TOK_STATUS_BEACON_ALL stmt_block { makeScript(PM_STATUS_BEACON_ALL, (List)$3); } | TOK_SCRIPT TOK_BEACON_ON stmt_block { makeScript(PM_BEACON_ON, (List)$3); } | TOK_SCRIPT TOK_BEACON_ON_RANGED stmt_block { makeScript(PM_BEACON_ON_RANGED, (List)$3); } | TOK_SCRIPT TOK_BEACON_OFF stmt_block { makeScript(PM_BEACON_OFF, (List)$3); } | TOK_SCRIPT TOK_BEACON_OFF_RANGED stmt_block { makeScript(PM_BEACON_OFF_RANGED, (List)$3); } | TOK_SCRIPT TOK_ON stmt_block { makeScript(PM_POWER_ON, (List)$3); } | TOK_SCRIPT TOK_ON_RANGED stmt_block { makeScript(PM_POWER_ON_RANGED, (List)$3); } | TOK_SCRIPT TOK_ON_ALL stmt_block { makeScript(PM_POWER_ON_ALL, (List)$3); } | TOK_SCRIPT TOK_OFF stmt_block { makeScript(PM_POWER_OFF, (List)$3); } | TOK_SCRIPT TOK_OFF_RANGED stmt_block { makeScript(PM_POWER_OFF_RANGED, (List)$3); } | TOK_SCRIPT TOK_OFF_ALL stmt_block { makeScript(PM_POWER_OFF_ALL, (List)$3); } | TOK_SCRIPT TOK_CYCLE stmt_block { makeScript(PM_POWER_CYCLE, (List)$3); } | TOK_SCRIPT TOK_CYCLE_RANGED stmt_block { makeScript(PM_POWER_CYCLE_RANGED, (List)$3); } | TOK_SCRIPT TOK_CYCLE_ALL stmt_block { makeScript(PM_POWER_CYCLE_ALL, (List)$3); } | TOK_SCRIPT TOK_RESET stmt_block { makeScript(PM_RESET, (List)$3); } | TOK_SCRIPT TOK_RESET_RANGED stmt_block { makeScript(PM_RESET_RANGED, (List)$3); } | TOK_SCRIPT TOK_RESET_ALL stmt_block { makeScript(PM_RESET_ALL, (List)$3); } | TOK_SCRIPT TOK_PING stmt_block { makeScript(PM_PING, (List)$3); } ; stmt_block : TOK_BEGIN stmt_list TOK_END { $$ = $2; } ; stmt_list : stmt_list stmt { list_append((List)$1, $2); $$ = $1; } | stmt { $$ = (char *)list_create((ListDelF)destroyPreStmt); list_append((List)$$, $1); } ; stmt : TOK_EXPECT TOK_STRING_VAL { $$ = (char *)makePreStmt(STMT_EXPECT, $2, NULL, NULL, NULL, NULL, NULL); } | TOK_SEND TOK_STRING_VAL { $$ = (char *)makePreStmt(STMT_SEND, $2, NULL, NULL, NULL, NULL, NULL); } | TOK_DELAY TOK_NUMERIC_VAL { $$ = (char *)makePreStmt(STMT_DELAY, NULL, $2, NULL, NULL, NULL, NULL); } | TOK_SETPLUGSTATE TOK_STRING_VAL regmatch { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, $2, NULL, NULL, $3, NULL, NULL); } | TOK_SETPLUGSTATE TOK_STRING_VAL regmatch interp_list { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, $2, NULL, NULL, $3, NULL, (List)$4); } | TOK_SETPLUGSTATE regmatch regmatch { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, NULL, NULL, $2, $3, NULL, NULL); } | TOK_SETPLUGSTATE regmatch regmatch interp_list { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, NULL, NULL, $2, $3, NULL,(List)$4); } | TOK_SETPLUGSTATE regmatch { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, NULL, NULL, NULL, $2, NULL, NULL); } | TOK_SETPLUGSTATE regmatch interp_list { $$ = (char *)makePreStmt(STMT_SETPLUGSTATE, NULL, NULL, NULL,$2,NULL,(List)$3); } | TOK_FOREACHNODE stmt_block { $$ = (char *)makePreStmt(STMT_FOREACHNODE, NULL, NULL, NULL, NULL, (List)$2, NULL); } | TOK_FOREACHPLUG stmt_block { $$ = (char *)makePreStmt(STMT_FOREACHPLUG, NULL, NULL, NULL, NULL, (List)$2, NULL); } | TOK_IFOFF stmt_block { $$ = (char *)makePreStmt(STMT_IFOFF, NULL, NULL, NULL, NULL, (List)$2, NULL); } | TOK_IFON stmt_block { $$ = (char *)makePreStmt(STMT_IFON, NULL, NULL, NULL, NULL, (List)$2, NULL); } ; interp_list : interp_list interp { list_append((List)$1, $2); $$ = $1; } | interp { $$ = (char *)list_create((ListDelF)destroyInterp); list_append((List)$$, $1); } ; interp : TOK_ON TOK_EQUALS TOK_STRING_VAL { $$ = (char *)makeInterp(ST_ON, $3); } | TOK_OFF TOK_EQUALS TOK_STRING_VAL { $$ = (char *)makeInterp(ST_OFF, $3); } ; regmatch : TOK_MATCHPOS TOK_NUMERIC_VAL { $$ = $2; } ; %% void scanner_init(char *filename); void scanner_fini(void); int scanner_line(void); char *scanner_file(void); /* * Entry point into the yacc/lex parser. */ int parse_config_file (char *filename) { extern FILE *yyin; /* part of lexer */ scanner_init(filename); yyin = fopen(filename, "r"); if (!yyin) err_exit(TRUE, "%s", filename); device_specs = list_create((ListDelF) destroySpec); _clear_current_spec(); yyparse(); fclose(yyin); scanner_fini(); list_destroy(device_specs); return 0; } /* makePreStmt(type, str, tv, mp1(plug), mp2(stat/node), prestmts, interps */ static PreStmt *makePreStmt(StmtType type, char *str, char *tvstr, char *mp1str, char *mp2str, List prestmts, List interps) { PreStmt *new; new = (PreStmt *) xmalloc(sizeof(PreStmt)); new->magic = PRESTMT_MAGIC; new->type = type; new->mp1 = mp1str ? _strtolong(mp1str) : -1; new->mp2 = mp2str ? _strtolong(mp2str) : -1; if (str) new->str = xstrdup(str); if (tvstr) _doubletotv(&new->tv, _strtodouble(tvstr)); new->prestmts = prestmts; new->interps = interps; return new; } static void destroyPreStmt(PreStmt *p) { assert(p->magic == PRESTMT_MAGIC); p->magic = 0; if (p->str) xfree(p->str); p->str = NULL; if (p->prestmts) list_destroy(p->prestmts); p->prestmts = NULL; if (p->interps) list_destroy(p->interps); p->interps = NULL; xfree(p); } static void _clear_current_spec(void) { int i; current_spec.name = NULL; current_spec.plugs = NULL; timerclear(¤t_spec.timeout); timerclear(¤t_spec.ping_period); for (i = 0; i < NUM_SCRIPTS; i++) current_spec.prescripts[i] = NULL; } static Spec *_copy_current_spec(void) { Spec *new = (Spec *) xmalloc(sizeof(Spec)); int i; *new = current_spec; for (i = 0; i < NUM_SCRIPTS; i++) new->prescripts[i] = current_spec.prescripts[i]; _clear_current_spec(); return new; } static Spec *makeSpec(char *name) { Spec *spec; current_spec.name = xstrdup(name); /* FIXME: check for manditory scripts here? what are they? */ spec = _copy_current_spec(); assert(device_specs != NULL); list_append(device_specs, spec); return spec; } static void destroySpec(Spec * spec) { int i; if (spec->name) xfree(spec->name); if (spec->plugs) list_destroy(spec->plugs); for (i = 0; i < NUM_SCRIPTS; i++) if (spec->prescripts[i]) list_destroy(spec->prescripts[i]); xfree(spec); } static int matchSpec(Spec * spec, void *key) { return (strcmp(spec->name, (char *) key) == 0); } static Spec *findSpec(char *name) { return list_find_first(device_specs, (ListFindF) matchSpec, name); } static void makeScript(int com, List stmts) { if (current_spec.prescripts[com] != NULL) _errormsg("duplicate script"); current_spec.prescripts[com] = stmts; } static Interp *makeInterp(InterpState state, char *str) { Interp *new = (Interp *)xmalloc(sizeof(Interp)); new->magic = INTERP_MAGIC; new->str = xstrdup(str); new->re = xregex_create(); new->state = state; return new; } static void destroyInterp(Interp *i) { assert(i->magic == INTERP_MAGIC); i->magic = 0; xfree(i->str); xregex_destroy(i->re); xfree(i); } static List copyInterpList(List il) { ListIterator itr; Interp *ip, *icpy; List new = list_create((ListDelF) destroyInterp); if (il != NULL) { itr = list_iterator_create(il); while((ip = list_next(itr))) { assert(ip->magic == INTERP_MAGIC); icpy = makeInterp(ip->state, ip->str); xregex_compile(icpy->re, icpy->str, FALSE); assert(icpy->magic == INTERP_MAGIC); list_append(new, icpy); } list_iterator_destroy(itr); } return new; } /** ** Powerman.conf stuff. **/ static void destroyStmt(Stmt *stmt) { assert(stmt != NULL); switch (stmt->type) { case STMT_SEND: xfree(stmt->u.send.fmt); break; case STMT_EXPECT: xregex_destroy(stmt->u.expect.exp); break; case STMT_DELAY: break; case STMT_SETPLUGSTATE: list_destroy(stmt->u.setplugstate.interps); break; case STMT_FOREACHNODE: case STMT_FOREACHPLUG: case STMT_IFON: case STMT_IFOFF: list_destroy(stmt->u.foreach.stmts); break; default: break; } xfree(stmt); } static Stmt *makeStmt(PreStmt *p) { Stmt *stmt; PreStmt *subp; ListIterator itr; assert(p->magic == PRESTMT_MAGIC); stmt = (Stmt *) xmalloc(sizeof(Stmt)); stmt->type = p->type; switch (p->type) { case STMT_SEND: stmt->u.send.fmt = xstrdup(p->str); break; case STMT_EXPECT: stmt->u.expect.exp = xregex_create(); xregex_compile(stmt->u.expect.exp, p->str, TRUE); break; case STMT_SETPLUGSTATE: stmt->u.setplugstate.stat_mp = p->mp2; if (p->str) stmt->u.setplugstate.plug_name = xstrdup(p->str); else stmt->u.setplugstate.plug_mp = p->mp1; stmt->u.setplugstate.interps = copyInterpList(p->interps); break; case STMT_DELAY: stmt->u.delay.tv = p->tv; break; case STMT_FOREACHNODE: case STMT_FOREACHPLUG: stmt->u.foreach.stmts = list_create((ListDelF) destroyStmt); itr = list_iterator_create(p->prestmts); while((subp = list_next(itr))) { assert(subp->magic == PRESTMT_MAGIC); list_append(stmt->u.foreach.stmts, makeStmt(subp)); } list_iterator_destroy(itr); break; case STMT_IFON: case STMT_IFOFF: stmt->u.ifonoff.stmts = list_create((ListDelF) destroyStmt); itr = list_iterator_create(p->prestmts); while((subp = list_next(itr))) { assert(subp->magic == PRESTMT_MAGIC); list_append(stmt->u.ifonoff.stmts, makeStmt(subp)); } list_iterator_destroy(itr); break; default: break; } return stmt; } static void _parse_hoststr(Device *dev, char *hoststr, char *flagstr) { /* pipe device, e.g. "conman -j baytech0 |&" */ if (strstr(hoststr, "|&") != NULL) { dev->data = pipe_create(hoststr, flagstr); dev->destroy = pipe_destroy; dev->connect = pipe_connect; dev->disconnect = pipe_disconnect; dev->finish_connect = NULL; dev->preprocess = NULL; /* serial device, e.g. "/dev/ttyS0" */ } else if (hoststr[0] == '/') { struct stat sb; if (stat(hoststr, &sb) == -1 || (!(sb.st_mode & S_IFCHR))) _errormsg("serial device not found or not a char special file"); dev->data = serial_create(hoststr, flagstr); dev->destroy = serial_destroy; dev->connect = serial_connect; dev->disconnect = serial_disconnect; dev->finish_connect = NULL; dev->preprocess = NULL; /* tcp device, e.g. "cyclades0:2001" */ } else { char *port = strchr(hoststr, ':'); int n; if (port) { /* host='host:port', flags=NULL */ *port++ = '\0'; } else _errormsg("hostname is missing :port"); n = _strtolong(port); /* verify port number */ if (n < 1 || n > 65535) _errormsg("port number out of range"); dev->data = tcp_create(hoststr, port, flagstr); dev->destroy = tcp_destroy; dev->connect = tcp_connect; dev->disconnect = tcp_disconnect; dev->finish_connect = tcp_finish_connect; dev->preprocess = tcp_preprocess; } } static void makeDevice(char *devstr, char *specstr, char *hoststr, char *flagstr) { ListIterator itr; Device *dev; Spec *spec; int i; /* find that spec */ spec = findSpec(specstr); if ( spec == NULL ) _errormsg("device specification not found"); /* make the Device */ dev = dev_create(devstr); dev->specname = xstrdup(specstr); dev->timeout = spec->timeout; dev->ping_period = spec->ping_period; _parse_hoststr(dev, hoststr, flagstr); /* create plugs (spec->plugs may be NULL) */ dev->plugs = pluglist_create(spec->plugs); /* transfer remaining info from the spec to the device */ for (i = 0; i < NUM_SCRIPTS; i++) { PreStmt *p; if (spec->prescripts[i] == NULL) { dev->scripts[i] = NULL; continue; /* unimplemented script */ } dev->scripts[i] = list_create((ListDelF) destroyStmt); /* copy the list of statements in each script */ itr = list_iterator_create(spec->prescripts[i]); while((p = list_next(itr))) { list_append(dev->scripts[i], makeStmt(p)); } list_iterator_destroy(itr); } dev_add(dev); } static void makeAlias(char *namestr, char *hostsstr) { if (!conf_add_alias(namestr, hostsstr)) _errormsg("bad alias"); } static void makeNode(char *nodestr, char *devstr, char *plugstr) { Device *dev = dev_findbyname(devstr); if (dev == NULL) _errormsg("unknown device"); /* plugstr can be NULL - see comment in pluglist.h */ switch (pluglist_map(dev->plugs, nodestr, plugstr)) { case EPL_DUPNODE: _errormsg("duplicate node"); case EPL_UNKPLUG: _errormsg("unknown plug name"); case EPL_DUPPLUG: _errormsg("plug already assigned"); case EPL_NOPLUGS: _errormsg("more nodes than plugs"); case EPL_NONODES: _errormsg("more plugs than nodes"); default: break; } if (!conf_addnodes(nodestr)) _errormsg("duplicate node name"); } /** ** Utility functions **/ static double _strtodouble(char *str) { char *endptr; double val = strtod(str, &endptr); if (val == 0.0 && endptr == str) _errormsg("error parsing double value"); if ((val == HUGE_VAL || val == -HUGE_VAL) && errno == ERANGE) _errormsg("double value would cause overflow"); return val; } static long _strtolong(char *str) { char *endptr; long val = strtol(str, &endptr, 0); if (val == 0 && endptr == str) _errormsg("error parsing long integer value"); if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) _errormsg("long integer value would cause under/overflow"); return val; } static void _doubletotv(struct timeval *tv, double val) { tv->tv_sec = (val * 10.0)/10; /* crude round-down without -lm */ tv->tv_usec = ((val - tv->tv_sec) * 1000000.0); } static void _errormsg(char *msg) { err_exit(FALSE, "%s: %s::%d", msg, scanner_file(), scanner_line()); } static void _warnmsg(char *msg) { err(FALSE, "warning: %s: %s::%d", msg, scanner_file(), scanner_line()); } void yyerror() { _errormsg("parse error"); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/parse_util.c000066400000000000000000000214701415616035500177560ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include /* * Define SYSLOG_NAMES to allow access to level names * needed for parsing in string_to_level(). */ #ifndef SYSLOG_NAMES #define SYSLOG_NAMES 1 #define UNDO_SYSLOG_NAMES 1 #endif #include #ifdef UNDO_SYSLOG_NAMES #undef SYSLOG_NAMES #undef UNDO_SYSLOG_NAMES #endif #include "list.h" #include "hostlist.h" #include "xtypes.h" #include "error.h" #include "parse_util.h" #include "xmalloc.h" #include "xpoll.h" #include "pluglist.h" #include "client.h" #include "powerman.h" typedef struct { char *name; hostlist_t hl; } alias_t; static bool conf_use_tcp_wrap = FALSE; static int conf_plug_log_level = LOG_DEBUG; /* syslog level */ static List conf_listen = NULL; /* list of host:port strings */ static hostlist_t conf_nodes = NULL; static List conf_aliases = NULL; /* list of alias_t's */ static bool _validate_config(void); static void _alias_destroy(alias_t *a); extern int parse_config_file(char *filename); /* yacc/lex parser */ /* * initialize module * parse the named config file - on error, exit with a message to stderr */ void conf_init(char *filename) { struct stat stbuf; bool valid; conf_listen = list_create((ListDelF) xfree); conf_nodes = hostlist_create(NULL); conf_aliases = list_create((ListDelF) _alias_destroy); /* validate config file */ if (stat(filename, &stbuf) < 0) err_exit(TRUE, "%s", filename); if ((stbuf.st_mode & S_IFMT) != S_IFREG) err_exit(FALSE, "%s is not a regular file\n", filename); /* * Call yacc parser against config file. The parser calls support * functions below and builds 'dev_devices' (devices.c), * 'conf_cluster', 'conf_specs' (config.c), and various other * conf_* attributes (config.c). */ parse_config_file(filename); valid = _validate_config(); if (!valid) exit(1); } /* finalize module */ void conf_fini(void) { if (conf_nodes != NULL) hostlist_destroy(conf_nodes); } /* * Check the config file and exit with error if any problems are found. */ static bool _validate_config(void) { ListIterator itr; bool valid = TRUE; alias_t *a; /* make sure aliases do not point to bogus node names */ itr = list_iterator_create(conf_aliases); while ((a = list_next(itr)) != NULL) { hostlist_iterator_t hitr = hostlist_iterator_create(a->hl); char *host; if (hitr == NULL) err_exit(FALSE, "hostlist_iterator_create failed"); while ((host = hostlist_next(hitr)) != NULL) { if (!conf_node_exists(host)) { err(FALSE, "alias '%s' references nonexistant node '%s'", a->name, host); valid = FALSE; free(host); break; } else free(host); } hostlist_iterator_destroy(hitr); } list_iterator_destroy(itr); /* make sure there is at least one node defined */ if (hostlist_is_empty(conf_nodes)) { err(FALSE, "no nodes are defined"); valid = FALSE; } /* if no listen ports, add the default */ if (list_count(conf_listen) == 0) { char *s = xmalloc(strlen(DFLT_HOSTNAME) + strlen(DFLT_PORT) + 2); sprintf(s, "%s:%s", DFLT_HOSTNAME, DFLT_PORT); list_append(conf_listen, s); } return valid; } /* * Node conf_nodes list. */ bool conf_node_exists(char *node) { int res; res = hostlist_find(conf_nodes, node); return (res == -1 ? FALSE : TRUE); } bool conf_addnodes(char *nodelist) { hostlist_t hl = hostlist_create(nodelist); hostlist_iterator_t itr = hostlist_iterator_create(hl); char *node; int res = TRUE; while ((node = hostlist_next(itr))) { if (conf_node_exists(node)) { free(node); res = FALSE; break; } else { hostlist_push(conf_nodes, node); free(node); } } hostlist_iterator_destroy(itr); hostlist_destroy(hl); return res; } hostlist_t conf_getnodes(void) { return conf_nodes; } /* * Accessor functions for misc. configurable values. */ bool conf_get_use_tcp_wrappers(void) { return conf_use_tcp_wrap; } void conf_set_use_tcp_wrappers(bool val) { #if ! HAVE_TCP_WRAPPERS if (val == TRUE) err_exit(FALSE, "powerman was not built with tcp_wrapper support"); #endif conf_use_tcp_wrap = val; } List conf_get_listen(void) { return conf_listen; } void conf_add_listen(char *hostport) { list_append(conf_listen, xstrdup(hostport)); } /* * Return the corresponding integer value if syslog prioritynames * contains a name identical to s. If no match can be found, return (-1) * and set errno to EINVAL. */ static int string_to_level(char *s) { int level = -1; CODE *record = prioritynames; if (!s || *s == '\0') return -1; while (record->c_val != -1) { if (strcmp(s, record->c_name) == 0) { level = record->c_val; break; } record++; } return level; } int conf_get_plug_log_level(void) { return conf_plug_log_level; } void conf_set_plug_log_level(char *level_string) { int level = string_to_level(level_string); if (level < 0) err_exit(FALSE, "unable to recognize plug_log_level config value"); conf_plug_log_level = level; } /* * Manage a list of nodename aliases. */ static int _alias_match(alias_t *a, char *name) { return (strcmp(a->name, name) == 0); } /* Expand any aliases present in hostlist. * N.B. Aliases cannot contain other aliases. */ void conf_exp_aliases(hostlist_t hl) { hostlist_iterator_t itr = NULL; hostlist_t newhosts = hostlist_create(NULL); char *host; /* Put the expansion of any aliases in the hostlist into 'newhosts', * deleting the original reference from the hostlist. */ if (newhosts == NULL) err_exit(FALSE, "hostlist_create failed"); if ((itr = hostlist_iterator_create(hl)) == NULL) err_exit(FALSE, "hostlist_iterator_create failed"); while ((host = hostlist_next(itr)) != NULL) { alias_t *a; a = list_find_first(conf_aliases, (ListFindF) _alias_match, host); if (a) { hostlist_delete_host(hl, host); hostlist_push_list(newhosts, a->hl); hostlist_iterator_reset(itr); /* not sure of itr position after insertion/deletion so reset */ } free(host); } hostlist_iterator_destroy(itr); /* dump the contents of 'newhosts' into the hostlist */ hostlist_push_list(hl, newhosts); hostlist_destroy(newhosts); } static void _alias_destroy(alias_t *a) { if (a->name) xfree(a->name); if (a->hl) hostlist_destroy(a->hl); xfree(a); } static alias_t *_alias_create(char *name, char *hosts) { alias_t *a = NULL; if (!list_find_first(conf_aliases, (ListFindF) _alias_match, name)) { a = (alias_t *)xmalloc(sizeof(alias_t)); a->name= xstrdup(name); a->hl = hostlist_create(hosts); if (a->hl == NULL) { _alias_destroy(a); a = NULL; } } return a; } /* * Called from the parser. */ bool conf_add_alias(char *name, char *hosts) { alias_t *a; if ((a = _alias_create(name, hosts))) { list_push(conf_aliases, a); return TRUE; } return FALSE; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/parse_util.h000066400000000000000000000011251415616035500177560ustar00rootroot00000000000000#ifndef PM_PARSE_UTIL_H #define PM_PARSE_UTIL_H void conf_init(char *filename); void conf_fini(void); bool conf_addnodes(char *nodelist); bool conf_node_exists(char *node); hostlist_t conf_getnodes(void); bool conf_get_use_tcp_wrappers(void); void conf_set_use_tcp_wrappers(bool val); int conf_get_plug_log_level(void); void conf_set_plug_log_level(char *level); List conf_get_listen(void); void conf_add_listen(char *hostport); void conf_exp_aliases(hostlist_t hl); bool conf_add_alias(char *name, char *hosts); #endif /* PM_PARSE_UTIL_H */ /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/powermand/powermand.c000066400000000000000000000153071415616035500176050ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include "xtypes.h" #include "list.h" #include "hostlist.h" #include "parse_util.h" #include "xmalloc.h" #include "xpoll.h" #include "xsignal.h" #include "pluglist.h" #include "device.h" #include "daemon.h" #include "client.h" #include "error.h" #include "debug.h" #include "hprintf.h" #include "powerman.h" /* prototypes */ static void _usage(char *prog); static void _version(void); static void _noop_handler(int signum); static void _exit_handler(int signum); static void _select_loop(void); #define OPTIONS "c:fhd:VsY1" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { {"conf", required_argument, 0, 'c'}, {"foreground", no_argument, 0, 'f'}, {"help", no_argument, 0, 'h'}, {"debug", required_argument, 0, 'd'}, {"version", no_argument, 0, 'V'}, {"stdio", no_argument, 0, 's'}, {"short-circuit-delay", no_argument, 0, 'Y'}, {"one-client", no_argument, 0, '1'}, {0, 0, 0, 0} }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char **argv) { int c; char *config_filename = NULL; bool daemonize = TRUE; bool use_stdio = FALSE; bool short_circuit_delay = FALSE; bool one_client = FALSE; /* parse command line options */ err_init(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'Y': /* --short-circuit-delay */ short_circuit_delay = TRUE; break; case 'c': /* --conf */ if (!config_filename) config_filename = xstrdup(optarg); break; case 'f': /* --foreground */ daemonize = FALSE; break; case 'd': /* --debug */ { unsigned long val = strtol(optarg, NULL, 0); if ((val == LONG_MAX || val == LONG_MIN) && errno == ERANGE) err_exit(TRUE, "strtol on debug mask"); dbg_setmask(val); } break; case 'V': /* --version */ _version(); /*NOTREACHED*/ break; case 's': /* --stdio */ use_stdio = TRUE; one_client = TRUE; break; case '1': /* --one-client */ one_client = TRUE; break; case 'h': /* --help */ default: _usage(argv[0]); /*NOTREACHED*/ break; } } if (use_stdio && daemonize) err_exit(FALSE, "--stdio should only be used with --foreground"); if (!config_filename) config_filename = hsprintf("%s/%s/%s", X_SYSCONFDIR, "powerman", "powerman.conf"); dev_init(short_circuit_delay); cli_init(); conf_init(config_filename); xfree(config_filename); xsignal(SIGHUP, _noop_handler); xsignal(SIGTERM, _exit_handler); xsignal(SIGINT, _exit_handler); xsignal(SIGPIPE, SIG_IGN); cli_start(use_stdio, one_client); if (daemonize) { char *rundir = hsprintf("%s/run/powerman", X_LOCALSTATEDIR); char *pidfile = hsprintf("%s/powermand.pid", rundir); int *fds, len; cli_listen_fds(&fds, &len); daemon_init(fds, len, rundir, pidfile, DAEMON_NAME); xfree(rundir); xfree(pidfile); err_notty(); dbg_notty(); } /* We now have a socket at listener fd running in listen mode */ /* and a file descriptor for communicating with each device */ _select_loop(); return 0; } static void _usage(char *prog) { printf("Usage: %s [OPTIONS]\n", prog); printf(" -c --conf Specify config file path\n"); printf(" -d --debug Set debug mask [0]\n"); printf(" -f --foreground Don't daemonize\n"); printf(" -V --version Report powerman version\n"); printf(" -s --stdio Talk to client on stdin/stdout\n"); printf(" -1 --one-client Terminate when client disconnects\n"); exit(0); } static void _version(void) { printf("%s\n", VERSION); exit(0); } static void _select_loop(void) { struct timeval tmout; xpollfd_t pfd = xpollfd_create(); timerclear(&tmout); /* start non-blocking connections to all the devices - finish them inside * the poll loop. */ dev_initial_connect(); while (1) { xpollfd_zero(pfd); cli_pre_poll(pfd); dev_pre_poll(pfd); xpoll(pfd, timerisset(&tmout) ? &tmout : NULL); timerclear(&tmout); /* * Process activity on client and device fd's. * If a device requires a timeout, for example to reconnect or * to process a scripted delay, tmout is updated. */ cli_post_poll(pfd); dev_post_poll(pfd, &tmout); if (cli_server_done()) break; } xpollfd_destroy(pfd); } static void _noop_handler(int signum) { /* do nothing */ } static void _exit_handler(int signum) { cli_fini(); dev_fini(); conf_fini(); err_exit(FALSE, "exiting on signal %d", signum); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/redfishpower/000077500000000000000000000000001415616035500161445ustar00rootroot00000000000000powerman-2.3.27/redfishpower/Makefile.am000066400000000000000000000004411415616035500201770ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = \ -I$(top_srcdir)/liblsd \ -I$(top_srcdir)/libcommon sbin_PROGRAMS = redfishpower redfishpower_SOURCES = redfishpower.c redfishpower_LDADD = \ $(top_builddir)/liblsd/liblsd.a \ $(top_builddir)/libcommon/libcommon.a \ $(LIBCURL) \ $(LIBJANSSON) powerman-2.3.27/redfishpower/redfishpower.c000066400000000000000000000706441415616035500210240ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2021 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Albert Chu * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://code.google.com/p/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "list.h" #include "hostlist.h" #include "error.h" #include "argv.h" static hostlist_t hosts = NULL; static char *header = NULL; static struct curl_slist *header_list = NULL; static int verbose = 0; static char *userpwd = NULL; static char *statpath = NULL; static char *onpath = NULL; static char *onpostdata = NULL; static char *offpath = NULL; static char *offpostdata = NULL; static char *cyclepath = NULL; static char *cyclepostdata = NULL; /* in seconds */ #define MESSAGE_TIMEOUT 10 #define CMD_TIMEOUT 60 /* Per documentation, wait incremental time then proceed if timeout < 0 */ #define INCREMENTAL_WAIT 500 /* in usec * * wait delay of 1 second may seem long, but testing shows * wait ranges from a few seconds to 20 seconds */ #define WAIT_UNTIL_DELAY 1000000 #define MS_IN_SEC 1000 struct powermsg { CURLM *mh; /* curl multi handle pointer */ CURL *eh; /* curl easy handle */ char *cmd; /* "on", "off", "cycle", or "stat" */ char *hostname; /* host we're working with */ char *url; /* on, off, cycle, stat */ char *postdata; /* on, off, cycle */ char *output; /* on, off, stat */ size_t output_len; /* flag indicating if we are in the "wait" mode of on or off */ int wait_until_on_off; /* start - when power op started, may be set to start time of a * previous message if this is a follow on message. * * timeout - when the overal power command times out * * delaystart - if message should be sent after a wait */ struct timeval start; struct timeval timeout; struct timeval delaystart; }; #define Curl_easy_setopt(args) \ do { \ CURLcode _ec; \ if ((_ec = curl_easy_setopt args) != CURLE_OK) \ err_exit(FALSE, "curl_easy_setopt: %s", curl_easy_strerror(_ec)); \ } while(0) #define OPTIONS "h:H:S:O:F:C:P:G:D:v" static struct option longopts[] = { {"hostname", required_argument, 0, 'h' }, {"hostsfile", required_argument, 0, 'f' }, {"header", required_argument, 0, 'H' }, {"statpath", required_argument, 0, 'S' }, {"onpath", required_argument, 0, 'O' }, {"offpath", required_argument, 0, 'F' }, {"cyclepath", required_argument, 0, 'C' }, {"onpostdata", required_argument, 0, 'P' }, {"offpostdata", required_argument, 0, 'G' }, {"cyclepostdata", required_argument, 0, 'D' }, {"verbose", no_argument, 0, 'v' }, {0,0,0,0}, }; void help(void) { printf("Valid commands are:\n"); printf(" auth user:passwd\n"); printf(" setheader string\n"); printf(" setstatpath url\n"); printf(" setonpath url [data]\n"); printf(" setoffpath url [data]\n"); printf(" setcyclepath url [data]\n"); printf(" stat [nodes]\n"); printf(" on [nodes]\n"); printf(" off [nodes]\n"); printf(" cycle [nodes]\n"); } static size_t output_cb(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct powermsg *pm = userp; if (pm->output) { char *tmp = calloc(1, pm->output_len + realsize + 1); if (!tmp) err_exit(TRUE, "calloc"); memcpy(tmp, pm->output, pm->output_len); memcpy(tmp + pm->output_len, contents, realsize); pm->output_len += realsize; free(pm->output); pm->output = tmp; } else { if (!(pm->output = calloc(1, realsize + 1))) err_exit(TRUE, "calloc"); memcpy(pm->output, contents, realsize); pm->output_len = realsize; } return realsize; } static struct powermsg *powermsg_create(CURLM *mh, const char *hostname, const char *cmd, const char *path, const char *postdata, struct timeval *start, unsigned long delay_usec) { struct powermsg *pm = calloc(1, sizeof(*pm)); struct timeval now; struct timeval waitdelay = { 0 }; CURLMcode mc; if (!pm) err_exit(TRUE, "calloc"); pm->mh = mh; if ((pm->eh = curl_easy_init()) == NULL) err_exit(FALSE, "curl_easy_init failed"); Curl_easy_setopt((pm->eh, CURLOPT_TIMEOUT, MESSAGE_TIMEOUT)); Curl_easy_setopt((pm->eh, CURLOPT_FAILONERROR, 1)); /* for time being */ Curl_easy_setopt((pm->eh, CURLOPT_SSL_VERIFYPEER, 0L)); Curl_easy_setopt((pm->eh, CURLOPT_SSL_VERIFYHOST, 0L)); if (verbose) Curl_easy_setopt((pm->eh, CURLOPT_VERBOSE, 1L)); if (header) { if (!header_list) { if (!(header_list = curl_slist_append(header_list, header))) err_exit(FALSE, "curl_slist_append"); } Curl_easy_setopt((pm->eh, CURLOPT_HTTPHEADER, header_list)); } if (userpwd) { Curl_easy_setopt((pm->eh, CURLOPT_USERPWD, userpwd)); Curl_easy_setopt((pm->eh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC)); } Curl_easy_setopt((pm->eh, CURLOPT_WRITEFUNCTION, output_cb)); Curl_easy_setopt((pm->eh, CURLOPT_WRITEDATA, (void *)pm)); Curl_easy_setopt((pm->eh, CURLOPT_PRIVATE, pm)); if ((mc = curl_multi_add_handle(pm->mh, pm->eh)) != CURLM_OK) err_exit(FALSE, "curl_multi_add_handle: %s", curl_multi_strerror(mc)); pm->cmd = xstrdup(cmd); pm->hostname = xstrdup(hostname); pm->url = xmalloc(strlen("https://") + strlen(hostname) + strlen(path) + 2); sprintf(pm->url, "https://%s/%s", hostname, path); if (postdata) pm->postdata = xstrdup(postdata); Curl_easy_setopt((pm->eh, CURLOPT_URL, pm->url)); if (start) { pm->start.tv_sec = start->tv_sec; pm->start.tv_usec = start->tv_usec; } else gettimeofday(&pm->start, NULL); pm->timeout.tv_sec = pm->start.tv_sec + CMD_TIMEOUT; pm->timeout.tv_usec = pm->start.tv_usec; if (delay_usec) { gettimeofday(&now, NULL); waitdelay.tv_usec = delay_usec; timeradd(&now, &waitdelay, &pm->delaystart); } return pm; } static void powermsg_destroy(struct powermsg *pm) { if (pm) { CURLMcode mc; Curl_easy_setopt((pm->eh, CURLOPT_URL, "")); if (pm->cmd) xfree(pm->cmd); if (pm->url) xfree(pm->url); if (pm->postdata) xfree(pm->postdata); free(pm->output); if ((mc = curl_multi_remove_handle(pm->mh, pm->eh)) != CURLM_OK) err_exit(FALSE, "curl_multi_remove_handle: %s", curl_multi_strerror(mc)); curl_easy_cleanup(pm->eh); free(pm); } } /* get hostlist of input hosts, make sure are legal based on initial input */ static hostlist_t parse_input_hosts(const char *inputhosts) { hostlist_t lhosts = NULL; hostlist_iterator_t itr = NULL; char *hostname; hostlist_t rv = NULL; if (!(lhosts = hostlist_create(inputhosts))) { printf("illegal hosts input\n"); return NULL; } if (!(itr = hostlist_iterator_create(lhosts))) err_exit(TRUE, "hostlist_iterator_create"); while ((hostname = hostlist_next(itr))) { if (hostlist_find(hosts, hostname) < 0) { printf("unknown host specified: %s\n", hostname); free(hostname); goto cleanup; } free(hostname); } rv = lhosts; cleanup: hostlist_iterator_destroy(itr); if (!rv) hostlist_destroy(lhosts); return rv; } static struct powermsg *stat_cmd_host(CURLM * mh, char *hostname) { struct powermsg *pm = powermsg_create(mh, hostname, "stat", statpath, NULL, NULL, 0); Curl_easy_setopt((pm->eh, CURLOPT_HTTPGET, 1)); return pm; } static void stat_cmd(List activecmds, CURLM *mh, char **av) { hostlist_iterator_t itr = NULL; char *hostname; hostlist_t *hostsptr = NULL; hostlist_t lhosts = NULL; if (!statpath) { printf("Statpath not setup\n"); return; } if (av[0]) { if (!(lhosts = parse_input_hosts(av[0]))) return; hostsptr = &lhosts; } else hostsptr = &hosts; if (!(itr = hostlist_iterator_create(*hostsptr))) err_exit(TRUE, "hostlist_iterator_create"); while ((hostname = hostlist_next(itr))) { struct powermsg *pm = stat_cmd_host(mh, hostname); if (!list_append(activecmds, pm)) err_exit(TRUE, "list_append"); free(hostname); } hostlist_iterator_destroy(itr); hostlist_destroy(lhosts); } static void parse_onoff (struct powermsg *pm, const char **strp) { if (pm->output) { json_error_t error; json_t *o; if (!(o = json_loads(pm->output, 0, &error))) { (*strp) = "parse error"; if (verbose) printf("%s: parse response error %s\n", pm->hostname, error.text); } else { json_t *val = json_object_get(o, "PowerState"); if (!val) { (*strp) = "no powerstate"; if (verbose) printf("%s: no PowerState\n", pm->hostname); } else { const char *str = json_string_value(val); if (strcasecmp(str, "On") == 0) (*strp) = "on"; else if (strcasecmp(str, "Off") == 0) (*strp) = "off"; else (*strp) = "unknown"; } } json_decref(o); } else (*strp) = "no output error"; } static void stat_process (struct powermsg *pm) { const char *str; parse_onoff(pm, &str); printf("%s: %s\n", pm->hostname, str); } static void stat_cleanup(struct powermsg *pm) { powermsg_destroy(pm); } struct powermsg *power_cmd_host(CURLM * mh, char *hostname, const char *cmd, const char *path, const char *postdata) { struct powermsg *pm = powermsg_create(mh, hostname, cmd, path, postdata, NULL, 0); Curl_easy_setopt((pm->eh, CURLOPT_POST, 1)); Curl_easy_setopt((pm->eh, CURLOPT_POSTFIELDS, pm->postdata)); Curl_easy_setopt((pm->eh, CURLOPT_POSTFIELDSIZE, strlen(pm->postdata))); return pm; } static void power_cmd(List activecmds, CURLM *mh, char **av, const char *cmd, const char *path, const char *postdata) { hostlist_iterator_t itr = NULL; char *hostname; hostlist_t *hostsptr = NULL; hostlist_t lhosts = NULL; if (!path) { printf("%s path not setup\n", cmd); return; } if (av[0]) { if (!(lhosts = parse_input_hosts(av[0]))) return; hostsptr = &lhosts; } else hostsptr = &hosts; if (!(itr = hostlist_iterator_create(*hostsptr))) err_exit(TRUE, "hostlist_iterator_create"); while ((hostname = hostlist_next(itr))) { struct powermsg *pm = power_cmd_host(mh, hostname, cmd, path, postdata); if (!list_append(activecmds, pm)) err_exit(TRUE, "list_append"); free(hostname); } hostlist_iterator_destroy(itr); hostlist_destroy(lhosts); } static void on_cmd(List activecmds, CURLM *mh, char **av) { if (!statpath) { printf("Statpath not setup\n"); return; } power_cmd(activecmds, mh, av, "on", onpath, onpostdata); } static void off_cmd(List activecmds, CURLM *mh, char **av) { if (!statpath) { printf("Statpath not setup\n"); return; } power_cmd(activecmds, mh, av, "off", offpath, offpostdata); } static void cycle_cmd(List activecmds, CURLM *mh, char **av) { power_cmd(activecmds, mh, av, "cycle", cyclepath, cyclepostdata); } static void on_off_process(List delayedcmds, struct powermsg *pm) { struct powermsg *nextpm; struct timeval now; if (pm->wait_until_on_off) { const char *str; parse_onoff(pm, &str); if (strcmp(str, pm->cmd) == 0) { printf("%s: %s\n", pm->hostname, "ok"); return; } /* fallthrough, check again */ } gettimeofday(&now, NULL); if (timercmp(&now, &pm->timeout, >)) { printf("%s: %s\n", pm->hostname, "timeout"); return; } /* issue a follow on stat to wait until the on/off is complete. * note that we initial start time of this new command to * the original on/off, so we can timeout correctly */ nextpm = powermsg_create(pm->mh, pm->hostname, pm->cmd, statpath, NULL, &pm->start, WAIT_UNTIL_DELAY); Curl_easy_setopt((nextpm->eh, CURLOPT_HTTPGET, 1)); nextpm->wait_until_on_off = 1; if (!list_append(delayedcmds, nextpm)) err_exit(TRUE, "list_append"); } static void on_process(List delayedcmds, struct powermsg *pm) { on_off_process(delayedcmds, pm); } static void off_process(List delayedcmds, struct powermsg *pm) { on_off_process(delayedcmds, pm); } static void cycle_process(struct powermsg *pm) { printf("%s: %s\n", pm->hostname, "ok"); } static void power_cleanup(struct powermsg *pm) { Curl_easy_setopt((pm->eh, CURLOPT_POSTFIELDS, "")); Curl_easy_setopt((pm->eh, CURLOPT_POSTFIELDSIZE, 0)); powermsg_destroy(pm); } static void on_cleanup(struct powermsg *pm) { power_cleanup(pm); } static void off_cleanup(struct powermsg *pm) { power_cleanup(pm); } static void cycle_cleanup(struct powermsg *pm) { power_cleanup(pm); } static void auth(char **av) { if (av[0] == NULL) { printf("Usage: auth user:passwd\n"); return; } if (userpwd) xfree(userpwd); userpwd = xstrdup(av[0]); } static void setheader(char **av) { if (header) { xfree(header); curl_slist_free_all(header_list); header = NULL; header_list = NULL; } if (av[0]) { header = xstrdup(av[0]); header_list = curl_slist_append(header_list, header); } } static void setstatpath(char **av) { if (statpath) { xfree(statpath); statpath = NULL; } if (av[0]) statpath = xstrdup(av[0]); } static void setpowerpath(char **av, char **path, char **postdata) { if (*path) { xfree(*path); *path = NULL; } if (*postdata) { xfree(*postdata); *postdata = NULL; } if (av[0]) (*path) = xstrdup(av[0]); if (av[1]) (*postdata) = xstrdup(av[1]); } static void process_cmd(List activecmds, CURLM *mh, char **av, int *exitflag) { if (av[0] != NULL) { if (strcmp(av[0], "help") == 0) help(); else if (strcmp(av[0], "quit") == 0) (*exitflag) = 1; else if (strcmp(av[0], "auth") == 0) auth(av + 1); else if (strcmp(av[0], "setheader") == 0) setheader(av + 1); else if (strcmp(av[0], "setstatpath") == 0) setstatpath(av + 1); else if (strcmp(av[0], "setonpath") == 0) setpowerpath(av + 1, &onpath, &onpostdata); else if (strcmp(av[0], "setoffpath") == 0) setpowerpath(av + 1, &offpath, &offpostdata); else if (strcmp(av[0], "setcyclepath") == 0) setpowerpath(av + 1, &cyclepath, &cyclepostdata); else if (strcmp(av[0], "stat") == 0) stat_cmd(activecmds, mh, av + 1); else if (strcmp(av[0], "on") == 0) on_cmd(activecmds, mh, av + 1); else if (strcmp(av[0], "off") == 0) off_cmd(activecmds, mh, av + 1); else if (strcmp(av[0], "cycle") == 0) cycle_cmd(activecmds, mh, av + 1); else printf("type \"help\" for a list of commands\n"); } } static int activecmds_find(void *x, void *key) { if (x == key) return 1; return 0; } static void cleanup_powermsg(void *x) { struct powermsg *pm = x; if (pm) { if (strcmp(pm->cmd, "stat") == 0) stat_cleanup(pm); else if (strcmp(pm->cmd, "on") == 0) on_cleanup(pm); else if (strcmp(pm->cmd, "off") == 0) off_cleanup(pm); else if (strcmp(pm->cmd, "cycle") == 0) cycle_cleanup(pm); } } static void shell(CURLM *mh) { struct powermsg *tmp; List activecmds; List delayedcmds; int exitflag = 0; if (!(activecmds = list_create(cleanup_powermsg))) err_exit(TRUE, "list_create"); if (!(delayedcmds = list_create(NULL))) err_exit(TRUE, "list_create"); while (exitflag == 0) { CURLMcode mc; fd_set fdread; fd_set fdwrite; fd_set fderror; struct timeval timeout = {0}; struct timeval *timeoutptr = NULL; int maxfd = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fderror); if (list_is_empty(activecmds) && list_is_empty(delayedcmds)) { printf("redfishpower> "); fflush(stdout); FD_SET(STDIN_FILENO, &fdread); timeoutptr = NULL; maxfd = STDIN_FILENO; } else { struct timeval curl_timeout; long curl_timeout_ms; /* First check if there are any delayedcmds to send or are * waiting. Setup timeout accordingly if one is * waiting */ if (!list_is_empty(delayedcmds)) { ListIterator itr = list_iterator_create(delayedcmds); struct powermsg *delaypm; struct timeval delaytimeout; struct timeval now; gettimeofday(&now, NULL); while ((tmp = list_next(itr))) { if (timercmp(&tmp->delaystart, &now, >)) break; list_remove(itr); if (!list_append(activecmds, tmp)) err_exit(TRUE, "list_append"); } delaypm = list_peek(delayedcmds); if (delaypm) { timersub(&delaypm->delaystart, &now, &delaytimeout); timeout.tv_sec = delaytimeout.tv_sec; timeout.tv_usec = delaytimeout.tv_usec; timeoutptr = &timeout; } } if ((mc = curl_multi_timeout(mh, &curl_timeout_ms)) != CURLM_OK) err_exit(FALSE, "curl_multi_timeout: %s", curl_multi_strerror(mc)); /* Per documentation, wait incremental time then proceed if timeout < 0 */ if (curl_timeout_ms < 0) curl_timeout_ms = INCREMENTAL_WAIT; curl_timeout.tv_sec = curl_timeout_ms / MS_IN_SEC; curl_timeout.tv_usec = (curl_timeout_ms % MS_IN_SEC) * MS_IN_SEC; /* if timeout previously set, must compare */ if (timeoutptr) { /* only compare if curl_timeout_ms > 0, otherwise we'd spin */ if (curl_timeout_ms > 0) { if (timercmp(&curl_timeout, timeoutptr, <)) { timeoutptr->tv_sec = curl_timeout.tv_sec; timeoutptr->tv_usec = curl_timeout.tv_usec; } } } else { timeout.tv_sec = curl_timeout.tv_sec; timeout.tv_usec = curl_timeout.tv_usec; timeoutptr = &timeout; } if ((mc = curl_multi_fdset(mh, &fdread, &fdwrite, &fderror, &maxfd)) != CURLM_OK) err_exit(FALSE, "curl_multi_fdset: %s", curl_multi_strerror(mc)); } /* XXX: use curl_multi_poll/wait on newer versions of curl */ if (select(maxfd+1, &fdread, &fdwrite, &fderror, timeoutptr) < 0) err_exit(TRUE, "select"); if (FD_ISSET(STDIN_FILENO, &fdread)) { char buf[256]; if (fgets(buf, sizeof(buf), stdin)) { char **av; av = argv_create(buf, ""); process_cmd(activecmds, mh, av, &exitflag); argv_destroy(av); } else break; if (exitflag) break; } if (!list_is_empty(activecmds)) { struct CURLMsg *cmsg; int msgq = 0; int stillrunning; if ((mc = curl_multi_perform(mh, &stillrunning)) != CURLM_OK) err_exit(FALSE, "curl_multi_perform: %s", curl_multi_strerror(mc)); do { cmsg = curl_multi_info_read(mh, &msgq); if(cmsg && (cmsg->msg == CURLMSG_DONE)) { struct powermsg *pm = NULL; CURL *eh = cmsg->easy_handle; CURLcode ec; if ((ec = curl_easy_getinfo(eh, CURLINFO_PRIVATE, (char **)&pm)) != CURLE_OK) err_exit(FALSE, "curl_easy_getinfo: %s", curl_easy_strerror(ec)); if (!pm) err_exit(FALSE, "private data not set in easy handle"); if (cmsg->data.result != 0) { printf("%s: %s\n", pm->hostname, "error"); if (verbose) printf("%s: %s\n", pm->hostname, curl_easy_strerror(cmsg->data.result)); } else { if (strcmp(pm->cmd, "stat") == 0) stat_process(pm); else if (strcmp(pm->cmd, "on") == 0) on_process(delayedcmds, pm); else if (strcmp(pm->cmd, "off") == 0) off_process(delayedcmds, pm); else if (strcmp(pm->cmd, "cycle") == 0) cycle_process(pm); } fflush(stdout); list_delete_all(activecmds, activecmds_find, pm); } } while (cmsg); } } list_destroy(activecmds); list_destroy(delayedcmds); } static void usage(void) { fprintf(stderr, "Usage: redfishpower <--hostname host(s) | --hostsfile file> [OPTIONS]\n" " OPTIONS:\n" " -H, --header Set extra header string\n" " -S, --statpath Set stat path\n" " -O, --onpath Set on path\n" " -F, --offpath Set off path\n" " -C, --cyclepath Set cycle path\n" " -P, --onpostdata Set on post data\n" " -G, --offpostdata Set off post data\n" " -D, --cyclepostdata Set cycle post data\n" " -v, --verbose Increase output verbosity\n" ); exit(1); } /* copied from xread.c */ static void _remove_trailing_whitespace(char *s) { char *p = s + strlen(s) - 1; while (p >= s && isspace(*p)) *p-- = '\0'; } static void readhostsfile(const char *file) { char buf[1024]; FILE *stream; if (!hosts) { if (!(hosts = hostlist_create(NULL))) err_exit(TRUE, "hostlist_create"); } if (!(stream = fopen(file, "r"))) err_exit(TRUE, "error opening file %s", file); while (fgets(buf, 1024, stream)) { _remove_trailing_whitespace(buf); /* ignore empty lines */ if (strlen(buf) == 0) continue; /* ignore commented lines */ if (buf[0] == '#') continue; if (!hostlist_push(hosts, buf)) err_exit(TRUE, "hostlist_push error on %s", optarg); } fclose(stream); } int main(int argc, char *argv[]) { CURLM *mh; CURLcode ec; int c; err_init(basename(argv[0])); while ((c = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != EOF) { switch (c) { case 'h': /* --hostname */ if (hosts) { if (!hostlist_push(hosts, optarg)) err_exit(TRUE, "hostlist_push error on %s", optarg); } else { if (!(hosts = hostlist_create(optarg))) err_exit(TRUE, "hostlist_create error on %s", optarg); } break; case 'f': /* --hostsfile */ readhostsfile(optarg); break; case 'H': /* --header */ header = xstrdup(optarg); break; case 'S': /* --statpath */ statpath = xstrdup(optarg); break; case 'O': /* --onpath */ onpath = xstrdup(optarg); break; case 'F': /* --offpath */ offpath = xstrdup(optarg); break; case 'C': /* --cyclepath */ cyclepath = xstrdup(optarg); break; case 'P': /* --onpostdata */ onpostdata = xstrdup(optarg); break; case 'G': /* --offpostdata */ offpostdata = xstrdup(optarg); break; case 'D': /* --cyclepostdata */ cyclepostdata = xstrdup(optarg); break; case 'v': /* --verbose */ verbose = 1; break; default: usage(); break; } } if (optind < argc) usage(); if (!hosts) usage(); if ((ec = curl_global_init(CURL_GLOBAL_ALL)) != CURLE_OK) err_exit(FALSE, "curl_global_init: %s", curl_easy_strerror(ec)); if (!(mh = curl_multi_init())) err_exit(FALSE, "curl_multi_init failed"); shell(mh); curl_multi_cleanup(mh); xfree(userpwd); hostlist_destroy(hosts); xfree(statpath); xfree(onpath); xfree(onpostdata); xfree(offpath); xfree(offpostdata); xfree(cyclepath); xfree(cyclepostdata); exit(0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/scripts/000077500000000000000000000000001415616035500151325ustar00rootroot00000000000000powerman-2.3.27/scripts/Makefile.am000066400000000000000000000004511415616035500171660ustar00rootroot00000000000000if HAVE_SYSTEMD systemdsystemunit_SCRIPTS = powerman.service systemdtmpdir_ddir = ${prefix}/lib/tmpfiles.d systemdtmpdir_d_SCRIPTS = tmpfiles.d/powerman.conf else initconfdir = $(sysconfdir)/init.d initconf_SCRIPTS = powerman endif EXTRA_DIST = powerman.service powerman tmpfiles.d/powerman.conf powerman-2.3.27/scripts/powerman.in000066400000000000000000000336061415616035500173220ustar00rootroot00000000000000#!/bin/sh ############################################################################### # $Id: powerman.init.in 808 2008-01-09 19:20:23Z dun $ ############################################################################### # Originally written by Chris Dunlap for ConMan: # Copyright (C) 2007-2008 Lawrence Livermore National Security, LLC. # Copyright (C) 2001-2007 The Regents of the University of California. # UCRL-CODE-2002-009. ############################################################################### # chkconfig: 2345 95 5 # Description: Start/Stop the PowerMan (remote power manager) daemon. ############################################################################### ### BEGIN INIT INFO # Provides: powerman # Required-Start: $local_fs $named $network # Required-Stop: $local_fs $named $network # Should-Start: $remote_fs $syslog $time # Should-Stop: $remote_fs $syslog $time # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start/Stop the PowerMan (remote power manager) daemon. ### END INIT INFO ############################################################################### unset DESC DAEMON DAEMON_ARGS CONFIG PIDFILE NICE USER SIGHUP_RELOAD prefix="@prefix@" exec_prefix="@exec_prefix@" sbindir="@sbindir@" sysconfdir="@sysconfdir@" localstatedir="@localstatedir@" DESC="PowerMan" DAEMON="$sbindir/powermand" #DAEMON_ARGS= CONFIG=$sysconfdir/powerman/powerman.conf PIDFILE="$localstatedir/run/powerman/powermand.pid" #NICE= USER=@RUN_AS_USER@ #SIGHUP_RELOAD= ############################################################################### service_init () { # Determine the system type and initialize the environment. # # Note that the shell positional parameters must be preserved when calling # this function in order for SuSE to initialize its environment properly. ## PATH=/sbin:/usr/sbin:/bin:/usr/bin DAEMON_NAME="`basename \"$DAEMON\"`" SCRIPT_NAME="`basename \"$0\" .init | sed 's/^[SK][0-9][0-9]*//'`" SIGTERM_TIMEOUT="3" STATUS=0 # Read configuration defaults to override variables: # $DAEMON_ARGS, $CONFIG, $PIDFILE, $USER, $NICE, $SIGHUP_RELOAD ## for dir in "$sysconfdir/default" "$sysconfdir/sysconfig"; do [ -r "$dir/$SCRIPT_NAME" ] && . "$dir/$SCRIPT_NAME" done [ -z "$DAEMON_ARGS" -a -n "$OPTIONS" ] && DAEMON_ARGS="$OPTIONS" [ "`id | sed 's/^uid=\([0-9]*\).*/\1/'`" -ne 0 ] && unset USER expr -- "$NICE" : '[0-9]*$' >/dev/null 2>&1 && NICE="+$NICE" [ -n "$SIGHUP_RELOAD" -a "$SIGHUP_RELOAD" != 0 ] \ && RELOAD=1 || unset RELOAD if [ -f /etc/debian_version -a -x /sbin/start-stop-daemon ]; then SYSTEM="DEBIAN" [ -x "$DAEMON" ] || exit 0 # pkg removed but not purged [ -r /etc/default/rcS ] && . /etc/default/rcS [ -r /lib/init/vars.sh ] && . /lib/init/vars.sh [ -r /lib/lsb/init-functions ] && . /lib/lsb/init-functions elif [ -f /etc/redhat-release -a -r /etc/init.d/functions ]; then SYSTEM="REDHAT" . /etc/init.d/functions RH_SUBSYS="/var/lock/subsys/$DAEMON_NAME" elif [ -f /etc/SuSE-release -a -r /etc/rc.status ]; then SYSTEM="SUSE" . /etc/rc.status rc_reset elif [ -r /lib/lsb/init-functions ]; then SYSTEM="LSB" . /lib/lsb/init-functions else SYSTEM="OTHER" fi # Exit if the package has been removed. ## [ -x "$DAEMON" ] || exit 5 # LSB: program not installed # Exit if the configuration has been removed. ## [ -z "$CONFIG" -o -r "$CONFIG" ] || exit 6 # LSB: program not configured } service_fini () { # Return the exit status. ## case $SYSTEM in SUSE) rc_exit ;; DEBIAN|REDHAT|LSB|*) exit $STATUS ;; esac } service_start () { # Start the service. # # Required by LSB, where running "start" on a service already running should be # considered successful. ## log_init "Starting $DESC" "$DAEMON_NAME" case $SYSTEM in DEBIAN) if $0 status >/dev/null 2>&1; then STATUS=0 else ERRMSG=`start-stop-daemon --start --quiet \ ${NICE:+"--nicelevel"} ${NICE:+"$NICE"} \ ${USER:+"--chuid"} ${USER:+"$USER"} \ ${PIDFILE:+"--pidfile"} ${PIDFILE:+"$PIDFILE"} \ --exec "$DAEMON" -- $DAEMON_ARGS 2>&1` STATUS=$? fi ;; REDHAT) if $0 status >/dev/null 2>&1; then STATUS=0 else daemon ${NICE:+"$NICE"} ${USER:+"--user"} ${USER:+"$USER"} \ "$DAEMON" $DAEMON_ARGS STATUS=$? fi [ $STATUS -eq 0 ] && touch "$RH_SUBSYS" >/dev/null 2>&1 ;; SUSE) ERRMSG=`startproc ${NICE:+"-n"} ${NICE:+"$NICE"} \ ${USER:+"-u"} ${USER:+"$USER"} \ ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} \ "$DAEMON" $DAEMON_ARGS 2>&1` rc_status -v STATUS=$? ;; LSB) if [ -n "$USER" ]; then ERRMSG=`su "$USER" -c "/sbin/start_daemon \ ${NICE:+\"-n\"} ${NICE:+\"$NICE\"} \ ${PIDFILE:+\"-p\"} ${PIDFILE:+\"$PIDFILE\"} \ \"$DAEMON\" $DAEMON_ARGS" 2>&1` else ERRMSG=`start_daemon ${NICE:+"-n"} ${NICE:+"$NICE"} \ ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} "$DAEMON" $DAEMON_ARGS 2>&1` fi STATUS=$? ;; *) if $0 status >/dev/null 2>&1; then STATUS=0 else [ -n "$NICE" ] && nice="nice -n $NICE" if [ -n "$USER" ]; then ERRMSG=`su "$USER" -c "$nice \"$DAEMON\" $DAEMON_ARGS" 2>&1` else ERRMSG=`$nice "$DAEMON" $DAEMON_ARGS 2>&1` fi STATUS=$? fi ;; esac log_fini "$STATUS" "$ERRMSG" } service_stop () { # Stop the service. # # Required by LSB, where running "stop" on a service already stopped or not # running should be considered successful. ## log_init "Stopping $DESC" "$DAEMON_NAME" case $SYSTEM in DEBIAN) if ! $0 status >/dev/null 2>&1; then STATUS=0 else start-stop-daemon --stop --quiet \ ${PIDFILE:+"--pidfile"} ${PIDFILE:+"$PIDFILE"} \ --name "$DAEMON_NAME" ${SIGTERM_TIMEOUT:+"--retry"} \ ${SIGTERM_TIMEOUT:+"$SIGTERM_TIMEOUT"} >/dev/null 2>&1 STATUS=$? fi ;; REDHAT) if ! $0 status >/dev/null 2>&1; then STATUS=0 else killproc "$DAEMON" STATUS=$? fi [ $STATUS -eq 0 ] && rm -f "$RH_SUBSYS" >/dev/null 2>&1 ;; SUSE) killproc ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} \ ${SIGTERM_TIMEOUT:+"-t"} ${SIGTERM_TIMEOUT:+"$SIGTERM_TIMEOUT"} \ "$DAEMON" rc_status -v ;; LSB) killproc ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} "$DAEMON" STATUS=$? ;; *) signal_process "$DAEMON" rc=$? [ $rc -eq 0 -o $rc -eq 2 ] && STATUS=0 || STATUS=1 ;; esac log_fini "$STATUS" [ -f "$PIDFILE" ] && rm -f "$PIDFILE" } service_restart () { # Stop and restart the service if it is already running; # otherwise, start the service. # # Required by LSB, where running "restart" on a service already stopped or not # running should be considered successful. ## if $0 status >/dev/null 2>&1; then $0 stop && $0 start else $0 start fi case $SYSTEM in SUSE) rc_status ;; DEBIAN|REDHAT|LSB|*) STATUS=$? ;; esac } service_try_restart () { # Restart the service if it is already running. # # Optional for LSB, where running "try-restart" on a service already stopped or # not running should be considered successful. # Also known as "condrestart" by RedHat. ## case $SYSTEM in REDHAT) [ -f "$RH_SUBSYS" ] && $0 restart || : STATUS=$? ;; SUSE) $0 status >/dev/null 2>&1 && $0 restart || rc_reset rc_status ;; DEBIAN|LSB|*) $0 status >/dev/null 2>&1 && $0 restart || : STATUS=$? ;; esac } service_reload () { # Reload the configuration without stopping and restarting the service. # # Optional for LSB. ## [ -z "$RELOAD" ] && STATUS=3 # LSB: unimplemented feature log_init "Reloading $DESC" "$DAEMON_NAME" case $SYSTEM in DEBIAN) if [ -n "$RELOAD" ]; then start-stop-daemon --stop --quiet --signal HUP \ ${PIDFILE:+"--pidfile"} ${PIDFILE:+"$PIDFILE"} \ --name "$DAEMON_NAME" >/dev/null 2>&1 STATUS=$? fi ;; REDHAT) if [ -n "$RELOAD" ]; then killproc "$DAEMON" -HUP STATUS=$? else echo_failure fi ;; SUSE) if [ -n "$RELOAD" ]; then killproc -HUP ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} "$DAEMON" else rc_failed $STATUS fi rc_status -v ;; LSB) if [ -n "$RELOAD" ]; then killproc ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} "$DAEMON" -HUP STATUS=$? fi ;; *) if [ -n "$RELOAD" ]; then signal_process "$DAEMON" "HUP" STATUS=$? fi ;; esac log_fini "$STATUS" } service_force_reload () { # Reload the configuration if the service supports this; # otherwise, restart the service if it is already running. # # Required by LSB, where running "force-reload" on a service already stopped or # not running should be considered successful. ## if [ -n "$RELOAD" ]; then $0 reload else $0 try-restart fi case $SYSTEM in SUSE) rc_status ;; DEBIAN|REDHAT|LSB|*) STATUS=$? ;; esac } service_status () { # Print the current status of the service. # # Required by LSB. ## case $SYSTEM in REDHAT) status "$DAEMON" STATUS=$? ;; SUSE) printf "Checking for service $DESC: " checkproc ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} "$DAEMON" rc_status -v ;; LSB) printf "Checking status of $DESC: " pids=`pidofproc ${PIDFILE:+"-p"} ${PIDFILE:+"$PIDFILE"} \ "$DAEMON" 2>/dev/null` STATUS=$? if [ $STATUS -eq 0 -a -n "$pids" ]; then echo "running." elif [ $STATUS -ne 0 -a -s "$PIDFILE" ]; then echo "dead." else echo "stopped." fi ;; DEBIAN|*) printf "Checking status of $DESC: " pids=`query_pids "$DAEMON" "$PIDFILE"` rc=$? if [ $rc -eq 0 -a -n "$pids" ]; then echo "running." STATUS=0 # LSB: program is running elif [ $rc -ne 0 -a -s "$PIDFILE" ]; then echo "dead." STATUS=1 # LSB: program is dead & pidfile exists elif [ $rc -ne 0 ]; then echo "stopped." STATUS=3 # LSB: program is not running else echo "unknown." STATUS=4 # LSB: program status unknown fi ;; esac } query_pids () { # Writes the matching PIDs to stdout. # Returns 0 on success (ie, pids found). ## PROCNAME="$1" PIDFILE="$2" if type pgrep >/dev/null 2>&1; then pids=`pgrep -d ' ' -x "\`basename \"$PROCNAME\"\`" 2>/dev/null` rc=$? elif type pidof >/dev/null 2>&1; then pids=`pidof -o $$ -x "$PROCNAME" 2>/dev/null` rc=$? else pids=`(ps awx -o pid -o command || ps -e -f -o pid -o args) 2>/dev/null \ | tail +2 | egrep "( |/)$PROCNAME( |$)" | grep -v egrep \ | sed 's/ *\([0-9]*\).*/\1/' | sort -n | tr '\012' ' '` [ -n "$pids" ] && rc=0 || rc=1 fi unset pids_running if [ -n "$pids" -a -r "$PIDFILE" ]; then read pid_line < "$PIDFILE" for pid in $pid_line; do expr -- "$pid" : '[0-9]*$' >/dev/null 2>&1 \ && expr -- " $pids " : ".* $pid .*" >/dev/null 2>&1 \ && pids_running="$pids_running $pid" done [ -n "$pids_running" ] && pids=$pids_running fi echo $pids return $rc } signal_process () { # Returns 0 on success, 1 if kill failed, 2 if PROCNAME is not running. ## PROCNAME="$1" SIGNUM="$2" pids=`query_pids "$DAEMON" "$PIDFILE"` [ $? -ne 0 -o -z "$pids" ] && return 2 kill ${SIGNUM:+"-$SIGNUM"} $pids >/dev/null 2>&1 [ $? -ne 0 ] && return 1 [ -n "$SIGNUM" ] && return 0 pids=`query_pids "$DAEMON" "$PIDFILE"` [ $? -ne 0 -o -z "$pids" ] && return 0 [ -z "$SIGTERM_TIMEOUT" ] && return 1 sleep "$SIGTERM_TIMEOUT" kill -KILL $pids >/dev/null 2>&1 pids=`query_pids "$DAEMON" "$PIDFILE"` [ $? -ne 0 -o -z "$pids" ] && return 0 return 1 } log_init () { # Output informational message at beginning of action. ## MESSAGE="$1" PROCNAME="$2" case $SYSTEM in DEBIAN) if [ "$VERBOSE" != no ]; then if type log_daemon_msg >/dev/null 2>&1; then log_daemon_msg "$MESSAGE" "$PROCNAME" else printf "$MESSAGE: $PROCNAME" fi fi ;; REDHAT|SUSE|LSB|*) printf "$MESSAGE: " ;; esac } log_fini () { # Output informational/error message at end of action. ## STATUS="$1" ERRMSG="$2" case $SYSTEM in DEBIAN) if [ "$VERBOSE" != no ]; then if ( type log_end_msg && type log_failure_msg ) >/dev/null 2>&1; then log_end_msg "$STATUS" [ $STATUS -eq 0 -o -z "$ERRMSG" ] || log_failure_msg "$ERRMSG" else [ $STATUS -eq 0 ] && echo "." || echo " (failed)." [ $STATUS -eq 0 -o -z "$ERRMSG" ] || echo "$ERRMSG" >&2 fi fi ;; REDHAT) echo ;; SUSE) [ $STATUS -eq 0 -o -z "$ERRMSG" ] || echo "$ERRMSG" >&2 ;; LSB|*) [ $STATUS -eq 0 ] && echo "." || echo " (failed)." [ $STATUS -eq 0 -o -z "$ERRMSG" ] || echo "$ERRMSG" >&2 ;; esac } ############################################################################### service_init "$@" case "$1" in start) service_start ;; stop) service_stop ;; restart) service_restart ;; try-restart|condrestart) service_try_restart ;; reload) service_reload ;; force-reload) service_force_reload ;; status) service_status ;; *) echo "Usage: `basename \"$0\"`" \ "(start|stop|restart|try-restart|reload|force-reload|status)" >&2 exit 2 # LSB: invalid or excess argument(s) ;; esac service_fini powerman-2.3.27/scripts/powerman.service000066400000000000000000000003531415616035500203450ustar00rootroot00000000000000[Unit] Description=PowerMan After=syslog.target network.target [Service] Type=forking PrivateTmp=yes User=daemon Group=daemon ExecStart=/usr/sbin/powermand PIDFile=/var/run/powerman/powermand.pid [Install] WantedBy=multi-user.target powerman-2.3.27/scripts/tmpfiles.d/000077500000000000000000000000001415616035500171775ustar00rootroot00000000000000powerman-2.3.27/scripts/tmpfiles.d/powerman.conf.in000066400000000000000000000000651415616035500223040ustar00rootroot00000000000000d @X_LOCALSTATEDIR@/run/powerman 755 daemon daemon powerman-2.3.27/snmppower/000077500000000000000000000000001415616035500154755ustar00rootroot00000000000000powerman-2.3.27/snmppower/Makefile.am000066400000000000000000000003171415616035500175320ustar00rootroot00000000000000AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = -I$(top_srcdir)/libcommon sbin_PROGRAMS = snmppower snmppower_SOURCES = snmppower.c snmppower_LDADD = $(top_builddir)/libcommon/libcommon.a $(LIBNETSNMP) $(LIBFORKPTY) powerman-2.3.27/snmppower/snmppower.c000066400000000000000000000227571415616035500177100ustar00rootroot00000000000000/*****************************************************************************\ * Copyright (C) 2010 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "xtypes.h" #include "xmalloc.h" #include "error.h" #include "argv.h" #define OPTIONS "h:" static struct option longopts[] = { {"hostname", required_argument, 0, 'h' }, {0,0,0,0}, }; static void get (char **av, struct snmp_session **ssp) { struct snmp_pdu *pdu; struct snmp_pdu *response; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars; int status; if (av[1] == NULL) { err (FALSE, "missing oid"); return; } if (*ssp == NULL) { err (FALSE, "start session first"); return; } pdu = snmp_pdu_create (SNMP_MSG_GET); if (!get_node (av[1], anOID, &anOID_len)) { snmp_free_pdu (pdu); printf ("error parsing oid\n"); return; } snmp_add_null_var (pdu, anOID, anOID_len); status = snmp_synch_response (*ssp, pdu, &response); if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { for (vars = response->variables; vars; vars = vars->next_variable) { switch (vars->type) { case ASN_OCTET_STR: printf("%s: %*s\n", av[1], (int)vars->val_len, vars->val.string); break; case ASN_INTEGER: printf("%s: %ld\n", av[1], *vars->val.integer); break; default: print_variable (vars->name, vars->name_length, vars); break; } } } else { if (status == STAT_SUCCESS) err_exit (FALSE, "error in packet: %s", snmp_errstring (response->errstat)); else snmp_sess_perror ("snmpget", *ssp); } if (response) snmp_free_pdu (response); } static void set (char **av, struct snmp_session **ssp) { struct snmp_pdu *pdu; struct snmp_pdu *response; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars; int status; if (av[1] == NULL) { err (FALSE, "missing oid"); return; } if (av[2] == NULL) { err (FALSE, "missing type"); return; } if (av[3] == NULL) { err (FALSE, "missing value"); return; } if (*ssp == NULL) { err (FALSE, "start session first"); return; } pdu = snmp_pdu_create (SNMP_MSG_SET); if (!get_node (av[1], anOID, &anOID_len)) { snmp_free_pdu (pdu); printf ("error parsing oid\n"); return; } snmp_add_var (pdu, anOID, anOID_len, *(av[2]), av[3]); status = snmp_synch_response (*ssp, pdu, &response); if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { for (vars = response->variables; vars; vars = vars->next_variable) { switch (vars->type) { case ASN_OCTET_STR: printf("%s: %*s\n", av[1], (int)vars->val_len, vars->val.string); break; case ASN_INTEGER: printf("%s: %ld\n", av[1], *vars->val.integer); break; default: print_variable (vars->name, vars->name_length, vars); break; } } } else { if (status == STAT_SUCCESS) err_exit (FALSE, "error in packet: %s", snmp_errstring (response->errstat)); else snmp_sess_perror ("snmpset", *ssp); } if (response) snmp_free_pdu (response); } static void start_v1v2c (char **av, int version, char *hostname, struct snmp_session **ssp) { struct snmp_session session; if (av[1] == NULL) { err (FALSE, "missing community"); return; } if (*ssp) { err (FALSE, "finish current session first"); return; } snmp_sess_init (&session); session.version = version; session.community = (u_char *)xstrdup (av[1]); session.community_len = strlen (av[1]); session.peername = hostname; if (!(*ssp = snmp_open (&session))) { err (FALSE, "snmp_open failed"); xfree (session.community); } } static void start_v3 (char **av, char *hostname, struct snmp_session **ssp) { struct snmp_session session; if (av[1] == NULL) { err (FALSE, "missing security name"); return; } if (av[2] == NULL) { err (FALSE, "missing passphrase"); return; } if (strlen (av[2]) < 8) { err (FALSE, "passphrase must be at least 8 characters"); return; } snmp_sess_init (&session); session.version = SNMP_VERSION_3; session.peername = hostname; session.securityName = xstrdup (av[1]); session.securityNameLen = strlen (av[1]); session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; session.securityAuthProto = usmHMACMD5AuthProtocol; session.securityAuthProtoLen = sizeof (usmHMACMD5AuthProtocol) / sizeof (oid); session.securityAuthKeyLen = USM_AUTH_KU_LEN; if (generate_Ku (session.securityAuthProto, session.securityAuthProtoLen, (u_char *)av[2], strlen (av[2]), session.securityAuthKey, &session.securityAuthKeyLen) != SNMPERR_SUCCESS) { err (FALSE, "Error generating Ku from auth pass phrase"); } if (!(*ssp = snmp_open (&session))) err (FALSE, "snmp_open failed"); } static void mib (char **av, struct snmp_session **ssp) { static int initialized = 0; if (av[1] == NULL) { err (FALSE, "missing name"); return; } if (!initialized) { init_mib (); initialized = 1; } netsnmp_read_module (av[1]); /* prints its own errors */ } static void finish (char **av, struct snmp_session **ssp) { snmp_close (*ssp); *ssp = NULL; } static void help (void) { printf ("Valid commands are:\n"); printf (" start_v1 community\n"); printf (" start_v2c community\n"); printf (" start_v3 name passphrase\n"); printf (" mib name\n"); printf (" finish\n"); printf (" get oid\n"); printf (" set oid type value\n"); } static int docmd (char **av, char *hostname, struct snmp_session **ssp) { int rc = 0; if (av[0] != NULL) { if (strcmp (av[0], "help") == 0) help (); else if (strcmp (av[0], "get") == 0) get (av, ssp); else if (strcmp (av[0], "set") == 0) set (av, ssp); else if (strcmp (av[0], "start_v1") == 0) start_v1v2c (av, SNMP_VERSION_1, hostname, ssp); else if (strcmp (av[0], "start_v2c") == 0) start_v1v2c (av, SNMP_VERSION_2c, hostname, ssp); else if (strcmp (av[0], "start_v3") == 0) start_v3 (av, hostname, ssp); else if (strcmp (av[0], "mib") == 0) mib (av, ssp); else if (strcmp (av[0], "finish") == 0) finish (av, ssp); else printf ("type \"help\" for a list of commands\n"); } return rc; } static void shell (char *hostname) { char buf[128]; char **av; int rc = 0; struct snmp_session *ss = NULL; while (rc == 0) { printf ("snmppower> "); fflush (stdout); if (fgets (buf, sizeof (buf), stdin)) { av = argv_create (buf, ""); rc = docmd (av, hostname, &ss); argv_destroy (av); } else rc = 1; } } static void usage (void) { fprintf (stderr, "Usage: snmppower -h hostname\n"); exit(1); } int main (int argc, char *argv[]) { int c; char *hostname = NULL; err_init (basename(argv[0])); init_snmp ("snmppower"); while ((c = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != EOF) { switch (c) { case 'h': /* --hostname */ hostname = optarg; break; default: usage(); break; } } if (optind != argc) usage (); if (hostname == NULL) usage (); shell(hostname); exit(0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/000077500000000000000000000000001415616035500144225ustar00rootroot00000000000000powerman-2.3.27/test/Makefile.am000066400000000000000000000053471415616035500164670ustar00rootroot00000000000000sbin_PROGRAMS = vpcd check_PROGRAMS = \ tpl \ tregex \ targv \ baytech \ icebox \ gpib \ dli \ cyclades \ ipmipower \ redfishpower \ cli \ ilom \ lom \ swpdu \ openbmc-httppower \ redfish-httppower dist_check_SCRIPTS = \ pm-sim \ mkconf.pl \ $(TESTS) TESTS_ENVIRONMENT = env TESTS_ENVIRONMENT += "PATH_POWERMAN=$(top_builddir)/powerman/powerman" TESTS_ENVIRONMENT += "PATH_POWERMAND=$(top_builddir)/powermand/powermand" TESTS_ENVIRONMENT += "PATH_ETC=$(top_builddir)/etc" TESTS_ENVIRONMENT += "PATH_POWERMAN_STONITH=$(top_srcdir)/heartbeat/powerman" TESTS_ENVIRONMENT += "TEST_SRCDIR=$(top_srcdir)/test" TESTS_ENVIRONMENT += "TEST_BUILDDIR=$(top_builddir)/test" TESTS = t00 t01 t02 t03 t04 t05 t06 t07 t08 t09 t10 t11 t12 t13 \ t14 t15 t16 t17 t18 t19 t20 t21 t22 t23 t24 t25 t26 t27 \ t28 t29 t30 t31 t32 t33 t34 t35 t36 t37 t38 t39 t40 t41 \ t42 t43 t44 t46 t47 t48 t49 t50 t51 t52 t53 t54 t55 \ t56 t57 t58 t59 t60 t61 t62 t63 XFAIL_TESTS = CLEANFILES = *.out *.err *.diff AM_CFLAGS = @GCCWARN@ AM_CPPFLAGS = \ -I$(top_srcdir)/libcommon \ -I$(top_srcdir)/libpowerman \ -I$(top_srcdir)/liblsd common_ldadd = \ $(top_builddir)/liblsd/liblsd.a \ $(top_builddir)/libcommon/libcommon.a \ $(LIBFORKPTY) vpcd_SOURCES = vpcd.c vpcd_LDADD = $(common_ldadd) tpl_SOURCES = tpl.c tpl_LDADD = $(common_ldadd) tregex_SOURCES = tregex.c tregex_LDADD = $(common_ldadd) targv_SOURCES = targv.c targv_LDADD = $(common_ldadd) baytech_SOURCES = baytech.c baytech_LDADD = $(common_ldadd) icebox_SOURCES = icebox.c icebox_LDADD = $(common_ldadd) swpdu_SOURCES = swpdu.c swpdu_LDADD = $(common_ldadd) gpib_SOURCES = gpib.c gpib_LDADD = $(common_ldadd) dli_SOURCES = dli.c dli_LDADD = $(common_ldadd) ilom_SOURCES = ilom.c ilom_LDADD = $(common_ldadd) lom_SOURCES = lom.c lom_LDADD = $(common_ldadd) cyclades_SOURCES = cyclades.c cyclades_LDADD = $(common_ldadd) ipmipower_SOURCES = ipmipower.c ipmipower_LDADD = $(common_ldadd) redfishpower_SOURCES = redfishpower.c redfishpower_LDADD = $(common_ldadd) openbmc_httppower_SOURCES = openbmc-httppower.c openbmc_httppower_LDADD = $(common_ldadd) redfish_httppower_SOURCES = redfish-httppower.c redfish_httppower_LDADD = $(common_ldadd) cli_SOURCES = cli.c cli_LDADD = -L$(top_builddir)/libpowerman -lpowerman check_DATA = \ mcr.conf sierra.conf \ t07.conf t09.conf t10.conf t17.conf t18.conf t19.conf t20.conf \ t21.conf t22.conf t23.conf t24.conf t25.conf t26.conf t27.conf \ t28.conf t29.conf t30.conf t31.conf t32.conf t33.conf t34.conf \ t35.conf t36.conf t37.conf t38.conf t39.conf t40.conf t41.conf \ t42.conf t43.conf t44.conf t46.conf t47.conf t48.conf \ t49.conf t50.conf t51.conf t53.conf t54.conf t55.conf t60.conf \ t61.conf test4.conf test.conf EXTRA_DIST = $(TESTS:%=%.exp) t53.dev powerman-2.3.27/test/README000066400000000000000000000061161415616035500153060ustar00rootroot00000000000000On running 'make check': The test methodology here is to run the powerman daemon as a child of the powerman client, connected via pty. The powerman daemon in turn spawns copies of 'vpcd' (virtual power control device), connected via ptys. Each test starts a fresh powerman+powermand+vpcd(s) so no state is preserved between tests. Root privilage or available well known ports are not required to run these tests. The client can send multiple commands, so we can send commands and change state and then query the state to see what happened. The output of each command is compared against expected output. The tests are summarized here: t00-t03 pluglist.c tests using tpl.c. t04 argv.c test using targv.c. t05 xregex.c tests using tregex.c. t06 Check power status query options pm --query-all --query t1 --query t[3-5] t07 Check power status query options with no status_all script implemented. pm --query-all --query t1 --query t[3-5] t08 Telemetry option check. pm --telemetry --query-all t09 Check handling of large volume (size < min) of data returned by device. pm --telemetry --query-all t10 Check handling of large volume (min < size < max) of data returned by device. pm --telemetry --query-all t11 Check power options. pm --query-all --on t4 --query-all --off t4 --query-all \ --cycle t5 --query-all t12 Check handling of "dangling" target args. pm --query t1 t2 t13 Check beacon options: pm --beacon-all --flash t[13-15] --beacon-all --unflash t13 \ --beacon-all --beacon t13 --beacon t14 t14 Check temperature options: pm --temp-all --temp t13 --temp t[13-15] t15 Check reset options pm --reset t1 --reset t[3-5] t16 Check list and device options pm --list \ --device-all --query t1 --device-all --query t1 --device test0 t17 Check handling of large volume (max < size) of data returned by device. pm --telemetry --query-all t18 Check handling of large volume (2*max < size) of data returned by device. pm --telemetry --query-all t19 Check timeout/reconnect. pm -I --query-all t20 Check timeout/reconnect with partial success (32 plugs). pm -I --query t[14-18] --query t[16-31] t21-t22 Test baytech-rpc3-nc script using baytech.c. t23-t24 Test baytech-rpc28-nc script using baytech.c. t25-t26 Ensure that delays are process expeditiously. t27-t28 Test baytech script using baytech.c. t29-t30 Test icebox v3 using icebox.c. t31-t32 Test icebox v2 using icebox.c. t33-t34 Test icebox v4 using icebox.c. t35 Powerman as a pseudo-power controller, direct mapping. t36 Powerman as a pseudo-power controller, remapped. t37-38 Test hp3488 using gpib.c t39-40 Test ics8064 using gpib.c t41 Test plmpower using plm.c t42-t43 Test DLI LPC using dli.c t44 Test Sun ILOM using ilom.c t45 Test Rackable Phantom using phantom.c t46 Test cyclades pm8/pm10 using cyclades.c t47 Test FreeIPMI ipmipower using ipmipower.c t48 Run some simple vpcd tests using sockets. t49 Test libpowerman API t50 Test bashfun demo script. t51 Test Sun LOM using lom.c t61 Test httppower openbmc using openbmc-httppower.c powerman-2.3.27/test/baytech.c000066400000000000000000000610031415616035500162050ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* baytech.c - baytech simulator */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop_rpc3_de(void); static void _prompt_loop_rpc28_nc(void); static void _prompt_loop_rpc3_nc(void); static void _prompt_loop_rpc3(void); typedef enum { NONE, RPC3, RPC3_NC, RPC28_NC, RPC3_DE } baytype_t; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; baytype_t personality = NONE; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "rpc3") == 0) personality = RPC3; else if (strcmp(optarg, "rpc3-nc") == 0) personality = RPC3_NC; else if (strcmp(optarg, "rpc28-nc") == 0) personality = RPC28_NC; else if (strcmp(optarg, "rpc3-de") == 0) personality = RPC3_DE; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } switch (personality) { case NONE: usage(); case RPC3: _prompt_loop_rpc3(); break; case RPC3_NC: _prompt_loop_rpc3_nc(); break; case RPC28_NC: _prompt_loop_rpc28_nc(); break; case RPC3_DE: _prompt_loop_rpc3_de(); break; } exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p rpc3|rpc3-nc|rpc28-nc|rpc3-de\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } #define RPC28_NC_BANNER "\ RPC-28 Series\n\ (C) 2000 by BayTech\n\ F3.01\n\ \n\ Option(s) Installed:\n\ True RMS Current\n\ Internal Temperature\n\ True RMS Voltage\n\ \n" #define RPC28_NC_PROMPT "RPC-28>" #define RPC28_NC_PROMPT2 "RPC-28A>" #define RPC28_NC_STATUS "\r\n\ Outlet 1-10 Outlet 11-21 \r\n\ Average Power: 619 Watts : 5 Watts \r\n\ True RMS Voltage: 117.9 Volts : 118.8 Volts \r\n\ True RMS Current: 5.4 Amps : 0.1 Amps\r\n\ Maximum Detected: 6.9 Amps : 2.8 Amps\r\n\ Circuit Breaker: Good : Good \r\n\ \r\n\ Internal Temperature: 30.0 C\r\n\ \r\n\ \r\n\ 1)...Outlet 1 : %s 2)...Outlet 2 : %s \r\n\ 3)...Outlet 3 : %s 4)...Outlet 4 : %s \r\n\ 5)...Outlet 5 : %s 6)...Outlet 6 : %s \r\n\ 7)...Outlet 7 : %s 8)...Outlet 8 : %s \r\n\ 9)...Outlet 9 : %s 10)...Outlet 10 : %s \r\n\ 11)...Outlet 11 : %s 12)...Outlet 12 : %s \r\n\ 13)...Outlet 13 : %s 14)...Outlet 14 : %s \r\n\ 15)...Outlet 15 : %s 16)...Outlet 16 : %s \r\n\ 17)...Outlet 17 : %s 18)...Outlet 18 : %s \r\n\ 19)...Outlet 19 : %s 20)...Outlet 20 : %s \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC28_NC_HELP "\r\n\ On n --Turn on an Outlet, n=0,1...20,all\r\n\ Off n --Turn off an Outlet, n=0,1...20,all\r\n\ Reboot n --Reboot an Outlet, n=0,1...20,all\r\n\ Status --RPC-28 Status\r\n\ Config --Enter configuration mode\r\n\ Lock n --Locks Outlet(s) state, n=0,1...20,all\r\n\ Unlock n --Unlock Outlet(s) state, n=0,1...20,all\r\n\ Current --Display True RMS Current\r\n\ Clear --Reset the maximum detected current\r\n\ Temp --Read current temperature\r\n\ Voltage --Display True RMS Voltage\r\n\ Logout --Logoff\r\n\ Logoff --Logoff\r\n\ Exit --Logoff\r\n\ Password --Changes the current user password\r\n\ Whoami --Displays the current user name\r\n\ Unitid --Displays the unit ID\r\n\ Help --This Command\r\n\ \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC28_NC_TEMP "\r\n\ Internal Temperature: 30.0 C\r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC28_NC_VOLTAGE "\r\n\ Outlet 1-10 Outlet 11-21 \r\n\ True RMS Voltage: 118.0 Volts : 118.7 Volts \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC28_NC_CURRENT "\r\n\ Outlet 1-10 Outlet 11-21 \r\n\ True RMS Current: 5.5 Amps : 0.1 Amps\r\n\ Maximum Detected: 6.9 Amps : 2.8 Amps\r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" static void _prompt_loop_rpc28_nc(void) { int i; char buf[128]; int num_plugs = 20; char plug[20][4]; int plug_origin = 1; int logged_in = 1; int seq = 0; for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); printf(RPC28_NC_BANNER); while (logged_in) { /* switch between two possible prompts - our scripts must handle both */ if (xreadline((seq++ % 2) ? RPC28_NC_PROMPT : RPC28_NC_PROMPT2, buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "logoff") || !strcmp(buf, "logout") || !strcmp(buf, "exit")) { break; } else if (!strcmp(buf, "help")) { printf(RPC28_NC_HELP); } else if (!strcmp(buf, "temp")) printf(RPC28_NC_TEMP); else if (!strcmp(buf, "voltage")) printf(RPC28_NC_VOLTAGE); else if (!strcmp(buf, "current")) printf(RPC28_NC_CURRENT); else if (!strcmp(buf, "status")) { printf(RPC28_NC_STATUS, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9], plug[10], plug[11], plug[12], plug[13], plug[14], plug[15], plug[16], plug[17], plug[18], plug[19]); /* NOTE: we only suport one plug at a time or all for on,off,reboot */ } else if (sscanf(buf, "on %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "On "); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "On "); else goto err; } else if (sscanf(buf, "off %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "Off"); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); else goto err; } else if (sscanf(buf, "reboot %d", &i) == 1) { /* if off, leaves it off */ if (i == 0 || (i >= plug_origin && i < num_plugs + plug_origin)) { printf("\r\nRebooting... "); for (i = 9; i >= 0; i--) { printf("%d", i); fflush(stdout); sleep(1); } printf("\r\n"); } else goto err; } else goto err; continue; err: printf("Input error\r\n\r\n"); } } #define RPC3_DE_BANNER "\r\n\r\n\ RPC-3/4(A)DE Series\r\n\ (C) 2004 BayTech\r\n\ F1.08\r\n\ \r\n\ Option(s) Installed:\r\n\ True RMS Voltage\r\n\ True RMS Current\r\n\ Internal Temperature\r\n\ \r\n" #define RPC3_DE_PROMPT "RPC-4>" #define RPC3_DE_STATUS "\r\n\ \r\n\ -------------------------------------------------------------------------------\r\n\ | Outlet | True RMS | Peak RMS | True RMS | Average | Volt- |\r\n\ | Group | Current | Current | Voltage | Power | Amps |\r\n\ -------------------------------------------------------------------------------\r\n\ | Outlet 1-4 | 1.8 Amps | 2.3 Amps | 122.5 Volts | 216 Watts | 220 VA |\r\n\ | Outlet 5-8 | 2.4 Amps | 5.0 Amps | 122.1 Volts | 269 Watts | 277 VA |\r\n\ -------------------------------------------------------------------------------\r\n\ \r\n\ Internal Temperature: 78.8 F\r\n\ \r\n\ Switch 1: Open 2: Open\r\n\ \r\n\ 1)...Outlet 1 : %s \r\n\ 2)...Outlet 2 : %s \r\n\ 3)...Outlet 3 : %s \r\n\ 4)...Outlet 4 : %s \r\n\ 5)...Outlet 5 : %s \r\n\ 6)...Outlet 6 : %s \r\n\ 7)...Outlet 7 : %s \r\n\ 8)...Outlet 8 : %s \r\n\ \r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" #define RPC3_DE_HELP "\r\n\r\n\ On n --Turn on an Outlet, n=0,1...8,all\r\n\ Off n --Turn off an Outlet, n=0,1...8,all\r\n\ Reboot n --Reboot an Outlet, n=0,1...8,all\r\n\ Status --RPC-4 Status\r\n\ Config --Enter configuration mode\r\n\ RC --Powerup/watchdog reset counts\r\n\ Lock n --Locks Outlet(s) state, n=0,1...8,all\r\n\ Unlock n --Unlock Outlet(s) state, n=0,1...8,all\r\n\ Current --Display True RMS Current\r\n\ Voltage --Display True RMS Voltage\r\n\ Power --Display Average Power\r\n\ Clear --Reset the maximum detected current\r\n\ Temp --Read current temperature\r\n\ Logout --Logoff\r\n\ Logoff --Logoff\r\n\ Exit --Logoff\r\n\ Password --Changes the current user password\r\n\ Whoami --Displays the current user name\r\n\ Unitid --Displays the unit ID\r\n\ \r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" #define RPC3_DE_TEMP "\r\n\r\n\ Internal Temperature: 77.9 F\r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" #define RPC3_DE_VOLTAGE "\r\n\r\n\ --------------------------------\r\n\ | Outlet | True RMS |\r\n\ | Group | Voltage |\r\n\ --------------------------------\r\n\ | Outlet 1-4 | 122.4 Volts | \r\n\ | Outlet 5-8 | 122.3 Volts | \r\n\ --------------------------------\r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" #define RPC3_DE_CURRENT "\r\n\r\n\ ------------------------------------------\r\n\ | Outlet | True RMS | Peak RMS |\r\n\ | Group | Current | Current |\r\n\ ------------------------------------------\r\n\ | Outlet 1-4 | 1.8 Amps | 2.3 Amps |\r\n\ | Outlet 5-8 | 2.3 Amps | 5.0 Amps |\r\n\ ------------------------------------------\r\n\ \r\n\ \r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" #define RPC3_DE_POWER "\r\n\r\n\ ------------------------------------------\r\n\ | Outlet | True RMS | Peak RMS |\r\n\ | Group | Current | Current |\r\n\ ------------------------------------------\r\n\ | Outlet 1-4 | 1.8 Amps | 2.3 Amps |\r\n\ | Outlet 5-8 | 2.3 Amps | 5.0 Amps |\r\n\ ------------------------------------------\r\n\ \r\n\ \r\n\ \r\n\ Type Help for a list of commands\r\n\ \r\n" static void _prompt_loop_rpc3_de(void) { int i; char buf[128]; int num_plugs = 8; char plug[8][4]; int plug_origin = 1; int logged_in = 1; for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); printf(RPC3_DE_BANNER); while (logged_in) { if (xreadline(RPC3_DE_PROMPT, buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "logoff") || !strcmp(buf, "logout") || !strcmp(buf, "exit")) { break; } else if (!strcmp(buf, "help")) { printf(RPC3_DE_HELP); } else if (!strcmp(buf, "temp")) printf(RPC3_DE_TEMP); else if (!strcmp(buf, "voltage")) printf(RPC3_DE_VOLTAGE); else if (!strcmp(buf, "current")) printf(RPC3_DE_CURRENT); else if (!strcmp(buf, "power")) printf(RPC3_DE_POWER); else if (!strcmp(buf, "status")) { printf(RPC3_DE_STATUS, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7]); /* NOTE: we only suport one plug at a time or all for on,off,reboot */ } else if (sscanf(buf, "on %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "On "); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "On "); else goto err; } else if (sscanf(buf, "off %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "Off"); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); else goto err; } else if (sscanf(buf, "reboot %d", &i) == 1) { /* if off, leaves it off */ if (i == 0 || (i >= plug_origin && i < num_plugs + plug_origin)) { printf("\r\nRebooting... "); for (i = 9; i >= 0; i--) { printf("%d", i); fflush(stdout); sleep(1); } printf("\r\n"); } else goto err; } else goto err; continue; err: printf("Input error\r\n\r\n"); } } #define RPC3_NC_BANNER "\r\n\ \r\n\ RPC3-NC Series\r\n\ (C) 2002 by BayTech\r\n\ F4.00\r\n\ \r\n\ Option(s) Installed:\r\n\ True RMS Current\r\n\ Internal Temperature\r\n\ True RMS Voltage\r\n\ \r\n" #define RPC3_NC_PROMPT "RPC3-NC>" #define RPC3_NC_STATUS "\r\n\ \r\n\ Average Power: 338 Watts\r\n\ True RMS Voltage: 120.9 Volts\r\n\ True RMS Current: 2.9 Amps\r\n\ Maximum Detected: 4.3 Amps\r\n\ Circuit Breaker: Good\r\n\ \r\n\ Internal Temperature: 40.0 C\r\n\ \r\n\ \r\n\ 1)...Outlet 1 : %s \r\n\ 2)...Outlet 2 : %s \r\n\ 3)...Outlet 3 : %s \r\n\ 4)...Outlet 4 : %s \r\n\ 5)...Outlet 5 : %s \r\n\ 6)...Outlet 6 : %s \r\n\ 7)...Outlet 7 : %s \r\n\ 8)...Outlet 8 : %s \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC3_NC_HELP "\r\n\ On n --Turn on an Outlet, n=0,1...8,all\r\n\ Off n --Turn off an Outlet, n=0,1...8,all\r\n\ Reboot n --Reboot an Outlet, n=0,1...8,all\r\n\ Status --RPC3-NC Status\r\n\ Config --Enter configuration mode\r\n\ Lock n --Locks Outlet(s) state, n=0,1...8,all\r\n\ Unlock n --Unlock Outlet(s) state, n=0,1...8,all\r\n\ Current --Display True RMS Current\r\n\ Clear --Reset the maximum detected current\r\n\ Temp --Read current temperature\r\n\ Voltage --Display True RMS Voltage\r\n\ Logout --Logoff\r\n\ Logoff --Logoff\r\n\ Exit --Logoff\r\n\ Password --Changes the current user password\r\n\ Whoami --Displays the current user name\r\n\ Unitid --Displays the unit ID\r\n\ Help --This Command\r\n\ \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC3_NC_TEMP "\r\n\ Internal Temperature: 38.5 C\r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC3_NC_VOLTAGE "\r\n\r\n\ True RMS Voltage: 120.5 Volts \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC3_NC_CURRENT "\r\n\r\n\ True RMS Current: 2.9 Amps\r\n\ Maximum Detected: 4.3 Amps\r\n\ \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" static void _prompt_loop_rpc3_nc(void) { int i; char buf[128]; int num_plugs = 8; char plug[8][4]; int plug_origin = 1; int logged_in = 1; for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); printf(RPC3_NC_BANNER); while (logged_in) { if (xreadline(RPC3_NC_PROMPT, buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "logoff") || !strcmp(buf, "logout") || !strcmp(buf, "exit")) { break; } else if (!strcmp(buf, "help")) { printf(RPC3_NC_HELP); } else if (!strcmp(buf, "temp")) printf(RPC3_NC_TEMP); else if (!strcmp(buf, "voltage")) printf(RPC3_NC_VOLTAGE); else if (!strcmp(buf, "current")) printf(RPC3_NC_CURRENT); else if (!strcmp(buf, "status")) { printf(RPC3_NC_STATUS, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7]); /* NOTE: we only suport one plug at a time or all for on,off,reboot */ } else if (sscanf(buf, "on %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "On "); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "On "); else goto err; } else if (sscanf(buf, "off %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "Off"); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); else goto err; } else if (sscanf(buf, "reboot %d", &i) == 1) { /* if off, leaves it off */ if (i == 0 || (i >= plug_origin && i < num_plugs + plug_origin)) { printf("\r\nRebooting... "); for (i = 9; i >= 0; i--) { printf("%d", i); fflush(stdout); sleep(1); } printf("\r\n"); } else goto err; } else goto err; continue; err: printf("Input error\r\n\r\n"); } } #define RPC3_PROMPT " RPC-3>" #define RPC3_WELCOME "\ \r\n\ \r\n\ \r\n\ RPC-3 Telnet Host\r\n\ Revision F 5.01, (C) 2001 \r\n\ Bay Technical Associates\r\n\ Unit ID: BT RPC3-20\r\n" #define RPC3_LOGIN "\ \r\n\ Enter password>" #define RPC3_BANNER "\ Option(s) installed:\r\n\ True RMS Current\r\n\ Internal Temperature\r\n\ \r\n\ \r\n" #define RPC3_MENU "\r\n\ RPC-3 Menu:\r\n\ \r\n\ 1)...Outlet Control\r\n\ 2)...Manage Users\r\n\ 3)...Configuration\r\n\ 4)...Unit Status\r\n\ 5)...Reset Unit\r\n\ 6)...Logout\r\n\ \r\n\ Enter Selection>" #define RPC3_OUTLET "\ True RMS current: 1.7 Amps\r\n\ Maximum Detected: 2.5 Amps\r\n\ \r\n\ Internal Temperature: 32.0 C\r\n\ \r\n\ Circuit Breaker: On \r\n\ \r\n\ Selection Outlet Outlet Power\r\n\ Number Name Number Status\r\n\ 1 Outlet 1 1 %s \r\n\ 2 Outlet 2 2 %s \r\n\ 3 Outlet 3 3 %s \r\n\ 4 Outlet 4 4 %s \r\n\ 5 Outlet 5 5 %s \r\n\ 6 Outlet 6 6 %s \r\n\ 7 Outlet 7 7 %s \r\n\ 8 Outlet 8 8 %s \r\n\ \r\n\ Type \"Help\" for a list of commands\r\n\ \r\n" #define RPC3_OUTLET_HELP "\ RPC3 Command Summary (F 5.01).\r\n\ \"n\" refers to Selection Number, as displayed in outlet status\r\n\ LOGOUT : terminate session\r\n\ OFF n : turn off outlet \"n\", do all for n = 0\r\n\ ON n : turn on outlet \"n\", do all for n = 0\r\n\ REBOOT n : cycle power off/on outlet \"n\", do all for n = 0\r\n\ RC : display outlet relay control info\r\n\ STATUS : display power status of outlets\r\n\ HELP : display this message\r\n\ CLEAR : Reset the maximum detected current\r\n\ CURRENT : Read the current\r\n\ TEMP : Read current temperature\r\n\ MENU : return to main menu\r\n\ \r\n\ " static void _prompt_loop_rpc3(void) { int i; char buf[128]; int num_plugs = 8; char plug[8][4]; int plug_origin = 1; enum { START, MENU, OUTLET, QUIT } state = START; char *prompt = NULL; for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); printf(RPC3_WELCOME); while (state != QUIT) { switch (state) { case START: prompt = RPC3_LOGIN; break; case MENU: prompt = RPC3_MENU; break; case OUTLET: printf(RPC3_OUTLET, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7]); prompt = RPC3_PROMPT; break; case QUIT: break; } if (xreadline(prompt, buf, sizeof(buf)) == NULL) { state = QUIT; continue; } switch (state) { case START: if (!strcmp(buf, "baytech")) { printf(RPC3_BANNER); state = MENU; } else printf(" Invalid password.\r\n\r\n"); break; case MENU: if (!strcmp(buf, "1")) state = OUTLET; else if (!strcmp(buf, "6")) state = QUIT; else goto err; break; case OUTLET: if (!strcmp(buf, "?") || !strcmp(buf, "help")) { if (xreadline(RPC3_OUTLET_HELP, buf, sizeof(buf)) == NULL) state = QUIT; } else if (!strcmp(buf, "menu")) { state = MENU; } else if (!strcmp(buf, "logout")) { state = QUIT; } else if (!strcmp(buf, "status")) { } else if (sscanf(buf, "on %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "On "); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "On "); else goto err; } else if (sscanf(buf, "off %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) strcpy(plug[i - plug_origin], "Off"); else if (i == 0) for (i = 0; i < num_plugs; i++) strcpy(plug[i], "Off"); else goto err; } else goto err; break; case QUIT: break; } continue; err: printf("\r\n Input error.\r\n\r\n"); } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/cli.c000066400000000000000000000064331415616035500153430ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* cli.c - simple client to demo the libpowerman api */ #include #include #include "libpowerman.h" static pm_err_t list_nodes(pm_handle_t pm); static void usage(void); #define statstr(s) ((s) == PM_ON ? "on" : (s) == PM_OFF ? "off" : "unknown") int main(int argc, char *argv[]) { pm_err_t err = PM_ESUCCESS; pm_node_state_t ns; pm_handle_t pm; char ebuf[64]; char *server, *node = NULL; char cmd; if (argc < 3 || argc > 4) usage(); server = argv[1]; cmd = argv[2][0]; if (argc == 3 && cmd != 'l') usage(); if (argc == 4 && cmd != '1' && cmd != '0' && cmd != 'c' && cmd != 'q') usage(); if (argc == 4) node = argv[3]; if ((err = pm_connect(server, NULL, &pm, 0)) != PM_ESUCCESS) { fprintf(stderr, "%s: %s\n", server, pm_strerror(err, ebuf, sizeof(ebuf))); exit(1); } switch (cmd) { case '1': err = pm_node_on(pm, node); break; case '0': err = pm_node_off(pm, node); break; case 'c': err = pm_node_cycle(pm, node); break; case 'l': err = list_nodes(pm); break; case 'q': ns = PM_UNKNOWN; if ((err = pm_node_status(pm, node, &ns)) == PM_ESUCCESS) printf("%s: %s\n", node, statstr(ns)); break; } if (err != PM_ESUCCESS) { fprintf(stderr, "Error: %s\n", pm_strerror(err, ebuf, sizeof(ebuf))); pm_disconnect(pm); exit(1); } pm_disconnect(pm); exit(0); } static pm_err_t list_nodes(pm_handle_t pm) { pm_node_iterator_t pmi; pm_err_t err; char *s; if ((err = pm_node_iterator_create(pm, &pmi)) != PM_ESUCCESS) return err; while ((s = pm_node_next(pmi))) printf("%s\n", s); pm_node_iterator_destroy(pmi); return err; } static void usage(void) { fprintf(stderr, "Usage: cli host:port 0|1|q node\n"); fprintf(stderr, " cli host:port l\n"); exit(1); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/cyclades.c000066400000000000000000000344571415616035500163720ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see . * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* cyclades.c - simulate cyclades power controllers */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); typedef enum { NONE, PM8, PM10, PM20, PM42 } cytype_t; static char *prog; static cytype_t personality = NONE; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "pm8") == 0) personality = PM8; else if (strcmp(optarg, "pm10") == 0) personality = PM10; else if (strcmp(optarg, "pm20") == 0) personality = PM20; else if (strcmp(optarg, "pm42") == 0) personality = PM42; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (personality == NONE) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p pm8|pm10|pm20|pm42\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } #define BANNER "\ AlterPath PM\n\ Copyright (c) 2002-2003 Cyclades Corporation\n\ V 1.0.9a Jun 26, 2003\n\n" #define BANNER2 "\ AlterPath PM\n\ Copyright (c) 2007 Avocent Corporation\n\ V 1.9.1 May 2, 2007\n\ [PM]: IPDU: 1\n\ [PM]: OUT: 42\n" #define USER_PROMPT "Username: " /* admin */ #define PASS_PROMPT "Password: " /* pm8 */ #define CMD_PROMPT "pm>" #define FAILED_MSG "\nAuthentication failed.\n" #define HELP_MSG "\n\n\n\ Available commands:\n\ \n\ adduser alarm assign buzzer current\n\ cycle deluser factory_defaults help\n\ list lock name off on\n\ passwd reboot restore save status\n\ syslog unassign unlock ver whoami\n\ \n\ NOTE: To get detailed help on the commands listed above type\n\ ' help';\n\ NOTE: Some commands accept as input a data type called \n\ . is a string representing\n\ one or more outlets. This string can be:\n\ - one single outlet.\n\ Examples: on 3 (turn on outlet 3);\n\ off router (turn off the outlet called router).\n\ - a group of outlets.\n\ Examples: status 1,3,5 (get status of outlets 1, 3 and 5);\n\ cycle 2-7 (cycle the outlets 2, 3, 4, 5, 6, 7)\n\ lock 2,5-7 (lock the outlets 2, 5, 6 and 7).\n" #define HELP_MSG2 "\n\ Available commands:\n\ \n\ adduser alarm assign \n\ buzzer current currentprotection\n\ currseg cycle dbsync \n\ deluser display exit \n\ factory_defaults help hwocp \n\ humidity id interval \n\ list lock name \n\ off on outcycledelay \n\ passwd reboot restore \n\ save status syslog \n\ temperature unassign unlock \n\ upgrade ver voltage \n\ whoami \n\ \n\ NOTE: To get detailed help on the commands listed above type\n\ ' help'\n\n" #define STATUS_TMPL_PM8 "\ Outlet Name Status Users\n\ 1 Unlocked %s\n\ 2 Unlocked %s\n\ 3 Unlocked %s\n\ 4 Unlocked %s\n\ 5 Unlocked %s\n\ 6 Unlocked %s\n\ 7 Unlocked %s\n\ 8 Unlocked %s\n" #define STATUS_TMPL_PM10 "\ Outlet Name Status Users\n\ 1 Unlocked %s\n\ 2 Unlocked %s\n\ 3 Unlocked %s\n\ 4 Unlocked %s\n\ 5 Unlocked %s\n\ 6 Unlocked %s\n\ 7 Unlocked %s\n\ 8 Unlocked %s\n\ 9 Unlocked %s\n\ 10 Unlocked %s\n" #define STATUS_TMPL_PM20 "\ Outlet Name Status Users\n\ 1 Unlocked %s\n\ 2 Unlocked %s\n\ 3 Unlocked %s\n\ 4 Unlocked %s\n\ 5 Unlocked %s\n\ 6 Unlocked %s\n\ 7 Unlocked %s\n\ 8 Unlocked %s\n\ 9 Unlocked %s\n\ 10 Unlocked %s\n\ 11 Unlocked %s\n\ 12 Unlocked %s\n\ 13 Unlocked %s\n\ 14 Unlocked %s\n\ 15 Unlocked %s\n\ 16 Unlocked %s\n\ 17 Unlocked %s\n\ 18 Unlocked %s\n\ 19 Unlocked %s\n\ 20 Unlocked %s\n" #define STATUS_TMPL_PM42 "\ Outlet Name Status Interval (s) Users\n\ 1 Unlocked %s 0.0\n\ 2 Unlocked %s 0.0\n\ 3 Unlocked %s 0.0\n\ 4 Unlocked %s 0.0\n\ 5 Unlocked %s 0.0\n\ 6 Unlocked %s 0.0\n\ 7 Unlocked %s 0.0\n\ 8 Unlocked %s 0.0\n\ 9 Unlocked %s 0.0\n\ 10 Unlocked %s 0.0\n\ 11 Unlocked %s 0.0\n\ 12 Unlocked %s 0.0\n\ 13 Unlocked %s 0.0\n\ 14 Unlocked %s 0.0\n\ 15 Unlocked %s 0.0\n\ 16 Unlocked %s 0.0\n\ 17 Unlocked %s 0.0\n\ 18 Unlocked %s 0.0\n\ 19 Unlocked %s 0.0\n\ 20 Unlocked %s 0.0\n\ 21 Unlocked %s 0.0\n\ 22 Unlocked %s 0.0\n\ 23 Unlocked %s 0.0\n\ 24 Unlocked %s 0.0\n\ 25 Unlocked %s 0.0\n\ 26 Unlocked %s 0.0\n\ 27 Unlocked %s 0.0\n\ 28 Unlocked %s 0.0\n\ 29 Unlocked %s 0.0\n\ 30 Unlocked %s 0.0\n\ 31 Unlocked %s 0.0\n\ 32 Unlocked %s 0.0\n\ 33 Unlocked %s 0.0\n\ 34 Unlocked %s 0.0\n\ 35 Unlocked %s 0.0\n\ 36 Unlocked %s 0.0\n\ 37 Unlocked %s 0.0\n\ 38 Unlocked %s 0.0\n\ 39 Unlocked %s 0.0\n\ 40 Unlocked %s 0.0\n\ 41 Unlocked %s 0.0\n\ 42 Unlocked %s 0.0\n" #define CURRENT_PM42 "\ IPDU #1: RMS current for phase X: 2.3A. Maximum current for phase X: 10.8A\n\ IPDU #1: RMS current for phase Y: 0.0A. Maximum current for phase Y: 11.6A\n\ IPDU #1: RMS current for phase Z: 2.5A. Maximum current for phase Z: 11.0A\n" #define OFF_MSG "%d: Outlet turned off.\n" #define ON_MSG "%d: Outlet turned on.\n" static void _prompt_loop(void) { int i; char buf[128]; int num_plugs = 0; char plug[42][4]; int plug_origin = 1; char user[32], pass[32]; char status_all[32]; char on_all[32]; char off_all[32]; switch (personality) { case PM8: num_plugs = 8; break; case PM10: num_plugs = 10; break; case PM20: num_plugs = 20; break; case PM42: num_plugs = 42; break; case NONE: num_plugs = 0; } snprintf(status_all, sizeof(status_all), "status 1-%d", num_plugs); snprintf(on_all, sizeof(on_all), "on 1-%d", num_plugs); snprintf(off_all, sizeof(off_all), "off 1-%d", num_plugs); for (i = 0; i < num_plugs; i++) strcpy(plug[i], "OFF"); login_again: printf(personality == PM42 ? BANNER2 : BANNER); do { if (xreadline(USER_PROMPT, user, sizeof(user)) == NULL) goto done; if (xreadline(PASS_PROMPT, pass, sizeof(pass)) == NULL) goto done; } while (strcmp(user, "admin") != 0 || strcmp(pass, "pm8") != 0); while (1) { if (xreadline(CMD_PROMPT, buf, sizeof(buf)) == NULL) { goto done; } else if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "exit")) { sleep(1); goto login_again; } else if (!strcmp(buf, "help")) { printf(personality == PM42 ? HELP_MSG2 : HELP_MSG); } else if (!strcmp(buf, status_all)) { if (personality == PM8) { printf(STATUS_TMPL_PM8, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7]); } else if (personality == PM10) { printf(STATUS_TMPL_PM10, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9]); } else if (personality == PM20) { printf(STATUS_TMPL_PM20, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9], plug[10], plug[11], plug[12], plug[13], plug[14], plug[15], plug[16], plug[17], plug[18], plug[19]); } else if (personality == PM42) { printf(STATUS_TMPL_PM42, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9], plug[10], plug[11], plug[12], plug[13], plug[14], plug[15], plug[16], plug[17], plug[18], plug[19], plug[20], plug[21], plug[22], plug[23], plug[24], plug[25], plug[26], plug[27], plug[28], plug[29], plug[30], plug[31], plug[32], plug[33], plug[34], plug[35], plug[36], plug[37], plug[38], plug[39], plug[40], plug[41]); } } else if (!strcmp(buf, on_all)) { for (i = 0; i < num_plugs; i++) { strcpy(plug[i], personality == PM42 ? "ON " : "ON"); printf(ON_MSG, i); } } else if (sscanf(buf, "on %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) { strcpy(plug[i - plug_origin], personality == PM42 ? "ON ":"ON"); printf(ON_MSG, i); } else goto err; } else if (!strcmp(buf, off_all)) { for (i = 0; i < num_plugs; i++) { strcpy(plug[i], "OFF"); printf(OFF_MSG, i); } } else if (sscanf(buf, "off %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) { strcpy(plug[i - plug_origin], "OFF"); printf(OFF_MSG, i); } else goto err; } else goto err; continue; err: printf("Input error\r\n\r\n"); } done: return; } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/dli.c000066400000000000000000000207541415616035500153460ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* dli.c - mimic httppower talking to a Digital Loggers Inc LPC */ #include #include #include #include #include "xread.h" #define DLI_POST "\ \n\ \n\ \n\ \n\ \n" #define DLI_GET "\ \n\ \n\ \n\ \n\ Outlet Control - Lite Power Controller\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\n\ \n\
Ethernet Power Controller
\n\
\n\
Outlet Control
Setup
AutoPing
Logout
Help

Link 1
Link 2
Link 3
Link 4
\n\
\n\ Version 1.2.1 (Aug 23 2007 / 20:14:33) 1555A5A1-D43E3FC2\n\
\n\ S/N:0000130175\n\
\n\ \n\ \n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\n\ Controller: Lite Power Controller\n\
\n\ Uptime: 0:35:01 \n\
\n\ \n\ \n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
\n\ Individual Control\n\
#NameStateAction
1Outlet 1\n\ %s\n\ Switch ON\n\ \n\ \n\
2Outlet 2\n\ %s\n\ Switch ON\n\ \n\ \n\
3Outlet 3\n\ %s\n\ Switch ON\n\ \n\ \n\
4Outlet 4\n\ %s\n\ Switch ON\n\ \n\ \n\
5Outlet 5\n\ %s\n\ Switch ON\n\ \n\ \n\
6Outlet 6\n\ %s\n\ Switch ON\n\ \n\ \n\
7Outlet 7\n\ %s\n\ Switch ON\n\ \n\ \n\
8Outlet 8\n\ %s\n\ Switch ON\n\ \n\ \n\
\n\ \n\ \n\
\n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\ \n\
Master Control
All outlets OFF
All outlets ON
Cycle all outlets
Sequence delay: 1 sec.
\n\ \n\ \n\
\n\ \n\ \n\ \n" static void prompt_loop(void) { char buf[128], tmp[32]; char plug[8][4]; int num_plugs = 8; int plug_origin = 1; int i; int authenticated = 0; for (i = 0; i < num_plugs; i++) strcpy(plug[i], "OFF"); for (;;) { if (xreadline("httppower> ", buf, sizeof(buf)) == NULL) break; if (!strcmp(buf, "help")) { printf("Commands are:\n"); printf(" auth admin:admin\n"); printf(" get\n"); printf(" post outlet [1-8]=ON|OFF\n"); } else if (!strcmp(buf, "auth admin:admin")) { authenticated = 1; } else if (!strcmp(buf, "get")) { if (!authenticated) goto err; printf(DLI_GET, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7]); } else if (sscanf(buf, "post outlet %d=%s", &i, tmp) == 2) { if (!authenticated) goto err; if (i < plug_origin || i >= num_plugs + plug_origin) goto err; if (!strcmp(tmp, "ON")) strcpy(plug[i - plug_origin], "ON"); else if (!strcmp(tmp, "OFF")) strcpy(plug[i - plug_origin], "OFF"); else goto err; printf(DLI_POST); } else goto err; continue; err: printf("Error\n"); } } int main(int argc, char *argv[]) { prompt_loop(); exit (0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/gpib.c000066400000000000000000000204661415616035500155170ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* gpib.c - gpib-utils hp3488/ics8064 simulator */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "hostlist.h" #include "argv.h" #include "xmalloc.h" #include "xread.h" typedef enum { QUERY, OFF, ON } relayop_t; typedef enum { NONE, ICS8064, HP3488 } gptype_t; static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); static int relay_op(char *s, relayop_t op, int *plug, int num_plugs, int plug_origin); static int ics8064_cmd(char **av, int plug[], int num_plugs, int plug_origin, int *qp); static int hp3488_cmd(char **av, int plug[], int num_plugs, int plug_origin, int *qp); static gptype_t personality = NONE; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "hp3488") == 0) personality = HP3488; else if (strcmp(optarg, "ics8064") == 0) personality = ICS8064; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (personality == NONE) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p ics8064|hp3488\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } static int relay_op(char *s, relayop_t op, int *plug, int num_plugs, int plug_origin) { /* N.B. WANT_RECKLESS_HOSTRANGE_EXPANSION is defined by gpib-utils, * but not by powerman. Dev script will work but help cmd lies. */ hostlist_t h = hostlist_create(s); hostlist_iterator_t it = hostlist_iterator_create(h); char *tmp; int i; while ((tmp = hostlist_next(it))) { i = strtoul(tmp, NULL, 10); if (i < plug_origin || i >= num_plugs + plug_origin) break; if (op == ON) { plug[i - plug_origin] = 1; } else if (op == OFF) { plug[i - plug_origin] = 0; } else if (op == QUERY) { if (personality != HP3488) break; printf("%.3d: %d\n", i, plug[i - plug_origin]); } } hostlist_iterator_destroy(it); hostlist_destroy(h); return (tmp ? 0 : 1); } #define ICS8064_STATUS "ics8064> %d, %d, %d, %d, %d, %d, %d,\ %d, %d, %d, %d, %d, %d, %d, %d, %d\n" static int ics8064_cmd(char **av, int plug[], int num_plugs, int plug_origin, int *qp) { if (argv_length(av) == 0) { } else if (!strcmp(av[0], "quit")) { *qp = 1; } else if (!strcmp(av[0], "help")) { printf("Commands:\n"); printf("open relay-list open the specified relay(s)\n"); printf("close relay-list close the specified relay(s)\n"); printf("status show relay status\n"); printf("quit exit interactive mode\n"); printf("Relay-list is comma-separated and may include ranges,\n"); printf(" e.g.: \"1,2\", \"1-16\", or \"1-10,16\".\n"); } else if (!strcmp(av[0], "status")) { if (argv_length(av) != 1) return 0; printf(ICS8064_STATUS, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9], plug[10], plug[11], plug[12], plug[13], plug[14], plug[15]); } else if (!strcmp(av[0], "close")) { if (argv_length(av) != 2) return 0; if (!relay_op(av[1], ON, plug, num_plugs, plug_origin)) return 0; } else if (!strcmp(av[0], "open")) { if (argv_length(av) != 2) return 0; if (!relay_op(av[1], OFF, plug, num_plugs, plug_origin)) return 0; } else return 0; return 1; } static int hp3488_cmd(char **av, int plug[], int num_plugs, int plug_origin, int *qp) { if (argv_length(av) == 0) { } else if (!strcmp(av[0], "quit")) { *qp = 1; } else if (!strcmp(av[0], "help")) { printf("Possible commands are:\n"); printf(" on [targets] - turn on specified channels\n"); printf(" off [targets] - turn off specified channels\n"); printf(" query [targets] - query specified channels (0=off,1=on)\n"); printf(" list - list valid caddrs\n"); printf(" show - show slot configuration\n"); printf(" id - query instrument id\n"); printf(" verbose - toggle verbose flag\n"); printf(" help - display this help text\n"); printf(" quit - exit this shell\n"); printf("Where channel address is (3 digits).\n"); } else if (!strcmp(av[0], "query")) { if (argv_length(av) != 2) return 0; if (!relay_op(av[1], QUERY, plug, num_plugs, plug_origin)) return 0; } else if (!strcmp(av[0], "on")) { if (argv_length(av) != 2) return 0; if (!relay_op(av[1], ON, plug, num_plugs, plug_origin)) return 0; } else if (!strcmp(av[0], "off")) { if (argv_length(av) != 2) return 0; if (!relay_op(av[1], OFF, plug, num_plugs, plug_origin)) return 0; } else return 0; return 1; } void _prompt_loop(void) { char buf[128]; int num_plugs; int plug_origin; int res, quit = 0; int *plug; char **av; if (personality == ICS8064) { num_plugs = 16; plug_origin = 1; plug = (int *)xmalloc(sizeof(int) * num_plugs); } else { num_plugs = 500; /* 100-599 */ plug_origin = 100; } plug = (int *)xmalloc(sizeof(int) * num_plugs); memset(plug, 0, sizeof(int) * num_plugs); while (!quit) { if (xreadline(personality == ICS8064 ? "ics8064> " : "hp3488> ", buf, sizeof(buf))) { av = argv_create(buf, ""); if (personality == ICS8064) res = ics8064_cmd(av, plug, num_plugs, plug_origin, &quit); else res = hp3488_cmd(av, plug, num_plugs, plug_origin, &quit); if (!res) printf("Unknown command\n"); argv_destroy(av); } else break; } xfree(plug); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/icebox.c000066400000000000000000000166771415616035500160600ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* icebox.c - icebox simulator */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); typedef enum { NONE, V2, V3, V4 } icetype_t; static icetype_t personality = NONE; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "v2") == 0) personality = V2; else if (strcmp(optarg, "v3") == 0) personality = V3; else if (strcmp(optarg, "v4") == 0) personality = V4; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (personality == NONE) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p v2|v3|v4\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } #define V2_BANNER "V2.1\r\n" #define V3_BANNER "V3.0\r\n" #define V4_BANNER "V4.0\r\n" #define V3_AUTHCMD "auth icebox\r\n" #define V3_RESP_OK "OK\r\n" #define V3_ERROR_CMD "ERROR 0\r\n" #define V3_ERROR_AUTH "ERROR 4\r\n" #define V3_POWER_STATUS "\ N1:%d N2:%d N3:%d N4:%d N5:%d N6:%d N7:%d N8:%d N9:%d N10:%d\r\n" #define V3_BEACON_STATUS "\ N1:%s N2:%s N3:%s N4:%s N5:%s N6:%s N7:%s N8:%s N9:%s N10:%s N11:%s N12:%s\r\n" #define V2_TEMP "\ N1:%d,0,0,0 N2:%d,0,0,0 N3:%d,0,0,0 N4:%d,0,0,0 N5:%d,0,0,0 N6:%d,0,0,0 N7:%d,0,0,0 N8:%d,0,0,0 N9:%d,0,0,0 N10:%d,0,0,0 N11:%d,0,0,0 N12:%d,0,0,0\r\n" #define V3_TEMP "\ N1:%d: N2:%d: N3:%d: N4:%d: N5:%d: N6:%d: N7:%d: N8:%d: N9:%d: N10:%d: N11:%d: N12:%d:\r\n" static void _prompt_loop(void) { int i; char buf[128]; int num_plugs = 10; int num_plugs_ext = 12; int plug[12]; char beacon[12][4]; int temp[12]; int plug_origin = 1; int logged_in = 0; char arg[80]; for (i = 0; i < num_plugs_ext; i++) { plug[i] = 0; temp[i] = 73 + i; strcpy(beacon[i], "OFF"); } /* User must first authenticate. */ switch (personality) { case V2: printf(V2_BANNER); break; case V3: printf(V3_BANNER); break; case V4: printf(V4_BANNER); break; case NONE: break; } while (!logged_in) { if (xreadline("", buf, sizeof(buf)) == NULL) return; if (strcmp(buf, "auth icebox") == 0) { logged_in = 1; printf(V3_RESP_OK); } else printf(V3_ERROR_AUTH); } /* Process comands. */ while (logged_in) { if (xreadline("", buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) { goto err; } else if (!strcmp(buf, "q")) { logged_in = 0; } else if (!strcmp(buf, "ps *") || !strcmp(buf, "ns *")) { printf(V3_POWER_STATUS, plug[0], plug[1], plug[2], plug[3], plug[4], plug[5], plug[6], plug[7], plug[8], plug[9]); } else if (personality != V2 && !strcmp(buf, "be *")) { printf(V3_BEACON_STATUS, beacon[0], beacon[1], beacon[2], beacon[3], beacon[4], beacon[5], beacon[6], beacon[7], beacon[8], beacon[9], beacon[10], beacon[11]); } else if (personality != V2 && !strcmp(buf, "is *")) { printf(V3_TEMP, temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7], temp[8], temp[9], temp[10], temp[11]); } else if (personality == V2 && !strcmp(buf, "ts *")) { printf(V2_TEMP, temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7], temp[8], temp[9], temp[10], temp[11]); } else if (!strcmp(buf, "ph *")) { for (i = 0; i < num_plugs; i++) plug[i] = 1; } else if (sscanf(buf, "ph %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) plug[i - plug_origin] = 1; else goto err; } else if (!strcmp(buf, "pl *")) { for (i = 0; i < num_plugs; i++) plug[i] = 0; } else if (sscanf(buf, "pl %d", &i) == 1) { if (i >= plug_origin && i < num_plugs + plug_origin) plug[i - plug_origin] = 0; else goto err; } else if (!strcmp(buf, "rp *")) { } else if (sscanf(buf, "rp %d", &i) == 1) { if (!(i >= plug_origin && i < num_plugs + plug_origin)) goto err; } else if (personality != V2 && sscanf(buf, "be %d %s", &i, arg) == 2) { if (i >= plug_origin && i < num_plugs_ext + plug_origin) { if (!strcmp(arg, "off")) strcpy(beacon[i - plug_origin], "OFF"); else if (!strcmp(arg, "on")) strcpy(beacon[i - plug_origin], "ON"); else goto err; } else goto err; } else goto err; if (logged_in) printf(V3_RESP_OK); continue; err: printf(V3_ERROR_CMD); } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/ilom.c000066400000000000000000000163251415616035500155350ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include "xread.h" #define ILOM_LOGIN_PROMPT "SUNSP00144FEE320F login: " #define ILOM_PASSWD_PROMPT "Password: " #define ILOM_PROMPT " -> " #define ILOM_BANNER "\n\ Sun(TM) Integrated Lights Out Manager\n\ \n\ Version 2.0.2.3\n\ \n\ Copyright 2007 Sun Microsystems, Inc. All rights reserved.\n\ Use is subject to license terms.\n\ \n\ Warning: password is set to factory default.\n\n" #define ILOM_PROP_SYS "\ /SYS\n\ Properties:\n\ type = Host System\n\ chassis_name = SUN FIRE X4140\n\ chassis_part_number = 540-7618-XX\n\ chassis_serial_number = 0226LHF-0823A600HM\n\ chassis_manufacturer = SUN MICROSYSTEMS\n\ product_name = SUN FIRE X4140\n\ product_part_number = 602-4125-01\n\ product_serial_number = 0826QAD075\n\ product_manufacturer = SUN MICROSYSTEMS\n\ power_state = %s\n\n\n" #define ILOM_STOP_RESP "Stopping /SYS immediately\n\n" #define ILOM_STOP_RESP2 "stop: Target already stopped\n\n" #define ILOM_START_RESP "Starting /SYS\n\n" #define ILOM_START_RESP2 "start: Target already started\n\n" #define ILOM_RESET_RESP "Performing hard reset on /SYS\n\n" #define ILOM_RESET_RESP2 "Performing hard reset on /SYS failed\n\ reset: Target already stopped\n\n" #define ILOM_CMD_INVAL "\ Invalid command '%s' - type help for a list of commands.\n\n" #define ILOM_HELP "\ The help command is used to view information about commands and targets\n\ \n\ Usage: help [-o|-output terse|verbose] [|legal|targets]\n\ \n\ Special characters used in the help command are\n\ [] encloses optional keywords or options\n\ <> encloses a description of the keyword\n\ (If <> is not present, an actual keyword is indicated)\n\ | indicates a choice of keywords or options\n\ \n\ help targets displays a list of targets\n\ help legal displays the product legal notice\n\ \n\ Commands are:\n\ cd\n\ create\n\ delete\n\ exit\n\ help\n\ load\n\ reset\n\ set\n\ show\n\ start\n\ stop\n\ version\n\n" #define ILOM_VERS "\ SP firmware 2.0.2.3\n\ SP firmware build number: 29049\n\ SP firmware date: Thu Feb 21 19:42:30 PST 2008\n\ SP filesystem version: 0.1.16\n\n" static void usage(void); static void prompt_loop(void); typedef enum { NONE, SSH, SER, SER_LOGIN } ilomtype_t; static ilomtype_t personality = NONE; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "ssh") == 0) personality = SSH; else if (strcmp(optarg, "serial") == 0) personality = SER; else if (strcmp(optarg, "serial_loggedin") == 0) personality = SER_LOGIN; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (personality == NONE) usage(); prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p ssh|serial|serial_loggedin\n", prog); exit(1); } static void prompt_loop(void) { char buf[128]; static char plug[4]; int authenticated; strcpy(plug, "Off"); switch (personality) { case SER: authenticated = 0; break; case SSH: authenticated = 1; break; case SER_LOGIN: authenticated = 2; break; case NONE: authenticated = 0; } for (;;) { switch (authenticated) { case 0: if (xreadline(ILOM_LOGIN_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "root")) authenticated = 1; break; case 1: if (xreadline(ILOM_PASSWD_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "changeme")) { authenticated = 2; printf(ILOM_BANNER); } break; case 2: if (xreadline(ILOM_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "exit")) { goto done; } else if (!strcmp(buf, "help")) { printf(ILOM_HELP); } else if (!strcmp(buf, "version")) { printf(ILOM_VERS); } else if (!strcmp(buf, "show -d properties /SYS")) { printf(ILOM_PROP_SYS, plug); } else if (!strcmp(buf, "start -script /SYS")) { if (!strcmp(plug, "Off")) { strcpy(plug, "On"); printf(ILOM_START_RESP); } else printf(ILOM_START_RESP2); } else if (!strcmp(buf, "stop -script -force /SYS")) { if (!strcmp(plug, "On")) { strcpy(plug, "Off"); printf(ILOM_STOP_RESP); } else printf(ILOM_STOP_RESP2); } else if (!strcmp(buf, "reset -script /SYS")) { if (!strcmp(plug, "On")) { printf(ILOM_RESET_RESP); } else printf(ILOM_RESET_RESP2); } else { printf(ILOM_CMD_INVAL, buf); } } continue; done: break; } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/ipmipower.c000066400000000000000000000177721415616035500166170ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* ipmipower.c - simulate FreeIPMI ipmipower */ /* achu: I'm not supporting a full-fledged ipmipower, there are over * 20 different configurations you can set (via cmdline, prompt, and * config file) and 7 power control commands (on, off, stat, cycle, * reset, pulse, soft). Many of the commands accepts all, hostrange, * or single host. * * Assumptions: * * Users configure ipmipower authentication via FreeIPMI's * configuration file. So there is no ipmipower authentication * configuration via powerman. Thus, I assume there is no need for * those configuration capabilities in this simulator (cmdline, config * file, or prompt). * * Users configure hostnames via cmdline in the powerman.conf. So we * support the -h/--hostname option on the command line, but not * anywhere else. * * powerman's ipmipower.dev only utilizes on, off, and stat in * ipmipower. So we only support those power control commands in the * command line prompt of this simulator (not on the cmdline). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "hash.h" #include "hostlist.h" #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); static char *prog; static char *hostname = NULL; static int auth_failure = 0; #define OPTIONS "h:A" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "hostname", required_argument, 0, 'h' }, { "auth-failure", no_argument, 0, 'A' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'h': hostname = optarg; break; case 'A': auth_failure = 1; break; default: usage(); } } if (optind < argc) usage(); if (hostname == NULL) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -h hostlist\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } #define CMD_PROMPT "ipmipower> " #define OFF_STATUS "off" #define ON_STATUS "on" #define OK_STATUS "ok" #define HASH_SIZE 1024 static void _stat(hash_t hstatus, const char *nodes) { hostlist_iterator_t hlitr; hostlist_t hlnodes; char *node; char *str; assert(hstatus); if (!(hlnodes = hostlist_create(nodes))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hlnodes))) { perror("hostlist_iterator_create"); exit(1); } while ((node = hostlist_next(hlitr))) { if ((str = hash_find(hstatus, node))) { if (auth_failure) { /* github issue #14 * The error string contains "on". * Ideally we want to return "unknown" state without delay. */ printf ("%s: %s\n", node, "password verification timeout"); auth_failure = 0; } else printf("%s: %s\n", node, str); } else printf("%s: %s\n", node, "invalid hostname"); free(node); } hostlist_iterator_destroy(hlitr); hostlist_destroy(hlnodes); } static void _onoff(hash_t hstatus, const char *nodes, const char *state) { hostlist_iterator_t hlitr; hostlist_t hlnodes; char *node; char *str; assert(hstatus); if (!(hlnodes = hostlist_create(nodes))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hlnodes))) { perror("hostlist_iterator_create"); exit(1); } while ((node = hostlist_next(hlitr))) { if ((str = hash_find(hstatus, node))) { printf("%s: %s\n", node, OK_STATUS); hash_remove(hstatus, node); if (!hash_insert(hstatus, (void *)node, (void *)state)) { perror("hash_insert"); exit(1); } /* XXX: Don't free 'node' here, it needs to be alloc'd for * the hash key. It's a mem-leak. Fix later. */ } else { printf("%s: %s\n", node, "invalid hostname"); free(node); } } hostlist_iterator_destroy(hlitr); hostlist_destroy(hlnodes); } static void _prompt_loop(void) { char buf[128]; char bufnode[128]; hash_t hstatus = NULL; hostlist_t hl = NULL; hostlist_iterator_t hlitr = NULL; char *node; assert(hostname); if (!(hstatus = hash_create(HASH_SIZE, (hash_key_f)hash_key_string, (hash_cmp_f)strcmp, (hash_del_f)NULL))) { perror("hash_create"); exit(1); } if (!(hl = hostlist_create(hostname))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hl))) { perror("hostlist_iterator"); exit(1); } /* all nodes begin as off */ while ((node = hostlist_next(hlitr))) { if (!hash_insert(hstatus, (void *)node, OFF_STATUS)) { perror("hash_insert"); exit(1); } /* XXX: Don't free 'node' here, it needs to be alloc'd for * the hash key. It's a mem-leak. Fix later. */ } hostlist_iterator_destroy(hlitr); hostlist_destroy(hl); while (1) { if (xreadline(CMD_PROMPT, buf, sizeof(buf)) == NULL) { break; } else if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "quit")) { break; } else if (!strcmp(buf, "stat")) { _stat(hstatus, hostname); } else if (sscanf(buf, "stat %s", bufnode) == 1) { _stat(hstatus, bufnode); } else if (!strcmp(buf, "on")) { _onoff(hstatus, hostname, ON_STATUS); } else if (sscanf(buf, "on %s", bufnode) == 1) { _onoff(hstatus, bufnode, ON_STATUS); } else if (!strcmp(buf, "off")) { _onoff(hstatus, hostname, OFF_STATUS); } else if (sscanf(buf, "off %s", bufnode) == 1) { _onoff(hstatus, bufnode, OFF_STATUS); } else printf("unknown command - type \"help\"\n"); } hash_destroy(hstatus); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/lom.c000066400000000000000000000117471415616035500153670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include "xread.h" #define LOM_LOGIN_PROMPT "SUNSP00144FEE320F login: " #define LOM_PASSWD_PROMPT "admin@paradise-sp's password: " #define LOM_PROMPT "paradise $ " #define LOM_BANNER "\n\ Sun Microsystems\n\ IPMI v1.5 Service Processor\n\ \n\ Version: V2.1.0.16\n" #define LOM_ON_RESP "Scheduled platform on\n" #define LOM_OFF_RESP "Scheduled platform off\n" #define LOM_CMD_INVAL "\ %s: not found\n" static void usage(void); static void prompt_loop(void); typedef enum { NONE, SSH, SER, SER_LOGIN } ilomtype_t; static ilomtype_t personality = NONE; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "personality", required_argument, 0, 'p' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': if (strcmp(optarg, "ssh") == 0) personality = SSH; else if (strcmp(optarg, "serial") == 0) personality = SER; else if (strcmp(optarg, "serial_loggedin") == 0) personality = SER_LOGIN; else usage(); break; default: usage(); } } if (optind < argc) usage(); if (personality == NONE) usage(); prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p ssh|serial|serial_loggedin\n", prog); exit(1); } static void prompt_loop(void) { char buf[128]; static char plug[4]; int authenticated; strcpy(plug, "Off"); switch (personality) { case SER: authenticated = 0; break; case SSH: authenticated = 1; break; case SER_LOGIN: authenticated = 2; break; case NONE: break; } for (;;) { switch (authenticated) { case 0: if (xreadline(LOM_LOGIN_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "admin")) authenticated = 1; break; case 1: if (xreadline(LOM_PASSWD_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "admin")) { authenticated = 2; printf(LOM_BANNER); } break; case 2: if (xreadline(LOM_PROMPT, buf, sizeof(buf)) == NULL) goto done; if (!strcmp(buf, "exit")) { goto done; } else if (!strcmp(buf, "platform get power state")) { printf("%s\n", plug); } else if (!strcmp(buf, "platform set power state -W -f -q on")) { if (!strcmp(plug, "Off")) { strcpy(plug, "On"); printf(LOM_ON_RESP); } } else if (!strcmp(buf, "platform set power state -W -f -q off")) { if (!strcmp(plug, "On")) { strcpy(plug, "Off"); printf(LOM_OFF_RESP); } } else { printf(LOM_CMD_INVAL, buf); } } continue; done: break; } } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/mcr.conf.in000066400000000000000000001176211415616035500164670ustar00rootroot00000000000000# # $Id: powerman.conf-mcr 789 2006-10-27 22:28:44Z garlick $ # # MCR powerman.conf (1152 nodes, 121 iceboxes) - mod to work in test harness. # FIXME: we run out of ptys on some platforms with this many (121) coprocesses # include "@top_srcdir@/etc/icebox3.dev" tcpwrappers yes # 10 ports per power controller. device "ice-r1-1" "icebox3" "icebox -pv3|&" device "ice-r2-1" "icebox3" "icebox -pv3|&" device "ice-r4-1" "icebox3" "icebox -pv3|&" device "ice-r5-1" "icebox3" "icebox -pv3|&" device "ice-r6-1" "icebox3" "icebox -pv3|&" device "ice-r7-1" "icebox3" "icebox -pv3|&" device "ice-r7-2" "icebox3" "icebox -pv3|&" device "ice-r7-3" "icebox3" "icebox -pv3|&" device "ice-r8-1" "icebox3" "icebox -pv3|&" device "ice-r8-2" "icebox3" "icebox -pv3|&" device "ice-r8-3" "icebox3" "icebox -pv3|&" device "ice-r9-1" "icebox3" "icebox -pv3|&" device "ice-r9-2" "icebox3" "icebox -pv3|&" device "ice-r9-3" "icebox3" "icebox -pv3|&" device "ice-r9-4" "icebox3" "icebox -pv3|&" device "ice-r10-1" "icebox3" "icebox -pv3|&" device "ice-r10-2" "icebox3" "icebox -pv3|&" device "ice-r11-1" "icebox3" "icebox -pv3|&" device "ice-r11-2" "icebox3" "icebox -pv3|&" device "ice-r11-3" "icebox3" "icebox -pv3|&" device "ice-r11-4" "icebox3" "icebox -pv3|&" device "ice-r15-1" "icebox3" "icebox -pv3|&" device "ice-r15-2" "icebox3" "icebox -pv3|&" device "ice-r15-3" "icebox3" "icebox -pv3|&" device "ice-r15-4" "icebox3" "icebox -pv3|&" device "ice-r16-1" "icebox3" "icebox -pv3|&" device "ice-r16-2" "icebox3" "icebox -pv3|&" device "ice-r17-1" "icebox3" "icebox -pv3|&" device "ice-r17-2" "icebox3" "icebox -pv3|&" device "ice-r17-3" "icebox3" "icebox -pv3|&" device "ice-r17-4" "icebox3" "icebox -pv3|&" device "ice-r18-1" "icebox3" "icebox -pv3|&" device "ice-r18-2" "icebox3" "icebox -pv3|&" device "ice-r18-3" "icebox3" "icebox -pv3|&" device "ice-r18-4" "icebox3" "icebox -pv3|&" device "ice-r19-1" "icebox3" "icebox -pv3|&" device "ice-r19-2" "icebox3" "icebox -pv3|&" device "ice-r20-1" "icebox3" "icebox -pv3|&" device "ice-r20-2" "icebox3" "icebox -pv3|&" device "ice-r20-3" "icebox3" "icebox -pv3|&" device "ice-r20-4" "icebox3" "icebox -pv3|&" device "ice-r23-1" "icebox3" "icebox -pv3|&" device "ice-r23-2" "icebox3" "icebox -pv3|&" device "ice-r23-3" "icebox3" "icebox -pv3|&" device "ice-r23-4" "icebox3" "icebox -pv3|&" device "ice-r24-1" "icebox3" "icebox -pv3|&" device "ice-r24-2" "icebox3" "icebox -pv3|&" device "ice-r25-1" "icebox3" "icebox -pv3|&" device "ice-r25-2" "icebox3" "icebox -pv3|&" device "ice-r25-3" "icebox3" "icebox -pv3|&" device "ice-r25-4" "icebox3" "icebox -pv3|&" device "ice-r26-1" "icebox3" "icebox -pv3|&" device "ice-r26-2" "icebox3" "icebox -pv3|&" device "ice-r26-3" "icebox3" "icebox -pv3|&" device "ice-r26-4" "icebox3" "icebox -pv3|&" device "ice-r27-1" "icebox3" "icebox -pv3|&" device "ice-r27-2" "icebox3" "icebox -pv3|&" device "ice-r28-1" "icebox3" "icebox -pv3|&" device "ice-r28-2" "icebox3" "icebox -pv3|&" device "ice-r28-3" "icebox3" "icebox -pv3|&" device "ice-r28-4" "icebox3" "icebox -pv3|&" device "ice-r29-1" "icebox3" "icebox -pv3|&" device "ice-r29-2" "icebox3" "icebox -pv3|&" device "ice-r29-3" "icebox3" "icebox -pv3|&" device "ice-r29-4" "icebox3" "icebox -pv3|&" device "ice-r30-1" "icebox3" "icebox -pv3|&" device "ice-r30-2" "icebox3" "icebox -pv3|&" device "ice-r31-1" "icebox3" "icebox -pv3|&" device "ice-r31-2" "icebox3" "icebox -pv3|&" device "ice-r31-3" "icebox3" "icebox -pv3|&" device "ice-r31-4" "icebox3" "icebox -pv3|&" device "ice-r32-1" "icebox3" "icebox -pv3|&" device "ice-r32-2" "icebox3" "icebox -pv3|&" device "ice-r32-3" "icebox3" "icebox -pv3|&" device "ice-r32-4" "icebox3" "icebox -pv3|&" device "ice-r33-1" "icebox3" "icebox -pv3|&" device "ice-r33-2" "icebox3" "icebox -pv3|&" device "ice-r34-1" "icebox3" "icebox -pv3|&" device "ice-r34-2" "icebox3" "icebox -pv3|&" device "ice-r34-3" "icebox3" "icebox -pv3|&" device "ice-r34-4" "icebox3" "icebox -pv3|&" device "ice-r35-1" "icebox3" "icebox -pv3|&" device "ice-r35-2" "icebox3" "icebox -pv3|&" device "ice-r35-3" "icebox3" "icebox -pv3|&" device "ice-r35-4" "icebox3" "icebox -pv3|&" device "ice-r36-1" "icebox3" "icebox -pv3|&" device "ice-r36-2" "icebox3" "icebox -pv3|&" device "ice-r37-1" "icebox3" "icebox -pv3|&" device "ice-r37-2" "icebox3" "icebox -pv3|&" device "ice-r37-3" "icebox3" "icebox -pv3|&" device "ice-r37-4" "icebox3" "icebox -pv3|&" device "ice-r38-1" "icebox3" "icebox -pv3|&" device "ice-r38-2" "icebox3" "icebox -pv3|&" device "ice-r38-3" "icebox3" "icebox -pv3|&" device "ice-r38-4" "icebox3" "icebox -pv3|&" device "ice-r39-1" "icebox3" "icebox -pv3|&" device "ice-r39-2" "icebox3" "icebox -pv3|&" device "ice-r40-1" "icebox3" "icebox -pv3|&" device "ice-r40-2" "icebox3" "icebox -pv3|&" device "ice-r40-3" "icebox3" "icebox -pv3|&" device "ice-r40-4" "icebox3" "icebox -pv3|&" device "ice-r41-1" "icebox3" "icebox -pv3|&" device "ice-r41-2" "icebox3" "icebox -pv3|&" device "ice-r41-3" "icebox3" "icebox -pv3|&" device "ice-r41-4" "icebox3" "icebox -pv3|&" device "ice-r42-1" "icebox3" "icebox -pv3|&" device "ice-r42-2" "icebox3" "icebox -pv3|&" device "ice-r43-1" "icebox3" "icebox -pv3|&" device "ice-r43-2" "icebox3" "icebox -pv3|&" device "ice-r43-3" "icebox3" "icebox -pv3|&" device "ice-r43-4" "icebox3" "icebox -pv3|&" device "ice-r12-1" "icebox3" "icebox -pv3|&" device "ice-r12-2" "icebox3" "icebox -pv3|&" device "ice-r12-3" "icebox3" "icebox -pv3|&" device "ice-r12-4" "icebox3" "icebox -pv3|&" device "ice-r13-1" "icebox3" "icebox -pv3|&" device "ice-r13-2" "icebox3" "icebox -pv3|&" device "ice-r14-1" "icebox3" "icebox -pv3|&" device "ice-r14-2" "icebox3" "icebox -pv3|&" device "ice-r14-3" "icebox3" "icebox -pv3|&" device "ice-r14-4" "icebox3" "icebox -pv3|&" node "mcr0" "ice-r1-1" "1" node "mcr1" "ice-r1-1" "2" node "mcr2" "ice-r1-1" "3" node "mcr3" "ice-r1-1" "4" node "mcr4" "ice-r1-1" "5" node "mcr5" "ice-r1-1" "6" node "mcr6" "ice-r1-1" "7" node "mcr7" "ice-r1-1" "8" node "mcr8" "ice-r1-1" "9" node "mcr9" "ice-r1-1" "10" # node "mcr10" "ice-r2-1" "1" node "mcr11" "ice-r2-1" "2" node "mcr12" "ice-r2-1" "3" node "mcr13" "ice-r2-1" "4" node "mcr14" "ice-r2-1" "5" node "mcr15" "ice-r2-1" "6" node "mcr16" "ice-r2-1" "7" node "mcr17" "ice-r2-1" "8" node "mcr18" "ice-r2-1" "9" node "mcr19" "ice-r2-1" "10" # node "mcr20" "ice-r4-1" "1" node "mcr21" "ice-r4-1" "2" node "mcr22" "ice-r4-1" "3" node "mcr23" "ice-r4-1" "4" # node "mcr36" "ice-r4-1" "5" node "mcr37" "ice-r4-1" "6" node "mcr38" "ice-r4-1" "7" node "mcr39" "ice-r4-1" "8" # node "mcr24" "ice-r5-1" "1" node "mcr25" "ice-r5-1" "2" node "mcrj" "ice-r5-1" "4" # node "mcr26" "ice-r6-1" "1" node "mcr27" "ice-r6-1" "2" node "mcr28" "ice-r6-1" "3" node "mcr29" "ice-r6-1" "4" node "mcr30" "ice-r6-1" "5" node "mcr31" "ice-r6-1" "6" node "mcr32" "ice-r6-1" "7" node "mcr33" "ice-r6-1" "8" node "mcr34" "ice-r6-1" "9" node "mcr35" "ice-r6-1" "10" # #OLD node "mcr36" "ice-r7-1" "1" #OLD node "mcr37" "ice-r7-1" "2" #OLD node "mcr38" "ice-r7-1" "3" #OLD node "mcr39" "ice-r7-1" "4" node "mcr40" "ice-r7-1" "5" node "mcr41" "ice-r7-1" "6" node "mcr42" "ice-r7-1" "7" node "mcr43" "ice-r7-1" "8" node "mcr44" "ice-r7-1" "9" node "mcr45" "ice-r7-1" "10" # node "mcr46" "ice-r7-2" "1" node "mcr47" "ice-r7-2" "2" node "mcr48" "ice-r7-2" "3" node "mcr49" "ice-r7-2" "4" node "mcr50" "ice-r7-2" "5" node "mcr51" "ice-r7-2" "6" node "mcr52" "ice-r7-2" "7" node "mcr53" "ice-r7-2" "8" node "mcr54" "ice-r7-2" "9" node "mcr55" "ice-r7-2" "10" # node "mcr56" "ice-r7-3" "1" node "mcr57" "ice-r7-3" "2" node "mcr58" "ice-r7-3" "3" node "mcr59" "ice-r7-3" "4" node "mcr60" "ice-r7-3" "5" node "mcr61" "ice-r7-3" "6" node "mcr62" "ice-r7-3" "7" node "mcr63" "ice-r7-3" "8" node "mcr64" "ice-r7-3" "9" node "mcr65" "ice-r7-3" "10" # node "mcr66" "ice-r8-1" "1" node "mcr67" "ice-r8-1" "2" node "mcr68" "ice-r8-1" "3" node "mcr69" "ice-r8-1" "4" node "mcr70" "ice-r8-1" "5" node "mcr71" "ice-r8-1" "6" node "mcr72" "ice-r8-1" "7" node "mcr73" "ice-r8-1" "8" node "mcr74" "ice-r8-1" "9" node "mcr75" "ice-r8-1" "10" # node "mcr76" "ice-r8-2" "1" node "mcr77" "ice-r8-2" "2" node "mcr78" "ice-r8-2" "3" node "mcr79" "ice-r8-2" "4" node "mcr80" "ice-r8-2" "5" node "mcr81" "ice-r8-2" "6" node "mcr82" "ice-r8-2" "7" node "mcr83" "ice-r8-2" "8" node "mcr84" "ice-r8-2" "9" node "mcr85" "ice-r8-2" "10" # node "mcr86" "ice-r8-3" "1" node "mcr87" "ice-r8-3" "2" node "mcr88" "ice-r8-3" "3" node "mcr89" "ice-r8-3" "4" node "mcr90" "ice-r8-3" "5" node "mcr91" "ice-r8-3" "6" node "mcr92" "ice-r8-3" "7" node "mcr93" "ice-r8-3" "8" node "mcr94" "ice-r8-3" "9" node "mcr95" "ice-r8-3" "10" # # # CNSU0 # node "mcr96" "ice-r9-1" "1" node "mcr97" "ice-r9-1" "2" node "mcr98" "ice-r9-1" "3" node "mcr99" "ice-r9-1" "4" node "mcr100" "ice-r9-1" "5" node "mcr101" "ice-r9-1" "6" node "mcr102" "ice-r9-1" "7" node "mcr103" "ice-r9-1" "8" node "mcr104" "ice-r9-1" "9" node "mcr105" "ice-r9-1" "10" # node "mcr106" "ice-r9-2" "1" node "mcr107" "ice-r9-2" "2" node "mcr108" "ice-r9-2" "3" node "mcr109" "ice-r9-2" "4" node "mcr110" "ice-r9-2" "5" node "mcr111" "ice-r9-2" "6" node "mcr112" "ice-r9-2" "7" node "mcr113" "ice-r9-2" "8" node "mcr114" "ice-r9-2" "9" node "mcr115" "ice-r9-2" "10" # node "mcr116" "ice-r9-3" "1" node "mcr117" "ice-r9-3" "2" node "mcr118" "ice-r9-3" "3" node "mcr119" "ice-r9-3" "4" node "mcr120" "ice-r9-3" "5" node "mcr121" "ice-r9-3" "6" node "mcr122" "ice-r9-3" "7" node "mcr123" "ice-r9-3" "8" node "mcr124" "ice-r9-3" "9" node "mcr125" "ice-r9-3" "10" # node "mcr126" "ice-r9-4" "1" node "mcr127" "ice-r9-4" "2" node "mcr128" "ice-r9-4" "3" node "mcr129" "ice-r9-4" "4" node "mcr130" "ice-r9-4" "5" node "mcr131" "ice-r9-4" "6" node "mcr132" "ice-r9-4" "7" node "mcr133" "ice-r9-4" "8" node "mcr134" "ice-r9-4" "9" node "mcr135" "ice-r9-4" "10" # node "mcr136" "ice-r10-1" "1" node "mcr137" "ice-r10-1" "2" node "mcr138" "ice-r10-1" "3" node "mcr139" "ice-r10-1" "4" node "mcr140" "ice-r10-1" "5" node "mcr141" "ice-r10-1" "6" # node "mcr142" "ice-r10-2" "1" node "mcr143" "ice-r10-2" "2" node "mcr144" "ice-r10-2" "3" node "mcr145" "ice-r10-2" "4" node "mcr146" "ice-r10-2" "5" node "mcr147" "ice-r10-2" "6" node "mcr148" "ice-r10-2" "7" node "mcr149" "ice-r10-2" "8" node "mcr150" "ice-r10-2" "9" node "mcr151" "ice-r10-2" "10" # node "mcr152" "ice-r11-1" "1" node "mcr153" "ice-r11-1" "2" node "mcr154" "ice-r11-1" "3" node "mcr155" "ice-r11-1" "4" node "mcr156" "ice-r11-1" "5" node "mcr157" "ice-r11-1" "6" node "mcr158" "ice-r11-1" "7" node "mcr159" "ice-r11-1" "8" node "mcr160" "ice-r11-1" "9" node "mcr161" "ice-r11-1" "10" # node "mcr162" "ice-r11-2" "1" node "mcr163" "ice-r11-2" "2" node "mcr164" "ice-r11-2" "3" node "mcr165" "ice-r11-2" "4" node "mcr166" "ice-r11-2" "5" node "mcr167" "ice-r11-2" "6" node "mcr168" "ice-r11-2" "7" node "mcr169" "ice-r11-2" "8" node "mcr170" "ice-r11-2" "9" node "mcr171" "ice-r11-2" "10" # node "mcr172" "ice-r11-3" "1" node "mcr173" "ice-r11-3" "2" node "mcr174" "ice-r11-3" "3" node "mcr175" "ice-r11-3" "4" node "mcr176" "ice-r11-3" "5" node "mcr177" "ice-r11-3" "6" node "mcr178" "ice-r11-3" "7" node "mcr179" "ice-r11-3" "8" node "mcr180" "ice-r11-3" "9" node "mcr181" "ice-r11-3" "10" # node "mcr182" "ice-r11-4" "1" node "mcr183" "ice-r11-4" "2" node "mcr184" "ice-r11-4" "3" node "mcr185" "ice-r11-4" "4" node "mcr186" "ice-r11-4" "5" node "mcr187" "ice-r11-4" "6" node "mcr188" "ice-r11-4" "7" node "mcr189" "ice-r11-4" "8" node "mcr190" "ice-r11-4" "9" node "mcr191" "ice-r11-4" "10" # # CNSU1 # node "mcr192" "ice-r15-1" "1" node "mcr193" "ice-r15-1" "2" node "mcr194" "ice-r15-1" "3" node "mcr195" "ice-r15-1" "4" node "mcr196" "ice-r15-1" "5" node "mcr197" "ice-r15-1" "6" node "mcr198" "ice-r15-1" "7" node "mcr199" "ice-r15-1" "8" node "mcr200" "ice-r15-1" "9" node "mcr201" "ice-r15-1" "10" # node "mcr202" "ice-r15-2" "1" node "mcr203" "ice-r15-2" "2" node "mcr204" "ice-r15-2" "3" node "mcr205" "ice-r15-2" "4" node "mcr206" "ice-r15-2" "5" node "mcr207" "ice-r15-2" "6" node "mcr208" "ice-r15-2" "7" node "mcr209" "ice-r15-2" "8" node "mcr210" "ice-r15-2" "9" node "mcr211" "ice-r15-2" "10" # node "mcr212" "ice-r15-3" "1" node "mcr213" "ice-r15-3" "2" node "mcr214" "ice-r15-3" "3" node "mcr215" "ice-r15-3" "4" node "mcr216" "ice-r15-3" "5" node "mcr217" "ice-r15-3" "6" node "mcr218" "ice-r15-3" "7" node "mcr219" "ice-r15-3" "8" node "mcr220" "ice-r15-3" "9" node "mcr221" "ice-r15-3" "10" # node "mcr222" "ice-r15-4" "1" node "mcr223" "ice-r15-4" "2" node "mcr224" "ice-r15-4" "3" node "mcr225" "ice-r15-4" "4" node "mcr226" "ice-r15-4" "5" node "mcr227" "ice-r15-4" "6" node "mcr228" "ice-r15-4" "7" node "mcr229" "ice-r15-4" "8" node "mcr230" "ice-r15-4" "9" node "mcr231" "ice-r15-4" "10" # node "mcr232" "ice-r16-1" "1" node "mcr233" "ice-r16-1" "2" node "mcr234" "ice-r16-1" "3" node "mcr235" "ice-r16-1" "4" node "mcr236" "ice-r16-1" "5" node "mcr237" "ice-r16-1" "6" # node "mcr238" "ice-r16-2" "1" node "mcr239" "ice-r16-2" "2" node "mcr240" "ice-r16-2" "3" node "mcr241" "ice-r16-2" "4" node "mcr242" "ice-r16-2" "5" node "mcr243" "ice-r16-2" "6" node "mcr244" "ice-r16-2" "7" node "mcr245" "ice-r16-2" "8" node "mcr246" "ice-r16-2" "9" node "mcr247" "ice-r16-2" "10" # node "mcr248" "ice-r17-1" "1" node "mcr249" "ice-r17-1" "2" node "mcr250" "ice-r17-1" "3" node "mcr251" "ice-r17-1" "4" node "mcr252" "ice-r17-1" "5" node "mcr253" "ice-r17-1" "6" node "mcr254" "ice-r17-1" "7" node "mcr255" "ice-r17-1" "8" node "mcr256" "ice-r17-1" "9" node "mcr257" "ice-r17-1" "10" # node "mcr258" "ice-r17-2" "1" node "mcr259" "ice-r17-2" "2" node "mcr260" "ice-r17-2" "3" node "mcr261" "ice-r17-2" "4" node "mcr262" "ice-r17-2" "5" node "mcr263" "ice-r17-2" "6" node "mcr264" "ice-r17-2" "7" node "mcr265" "ice-r17-2" "8" node "mcr266" "ice-r17-2" "9" node "mcr267" "ice-r17-2" "10" # node "mcr268" "ice-r17-3" "1" node "mcr269" "ice-r17-3" "2" node "mcr270" "ice-r17-3" "3" node "mcr271" "ice-r17-3" "4" node "mcr272" "ice-r17-3" "5" node "mcr273" "ice-r17-3" "6" node "mcr274" "ice-r17-3" "7" node "mcr275" "ice-r17-3" "8" node "mcr276" "ice-r17-3" "9" node "mcr277" "ice-r17-3" "10" # node "mcr278" "ice-r17-4" "1" node "mcr279" "ice-r17-4" "2" node "mcr280" "ice-r17-4" "3" node "mcr281" "ice-r17-4" "4" node "mcr282" "ice-r17-4" "5" node "mcr283" "ice-r17-4" "6" node "mcr284" "ice-r17-4" "7" node "mcr285" "ice-r17-4" "8" node "mcr286" "ice-r17-4" "9" node "mcr287" "ice-r17-4" "10" # # CNSU2 # node "mcr288" "ice-r18-1" "1" node "mcr289" "ice-r18-1" "2" node "mcr290" "ice-r18-1" "3" node "mcr291" "ice-r18-1" "4" node "mcr292" "ice-r18-1" "5" node "mcr293" "ice-r18-1" "6" node "mcr294" "ice-r18-1" "7" node "mcr295" "ice-r18-1" "8" node "mcr296" "ice-r18-1" "9" node "mcr297" "ice-r18-1" "10" # node "mcr298" "ice-r18-2" "1" node "mcr299" "ice-r18-2" "2" node "mcr300" "ice-r18-2" "3" node "mcr301" "ice-r18-2" "4" node "mcr302" "ice-r18-2" "5" node "mcr303" "ice-r18-2" "6" node "mcr304" "ice-r18-2" "7" node "mcr305" "ice-r18-2" "8" node "mcr306" "ice-r18-2" "9" node "mcr307" "ice-r18-2" "10" # node "mcr308" "ice-r18-3" "1" node "mcr309" "ice-r18-3" "2" node "mcr310" "ice-r18-3" "3" node "mcr311" "ice-r18-3" "4" node "mcr312" "ice-r18-3" "5" node "mcr313" "ice-r18-3" "6" node "mcr314" "ice-r18-3" "7" node "mcr315" "ice-r18-3" "8" node "mcr316" "ice-r18-3" "9" node "mcr317" "ice-r18-3" "10" # node "mcr318" "ice-r18-4" "1" node "mcr319" "ice-r18-4" "2" node "mcr320" "ice-r18-4" "3" node "mcr321" "ice-r18-4" "4" node "mcr322" "ice-r18-4" "5" node "mcr323" "ice-r18-4" "6" node "mcr324" "ice-r18-4" "7" node "mcr325" "ice-r18-4" "8" node "mcr326" "ice-r18-4" "9" node "mcr327" "ice-r18-4" "10" # node "mcr328" "ice-r19-1" "1" node "mcr329" "ice-r19-1" "2" node "mcr330" "ice-r19-1" "3" node "mcr331" "ice-r19-1" "4" node "mcr332" "ice-r19-1" "5" node "mcr333" "ice-r19-1" "6" # node "mcr334" "ice-r19-2" "1" node "mcr335" "ice-r19-2" "2" node "mcr336" "ice-r19-2" "3" node "mcr337" "ice-r19-2" "4" node "mcr338" "ice-r19-2" "5" node "mcr339" "ice-r19-2" "6" node "mcr340" "ice-r19-2" "7" node "mcr341" "ice-r19-2" "8" node "mcr342" "ice-r19-2" "9" node "mcr343" "ice-r19-2" "10" # node "mcr344" "ice-r20-1" "1" node "mcr345" "ice-r20-1" "2" node "mcr346" "ice-r20-1" "3" node "mcr347" "ice-r20-1" "4" node "mcr348" "ice-r20-1" "5" node "mcr349" "ice-r20-1" "6" node "mcr350" "ice-r20-1" "7" node "mcr351" "ice-r20-1" "8" node "mcr352" "ice-r20-1" "9" node "mcr353" "ice-r20-1" "10" # node "mcr354" "ice-r20-2" "1" node "mcr355" "ice-r20-2" "2" node "mcr356" "ice-r20-2" "3" node "mcr357" "ice-r20-2" "4" node "mcr358" "ice-r20-2" "5" node "mcr359" "ice-r20-2" "6" node "mcr360" "ice-r20-2" "7" node "mcr361" "ice-r20-2" "8" node "mcr362" "ice-r20-2" "9" node "mcr363" "ice-r20-2" "10" # node "mcr364" "ice-r20-3" "1" node "mcr365" "ice-r20-3" "2" node "mcr366" "ice-r20-3" "3" node "mcr367" "ice-r20-3" "4" node "mcr368" "ice-r20-3" "5" node "mcr369" "ice-r20-3" "6" node "mcr370" "ice-r20-3" "7" node "mcr371" "ice-r20-3" "8" node "mcr372" "ice-r20-3" "9" node "mcr373" "ice-r20-3" "10" # node "mcr374" "ice-r20-4" "1" node "mcr375" "ice-r20-4" "2" node "mcr376" "ice-r20-4" "3" node "mcr377" "ice-r20-4" "4" node "mcr378" "ice-r20-4" "5" node "mcr379" "ice-r20-4" "6" node "mcr380" "ice-r20-4" "7" node "mcr381" "ice-r20-4" "8" node "mcr382" "ice-r20-4" "9" node "mcr383" "ice-r20-4" "10" # # CNSU3 # node "mcr384" "ice-r23-1" "1" node "mcr385" "ice-r23-1" "2" node "mcr386" "ice-r23-1" "3" node "mcr387" "ice-r23-1" "4" node "mcr388" "ice-r23-1" "5" node "mcr389" "ice-r23-1" "6" node "mcr390" "ice-r23-1" "7" node "mcr391" "ice-r23-1" "8" node "mcr392" "ice-r23-1" "9" node "mcr393" "ice-r23-1" "10" # node "mcr394" "ice-r23-2" "1" node "mcr395" "ice-r23-2" "2" node "mcr396" "ice-r23-2" "3" node "mcr397" "ice-r23-2" "4" node "mcr398" "ice-r23-2" "5" node "mcr399" "ice-r23-2" "6" node "mcr400" "ice-r23-2" "7" node "mcr401" "ice-r23-2" "8" node "mcr402" "ice-r23-2" "9" node "mcr403" "ice-r23-2" "10" # node "mcr404" "ice-r23-3" "1" node "mcr405" "ice-r23-3" "2" node "mcr406" "ice-r23-3" "3" node "mcr407" "ice-r23-3" "4" node "mcr408" "ice-r23-3" "5" node "mcr409" "ice-r23-3" "6" node "mcr410" "ice-r23-3" "7" node "mcr411" "ice-r23-3" "8" node "mcr412" "ice-r23-3" "9" node "mcr413" "ice-r23-3" "10" # node "mcr414" "ice-r23-4" "1" node "mcr415" "ice-r23-4" "2" node "mcr416" "ice-r23-4" "3" node "mcr417" "ice-r23-4" "4" node "mcr418" "ice-r23-4" "5" node "mcr419" "ice-r23-4" "6" node "mcr420" "ice-r23-4" "7" node "mcr421" "ice-r23-4" "8" node "mcr422" "ice-r23-4" "9" node "mcr423" "ice-r23-4" "10" # node "mcr424" "ice-r24-1" "1" node "mcr425" "ice-r24-1" "2" node "mcr426" "ice-r24-1" "3" node "mcr427" "ice-r24-1" "4" node "mcr428" "ice-r24-1" "5" node "mcr429" "ice-r24-1" "6" # node "mcr430" "ice-r24-2" "1" node "mcr431" "ice-r24-2" "2" node "mcr432" "ice-r24-2" "3" node "mcr433" "ice-r24-2" "4" node "mcr434" "ice-r24-2" "5" node "mcr435" "ice-r24-2" "6" node "mcr436" "ice-r24-2" "7" node "mcr437" "ice-r24-2" "8" node "mcr438" "ice-r24-2" "9" node "mcr439" "ice-r24-2" "10" # node "mcr440" "ice-r25-1" "1" node "mcr441" "ice-r25-1" "2" node "mcr442" "ice-r25-1" "3" node "mcr443" "ice-r25-1" "4" node "mcr444" "ice-r25-1" "5" node "mcr445" "ice-r25-1" "6" node "mcr446" "ice-r25-1" "7" node "mcr447" "ice-r25-1" "8" node "mcr448" "ice-r25-1" "9" node "mcr449" "ice-r25-1" "10" # node "mcr450" "ice-r25-2" "1" node "mcr451" "ice-r25-2" "2" node "mcr452" "ice-r25-2" "3" node "mcr453" "ice-r25-2" "4" node "mcr454" "ice-r25-2" "5" node "mcr455" "ice-r25-2" "6" node "mcr456" "ice-r25-2" "7" node "mcr457" "ice-r25-2" "8" node "mcr458" "ice-r25-2" "9" node "mcr459" "ice-r25-2" "10" # node "mcr460" "ice-r25-3" "1" node "mcr461" "ice-r25-3" "2" node "mcr462" "ice-r25-3" "3" node "mcr463" "ice-r25-3" "4" node "mcr464" "ice-r25-3" "5" node "mcr465" "ice-r25-3" "6" node "mcr466" "ice-r25-3" "7" node "mcr467" "ice-r25-3" "8" node "mcr468" "ice-r25-3" "9" node "mcr469" "ice-r25-3" "10" # node "mcr470" "ice-r25-4" "1" node "mcr471" "ice-r25-4" "2" node "mcr472" "ice-r25-4" "3" node "mcr473" "ice-r25-4" "4" node "mcr474" "ice-r25-4" "5" node "mcr475" "ice-r25-4" "6" node "mcr476" "ice-r25-4" "7" node "mcr477" "ice-r25-4" "8" node "mcr478" "ice-r25-4" "9" node "mcr479" "ice-r25-4" "10" # # CNSU4 # node "mcr480" "ice-r26-1" "1" node "mcr481" "ice-r26-1" "2" node "mcr482" "ice-r26-1" "3" node "mcr483" "ice-r26-1" "4" node "mcr484" "ice-r26-1" "5" node "mcr485" "ice-r26-1" "6" node "mcr486" "ice-r26-1" "7" node "mcr487" "ice-r26-1" "8" node "mcr488" "ice-r26-1" "9" node "mcr489" "ice-r26-1" "10" # node "mcr490" "ice-r26-2" "1" node "mcr491" "ice-r26-2" "2" node "mcr492" "ice-r26-2" "3" node "mcr493" "ice-r26-2" "4" node "mcr494" "ice-r26-2" "5" node "mcr495" "ice-r26-2" "6" node "mcr496" "ice-r26-2" "7" node "mcr497" "ice-r26-2" "8" node "mcr498" "ice-r26-2" "9" node "mcr499" "ice-r26-2" "10" # node "mcr500" "ice-r26-3" "1" node "mcr501" "ice-r26-3" "2" node "mcr502" "ice-r26-3" "3" node "mcr503" "ice-r26-3" "4" node "mcr504" "ice-r26-3" "5" node "mcr505" "ice-r26-3" "6" node "mcr506" "ice-r26-3" "7" node "mcr507" "ice-r26-3" "8" node "mcr508" "ice-r26-3" "9" node "mcr509" "ice-r26-3" "10" # node "mcr510" "ice-r26-4" "1" node "mcr511" "ice-r26-4" "2" node "mcr512" "ice-r26-4" "3" node "mcr513" "ice-r26-4" "4" node "mcr514" "ice-r26-4" "5" node "mcr515" "ice-r26-4" "6" node "mcr516" "ice-r26-4" "7" node "mcr517" "ice-r26-4" "8" node "mcr518" "ice-r26-4" "9" node "mcr519" "ice-r26-4" "10" # node "mcr520" "ice-r27-1" "1" node "mcr521" "ice-r27-1" "2" node "mcr522" "ice-r27-1" "3" node "mcr523" "ice-r27-1" "4" node "mcr524" "ice-r27-1" "5" node "mcr525" "ice-r27-1" "6" # node "mcr526" "ice-r27-2" "1" node "mcr527" "ice-r27-2" "2" node "mcr528" "ice-r27-2" "3" node "mcr529" "ice-r27-2" "4" node "mcr530" "ice-r27-2" "5" node "mcr531" "ice-r27-2" "6" node "mcr532" "ice-r27-2" "7" node "mcr533" "ice-r27-2" "8" node "mcr534" "ice-r27-2" "9" node "mcr535" "ice-r27-2" "10" # node "mcr536" "ice-r28-1" "1" node "mcr537" "ice-r28-1" "2" node "mcr538" "ice-r28-1" "3" node "mcr539" "ice-r28-1" "4" node "mcr540" "ice-r28-1" "5" node "mcr541" "ice-r28-1" "6" node "mcr542" "ice-r28-1" "7" node "mcr543" "ice-r28-1" "8" node "mcr544" "ice-r28-1" "9" node "mcr545" "ice-r28-1" "10" # node "mcr546" "ice-r28-2" "1" node "mcr547" "ice-r28-2" "2" node "mcr548" "ice-r28-2" "3" node "mcr549" "ice-r28-2" "4" node "mcr550" "ice-r28-2" "5" node "mcr551" "ice-r28-2" "6" node "mcr552" "ice-r28-2" "7" node "mcr553" "ice-r28-2" "8" node "mcr554" "ice-r28-2" "9" node "mcr555" "ice-r28-2" "10" # node "mcr556" "ice-r28-3" "1" node "mcr557" "ice-r28-3" "2" node "mcr558" "ice-r28-3" "3" node "mcr559" "ice-r28-3" "4" node "mcr560" "ice-r28-3" "5" node "mcr561" "ice-r28-3" "6" node "mcr562" "ice-r28-3" "7" node "mcr563" "ice-r28-3" "8" node "mcr564" "ice-r28-3" "9" node "mcr565" "ice-r28-3" "10" # node "mcr566" "ice-r28-4" "1" node "mcr567" "ice-r28-4" "2" node "mcr568" "ice-r28-4" "3" node "mcr569" "ice-r28-4" "4" node "mcr570" "ice-r28-4" "5" node "mcr571" "ice-r28-4" "6" node "mcr572" "ice-r28-4" "7" node "mcr573" "ice-r28-4" "8" node "mcr574" "ice-r28-4" "9" node "mcr575" "ice-r28-4" "10" # # CNSU5 # node "mcr576" "ice-r29-1" "1" node "mcr577" "ice-r29-1" "2" node "mcr578" "ice-r29-1" "3" node "mcr579" "ice-r29-1" "4" node "mcr580" "ice-r29-1" "5" node "mcr581" "ice-r29-1" "6" node "mcr582" "ice-r29-1" "7" node "mcr583" "ice-r29-1" "8" node "mcr584" "ice-r29-1" "9" node "mcr585" "ice-r29-1" "10" # node "mcr586" "ice-r29-2" "1" node "mcr587" "ice-r29-2" "2" node "mcr588" "ice-r29-2" "3" node "mcr589" "ice-r29-2" "4" node "mcr590" "ice-r29-2" "5" node "mcr591" "ice-r29-2" "6" node "mcr592" "ice-r29-2" "7" node "mcr593" "ice-r29-2" "8" node "mcr594" "ice-r29-2" "9" node "mcr595" "ice-r29-2" "10" # node "mcr596" "ice-r29-3" "1" node "mcr597" "ice-r29-3" "2" node "mcr598" "ice-r29-3" "3" node "mcr599" "ice-r29-3" "4" node "mcr600" "ice-r29-3" "5" node "mcr601" "ice-r29-3" "6" node "mcr602" "ice-r29-3" "7" node "mcr603" "ice-r29-3" "8" node "mcr604" "ice-r29-3" "9" node "mcr605" "ice-r29-3" "10" # node "mcr606" "ice-r29-4" "1" node "mcr607" "ice-r29-4" "2" node "mcr608" "ice-r29-4" "3" node "mcr609" "ice-r29-4" "4" node "mcr610" "ice-r29-4" "5" node "mcr611" "ice-r29-4" "6" node "mcr612" "ice-r29-4" "7" node "mcr613" "ice-r29-4" "8" node "mcr614" "ice-r29-4" "9" node "mcr615" "ice-r29-4" "10" # node "mcr616" "ice-r30-1" "1" node "mcr617" "ice-r30-1" "2" node "mcr618" "ice-r30-1" "3" node "mcr619" "ice-r30-1" "4" node "mcr620" "ice-r30-1" "5" node "mcr621" "ice-r30-1" "6" # node "mcr622" "ice-r30-2" "1" node "mcr623" "ice-r30-2" "2" node "mcr624" "ice-r30-2" "3" node "mcr625" "ice-r30-2" "4" node "mcr626" "ice-r30-2" "5" node "mcr627" "ice-r30-2" "6" node "mcr628" "ice-r30-2" "7" node "mcr629" "ice-r30-2" "8" node "mcr630" "ice-r30-2" "9" node "mcr631" "ice-r30-2" "10" # node "mcr632" "ice-r31-1" "1" node "mcr633" "ice-r31-1" "2" node "mcr634" "ice-r31-1" "3" node "mcr635" "ice-r31-1" "4" node "mcr636" "ice-r31-1" "5" node "mcr637" "ice-r31-1" "6" node "mcr638" "ice-r31-1" "7" node "mcr639" "ice-r31-1" "8" node "mcr640" "ice-r31-1" "9" node "mcr641" "ice-r31-1" "10" # node "mcr642" "ice-r31-2" "1" node "mcr643" "ice-r31-2" "2" node "mcr644" "ice-r31-2" "3" node "mcr645" "ice-r31-2" "4" node "mcr646" "ice-r31-2" "5" node "mcr647" "ice-r31-2" "6" node "mcr648" "ice-r31-2" "7" node "mcr649" "ice-r31-2" "8" node "mcr650" "ice-r31-2" "9" node "mcr651" "ice-r31-2" "10" # node "mcr652" "ice-r31-3" "1" node "mcr653" "ice-r31-3" "2" node "mcr654" "ice-r31-3" "3" node "mcr655" "ice-r31-3" "4" node "mcr656" "ice-r31-3" "5" node "mcr657" "ice-r31-3" "6" node "mcr658" "ice-r31-3" "7" node "mcr659" "ice-r31-3" "8" node "mcr660" "ice-r31-3" "9" node "mcr661" "ice-r31-3" "10" # node "mcr662" "ice-r31-4" "1" node "mcr663" "ice-r31-4" "2" node "mcr664" "ice-r31-4" "3" node "mcr665" "ice-r31-4" "4" node "mcr666" "ice-r31-4" "5" node "mcr667" "ice-r31-4" "6" node "mcr668" "ice-r31-4" "7" node "mcr669" "ice-r31-4" "8" node "mcr670" "ice-r31-4" "9" node "mcr671" "ice-r31-4" "10" # # CNSU6 # node "mcr672" "ice-r32-1" "1" node "mcr673" "ice-r32-1" "2" node "mcr674" "ice-r32-1" "3" node "mcr675" "ice-r32-1" "4" node "mcr676" "ice-r32-1" "5" node "mcr677" "ice-r32-1" "6" node "mcr678" "ice-r32-1" "7" node "mcr679" "ice-r32-1" "8" node "mcr680" "ice-r32-1" "9" node "mcr681" "ice-r32-1" "10" # node "mcr682" "ice-r32-2" "1" node "mcr683" "ice-r32-2" "2" node "mcr684" "ice-r32-2" "3" node "mcr685" "ice-r32-2" "4" node "mcr686" "ice-r32-2" "5" node "mcr687" "ice-r32-2" "6" node "mcr688" "ice-r32-2" "7" node "mcr689" "ice-r32-2" "8" node "mcr690" "ice-r32-2" "9" node "mcr691" "ice-r32-2" "10" # node "mcr692" "ice-r32-3" "1" node "mcr693" "ice-r32-3" "2" node "mcr694" "ice-r32-3" "3" node "mcr695" "ice-r32-3" "4" node "mcr696" "ice-r32-3" "5" node "mcr697" "ice-r32-3" "6" node "mcr698" "ice-r32-3" "7" node "mcr699" "ice-r32-3" "8" node "mcr700" "ice-r32-3" "9" node "mcr701" "ice-r32-3" "10" # node "mcr702" "ice-r32-4" "1" node "mcr703" "ice-r32-4" "2" node "mcr704" "ice-r32-4" "3" node "mcr705" "ice-r32-4" "4" node "mcr706" "ice-r32-4" "5" node "mcr707" "ice-r32-4" "6" node "mcr708" "ice-r32-4" "7" node "mcr709" "ice-r32-4" "8" node "mcr710" "ice-r32-4" "9" node "mcr711" "ice-r32-4" "10" # node "mcr712" "ice-r33-1" "1" node "mcr713" "ice-r33-1" "2" node "mcr714" "ice-r33-1" "3" node "mcr715" "ice-r33-1" "4" node "mcr716" "ice-r33-1" "5" node "mcr717" "ice-r33-1" "6" # node "mcr718" "ice-r33-2" "1" node "mcr719" "ice-r33-2" "2" node "mcr720" "ice-r33-2" "3" node "mcr721" "ice-r33-2" "4" node "mcr722" "ice-r33-2" "5" node "mcr723" "ice-r33-2" "6" node "mcr724" "ice-r33-2" "7" node "mcr725" "ice-r33-2" "8" node "mcr726" "ice-r33-2" "9" node "mcr727" "ice-r33-2" "10" # node "mcr728" "ice-r34-1" "1" node "mcr729" "ice-r34-1" "2" node "mcr730" "ice-r34-1" "3" node "mcr731" "ice-r34-1" "4" node "mcr732" "ice-r34-1" "5" node "mcr733" "ice-r34-1" "6" node "mcr734" "ice-r34-1" "7" node "mcr735" "ice-r34-1" "8" node "mcr736" "ice-r34-1" "9" node "mcr737" "ice-r34-1" "10" # node "mcr738" "ice-r34-2" "1" node "mcr739" "ice-r34-2" "2" node "mcr740" "ice-r34-2" "3" node "mcr741" "ice-r34-2" "4" node "mcr742" "ice-r34-2" "5" node "mcr743" "ice-r34-2" "6" node "mcr744" "ice-r34-2" "7" node "mcr745" "ice-r34-2" "8" node "mcr746" "ice-r34-2" "9" node "mcr747" "ice-r34-2" "10" # node "mcr748" "ice-r34-3" "1" node "mcr749" "ice-r34-3" "2" node "mcr750" "ice-r34-3" "3" node "mcr751" "ice-r34-3" "4" node "mcr752" "ice-r34-3" "5" node "mcr753" "ice-r34-3" "6" node "mcr754" "ice-r34-3" "7" node "mcr755" "ice-r34-3" "8" node "mcr756" "ice-r34-3" "9" node "mcr757" "ice-r34-3" "10" # node "mcr758" "ice-r34-4" "1" node "mcr759" "ice-r34-4" "2" node "mcr760" "ice-r34-4" "3" node "mcr761" "ice-r34-4" "4" node "mcr762" "ice-r34-4" "5" node "mcr763" "ice-r34-4" "6" node "mcr764" "ice-r34-4" "7" node "mcr765" "ice-r34-4" "8" node "mcr766" "ice-r34-4" "9" node "mcr767" "ice-r34-4" "10" # # CNSU7 # node "mcr768" "ice-r35-1" "1" node "mcr769" "ice-r35-1" "2" node "mcr770" "ice-r35-1" "3" node "mcr771" "ice-r35-1" "4" node "mcr772" "ice-r35-1" "5" node "mcr773" "ice-r35-1" "6" node "mcr774" "ice-r35-1" "7" node "mcr775" "ice-r35-1" "8" node "mcr776" "ice-r35-1" "9" node "mcr777" "ice-r35-1" "10" # node "mcr778" "ice-r35-2" "1" node "mcr779" "ice-r35-2" "2" node "mcr780" "ice-r35-2" "3" node "mcr781" "ice-r35-2" "4" node "mcr782" "ice-r35-2" "5" node "mcr783" "ice-r35-2" "6" node "mcr784" "ice-r35-2" "7" node "mcr785" "ice-r35-2" "8" node "mcr786" "ice-r35-2" "9" node "mcr787" "ice-r35-2" "10" # node "mcr788" "ice-r35-3" "1" node "mcr789" "ice-r35-3" "2" node "mcr790" "ice-r35-3" "3" node "mcr791" "ice-r35-3" "4" node "mcr792" "ice-r35-3" "5" node "mcr793" "ice-r35-3" "6" node "mcr794" "ice-r35-3" "7" node "mcr795" "ice-r35-3" "8" node "mcr796" "ice-r35-3" "9" node "mcr797" "ice-r35-3" "10" # node "mcr798" "ice-r35-4" "1" node "mcr799" "ice-r35-4" "2" node "mcr800" "ice-r35-4" "3" node "mcr801" "ice-r35-4" "4" node "mcr802" "ice-r35-4" "5" node "mcr803" "ice-r35-4" "6" node "mcr804" "ice-r35-4" "7" node "mcr805" "ice-r35-4" "8" node "mcr806" "ice-r35-4" "9" node "mcr807" "ice-r35-4" "10" # node "mcr808" "ice-r36-1" "1" node "mcr809" "ice-r36-1" "2" node "mcr810" "ice-r36-1" "3" node "mcr811" "ice-r36-1" "4" node "mcr812" "ice-r36-1" "5" node "mcr813" "ice-r36-1" "6" # node "mcr814" "ice-r36-2" "1" node "mcr815" "ice-r36-2" "2" node "mcr816" "ice-r36-2" "3" node "mcr817" "ice-r36-2" "4" node "mcr818" "ice-r36-2" "5" node "mcr819" "ice-r36-2" "6" node "mcr820" "ice-r36-2" "7" node "mcr821" "ice-r36-2" "8" node "mcr822" "ice-r36-2" "9" node "mcr823" "ice-r36-2" "10" # node "mcr824" "ice-r37-1" "1" node "mcr825" "ice-r37-1" "2" node "mcr826" "ice-r37-1" "3" node "mcr827" "ice-r37-1" "4" node "mcr828" "ice-r37-1" "5" node "mcr829" "ice-r37-1" "6" node "mcr830" "ice-r37-1" "7" node "mcr831" "ice-r37-1" "8" node "mcr832" "ice-r37-1" "9" node "mcr833" "ice-r37-1" "10" # node "mcr834" "ice-r37-2" "1" node "mcr835" "ice-r37-2" "2" node "mcr836" "ice-r37-2" "3" node "mcr837" "ice-r37-2" "4" node "mcr838" "ice-r37-2" "5" node "mcr839" "ice-r37-2" "6" node "mcr840" "ice-r37-2" "7" node "mcr841" "ice-r37-2" "8" node "mcr842" "ice-r37-2" "9" node "mcr843" "ice-r37-2" "10" # node "mcr844" "ice-r37-3" "1" node "mcr845" "ice-r37-3" "2" node "mcr846" "ice-r37-3" "3" node "mcr847" "ice-r37-3" "4" node "mcr848" "ice-r37-3" "5" node "mcr849" "ice-r37-3" "6" node "mcr850" "ice-r37-3" "7" node "mcr851" "ice-r37-3" "8" node "mcr852" "ice-r37-3" "9" node "mcr853" "ice-r37-3" "10" # node "mcr854" "ice-r37-4" "1" node "mcr855" "ice-r37-4" "2" node "mcr856" "ice-r37-4" "3" node "mcr857" "ice-r37-4" "4" node "mcr858" "ice-r37-4" "5" node "mcr859" "ice-r37-4" "6" node "mcr860" "ice-r37-4" "7" node "mcr861" "ice-r37-4" "8" node "mcr862" "ice-r37-4" "9" node "mcr863" "ice-r37-4" "10" # # CNSU8 # node "mcr864" "ice-r38-1" "1" node "mcr865" "ice-r38-1" "2" node "mcr866" "ice-r38-1" "3" node "mcr867" "ice-r38-1" "4" node "mcr868" "ice-r38-1" "5" node "mcr869" "ice-r38-1" "6" node "mcr870" "ice-r38-1" "7" node "mcr871" "ice-r38-1" "8" node "mcr872" "ice-r38-1" "9" node "mcr873" "ice-r38-1" "10" # node "mcr874" "ice-r38-2" "1" node "mcr875" "ice-r38-2" "2" node "mcr876" "ice-r38-2" "3" node "mcr877" "ice-r38-2" "4" node "mcr878" "ice-r38-2" "5" node "mcr879" "ice-r38-2" "6" node "mcr880" "ice-r38-2" "7" node "mcr881" "ice-r38-2" "8" node "mcr882" "ice-r38-2" "9" node "mcr883" "ice-r38-2" "10" # node "mcr884" "ice-r38-3" "1" node "mcr885" "ice-r38-3" "2" node "mcr886" "ice-r38-3" "3" node "mcr887" "ice-r38-3" "4" node "mcr888" "ice-r38-3" "5" node "mcr889" "ice-r38-3" "6" node "mcr890" "ice-r38-3" "7" node "mcr891" "ice-r38-3" "8" node "mcr892" "ice-r38-3" "9" node "mcr893" "ice-r38-3" "10" # node "mcr894" "ice-r38-4" "1" node "mcr895" "ice-r38-4" "2" node "mcr896" "ice-r38-4" "3" node "mcr897" "ice-r38-4" "4" node "mcr898" "ice-r38-4" "5" node "mcr899" "ice-r38-4" "6" node "mcr900" "ice-r38-4" "7" node "mcr901" "ice-r38-4" "8" node "mcr902" "ice-r38-4" "9" node "mcr903" "ice-r38-4" "10" # node "mcr904" "ice-r39-1" "1" node "mcr905" "ice-r39-1" "2" node "mcr906" "ice-r39-1" "3" node "mcr907" "ice-r39-1" "4" node "mcr908" "ice-r39-1" "5" node "mcr909" "ice-r39-1" "6" # node "mcr910" "ice-r39-2" "1" node "mcr911" "ice-r39-2" "2" node "mcr912" "ice-r39-2" "3" node "mcr913" "ice-r39-2" "4" node "mcr914" "ice-r39-2" "5" node "mcr915" "ice-r39-2" "6" node "mcr916" "ice-r39-2" "7" node "mcr917" "ice-r39-2" "8" node "mcr918" "ice-r39-2" "9" node "mcr919" "ice-r39-2" "10" # node "mcr920" "ice-r40-1" "1" node "mcr921" "ice-r40-1" "2" node "mcr922" "ice-r40-1" "3" node "mcr923" "ice-r40-1" "4" node "mcr924" "ice-r40-1" "5" node "mcr925" "ice-r40-1" "6" node "mcr926" "ice-r40-1" "7" node "mcr927" "ice-r40-1" "8" node "mcr928" "ice-r40-1" "9" node "mcr929" "ice-r40-1" "10" # node "mcr930" "ice-r40-2" "1" node "mcr931" "ice-r40-2" "2" node "mcr932" "ice-r40-2" "3" node "mcr933" "ice-r40-2" "4" node "mcr934" "ice-r40-2" "5" node "mcr935" "ice-r40-2" "6" node "mcr936" "ice-r40-2" "7" node "mcr937" "ice-r40-2" "8" node "mcr938" "ice-r40-2" "9" node "mcr939" "ice-r40-2" "10" # node "mcr940" "ice-r40-3" "1" node "mcr941" "ice-r40-3" "2" node "mcr942" "ice-r40-3" "3" node "mcr943" "ice-r40-3" "4" node "mcr944" "ice-r40-3" "5" node "mcr945" "ice-r40-3" "6" node "mcr946" "ice-r40-3" "7" node "mcr947" "ice-r40-3" "8" node "mcr948" "ice-r40-3" "9" node "mcr949" "ice-r40-3" "10" # node "mcr950" "ice-r40-4" "1" node "mcr951" "ice-r40-4" "2" node "mcr952" "ice-r40-4" "3" node "mcr953" "ice-r40-4" "4" node "mcr954" "ice-r40-4" "5" node "mcr955" "ice-r40-4" "6" node "mcr956" "ice-r40-4" "7" node "mcr957" "ice-r40-4" "8" node "mcr958" "ice-r40-4" "9" node "mcr959" "ice-r40-4" "10" # # CNSU9 # node "mcr960" "ice-r41-1" "1" node "mcr961" "ice-r41-1" "2" node "mcr962" "ice-r41-1" "3" node "mcr963" "ice-r41-1" "4" node "mcr964" "ice-r41-1" "5" node "mcr965" "ice-r41-1" "6" node "mcr966" "ice-r41-1" "7" node "mcr967" "ice-r41-1" "8" node "mcr968" "ice-r41-1" "9" node "mcr969" "ice-r41-1" "10" # node "mcr970" "ice-r41-2" "1" node "mcr971" "ice-r41-2" "2" node "mcr972" "ice-r41-2" "3" node "mcr973" "ice-r41-2" "4" node "mcr974" "ice-r41-2" "5" node "mcr975" "ice-r41-2" "6" node "mcr976" "ice-r41-2" "7" node "mcr977" "ice-r41-2" "8" node "mcr978" "ice-r41-2" "9" node "mcr979" "ice-r41-2" "10" # node "mcr980" "ice-r41-3" "1" node "mcr981" "ice-r41-3" "2" node "mcr982" "ice-r41-3" "3" node "mcr983" "ice-r41-3" "4" node "mcr984" "ice-r41-3" "5" node "mcr985" "ice-r41-3" "6" node "mcr986" "ice-r41-3" "7" node "mcr987" "ice-r41-3" "8" node "mcr988" "ice-r41-3" "9" node "mcr989" "ice-r41-3" "10" # node "mcr990" "ice-r41-4" "1" node "mcr991" "ice-r41-4" "2" node "mcr992" "ice-r41-4" "3" node "mcr993" "ice-r41-4" "4" node "mcr994" "ice-r41-4" "5" node "mcr995" "ice-r41-4" "6" node "mcr996" "ice-r41-4" "7" node "mcr997" "ice-r41-4" "8" node "mcr998" "ice-r41-4" "9" node "mcr999" "ice-r41-4" "10" # node "mcr1000" "ice-r42-1" "1" node "mcr1001" "ice-r42-1" "2" node "mcr1002" "ice-r42-1" "3" node "mcr1003" "ice-r42-1" "4" node "mcr1004" "ice-r42-1" "5" node "mcr1005" "ice-r42-1" "6" # node "mcr1006" "ice-r42-2" "1" node "mcr1007" "ice-r42-2" "2" node "mcr1008" "ice-r42-2" "3" node "mcr1009" "ice-r42-2" "4" node "mcr1010" "ice-r42-2" "5" node "mcr1011" "ice-r42-2" "6" node "mcr1012" "ice-r42-2" "7" node "mcr1013" "ice-r42-2" "8" node "mcr1014" "ice-r42-2" "9" node "mcr1015" "ice-r42-2" "10" # node "mcr1016" "ice-r43-1" "1" node "mcr1017" "ice-r43-1" "2" node "mcr1018" "ice-r43-1" "3" node "mcr1019" "ice-r43-1" "4" node "mcr1020" "ice-r43-1" "5" node "mcr1021" "ice-r43-1" "6" node "mcr1022" "ice-r43-1" "7" node "mcr1023" "ice-r43-1" "8" node "mcr1024" "ice-r43-1" "9" node "mcr1025" "ice-r43-1" "10" # node "mcr1026" "ice-r43-2" "1" node "mcr1027" "ice-r43-2" "2" node "mcr1028" "ice-r43-2" "3" node "mcr1029" "ice-r43-2" "4" node "mcr1030" "ice-r43-2" "5" node "mcr1031" "ice-r43-2" "6" node "mcr1032" "ice-r43-2" "7" node "mcr1033" "ice-r43-2" "8" node "mcr1034" "ice-r43-2" "9" node "mcr1035" "ice-r43-2" "10" # node "mcr1036" "ice-r43-3" "1" node "mcr1037" "ice-r43-3" "2" node "mcr1038" "ice-r43-3" "3" node "mcr1039" "ice-r43-3" "4" node "mcr1040" "ice-r43-3" "5" node "mcr1041" "ice-r43-3" "6" node "mcr1042" "ice-r43-3" "7" node "mcr1043" "ice-r43-3" "8" node "mcr1044" "ice-r43-3" "9" node "mcr1045" "ice-r43-3" "10" # node "mcr1046" "ice-r43-4" "1" node "mcr1047" "ice-r43-4" "2" node "mcr1048" "ice-r43-4" "3" node "mcr1049" "ice-r43-4" "4" node "mcr1050" "ice-r43-4" "5" node "mcr1051" "ice-r43-4" "6" node "mcr1052" "ice-r43-4" "7" node "mcr1053" "ice-r43-4" "8" node "mcr1054" "ice-r43-4" "9" node "mcr1055" "ice-r43-4" "10" # # CNSU10 # node "mcr1056" "ice-r12-1" "1" node "mcr1057" "ice-r12-1" "2" node "mcr1058" "ice-r12-1" "3" node "mcr1059" "ice-r12-1" "4" node "mcr1060" "ice-r12-1" "5" node "mcr1061" "ice-r12-1" "6" node "mcr1062" "ice-r12-1" "7" node "mcr1063" "ice-r12-1" "8" node "mcr1064" "ice-r12-1" "9" node "mcr1065" "ice-r12-1" "10" # node "mcr1066" "ice-r12-2" "1" node "mcr1067" "ice-r12-2" "2" node "mcr1068" "ice-r12-2" "3" node "mcr1069" "ice-r12-2" "4" node "mcr1070" "ice-r12-2" "5" node "mcr1071" "ice-r12-2" "6" node "mcr1072" "ice-r12-2" "7" node "mcr1073" "ice-r12-2" "8" node "mcr1074" "ice-r12-2" "9" node "mcr1075" "ice-r12-2" "10" # node "mcr1076" "ice-r12-3" "1" node "mcr1077" "ice-r12-3" "2" node "mcr1078" "ice-r12-3" "3" node "mcr1079" "ice-r12-3" "4" node "mcr1080" "ice-r12-3" "5" node "mcr1081" "ice-r12-3" "6" node "mcr1082" "ice-r12-3" "7" node "mcr1083" "ice-r12-3" "8" node "mcr1084" "ice-r12-3" "9" node "mcr1085" "ice-r12-3" "10" # node "mcr1086" "ice-r12-4" "1" node "mcr1087" "ice-r12-4" "2" node "mcr1088" "ice-r12-4" "3" node "mcr1089" "ice-r12-4" "4" node "mcr1090" "ice-r12-4" "5" node "mcr1091" "ice-r12-4" "6" node "mcr1092" "ice-r12-4" "7" node "mcr1093" "ice-r12-4" "8" node "mcr1094" "ice-r12-4" "9" node "mcr1095" "ice-r12-4" "10" # node "mcr1096" "ice-r13-1" "1" node "mcr1097" "ice-r13-1" "2" node "mcr1098" "ice-r13-1" "3" node "mcr1099" "ice-r13-1" "4" node "mcr1100" "ice-r13-1" "5" node "mcr1101" "ice-r13-1" "6" # node "mcr1102" "ice-r13-2" "1" node "mcr1103" "ice-r13-2" "2" node "mcr1104" "ice-r13-2" "3" node "mcr1105" "ice-r13-2" "4" node "mcr1106" "ice-r13-2" "5" node "mcr1107" "ice-r13-2" "6" node "mcr1108" "ice-r13-2" "7" node "mcr1109" "ice-r13-2" "8" node "mcr1110" "ice-r13-2" "9" node "mcr1111" "ice-r13-2" "10" # node "mcr1112" "ice-r14-1" "1" node "mcr1113" "ice-r14-1" "2" node "mcr1114" "ice-r14-1" "3" node "mcr1115" "ice-r14-1" "4" node "mcr1116" "ice-r14-1" "5" node "mcr1117" "ice-r14-1" "6" node "mcr1118" "ice-r14-1" "7" node "mcr1119" "ice-r14-1" "8" node "mcr1120" "ice-r14-1" "9" node "mcr1121" "ice-r14-1" "10" # node "mcr1122" "ice-r14-2" "1" node "mcr1123" "ice-r14-2" "2" node "mcr1124" "ice-r14-2" "3" node "mcr1125" "ice-r14-2" "4" node "mcr1126" "ice-r14-2" "5" node "mcr1127" "ice-r14-2" "6" node "mcr1128" "ice-r14-2" "7" node "mcr1129" "ice-r14-2" "8" node "mcr1130" "ice-r14-2" "9" node "mcr1131" "ice-r14-2" "10" # node "mcr1132" "ice-r14-3" "1" node "mcr1133" "ice-r14-3" "2" node "mcr1134" "ice-r14-3" "3" node "mcr1135" "ice-r14-3" "4" node "mcr1136" "ice-r14-3" "5" node "mcr1137" "ice-r14-3" "6" node "mcr1138" "ice-r14-3" "7" node "mcr1139" "ice-r14-3" "8" node "mcr1140" "ice-r14-3" "9" node "mcr1141" "ice-r14-3" "10" # node "mcr1142" "ice-r14-4" "1" node "mcr1143" "ice-r14-4" "2" node "mcr1144" "ice-r14-4" "3" node "mcr1145" "ice-r14-4" "4" node "mcr1146" "ice-r14-4" "5" node "mcr1147" "ice-r14-4" "6" node "mcr1148" "ice-r14-4" "7" node "mcr1149" "ice-r14-4" "8" node "mcr1150" "ice-r14-4" "9" node "mcr1151" "ice-r14-4" "10" powerman-2.3.27/test/mkconf.pl000077500000000000000000000006411415616035500162400ustar00rootroot00000000000000#!/usr/bin/perl # # Usage: mkconf.pl plugcount # # Builds a powerman.conf file for a vpc config for plugcount plugs. $maxnodes = $ARGV[0]; $nodespervpc = 16; $devs = $maxnodes / $nodespervpc; print "include \"vpc.dev\"\n"; for ($i = 0; $i < $devs; $i++) { $m = $i * $nodespervpc; $n = $m + $nodespervpc - 1; print "device \"test$i\" \"vpc\" \"./vpcd |&\"\n"; print "node \"t[$m-$n]\" \"test$i\"\n"; } exit 0; powerman-2.3.27/test/openbmc-httppower.c000066400000000000000000000110451415616035500202440ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* openbmc-httppower.c - mimic httppower talking to a openbmc server */ #include #include #include #include #include "xread.h" static void print_unauthenticated (void) { printf("{\n" "\"data\": {\n" "\"description\": \"Login required\"\n" "},\n" "\"message\": \"401 Unauthorized\",\n" "\"status\": \"error\"\n" "}\n"); } static void prompt_loop(void) { char buf[1024], urltmp[1024], datatmp[1024]; int hoststatus = 0; /* 0 = off, 1 = on */ int authenticated = 0; for (;;) { if (xreadline("httppower> ", buf, sizeof(buf)) == NULL) break; if (!strcmp(buf, "help")) { printf("Commands are:\n"); printf(" get url data\n"); printf(" post url data\n"); printf(" put url data\n"); } else if (sscanf(buf, "post login %s", datatmp) == 1) { if (!authenticated) authenticated = 1; printf("{\n" "\"data\": \"User 'root' logged in\",\n" "\"message\": \"200 OK\",\n" "\"status\": \"ok\"\n" "}\n"); } else if (sscanf(buf, "post logout %s", datatmp) == 1) { if (authenticated) { authenticated = 0; printf("{\n" "\"data\": \"User 'root' logged in\",\n" "\"message\": \"200 OK\",\n" "\"status\": \"ok\"\n" "}\n"); } else printf("{\n" "\"data\": \"No user logged in\",\n" "\"message\": \"200 OK\",\n" "\"status\": \"ok\"\n" "}\n"); } else if (sscanf(buf, "get %s", urltmp) == 1) { if (!authenticated) { print_unauthenticated (); continue; } if (strstr (urltmp, "CurrentPowerState") == NULL) goto err; printf("{\n" "\"data\": \"xyz.openbmc_project.State.Chassis.PowerState.%s\",\n" "\"message\": \"200 OK\",\n" "\"status\": \"ok\"\n" "}\n", hoststatus ? "On" : "Off"); } else if (sscanf(buf, "put xyz/openbmc_project/state/host0/attr/RequestedHostTransition %s", datatmp) == 1) { if (!authenticated) { print_unauthenticated (); continue; } if (strstr (datatmp, "On")) { hoststatus = 1; } else if (strstr (datatmp, "Off")) { hoststatus = 0; } else if (strstr (datatmp, "Reboot")) { if (!hoststatus) hoststatus = 1; } else goto err; /* Doesn't matter what operation, output success */ printf("{\n" "\"data\": null,\n" "\"message\": \"200 OK\",\n" "\"status\": \"ok\"\n" "}\n"); } else goto err; continue; err: printf("Error\n"); } } int main(int argc, char *argv[]) { prompt_loop(); exit (0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/pm-sim000077500000000000000000000043171415616035500155570ustar00rootroot00000000000000#!/bin/bash # # pm-sim - simulate just enough powerman to test powerman-stonith script # declare -r prog=pm-sim aopt=0 Aopt=0 onopt=0 offopt=0 queryopt=0 targ="" t1=off t2=off t3=off t=off ropt=0 sopt=0 topt=0 if [ -n "PM_SIMSTATE" ]; then [ -r $PM_SIMSTATE ] && source ${PM_SIMSTATE} fi PATH=/usr/bin:/bin:$PATH die() { echo "${prog}: $1" >&2 exit 1 } usage() { echo "Usage: ${prog} OPTIONS [-x] [-q|-0|-1] target" 2>&1 echo "where OPTIONS are:" 2>&1 echo " -a alias t t[1-2]" 2>&1 echo " -A alias t t[1-3]" 2>&1 echo " -m off|on set t1 initial state" 2>&1 echo " -n off|on set t2 initial state" 2>&1 echo " -o off|on set t3 initial state" 2>&1 echo " -r make t1 stuck" 2>&1 echo " -s make t2 stuck" 2>&1 echo " -t make t3 stuck" 2>&1 exit 1 } [ $# == 0 ] && usage while getopts "1:0:q:aAxm:n:o:rst" opt; do case ${opt} in 1) onopt=1; targ=${OPTARG} ;; 0) offopt=1; targ=${OPTARG} ;; q) queryopt=1; targ=${OPTARG} ;; x) ;; a) aopt=1 ;; A) Aopt=1 ;; m) t1=${OPTARG} ;; n) t2=${OPTARG} ;; o) t3=${OPTARG} ;; r) ropt=1 ;; s) sopt=1 ;; t) topt=1 ;; *) usage ;; esac done shift $((${OPTIND} - 1)) if [ "$onopt" == 1 ]; then [ $ropt == 1 ] || t1=on [ $sopt == 1 ] || t2=on [ $topt == 1 ] || t3=on echo Command completed successfully elif [ "$offopt" == 1 ]; then [ $ropt == 1 ] || t1=off [ $sopt == 1 ] || t2=off [ $topt == 1 ] || t3=off echo Command completed successfully elif [ "$queryopt" == 1 ]; then if [ "$aopt" == 1 ]; then echo "t1: $t1" echo "t2: $t2" elif [ "$Aopt" == 1 ]; then echo "t1: $t1" echo "t2: $t2" echo "t3: $t3" else if [ $t1 == on ] && [ $t2 == on ] && [ $t3 == on ]; then echo "t: on" elif [ $t1 == off ] && [ $t2 == off ] && [ $t3 == off ]; then echo "t: off" else echo "t: unknown" fi fi fi if [ -n "$PM_SIMSTATE" ]; then (echo t1=$t1; echo t2=$t2; echo t3=$t3) >$PM_SIMSTATE fi exit 0 powerman-2.3.27/test/redfish-httppower.c000066400000000000000000000061101415616035500202420ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2021 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Albert Chu * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* redfish-httppower.c - mimic httppower talking to a redfish server */ #include #include #include #include #include "xread.h" static void prompt_loop(void) { char buf[1024], urltmp[1024], datatmp[1024]; int hoststatus = 0; /* 0 = off, 1 = on */ for (;;) { if (xreadline("httppower> ", buf, sizeof(buf)) == NULL) break; if (!strcmp(buf, "help")) { printf("Commands are:\n"); printf(" auth user:pass\n"); printf(" get url data\n"); printf(" post url data\n"); } else if (sscanf(buf, "auth %s", datatmp) == 1) { /* we're not authenticating for real, so do nothing */ } else if (sscanf(buf, "get %s", urltmp) == 1) { if (strstr (urltmp, "redfish") == NULL) goto err; printf("{\n" "\"PowerState\":\"%s\",\n" "}\n", hoststatus ? "On" : "Off"); } else if (sscanf(buf, "put redfish/v1/Systems/1/Actions/ComputerSystem.Reset %s", datatmp) == 1) { if (strstr (datatmp, "On")) { hoststatus = 1; } else if (strstr (datatmp, "ForceOff")) { hoststatus = 0; } else if (strstr (datatmp, "ForceRestart")) { if (!hoststatus) hoststatus = 1; } else goto err; /* Doesn't matter what operation, output success */ printf("{\n" "\"PowerState\":\"%s\",\n" "}\n", hoststatus ? "On" : "Off"); } else goto err; continue; err: printf("Error\n"); } } int main(int argc, char *argv[]) { prompt_loop(); exit (0); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/redfishpower.c000066400000000000000000000163401415616035500172730ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2021 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Albert Chu * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://code.google.com/p/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* redfishpower.c - simulate redfishpower */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "hash.h" #include "hostlist.h" #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); static char *prog; static char *hostname = NULL; /* we only support -h here, assuming user will configure all * paths/postdata via prompt */ #define OPTIONS "h:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { { "hostname", required_argument, 0, 'h' }, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'h': hostname = optarg; break; default: usage(); } } if (optind < argc) usage(); if (hostname == NULL) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -h hostlist\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } #define CMD_PROMPT "redfishpower> " #define OFF_STATUS "off" #define ON_STATUS "on" #define OK_STATUS "ok" #define HASH_SIZE 1024 static void _stat(hash_t hstatus, const char *nodes) { hostlist_iterator_t hlitr; hostlist_t hlnodes; char *node; char *str; assert(hstatus); if (!(hlnodes = hostlist_create(nodes))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hlnodes))) { perror("hostlist_iterator_create"); exit(1); } while ((node = hostlist_next(hlitr))) { if ((str = hash_find(hstatus, node))) printf("%s: %s\n", node, str); else printf("%s: %s\n", node, "invalid hostname"); free(node); } hostlist_iterator_destroy(hlitr); hostlist_destroy(hlnodes); } static void _powercmd(hash_t hstatus, const char *nodes, const char *state) { hostlist_iterator_t hlitr; hostlist_t hlnodes; char *node; char *str; assert(hstatus); if (!(hlnodes = hostlist_create(nodes))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hlnodes))) { perror("hostlist_iterator_create"); exit(1); } while ((node = hostlist_next(hlitr))) { if ((str = hash_find(hstatus, node))) { printf("%s: %s\n", node, OK_STATUS); hash_remove(hstatus, node); if (!hash_insert(hstatus, (void *)node, (void *)state)) { perror("hash_insert"); exit(1); } /* XXX: Don't free 'node' here, it needs to be alloc'd for * the hash key. It's a mem-leak. Fix later. */ } else { printf("%s: %s\n", node, "invalid hostname"); free(node); } } hostlist_iterator_destroy(hlitr); hostlist_destroy(hlnodes); } static void _prompt_loop(void) { char buf[128]; char bufnode[128]; hash_t hstatus = NULL; hostlist_t hl = NULL; hostlist_iterator_t hlitr = NULL; char *node; assert(hostname); if (!(hstatus = hash_create(HASH_SIZE, (hash_key_f)hash_key_string, (hash_cmp_f)strcmp, (hash_del_f)NULL))) { perror("hash_create"); exit(1); } if (!(hl = hostlist_create(hostname))) { perror("hostlist_create"); exit(1); } if (!(hlitr = hostlist_iterator_create(hl))) { perror("hostlist_iterator"); exit(1); } /* all nodes begin as off */ while ((node = hostlist_next(hlitr))) { if (!hash_insert(hstatus, (void *)node, OFF_STATUS)) { perror("hash_insert"); exit(1); } /* XXX: Don't free 'node' here, it needs to be alloc'd for * the hash key. It's a mem-leak. Fix later. */ } hostlist_iterator_destroy(hlitr); hostlist_destroy(hl); while (1) { if (xreadline(CMD_PROMPT, buf, sizeof(buf)) == NULL) { break; } else if (strlen(buf) == 0) { continue; } else if (!strcmp(buf, "quit")) { break; } else if (!strcmp(buf, "auth") || !strcmp(buf, "setheader") || !strcmp(buf, "setstatpath") || !strcmp(buf, "setonpath") || !strcmp(buf, "setoffpath") || !strcmp(buf, "setcyclepath")) { /* do nothing with config, just accept */ ; } else if (!strcmp(buf, "stat")) { _stat(hstatus, hostname); } else if (sscanf(buf, "stat %s", bufnode) == 1) { _stat(hstatus, bufnode); } else if (!strcmp(buf, "on")) { _powercmd(hstatus, hostname, ON_STATUS); } else if (sscanf(buf, "on %s", bufnode) == 1) { _powercmd(hstatus, bufnode, ON_STATUS); } else if (!strcmp(buf, "off")) { _powercmd(hstatus, hostname, OFF_STATUS); } else if (sscanf(buf, "off %s", bufnode) == 1) { _powercmd(hstatus, bufnode, OFF_STATUS); } else if (!strcmp(buf, "cycle")) { _powercmd(hstatus, hostname, ON_STATUS); } else if (sscanf(buf, "cycle %s", bufnode) == 1) { _powercmd(hstatus, bufnode, ON_STATUS); } else printf("unknown command - type \"help\"\n"); } hash_destroy(hstatus); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/sierra.conf.in000066400000000000000000002077061415616035500171770ustar00rootroot00000000000000# sierra powerman.conf, modified to work in test harness include "@top_srcdir@/etc/swpdu.dev" include "@top_srcdir@/etc/ipmipower.dev" #tcpwrappers yes # IPMI Control device "ipmi0" "ipmipower" "ipmipower -h psierra[0,2-143] |&" device "ipmi1" "ipmipower" "ipmipower -h psierra[144-287] |&" device "ipmi2" "ipmipower" "ipmipower -h psierra[288-431] |&" device "ipmi3" "ipmipower" "ipmipower -h psierra[432-575] |&" device "ipmi4" "ipmipower" "ipmipower -h psierra[576-719] |&" device "ipmi5" "ipmipower" "ipmipower -h psierra[720-863] |&" device "ipmi6" "ipmipower" "ipmipower -h psierra[864-1007] |&" device "ipmi7" "ipmipower" "ipmipower -h psierra[1008-1151] |&" device "ipmi8" "ipmipower" "ipmipower -h psierra[1152-1295] |&" device "ipmi9" "ipmipower" "ipmipower -h psierra[1296-1439] |&" device "ipmi10" "ipmipower" "ipmipower -h psierra[1440-1583] |&" device "ipmi11" "ipmipower" "ipmipower -h psierra[1584-1727] |&" device "ipmi12" "ipmipower" "ipmipower -h psierra[1728-1871] |&" device "ipmi13" "ipmipower" "ipmipower -h psierra[1872-1943] |&" node "sierra[0,2-143]" "ipmi0" "psierra[0,2-143]" node "sierra[144-287]" "ipmi1" "psierra[144-287]" node "sierra[288-431]" "ipmi2" "psierra[288-431]" node "sierra[432-575]" "ipmi3" "psierra[432-575]" node "sierra[576-719]" "ipmi4" "psierra[576-719]" node "sierra[720-863]" "ipmi5" "psierra[720-863]" node "sierra[864-1007]" "ipmi6" "psierra[864-1007]" node "sierra[1008-1151]" "ipmi7" "psierra[1008-1151]" node "sierra[1152-1295]" "ipmi8" "psierra[1152-1295]" node "sierra[1296-1439]" "ipmi9" "psierra[1296-1439]" node "sierra[1440-1583]" "ipmi10" "psierra[1440-1583]" node "sierra[1584-1727]" "ipmi11" "psierra[1584-1727]" node "sierra[1728-1871]" "ipmi12" "psierra[1728-1871]" node "sierra[1872-1943]" "ipmi13" "psierra[1872-1943]" # PDU Control # PDU Switches device "pdu1" "swpdu" "swpdu |&" device "pdu2" "swpdu" "swpdu |&" device "pdu3" "swpdu" "swpdu |&" device "pdu4" "swpdu" "swpdu |&" device "pdu5" "swpdu" "swpdu |&" device "pdu6" "swpdu" "swpdu |&" device "pdu7" "swpdu" "swpdu |&" device "pdu8" "swpdu" "swpdu |&" device "pdu9" "swpdu" "swpdu |&" device "pdu10" "swpdu" "swpdu |&" device "pdu11" "swpdu" "swpdu |&" device "pdu12" "swpdu" "swpdu |&" device "pdu13" "swpdu" "swpdu |&" device "pdu14" "swpdu" "swpdu |&" device "pdu15" "swpdu" "swpdu |&" ##device "pdu16" "swpdu" "swpdu |&" ##device "pdu17" "swpdu" "swpdu |&" ##device "pdu18" "swpdu" "swpdu |&" device "pdu19" "swpdu" "swpdu |&" device "pdu20" "swpdu" "swpdu |&" device "pdu21" "swpdu" "swpdu |&" device "pdu22" "swpdu" "swpdu |&" device "pdu23" "swpdu" "swpdu |&" device "pdu24" "swpdu" "swpdu |&" device "pdu25" "swpdu" "swpdu |&" device "pdu26" "swpdu" "swpdu |&" device "pdu27" "swpdu" "swpdu |&" device "pdu28" "swpdu" "swpdu |&" device "pdu29" "swpdu" "swpdu |&" device "pdu30" "swpdu" "swpdu |&" device "pdu31" "swpdu" "swpdu |&" device "pdu32" "swpdu" "swpdu |&" device "pdu33" "swpdu" "swpdu |&" # PDU Chassis Control # Rack 1 LSM,RPS,GW nodes node "pdu-sierra1a" "pdu1" "47" #sierra1ps1 node "pdu-sierra0" "pdu1" "46" #sierra0 node "pdu-sierra1b" "pdu1" "44" #sierra1ps2 node "pdu-sierra2" "pdu1" "43" #sierra2 node "pdu-sierra3" "pdu1" "42" #sierra3 node "pdu-sierra4" "pdu1" "41" #sierra4 node "pdu-sierra7a" "pdu1" "40" #sierra7ps1 node "pdu-sierra5" "pdu1" "39" #sierra5 node "pdu-sierra7b" "pdu1" "37" #sierra7ps2 node "pdu-sierra6" "pdu1" "36" #sierra6 node "pdu-sierra8" "pdu1" "34" #sierra8 node "pdu-sierra9" "pdu1" "32" #sierra9 node "pdu-sierra10" "pdu1" "31" #sierra10 node "pdu-sierra11" "pdu1" "29" #sierra11 # Rack 1 Compute nodes node "chassis1a" "pdu1" "23" #sierra[12,14] node "chassis1b" "pdu1" "20" #sierra[13,15] node "chassis2a" "pdu1" "18" #sierra[16,18] node "chassis2b" "pdu1" "15" #sierra[17,19] node "chassis3a" "pdu1" "13" #sierra[20,22] node "chassis3b" "pdu1" "10" #sierra[21,23] node "chassis4a" "pdu1" "12" #sierra[24,26] node "chassis4b" "pdu1" "9" #sierra[25,27] node "chassis5a" "pdu1" "5" #sierra[28,30] node "chassis5b" "pdu1" "2" #sierra[29,31] node "chassis6a" "pdu1" "4" #sierra[32,34] node "chassis6b" "pdu1" "1" #sierra[33,35] # Rack 2 node "chassis7a" "pdu2" "48" #sierra[36,38] node "chassis7b" "pdu2" "45" #sierra[37,39] node "chassis8a" "pdu2" "47" #sierra[40,42] node "chassis8b" "pdu2" "44" #sierra[41,43] node "chassis9a" "pdu2" "43" #sierra[44,46] node "chassis9b" "pdu2" "40" #sierra[45,47] node "chassis10a" "pdu2" "41" #sierra[48,50] node "chassis10b" "pdu2" "38" #sierra[49,51] node "chassis11a" "pdu2" "39" #sierra[52,54] node "chassis11b" "pdu2" "36" #sierra[53,55] node "chassis12a" "pdu2" "37" #sierra[56,58] node "chassis12b" "pdu2" "34" #sierra[57,59] node "chassis13a" "pdu2" "30" #sierra[60,62] node "chassis13b" "pdu2" "27" #sierra[61,63] node "chassis14a" "pdu2" "29" #sierra[64,66] node "chassis14b" "pdu2" "26" #sierra[65,67] node "chassis15a" "pdu2" "28" #sierra[68,70] node "chassis15b" "pdu2" "25" #sierra[69,71] node "chassis16a" "pdu2" "23" #sierra[72,74] node "chassis16b" "pdu2" "20" #sierra[73,75] node "chassis17a" "pdu2" "19" #sierra[76,78] node "chassis17b" "pdu2" "16" #sierra[77,79] node "chassis18a" "pdu2" "18" #sierra[80,82] node "chassis18b" "pdu2" "15" #sierra[81,83] node "chassis19a" "pdu2" "13" #sierra[84,86] node "chassis19b" "pdu2" "10" #sierra[85,87] node "chassis20a" "pdu2" "12" #sierra[88,90] node "chassis20b" "pdu2" "9" #sierra[89,91] node "chassis21a" "pdu2" "11" #sierra[92,94] node "chassis21b" "pdu2" "8" #sierra[93,95] node "chassis22a" "pdu2" "6" #sierra[96,98] node "chassis22b" "pdu2" "3" #sierra[97,99] node "chassis23a" "pdu2" "5" #sierra[100,102] node "chassis23b" "pdu2" "2" #sierra[101,103] node "chassis24a" "pdu2" "4" #sierra[104,106] node "chassis24b" "pdu2" "1" #sierra[105,107] # Rack 3 node "chassis25a" "pdu3" "48" #sierra[108,110] node "chassis25b" "pdu3" "45" #sierra[109,111] node "chassis26a" "pdu3" "47" node "chassis26b" "pdu3" "44" node "chassis27a" "pdu3" "43" node "chassis27b" "pdu3" "40" node "chassis28a" "pdu3" "41" node "chassis28b" "pdu3" "38" node "chassis29a" "pdu3" "39" node "chassis29b" "pdu3" "36" node "chassis30a" "pdu3" "37" node "chassis30b" "pdu3" "34" node "chassis31a" "pdu3" "30" node "chassis31b" "pdu3" "27" node "chassis32a" "pdu3" "29" node "chassis32b" "pdu3" "26" node "chassis33a" "pdu3" "28" node "chassis33b" "pdu3" "25" node "chassis34a" "pdu3" "23" node "chassis34b" "pdu3" "20" node "chassis35a" "pdu3" "19" node "chassis35b" "pdu3" "16" node "chassis36a" "pdu3" "18" node "chassis36b" "pdu3" "15" node "chassis37a" "pdu3" "13" node "chassis37b" "pdu3" "10" node "chassis38a" "pdu3" "12" node "chassis38b" "pdu3" "9" node "chassis39a" "pdu3" "11" node "chassis39b" "pdu3" "8" node "chassis40a" "pdu3" "6" node "chassis40b" "pdu3" "3" node "chassis41a" "pdu3" "5" node "chassis41b" "pdu3" "2" node "chassis42a" "pdu3" "4" #sierra[176,178] node "chassis42b" "pdu3" "1" #sierra[177,179] # Rack 4 node "chassis43a" "pdu4" "48" #sierra[180,182] node "chassis43b" "pdu4" "45" #sierra[181,183] node "chassis44a" "pdu4" "47" node "chassis44b" "pdu4" "44" node "chassis45a" "pdu4" "43" node "chassis45b" "pdu4" "40" node "chassis46a" "pdu4" "41" node "chassis46b" "pdu4" "38" node "chassis47a" "pdu4" "39" node "chassis47b" "pdu4" "36" node "chassis48a" "pdu4" "37" node "chassis48b" "pdu4" "34" node "chassis49a" "pdu4" "30" node "chassis49b" "pdu4" "27" node "chassis50a" "pdu4" "29" node "chassis50b" "pdu4" "26" node "chassis51a" "pdu4" "28" node "chassis51b" "pdu4" "25" node "chassis52a" "pdu4" "23" node "chassis52b" "pdu4" "20" node "chassis53a" "pdu4" "19" node "chassis53b" "pdu4" "16" node "chassis54a" "pdu4" "18" node "chassis54b" "pdu4" "15" node "chassis55a" "pdu4" "13" node "chassis55b" "pdu4" "10" node "chassis56a" "pdu4" "12" node "chassis56b" "pdu4" "9" node "chassis57a" "pdu4" "11" node "chassis57b" "pdu4" "8" node "chassis58a" "pdu4" "6" node "chassis58b" "pdu4" "3" node "chassis59a" "pdu4" "5" node "chassis59b" "pdu4" "2" node "chassis60a" "pdu4" "4" #sierra[248,250] node "chassis60b" "pdu4" "1" #sierra[249,251] # Rack 5 node "chassis61a" "pdu5" "48" #sierra[252,254] node "chassis61b" "pdu5" "45" #sierra[253,255] node "chassis62a" "pdu5" "47" node "chassis62b" "pdu5" "44" node "chassis63a" "pdu5" "43" node "chassis63b" "pdu5" "40" node "chassis64a" "pdu5" "41" node "chassis64b" "pdu5" "38" node "chassis65a" "pdu5" "39" node "chassis65b" "pdu5" "36" node "chassis66a" "pdu5" "37" node "chassis66b" "pdu5" "34" node "chassis67a" "pdu5" "30" node "chassis67b" "pdu5" "27" node "chassis68a" "pdu5" "29" node "chassis68b" "pdu5" "26" node "chassis69a" "pdu5" "28" node "chassis69b" "pdu5" "25" node "chassis70a" "pdu5" "23" node "chassis70b" "pdu5" "20" node "chassis71a" "pdu5" "19" node "chassis71b" "pdu5" "16" node "chassis72a" "pdu5" "18" node "chassis72b" "pdu5" "15" node "chassis73a" "pdu5" "13" node "chassis73b" "pdu5" "10" node "chassis74a" "pdu5" "12" node "chassis74b" "pdu5" "9" node "chassis75a" "pdu5" "11" node "chassis75b" "pdu5" "8" node "chassis76a" "pdu5" "6" node "chassis76b" "pdu5" "3" node "chassis77a" "pdu5" "5" node "chassis77b" "pdu5" "2" node "chassis78a" "pdu5" "4" #sierra[320,322] node "chassis78b" "pdu5" "1" #sierra[321,323] # Rack 6 LSM,RPS,GW nodes node "pdu-sierra325a" "pdu6" "47" #sierra325ps1 node "pdu-sierra324" "pdu6" "46" #sierra324 node "pdu-sierra325b" "pdu6" "44" #sierra325ps2 node "pdu-sierra326" "pdu6" "43" #sierra326 node "pdu-sierra327" "pdu6" "42" #sierra327 node "pdu-sierra328" "pdu6" "41" #sierra328 node "pdu-sierra331a" "pdu6" "40" #sierra331ps1 node "pdu-sierra329" "pdu6" "39" #sierra329 node "pdu-sierra331b" "pdu6" "37" #sierra331ps2 node "pdu-sierra330" "pdu6" "36" #sierra330 node "pdu-sierra332" "pdu6" "34" #sierra332 node "pdu-sierra333" "pdu6" "32" #sierra333 node "pdu-sierra334" "pdu6" "31" #sierra334 node "pdu-sierra335" "pdu6" "29" #sierra335 # Rack 6 Compute nodes node "chassis79a" "pdu6" "23" #sierra[336,338] node "chassis79b" "pdu6" "20" #sierra[337,339] node "chassis80a" "pdu6" "18" node "chassis80b" "pdu6" "15" node "chassis81a" "pdu6" "13" node "chassis81b" "pdu6" "10" node "chassis82a" "pdu6" "12" node "chassis82b" "pdu6" "9" node "chassis83a" "pdu6" "5" node "chassis83b" "pdu6" "2" node "chassis84a" "pdu6" "4" #sierra[356,358] node "chassis84b" "pdu6" "1" #sierra[357,359] # Rack 7 node "chassis85a" "pdu7" "48" #sierra[360,362] node "chassis85b" "pdu7" "45" #sierra[361,363] node "chassis86a" "pdu7" "47" node "chassis86b" "pdu7" "44" node "chassis87a" "pdu7" "43" node "chassis87b" "pdu7" "40" node "chassis88a" "pdu7" "41" node "chassis88b" "pdu7" "38" node "chassis89a" "pdu7" "39" node "chassis89b" "pdu7" "36" node "chassis90a" "pdu7" "37" node "chassis90b" "pdu7" "34" node "chassis91a" "pdu7" "30" node "chassis91b" "pdu7" "27" node "chassis92a" "pdu7" "29" node "chassis92b" "pdu7" "26" node "chassis93a" "pdu7" "28" node "chassis93b" "pdu7" "25" node "chassis94a" "pdu7" "23" node "chassis94b" "pdu7" "20" node "chassis95a" "pdu7" "19" node "chassis95b" "pdu7" "16" node "chassis96a" "pdu7" "18" node "chassis96b" "pdu7" "15" node "chassis97a" "pdu7" "13" node "chassis97b" "pdu7" "10" node "chassis98a" "pdu7" "12" node "chassis98b" "pdu7" "9" node "chassis99a" "pdu7" "11" node "chassis99b" "pdu7" "8" node "chassis100a" "pdu7" "6" node "chassis100b" "pdu7" "3" node "chassis101a" "pdu7" "5" node "chassis101b" "pdu7" "2" node "chassis102a" "pdu7" "4" #sierra[428,430] node "chassis102b" "pdu7" "1" #sierra[429,431] # Rack 8 node "chassis103a" "pdu8" "48" #sierra[432,434] node "chassis103b" "pdu8" "45" #sierra[433,435] node "chassis104a" "pdu8" "47" node "chassis104b" "pdu8" "44" node "chassis105a" "pdu8" "43" node "chassis105b" "pdu8" "40" node "chassis106a" "pdu8" "41" node "chassis106b" "pdu8" "38" node "chassis107a" "pdu8" "39" node "chassis107b" "pdu8" "36" node "chassis108a" "pdu8" "37" node "chassis108b" "pdu8" "34" node "chassis109a" "pdu8" "30" node "chassis109b" "pdu8" "27" node "chassis110a" "pdu8" "29" node "chassis110b" "pdu8" "26" node "chassis111a" "pdu8" "28" node "chassis111b" "pdu8" "25" node "chassis112a" "pdu8" "23" node "chassis112b" "pdu8" "20" node "chassis113a" "pdu8" "19" node "chassis113b" "pdu8" "16" node "chassis114a" "pdu8" "18" node "chassis114b" "pdu8" "15" node "chassis115a" "pdu8" "13" node "chassis115b" "pdu8" "10" node "chassis116a" "pdu8" "12" node "chassis116b" "pdu8" "9" node "chassis117a" "pdu8" "11" node "chassis117b" "pdu8" "8" node "chassis118a" "pdu8" "6" node "chassis118b" "pdu8" "3" node "chassis119a" "pdu8" "5" node "chassis119b" "pdu8" "2" node "chassis120a" "pdu8" "4" #sierra[500,502] node "chassis120b" "pdu8" "1" #sierra[501,503] # Rack 9 node "chassis121a" "pdu9" "48" #sierra[504,506] node "chassis121b" "pdu9" "45" #sierra[505,507] node "chassis122a" "pdu9" "47" node "chassis122b" "pdu9" "44" node "chassis123a" "pdu9" "43" node "chassis123b" "pdu9" "40" node "chassis124a" "pdu9" "41" node "chassis124b" "pdu9" "38" node "chassis125a" "pdu9" "39" node "chassis125b" "pdu9" "36" node "chassis126a" "pdu9" "37" node "chassis126b" "pdu9" "34" node "chassis127a" "pdu9" "30" node "chassis127b" "pdu9" "27" node "chassis128a" "pdu9" "29" node "chassis128b" "pdu9" "26" node "chassis129a" "pdu9" "28" node "chassis129b" "pdu9" "25" node "chassis130a" "pdu9" "23" node "chassis130b" "pdu9" "20" node "chassis131a" "pdu9" "19" node "chassis131b" "pdu9" "16" node "chassis132a" "pdu9" "18" node "chassis132b" "pdu9" "15" node "chassis133a" "pdu9" "13" node "chassis133b" "pdu9" "10" node "chassis134a" "pdu9" "12" node "chassis134b" "pdu9" "9" node "chassis135a" "pdu9" "11" node "chassis135b" "pdu9" "8" node "chassis136a" "pdu9" "6" node "chassis136b" "pdu9" "3" node "chassis137a" "pdu9" "5" node "chassis137b" "pdu9" "2" node "chassis138a" "pdu9" "4" #sierra[572,574] node "chassis138b" "pdu9" "1" #sierra[573,575] # Rack 10 node "chassis139a" "pdu10" "48" #sierra[576,578] node "chassis139b" "pdu10" "45" #sierra[577,579] node "chassis140a" "pdu10" "47" node "chassis140b" "pdu10" "44" node "chassis141a" "pdu10" "43" node "chassis141b" "pdu10" "40" node "chassis142a" "pdu10" "41" node "chassis142b" "pdu10" "38" node "chassis143a" "pdu10" "39" node "chassis143b" "pdu10" "36" node "chassis144a" "pdu10" "37" node "chassis144b" "pdu10" "34" node "chassis145a" "pdu10" "30" node "chassis145b" "pdu10" "27" node "chassis146a" "pdu10" "29" node "chassis146b" "pdu10" "26" node "chassis147a" "pdu10" "28" node "chassis147b" "pdu10" "25" node "chassis148a" "pdu10" "23" node "chassis148b" "pdu10" "20" node "chassis149a" "pdu10" "19" node "chassis149b" "pdu10" "16" node "chassis150a" "pdu10" "18" node "chassis150b" "pdu10" "15" node "chassis151a" "pdu10" "13" node "chassis151b" "pdu10" "10" node "chassis152a" "pdu10" "12" node "chassis152b" "pdu10" "9" node "chassis153a" "pdu10" "11" node "chassis153b" "pdu10" "8" node "chassis154a" "pdu10" "6" node "chassis154b" "pdu10" "3" node "chassis155a" "pdu10" "5" node "chassis155b" "pdu10" "2" node "chassis156a" "pdu10" "4" #sierra[644,646] node "chassis156b" "pdu10" "1" #sierra[645,647] # Rack 11 LSM,RPS,GW nodes node "pdu-sierra649a" "pdu11" "47" #sierra649ps1 node "pdu-sierra648" "pdu11" "46" #sierra648 node "pdu-sierra649b" "pdu11" "44" #sierra649ps2 node "pdu-sierra650" "pdu11" "43" #sierra650 node "pdu-sierra651" "pdu11" "42" #sierra651 node "pdu-sierra652" "pdu11" "41" #sierra652 node "pdu-sierra655a" "pdu11" "40" #sierra655ps1 node "pdu-sierra653" "pdu11" "39" #sierra653 node "pdu-sierra655b" "pdu11" "37" #sierra655ps2 node "pdu-sierra654" "pdu11" "36" #sierra654 node "pdu-sierra656" "pdu11" "34" #sierra656 node "pdu-sierra657" "pdu11" "32" #sierra657 node "pdu-sierra658" "pdu11" "31" #sierra658 node "pdu-sierra659" "pdu11" "29" #sierra659 # Rack 11 Compute nodes node "chassis157a" "pdu11" "23" #sierra[660,662] node "chassis157b" "pdu11" "20" #sierra[661,663] node "chassis158a" "pdu11" "18" node "chassis158b" "pdu11" "15" node "chassis159a" "pdu11" "13" node "chassis159b" "pdu11" "10" node "chassis160a" "pdu11" "12" node "chassis160b" "pdu11" "9" node "chassis161a" "pdu11" "5" node "chassis161b" "pdu11" "2" node "chassis162a" "pdu11" "4" #sierra[680,682] node "chassis162b" "pdu11" "1" #sierra[681,683] # Rack 12 node "chassis163a" "pdu12" "48" #sierra[684,686] node "chassis163b" "pdu12" "45" #sierra[685,687] node "chassis164a" "pdu12" "47" node "chassis164b" "pdu12" "44" node "chassis165a" "pdu12" "43" node "chassis165b" "pdu12" "40" node "chassis166a" "pdu12" "41" node "chassis166b" "pdu12" "38" node "chassis167a" "pdu12" "39" node "chassis167b" "pdu12" "36" node "chassis168a" "pdu12" "37" node "chassis168b" "pdu12" "34" node "chassis169a" "pdu12" "30" node "chassis169b" "pdu12" "27" node "chassis170a" "pdu12" "29" node "chassis170b" "pdu12" "26" node "chassis171a" "pdu12" "28" node "chassis171b" "pdu12" "25" node "chassis172a" "pdu12" "23" node "chassis172b" "pdu12" "20" node "chassis173a" "pdu12" "19" node "chassis173b" "pdu12" "16" node "chassis174a" "pdu12" "18" node "chassis174b" "pdu12" "15" node "chassis175a" "pdu12" "13" node "chassis175b" "pdu12" "10" node "chassis176a" "pdu12" "12" node "chassis176b" "pdu12" "9" node "chassis177a" "pdu12" "11" node "chassis177b" "pdu12" "8" node "chassis178a" "pdu12" "6" node "chassis178b" "pdu12" "3" node "chassis179a" "pdu12" "5" node "chassis179b" "pdu12" "2" node "chassis180a" "pdu12" "4" #sierra[752,754] node "chassis180b" "pdu12" "1" #sierra[753,755] # Rack 13 node "chassis181a" "pdu13" "48" #sierra[756,758] node "chassis181b" "pdu13" "45" #sierra[757,759] node "chassis182a" "pdu13" "47" node "chassis182b" "pdu13" "44" node "chassis183a" "pdu13" "43" node "chassis183b" "pdu13" "40" node "chassis184a" "pdu13" "41" node "chassis184b" "pdu13" "38" node "chassis185a" "pdu13" "39" node "chassis185b" "pdu13" "36" node "chassis186a" "pdu13" "37" node "chassis186b" "pdu13" "34" node "cyclades22b" "pdu13" "33" node "chassis187a" "pdu13" "30" node "chassis187b" "pdu13" "27" node "chassis188a" "pdu13" "29" node "chassis188b" "pdu13" "26" node "chassis189a" "pdu13" "28" node "chassis189b" "pdu13" "25" node "chassis190a" "pdu13" "23" node "chassis190b" "pdu13" "20" node "chassis191a" "pdu13" "19" node "chassis191b" "pdu13" "16" node "chassis192a" "pdu13" "18" node "chassis192b" "pdu13" "15" node "chassis193a" "pdu13" "13" node "chassis193b" "pdu13" "10" node "chassis194a" "pdu13" "12" node "chassis194b" "pdu13" "9" node "chassis195a" "pdu13" "11" node "chassis195b" "pdu13" "8" node "chassis196a" "pdu13" "6" node "chassis196b" "pdu13" "3" node "chassis197a" "pdu13" "5" node "chassis197b" "pdu13" "2" node "chassis198a" "pdu13" "4" #sierra[824,826] node "chassis198b" "pdu13" "1" #sierra[825,827] # Rack 14 node "chassis199a" "pdu14" "48" #sierra[828,830] node "chassis199b" "pdu14" "45" #sierra[829,831] node "chassis200a" "pdu14" "47" node "chassis200b" "pdu14" "44" node "chassis201a" "pdu14" "43" node "chassis201b" "pdu14" "40" node "chassis202a" "pdu14" "41" node "chassis202b" "pdu14" "38" node "chassis203a" "pdu14" "39" node "chassis203b" "pdu14" "36" node "chassis204a" "pdu14" "37" node "chassis204b" "pdu14" "34" node "chassis205a" "pdu14" "30" node "chassis205b" "pdu14" "27" node "chassis206a" "pdu14" "29" node "chassis206b" "pdu14" "26" node "chassis207a" "pdu14" "28" node "chassis207b" "pdu14" "25" node "chassis208a" "pdu14" "23" node "chassis208b" "pdu14" "20" node "chassis209a" "pdu14" "19" node "chassis209b" "pdu14" "16" node "chassis210a" "pdu14" "18" node "chassis210b" "pdu14" "15" node "chassis211a" "pdu14" "13" node "chassis211b" "pdu14" "10" node "chassis212a" "pdu14" "12" node "chassis212b" "pdu14" "9" node "chassis213a" "pdu14" "11" node "chassis213b" "pdu14" "8" node "chassis214a" "pdu14" "6" node "chassis214b" "pdu14" "3" node "chassis215a" "pdu14" "5" node "chassis215b" "pdu14" "2" node "chassis216a" "pdu14" "4" #sierra[896,898] node "chassis216b" "pdu14" "1" #sierra[897,899] # Rack 15 node "chassis217a" "pdu15" "48" #sierra[900,902] node "chassis217b" "pdu15" "45" #sierra[901,903] node "chassis218a" "pdu15" "47" node "chassis218b" "pdu15" "44" node "chassis219a" "pdu15" "43" node "chassis219b" "pdu15" "40" node "chassis220a" "pdu15" "41" node "chassis220b" "pdu15" "38" node "chassis221a" "pdu15" "39" node "chassis221b" "pdu15" "36" node "chassis222a" "pdu15" "37" node "chassis222b" "pdu15" "34" node "chassis223a" "pdu15" "30" node "chassis223b" "pdu15" "27" node "chassis224a" "pdu15" "29" node "chassis224b" "pdu15" "26" node "chassis225a" "pdu15" "28" node "chassis225b" "pdu15" "25" node "chassis226a" "pdu15" "23" node "chassis226b" "pdu15" "20" node "chassis227a" "pdu15" "19" node "chassis227b" "pdu15" "16" node "chassis228a" "pdu15" "18" node "chassis228b" "pdu15" "15" node "chassis229a" "pdu15" "13" node "chassis229b" "pdu15" "10" node "chassis230a" "pdu15" "12" node "chassis230b" "pdu15" "9" node "chassis231a" "pdu15" "11" node "chassis231b" "pdu15" "8" node "chassis232a" "pdu15" "6" node "chassis232b" "pdu15" "3" node "chassis233a" "pdu15" "5" node "chassis233b" "pdu15" "2" node "chassis234a" "pdu15" "4" #sierra[968,970] node "chassis234b" "pdu15" "1" #sierra[969,971] # Racks 16 - 18 IBCORE switches # Rack 19 LSM,RPS,GW nodes node "pdu-sierra973a" "pdu19" "47" #sierra973ps1 node "pdu-sierra972" "pdu19" "46" #sierra972 node "pdu-sierra973b" "pdu19" "44" #sierra973ps2 node "pdu-sierra974" "pdu19" "43" #sierra974 node "pdu-sierra975" "pdu19" "42" #sierra975 node "pdu-sierra976" "pdu19" "41" #sierra976 node "pdu-sierra979a" "pdu19" "40" #sierra979ps1 node "pdu-sierra977" "pdu19" "39" #sierra977 node "pdu-sierra979b" "pdu19" "37" #sierra979ps2 node "pdu-sierra978" "pdu19" "36" #sierra978 node "pdu-sierra980" "pdu19" "34" #sierra980 node "pdu-sierra981" "pdu19" "32" #sierra981 node "pdu-sierra982" "pdu19" "31" #sierra982 node "pdu-sierra983" "pdu19" "29" #sierra983 # Rack 19 Compute nodes node "chassis235a" "pdu19" "23" #sierra[984,986] node "chassis235b" "pdu19" "20" #sierra[985,987] node "chassis236a" "pdu19" "18" node "chassis236b" "pdu19" "15" node "chassis237a" "pdu19" "13" node "chassis237b" "pdu19" "10" node "chassis238a" "pdu19" "12" node "chassis238b" "pdu19" "9" node "chassis239a" "pdu19" "5" node "chassis239b" "pdu19" "2" node "chassis240a" "pdu19" "4" #sierra[1004,1006] node "chassis240b" "pdu19" "1" #sierra[1005,1007] # Rack 20 node "chassis241a" "pdu20" "48" #sierra[1008,1010] node "chassis241b" "pdu20" "45" #sierra[1009,1011] node "chassis242a" "pdu20" "47" node "chassis242b" "pdu20" "44" node "chassis243a" "pdu20" "43" node "chassis243b" "pdu20" "40" node "chassis244a" "pdu20" "41" node "chassis244b" "pdu20" "38" node "chassis245a" "pdu20" "39" node "chassis245b" "pdu20" "36" node "chassis246a" "pdu20" "37" node "chassis246b" "pdu20" "34" node "chassis247a" "pdu20" "30" node "chassis247b" "pdu20" "27" node "chassis248a" "pdu20" "29" node "chassis248b" "pdu20" "26" node "chassis249a" "pdu20" "28" node "chassis249b" "pdu20" "25" node "chassis250a" "pdu20" "23" node "chassis250b" "pdu20" "20" node "chassis251a" "pdu20" "19" node "chassis251b" "pdu20" "16" node "chassis252a" "pdu20" "18" node "chassis252b" "pdu20" "15" node "chassis253a" "pdu20" "13" node "chassis253b" "pdu20" "10" node "chassis254a" "pdu20" "12" node "chassis254b" "pdu20" "9" node "chassis255a" "pdu20" "11" node "chassis255b" "pdu20" "8" node "chassis256a" "pdu20" "6" node "chassis256b" "pdu20" "3" node "chassis257a" "pdu20" "5" node "chassis257b" "pdu20" "2" node "chassis258a" "pdu20" "4" #sierra[1076,1078] node "chassis258b" "pdu20" "1" #sierra[1077,1079] # Rack 21 node "chassis259a" "pdu21" "48" #sierra[1080,1082] node "chassis259b" "pdu21" "45" #sierra[1081,1083] node "chassis260a" "pdu21" "47" node "chassis260b" "pdu21" "44" node "chassis261a" "pdu21" "43" node "chassis261b" "pdu21" "40" node "chassis262a" "pdu21" "41" node "chassis262b" "pdu21" "38" node "chassis263a" "pdu21" "39" node "chassis263b" "pdu21" "36" node "chassis264a" "pdu21" "37" node "chassis264b" "pdu21" "34" node "chassis265a" "pdu21" "30" node "chassis265b" "pdu21" "27" node "chassis266a" "pdu21" "29" node "chassis266b" "pdu21" "26" node "chassis267a" "pdu21" "28" node "chassis267b" "pdu21" "25" node "chassis268a" "pdu21" "23" node "chassis268b" "pdu21" "20" node "chassis269a" "pdu21" "19" node "chassis269b" "pdu21" "16" node "chassis270a" "pdu21" "18" node "chassis270b" "pdu21" "15" node "chassis271a" "pdu21" "13" node "chassis271b" "pdu21" "10" node "chassis272a" "pdu21" "12" node "chassis272b" "pdu21" "9" node "chassis273a" "pdu21" "11" node "chassis273b" "pdu21" "8" node "chassis274a" "pdu21" "6" node "chassis274b" "pdu21" "3" node "chassis275a" "pdu21" "5" node "chassis275b" "pdu21" "2" node "chassis276a" "pdu21" "4" #sierra[1148,1150] node "chassis276b" "pdu21" "1" #sierra[1149,1151] # Rack 22 node "chassis277a" "pdu22" "48" #sierra[1152,1154] node "chassis277b" "pdu22" "45" #sierra[1153,1155] node "chassis278a" "pdu22" "47" node "chassis278b" "pdu22" "44" node "chassis279a" "pdu22" "43" node "chassis279b" "pdu22" "40" node "chassis280a" "pdu22" "41" node "chassis280b" "pdu22" "38" node "chassis281a" "pdu22" "39" node "chassis281b" "pdu22" "36" node "chassis282a" "pdu22" "37" node "chassis282b" "pdu22" "34" node "chassis283a" "pdu22" "30" node "chassis283b" "pdu22" "27" node "chassis284a" "pdu22" "29" node "chassis284b" "pdu22" "26" node "chassis285a" "pdu22" "28" node "chassis285b" "pdu22" "25" node "chassis286a" "pdu22" "23" node "chassis286b" "pdu22" "20" node "chassis287a" "pdu22" "19" node "chassis287b" "pdu22" "16" node "chassis288a" "pdu22" "18" node "chassis288b" "pdu22" "15" node "chassis289a" "pdu22" "13" node "chassis289b" "pdu22" "10" node "chassis290a" "pdu22" "12" node "chassis290b" "pdu22" "9" node "chassis291a" "pdu22" "11" node "chassis291b" "pdu22" "8" node "chassis292a" "pdu22" "6" node "chassis292b" "pdu22" "3" node "chassis293a" "pdu22" "5" node "chassis293b" "pdu22" "2" node "chassis294a" "pdu22" "4" #sierra[1220,1222] node "chassis294b" "pdu22" "1" #sierra[1221,1223] # Rack 23 node "chassis295a" "pdu23" "48" #sierra[1224,1226] node "chassis295b" "pdu23" "45" #sierra[1225,1227] node "chassis296a" "pdu23" "47" node "chassis296b" "pdu23" "44" node "chassis297a" "pdu23" "43" node "chassis297b" "pdu23" "40" node "chassis298a" "pdu23" "41" node "chassis298b" "pdu23" "38" node "chassis299a" "pdu23" "39" node "chassis299b" "pdu23" "36" node "chassis300a" "pdu23" "37" node "chassis300b" "pdu23" "34" node "chassis301a" "pdu23" "30" node "chassis301b" "pdu23" "27" node "chassis302a" "pdu23" "29" node "chassis302b" "pdu23" "26" node "chassis303a" "pdu23" "28" node "chassis303b" "pdu23" "25" node "chassis304a" "pdu23" "23" node "chassis304b" "pdu23" "20" node "chassis305a" "pdu23" "19" node "chassis305b" "pdu23" "16" node "chassis306a" "pdu23" "18" node "chassis306b" "pdu23" "15" node "chassis307a" "pdu23" "13" node "chassis307b" "pdu23" "10" node "chassis308a" "pdu23" "12" node "chassis308b" "pdu23" "9" node "chassis309a" "pdu23" "11" node "chassis309b" "pdu23" "8" node "chassis310a" "pdu23" "6" node "chassis310b" "pdu23" "3" node "chassis311a" "pdu23" "5" node "chassis311b" "pdu23" "2" node "chassis312a" "pdu23" "4" #sierra[1292,1294] node "chassis312b" "pdu23" "1" #sierra[1293,1295] # Rack 24 LSM,RPS,GW nodes node "pdu-sierra1297a" "pdu24" "47" #sierra1297ps1 node "pdu-sierra1296" "pdu24" "46" #sierra1296 node "pdu-sierra1297b" "pdu24" "44" #sierra1297ps2 node "pdu-sierra1298" "pdu24" "43" #sierra1298 node "pdu-sierra1299" "pdu24" "42" #sierra1299 node "pdu-sierra1300" "pdu24" "41" #sierra1300 node "pdu-sierra1303a" "pdu24" "40" #sierra1303ps1 node "pdu-sierra1301" "pdu24" "39" #sierra1301 node "pdu-sierra1303b" "pdu24" "37" #sierra1303ps2 node "pdu-sierra1302" "pdu24" "36" #sierra1302 node "pdu-sierra1304" "pdu24" "34" #sierra1304 node "pdu-sierra1305" "pdu24" "32" #sierra1305 node "pdu-sierra1306" "pdu24" "31" #sierra1306 node "pdu-sierra1307" "pdu24" "29" #sierra1307 # Rack 24 Compute nodes node "chassis313a" "pdu24" "23" #sierra[1308,1310] node "chassis313b" "pdu24" "20" #sierra[1309,1311] node "chassis314a" "pdu24" "18" node "chassis314b" "pdu24" "15" node "chassis315a" "pdu24" "13" node "chassis315b" "pdu24" "10" node "chassis316a" "pdu24" "12" node "chassis316b" "pdu24" "9" node "chassis317a" "pdu24" "5" node "chassis317b" "pdu24" "2" node "chassis318a" "pdu24" "4" #sierra[1328,1330] node "chassis318b" "pdu24" "1" #sierra[1329,1331] # Rack 25 node "chassis319a" "pdu25" "48" #sierra[1332,1334] node "chassis319b" "pdu25" "45" #sierra[1333,1335] node "chassis320a" "pdu25" "47" node "chassis320b" "pdu25" "44" node "chassis321a" "pdu25" "43" node "chassis321b" "pdu25" "40" node "chassis322a" "pdu25" "41" node "chassis322b" "pdu25" "38" node "chassis323a" "pdu25" "39" node "chassis323b" "pdu25" "36" node "chassis324a" "pdu25" "37" node "chassis324b" "pdu25" "34" node "chassis325a" "pdu25" "30" node "chassis325b" "pdu25" "27" node "chassis326a" "pdu25" "29" node "chassis326b" "pdu25" "26" node "chassis327a" "pdu25" "28" node "chassis327b" "pdu25" "25" node "chassis328a" "pdu25" "23" node "chassis328b" "pdu25" "20" node "chassis329a" "pdu25" "19" node "chassis329b" "pdu25" "16" node "chassis330a" "pdu25" "18" node "chassis330b" "pdu25" "15" node "chassis331a" "pdu25" "13" node "chassis331b" "pdu25" "10" node "chassis332a" "pdu25" "12" node "chassis332b" "pdu25" "9" node "chassis333a" "pdu25" "11" node "chassis333b" "pdu25" "8" node "chassis334a" "pdu25" "6" node "chassis334b" "pdu25" "3" node "chassis335a" "pdu25" "5" node "chassis335b" "pdu25" "2" node "chassis336a" "pdu25" "4" #sierra[1400,1402] node "chassis336b" "pdu25" "1" #sierra[1401,1403] # Rack 26 node "chassis337a" "pdu26" "48" #sierra[1404,1406] node "chassis337b" "pdu26" "45" #sierra[1405,1407] node "chassis338a" "pdu26" "47" node "chassis338b" "pdu26" "44" node "chassis339a" "pdu26" "43" node "chassis339b" "pdu26" "40" node "chassis340a" "pdu26" "41" node "chassis340b" "pdu26" "38" node "chassis341a" "pdu26" "39" node "chassis341b" "pdu26" "36" node "chassis342a" "pdu26" "37" node "chassis342b" "pdu26" "34" node "chassis343a" "pdu26" "30" node "chassis343b" "pdu26" "27" node "chassis344a" "pdu26" "29" node "chassis344b" "pdu26" "26" node "chassis345a" "pdu26" "28" node "chassis345b" "pdu26" "25" node "chassis346a" "pdu26" "23" node "chassis346b" "pdu26" "20" node "chassis347a" "pdu26" "19" node "chassis347b" "pdu26" "16" node "chassis348a" "pdu26" "18" node "chassis348b" "pdu26" "15" node "chassis349a" "pdu26" "13" node "chassis349b" "pdu26" "10" node "chassis350a" "pdu26" "12" node "chassis350b" "pdu26" "9" node "chassis351a" "pdu26" "11" node "chassis351b" "pdu26" "8" node "chassis352a" "pdu26" "6" node "chassis352b" "pdu26" "3" node "chassis353a" "pdu26" "5" node "chassis353b" "pdu26" "2" node "chassis354a" "pdu26" "4" #sierra[1472,1474] node "chassis354b" "pdu26" "1" #sierra[1473,1475] # Rack 27 node "chassis355a" "pdu27" "48" #sierra[1476,1478] node "chassis355b" "pdu27" "45" #sierra[1475,1477] node "chassis356a" "pdu27" "47" node "chassis356b" "pdu27" "44" node "chassis357a" "pdu27" "43" node "chassis357b" "pdu27" "40" node "chassis358a" "pdu27" "41" node "chassis358b" "pdu27" "38" node "chassis359a" "pdu27" "39" node "chassis359b" "pdu27" "36" node "chassis360a" "pdu27" "37" node "chassis360b" "pdu27" "34" node "chassis361a" "pdu27" "30" node "chassis361b" "pdu27" "27" node "chassis362a" "pdu27" "29" node "chassis362b" "pdu27" "26" node "chassis363a" "pdu27" "28" node "chassis363b" "pdu27" "25" node "chassis364a" "pdu27" "23" node "chassis364b" "pdu27" "20" node "chassis365a" "pdu27" "19" node "chassis365b" "pdu27" "16" node "chassis366a" "pdu27" "18" node "chassis366b" "pdu27" "15" node "chassis367a" "pdu27" "13" node "chassis367b" "pdu27" "10" node "chassis368a" "pdu27" "12" node "chassis368b" "pdu27" "9" node "chassis369a" "pdu27" "11" node "chassis369b" "pdu27" "8" node "chassis370a" "pdu27" "6" node "chassis370b" "pdu27" "3" node "chassis371a" "pdu27" "5" node "chassis371b" "pdu27" "2" node "chassis372a" "pdu27" "4" #sierra[1544,1546] node "chassis372b" "pdu27" "1" #sierra[1545,1547] # Rack 28 node "chassis373a" "pdu28" "48" #sierra[1548,1550] node "chassis373b" "pdu28" "45" #sierra[1549,1551] node "chassis374a" "pdu28" "47" node "chassis374b" "pdu28" "44" node "chassis375a" "pdu28" "43" node "chassis375b" "pdu28" "40" node "chassis376a" "pdu28" "41" node "chassis376b" "pdu28" "38" node "chassis377a" "pdu28" "39" node "chassis377b" "pdu28" "36" node "chassis378a" "pdu28" "37" node "chassis378b" "pdu28" "34" node "chassis379a" "pdu28" "30" node "chassis379b" "pdu28" "27" node "chassis380a" "pdu28" "29" node "chassis380b" "pdu28" "26" node "chassis381a" "pdu28" "28" node "chassis381b" "pdu28" "25" node "chassis382a" "pdu28" "23" node "chassis382b" "pdu28" "20" node "chassis383a" "pdu28" "19" node "chassis383b" "pdu28" "16" node "chassis384a" "pdu28" "18" node "chassis384b" "pdu28" "15" node "chassis385a" "pdu28" "13" node "chassis385b" "pdu28" "10" node "chassis386a" "pdu28" "12" node "chassis386b" "pdu28" "9" node "chassis387a" "pdu28" "11" node "chassis387b" "pdu28" "8" node "chassis388a" "pdu28" "6" node "chassis388b" "pdu28" "3" node "chassis389a" "pdu28" "5" node "chassis389b" "pdu28" "2" node "chassis390a" "pdu28" "4" #sierra[1616,1618] node "chassis390b" "pdu28" "1" #sierra[1617,1619] # Rack 29 LSM,RPS,GW nodes node "pdu-sierra1621a" "pdu29" "47" #sierra1621ps1 node "pdu-sierra1620" "pdu29" "46" #sierra1620 node "pdu-sierra1621b" "pdu29" "44" #sierra1621ps2 node "pdu-sierra1622" "pdu29" "43" #sierra1622 node "pdu-sierra1623" "pdu29" "42" #sierra1623 node "pdu-sierra1624" "pdu29" "41" #sierra1624 node "pdu-sierra1627a" "pdu29" "40" #sierra1627ps1 node "pdu-sierra1625" "pdu29" "39" #sierra1625 node "pdu-sierra1627b" "pdu29" "37" #sierra1627ps2 node "pdu-sierra1626" "pdu29" "36" #sierra1626 node "pdu-sierra1628" "pdu29" "34" #sierra1628 node "pdu-sierra1629" "pdu29" "32" #sierra1629 node "pdu-sierra1630" "pdu29" "31" #sierra1630 node "pdu-sierra1631" "pdu29" "29" #sierra1631 # Rack 29 Compute nodes node "chassis391a" "pdu29" "23" #sierra[1632,1634] node "chassis391b" "pdu29" "20" #sierra[1633,1635] node "chassis392a" "pdu29" "18" node "chassis392b" "pdu29" "15" node "chassis393a" "pdu29" "13" node "chassis393b" "pdu29" "10" node "chassis394a" "pdu29" "12" node "chassis394b" "pdu29" "9" node "chassis395a" "pdu29" "5" node "chassis395b" "pdu29" "2" node "chassis396a" "pdu29" "4" #sierra[1652,1654] node "chassis396b" "pdu29" "1" #sierra[1653,1655] # Rack 30 node "chassis397a" "pdu30" "48" #sierra[1656,1658] node "chassis397b" "pdu30" "45" #sierra[1657,1659] node "chassis398a" "pdu30" "47" node "chassis398b" "pdu30" "44" node "chassis399a" "pdu30" "43" node "chassis399b" "pdu30" "40" node "chassis400a" "pdu30" "41" node "chassis400b" "pdu30" "38" node "chassis401a" "pdu30" "39" node "chassis401b" "pdu30" "36" node "chassis402a" "pdu30" "37" node "chassis402b" "pdu30" "34" node "chassis403a" "pdu30" "30" node "chassis403b" "pdu30" "27" node "chassis404a" "pdu30" "29" node "chassis404b" "pdu30" "26" node "chassis405a" "pdu30" "28" node "chassis405b" "pdu30" "25" node "chassis406a" "pdu30" "23" node "chassis406b" "pdu30" "20" node "chassis407a" "pdu30" "19" node "chassis407b" "pdu30" "16" node "chassis408a" "pdu30" "18" node "chassis408b" "pdu30" "15" node "chassis409a" "pdu30" "13" node "chassis409b" "pdu30" "10" node "chassis410a" "pdu30" "12" node "chassis410b" "pdu30" "9" node "chassis411a" "pdu30" "11" node "chassis411b" "pdu30" "8" node "chassis412a" "pdu30" "6" node "chassis412b" "pdu30" "3" node "chassis413a" "pdu30" "5" node "chassis413b" "pdu30" "2" node "chassis414a" "pdu30" "4" #sierra[1724,1726] node "chassis414b" "pdu30" "1" #sierra[1725,1727] # Rack 31 node "chassis415a" "pdu31" "48" #sierra[1728,1730] node "chassis415b" "pdu31" "45" #sierra[1729,1731] node "chassis416a" "pdu31" "47" node "chassis416b" "pdu31" "44" node "chassis417a" "pdu31" "43" node "chassis417b" "pdu31" "40" node "chassis418a" "pdu31" "41" node "chassis418b" "pdu31" "38" node "chassis419a" "pdu31" "39" node "chassis419b" "pdu31" "36" node "chassis420a" "pdu31" "37" node "chassis420b" "pdu31" "34" node "chassis421a" "pdu31" "30" node "chassis421b" "pdu31" "27" node "chassis422a" "pdu31" "29" node "chassis422b" "pdu31" "26" node "chassis423a" "pdu31" "28" node "chassis423b" "pdu31" "25" node "chassis424a" "pdu31" "23" node "chassis424b" "pdu31" "20" node "chassis425a" "pdu31" "19" node "chassis425b" "pdu31" "16" node "chassis426a" "pdu31" "18" node "chassis426b" "pdu31" "15" node "chassis427a" "pdu31" "13" node "chassis427b" "pdu31" "10" node "chassis428a" "pdu31" "12" node "chassis428b" "pdu31" "9" node "chassis429a" "pdu31" "11" node "chassis429b" "pdu31" "8" node "chassis430a" "pdu31" "6" node "chassis430b" "pdu31" "3" node "chassis431a" "pdu31" "5" node "chassis431b" "pdu31" "2" node "chassis432a" "pdu31" "4" #sierra[1796,1798] node "chassis432b" "pdu31" "1" #sierra[1797,1799] # Rack 32 node "chassis433a" "pdu32" "48" #sierra[1800,1802] node "chassis433b" "pdu32" "45" #sierra[1801,1803] node "chassis434a" "pdu32" "47" node "chassis434b" "pdu32" "44" node "chassis435a" "pdu32" "43" node "chassis435b" "pdu32" "40" node "chassis436a" "pdu32" "41" node "chassis436b" "pdu32" "38" node "chassis437a" "pdu32" "39" node "chassis437b" "pdu32" "36" node "chassis438a" "pdu32" "37" node "chassis438b" "pdu32" "34" node "chassis439a" "pdu32" "30" node "chassis439b" "pdu32" "27" node "chassis440a" "pdu32" "29" node "chassis440b" "pdu32" "26" node "chassis441a" "pdu32" "28" node "chassis441b" "pdu32" "25" node "chassis442a" "pdu32" "23" node "chassis442b" "pdu32" "20" node "chassis443a" "pdu32" "19" node "chassis443b" "pdu32" "16" node "chassis444a" "pdu32" "18" node "chassis444b" "pdu32" "15" node "chassis445a" "pdu32" "13" node "chassis445b" "pdu32" "10" node "chassis446a" "pdu32" "12" node "chassis446b" "pdu32" "9" node "chassis447a" "pdu32" "11" node "chassis447b" "pdu32" "8" node "chassis448a" "pdu32" "6" node "chassis448b" "pdu32" "3" node "chassis449a" "pdu32" "5" node "chassis449b" "pdu32" "2" node "chassis450a" "pdu32" "4" #sierra[1868,1870] node "chassis450b" "pdu32" "1" #sierra[1869,1871] # Rack 33 node "chassis451a" "pdu33" "48" #sierra[1872,1874] node "chassis451b" "pdu33" "45" #sierra[1873,1875] node "chassis452a" "pdu33" "47" node "chassis452b" "pdu33" "44" node "chassis453a" "pdu33" "43" node "chassis453b" "pdu33" "40" node "chassis454a" "pdu33" "41" node "chassis454b" "pdu33" "38" node "chassis455a" "pdu33" "39" node "chassis455b" "pdu33" "36" node "chassis456a" "pdu33" "37" node "chassis456b" "pdu33" "34" node "chassis457a" "pdu33" "30" node "chassis457b" "pdu33" "27" node "chassis458a" "pdu33" "29" node "chassis458b" "pdu33" "26" node "chassis459a" "pdu33" "28" node "chassis459b" "pdu33" "25" node "chassis460a" "pdu33" "23" node "chassis460b" "pdu33" "20" node "chassis461a" "pdu33" "19" node "chassis461b" "pdu33" "16" node "chassis462a" "pdu33" "18" node "chassis462b" "pdu33" "15" node "chassis463a" "pdu33" "13" node "chassis463b" "pdu33" "10" node "chassis464a" "pdu33" "12" node "chassis464b" "pdu33" "9" node "chassis465a" "pdu33" "11" node "chassis465b" "pdu33" "8" node "chassis466a" "pdu33" "6" node "chassis466b" "pdu33" "3" node "chassis467a" "pdu33" "5" node "chassis467b" "pdu33" "2" node "chassis468a" "pdu33" "4" #sierra[1940,1942] node "chassis468b" "pdu33" "1" #sierra[1941,1943] # ALIAS section. # mgmt alias #alias "sierra1" "pdu-sierra1a pdu-sierra1b" #alias "sierra7" "pdu-sierra7a pdu-sierra7b" #alias "sierra325" "pdu-sierra325a pdu-sierra325b" #alias "sierra331" "pdu-sierra331a pdu-sierra331b" #alias "sierra649" "pdu-sierra649a pdu-sierra649b" #alias "sierra655" "pdu-sierra655a pdu-sierra655b" #alias "sierra973" "pdu-sierra973a pdu-sierra973b" #alias "sierra979" "pdu-sierra979a pdu-sierra979b" #alias "sierra1297" "pdu-sierra1297a pdu-sierra1297b" #alias "sierra1303" "pdu-sierra1303a pdu-sierra1303b" #alias "sierra1621" "pdu-sierra1621a pdu-sierra1621b" #alias "sierra1627" "pdu-sierra1627a pdu-sierra1627b" # more alias alias "chassis1" "chassis1a chassis1b" alias "chassis2" "chassis2a chassis2b" alias "chassis3" "chassis3a chassis3b" alias "chassis4" "chassis4a chassis4b" alias "chassis5" "chassis5a chassis5b" alias "chassis6" "chassis6a chassis6b" alias "chassis7" "chassis7a chassis7b" alias "chassis8" "chassis8a chassis8b" alias "chassis9" "chassis9a chassis9b" alias "chassis10" "chassis10a chassis10b" alias "chassis11" "chassis11a chassis11b" alias "chassis12" "chassis12a chassis12b" alias "chassis13" "chassis13a chassis13b" alias "chassis14" "chassis14a chassis14b" alias "chassis15" "chassis15a chassis15b" alias "chassis16" "chassis16a chassis16b" alias "chassis17" "chassis17a chassis17b" alias "chassis18" "chassis18a chassis18b" alias "chassis19" "chassis19a chassis19b" alias "chassis20" "chassis20a chassis20b" alias "chassis21" "chassis21a chassis21b" alias "chassis22" "chassis22a chassis22b" alias "chassis23" "chassis23a chassis23b" alias "chassis24" "chassis24a chassis24b" alias "chassis25" "chassis25a chassis25b" alias "chassis26" "chassis26a chassis26b" alias "chassis27" "chassis27a chassis27b" alias "chassis28" "chassis28a chassis28b" alias "chassis29" "chassis29a chassis29b" alias "chassis30" "chassis30a chassis30b" alias "chassis31" "chassis31a chassis31b" alias "chassis32" "chassis32a chassis32b" alias "chassis33" "chassis33a chassis33b" alias "chassis34" "chassis34a chassis34b" alias "chassis35" "chassis35a chassis35b" alias "chassis36" "chassis36a chassis36b" alias "chassis37" "chassis37a chassis37b" alias "chassis38" "chassis38a chassis38b" alias "chassis39" "chassis39a chassis39b" alias "chassis40" "chassis40a chassis40b" alias "chassis41" "chassis41a chassis41b" alias "chassis42" "chassis42a chassis42b" alias "chassis43" "chassis43a chassis43b" alias "chassis44" "chassis44a chassis44b" alias "chassis45" "chassis45a chassis45b" alias "chassis46" "chassis46a chassis46b" alias "chassis47" "chassis47a chassis47b" alias "chassis48" "chassis48a chassis48b" alias "chassis49" "chassis49a chassis49b" alias "chassis50" "chassis50a chassis50b" alias "chassis51" "chassis51a chassis51b" alias "chassis52" "chassis52a chassis52b" alias "chassis53" "chassis53a chassis53b" alias "chassis54" "chassis54a chassis54b" alias "chassis55" "chassis55a chassis55b" alias "chassis56" "chassis56a chassis56b" alias "chassis57" "chassis57a chassis57b" alias "chassis58" "chassis58a chassis58b" alias "chassis59" "chassis59a chassis59b" alias "chassis60" "chassis60a chassis60b" alias "chassis61" "chassis61a chassis61b" alias "chassis62" "chassis62a chassis62b" alias "chassis63" "chassis63a chassis63b" alias "chassis64" "chassis64a chassis64b" alias "chassis65" "chassis65a chassis65b" alias "chassis66" "chassis66a chassis66b" alias "chassis67" "chassis67a chassis67b" alias "chassis68" "chassis68a chassis68b" alias "chassis69" "chassis69a chassis69b" alias "chassis70" "chassis70a chassis70b" alias "chassis71" "chassis71a chassis71b" alias "chassis72" "chassis72a chassis72b" alias "chassis73" "chassis73a chassis73b" alias "chassis74" "chassis74a chassis74b" alias "chassis75" "chassis75a chassis75b" alias "chassis76" "chassis76a chassis76b" alias "chassis77" "chassis77a chassis77b" alias "chassis78" "chassis78a chassis78b" alias "chassis79" "chassis79a chassis79b" alias "chassis80" "chassis80a chassis80b" alias "chassis81" "chassis81a chassis81b" alias "chassis82" "chassis82a chassis82b" alias "chassis83" "chassis83a chassis83b" alias "chassis84" "chassis84a chassis84b" alias "chassis85" "chassis85a chassis85b" alias "chassis86" "chassis86a chassis86b" alias "chassis87" "chassis87a chassis87b" alias "chassis88" "chassis88a chassis88b" alias "chassis89" "chassis89a chassis89b" alias "chassis90" "chassis90a chassis90b" alias "chassis91" "chassis91a chassis91b" alias "chassis92" "chassis92a chassis92b" alias "chassis93" "chassis93a chassis93b" alias "chassis94" "chassis94a chassis94b" alias "chassis95" "chassis95a chassis95b" alias "chassis96" "chassis96a chassis96b" alias "chassis97" "chassis97a chassis97b" alias "chassis98" "chassis98a chassis98b" alias "chassis99" "chassis99a chassis99b" alias "chassis100" "chassis100a chassis100b" alias "chassis101" "chassis101a chassis101b" alias "chassis102" "chassis102a chassis102b" alias "chassis103" "chassis103a chassis103b" alias "chassis104" "chassis104a chassis104b" alias "chassis105" "chassis105a chassis105b" alias "chassis106" "chassis106a chassis106b" alias "chassis107" "chassis107a chassis107b" alias "chassis108" "chassis108a chassis108b" alias "chassis109" "chassis109a chassis109b" alias "chassis110" "chassis110a chassis110b" alias "chassis111" "chassis111a chassis111b" alias "chassis112" "chassis112a chassis112b" alias "chassis113" "chassis113a chassis113b" alias "chassis114" "chassis114a chassis114b" alias "chassis115" "chassis115a chassis115b" alias "chassis116" "chassis116a chassis116b" alias "chassis117" "chassis117a chassis117b" alias "chassis118" "chassis118a chassis118b" alias "chassis119" "chassis119a chassis119b" alias "chassis120" "chassis120a chassis120b" alias "chassis121" "chassis121a chassis121b" alias "chassis122" "chassis122a chassis122b" alias "chassis123" "chassis123a chassis123b" alias "chassis124" "chassis124a chassis124b" alias "chassis125" "chassis125a chassis125b" alias "chassis126" "chassis126a chassis126b" alias "chassis127" "chassis127a chassis127b" alias "chassis128" "chassis128a chassis128b" alias "chassis129" "chassis129a chassis129b" alias "chassis130" "chassis130a chassis130b" alias "chassis131" "chassis131a chassis131b" alias "chassis132" "chassis132a chassis132b" alias "chassis133" "chassis133a chassis133b" alias "chassis134" "chassis134a chassis134b" alias "chassis135" "chassis135a chassis135b" alias "chassis136" "chassis136a chassis136b" alias "chassis137" "chassis137a chassis137b" alias "chassis138" "chassis138a chassis138b" alias "chassis139" "chassis139a chassis139b" alias "chassis140" "chassis140a chassis140b" alias "chassis141" "chassis141a chassis141b" alias "chassis142" "chassis142a chassis142b" alias "chassis143" "chassis143a chassis143b" alias "chassis144" "chassis144a chassis144b" alias "chassis145" "chassis145a chassis145b" alias "chassis146" "chassis146a chassis146b" alias "chassis147" "chassis147a chassis147b" alias "chassis148" "chassis148a chassis148b" alias "chassis149" "chassis149a chassis149b" alias "chassis150" "chassis150a chassis150b" alias "chassis151" "chassis151a chassis151b" alias "chassis152" "chassis152a chassis152b" alias "chassis153" "chassis153a chassis153b" alias "chassis154" "chassis154a chassis154b" alias "chassis155" "chassis155a chassis155b" alias "chassis156" "chassis156a chassis156b" alias "chassis157" "chassis157a chassis157b" alias "chassis158" "chassis158a chassis158b" alias "chassis159" "chassis159a chassis159b" alias "chassis160" "chassis160a chassis160b" alias "chassis161" "chassis161a chassis161b" alias "chassis162" "chassis162a chassis162b" alias "chassis163" "chassis163a chassis163b" alias "chassis164" "chassis164a chassis164b" alias "chassis165" "chassis165a chassis165b" alias "chassis166" "chassis166a chassis166b" alias "chassis167" "chassis167a chassis167b" alias "chassis168" "chassis168a chassis168b" alias "chassis169" "chassis169a chassis169b" alias "chassis170" "chassis170a chassis170b" alias "chassis171" "chassis171a chassis171b" alias "chassis172" "chassis172a chassis172b" alias "chassis173" "chassis173a chassis173b" alias "chassis174" "chassis174a chassis174b" alias "chassis175" "chassis175a chassis175b" alias "chassis176" "chassis176a chassis176b" alias "chassis177" "chassis177a chassis177b" alias "chassis178" "chassis178a chassis178b" alias "chassis179" "chassis179a chassis179b" alias "chassis180" "chassis180a chassis180b" alias "chassis181" "chassis181a chassis181b" alias "chassis182" "chassis182a chassis182b" alias "chassis183" "chassis183a chassis183b" alias "chassis184" "chassis184a chassis184b" alias "chassis185" "chassis185a chassis185b" alias "chassis186" "chassis186a chassis186b" alias "chassis187" "chassis187a chassis187b" alias "chassis188" "chassis188a chassis188b" alias "chassis189" "chassis189a chassis189b" alias "chassis190" "chassis190a chassis190b" alias "chassis191" "chassis191a chassis191b" alias "chassis192" "chassis192a chassis192b" alias "chassis193" "chassis193a chassis193b" alias "chassis194" "chassis194a chassis194b" alias "chassis195" "chassis195a chassis195b" alias "chassis196" "chassis196a chassis196b" alias "chassis197" "chassis197a chassis197b" alias "chassis198" "chassis198a chassis198b" alias "chassis199" "chassis199a chassis199b" alias "chassis200" "chassis200a chassis200b" alias "chassis201" "chassis201a chassis201b" alias "chassis202" "chassis202a chassis202b" alias "chassis203" "chassis203a chassis203b" alias "chassis204" "chassis204a chassis204b" alias "chassis205" "chassis205a chassis205b" alias "chassis206" "chassis206a chassis206b" alias "chassis207" "chassis207a chassis207b" alias "chassis208" "chassis208a chassis208b" alias "chassis209" "chassis209a chassis209b" alias "chassis210" "chassis210a chassis210b" alias "chassis211" "chassis211a chassis211b" alias "chassis212" "chassis212a chassis212b" alias "chassis213" "chassis213a chassis213b" alias "chassis214" "chassis214a chassis214b" alias "chassis215" "chassis215a chassis215b" alias "chassis216" "chassis216a chassis216b" alias "chassis217" "chassis217a chassis217b" alias "chassis218" "chassis218a chassis218b" alias "chassis219" "chassis219a chassis219b" alias "chassis220" "chassis220a chassis220b" alias "chassis221" "chassis221a chassis221b" alias "chassis222" "chassis222a chassis222b" alias "chassis223" "chassis223a chassis223b" alias "chassis224" "chassis224a chassis224b" alias "chassis225" "chassis225a chassis225b" alias "chassis226" "chassis226a chassis226b" alias "chassis227" "chassis227a chassis227b" alias "chassis228" "chassis228a chassis228b" alias "chassis229" "chassis229a chassis229b" alias "chassis230" "chassis230a chassis230b" alias "chassis231" "chassis231a chassis231b" alias "chassis232" "chassis232a chassis232b" alias "chassis233" "chassis233a chassis233b" alias "chassis234" "chassis234a chassis234b" alias "chassis235" "chassis235a chassis235b" alias "chassis236" "chassis236a chassis236b" alias "chassis237" "chassis237a chassis237b" alias "chassis238" "chassis238a chassis238b" alias "chassis239" "chassis239a chassis239b" alias "chassis240" "chassis240a chassis240b" alias "chassis241" "chassis241a chassis241b" alias "chassis242" "chassis242a chassis242b" alias "chassis243" "chassis243a chassis243b" alias "chassis244" "chassis244a chassis244b" alias "chassis245" "chassis245a chassis245b" alias "chassis246" "chassis246a chassis246b" alias "chassis247" "chassis247a chassis247b" alias "chassis248" "chassis248a chassis248b" alias "chassis249" "chassis249a chassis249b" alias "chassis250" "chassis250a chassis250b" alias "chassis251" "chassis251a chassis251b" alias "chassis252" "chassis252a chassis252b" alias "chassis253" "chassis253a chassis253b" alias "chassis254" "chassis254a chassis254b" alias "chassis255" "chassis255a chassis255b" alias "chassis256" "chassis256a chassis256b" alias "chassis257" "chassis257a chassis257b" alias "chassis258" "chassis258a chassis258b" alias "chassis259" "chassis259a chassis259b" alias "chassis260" "chassis260a chassis260b" alias "chassis261" "chassis261a chassis261b" alias "chassis262" "chassis262a chassis262b" alias "chassis263" "chassis263a chassis263b" alias "chassis264" "chassis264a chassis264b" alias "chassis265" "chassis265a chassis265b" alias "chassis266" "chassis266a chassis266b" alias "chassis267" "chassis267a chassis267b" alias "chassis268" "chassis268a chassis268b" alias "chassis269" "chassis269a chassis269b" alias "chassis270" "chassis270a chassis270b" alias "chassis271" "chassis271a chassis271b" alias "chassis272" "chassis272a chassis272b" alias "chassis273" "chassis273a chassis273b" alias "chassis274" "chassis274a chassis274b" alias "chassis275" "chassis275a chassis275b" alias "chassis276" "chassis276a chassis276b" alias "chassis277" "chassis277a chassis277b" alias "chassis278" "chassis278a chassis278b" alias "chassis279" "chassis279a chassis279b" alias "chassis280" "chassis280a chassis280b" alias "chassis281" "chassis281a chassis281b" alias "chassis282" "chassis282a chassis282b" alias "chassis283" "chassis283a chassis283b" alias "chassis284" "chassis284a chassis284b" alias "chassis285" "chassis285a chassis285b" alias "chassis286" "chassis286a chassis286b" alias "chassis287" "chassis287a chassis287b" alias "chassis288" "chassis288a chassis288b" alias "chassis289" "chassis289a chassis289b" alias "chassis290" "chassis290a chassis290b" alias "chassis291" "chassis291a chassis291b" alias "chassis292" "chassis292a chassis292b" alias "chassis293" "chassis293a chassis293b" alias "chassis294" "chassis294a chassis294b" alias "chassis295" "chassis295a chassis295b" alias "chassis296" "chassis296a chassis296b" alias "chassis297" "chassis297a chassis297b" alias "chassis298" "chassis298a chassis298b" alias "chassis299" "chassis299a chassis299b" alias "chassis300" "chassis300a chassis300b" alias "chassis301" "chassis301a chassis301b" alias "chassis302" "chassis302a chassis302b" alias "chassis303" "chassis303a chassis303b" alias "chassis304" "chassis304a chassis304b" alias "chassis305" "chassis305a chassis305b" alias "chassis306" "chassis306a chassis306b" alias "chassis307" "chassis307a chassis307b" alias "chassis308" "chassis308a chassis308b" alias "chassis309" "chassis309a chassis309b" alias "chassis310" "chassis310a chassis310b" alias "chassis311" "chassis311a chassis311b" alias "chassis312" "chassis312a chassis312b" alias "chassis313" "chassis313a chassis313b" alias "chassis314" "chassis314a chassis314b" alias "chassis315" "chassis315a chassis315b" alias "chassis316" "chassis316a chassis316b" alias "chassis317" "chassis317a chassis317b" alias "chassis318" "chassis318a chassis318b" alias "chassis319" "chassis319a chassis319b" alias "chassis320" "chassis320a chassis320b" alias "chassis321" "chassis321a chassis321b" alias "chassis322" "chassis322a chassis322b" alias "chassis323" "chassis323a chassis323b" alias "chassis324" "chassis324a chassis324b" alias "chassis325" "chassis325a chassis325b" alias "chassis326" "chassis326a chassis326b" alias "chassis327" "chassis327a chassis327b" alias "chassis328" "chassis328a chassis328b" alias "chassis329" "chassis329a chassis329b" alias "chassis330" "chassis330a chassis330b" alias "chassis331" "chassis331a chassis331b" alias "chassis332" "chassis332a chassis332b" alias "chassis333" "chassis333a chassis333b" alias "chassis334" "chassis334a chassis334b" alias "chassis335" "chassis335a chassis335b" alias "chassis336" "chassis336a chassis336b" alias "chassis337" "chassis337a chassis337b" alias "chassis338" "chassis338a chassis338b" alias "chassis339" "chassis339a chassis339b" alias "chassis340" "chassis340a chassis340b" alias "chassis341" "chassis341a chassis341b" alias "chassis342" "chassis342a chassis342b" alias "chassis343" "chassis343a chassis343b" alias "chassis344" "chassis344a chassis344b" alias "chassis345" "chassis345a chassis345b" alias "chassis346" "chassis346a chassis346b" alias "chassis347" "chassis347a chassis347b" alias "chassis348" "chassis348a chassis348b" alias "chassis349" "chassis349a chassis349b" alias "chassis350" "chassis350a chassis350b" alias "chassis351" "chassis351a chassis351b" alias "chassis352" "chassis352a chassis352b" alias "chassis353" "chassis353a chassis353b" alias "chassis354" "chassis354a chassis354b" alias "chassis355" "chassis355a chassis355b" alias "chassis356" "chassis356a chassis356b" alias "chassis357" "chassis357a chassis357b" alias "chassis358" "chassis358a chassis358b" alias "chassis359" "chassis359a chassis359b" alias "chassis360" "chassis360a chassis360b" alias "chassis361" "chassis361a chassis361b" alias "chassis362" "chassis362a chassis362b" alias "chassis363" "chassis363a chassis363b" alias "chassis364" "chassis364a chassis364b" alias "chassis365" "chassis365a chassis365b" alias "chassis366" "chassis366a chassis366b" alias "chassis367" "chassis367a chassis367b" alias "chassis368" "chassis368a chassis368b" alias "chassis369" "chassis369a chassis369b" alias "chassis370" "chassis370a chassis370b" alias "chassis371" "chassis371a chassis371b" alias "chassis372" "chassis372a chassis372b" alias "chassis373" "chassis373a chassis373b" alias "chassis374" "chassis374a chassis374b" alias "chassis375" "chassis375a chassis375b" alias "chassis376" "chassis376a chassis376b" alias "chassis377" "chassis377a chassis377b" alias "chassis378" "chassis378a chassis378b" alias "chassis379" "chassis379a chassis379b" alias "chassis380" "chassis380a chassis380b" alias "chassis381" "chassis381a chassis381b" alias "chassis382" "chassis382a chassis382b" alias "chassis383" "chassis383a chassis383b" alias "chassis384" "chassis384a chassis384b" alias "chassis385" "chassis385a chassis385b" alias "chassis386" "chassis386a chassis386b" alias "chassis387" "chassis387a chassis387b" alias "chassis388" "chassis388a chassis388b" alias "chassis389" "chassis389a chassis389b" alias "chassis390" "chassis390a chassis390b" alias "chassis391" "chassis391a chassis391b" alias "chassis392" "chassis392a chassis392b" alias "chassis393" "chassis393a chassis393b" alias "chassis394" "chassis394a chassis394b" alias "chassis395" "chassis395a chassis395b" alias "chassis396" "chassis396a chassis396b" alias "chassis397" "chassis397a chassis397b" alias "chassis398" "chassis398a chassis398b" alias "chassis399" "chassis399a chassis399b" alias "chassis400" "chassis400a chassis400b" alias "chassis401" "chassis401a chassis401b" alias "chassis402" "chassis402a chassis402b" alias "chassis403" "chassis403a chassis403b" alias "chassis404" "chassis404a chassis404b" alias "chassis405" "chassis405a chassis405b" alias "chassis406" "chassis406a chassis406b" alias "chassis407" "chassis407a chassis407b" alias "chassis408" "chassis408a chassis408b" alias "chassis409" "chassis409a chassis409b" alias "chassis410" "chassis410a chassis410b" alias "chassis411" "chassis411a chassis411b" alias "chassis412" "chassis412a chassis412b" alias "chassis413" "chassis413a chassis413b" alias "chassis414" "chassis414a chassis414b" alias "chassis415" "chassis415a chassis415b" alias "chassis416" "chassis416a chassis416b" alias "chassis417" "chassis417a chassis417b" alias "chassis418" "chassis418a chassis418b" alias "chassis419" "chassis419a chassis419b" alias "chassis420" "chassis420a chassis420b" alias "chassis421" "chassis421a chassis421b" alias "chassis422" "chassis422a chassis422b" alias "chassis423" "chassis423a chassis423b" alias "chassis424" "chassis424a chassis424b" alias "chassis425" "chassis425a chassis425b" alias "chassis426" "chassis426a chassis426b" alias "chassis427" "chassis427a chassis427b" alias "chassis428" "chassis428a chassis428b" alias "chassis429" "chassis429a chassis429b" alias "chassis430" "chassis430a chassis430b" alias "chassis431" "chassis431a chassis431b" alias "chassis432" "chassis432a chassis432b" alias "chassis433" "chassis433a chassis433b" alias "chassis434" "chassis434a chassis434b" alias "chassis435" "chassis435a chassis435b" alias "chassis436" "chassis436a chassis436b" alias "chassis437" "chassis437a chassis437b" alias "chassis438" "chassis438a chassis438b" alias "chassis439" "chassis439a chassis439b" alias "chassis440" "chassis440a chassis440b" alias "chassis441" "chassis441a chassis441b" alias "chassis442" "chassis442a chassis442b" alias "chassis443" "chassis443a chassis443b" alias "chassis444" "chassis444a chassis444b" alias "chassis445" "chassis445a chassis445b" alias "chassis446" "chassis446a chassis446b" alias "chassis447" "chassis447a chassis447b" alias "chassis448" "chassis448a chassis448b" alias "chassis449" "chassis449a chassis449b" alias "chassis450" "chassis450a chassis450b" alias "chassis451" "chassis451a chassis451b" alias "chassis452" "chassis452a chassis452b" alias "chassis453" "chassis453a chassis453b" alias "chassis454" "chassis454a chassis454b" alias "chassis455" "chassis455a chassis455b" alias "chassis456" "chassis456a chassis456b" alias "chassis457" "chassis457a chassis457b" alias "chassis458" "chassis458a chassis458b" alias "chassis459" "chassis459a chassis459b" alias "chassis460" "chassis460a chassis460b" alias "chassis461" "chassis461a chassis461b" alias "chassis462" "chassis462a chassis462b" alias "chassis463" "chassis463a chassis463b" alias "chassis464" "chassis464a chassis464b" alias "chassis465" "chassis465a chassis465b" alias "chassis466" "chassis466a chassis466b" alias "chassis467" "chassis467a chassis467b" alias "chassis468" "chassis468a chassis468b" powerman-2.3.27/test/swpdu.c000066400000000000000000000102541415616035500157320ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* swpdu.c - appro swpdu simulator */ /* FIXME: created from swpdu.dev, thus needs a sync with reality */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include "xread.h" static void usage(void); static void _noop_handler(int signum); static void _prompt_loop(void); static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int c; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { default: usage(); } } if (optind < argc) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s -p v2|v3|v4\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } static void _prompt_loop(void) { int i; char buf[128]; int num_plugs = 48; int plug[48]; int plug_origin = 1; for (i = 0; i < num_plugs; i++) { plug[i] = 0; } /* Process comands. */ while (1) { if (xreadline("", buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) { /* */ } else if (!strcmp(buf, "exprange on")) { /* */ } else if (!strcmp(buf, "exprange off")) { /* */ } else if (!strcmp(buf, "status")) { for (i = 0; i < num_plugs; i++) printf ("plug %d: %s\n", i + plug_origin, plug[i] ? "on" : "off"); } else if (sscanf(buf, "status %d", &i) == 1) { i -= plug_origin; if (i < 0 || i >= num_plugs) break; printf ("plug %d: %s\n", i + plug_origin, plug[i] ? "on" : "off"); } else if (sscanf(buf, "on %d", &i) == 1) { i -= plug_origin; if (i < 0 || i >= num_plugs) break; plug[i] = 1; } else if (sscanf(buf, "off %d", &i) == 1) { i -= plug_origin; if (i < 0 || i >= num_plugs) break; plug[i] = 0; } else if (sscanf(buf, "cycle %d", &i) == 1) { i -= plug_origin; if (i < 0 || i >= num_plugs) break; plug[i] = 0; sleep(2); plug[i] = 1; } else break; printf("swpdu> "); } printf("Error, exiting"); exit (1); } /* * vi:tabstop=4 shiftwidth=4 expandtab */ powerman-2.3.27/test/t00000077500000000000000000000002261415616035500147530ustar00rootroot00000000000000#!/bin/sh TEST=t00 ${TEST_BUILDDIR}/tpl -f p493 'foo[1-500]' 'p[1-500]' >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t00.exp000066400000000000000000000000261415616035500155410ustar00rootroot00000000000000plug=p493 node=foo493 powerman-2.3.27/test/t01000077500000000000000000000002171415616035500147540ustar00rootroot00000000000000#!/bin/sh TEST=t01 ${TEST_BUILDDIR}/tpl 't[1,2,3]' 'p[999-1001]' >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t01.exp000066400000000000000000000000701415616035500155410ustar00rootroot00000000000000plug=p1001 node=t3 plug=p1000 node=t2 plug=p999 node=t1 powerman-2.3.27/test/t02000077500000000000000000000002251415616035500147540ustar00rootroot00000000000000#!/bin/sh TEST=t02 ${TEST_BUILDDIR}/tpl -p1,2,3,4,5,6 foo[11-15] [1-5] >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t02.exp000066400000000000000000000001531415616035500155440ustar00rootroot00000000000000plug=1 node=foo11 plug=2 node=foo12 plug=3 node=foo13 plug=4 node=foo14 plug=5 node=foo15 plug=6 node=NULL powerman-2.3.27/test/t03000077500000000000000000000002401415616035500147520ustar00rootroot00000000000000#!/bin/sh TEST=t03 ${TEST_BUILDDIR}/tpl -p 1,2,3,4,5,6,7,8 'foo[1-500]' '[1-500]' >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t03.exp000066400000000000000000000002251415616035500155450ustar00rootroot00000000000000unknown plug plug=1 node=foo1 plug=2 node=foo2 plug=3 node=foo3 plug=4 node=foo4 plug=5 node=foo5 plug=6 node=foo6 plug=7 node=foo7 plug=8 node=foo8 powerman-2.3.27/test/t04000077500000000000000000000001711415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t04 ${TEST_BUILDDIR}/targv >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t04.exp000066400000000000000000000000001415616035500155350ustar00rootroot00000000000000powerman-2.3.27/test/t05000077500000000000000000000001711415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t05 ${TEST_BUILDDIR}/tregex >$TEST.out 2>&1 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t05.exp000066400000000000000000000000001415616035500155360ustar00rootroot00000000000000powerman-2.3.27/test/t06000077500000000000000000000003151415616035500147600ustar00rootroot00000000000000#!/bin/sh TEST=t06 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -q -Q t1 -Q t[3-5] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t06.exp000066400000000000000000000001511415616035500155460ustar00rootroot00000000000000on: off: t[0-15] unknown: on: off: t1 unknown: on: off: t[3-5] unknown: powerman-2.3.27/test/t07000077500000000000000000000003161415616035500147620ustar00rootroot00000000000000#!/bin/sh TEST=t07 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -Q t1 -Q t[3-5] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t07.conf.in000066400000000000000000000010011415616035500163000ustar00rootroot00000000000000specification "vpc" { timeout 5.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status { send "stat %s\n" expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t07.exp000066400000000000000000000001511415616035500155470ustar00rootroot00000000000000on: off: t[0-15] unknown: on: off: t1 unknown: on: off: t[3-5] unknown: powerman-2.3.27/test/t08000077500000000000000000000003001415616035500147540ustar00rootroot00000000000000#!/bin/sh TEST=t08 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -T -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t08.exp000066400000000000000000000011001415616035500155430ustar00rootroot00000000000000send(test0): 'stat *\n' recv(test0): 'plug 0: OFF\n' recv(test0): 'plug 1: OFF\n' recv(test0): 'plug 2: OFF\n' recv(test0): 'plug 3: OFF\n' recv(test0): 'plug 4: OFF\n' recv(test0): 'plug 5: OFF\n' recv(test0): 'plug 6: OFF\n' recv(test0): 'plug 7: OFF\n' recv(test0): 'plug 8: OFF\n' recv(test0): 'plug 9: OFF\n' recv(test0): 'plug 10: OFF\n' recv(test0): 'plug 11: OFF\n' recv(test0): 'plug 12: OFF\n' recv(test0): 'plug 13: OFF\n' recv(test0): 'plug 14: OFF\n' recv(test0): 'plug 15: OFF\n' recv(test0): '1 OK\n' recv(test0): '2 vpc> ' on: off: t[0-15] unknown: powerman-2.3.27/test/t09000077500000000000000000000003011415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t09 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -T -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t09.conf.in000066400000000000000000000011601415616035500163100ustar00rootroot00000000000000specification "vpc" { timeout 5.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { send "spew 16\n" # noise generator expect "[0-9]* OK\n" expect "[0-9]* vpc> " send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t09.exp000066400000000000000000000036061415616035500155610ustar00rootroot00000000000000send(test0): 'spew 16\n' recv(test0): 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\n1 OK\n' recv(test0): '2 vpc> ' send(test0): 'stat *\n' recv(test0): 'plug 0: OFF\n' recv(test0): 'plug 1: OFF\n' recv(test0): 'plug 2: OFF\n' recv(test0): 'plug 3: OFF\n' recv(test0): 'plug 4: OFF\n' recv(test0): 'plug 5: OFF\n' recv(test0): 'plug 6: OFF\n' recv(test0): 'plug 7: OFF\n' recv(test0): 'plug 8: OFF\n' recv(test0): 'plug 9: OFF\n' recv(test0): 'plug 10: OFF\n' recv(test0): 'plug 11: OFF\n' recv(test0): 'plug 12: OFF\n' recv(test0): 'plug 13: OFF\n' recv(test0): 'plug 14: OFF\n' recv(test0): 'plug 15: OFF\n' recv(test0): '2 OK\n' recv(test0): '3 vpc> ' on: off: t[0-15] unknown: powerman-2.3.27/test/t10000077500000000000000000000003011415616035500147460ustar00rootroot00000000000000#!/bin/sh TEST=t10 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -T -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t10.conf.in000066400000000000000000000013611415616035500163030ustar00rootroot00000000000000specification "vpc" { timeout 5.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { # noise generator # spew more than 1K (MIN_DEV_BUF) but less than 64K (MAX_DEV_BUF) to # cause cbuf expansion but no wrap. (512 * 78 char = 39K) send "spew 512\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t10.exp000066400000000000000000001212071415616035500155470ustar00rootroot00000000000000send(test0): 'spew 512\n' recv(test0): 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\n1 OK\n' recv(test0): '2 vpc> ' send(test0): 'stat *\n' recv(test0): 'plug 0: OFF\n' recv(test0): 'plug 1: OFF\n' recv(test0): 'plug 2: OFF\n' recv(test0): 'plug 3: OFF\n' recv(test0): 'plug 4: OFF\n' recv(test0): 'plug 5: OFF\n' recv(test0): 'plug 6: OFF\n' recv(test0): 'plug 7: OFF\n' recv(test0): 'plug 8: OFF\n' recv(test0): 'plug 9: OFF\n' recv(test0): 'plug 10: OFF\n' recv(test0): 'plug 11: OFF\n' recv(test0): 'plug 12: OFF\n' recv(test0): 'plug 13: OFF\n' recv(test0): 'plug 14: OFF\n' recv(test0): 'plug 15: OFF\n' recv(test0): '2 OK\n' recv(test0): '3 vpc> ' on: off: t[0-15] unknown: powerman-2.3.27/test/t11000077500000000000000000000003261415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t11 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -q -1 t4 -q -0 t4 -q -c t5 -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t11.exp000066400000000000000000000003751415616035500155520ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t4 off: t[0-3,5-15] unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t5 off: t[0-4,6-15] unknown: powerman-2.3.27/test/t12000077500000000000000000000003031415616035500147520ustar00rootroot00000000000000#!/bin/sh TEST=t12 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -Q t1 t2 >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t12.exp000066400000000000000000000000441415616035500155440ustar00rootroot00000000000000on: off: t[1-2] unknown: powerman-2.3.27/test/t13000077500000000000000000000003421415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t13 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -b -f t[13-15] -b -u t13 -b -B t13 -B t14 >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t13.exp000066400000000000000000000003771415616035500155560ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t[13-15] off: t[0-12] unknown: Command completed successfully on: t[14-15] off: t[0-13] unknown: on: off: t13 unknown: on: t14 off: unknown: powerman-2.3.27/test/t14000077500000000000000000000003161415616035500147600ustar00rootroot00000000000000#!/bin/sh TEST=t14 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -t -P t13 -P t[13-15] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t14.exp000066400000000000000000000002261415616035500155500ustar00rootroot00000000000000t0: 83 t1: 84 t2: 85 t3: 86 t4: 87 t5: 88 t6: 89 t7: 90 t8: 91 t9: 92 t10: 93 t11: 94 t12: 95 t13: 96 t14: 97 t15: 98 t13: 96 t13: 96 t14: 97 t15: 98 powerman-2.3.27/test/t15000077500000000000000000000003101415616035500147530ustar00rootroot00000000000000#!/bin/sh TEST=t15 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -r t1 -r t[3-5] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t15.exp000066400000000000000000000000761415616035500155540ustar00rootroot00000000000000Command completed successfully Command completed successfully powerman-2.3.27/test/t16000077500000000000000000000003341415616035500147620ustar00rootroot00000000000000#!/bin/sh TEST=t16 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/test.conf \ -Q t1 -d -Q t1 -d -Q t1 -d -D t1 -l >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t16.exp000066400000000000000000000006141415616035500155530ustar00rootroot00000000000000on: off: t1 unknown: test0: state=connected reconnects=000 actions=002 type=vpc hosts=t[0-15] on: off: t1 unknown: test0: state=connected reconnects=000 actions=003 type=vpc hosts=t[0-15] on: off: t1 unknown: test0: state=connected reconnects=000 actions=004 type=vpc hosts=t[0-15] test0: state=connected reconnects=000 actions=004 type=vpc hosts=t[0-15] t[0-15] powerman-2.3.27/test/t17000077500000000000000000000003011415616035500147550ustar00rootroot00000000000000#!/bin/sh TEST=t17 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -T -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t17.conf.in000066400000000000000000000013041415616035500163070ustar00rootroot00000000000000specification "vpc" { timeout 15.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { # noise generator # spew more than 64K (MAX_DEV_BUF) to cause cbuf wrap. # (1024 * 78 char = 78K) send "spew 1024\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t17.exp000066400000000000000000002026721415616035500155640ustar00rootroot00000000000000send(test0): 'spew 1024\n' recv(test0): 'ghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\n1 OK\n' recv(test0): '2 vpc> ' send(test0): 'stat *\n' recv(test0): 'plug 0: OFF\n' recv(test0): 'plug 1: OFF\n' recv(test0): 'plug 2: OFF\n' recv(test0): 'plug 3: OFF\n' recv(test0): 'plug 4: OFF\n' recv(test0): 'plug 5: OFF\n' recv(test0): 'plug 6: OFF\n' recv(test0): 'plug 7: OFF\n' recv(test0): 'plug 8: OFF\n' recv(test0): 'plug 9: OFF\n' recv(test0): 'plug 10: OFF\n' recv(test0): 'plug 11: OFF\n' recv(test0): 'plug 12: OFF\n' recv(test0): 'plug 13: OFF\n' recv(test0): 'plug 14: OFF\n' recv(test0): 'plug 15: OFF\n' recv(test0): '2 OK\n' recv(test0): '3 vpc> ' on: off: t[0-15] unknown: powerman-2.3.27/test/t18000077500000000000000000000003011415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t18 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -T -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t18.conf.in000066400000000000000000000013221415616035500163100ustar00rootroot00000000000000specification "vpc" { timeout 60.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { # noise generator # spew more than twice 64K (MAX_DEV_BUF) to cause double cbuf wrap. # (1900 * 78 char = 144K) send "spew 1900\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t18.exp000066400000000000000000002026721415616035500155650ustar00rootroot00000000000000send(test0): 'spew 1900\n' recv(test0): 'yzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\nCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzAB\nDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABC\nEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCD\nFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDE\nGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEF\nHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFG\nIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGH\nJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHI\nKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJ\nLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJK\nMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL\nNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM\nOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN\nPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO\nQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOP\nRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQ\nSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR\nTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS\nUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST\nVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU\nWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV\nXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW\nYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX\nZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXY\n0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0\n23456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01\n3456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012\n456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123\n56789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234\n6789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345\n789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456\n89!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567\n9!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678\n!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\n@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\n#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@\n$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#\n%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$\n^&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%\n&*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\n*()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&\n()-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*\n)-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(\n-_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()\n_=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-\n=+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_\n+[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=\n[]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\n]abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[\nabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]\nbcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]a\ncdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]ab\ndefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abc\nefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcd\nfghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcde\nghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdef\nhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefg\nijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefgh\njklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghi\nklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghij\nlmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijk\nmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijkl\nnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklm\nopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmn\npqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmno\nqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnop\nrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopq\nstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqr\ntuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrs\nuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrst\nvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstu\nwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuv\nxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvw\nyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwx\nzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxy\nABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyz\nBCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]abcdefghijklmnopqrstuvwxyzA\n1 OK\n' recv(test0): '2 vpc> ' send(test0): 'stat *\n' recv(test0): 'plug 0: OFF\n' recv(test0): 'plug 1: OFF\n' recv(test0): 'plug 2: OFF\n' recv(test0): 'plug 3: OFF\n' recv(test0): 'plug 4: OFF\n' recv(test0): 'plug 5: OFF\n' recv(test0): 'plug 6: OFF\n' recv(test0): 'plug 7: OFF\n' recv(test0): 'plug 8: OFF\n' recv(test0): 'plug 9: OFF\n' recv(test0): 'plug 10: OFF\n' recv(test0): 'plug 11: OFF\n' recv(test0): 'plug 12: OFF\n' recv(test0): 'plug 13: OFF\n' recv(test0): 'plug 14: OFF\n' recv(test0): 'plug 15: OFF\n' recv(test0): '2 OK\n' recv(test0): '3 vpc> ' on: off: t[0-15] unknown: powerman-2.3.27/test/t19000077500000000000000000000003011415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t19 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -I -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t19.conf.in000066400000000000000000000006651415616035500163220ustar00rootroot00000000000000specification "vpc" { timeout 2.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } # Hacked not to work script status_all { send "stat *\n" expect "WONTGETTHIS" } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t19.exp000066400000000000000000000001671415616035500155610ustar00rootroot00000000000000test0: action timed out waiting for expected response on: off: unknown: t[0-15] Query completed with errors powerman-2.3.27/test/t20000077500000000000000000000003271415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t20 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -I -Q t[14-18] -Q t[16-31] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t20.conf.in000066400000000000000000000021111415616035500162760ustar00rootroot00000000000000specification "vpc" { timeout 2.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } # Hacked not to work script status_all { send "stat *\n" expect "WONTGETTHIS" } } specification "vpc2" { timeout 2.0 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script logout { send "logoff\n" expect "[0-9]* OK\n" } script status_all { send "stat *\n" foreachplug { expect "plug ([0-9]+): (ON|OFF)\n" setplugstate $1 $2 on="ON" off="OFF" } expect "[0-9]* OK\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" device "test1" "vpc2" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" node "t[16-31]" "test1" powerman-2.3.27/test/t20.exp000066400000000000000000000002461415616035500155470ustar00rootroot00000000000000test0: action timed out waiting for expected response on: off: t[16-18] unknown: t[14-15] Query completed with errors on: off: t[16-31] unknown: powerman-2.3.27/test/t21000077500000000000000000000004631415616035500147610ustar00rootroot00000000000000#!/bin/sh TEST=t21 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0,t8 \ -q -c t0,t8 \ -q -0 t0,t8 \ -q -1 t[0-15] \ -q -c t[0-15] \ -q -0 t[0-15] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t21.conf.in000066400000000000000000000003521415616035500163040ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech-rpc3-nc.dev" device "b0" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b1" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" node "t[0-7]" "b0" node "t[8-15]" "b1" powerman-2.3.27/test/t21.exp000066400000000000000000000007211415616035500155460ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t[0,8] off: t[1-7,9-15] unknown: Command completed successfully on: t[0,8] off: t[1-7,9-15] unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: off: t[0-15] unknown: powerman-2.3.27/test/t22000077500000000000000000000007001415616035500147540ustar00rootroot00000000000000#!/bin/sh TEST=t22 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -c t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -0 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -1 t[0-127] \ -q -c t[0-127] \ -q -0 t[0-127] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t22.conf.in000066400000000000000000000030631415616035500163070ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech-rpc3-nc.dev" device "b0" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b1" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b2" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b3" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b4" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b5" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b6" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b7" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-nc |&" device "b8" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b9" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b10" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b11" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b12" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b13" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b14" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" device "b15" "baytech-rpc3-nc" "@top_builddir@/test/baytech -p rpc3-de |&" node "t[0-7]" "b0" node "t[8-15]" "b1" node "t[16-23]" "b2" node "t[24-31]" "b3" node "t[32-39]" "b4" node "t[40-47]" "b5" node "t[48-55]" "b6" node "t[56-63]" "b7" node "t[64-71]" "b8" node "t[72-79]" "b9" node "t[80-87]" "b10" node "t[88-95]" "b11" node "t[96-103]" "b12" node "t[104-111]" "b13" node "t[112-119]" "b14" node "t[120-127]" "b15" powerman-2.3.27/test/t22.exp000066400000000000000000000013461415616035500155530ustar00rootroot00000000000000on: off: t[0-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: off: t[0-127] unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: off: t[0-127] unknown: powerman-2.3.27/test/t23000077500000000000000000000004521415616035500147610ustar00rootroot00000000000000#!/bin/sh TEST=t23 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-19] \ -q -c t[0-19] \ -q -0 t[0-19] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t23.conf.in000066400000000000000000000002201415616035500163000ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech-rpc28-nc.dev" device "b0" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" node "t[0-19]" "b0" powerman-2.3.27/test/t23.exp000066400000000000000000000007011415616035500155460ustar00rootroot00000000000000on: off: t[0-19] unknown: Command completed successfully on: t0 off: t[1-19] unknown: Command completed successfully on: t0 off: t[1-19] unknown: Command completed successfully on: off: t[0-19] unknown: Command completed successfully on: t[0-19] off: unknown: Command completed successfully on: t[0-19] off: unknown: Command completed successfully on: off: t[0-19] unknown: powerman-2.3.27/test/t24000077500000000000000000000005731415616035500147660ustar00rootroot00000000000000#!/bin/sh TEST=t24 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,20,40,60,80,100,120,140] \ -q -c t[0,20,40,60,80,100,120,140] \ -q -0 t[0,20,40,60,80,100,120,140] \ -q -1 t[0-159] \ -q -c t[0-159] \ -q -0 t[0-159] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t24.conf.in000066400000000000000000000014771415616035500163200ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech-rpc28-nc.dev" device "b0" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b1" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b2" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b3" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b4" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b5" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b6" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" device "b7" "baytech-rpc28-nc" "@top_builddir@/test/baytech -p rpc28-nc |&" node "t[0-19]" "b0" node "t[20-39]" "b1" node "t[40-59]" "b2" node "t[60-79]" "b3" node "t[80-99]" "b4" node "t[100-119]" "b5" node "t[120-139]" "b6" node "t[140-159]" "b7" powerman-2.3.27/test/t24.exp000066400000000000000000000011321415616035500155460ustar00rootroot00000000000000on: off: t[0-159] unknown: Command completed successfully on: t[0,20,40,60,80,100,120,140] off: t[1-19,21-39,41-59,61-79,81-99,101-119,121-139,141-159] unknown: Command completed successfully on: t[0,20,40,60,80,100,120,140] off: t[1-19,21-39,41-59,61-79,81-99,101-119,121-139,141-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: off: t[0-159] unknown: powerman-2.3.27/test/t25000077500000000000000000000021731415616035500147650ustar00rootroot00000000000000#!/bin/sh TEST=t25 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t25.conf.in000066400000000000000000000005211415616035500163060ustar00rootroot00000000000000specification "vpc" { # reduced timeout timeout 2 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script cycle { delay 0.01 } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t25.exp000066400000000000000000000076001415616035500155550ustar00rootroot00000000000000Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully powerman-2.3.27/test/t26000077500000000000000000000021731415616035500147660ustar00rootroot00000000000000#!/bin/sh TEST=t26 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ -c t1 -c t1 -c t1 -c t1 \ >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t26.conf.in000066400000000000000000000005431415616035500163130ustar00rootroot00000000000000specification "vpc" { timeout 2 plug name { "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" "12" "13" "14" "15" } script login { send "login\n" expect "[0-9]* OK\n" expect "[0-9]* vpc> " } script cycle { delay 0.01 send "\n" expect "[0-9]* vpc> " } } device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t26.exp000066400000000000000000000076001415616035500155560ustar00rootroot00000000000000Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully Command completed successfully powerman-2.3.27/test/t27000077500000000000000000000004471415616035500147710ustar00rootroot00000000000000#!/bin/sh TEST=t27 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-7] \ -q -c t[0-7] \ -q -0 t[0-7] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t27.conf.in000066400000000000000000000001711415616035500163110ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech.dev" device "b0" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" node "t[0-7]" "b0" powerman-2.3.27/test/t27.exp000066400000000000000000000006721415616035500155610ustar00rootroot00000000000000on: off: t[0-7] unknown: Command completed successfully on: t0 off: t[1-7] unknown: Command completed successfully on: t0 off: t[1-7] unknown: Command completed successfully on: off: t[0-7] unknown: Command completed successfully on: t[0-7] off: unknown: Command completed successfully on: t[0-7] off: unknown: Command completed successfully on: off: t[0-7] unknown: powerman-2.3.27/test/t28000077500000000000000000000007001415616035500147620ustar00rootroot00000000000000#!/bin/sh TEST=t28 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -c t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -0 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -1 t[0-127] \ -q -c t[0-127] \ -q -0 t[0-127] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t28.conf.in000066400000000000000000000025731415616035500163220ustar00rootroot00000000000000include "@top_srcdir@/etc/baytech.dev" device "b0" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b1" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b2" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b3" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b4" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b5" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b6" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b7" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b8" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b9" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b10" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b11" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b12" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b13" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b14" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" device "b15" "baytech" "@top_builddir@/test/baytech -p rpc3 |&" node "t[0-7]" "b0" node "t[8-15]" "b1" node "t[16-23]" "b2" node "t[24-31]" "b3" node "t[32-39]" "b4" node "t[40-47]" "b5" node "t[48-55]" "b6" node "t[56-63]" "b7" node "t[64-71]" "b8" node "t[72-79]" "b9" node "t[80-87]" "b10" node "t[88-95]" "b11" node "t[96-103]" "b12" node "t[104-111]" "b13" node "t[112-119]" "b14" node "t[120-127]" "b15" powerman-2.3.27/test/t28.exp000066400000000000000000000013461415616035500155610ustar00rootroot00000000000000on: off: t[0-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: off: t[0-127] unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: off: t[0-127] unknown: powerman-2.3.27/test/t29000077500000000000000000000005611415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t29 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-9] \ -q -c t[0-9] \ -q -0 t[0-9] \ -b -f t0 \ -b -u t0 \ -b -f t[0-9] \ -b -u t[0-9] \ -b -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t29.conf.in000066400000000000000000000001661415616035500163170ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox3.dev" device "i0" "icebox3" "@top_builddir@/test/icebox -p v3 |&" node "t[0-9]" "i0" powerman-2.3.27/test/t29.exp000066400000000000000000000014741415616035500155640ustar00rootroot00000000000000on: off: t[0-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: off: t[0-9] unknown: on: off: t[0-9] unknown: t0: 73: t1: 74: t2: 75: t3: 76: t4: 77: t5: 78: t6: 79: t7: 80: t8: 81: t9: 82: powerman-2.3.27/test/t30000077500000000000000000000012041415616035500147530ustar00rootroot00000000000000#!/bin/sh TEST=t30 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -c t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -0 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -1 t[0-159] \ -q -c t[0-159] \ -q -0 t[0-159] \ -b -f t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -b -u t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -b -f t[0-159] \ -q -u t[0-159] \ -b -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t30.conf.in000066400000000000000000000025201415616035500163030ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox3.dev" device "i0" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i1" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i2" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i3" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i4" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i5" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i6" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i7" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i8" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i9" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i10" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i11" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i12" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i13" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i14" "icebox3" "@top_builddir@/test/icebox -p v3 |&" device "i15" "icebox3" "@top_builddir@/test/icebox -p v3 |&" node "t[0-9]" "i0" node "t[10-19]" "i1" node "t[20-29]" "i2" node "t[30-39]" "i3" node "t[40-49]" "i4" node "t[50-59]" "i5" node "t[60-69]" "i6" node "t[70-79]" "i7" node "t[80-89]" "i8" node "t[90-99]" "i9" node "t[100-109]" "i10" node "t[110-119]" "i11" node "t[120-129]" "i12" node "t[130-139]" "i13" node "t[140-149]" "i14" node "t[150-159]" "i15" powerman-2.3.27/test/t30.exp000066400000000000000000000052411415616035500155500ustar00rootroot00000000000000on: off: t[0-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: off: t[0-159] unknown: on: off: t[0-159] unknown: t0: 73: t1: 74: t2: 75: t3: 76: t4: 77: t5: 78: t6: 79: t7: 80: t8: 81: t9: 82: t10: 73: t11: 74: t12: 75: t13: 76: t14: 77: t15: 78: t16: 79: t17: 80: t18: 81: t19: 82: t20: 73: t21: 74: t22: 75: t23: 76: t24: 77: t25: 78: t26: 79: t27: 80: t28: 81: t29: 82: t30: 73: t31: 74: t32: 75: t33: 76: t34: 77: t35: 78: t36: 79: t37: 80: t38: 81: t39: 82: t40: 73: t41: 74: t42: 75: t43: 76: t44: 77: t45: 78: t46: 79: t47: 80: t48: 81: t49: 82: t50: 73: t51: 74: t52: 75: t53: 76: t54: 77: t55: 78: t56: 79: t57: 80: t58: 81: t59: 82: t60: 73: t61: 74: t62: 75: t63: 76: t64: 77: t65: 78: t66: 79: t67: 80: t68: 81: t69: 82: t70: 73: t71: 74: t72: 75: t73: 76: t74: 77: t75: 78: t76: 79: t77: 80: t78: 81: t79: 82: t80: 73: t81: 74: t82: 75: t83: 76: t84: 77: t85: 78: t86: 79: t87: 80: t88: 81: t89: 82: t90: 73: t91: 74: t92: 75: t93: 76: t94: 77: t95: 78: t96: 79: t97: 80: t98: 81: t99: 82: t100: 73: t101: 74: t102: 75: t103: 76: t104: 77: t105: 78: t106: 79: t107: 80: t108: 81: t109: 82: t110: 73: t111: 74: t112: 75: t113: 76: t114: 77: t115: 78: t116: 79: t117: 80: t118: 81: t119: 82: t120: 73: t121: 74: t122: 75: t123: 76: t124: 77: t125: 78: t126: 79: t127: 80: t128: 81: t129: 82: t130: 73: t131: 74: t132: 75: t133: 76: t134: 77: t135: 78: t136: 79: t137: 80: t138: 81: t139: 82: t140: 73: t141: 74: t142: 75: t143: 76: t144: 77: t145: 78: t146: 79: t147: 80: t148: 81: t149: 82: t150: 73: t151: 74: t152: 75: t153: 76: t154: 77: t155: 78: t156: 79: t157: 80: t158: 81: t159: 82: powerman-2.3.27/test/t31000077500000000000000000000004521415616035500147600ustar00rootroot00000000000000#!/bin/sh TEST=t31 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-9] \ -q -c t[0-9] \ -q -0 t[0-9] \ -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t31.conf.in000066400000000000000000000001641415616035500163060ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox.dev" device "i0" "icebox" "@top_builddir@/test/icebox -p v2 |&" node "t[0-9]" "i0" powerman-2.3.27/test/t31.exp000066400000000000000000000010741415616035500155510ustar00rootroot00000000000000on: off: t[0-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: off: t[0-9] unknown: t0: 73,0,0,0 t1: 74,0,0,0 t2: 75,0,0,0 t3: 76,0,0,0 t4: 77,0,0,0 t5: 78,0,0,0 t6: 79,0,0,0 t7: 80,0,0,0 t8: 81,0,0,0 t9: 82,0,0,0 powerman-2.3.27/test/t32000077500000000000000000000007171415616035500147650ustar00rootroot00000000000000#!/bin/sh TEST=t32 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -c t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -0 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -1 t[0-159] \ -q -c t[0-159] \ -q -0 t[0-159] \ -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t32.conf.in000066400000000000000000000024771415616035500163200ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox.dev" device "i0" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i1" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i2" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i3" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i4" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i5" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i6" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i7" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i8" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i9" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i10" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i11" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i12" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i13" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i14" "icebox" "@top_builddir@/test/icebox -p v2 |&" device "i15" "icebox" "@top_builddir@/test/icebox -p v2 |&" node "t[0-9]" "i0" node "t[10-19]" "i1" node "t[20-29]" "i2" node "t[30-39]" "i3" node "t[40-49]" "i4" node "t[50-59]" "i5" node "t[60-69]" "i6" node "t[70-79]" "i7" node "t[80-89]" "i8" node "t[90-99]" "i9" node "t[100-109]" "i10" node "t[110-119]" "i11" node "t[120-129]" "i12" node "t[130-139]" "i13" node "t[140-149]" "i14" node "t[150-159]" "i15" powerman-2.3.27/test/t32.exp000066400000000000000000000057541415616035500155630ustar00rootroot00000000000000on: off: t[0-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: off: t[0-159] unknown: t0: 73,0,0,0 t1: 74,0,0,0 t2: 75,0,0,0 t3: 76,0,0,0 t4: 77,0,0,0 t5: 78,0,0,0 t6: 79,0,0,0 t7: 80,0,0,0 t8: 81,0,0,0 t9: 82,0,0,0 t10: 73,0,0,0 t11: 74,0,0,0 t12: 75,0,0,0 t13: 76,0,0,0 t14: 77,0,0,0 t15: 78,0,0,0 t16: 79,0,0,0 t17: 80,0,0,0 t18: 81,0,0,0 t19: 82,0,0,0 t20: 73,0,0,0 t21: 74,0,0,0 t22: 75,0,0,0 t23: 76,0,0,0 t24: 77,0,0,0 t25: 78,0,0,0 t26: 79,0,0,0 t27: 80,0,0,0 t28: 81,0,0,0 t29: 82,0,0,0 t30: 73,0,0,0 t31: 74,0,0,0 t32: 75,0,0,0 t33: 76,0,0,0 t34: 77,0,0,0 t35: 78,0,0,0 t36: 79,0,0,0 t37: 80,0,0,0 t38: 81,0,0,0 t39: 82,0,0,0 t40: 73,0,0,0 t41: 74,0,0,0 t42: 75,0,0,0 t43: 76,0,0,0 t44: 77,0,0,0 t45: 78,0,0,0 t46: 79,0,0,0 t47: 80,0,0,0 t48: 81,0,0,0 t49: 82,0,0,0 t50: 73,0,0,0 t51: 74,0,0,0 t52: 75,0,0,0 t53: 76,0,0,0 t54: 77,0,0,0 t55: 78,0,0,0 t56: 79,0,0,0 t57: 80,0,0,0 t58: 81,0,0,0 t59: 82,0,0,0 t60: 73,0,0,0 t61: 74,0,0,0 t62: 75,0,0,0 t63: 76,0,0,0 t64: 77,0,0,0 t65: 78,0,0,0 t66: 79,0,0,0 t67: 80,0,0,0 t68: 81,0,0,0 t69: 82,0,0,0 t70: 73,0,0,0 t71: 74,0,0,0 t72: 75,0,0,0 t73: 76,0,0,0 t74: 77,0,0,0 t75: 78,0,0,0 t76: 79,0,0,0 t77: 80,0,0,0 t78: 81,0,0,0 t79: 82,0,0,0 t80: 73,0,0,0 t81: 74,0,0,0 t82: 75,0,0,0 t83: 76,0,0,0 t84: 77,0,0,0 t85: 78,0,0,0 t86: 79,0,0,0 t87: 80,0,0,0 t88: 81,0,0,0 t89: 82,0,0,0 t90: 73,0,0,0 t91: 74,0,0,0 t92: 75,0,0,0 t93: 76,0,0,0 t94: 77,0,0,0 t95: 78,0,0,0 t96: 79,0,0,0 t97: 80,0,0,0 t98: 81,0,0,0 t99: 82,0,0,0 t100: 73,0,0,0 t101: 74,0,0,0 t102: 75,0,0,0 t103: 76,0,0,0 t104: 77,0,0,0 t105: 78,0,0,0 t106: 79,0,0,0 t107: 80,0,0,0 t108: 81,0,0,0 t109: 82,0,0,0 t110: 73,0,0,0 t111: 74,0,0,0 t112: 75,0,0,0 t113: 76,0,0,0 t114: 77,0,0,0 t115: 78,0,0,0 t116: 79,0,0,0 t117: 80,0,0,0 t118: 81,0,0,0 t119: 82,0,0,0 t120: 73,0,0,0 t121: 74,0,0,0 t122: 75,0,0,0 t123: 76,0,0,0 t124: 77,0,0,0 t125: 78,0,0,0 t126: 79,0,0,0 t127: 80,0,0,0 t128: 81,0,0,0 t129: 82,0,0,0 t130: 73,0,0,0 t131: 74,0,0,0 t132: 75,0,0,0 t133: 76,0,0,0 t134: 77,0,0,0 t135: 78,0,0,0 t136: 79,0,0,0 t137: 80,0,0,0 t138: 81,0,0,0 t139: 82,0,0,0 t140: 73,0,0,0 t141: 74,0,0,0 t142: 75,0,0,0 t143: 76,0,0,0 t144: 77,0,0,0 t145: 78,0,0,0 t146: 79,0,0,0 t147: 80,0,0,0 t148: 81,0,0,0 t149: 82,0,0,0 t150: 73,0,0,0 t151: 74,0,0,0 t152: 75,0,0,0 t153: 76,0,0,0 t154: 77,0,0,0 t155: 78,0,0,0 t156: 79,0,0,0 t157: 80,0,0,0 t158: 81,0,0,0 t159: 82,0,0,0 powerman-2.3.27/test/t33000077500000000000000000000005611415616035500147630ustar00rootroot00000000000000#!/bin/sh TEST=t33 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-9] \ -q -c t[0-9] \ -q -0 t[0-9] \ -b -f t0 \ -b -u t0 \ -b -f t[0-9] \ -b -u t[0-9] \ -b -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t33.conf.in000066400000000000000000000001661415616035500163120ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox3.dev" device "i0" "icebox3" "@top_builddir@/test/icebox -p v4 |&" node "t[0-9]" "i0" powerman-2.3.27/test/t33.exp000066400000000000000000000014741415616035500155570ustar00rootroot00000000000000on: off: t[0-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t0 off: t[1-9] unknown: Command completed successfully on: off: t[0-9] unknown: Command completed successfully on: t[0-9] off: unknown: Command completed successfully on: off: t[0-9] unknown: on: off: t[0-9] unknown: t0: 73: t1: 74: t2: 75: t3: 76: t4: 77: t5: 78: t6: 79: t7: 80: t8: 81: t9: 82: powerman-2.3.27/test/t34000077500000000000000000000012041415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t34 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -c t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -0 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -q -1 t[0-159] \ -q -c t[0-159] \ -q -0 t[0-159] \ -b -f t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -b -u t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] \ -b -f t[0-159] \ -b -u t[0-159] \ -b -q -t >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t34.conf.in000066400000000000000000000025201415616035500163070ustar00rootroot00000000000000include "@top_srcdir@/etc/icebox3.dev" device "i0" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i1" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i2" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i3" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i4" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i5" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i6" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i7" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i8" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i9" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i10" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i11" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i12" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i13" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i14" "icebox3" "@top_builddir@/test/icebox -p v4 |&" device "i15" "icebox3" "@top_builddir@/test/icebox -p v4 |&" node "t[0-9]" "i0" node "t[10-19]" "i1" node "t[20-29]" "i2" node "t[30-39]" "i3" node "t[40-49]" "i4" node "t[50-59]" "i5" node "t[60-69]" "i6" node "t[70-79]" "i7" node "t[80-89]" "i8" node "t[90-99]" "i9" node "t[100-109]" "i10" node "t[110-119]" "i11" node "t[120-129]" "i12" node "t[130-139]" "i13" node "t[140-149]" "i14" node "t[150-159]" "i15" powerman-2.3.27/test/t34.exp000066400000000000000000000052411415616035500155540ustar00rootroot00000000000000on: off: t[0-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149,151-159] unknown: Command completed successfully on: off: t[0-159] unknown: Command completed successfully on: t[0-159] off: unknown: Command completed successfully on: off: t[0-159] unknown: on: off: t[0-159] unknown: t0: 73: t1: 74: t2: 75: t3: 76: t4: 77: t5: 78: t6: 79: t7: 80: t8: 81: t9: 82: t10: 73: t11: 74: t12: 75: t13: 76: t14: 77: t15: 78: t16: 79: t17: 80: t18: 81: t19: 82: t20: 73: t21: 74: t22: 75: t23: 76: t24: 77: t25: 78: t26: 79: t27: 80: t28: 81: t29: 82: t30: 73: t31: 74: t32: 75: t33: 76: t34: 77: t35: 78: t36: 79: t37: 80: t38: 81: t39: 82: t40: 73: t41: 74: t42: 75: t43: 76: t44: 77: t45: 78: t46: 79: t47: 80: t48: 81: t49: 82: t50: 73: t51: 74: t52: 75: t53: 76: t54: 77: t55: 78: t56: 79: t57: 80: t58: 81: t59: 82: t60: 73: t61: 74: t62: 75: t63: 76: t64: 77: t65: 78: t66: 79: t67: 80: t68: 81: t69: 82: t70: 73: t71: 74: t72: 75: t73: 76: t74: 77: t75: 78: t76: 79: t77: 80: t78: 81: t79: 82: t80: 73: t81: 74: t82: 75: t83: 76: t84: 77: t85: 78: t86: 79: t87: 80: t88: 81: t89: 82: t90: 73: t91: 74: t92: 75: t93: 76: t94: 77: t95: 78: t96: 79: t97: 80: t98: 81: t99: 82: t100: 73: t101: 74: t102: 75: t103: 76: t104: 77: t105: 78: t106: 79: t107: 80: t108: 81: t109: 82: t110: 73: t111: 74: t112: 75: t113: 76: t114: 77: t115: 78: t116: 79: t117: 80: t118: 81: t119: 82: t120: 73: t121: 74: t122: 75: t123: 76: t124: 77: t125: 78: t126: 79: t127: 80: t128: 81: t129: 82: t130: 73: t131: 74: t132: 75: t133: 76: t134: 77: t135: 78: t136: 79: t137: 80: t138: 81: t139: 82: t140: 73: t141: 74: t142: 75: t143: 76: t144: 77: t145: 78: t146: 79: t147: 80: t148: 81: t149: 82: t150: 73: t151: 74: t152: 75: t153: 76: t154: 77: t155: 78: t156: 79: t157: 80: t158: 81: t159: 82: powerman-2.3.27/test/t35000077500000000000000000000006451415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t35 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8,16,24,32,40,48,56] \ -q -c t[0,8,16,24,32,40,48,56] \ -q -0 t[0,8,16,24,32,40,48,56] \ -q -r t[0,8,16,24,32,40,48,56] \ -q -1 t[0-63] \ -q -c t[0-63] \ -q -0 t[0-63] \ -q -r t[0-63] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t35.conf.in000066400000000000000000000002451415616035500163120ustar00rootroot00000000000000include "@top_srcdir@/etc/powerman.dev" device "p0" "powerman" "@top_builddir@/powermand/powermand -f -c @top_builddir@/test/test4.conf -s |&" node "t[0-63]" "p0" powerman-2.3.27/test/t35.exp000066400000000000000000000013051415616035500155520ustar00rootroot00000000000000on: off: t[0-63] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63] unknown: Command completed successfully on: off: t[0-63] unknown: Command completed successfully on: off: t[0-63] unknown: Command completed successfully on: t[0-63] off: unknown: Command completed successfully on: t[0-63] off: unknown: Command completed successfully on: off: t[0-63] unknown: Command completed successfully on: off: t[0-63] unknown: powerman-2.3.27/test/t36000077500000000000000000000005651415616035500147720ustar00rootroot00000000000000#!/bin/sh TEST=t36 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 x[0,8,16,24] \ -q -c x[0,8,16,24] \ -q -0 x[0,8,16,24] \ -q -r x[0,8,16,24] \ -q -1 x[0-31] \ -q -c x[0-31] \ -q -0 x[0-31] \ -q -r x[0-31] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t36.conf.in000066400000000000000000000002551415616035500163140ustar00rootroot00000000000000include "@top_srcdir@/etc/powerman.dev" device "p0" "powerman" "@top_builddir@/powermand/powermand -f -c @top_builddir@/test/test4.conf -s |&" node "x[0-63]" "p0" "t[0-63]" powerman-2.3.27/test/t36.exp000066400000000000000000000012151415616035500155530ustar00rootroot00000000000000on: off: x[0-63] unknown: Command completed successfully on: x[0,8,16,24] off: x[1-7,9-15,17-23,25-63] unknown: Command completed successfully on: x[0,8,16,24] off: x[1-7,9-15,17-23,25-63] unknown: Command completed successfully on: off: x[0-63] unknown: Command completed successfully on: off: x[0-63] unknown: Command completed successfully on: x[0-31] off: x[32-63] unknown: Command completed successfully on: x[0-31] off: x[32-63] unknown: Command completed successfully on: off: x[0-63] unknown: Command completed successfully on: off: x[0-63] unknown: powerman-2.3.27/test/t37000077500000000000000000000004521415616035500147660ustar00rootroot00000000000000#!/bin/sh TEST=t37 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-19] \ -q -c t[0-19] \ -q -0 t[0-19] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t37.conf.in000066400000000000000000000002451415616035500163140ustar00rootroot00000000000000include "@top_srcdir@/etc/hp3488.dev" device "h0" "hp3488" "@top_builddir@/test/gpib -p hp3488|&" node "t[0-9]" "h0" "[100-109]" node "t[10-19]" "h0" "[200-209]" powerman-2.3.27/test/t37.exp000066400000000000000000000007011415616035500155530ustar00rootroot00000000000000on: off: t[0-19] unknown: Command completed successfully on: t0 off: t[1-19] unknown: Command completed successfully on: t0 off: t[1-19] unknown: Command completed successfully on: off: t[0-19] unknown: Command completed successfully on: t[0-19] off: unknown: Command completed successfully on: t[0-19] off: unknown: Command completed successfully on: off: t[0-19] unknown: powerman-2.3.27/test/t38000077500000000000000000000007001415616035500147630ustar00rootroot00000000000000#!/bin/sh TEST=t38 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140] \ -q -c t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140] \ -q -0 t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140] \ -q -1 t[0-149] \ -q -c t[0-149] \ -q -0 t[0-149] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t38.conf.in000066400000000000000000000013311415616035500163120ustar00rootroot00000000000000include "@top_srcdir@/etc/hp3488.dev" device "h0" "hp3488" "@top_builddir@/test/gpib -p hp3488|&" device "h1" "hp3488" "@top_builddir@/test/gpib -p hp3488|&" device "h2" "hp3488" "@top_builddir@/test/gpib -p hp3488|&" node "t[0-9]" "h0" "[100-109]" node "t[10-19]" "h0" "[200-209]" node "t[20-29]" "h0" "[300-309]" node "t[30-39]" "h0" "[400-409]" node "t[40-49]" "h0" "[500-509]" node "t[50-59]" "h1" "[100-109]" node "t[60-69]" "h1" "[200-209]" node "t[70-79]" "h1" "[300-309]" node "t[80-89]" "h1" "[400-409]" node "t[90-99]" "h1" "[500-509]" node "t[100-109]" "h2" "[100-109]" node "t[110-119]" "h2" "[200-209]" node "t[120-129]" "h2" "[300-309]" node "t[130-139]" "h2" "[400-409]" node "t[140-149]" "h2" "[500-509]" powerman-2.3.27/test/t38.exp000066400000000000000000000013421415616035500155560ustar00rootroot00000000000000on: off: t[0-149] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149] unknown: Command completed successfully on: t[0,10,20,30,40,50,60,70,80,90,100,110,120,130,140] off: t[1-9,11-19,21-29,31-39,41-49,51-59,61-69,71-79,81-89,91-99,101-109,111-119,121-129,131-139,141-149] unknown: Command completed successfully on: off: t[0-149] unknown: Command completed successfully on: t[0-149] off: unknown: Command completed successfully on: t[0-149] off: unknown: Command completed successfully on: off: t[0-149] unknown: powerman-2.3.27/test/t39000077500000000000000000000004521415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t39 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-15] \ -q -c t[0-15] \ -q -0 t[0-15] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t39.conf.in000066400000000000000000000001721415616035500163150ustar00rootroot00000000000000include "@top_srcdir@/etc/ics8064.dev" device "i0" "ics8064" "@top_builddir@/test/gpib -p ics8064|&" node "t[0-15]" "i0" powerman-2.3.27/test/t39.exp000066400000000000000000000007011415616035500155550ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t0 off: t[1-15] unknown: Command completed successfully on: t0 off: t[1-15] unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: off: t[0-15] unknown: powerman-2.3.27/test/t40000077500000000000000000000005131415616035500147560ustar00rootroot00000000000000#!/bin/sh TEST=t40 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,16,32,48] \ -q -c t[0,16,32,48] \ -q -0 t[0,16,32,48] \ -q -1 t[0-63] \ -q -c t[0-63] \ -q -0 t[0-63] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t40.conf.in000066400000000000000000000005631415616035500163110ustar00rootroot00000000000000include "@top_srcdir@/etc/ics8064.dev" device "i0" "ics8064" "@top_builddir@/test/gpib -p ics8064|&" device "i1" "ics8064" "@top_builddir@/test/gpib -p ics8064|&" device "i2" "ics8064" "@top_builddir@/test/gpib -p ics8064|&" device "i3" "ics8064" "@top_builddir@/test/gpib -p ics8064|&" node "t[0-15]" "i0" node "t[16-31]" "i1" node "t[32-47]" "i2" node "t[48-63]" "i3" powerman-2.3.27/test/t40.exp000066400000000000000000000007731415616035500155560ustar00rootroot00000000000000on: off: t[0-63] unknown: Command completed successfully on: t[0,16,32,48] off: t[1-15,17-31,33-47,49-63] unknown: Command completed successfully on: t[0,16,32,48] off: t[1-15,17-31,33-47,49-63] unknown: Command completed successfully on: off: t[0-63] unknown: Command completed successfully on: t[0-63] off: unknown: Command completed successfully on: t[0-63] off: unknown: Command completed successfully on: off: t[0-63] unknown: powerman-2.3.27/test/t41000077500000000000000000000004471415616035500147650ustar00rootroot00000000000000#!/bin/sh TEST=t41 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-1] \ -q -c t[0-1] \ -q -0 t[0-1] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t41.conf.in000066400000000000000000000002321415616035500163030ustar00rootroot00000000000000include "@top_srcdir@/etc/plmpower.dev" device "i0" "plmpower" "@top_builddir@/plmpower/plmpower -T |&" node "t0" "i0" "aa.bb.cc" node "t1" "i0" "G1" powerman-2.3.27/test/t41.exp000066400000000000000000000006501415616035500155510ustar00rootroot00000000000000on: off: t0 unknown: t1 Command completed successfully on: t0 off: unknown: t1 Command completed successfully on: t0 off: unknown: t1 Command completed successfully on: off: t0 unknown: t1 Command completed successfully on: t0 off: unknown: t1 Command completed successfully on: t0 off: unknown: t1 Command completed successfully on: off: t0 unknown: t1 powerman-2.3.27/test/t42000077500000000000000000000004471415616035500147660ustar00rootroot00000000000000#!/bin/sh TEST=t42 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t0 \ -q -c t0 \ -q -0 t0 \ -q -1 t[0-7] \ -q -c t[0-7] \ -q -0 t[0-7] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t42.conf.in000066400000000000000000000001451415616035500163070ustar00rootroot00000000000000include "@top_srcdir@/etc/dli.dev" device "d0" "dli" "@top_builddir@/test/dli |&" node "t[0-7]" "d0" powerman-2.3.27/test/t42.exp000066400000000000000000000006721415616035500155560ustar00rootroot00000000000000on: off: t[0-7] unknown: Command completed successfully on: t0 off: t[1-7] unknown: Command completed successfully on: t0 off: t[1-7] unknown: Command completed successfully on: off: t[0-7] unknown: Command completed successfully on: t[0-7] off: unknown: Command completed successfully on: t[0-7] off: unknown: Command completed successfully on: off: t[0-7] unknown: powerman-2.3.27/test/t43000077500000000000000000000007001415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t43 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -c t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -0 t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] \ -q -1 t[0-127] \ -q -c t[0-127] \ -q -0 t[0-127] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t43.conf.in000066400000000000000000000021671415616035500163160ustar00rootroot00000000000000include "@top_srcdir@/etc/dli.dev" device "b0" "dli" "@top_builddir@/test/dli |&" device "b1" "dli" "@top_builddir@/test/dli |&" device "b2" "dli" "@top_builddir@/test/dli |&" device "b3" "dli" "@top_builddir@/test/dli |&" device "b4" "dli" "@top_builddir@/test/dli |&" device "b5" "dli" "@top_builddir@/test/dli |&" device "b6" "dli" "@top_builddir@/test/dli |&" device "b7" "dli" "@top_builddir@/test/dli |&" device "b8" "dli" "@top_builddir@/test/dli |&" device "b9" "dli" "@top_builddir@/test/dli |&" device "b10" "dli" "@top_builddir@/test/dli |&" device "b11" "dli" "@top_builddir@/test/dli |&" device "b12" "dli" "@top_builddir@/test/dli |&" device "b13" "dli" "@top_builddir@/test/dli |&" device "b14" "dli" "@top_builddir@/test/dli |&" device "b15" "dli" "@top_builddir@/test/dli |&" node "t[0-7]" "b0" node "t[8-15]" "b1" node "t[16-23]" "b2" node "t[24-31]" "b3" node "t[32-39]" "b4" node "t[40-47]" "b5" node "t[48-55]" "b6" node "t[56-63]" "b7" node "t[64-71]" "b8" node "t[72-79]" "b9" node "t[80-87]" "b10" node "t[88-95]" "b11" node "t[96-103]" "b12" node "t[104-111]" "b13" node "t[112-119]" "b14" node "t[120-127]" "b15" powerman-2.3.27/test/t43.exp000066400000000000000000000013461415616035500155560ustar00rootroot00000000000000on: off: t[0-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: t[0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120] off: t[1-7,9-15,17-23,25-31,33-39,41-47,49-55,57-63,65-71,73-79,81-87,89-95,97-103,105-111,113-119,121-127] unknown: Command completed successfully on: off: t[0-127] unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: t[0-127] off: unknown: Command completed successfully on: off: t[0-127] unknown: powerman-2.3.27/test/t44000077500000000000000000000004401415616035500147610ustar00rootroot00000000000000#!/bin/sh TEST=t44 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0-2] \ -q -r t[0-2] \ -q -c t[0-2] \ -q -0 t[0-2] \ -q -r t[0-2] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t44.conf.in000066400000000000000000000004051415616035500163100ustar00rootroot00000000000000include "@top_srcdir@/etc/ilom.dev" device "d0" "ilom" "@top_builddir@/test/ilom -p ssh|&" device "d1" "ilom" "@top_builddir@/test/ilom -p serial|&" device "d2" "ilom" "@top_builddir@/test/ilom -p serial_loggedin|&" node "t0" "d0" node "t1" "d1" node "t2" "d2" powerman-2.3.27/test/t44.exp000066400000000000000000000005631415616035500155570ustar00rootroot00000000000000on: off: t[0-2] unknown: Command completed successfully on: t[0-2] off: unknown: Command completed successfully on: t[0-2] off: unknown: Command completed successfully on: t[0-2] off: unknown: Command completed successfully on: off: t[0-2] unknown: Command completed successfully on: off: t[0-2] unknown: powerman-2.3.27/test/t46000077500000000000000000000004771415616035500147750ustar00rootroot00000000000000#!/bin/sh TEST=t46 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8,16] \ -q -c t[0,8,16] \ -q -0 t[0,8,16] \ -q -1 t[0-57] \ -q -c t[0-57] \ -q -0 t[0-57] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t46.conf.in000066400000000000000000000007631415616035500163210ustar00rootroot00000000000000include "@top_srcdir@/etc/cyclades-pm8.dev" include "@top_srcdir@/etc/cyclades-pm10.dev" include "@top_srcdir@/etc/cyclades-pm20.dev" include "@top_srcdir@/etc/cyclades-pm42.dev" device "d0" "pm8" "@top_builddir@/test/cyclades -p pm8|&" device "d1" "pm10" "@top_builddir@/test/cyclades -p pm10|&" device "d2" "pm42" "@top_builddir@/test/cyclades -p pm42|&" device "d3" "pm20" "@top_builddir@/test/cyclades -p pm20|&" node "t[0-7]" "d0" node "t[8-15]" "d1" node "t[16-57]" "d2" node "t[58-77]" "d3" powerman-2.3.27/test/t46.exp000066400000000000000000000007631415616035500155630ustar00rootroot00000000000000on: off: t[0-77] unknown: Command completed successfully on: t[0,8,16] off: t[1-7,9-15,17-77] unknown: Command completed successfully on: t[0,8,16] off: t[1-7,9-15,17-77] unknown: Command completed successfully on: off: t[0-77] unknown: Command completed successfully on: t[0-57] off: t[58-77] unknown: Command completed successfully on: t[0-57] off: t[58-77] unknown: Command completed successfully on: off: t[0-77] unknown: powerman-2.3.27/test/t47000077500000000000000000000004171415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t47 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8] \ -q -0 t[0,8] \ -q -1 t[0-15] \ -q -0 t[0-15] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t47.conf.in000066400000000000000000000002021415616035500163060ustar00rootroot00000000000000include "@top_srcdir@/etc/ipmipower.dev" device "d0" "ipmipower" "@top_builddir@/test/ipmipower -h t[0-15]|&" node "t[0-15]" "d0" powerman-2.3.27/test/t47.exp000066400000000000000000000004771415616035500155660ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t[0,8] off: t[1-7,9-15] unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: off: t[0-15] unknown: powerman-2.3.27/test/t48000077500000000000000000000010571415616035500147720ustar00rootroot00000000000000#!/bin/sh # # All the previous tests use pty's to communicate between # client and server, server and power controller. # This one uses sockets. # TEST=t48 ${TEST_BUILDDIR}/vpcd -p 10102 & sleep 1 # -1 means handle one client connection and exit when it exits # $TEST.conf file specifies nonstandard port of 10103 $PATH_POWERMAND -c ${TEST_BUILDDIR}/$TEST.conf -f -1 2>/dev/null& sleep 1 $PATH_POWERMAN -h localhost:10103 \ -q -Q t1 -Q t[3-5] >$TEST.out 2>$TEST.err test $? = 0 || exit 1 wait; wait diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t48.conf.in000066400000000000000000000001731415616035500163160ustar00rootroot00000000000000listen "127.0.0.1:10103" include "@top_srcdir@/etc/vpc.dev" device "test0" "vpc" "127.0.0.1:10102" node "t[0-15]" "test0" powerman-2.3.27/test/t48.exp000066400000000000000000000001511415616035500155540ustar00rootroot00000000000000on: off: t[0-15] unknown: on: off: t1 unknown: on: off: t[3-5] unknown: powerman-2.3.27/test/t49000077500000000000000000000010271415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t49 $PATH_POWERMAND -c ${TEST_BUILDDIR}/$TEST.conf -f -1 2>/dev/null& sleep 1 ./cli localhost:10103 q t1 >$TEST.out 2>$TEST.err test $? = 0 || exit 1 wait $PATH_POWERMAND -c ${TEST_BUILDDIR}/$TEST.conf -f -1 2>/dev/null& sleep 1 ./cli localhost:10103 l >>$TEST.out 2>>$TEST.err test $? = 0 || exit 1 wait $PATH_POWERMAND -c ${TEST_BUILDDIR}/$TEST.conf -f -1 2>/dev/null& sleep 1 ./cli localhost:10103 1 t0 >>$TEST.out 2>>$TEST.err test $? = 0 || exit 1 wait diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t49.conf.in000066400000000000000000000002051415616035500163130ustar00rootroot00000000000000listen "0.0.0.0:10103" include "@top_srcdir@/etc/vpc.dev" device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/t49.exp000066400000000000000000000000761415616035500155630ustar00rootroot00000000000000t1: off t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14 t15 powerman-2.3.27/test/t50000077500000000000000000000003201415616035500147530ustar00rootroot00000000000000#!/bin/sh TEST=t50 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t1 -q -0 t1 -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t50.conf.in000066400000000000000000000001421415616035500163030ustar00rootroot00000000000000include "@top_srcdir@/etc/bashfun.dev" device "bf0" "bashfun" "/bin/bash |&" node "t1" "bf0" "1" powerman-2.3.27/test/t50.exp000066400000000000000000000002361415616035500155510ustar00rootroot00000000000000on: off: t1 unknown: Command completed successfully on: t1 off: unknown: Command completed successfully on: off: t1 unknown: powerman-2.3.27/test/t51000077500000000000000000000003301415616035500147550ustar00rootroot00000000000000#!/bin/sh TEST=t51 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0-2] -q -0 t[0-2] -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t51.conf.in000066400000000000000000000004001415616035500163010ustar00rootroot00000000000000include "@top_srcdir@/etc/lom.dev" device "d0" "lom" "@top_builddir@/test/lom -p ssh|&" device "d1" "lom" "@top_builddir@/test//lom -p serial|&" device "d2" "lom" "@top_builddir@/test//lom -p serial_loggedin|&" node "t0" "d0" node "t1" "d1" node "t2" "d2" powerman-2.3.27/test/t51.exp000066400000000000000000000002521415616035500155500ustar00rootroot00000000000000on: off: t[0-2] unknown: Command completed successfully on: t[0-2] off: unknown: Command completed successfully on: off: t[0-2] unknown: powerman-2.3.27/test/t52000077500000000000000000000002771415616035500147700ustar00rootroot00000000000000#!/bin/sh TEST=t52 $PATH_POWERMAN -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/sierra.conf \ -l >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t52.exp000066400000000000000000000264221415616035500155600ustar00rootroot00000000000000chassis100a,chassis100b,chassis101a,chassis101b,chassis102a,chassis102b,chassis103a,chassis103b,chassis104a,chassis104b,chassis105a,chassis105b,chassis106a,chassis106b,chassis107a,chassis107b,chassis108a,chassis108b,chassis109a,chassis109b,chassis10a,chassis10b,chassis110a,chassis110b,chassis111a,chassis111b,chassis112a,chassis112b,chassis113a,chassis113b,chassis114a,chassis114b,chassis115a,chassis115b,chassis116a,chassis116b,chassis117a,chassis117b,chassis118a,chassis118b,chassis119a,chassis119b,chassis11a,chassis11b,chassis120a,chassis120b,chassis121a,chassis121b,chassis122a,chassis122b,chassis123a,chassis123b,chassis124a,chassis124b,chassis125a,chassis125b,chassis126a,chassis126b,chassis127a,chassis127b,chassis128a,chassis128b,chassis129a,chassis129b,chassis12a,chassis12b,chassis130a,chassis130b,chassis131a,chassis131b,chassis132a,chassis132b,chassis133a,chassis133b,chassis134a,chassis134b,chassis135a,chassis135b,chassis136a,chassis136b,chassis137a,chassis137b,chassis138a,chassis138b,chassis139a,chassis139b,chassis13a,chassis13b,chassis140a,chassis140b,chassis141a,chassis141b,chassis142a,chassis142b,chassis143a,chassis143b,chassis144a,chassis144b,chassis145a,chassis145b,chassis146a,chassis146b,chassis147a,chassis147b,chassis148a,chassis148b,chassis149a,chassis149b,chassis14a,chassis14b,chassis150a,chassis150b,chassis151a,chassis151b,chassis152a,chassis152b,chassis153a,chassis153b,chassis154a,chassis154b,chassis155a,chassis155b,chassis156a,chassis156b,chassis157a,chassis157b,chassis158a,chassis158b,chassis159a,chassis159b,chassis15a,chassis15b,chassis160a,chassis160b,chassis161a,chassis161b,chassis162a,chassis162b,chassis163a,chassis163b,chassis164a,chassis164b,chassis165a,chassis165b,chassis166a,chassis166b,chassis167a,chassis167b,chassis168a,chassis168b,chassis169a,chassis169b,chassis16a,chassis16b,chassis170a,chassis170b,chassis171a,chassis171b,chassis172a,chassis172b,chassis173a,chassis173b,chassis174a,chassis174b,chassis175a,chassis175b,chassis176a,chassis176b,chassis177a,chassis177b,chassis178a,chassis178b,chassis179a,chassis179b,chassis17a,chassis17b,chassis180a,chassis180b,chassis181a,chassis181b,chassis182a,chassis182b,chassis183a,chassis183b,chassis184a,chassis184b,chassis185a,chassis185b,chassis186a,chassis186b,chassis187a,chassis187b,chassis188a,chassis188b,chassis189a,chassis189b,chassis18a,chassis18b,chassis190a,chassis190b,chassis191a,chassis191b,chassis192a,chassis192b,chassis193a,chassis193b,chassis194a,chassis194b,chassis195a,chassis195b,chassis196a,chassis196b,chassis197a,chassis197b,chassis198a,chassis198b,chassis199a,chassis199b,chassis19a,chassis19b,chassis1a,chassis1b,chassis200a,chassis200b,chassis201a,chassis201b,chassis202a,chassis202b,chassis203a,chassis203b,chassis204a,chassis204b,chassis205a,chassis205b,chassis206a,chassis206b,chassis207a,chassis207b,chassis208a,chassis208b,chassis209a,chassis209b,chassis20a,chassis20b,chassis210a,chassis210b,chassis211a,chassis211b,chassis212a,chassis212b,chassis213a,chassis213b,chassis214a,chassis214b,chassis215a,chassis215b,chassis216a,chassis216b,chassis217a,chassis217b,chassis218a,chassis218b,chassis219a,chassis219b,chassis21a,chassis21b,chassis220a,chassis220b,chassis221a,chassis221b,chassis222a,chassis222b,chassis223a,chassis223b,chassis224a,chassis224b,chassis225a,chassis225b,chassis226a,chassis226b,chassis227a,chassis227b,chassis228a,chassis228b,chassis229a,chassis229b,chassis22a,chassis22b,chassis230a,chassis230b,chassis231a,chassis231b,chassis232a,chassis232b,chassis233a,chassis233b,chassis234a,chassis234b,chassis235a,chassis235b,chassis236a,chassis236b,chassis237a,chassis237b,chassis238a,chassis238b,chassis239a,chassis239b,chassis23a,chassis23b,chassis240a,chassis240b,chassis241a,chassis241b,chassis242a,chassis242b,chassis243a,chassis243b,chassis244a,chassis244b,chassis245a,chassis245b,chassis246a,chassis246b,chassis247a,chassis247b,chassis248a,chassis248b,chassis249a,chassis249b,chassis24a,chassis24b,chassis250a,chassis250b,chassis251a,chassis251b,chassis252a,chassis252b,chassis253a,chassis253b,chassis254a,chassis254b,chassis255a,chassis255b,chassis256a,chassis256b,chassis257a,chassis257b,chassis258a,chassis258b,chassis259a,chassis259b,chassis25a,chassis25b,chassis260a,chassis260b,chassis261a,chassis261b,chassis262a,chassis262b,chassis263a,chassis263b,chassis264a,chassis264b,chassis265a,chassis265b,chassis266a,chassis266b,chassis267a,chassis267b,chassis268a,chassis268b,chassis269a,chassis269b,chassis26a,chassis26b,chassis270a,chassis270b,chassis271a,chassis271b,chassis272a,chassis272b,chassis273a,chassis273b,chassis274a,chassis274b,chassis275a,chassis275b,chassis276a,chassis276b,chassis277a,chassis277b,chassis278a,chassis278b,chassis279a,chassis279b,chassis27a,chassis27b,chassis280a,chassis280b,chassis281a,chassis281b,chassis282a,chassis282b,chassis283a,chassis283b,chassis284a,chassis284b,chassis285a,chassis285b,chassis286a,chassis286b,chassis287a,chassis287b,chassis288a,chassis288b,chassis289a,chassis289b,chassis28a,chassis28b,chassis290a,chassis290b,chassis291a,chassis291b,chassis292a,chassis292b,chassis293a,chassis293b,chassis294a,chassis294b,chassis295a,chassis295b,chassis296a,chassis296b,chassis297a,chassis297b,chassis298a,chassis298b,chassis299a,chassis299b,chassis29a,chassis29b,chassis2a,chassis2b,chassis300a,chassis300b,chassis301a,chassis301b,chassis302a,chassis302b,chassis303a,chassis303b,chassis304a,chassis304b,chassis305a,chassis305b,chassis306a,chassis306b,chassis307a,chassis307b,chassis308a,chassis308b,chassis309a,chassis309b,chassis30a,chassis30b,chassis310a,chassis310b,chassis311a,chassis311b,chassis312a,chassis312b,chassis313a,chassis313b,chassis314a,chassis314b,chassis315a,chassis315b,chassis316a,chassis316b,chassis317a,chassis317b,chassis318a,chassis318b,chassis319a,chassis319b,chassis31a,chassis31b,chassis320a,chassis320b,chassis321a,chassis321b,chassis322a,chassis322b,chassis323a,chassis323b,chassis324a,chassis324b,chassis325a,chassis325b,chassis326a,chassis326b,chassis327a,chassis327b,chassis328a,chassis328b,chassis329a,chassis329b,chassis32a,chassis32b,chassis330a,chassis330b,chassis331a,chassis331b,chassis332a,chassis332b,chassis333a,chassis333b,chassis334a,chassis334b,chassis335a,chassis335b,chassis336a,chassis336b,chassis337a,chassis337b,chassis338a,chassis338b,chassis339a,chassis339b,chassis33a,chassis33b,chassis340a,chassis340b,chassis341a,chassis341b,chassis342a,chassis342b,chassis343a,chassis343b,chassis344a,chassis344b,chassis345a,chassis345b,chassis346a,chassis346b,chassis347a,chassis347b,chassis348a,chassis348b,chassis349a,chassis349b,chassis34a,chassis34b,chassis350a,chassis350b,chassis351a,chassis351b,chassis352a,chassis352b,chassis353a,chassis353b,chassis354a,chassis354b,chassis355a,chassis355b,chassis356a,chassis356b,chassis357a,chassis357b,chassis358a,chassis358b,chassis359a,chassis359b,chassis35a,chassis35b,chassis360a,chassis360b,chassis361a,chassis361b,chassis362a,chassis362b,chassis363a,chassis363b,chassis364a,chassis364b,chassis365a,chassis365b,chassis366a,chassis366b,chassis367a,chassis367b,chassis368a,chassis368b,chassis369a,chassis369b,chassis36a,chassis36b,chassis370a,chassis370b,chassis371a,chassis371b,chassis372a,chassis372b,chassis373a,chassis373b,chassis374a,chassis374b,chassis375a,chassis375b,chassis376a,chassis376b,chassis377a,chassis377b,chassis378a,chassis378b,chassis379a,chassis379b,chassis37a,chassis37b,chassis380a,chassis380b,chassis381a,chassis381b,chassis382a,chassis382b,chassis383a,chassis383b,chassis384a,chassis384b,chassis385a,chassis385b,chassis386a,chassis386b,chassis387a,chassis387b,chassis388a,chassis388b,chassis389a,chassis389b,chassis38a,chassis38b,chassis390a,chassis390b,chassis391a,chassis391b,chassis392a,chassis392b,chassis393a,chassis393b,chassis394a,chassis394b,chassis395a,chassis395b,chassis396a,chassis396b,chassis397a,chassis397b,chassis398a,chassis398b,chassis399a,chassis399b,chassis39a,chassis39b,chassis3a,chassis3b,chassis400a,chassis400b,chassis401a,chassis401b,chassis402a,chassis402b,chassis403a,chassis403b,chassis404a,chassis404b,chassis405a,chassis405b,chassis406a,chassis406b,chassis407a,chassis407b,chassis408a,chassis408b,chassis409a,chassis409b,chassis40a,chassis40b,chassis410a,chassis410b,chassis411a,chassis411b,chassis412a,chassis412b,chassis413a,chassis413b,chassis414a,chassis414b,chassis415a,chassis415b,chassis416a,chassis416b,chassis417a,chassis417b,chassis418a,chassis418b,chassis419a,chassis419b,chassis41a,chassis41b,chassis420a,chassis420b,chassis421a,chassis421b,chassis422a,chassis422b,chassis423a,chassis423b,chassis424a,chassis424b,chassis425a,chassis425b,chassis426a,chassis426b,chassis427a,chassis427b,chassis428a,chassis428b,chassis429a,chassis429b,chassis42a,chassis42b,chassis430a,chassis430b,chassis431a,chassis431b,chassis432a,chassis432b,chassis433a,chassis433b,chassis434a,chassis434b,chassis435a,chassis435b,chassis436a,chassis436b,chassis437a,chassis437b,chassis438a,chassis438b,chassis439a,chassis439b,chassis43a,chassis43b,chassis440a,chassis440b,chassis441a,chassis441b,chassis442a,chassis442b,chassis443a,chassis443b,chassis444a,chassis444b,chassis445a,chassis445b,chassis446a,chassis446b,chassis447a,chassis447b,chassis448a,chassis448b,chassis449a,chassis449b,chassis44a,chassis44b,chassis450a,chassis450b,chassis451a,chassis451b,chassis452a,chassis452b,chassis453a,chassis453b,chassis454a,chassis454b,chassis455a,chassis455b,chassis456a,chassis456b,chassis457a,chassis457b,chassis458a,chassis458b,chassis459a,chassis459b,chassis45a,chassis45b,chassis460a,chassis460b,chassis461a,chassis461b,chassis462a,chassis462b,chassis463a,chassis463b,chassis464a,chassis464b,chassis465a,chassis465b,chassis466a,chassis466b,chassis467a,chassis467b,chassis468a,chassis468b,chassis46a,chassis46b,chassis47a,chassis47b,chassis48a,chassis48b,chassis49a,chassis49b,chassis4a,chassis4b,chassis50a,chassis50b,chassis51a,chassis51b,chassis52a,chassis52b,chassis53a,chassis53b,chassis54a,chassis54b,chassis55a,chassis55b,chassis56a,chassis56b,chassis57a,chassis57b,chassis58a,chassis58b,chassis59a,chassis59b,chassis5a,chassis5b,chassis60a,chassis60b,chassis61a,chassis61b,chassis62a,chassis62b,chassis63a,chassis63b,chassis64a,chassis64b,chassis65a,chassis65b,chassis66a,chassis66b,chassis67a,chassis67b,chassis68a,chassis68b,chassis69a,chassis69b,chassis6a,chassis6b,chassis70a,chassis70b,chassis71a,chassis71b,chassis72a,chassis72b,chassis73a,chassis73b,chassis74a,chassis74b,chassis75a,chassis75b,chassis76a,chassis76b,chassis77a,chassis77b,chassis78a,chassis78b,chassis79a,chassis79b,chassis7a,chassis7b,chassis80a,chassis80b,chassis81a,chassis81b,chassis82a,chassis82b,chassis83a,chassis83b,chassis84a,chassis84b,chassis85a,chassis85b,chassis86a,chassis86b,chassis87a,chassis87b,chassis88a,chassis88b,chassis89a,chassis89b,chassis8a,chassis8b,chassis90a,chassis90b,chassis91a,chassis91b,chassis92a,chassis92b,chassis93a,chassis93b,chassis94a,chassis94b,chassis95a,chassis95b,chassis96a,chassis96b,chassis97a,chassis97b,chassis98a,chassis98b,chassis99a,chassis99b,chassis9a,chassis9b,cyclades22b,pdu-sierra[0,2-6,8-11,324,326-330,332-335,648,650-654,656-659,972,974-978,980-983,1296,1298-1302,1304-1307,1620,1622-1626,1628-1631],pdu-sierra1297a,pdu-sierra1297b,pdu-sierra1303a,pdu-sierra1303b,pdu-sierra1621a,pdu-sierra1621b,pdu-sierra1627a,pdu-sierra1627b,pdu-sierra1a,pdu-sierra1b,pdu-sierra325a,pdu-sierra325b,pdu-sierra331a,pdu-sierra331b,pdu-sierra649a,pdu-sierra649b,pdu-sierra655a,pdu-sierra655b,pdu-sierra7a,pdu-sierra7b,pdu-sierra973a,pdu-sierra973b,pdu-sierra979a,pdu-sierra979b,sierra[0,2-1943] powerman-2.3.27/test/t53000077500000000000000000000003211415616035500147570ustar00rootroot00000000000000#!/bin/sh TEST=t53 $PATH_POWERMAND -f -c ${TEST_BUILDDIR}/$TEST.conf >$TEST.out 2>&1 test $? = 1 || exit 1 sed -i -e 's! [^: ]*t53\.dev! t53.dev!' $TEST.out diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t53.conf.in000066400000000000000000000001331415616035500163060ustar00rootroot00000000000000# comment include "@top_srcdir@/etc/vpc.dev" # comment include "@top_srcdir@/test/t53.dev" powerman-2.3.27/test/t53.dev000066400000000000000000000000501415616035500155300ustar00rootroot00000000000000# 1 # 2 # 3 # 4 syntaxerror # 5 # 6 # 7 powerman-2.3.27/test/t53.exp000066400000000000000000000000431415616035500155500ustar00rootroot00000000000000powermand: parse error: t53.dev::5 powerman-2.3.27/test/t54000077500000000000000000000004211415616035500147610ustar00rootroot00000000000000#!/bin/sh TEST=t54 #$PATH_POWERMAND -f -c ${TEST_BUILDDIR}/$TEST.conf >$TEST.out 2>&1 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q widow-mds1 >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t54.conf.in000066400000000000000000000004131415616035500163100ustar00rootroot00000000000000# issue 34 (google code) include "@top_srcdir@/etc/vpc.dev" device "linkfarm" "vpc" "@top_builddir@/test/vpcd |&" device "mds" "vpc" "@top_builddir@/test/vpcd |&" node "widow-mds" "linkfarm" "1" node "widow-mds[0-3]" "mds" "[2-5]" powerman-2.3.27/test/t54.exp000066400000000000000000000000501415616035500155470ustar00rootroot00000000000000on: off: widow-mds1 unknown: powerman-2.3.27/test/t55000077500000000000000000000004131415616035500147630ustar00rootroot00000000000000#!/bin/sh TEST=t55 #$PATH_POWERMAND -f -c ${TEST_BUILDDIR}/$TEST.conf >$TEST.out 2>&1 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q corn2 >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t55.conf.in000066400000000000000000000002601415616035500163110ustar00rootroot00000000000000# issue 35 (google code) include "@top_srcdir@/etc/vpc.dev" device "pdu1" "vpc" "@top_builddir@/test/vpcd |&" node "corn1-p2" "pdu1" "1" node "corn2" "pdu1" "2" powerman-2.3.27/test/t55.exp000066400000000000000000000000431415616035500155520ustar00rootroot00000000000000on: off: corn2 unknown: powerman-2.3.27/test/t56000077500000000000000000000007041415616035500147670ustar00rootroot00000000000000#!/bin/sh # check stonith script with single plug TEST=t56 PM_SIMSTATE=$(mktemp) || exit 1 export PM_SIMSTATE PM_OVERRIDE="${TEST_SRCDIR}/pm-sim" export PM_OVERRIDE PM_VERBOSE=1 export PM_VERBOSE $PATH_POWERMAN_STONITH on t >$TEST.out 2>&1 test $? = 0 || exit 1 $PATH_POWERMAN_STONITH off t >>$TEST.out 2>&1 test $? = 0 || exit 1 rm -f $PM_SIMSTATE sed -i -e 's/ [^ ]*pm-sim/ pm-sim/g' $TEST.out diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t56.exp000066400000000000000000000002651415616035500155610ustar00rootroot00000000000000Command completed successfully powerman-stonith: pm-sim -1 t, rc=0 Command completed successfully powerman-stonith: pm-sim -0 t, rc=0 powerman-stonith: pm-sim -q t, state=off, rc=0 powerman-2.3.27/test/t57000077500000000000000000000007121415616035500147670ustar00rootroot00000000000000#!/bin/sh # check stonith script wtih aliased plugs TEST=t57 PM_SIMSTATE=$(mktemp) || exit 1 export PM_SIMSTATE PM_OVERRIDE="${TEST_SRCDIR}/pm-sim -A" export PM_OVERRIDE PM_VERBOSE=1 export PM_VERBOSE $PATH_POWERMAN_STONITH on t >$TEST.out 2>&1 test $? = 0 || exit 1 $PATH_POWERMAN_STONITH off t >>$TEST.out 2>&1 test $? = 0 || exit 1 rm -f $PM_SIMSTATE sed -i -e 's/ [^ ]*pm-sim/ pm-sim/g' $TEST.out diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t57.exp000066400000000000000000000002761415616035500155640ustar00rootroot00000000000000Command completed successfully powerman-stonith: pm-sim -A -1 t, rc=0 Command completed successfully powerman-stonith: pm-sim -A -0 t, rc=0 powerman-stonith: pm-sim -A -q t, state=off, rc=0 powerman-2.3.27/test/t58000077500000000000000000000010011415616035500147600ustar00rootroot00000000000000#!/bin/sh # check stonith script with single plug that fails off TEST=t58 PM_SIMSTATE=$(mktemp) || exit 1 export PM_SIMSTATE PM_OVERRIDE="${TEST_SRCDIR}/pm-sim" export PM_OVERRIDE PM_VERBOSE=1 export PM_VERBOSE $PATH_POWERMAN_STONITH on t >$TEST.out 2>&1 test $? = 0 || exit 1 PM_OVERRIDE="${TEST_SRCDIR}/pm-sim -r -s -t" $PATH_POWERMAN_STONITH off t >>$TEST.out 2>&1 test $? = 1 || exit 1 rm -f $PM_SIMSTATE sed -i -e 's/ [^ ]*pm-sim/ pm-sim/g' $TEST.out diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t58.exp000066400000000000000000000003131415616035500155550ustar00rootroot00000000000000Command completed successfully powerman-stonith: pm-sim -1 t, rc=0 Command completed successfully powerman-stonith: pm-sim -r -s -t -0 t, rc=0 powerman-stonith: pm-sim -r -s -t -q t, state=unknown, rc=1 powerman-2.3.27/test/t59000077500000000000000000000010021415616035500147620ustar00rootroot00000000000000#!/bin/sh # check stonith script with aliased plug that fails off TEST=t59 PM_SIMSTATE=$(mktemp) || exit 1 export PM_SIMSTATE PM_OVERRIDE="${TEST_SRCDIR}/pm-sim -A" export PM_OVERRIDE PM_VERBOSE=1 export PM_VERBOSE $PATH_POWERMAN_STONITH on t >$TEST.out 2>&1 test $? = 0 || exit 1 PM_OVERRIDE="${TEST_SRCDIR}/pm-sim -A -s" $PATH_POWERMAN_STONITH off t >>$TEST.out 2>&1 test $? = 1 || exit 1 rm -f $PM_SIMSTATE sed -i -e 's/ [^ ]*pm-sim/ pm-sim/g' $TEST.out diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t59.exp000066400000000000000000000003101415616035500155530ustar00rootroot00000000000000Command completed successfully powerman-stonith: pm-sim -A -1 t, rc=0 Command completed successfully powerman-stonith: pm-sim -A -s -0 t, rc=0 powerman-stonith: pm-sim -A -s -q t, state=unknown, rc=1 powerman-2.3.27/test/t60000077500000000000000000000003171415616035500147620ustar00rootroot00000000000000#!/bin/sh TEST=t60 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q t[0-15] \ >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t60.conf.in000066400000000000000000000002211415616035500163020ustar00rootroot00000000000000include "@top_srcdir@/etc/ipmipower.dev" device "d0" "ipmipower" "@top_builddir@/test/ipmipower --auth-failure -h t[0-15]|&" node "t[0-15]" "d0" powerman-2.3.27/test/t60.exp000066400000000000000000000000471415616035500155520ustar00rootroot00000000000000on: off: t[1-15] unknown: t0 powerman-2.3.27/test/t61000077500000000000000000000004151415616035500147620ustar00rootroot00000000000000#!/bin/sh TEST=t61 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0-4] \ -q -0 t[0-4] \ -q -c t[0-4] \ -q -0 t[0-4] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t61.conf.in000066400000000000000000000007221415616035500163110ustar00rootroot00000000000000include "@top_srcdir@/etc/openbmc.dev" device "b0" "openbmc" "@top_builddir@/test/openbmc-httppower |&" device "b1" "openbmc" "@top_builddir@/test/openbmc-httppower |&" device "b2" "openbmc" "@top_builddir@/test/openbmc-httppower |&" device "b3" "openbmc" "@top_builddir@/test/openbmc-httppower |&" device "b4" "openbmc" "@top_builddir@/test/openbmc-httppower |&" node "t0" "b0" "t0" node "t1" "b1" "t1" node "t2" "b2" "t2" node "t3" "b3" "t3" node "t4" "b4" "t4" powerman-2.3.27/test/t61.exp000066400000000000000000000004601415616035500155520ustar00rootroot00000000000000on: off: t[0-4] unknown: Command completed successfully on: t[0-4] off: unknown: Command completed successfully on: off: t[0-4] unknown: Command completed successfully on: t[0-4] off: unknown: Command completed successfully on: off: t[0-4] unknown: powerman-2.3.27/test/t62000077500000000000000000000004151415616035500147630ustar00rootroot00000000000000#!/bin/sh TEST=t61 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0-4] \ -q -0 t[0-4] \ -q -c t[0-4] \ -q -0 t[0-4] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t62.conf.in000066400000000000000000000007221415616035500163120ustar00rootroot00000000000000include "@top_srcdir@/etc/redfish.dev" device "b0" "redfish" "@top_builddir@/test/redfish-httppower |&" device "b1" "redfish" "@top_builddir@/test/redfish-httppower |&" device "b2" "redfish" "@top_builddir@/test/redfish-httppower |&" device "b3" "redfish" "@top_builddir@/test/redfish-httppower |&" device "b4" "redfish" "@top_builddir@/test/redfish-httppower |&" node "t0" "b0" "t0" node "t1" "b1" "t1" node "t2" "b2" "t2" node "t3" "b3" "t3" node "t4" "b4" "t4" powerman-2.3.27/test/t62.exp000066400000000000000000000004601415616035500155530ustar00rootroot00000000000000on: off: t[0-4] unknown: Command completed successfully on: t[0-4] off: unknown: Command completed successfully on: off: t[0-4] unknown: Command completed successfully on: t[0-4] off: unknown: Command completed successfully on: off: t[0-4] unknown: powerman-2.3.27/test/t63000077500000000000000000000004671415616035500147730ustar00rootroot00000000000000#!/bin/sh TEST=t63 $PATH_POWERMAN -Y -S $PATH_POWERMAND -C ${TEST_BUILDDIR}/$TEST.conf \ -q -1 t[0,8] \ -q -0 t[0,8] \ -q -1 t[0-15] \ -q -0 t[0-15] \ -q -c t[0-15] \ -q -c t[0-15] \ -q >$TEST.out 2>$TEST.err test $? = 0 || exit 1 diff $TEST.out ${TEST_SRCDIR}/$TEST.exp >$TEST.diff powerman-2.3.27/test/t63.conf.in000066400000000000000000000002021415616035500163040ustar00rootroot00000000000000include "@top_srcdir@/etc/ipmipower.dev" device "d0" "ipmipower" "@top_builddir@/test/ipmipower -h t[0-15]|&" node "t[0-15]" "d0" powerman-2.3.27/test/t63.exp000066400000000000000000000007071415616035500155600ustar00rootroot00000000000000on: off: t[0-15] unknown: Command completed successfully on: t[0,8] off: t[1-7,9-15] unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: off: t[0-15] unknown: Command completed successfully on: t[0-15] off: unknown: Command completed successfully on: t[0-15] off: unknown: powerman-2.3.27/test/targv.c000066400000000000000000000036621415616035500157200ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "argv.h" int main(int argc, char *argv[]) { char **av; av = argv_create("foo bar baz", ""); assert(argv_length(av) == 3); av = argv_append(av, "bonk"); assert(argv_length(av) == 4); assert(strcmp(av[0], "foo") == 0); assert(strcmp(av[1], "bar") == 0); assert(strcmp(av[2], "baz") == 0); assert(strcmp(av[3], "bonk") == 0); assert(av[4] == NULL); argv_destroy(av); av = argv_create("a,b:c d", ",:"); assert(argv_length(av) == 4); assert(strcmp(av[0], "a") == 0); assert(strcmp(av[1], "b") == 0); assert(strcmp(av[2], "c") == 0); assert(strcmp(av[3], "d") == 0); assert(av[4] == NULL); argv_destroy(av); exit(0); } powerman-2.3.27/test/test.conf.in000066400000000000000000000001551415616035500166560ustar00rootroot00000000000000include "@top_srcdir@/etc/vpc.dev" device "test0" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" powerman-2.3.27/test/test4.conf.in000066400000000000000000000005171415616035500167440ustar00rootroot00000000000000include "@top_srcdir@/etc/vpc.dev" device "test0" "vpc" "@top_builddir@/test/vpcd |&" device "test1" "vpc" "@top_builddir@/test/vpcd |&" device "test2" "vpc" "@top_builddir@/test/vpcd |&" device "test3" "vpc" "@top_builddir@/test/vpcd |&" node "t[0-15]" "test0" node "t[16-31]" "test1" node "t[32-47]" "test2" node "t[48-63]" "test3" powerman-2.3.27/test/tpl.c000066400000000000000000000066041415616035500153730ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004-2008 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ /* * Test driver for pluglist module. */ #include #include #include #include #include "list.h" #include "xtypes.h" #include "pluglist.h" #include "hostlist.h" #include "error.h" #include "xmalloc.h" void usage(void) { fprintf(stderr, "Usage: tpl [-f plug_to_find] [-p fixed_plugs] nodelist [pluglist]\n"); exit(1); } int main(int argc, char *argv[]) { extern int optind; extern char *optarg; int c; PlugList pl = NULL; char *hwplugs = NULL; char *nodelist = NULL; char *pluglist = NULL; char *findplug = NULL; err_init(basename(argv[0])); while ((c = getopt(argc, argv, "p:f:")) != EOF) { switch (c) { case 'p': hwplugs = optarg; break; case 'f': findplug = optarg; break; default: usage(); } } if (argc - optind == 0) usage(); nodelist = argv[optind++]; if (argc - optind == 1) pluglist = argv[optind++]; if (argc - optind != 0) usage(); if (hwplugs) { hostlist_t hl = hostlist_create(hwplugs); hostlist_iterator_t itr = hostlist_iterator_create(hl); List l = list_create((ListDelF)xfree); char *plug; while ((plug = hostlist_next(itr))) list_append(l, xstrdup(plug)); hostlist_iterator_destroy(itr); hostlist_destroy(hl); pl = pluglist_create(l); list_destroy(l); } else pl = pluglist_create(NULL); switch (pluglist_map(pl, nodelist, pluglist)) { case EPL_DUPNODE: fprintf(stderr, "duplicate node\n"); break; case EPL_UNKPLUG: fprintf(stderr, "unknown plug\n"); break; case EPL_DUPPLUG: fprintf(stderr, "duplicate plug\n"); break; case EPL_NOPLUGS: fprintf(stderr, "more nodes than plugs\n"); break; case EPL_NONODES: fprintf(stderr, "more plugs than nodes\n"); break; case EPL_SUCCESS: break; } if (findplug) { Plug *plug = pluglist_find(pl, findplug); if (plug) printf("plug=%s node=%s\n", plug->name, plug->node ? plug->node : "NULL"); else printf("plug %s: not found\n", findplug); } else { PlugListIterator itr = pluglist_iterator_create(pl); Plug *plug; while ((plug = pluglist_next(itr))) { printf("plug=%s node=%s\n", plug->name, plug->node ? plug->node : "NULL"); } pluglist_iterator_destroy(itr); } exit(0); } powerman-2.3.27/test/tpm000077500000000000000000000001721415616035500151500ustar00rootroot00000000000000#!/bin/bash if [ "$PATH_POWERMAND" = "" ]; then PATH_POWERMAND=../src/powermand fi $PATH_POWERMAND -f -c t51.conf -s powerman-2.3.27/test/tregex.c000066400000000000000000000127301415616035500160670ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2004 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Jim Garlick * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #include #include #include #include #include "xtypes.h" #include "xregex.h" #include "xmalloc.h" #include "error.h" /* Return true if regex [r] matches exactly [p] in [s]. */ static bool _matchstr(char *r, char *s, char *p) { xregex_t re; xregex_match_t rm; int res; char *tmp; re = xregex_create(); rm = xregex_match_create(2); xregex_compile(re, r, TRUE); res = xregex_exec(re, s, rm); if (res && p) { tmp = xregex_match_strdup(rm); if (strcmp(tmp, p) != 0) res = FALSE; xfree(tmp); } xregex_match_destroy(rm); xregex_destroy(re); return res; } /* Return true if regex [r] matches exactly [s] in [s]. */ static bool _matchstr_all(char *r, char *s) { return _matchstr(r, s, s); } /* Return true if regex [r] matches anything in [s]. */ static bool _match(char *r, char *s) { return _matchstr(r, s, NULL); } static void _check_substr_match(void) { xregex_t re; xregex_match_t rm; char *s; re = xregex_create(); rm = xregex_match_create(2); xregex_compile(re, "foo([0-9]+)bar([0-9]+)", TRUE); assert(xregex_exec(re, "xxxfoo1bar2", rm) == TRUE); s = xregex_match_sub_strdup(rm, 0); assert(s != NULL); assert(strcmp(s, "foo1bar2") == 0); xfree(s); s = xregex_match_sub_strdup(rm, 1); assert(s != NULL); assert(strcmp(s, "1") == 0); xfree(s); s = xregex_match_sub_strdup(rm, 2); assert(s != NULL); assert(strcmp(s, "2") == 0); xfree(s); s = xregex_match_sub_strdup(rm, 3); assert(s == NULL); s = xregex_match_sub_strdup(rm, -1); /* powerman actually does this! */ assert(s == NULL); s = xregex_match_strdup(rm); assert(strcmp(s, "xxxfoo1bar2") == 0); assert(xregex_match_strlen(rm) == strlen(s)); xfree(s); xregex_match_recycle(rm); assert(xregex_exec(re, "foobar2", rm) == FALSE); s = xregex_match_sub_strdup(rm, 0); assert(s == NULL); s = xregex_match_sub_strdup(rm, 1); assert(s == NULL); xregex_match_recycle(rm); assert(xregex_exec(re, "xxxfoo1bar2yyy", rm) == TRUE); s = xregex_match_sub_strdup(rm, 0); assert(s != NULL); assert(strcmp(s, "foo1bar2") == 0); xfree(s); s = xregex_match_sub_strdup(rm, 1); assert(s != NULL); assert(strcmp(s, "1") == 0); xfree(s); s = xregex_match_sub_strdup(rm, 2); assert(s != NULL); assert(strcmp(s, "2") == 0); xfree(s); s = xregex_match_strdup(rm); assert(strcmp(s, "xxxfoo1bar2") == 0); assert(xregex_match_strlen(rm) == strlen(s)); xfree(s); xregex_match_destroy(rm); xregex_destroy(re); } int main(int argc, char *argv[]) { char *s; err_init("tregex"); assert(_match("foo", "foo")); assert(_match("foo", "fooxxx")); assert(_match("foo", "xxxfoo")); assert(!_match("foo", "bar")); _check_substr_match(); /* verify that \\n and \\r are converted into \r and \r */ assert(!_match("foo\\r\\n", "foo\\r\\n")); assert( _match("foo\\r\\n", "foo\r\n")); /* check a really long string for a regex */ #define LONG_STR_LEN (64*1024*1024) #define POS_MAGIC 42 #define POS_WONDERFUL 32*1024*1024 #define POS_COOKIE 63*1024*1024 s = xmalloc(LONG_STR_LEN); memset(s, 'a', LONG_STR_LEN - 1); memcpy(s + POS_MAGIC, "MAGIC", 5); memcpy(s + POS_WONDERFUL, "WONDERFUL", 9); memcpy(s + POS_COOKIE, "COOKIE", 6); s[LONG_STR_LEN - 1] = '\0'; assert( _match("MAGIC", s)); assert( _match("WONDERFUL", s)); assert( _match("COOKIE", s)); assert(!_match("CHOCOLATE", s)); xfree(s); /* end of line handling should be disabled since end of string * (which normally matches) is non-deterministic in powerman. * We should be explicitly matching end-of-line sentinels like * \n in scripts. */ assert(!_match("foo$", "foo")); assert(!_match("foo$", "foo\n")); assert(!_match("foo\n", "foo")); assert(!_match("foo\n", "bar\nfoo")); assert( _match("foo\n", "barfoo\n")); /* regex takes first match if there are > 1, * but leading wildcard matches greedily */ assert(_matchstr("foo", "abfoocdfoo", "abfoo")); assert(_matchstr_all(".*foo", "abfoocdfoo")); /* check that [:space:] character class works inside bracket * expression */ assert(_matchstr_all("bar[0-9[:space:]]*foo", "bar 42 foo")); /* debug apcpdu3 regex */ #define B3RX "([0-9])*[^\r\n]*(ON|OFF)\r\n" assert(_matchstr_all(B3RX, " 2- Outlet 2 ON\r\n")); assert(_matchstr_all(B3RX, " 9- ON\r\n")); exit(0); } powerman-2.3.27/test/vpcd.c000066400000000000000000000264271415616035500155350ustar00rootroot00000000000000/***************************************************************************** * Copyright (C) 2001 The Regents of the University of California. * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). * Written by Andrew Uselton * UCRL-CODE-2002-008. * * This file is part of PowerMan, a remote power management program. * For details, see http://github.com/chaos/powerman/ * * PowerMan 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. * * PowerMan 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 PowerMan; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. \*****************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #if HAVE_GETOPT_H #include #endif #include #include #include #include #include #include #include #include #include #include #include "xmalloc.h" #include "xread.h" #include "xpoll.h" static void usage(void); static void _noop_handler(int signum); static void _spew_one(int linenum); static void _spew(int lines); static void _prompt_loop(void); static void _setup_socket(char *port); #define NUM_PLUGS 16 static int plug[NUM_PLUGS]; static int beacon[NUM_PLUGS]; static int temp[NUM_PLUGS]; static int logged_in = 0; static char *prog; #define OPTIONS "p:" #if HAVE_GETOPT_LONG #define GETOPT(ac,av,opt,lopt) getopt_long(ac,av,opt,lopt,NULL) static const struct option longopts[] = { {"port", required_argument, 0, 'p'}, {0, 0, 0, 0}, }; #else #define GETOPT(ac,av,opt,lopt) getopt(ac,av,opt) #endif int main(int argc, char *argv[]) { int i, c; char *port = NULL; prog = basename(argv[0]); while ((c = GETOPT(argc, argv, OPTIONS, longopts)) != -1) { switch (c) { case 'p': /* --port n */ port = xstrdup(optarg); break; default: usage(); } } if (optind < argc) usage(); if (signal(SIGPIPE, _noop_handler) == SIG_ERR) { perror("signal"); exit(1); } if (port) _setup_socket(port); for (i = 0; i < NUM_PLUGS; i++) { plug[i] = 0; beacon[i] = 0; temp[i] = 83 + i; } _prompt_loop(); exit(0); } static void usage(void) { fprintf(stderr, "Usage: %s\n", prog); exit(1); } static void _noop_handler(int signum) { fprintf(stderr, "%s: received signal %d\n", prog, signum); } /* Return with stdin/stdout reopened as a connected socket. */ #define LISTEN_BACKLOG 5 static void _setup_socket(char *serv) { struct addrinfo hints, *res, *r; int *fds, fd, fdlen, saved_errno, count, error, i, opt; char *what = NULL; xpollfd_t pfd; struct sockaddr_storage addr; socklen_t addr_size; short flags; /* get addresses to listen on for this port */ memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ((error = getaddrinfo(NULL, serv, &hints, &res))) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error)); exit(1); } if (res == NULL) { fprintf(stderr, "getaddrinfo: no address to bind to\n"); exit(1); } /* allocate array of listen fd's */ fdlen = 0; for (r = res; r != NULL; r = r->ai_next) fdlen++; fds = (int *)xmalloc(sizeof(int) * fdlen); /* bind fds to addresses and listen */ count = 0; saved_errno = 0; for (r = res, i = 0; r != NULL; r = r->ai_next, i++) { fds[i] = -1; if ((fd = socket(r->ai_family, r->ai_socktype, 0)) < 0) { saved_errno = errno; what = "socket"; continue; } opt = 1; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { saved_errno = errno; what = "setsockopt"; close(fd); continue; } if (bind(fd, r->ai_addr, r->ai_addrlen) < 0) { saved_errno = errno; what = "bind"; close(fd); continue; } if (listen(fd, LISTEN_BACKLOG) < 0) { saved_errno = errno; what = "listen"; close(fd); continue; } fds[i] = fd; count++; } freeaddrinfo(res); if (count == 0) { fprintf(stderr, "%s: %s\n", what, strerror(saved_errno)); exit(1); } /* accept a connection on 'fd' */ pfd = xpollfd_create(); fd = -1; while (fd == -1) { xpollfd_zero(pfd); for (i = 0; i < fdlen; i++) { if (fds[i] != -1) xpollfd_set(pfd, fds[i], XPOLLIN); } if (xpoll(pfd, NULL) < 0) { fprintf(stderr, "poll: %s\n", strerror(errno)); exit(1); } for (i = 0; i < fdlen; i++) { if (fds[i] != -1) { flags = xpollfd_revents(pfd, fds[i]); if ((flags & (XPOLLERR|XPOLLHUP|XPOLLNVAL))) { fprintf(stderr, "poll: error on fd %d\n", fds[i]); exit(1); } if ((flags & XPOLLIN)) { addr_size = sizeof(addr); fd = accept(fds[i], (struct sockaddr *)&addr, &addr_size); if (fd < 0) { fprintf(stderr, "accept: %s\n", strerror(errno)); exit(1); } break; } } } } xpollfd_destroy(pfd); for (i = 0; i < fdlen; i++) { if (fds[i] != -1 && fds[i] != fd) close(fds[i]); } /* dup socket to stdio */ (void)close(0); if (dup2(fd, 0) < 0) { fprintf(stderr, "dup2(stdin): %s\n", strerror(errno)); exit(1); } (void)close(1); if (dup2(fd, 1) < 0) { fprintf(stderr, "dup2(stdout): %s\n", strerror(errno)); exit(1); } } #define SPEW \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]" static void _spew_one(int linenum) { char buf[80]; linenum %= strlen(SPEW); memcpy(buf, SPEW + linenum, strlen(SPEW) - linenum); memcpy(buf + strlen(SPEW) - linenum, SPEW, linenum); buf[strlen(SPEW)] = '\0'; printf("%s\n", buf); } static void _spew(int lines) { int i; for (i = 0; i < lines; i++) _spew_one(i); } static void _prompt_loop(void) { int seq, i; char buf[128]; char prompt[16]; for (seq = 0;; seq++) { snprintf(prompt, sizeof(prompt), "%d vpc> ", seq); if (xreadline(prompt, buf, sizeof(buf)) == NULL) break; if (strlen(buf) == 0) continue; if (strcmp(buf, "logoff") == 0) { /* logoff */ printf("%d OK\n", seq); logged_in = 0; break; } if (strcmp(buf, "login") == 0) { /* logon */ logged_in = 1; goto ok; } if (!logged_in) { printf("%d Please login\n", seq); continue; } if (sscanf(buf, "stat %d", &i) == 1) { /* stat */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } printf("plug %d: %s\n", i, plug[i] ? "ON" : "OFF"); goto ok; } if (strcmp(buf, "stat *") == 0) { /* stat * */ for (i = 0; i < NUM_PLUGS; i++) printf("plug %d: %s\n", i, plug[i] ? "ON" : "OFF"); goto ok; } if (sscanf(buf, "beacon %d", &i) == 1) { /* beacon */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } printf("plug %d: %s\n", i, beacon[i] ? "ON" : "OFF"); goto ok; } if (strcmp(buf, "beacon *") == 0) { /* beacon * */ for (i = 0; i < NUM_PLUGS; i++) printf("plug %d: %s\n", i, beacon[i] ? "ON" : "OFF"); goto ok; } if (sscanf(buf, "temp %d", &i) == 1) { /* temp */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } printf("plug %d: %d\n", i, temp[i]); } if (strcmp(buf, "temp *") == 0) { /* temp * */ for (i = 0; i < NUM_PLUGS; i++) printf("plug %d: %d\n", i, temp[i]); goto ok; } if (sscanf(buf, "spew %d", &i) == 1) { /* spew */ if (i <= 0) { printf("%d BADVAL: %d\n", seq, i); continue; } _spew(i); goto ok; } if (sscanf(buf, "on %d", &i) == 1) { /* on */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } plug[i] = 1; goto ok; } if (sscanf(buf, "off %d", &i) == 1) { /* off */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } plug[i] = 0; goto ok; } if (sscanf(buf, "flash %d", &i) == 1) { /* flash */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } beacon[i] = 1; goto ok; } if (sscanf(buf, "unflash %d", &i) == 1) { /* unflash */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } beacon[i] = 0; goto ok; } if (strcmp(buf, "on *") == 0) { /* on * */ for (i = 0; i < NUM_PLUGS; i++) plug[i] = 1; goto ok; } if (strcmp(buf, "off *") == 0) { /* off * */ for (i = 0; i < NUM_PLUGS; i++) plug[i] = 0; goto ok; } if (sscanf(buf, "reset %d", &i) == 1) { /* reset */ if (i < 0 || i >= NUM_PLUGS) { printf("%d BADVAL: %d\n", seq, i); continue; } sleep(1); /* noop */ goto ok; } if (strcmp(buf, "reset *") == 0) { /* reset * */ sleep(1); /* noop */ goto ok; } printf("%d UNKNOWN: %s\n", seq, buf); continue; ok: printf("%d OK\n", seq); } } /* * vi:tabstop=4 shiftwidth=4 expandtab */