From 45043b58d08e1e6422d4d05c6480da74b407875f Mon Sep 17 00:00:00 2001 From: Arnaud Quette Date: Thu, 29 Sep 2011 20:14:46 +0200 Subject: [PATCH] Imported Upstream version 2.6.2 --- ChangeLog | 443 ++++- MAINTAINERS | 10 +- Makefile.in | 19 +- NEWS | 73 + UPGRADING | 6 + aclocal.m4 | 160 ++ clients/Makefile.in | 12 + clients/upsclient.c | 50 +- clients/upsclient.h | 2 + common/Makefile.in | 12 + common/common.c | 5 + conf/Makefile.in | 12 + configure | 1356 ++++++++++++- configure.in | 151 +- data/Makefile.in | 12 + data/driver.list.in | 9 + data/html/Makefile.in | 12 + docs/FAQ.txt | 6 +- docs/Makefile.in | 12 + docs/acknowledgements.txt | 4 +- docs/config-notes.txt | 17 +- docs/configure.txt | 42 +- docs/download.txt | 16 +- docs/man/Makefile.am | 76 +- docs/man/Makefile.in | 87 +- docs/man/apcsmart-old.8 | 124 ++ docs/man/apcsmart-old.txt | 103 + docs/man/apcsmart.8 | 432 +++- docs/man/apcsmart.txt | 314 ++- docs/man/bcmxcp.8 | 4 +- docs/man/bcmxcp_usb.8 | 4 +- docs/man/belkin.8 | 4 +- docs/man/belkinunv.8 | 4 +- docs/man/bestfcom.8 | 4 +- docs/man/bestfortress.8 | 4 +- docs/man/bestuferrups.8 | 4 +- docs/man/bestups.8 | 4 +- docs/man/blazer.8 | 14 +- docs/man/blazer.txt | 9 +- docs/man/clone.8 | 4 +- docs/man/dummy-ups.8 | 4 +- docs/man/etapro.8 | 4 +- docs/man/everups.8 | 4 +- docs/man/gamatronic.8 | 4 +- docs/man/genericups.8 | 4 +- docs/man/hosts.conf.5 | 4 +- docs/man/isbmex.8 | 4 +- docs/man/ivtscd.8 | 4 +- docs/man/libupsclient-config.1 | 4 +- docs/man/liebert-esp2.8 | 4 +- docs/man/liebert.8 | 4 +- docs/man/masterguard.8 | 4 +- docs/man/metasys.8 | 4 +- docs/man/mge-shut.8 | 4 +- docs/man/mge-utalk.8 | 4 +- docs/man/microdowell.8 | 4 +- docs/man/netxml-ups.8 | 4 +- docs/man/nut-ipmipsu.8 | 231 +++ docs/man/nut-ipmipsu.txt | 115 ++ docs/man/nut-scanner.8 | 186 ++ docs/man/nut-scanner.txt | 131 ++ docs/man/nut.conf.5 | 4 +- docs/man/nutscan_add_device_to_device.3 | 68 + docs/man/nutscan_add_device_to_device.txt | 45 + docs/man/nutscan_add_option_to_device.3 | 65 + docs/man/nutscan_add_option_to_device.txt | 40 + docs/man/nutscan_cidr_to_ip.3 | 49 + docs/man/nutscan_cidr_to_ip.txt | 31 + docs/man/nutscan_display_parsable.3 | 50 + docs/man/nutscan_display_parsable.txt | 34 + docs/man/nutscan_display_ups_conf.3 | 46 + docs/man/nutscan_display_ups_conf.txt | 28 + docs/man/nutscan_free_device.3 | 46 + docs/man/nutscan_free_device.txt | 28 + docs/man/nutscan_new_device.3 | 49 + docs/man/nutscan_new_device.txt | 33 + docs/man/nutscan_scan_avahi.3 | 51 + docs/man/nutscan_scan_avahi.txt | 35 + docs/man/nutscan_scan_ipmi.3 | 49 + docs/man/nutscan_scan_ipmi.txt | 33 + docs/man/nutscan_scan_nut.3 | 53 + docs/man/nutscan_scan_nut.txt | 37 + docs/man/nutscan_scan_snmp.3 | 87 + docs/man/nutscan_scan_snmp.txt | 63 + docs/man/nutscan_scan_usb.3 | 49 + docs/man/nutscan_scan_usb.txt | 33 + docs/man/nutscan_scan_xml_http.3 | 49 + docs/man/nutscan_scan_xml_http.txt | 33 + docs/man/nutupsdrv.8 | 4 +- docs/man/oneac.8 | 4 +- docs/man/optiups.8 | 4 +- docs/man/powercom.8 | 4 +- docs/man/powerman-pdu.8 | 4 +- docs/man/powerpanel.8 | 4 +- docs/man/rhino.8 | 4 +- docs/man/richcomm_usb.8 | 4 +- docs/man/safenet.8 | 4 +- docs/man/snmp-ups.8 | 4 +- docs/man/solis.8 | 4 +- docs/man/tripplite.8 | 4 +- docs/man/tripplite_usb.8 | 4 +- docs/man/tripplitesu.8 | 4 +- docs/man/ups.conf.5 | 4 +- docs/man/upsc.8 | 4 +- docs/man/upscli_connect.3 | 4 +- docs/man/upscli_disconnect.3 | 4 +- docs/man/upscli_fd.3 | 4 +- docs/man/upscli_get.3 | 4 +- docs/man/upscli_list_next.3 | 4 +- docs/man/upscli_list_start.3 | 4 +- docs/man/upscli_readline.3 | 4 +- docs/man/upscli_sendline.3 | 4 +- docs/man/upscli_splitaddr.3 | 4 +- docs/man/upscli_splitname.3 | 4 +- docs/man/upscli_ssl.3 | 4 +- docs/man/upscli_strerror.3 | 4 +- docs/man/upscli_upserror.3 | 4 +- docs/man/upsclient.3 | 4 +- docs/man/upscmd.8 | 4 +- docs/man/upscode2.8 | 4 +- docs/man/upsd.8 | 4 +- docs/man/upsd.conf.5 | 4 +- docs/man/upsd.users.5 | 4 +- docs/man/upsdrvctl.8 | 4 +- docs/man/upsimage.cgi.8 | 4 +- docs/man/upslog.8 | 4 +- docs/man/upsmon.8 | 4 +- docs/man/upsmon.conf.5 | 4 +- docs/man/upsrw.8 | 4 +- docs/man/upssched.8 | 4 +- docs/man/upssched.conf.5 | 4 +- docs/man/upsset.cgi.8 | 4 +- docs/man/upsset.conf.5 | 4 +- docs/man/upsstats.cgi.8 | 4 +- docs/man/upsstats.html.5 | 4 +- docs/man/usbhid-ups.8 | 4 +- docs/man/victronups.8 | 4 +- docs/new-clients.txt | 10 + docs/nut-names.txt | 2 +- docs/stable-hcl.txt | 22 +- docs/website/Makefile.in | 12 + docs/website/news.txt | 6 +- docs/website/projects.txt | 37 +- docs/website/web-layout.conf | 8 +- drivers/Makefile.am | 27 +- drivers/Makefile.in | 149 +- drivers/apc-mib.c | 11 + drivers/apcsmart-old.c | 1501 ++++++++++++++ drivers/apcsmart-old.h | 291 +++ drivers/apcsmart.c | 1743 +++++++++++------ drivers/apcsmart.h | 374 ++-- drivers/apcsmart_tabs.c | 155 ++ drivers/apcsmart_tabs.h | 100 + drivers/bcmxcp.c | 135 +- drivers/bcmxcp.h | 18 + drivers/bcmxcp_ser.c | 2 +- drivers/bestfcom.c | 5 +- drivers/bestpower-mib.c | 4 + drivers/blazer.c | 9 + drivers/eaton-mib.c | 144 +- drivers/eaton-mib.h | 1 + drivers/ietf-mib.c | 3 +- drivers/main.c | 41 +- drivers/mge-hid.c | 144 +- drivers/mge-mib.c | 6 +- drivers/mge-utalk.c | 3 +- drivers/netvision-mib.c | 4 +- drivers/nut-ipmi.h | 57 + drivers/nut-ipmipsu.c | 240 +++ drivers/nut-libfreeipmi.c | 935 +++++++++ drivers/powerware-mib.c | 13 +- drivers/raritan-pdu-mib.c | 6 +- drivers/snmp-ups.c | 204 +- drivers/snmp-ups.h | 16 +- drivers/usb-common.c | 2 +- include/Makefile.in | 12 + include/config.h.in | 36 + include/nut_version.h | 2 +- include/parseconf.h | 2 + lib/Makefile.in | 12 + m4/nut_check_libavahi.m4 | 78 + m4/nut_check_libfreeipmi.m4 | 85 + m4/nut_check_os.m4 | 1 + m4/nut_report_feature.m4 | 3 +- scripts/Makefile.am | 3 +- scripts/Makefile.in | 15 +- scripts/README | 4 +- scripts/augeas/Makefile.in | 12 + scripts/augeas/README | 56 + scripts/augeas/nutupsconf.aug.in | 5 + scripts/avahi/nut.service.in | 34 + scripts/hal/Makefile.in | 12 + scripts/hal/ups-nut-device.fdi.in | 45 + scripts/hotplug/Makefile.in | 12 + scripts/hotplug/libhid.usermap | 10 + scripts/java/Makefile.am | 15 + scripts/java/Makefile.in | 441 +++++ scripts/java/README | 14 + scripts/java/jNut/README | 71 + scripts/java/jNut/pom.xml | 40 + .../java/org/networkupstools/jnut/Client.java | 619 ++++++ .../org/networkupstools/jnut/Command.java | 100 + .../java/org/networkupstools/jnut/Device.java | 279 +++ .../networkupstools/jnut/NutException.java | 107 + .../jnut/StringLineSocket.java | 137 ++ .../org/networkupstools/jnut/Variable.java | 120 ++ .../org/networkupstools/jnut/ClientTest.java | 95 + scripts/java/jNutList/README | 30 + scripts/java/jNutList/pom.xml | 62 + .../org/networkupstools/jnutlist/AppList.java | 112 ++ scripts/python/Makefile.in | 12 + scripts/systemd/Makefile.am | 21 + scripts/systemd/Makefile.in | 531 +++++ scripts/systemd/README | 8 + scripts/systemd/nut-driver.service.in | 10 + scripts/systemd/nut-monitor.service.in | 11 + scripts/systemd/nut-server.service.in | 12 + scripts/systemd/nutshutdown.in | 2 + scripts/udev/Makefile.am | 15 +- scripts/udev/Makefile.in | 29 +- scripts/udev/README | 23 +- scripts/udev/nut-ipmipsu.rules.in | 4 + scripts/udev/nut-usbups.rules.in | 10 + server/Makefile.in | 12 + tools/Makefile.am | 47 +- tools/Makefile.in | 332 +++- tools/nut-scanner/Makefile.am | 46 + tools/nut-scanner/Makefile.in | 797 ++++++++ tools/nut-scanner/nut-scan.h | 65 + tools/nut-scanner/nut-scanner.c | 415 ++++ tools/nut-scanner/nutscan-device.c | 183 ++ tools/nut-scanner/nutscan-device.h | 52 + tools/nut-scanner/nutscan-display.c | 112 ++ tools/nut-scanner/nutscan-ip.c | 219 +++ tools/nut-scanner/nutscan-ip.h | 42 + tools/nut-scanner/nutscan-snmp.h | 45 + tools/nut-scanner/nutscan-usb.h | 111 ++ tools/nut-scanner/scan_avahi.c | 338 ++++ tools/nut-scanner/scan_ipmi.c | 29 + tools/nut-scanner/scan_nut.c | 194 ++ tools/nut-scanner/scan_snmp.c | 520 +++++ tools/nut-scanner/scan_usb.c | 168 ++ tools/nut-scanner/scan_xml_http.c | 160 ++ tools/nut-snmpinfo.py | 137 ++ tools/nut-usbinfo.pl | 45 +- tools/svn2cl.authors | 14 +- 246 files changed, 18228 insertions(+), 1415 deletions(-) create mode 100644 docs/man/apcsmart-old.8 create mode 100644 docs/man/apcsmart-old.txt create mode 100644 docs/man/nut-ipmipsu.8 create mode 100644 docs/man/nut-ipmipsu.txt create mode 100644 docs/man/nut-scanner.8 create mode 100644 docs/man/nut-scanner.txt create mode 100644 docs/man/nutscan_add_device_to_device.3 create mode 100644 docs/man/nutscan_add_device_to_device.txt create mode 100644 docs/man/nutscan_add_option_to_device.3 create mode 100644 docs/man/nutscan_add_option_to_device.txt create mode 100644 docs/man/nutscan_cidr_to_ip.3 create mode 100644 docs/man/nutscan_cidr_to_ip.txt create mode 100644 docs/man/nutscan_display_parsable.3 create mode 100644 docs/man/nutscan_display_parsable.txt create mode 100644 docs/man/nutscan_display_ups_conf.3 create mode 100644 docs/man/nutscan_display_ups_conf.txt create mode 100644 docs/man/nutscan_free_device.3 create mode 100644 docs/man/nutscan_free_device.txt create mode 100644 docs/man/nutscan_new_device.3 create mode 100644 docs/man/nutscan_new_device.txt create mode 100644 docs/man/nutscan_scan_avahi.3 create mode 100644 docs/man/nutscan_scan_avahi.txt create mode 100644 docs/man/nutscan_scan_ipmi.3 create mode 100644 docs/man/nutscan_scan_ipmi.txt create mode 100644 docs/man/nutscan_scan_nut.3 create mode 100644 docs/man/nutscan_scan_nut.txt create mode 100644 docs/man/nutscan_scan_snmp.3 create mode 100644 docs/man/nutscan_scan_snmp.txt create mode 100644 docs/man/nutscan_scan_usb.3 create mode 100644 docs/man/nutscan_scan_usb.txt create mode 100644 docs/man/nutscan_scan_xml_http.3 create mode 100644 docs/man/nutscan_scan_xml_http.txt create mode 100644 drivers/apcsmart-old.c create mode 100644 drivers/apcsmart-old.h create mode 100644 drivers/apcsmart_tabs.c create mode 100644 drivers/apcsmart_tabs.h create mode 100644 drivers/nut-ipmi.h create mode 100644 drivers/nut-ipmipsu.c create mode 100644 drivers/nut-libfreeipmi.c create mode 100644 m4/nut_check_libavahi.m4 create mode 100644 m4/nut_check_libfreeipmi.m4 create mode 100644 scripts/avahi/nut.service.in create mode 100644 scripts/java/Makefile.am create mode 100644 scripts/java/Makefile.in create mode 100644 scripts/java/README create mode 100644 scripts/java/jNut/README create mode 100644 scripts/java/jNut/pom.xml create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/Command.java create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/NutException.java create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java create mode 100644 scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java create mode 100644 scripts/java/jNut/src/test/java/org/networkupstools/jnut/ClientTest.java create mode 100644 scripts/java/jNutList/README create mode 100644 scripts/java/jNutList/pom.xml create mode 100644 scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java create mode 100644 scripts/systemd/Makefile.am create mode 100644 scripts/systemd/Makefile.in create mode 100644 scripts/systemd/README create mode 100644 scripts/systemd/nut-driver.service.in create mode 100644 scripts/systemd/nut-monitor.service.in create mode 100644 scripts/systemd/nut-server.service.in create mode 100644 scripts/systemd/nutshutdown.in create mode 100644 scripts/udev/nut-ipmipsu.rules.in create mode 100644 tools/nut-scanner/Makefile.am create mode 100644 tools/nut-scanner/Makefile.in create mode 100644 tools/nut-scanner/nut-scan.h create mode 100644 tools/nut-scanner/nut-scanner.c create mode 100644 tools/nut-scanner/nutscan-device.c create mode 100644 tools/nut-scanner/nutscan-device.h create mode 100644 tools/nut-scanner/nutscan-display.c create mode 100644 tools/nut-scanner/nutscan-ip.c create mode 100644 tools/nut-scanner/nutscan-ip.h create mode 100644 tools/nut-scanner/nutscan-snmp.h create mode 100644 tools/nut-scanner/nutscan-usb.h create mode 100644 tools/nut-scanner/scan_avahi.c create mode 100644 tools/nut-scanner/scan_ipmi.c create mode 100644 tools/nut-scanner/scan_nut.c create mode 100644 tools/nut-scanner/scan_snmp.c create mode 100644 tools/nut-scanner/scan_usb.c create mode 100644 tools/nut-scanner/scan_xml_http.c create mode 100755 tools/nut-snmpinfo.py diff --git a/ChangeLog b/ChangeLog index 12e3085..0e1be23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,438 @@ +2011-09-15 Arnaud Quette + + * [r3238] drivers/nut-ipmipsu.c, drivers/nut-libfreeipmi.c: Don't + override PSU absence with the power failure flag + * [r3237] NEWS, UPGRADING, configure.in, docs/download.txt, + docs/website/news.txt: Final update for 2.6.2 release + * [r3236] docs/configure.txt: Complete the minimum FreeIPMI version + required + * [r3235] tools/nut-scanner: Mark remaining generated files as a + Subversion ignored files (no functional changes) + +2011-09-15 Frederic Bohe + + * [r3234] tools/nut-scanner/scan_nut.c: Conditional inclusion of + pthread.h + * [r3233] tools/nut-scanner/nut-scanner.c, + tools/nut-scanner/nutscan-display.c, + tools/nut-scanner/scan_avahi.c, tools/nut-scanner/scan_ipmi.c, + tools/nut-scanner/scan_nut.c, tools/nut-scanner/scan_usb.c, + tools/nut-scanner/scan_xml_http.c: config.h is included in + common.h, so only include common.h + * [r3232] include/parseconf.h: We need stdio.h because we use FILE + type. + +2011-09-15 Arnaud Quette + + * [r3231] docs/man: Mark remaining generated manual pages as a + Subversion ignored files (no functional changes) + * [r3230] docs/man/nut-ipmipsu.txt, drivers/nut-ipmi.h, + drivers/nut-ipmipsu.c, drivers/nut-libfreeipmi.c, + m4/nut_check_libfreeipmi.m4: Complete nut-ipmipsu, by adding + sensors discovery and monitoring + +2011-09-14 Frederic Bohe + + * [r3229] tools/nut-scanner/scan_snmp.c: Remove use of strndup. + This is not supported on Solaris. + +2011-09-14 Charles Lepple + + * [r3228] tools/nut-scanner/scan_snmp.c: Remove unbalanced #endif + * [r3227] tools/nut-scanner/scan_snmp.c: nut-scanner: use + "common.h", which includes "config.h" + * [r3226] tools/nut-scanner/scan_snmp.c, + tools/nut-scanner/scan_usb.c: Include for nut-scanner + * [r3225] tools/nut-scanner/scan_snmp.c: Silence redefined PACKAGE_ + macro warnings + + This should be fixed properly upstream, but in the mean time, the + SNMP-based + tools can't use these macros properly (since they will have the + values for + Net-SNMP, not NUT). + +2011-09-14 Frederic Bohe + + * [r3224] tools/nut-scanner/nutscan-ip.c: Get rid of s6_addr32 in + IPv6 code since it is implementation specific. Replaced by + s6_addr. ( thanks to Charles Lepple) + +2011-09-14 Arnaud Quette + + * [r3223] drivers: Mark apcsmart-old binary as a Subversion ignored + file (no functional changes) + +2011-09-14 Emilien Kia + + * [r3222] + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Command.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/NutException.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java: + Fix mail address typo for javadoc. + +2011-09-13 Frederic Bohe + + * [r3221] tools/nut-scanner/Makefile.am: Fix make distcheck-light + +2011-09-13 Arnaud Quette + + * [r3220] drivers/bcmxcp.c: Fix compilation warning on values + comparison being always false + * [r3219] configure.in, tools/nut-scanner/nut-scanner.c: Complete + commit r3218, to address getopt_long too + * [r3218] configure.in: Do a second check to ensure inclusion of + getopt.h, in case optind is known + * [r3217] drivers/bcmxcp.c, drivers/bcmxcp.h, drivers/bcmxcp_ser.c: + Add support for outlet.n.delay.{start,shutdown}, and use + outlet.n.delay.shutdown for outlet.n.shutdown.return instead of + the default 3 seconds (patch from Rich Wrenn) + +2011-09-13 Frederic Bohe + + * [r3216] tools/nut-scanner/nutscan-ip.c: Do not use long long + variable anymore + * [r3215] tools/nut-scanner/scan_avahi.c, + tools/nut-scanner/scan_nut.c: Remove all calls to asprintf + +2011-09-12 Frederic Bohe + + * [r3214] clients/upsclient.c, clients/upsclient.h, configure.in, + docs/man/Makefile.am, docs/man/nut-scanner.txt, + docs/man/nutscan_add_device_to_device.txt, + docs/man/nutscan_add_option_to_device.txt, + docs/man/nutscan_cidr_to_ip.txt, + docs/man/nutscan_display_parsable.txt, + docs/man/nutscan_display_ups_conf.txt, + docs/man/nutscan_free_device.txt, + docs/man/nutscan_new_device.txt, docs/man/nutscan_scan_avahi.txt, + docs/man/nutscan_scan_ipmi.txt, docs/man/nutscan_scan_nut.txt, + docs/man/nutscan_scan_snmp.txt, docs/man/nutscan_scan_usb.txt, + docs/man/nutscan_scan_xml_http.txt, m4/nut_check_libavahi.m4, + tools/Makefile.am, tools/nut-scanner, + tools/nut-scanner/Makefile.am, tools/nut-scanner/nut-scan.h, + tools/nut-scanner/nut-scanner.c, + tools/nut-scanner/nutscan-device.c, + tools/nut-scanner/nutscan-device.h, + tools/nut-scanner/nutscan-display.c, + tools/nut-scanner/nutscan-ip.c, tools/nut-scanner/nutscan-ip.h, + tools/nut-scanner/scan_avahi.c, tools/nut-scanner/scan_ipmi.c, + tools/nut-scanner/scan_nut.c, tools/nut-scanner/scan_snmp.c, + tools/nut-scanner/scan_usb.c, tools/nut-scanner/scan_xml_http.c, + tools/nut-snmpinfo.py, tools/nut-usbinfo.pl: Add nut-scanner tool + +2011-09-12 Michal Soltys + + * [r3211] docs/man/Makefile.am, docs/man/apcsmart-old.txt, + docs/man/apcsmart.txt, drivers/Makefile.am, + drivers/apcsmart-old.c, drivers/apcsmart-old.h, + drivers/apcsmart.c, drivers/apcsmart.h, drivers/apcsmart_tabs.c, + drivers/apcsmart_tabs.h: merge updated apcsmart driver from + apcsmart-dev branch + + This commit clones trunk apcsmart to apcsmart-old, and merges + updated driver from apcsmart-dev. + + Both drivers are built and available for the users, should there + be any issues with the new version. + + The driver/table version is also incremented (3.0). + +2011-09-12 Charles Lepple + + * [r3206] docs/FAQ.txt: Reword rewording in FAQ + +2011-09-09 Arnaud Quette + + * [r3205] docs/FAQ.txt: Fix wording, that is not appropriate + anymore + * [r3204] docs/config-notes.txt: Complete shutdown information on + the "critical UPS" notion + * [r3203] docs/download.txt: Add missing comma for OpenWrt + * [r3202] docs/stable-hcl.txt: Complete information for reporting + new device + * [r3201] drivers/eaton-mib.c, drivers/eaton-mib.h, + drivers/snmp-ups.c: Add a missing Eaton MIB for PDU + +2011-09-08 Arnaud Quette + + * [r3199] docs/download.txt: Forgotten commit for the new updated + Windows package + * [r3198] docs/website/web-layout.conf: Fix XHTML 1.1 compliance + (reported by W3C validators) + * [r3196] ., configure.in, m4/nut_check_os.m4, scripts/Makefile.am, + scripts/README, scripts/systemd, scripts/systemd/Makefile.am, + scripts/systemd/README, scripts/systemd/nut-driver.service.in, + scripts/systemd/nut-monitor.service.in, + scripts/systemd/nut-server.service.in, + scripts/systemd/nutshutdown.in: Add initial support for systemd + (patch from Michal Hlavinka) + +2011-09-06 Arnaud Quette + + * [r3194] drivers/apc-mib.c, drivers/bestpower-mib.c, + drivers/eaton-mib.c, drivers/ietf-mib.c, drivers/mge-mib.c, + drivers/netvision-mib.c, drivers/powerware-mib.c, + drivers/raritan-pdu-mib.c, drivers/snmp-ups.c, + drivers/snmp-ups.h: Add a new initialization method, that uses + sysObjectID (indirection to the main MIB of the device) to detect + supported devices. This speeds up even more init stage and should + render void the use of 'mib' option + * [r3193] drivers/snmp-ups.c: Force numeric OIDs resolution, ie do + not resolve to textual names. This is mostly for the convenience + of debug output + +2011-09-05 Arnaud Quette + + * [r3186] scripts/java/Makefile.am, scripts/java/jNutList/src/test: + Remove test code, since it is bound to jNut and not jNutList + (reported by Emilien Kia) + * [r3185] drivers/mge-hid.c: Add support for battery.runtime.low, + and end of battery life (life cycle monitoring) ; along with + measurements (outlet power factor, power, real power and current) + for 5 PX + * [r3184] configure.in, scripts/Makefile.am, scripts/java, + scripts/java/Makefile.am: Complete jNut automake integration + (distribution rules) + +2011-09-03 Arnaud Quette + + * [r3183] docs/man: Mark nut-ipmipsu.html as a Subversion ignored + files (no functional changes) + +2011-09-02 Arnaud Quette + + * [r3182] docs/new-clients.txt: Fix jNut Asciidoc integration + * [r3181] docs/download.txt, docs/new-clients.txt, + docs/website/news.txt, scripts/README, scripts/java/README, + scripts/java/jNut/README, scripts/java/jNutList/README: Integrate + jNUT information in the developer guide, along with news and + download section + * [r3180] docs/website/news.txt: Add the Beta NUT 2.6.1-1 package + for Windows, and some news history (just intended for VCS + history) + * [r3179] docs/website/projects.txt: Formatting fixes + +2011-09-02 Emilien Kia + + * [r3178] scripts/java, scripts/java/README, scripts/java/jNut, + scripts/java/jNut/README, scripts/java/jNut/pom.xml, + scripts/java/jNut/src, scripts/java/jNut/src/main, + scripts/java/jNut/src/main/java, + scripts/java/jNut/src/main/java/org, + scripts/java/jNut/src/main/java/org/networkupstools, + scripts/java/jNut/src/main/java/org/networkupstools/jnut, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Command.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/NutException.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java, + scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java, + scripts/java/jNut/src/main/resources, scripts/java/jNut/src/test, + scripts/java/jNut/src/test/java, + scripts/java/jNut/src/test/java/org, + scripts/java/jNut/src/test/java/org/networkupstools, + scripts/java/jNut/src/test/java/org/networkupstools/jnut, + scripts/java/jNut/src/test/java/org/networkupstools/jnut/ClientTest.java, + scripts/java/jNutList, scripts/java/jNutList/README, + scripts/java/jNutList/pom.xml, scripts/java/jNutList/src, + scripts/java/jNutList/src/main, + scripts/java/jNutList/src/main/java, + scripts/java/jNutList/src/main/java/org, + scripts/java/jNutList/src/main/java/org/networkupstools, + scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist, + scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java, + scripts/java/jNutList/src/main/resources, + scripts/java/jNutList/src/test, + scripts/java/jNutList/src/test/java, + scripts/java/jNutList/src/test/java/org, + scripts/java/jNutList/src/test/java/org/networkupstools, + scripts/java/jNutList/src/test/java/org/networkupstools/jnuttest, + scripts/java/jNutList/src/test/java/org/networkupstools/jnuttest/AppTest.java: + Add jNut (NUT client in Java) to trunk. + +2011-09-02 Arnaud Quette + + * [r3174] drivers/main.c: Remove extraneous empty line + +2011-08-31 Emilien Kia + + * [r3173] drivers/usb-common.c: Fix pointer check on wrong variable + (Patch from Thomas Jarosch) + * [r3172] drivers/mge-utalk.c: Fix use of uninitialized variable + (Patch from Thomas Jarosch) + * [r3171] common/common.c: Fix file descriptor leak (Patch from + Thomas Jarosch) + +2011-08-29 Arnaud Quette + + * [r3164] drivers/mge-hid.c: Add region/country management, to + improve features provided such as 'output.voltage.nominal' and 3S + Eco control + * [r3163] data/driver.list.in, drivers/mge-hid.c: Add Eaton 3S to + the list of usbhid-ups supported models + +2011-08-25 Arnaud Quette + + * [r3160] docs/nut-names.txt: Fix duplication + +2011-08-20 Charles Lepple + + * [r3158] m4/nut_report_feature.m4: Avoid implementation-specific + use of "echo" in autoconf + + http://pubs.opengroup.org/onlinepubs/009695399/utilities/echo.html + +2011-08-05 Charles Lepple + + * [r3150] configure.in: configure.in: minor changes to output + + * Capitalized "UPS" + * --with-drivers= : Only *build* specific drivers + +2011-07-30 Arnaud Quette + + * [r3149] data/driver.list.in: Add Cyber Power Systems CP1000AVRLCD + to the list of usbhid-ups supported models (reported by David C. + Rankin) + +2011-07-28 Arnaud Quette + + * [r3148] tools/nut-usbinfo.pl: Proper fix to r3012, which + satisfies both udev and upower + +2011-07-27 Arnaud Quette + + * [r3147] tools/nut-usbinfo.pl: Partially revert r3012. It caused a + udev regression, with several missing USB IDs (thanks to Pawel + Sikora for uncovering it) + * [r3146] scripts/augeas/README: Add a complete Python Augeas + example code + +2011-07-26 Arnaud Quette + + * [r3145] configure.in, docs/man/nut-ipmipsu.txt, scripts/udev, + scripts/udev/Makefile.am, scripts/udev/README, + scripts/udev/nut-ipmipsu.rules.in: Add udev rules file and + documentation for nut-ipmipsu + * [r3144] m4/nut_check_libfreeipmi.m4: Improve detection of the + needed functions + * [r3143] data/driver.list.in: Add Orvaldi 750 / 900SP to the list + of blazer_usb supported models (reported by Pawel Sikora) + * [r3142] drivers/nut-ipmipsu.c: Fix missing comment closure, add a + TODO list and remove unused variables + +2011-07-21 Charles Lepple + + * [r3141] tools/git-svn.authors: Added authors file for git-svn + synchronization + +2011-07-19 Arnaud Quette + + * [r3140] data/driver.list.in: Add POWEREX VI 1000 LED to the list + of blazer_usb supported models (reported by Sergey Talchuk) + +2011-07-17 Arnaud Quette + + * [r3139] data/driver.list.in: Add SVEN Power Pro+ series (USB ID + ffff:0000) to the list of blazer_usb supported models (reported + by Vlad) + +2011-07-16 Arnaud Quette + + * [r3138] configure.in: Fix --with-[free]ipmi configure option so + that it actually behave correctly in automatic detection mode + +2011-07-14 Arnaud Quette + + * [r3137] configure.in: Fix the typo that made its way into commit + r3136, and broke configure + * [r3136] configure.in, docs/configure.txt, docs/man, + docs/man/Makefile.am, docs/man/nut-ipmipsu.txt, drivers, + drivers/Makefile.am, drivers/nut-ipmi.h, drivers/nut-ipmipsu.c, + drivers/nut-libfreeipmi.c, m4/nut_check_libfreeipmi.m4: First + attempt to create a driver to monitor power supply units using + IPMI. This preliminary version only reads FRU (Field Replace + Unit) information, but not yet the sensor information (describing + if the PSU is present and online), and includes base + documentation (manpage and configure options). It currently + supports GNU FreeIPMI, but uses an abstract IPMI implementation + that will allow to use other IPMI toolkits + +2011-07-13 Arnaud Quette + + * [r3135] docs/configure.txt: Move several misplaced options to the + right sections + * [r3132] drivers/bestfcom.c: Remove unused variables (patch from + Regid Ichira, Debian bug #633756) + +2011-07-12 Arnaud Quette + + * [r3131] MAINTAINERS: Update the corporate mail address and some + details + +2011-07-08 Charles Lepple + + * [r3129] docs/acknowledgements.txt: Fix typo in link on + Acknowledgements page + +2011-07-07 Arnaud Quette + + * [r3127] docs/acknowledgements.txt: Move Arjen de Korte, NUT + Senior lieutenant, to the Retired members section. Thanks for all + his years of dedication to make NUT better + +2011-07-01 Arjen de Korte + + * [r3115] MAINTAINERS: It's been fun, but I feel the time has come + to say farewell. All the best... + +2011-06-29 Arnaud Quette + + * [r3109] configure.in, scripts/Makefile.am, scripts/avahi, + scripts/avahi/nut.service.in: Add Avahi support for NUT mDNS + publication, using a static service file + * [r3106] tools/svn2cl.authors: Add missing committers, and reorder + using the Project Member List: + https://alioth.debian.org/project/memberlist.php?group_id=30602 + +2011-06-28 Arnaud Quette + + * [r3105] data/driver.list.in: Add various models equiped with APC + AP9618 management card, including APC Smart-UPS RT XL, to the + list of snmp-ups supported models (reported by Angela Williams) + +2011-06-23 Arjen de Korte + + * [r3057] drivers/main.c: Try to prevent that drivers are started + multiple times for the same UPS. + +2011-06-17 Arjen de Korte + + * [r3047] docs/man/blazer.txt, drivers/blazer.c: Add preselection + of communication protocol used + +2011-06-16 Frederic Bohe + + * [r3045] drivers/snmp-ups.c: Fix SNMP v3 session initialisation + +2011-06-08 Arnaud Quette + + * [r3037] docs/website/web-layout.conf: Update the Firefox download + button, since the previous one has disappeared + * [r3036] docs/website/news.txt, docs/website/projects.txt: Add a + news entry, and a reference in the Related projects, on Dell + PowerVault NX3500, which uses NUT for power protection (approved + by Dell) + +2011-06-04 Arnaud Quette + + * [r3026] data/driver.list.in: Add PowerWalker VI 850 LCD to the + list of blazer_usb supported models (reported by Wayne Thomas) + 2011-06-01 Arnaud Quette * [r3023] docs/download.txt: Add the missing SHA-256 sum on the @@ -51,7 +486,7 @@ * [r3002] server/netinstcmd.c: Fix the missing 'extra value' handling for instant commands -2011-05-24 msoltyspl-guest +2011-05-24 Michal Soltys * [r2997] drivers/apcsmart.c: apcmsart.c: fix upsdrv_shutdown_advanced() - with 'continue' statement, sdcmd_*s @@ -136,7 +571,7 @@ [http://lists.alioth.debian.org/pipermail/nut-upsuser/2011-March/006770.html] -2011-03-31 fbohe-guest +2011-03-31 Frederic Bohe * [r2962] data/driver.list.in, drivers/mge-hid.c: Add Eaton Powerware 9140 to the list of usbhid-ups supported models @@ -153,7 +588,7 @@ which cause unresolved symbol on libupsclient users (reported by Fabrice Coutadeur on Ubuntu) -2011-03-23 fbohe-guest +2011-03-23 Frederic Bohe * [r2957] INSTALL: Reverting previous commit (should not be in the trunk) @@ -341,7 +776,7 @@ * [r2891] drivers/dummy-ups.c: Prefer 'snprintf' and 'snprintfcat' over 'strncat' (the latter can overflow the destination buffer) -2011-02-09 fbohe-guest +2011-02-09 Frederic Bohe * [r2888] drivers/dummy-ups.c: Fix a memory leak in dummy-ups driver diff --git a/MAINTAINERS b/MAINTAINERS index 7d403cc..c52d095 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -25,7 +25,7 @@ S: Status: (add others as necessary) In the case of drivers, "maintained" should only be used if you have -access to the hardware in question for testing. +access to the hardware in question for testing. Drivers ======= @@ -37,13 +37,9 @@ S: Maintained: apcsmart, belkin, bestups, cyberpower, dummycons, P: Arnaud Quette M: aquette.dev@gmail.com -M: arnaud.quette@mgeups.com +M: ArnaudQuette@eaton.com S: Maintained or Supported: dummy-ups, usbhid-ups, mge-shut, newmge-shut - mge-utalk, snmp-ups, HAL support - -P: Arjen de Korte -M: arjen@de-korte.org -S: Maintained: safenet, genericups, powerpanel, netxml-ups, usbhid-ups + mge-utalk, snmp-ups, ... P: Fabio Di Niro M: blaxwan@users.sourceforge.net diff --git a/Makefile.in b/Makefile.in index 2f6c7aa..2cd8916 100644 --- a/Makefile.in +++ b/Makefile.in @@ -38,7 +38,8 @@ host_triplet = @host@ target_triplet = @target@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ + $(srcdir)/Makefile.in $(top_srcdir)/configure \ + $(top_srcdir)/scripts/avahi/nut.service.in AUTHORS COPYING \ ChangeLog INSTALL NEWS TODO compile config.guess config.sub \ depcomp install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -48,6 +49,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -67,7 +70,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/config.h -CONFIG_CLEAN_FILES = +CONFIG_CLEAN_FILES = scripts/avahi/nut.service CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = @@ -166,10 +169,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -207,6 +214,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -271,6 +282,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -349,6 +362,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): +scripts/avahi/nut.service: $(top_builddir)/config.status $(top_srcdir)/scripts/avahi/nut.service.in + cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo diff --git a/NEWS b/NEWS index e381249..4552f1f 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,79 @@ If you're upgrading from an earlier version, see the UPGRADING file. For a complete list of changes, please refer to the ChangeLog file. +--------------------------------------------------------------------------- +Release notes for NUT 2.6.2 - what's new since 2.6.1: + + - NUT can now monitor power supply units (PSU) in servers, through IPMI, using + the new experimental 'nut-ipmipsu' driver. Users are encouraged to test it, + and send feedback and debug output to the development mailing list. + This requires GNU FreeIPMI (0.8.5 or higher) development package or files. + Thanks goes to Al Chu, FreeIPMI project leader, for his help during this + development. + + - NUT now provides a tool, called 'nut-scanner', to discover supported devices, + both local and remote. nut-scanner will help to ease the configuration step, + and power infrastructure discovery. + This development, sponsored by Eaton, supports the following methods: + * USB, + * SNMP, + * XML/HTTP (from Eaton), + * NUT servers, using the classic connect or Avahi / mDNS methods. + + IPMI support will be added in the next release. + A separate library, called 'libnutscan', is also available to provide these + feature. Future NUT releases will provides binding for the supported + languages (Perl, Python and Java). + + - NUT now provides a Java interface called 'jNut'. + This development, sponsored by Eaton, is currently limited to the client + interface. But it will be broaden to device discovery and configuration in + the future. + For more info, refer to nut/scripts/java/README, or the developer guide + (chapter 'Creating new client'). Javadoc documentation is also provided, + along with Java archives (.jar) in the Download section. + + - support for new devices: Eaton 3S ; Cyber Power Systems CP1000AVRLCD ; + various APC models equiped with APC AP9618 management card, including APC + Smart-UPS RT XL ; Orvaldi 750 / 900SP ; POWEREX VI 1000 LED ; PowerWalker + VI 850 LCD ; SVEN Power Pro+ series (USB ID ffff:0000). + + - A regression has been fixed in udev rules file. This previously caused + permission issues to owners of some USB devices. + + - Avahi support has been added, for NUT mDNS publication, through a static + service file (nut/scripts/avahi/nut.service). + + - usbhid-ups has had Eaton completion: some features have been improved, such + as 'output.voltage.nominal' ; 3S Eco control support has been added, along + with battery.runtime.low and end of battery life (life cycle monitoring) + support ; new measurements for 5 PX are also supported now (outlet power + factor, power, real power and current). + + - apcsmart has been updated to support more variables and features ; the + previous driver is however still available as 'apcsmart-old', in case of + issues. + + - bcmxcp now supports per outlet startup and shutdown delays setting ; shutdown + delay is also used, when available, for outlet.n.shutdown.return instead of + the default 3 seconds. + + - snmp-ups.c has a new initialization method, that uses sysObjectID, which is + a pointer to the prefered MIB of the device, to detect supported devices. + This speeds up even more init stage and should render void the use of 'mib' + option. SNMP v3 session initialisation has also been fixed, and Eaton PDU + support has been completed. + + - Initial support has been added for systemd, the System and Service Manager + from RedHat. + + - The chapter 'NUT configuration management with Augeas' of the developer guide + has received some completion: a complete Python Augeas example code is now + provided. + + - Finally, after years of dedication to NUT, Arjen de Korte is now retired. + Sincere thanks to you Arjen from us all. + --------------------------------------------------------------------------- Release notes for NUT 2.6.1 - what's new since 2.6.0: diff --git a/UPGRADING b/UPGRADING index 12680d9..ef7d59c 100644 --- a/UPGRADING +++ b/UPGRADING @@ -7,6 +7,12 @@ This file lists changes that affect users who installed older versions of this software. When upgrading from an older version, be sure to check this file to see if you need to make changes to your system. +Changes from 2.6.1 to 2.6.2 +--------------------------- + +- apcsmart driver has been replaced by a new implementation. In case of issue +with this new version, users can revert to apcsmart-old. + Changes from 2.6.0 to 2.6.1 --------------------------- diff --git a/aclocal.m4 b/aclocal.m4 index 99662b0..d5e9925 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -126,6 +126,164 @@ AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], | (ullmax / ull) | (ullmax % ull));]]) ]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation @@ -1139,6 +1297,8 @@ m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/nut_arg_with.m4]) m4_include([m4/nut_check_asciidoc.m4]) +m4_include([m4/nut_check_libavahi.m4]) +m4_include([m4/nut_check_libfreeipmi.m4]) m4_include([m4/nut_check_libgd.m4]) m4_include([m4/nut_check_libhal.m4]) m4_include([m4/nut_check_libneon.m4]) diff --git a/clients/Makefile.in b/clients/Makefile.in index 71f8770..29abfac 100644 --- a/clients/Makefile.in +++ b/clients/Makefile.in @@ -59,6 +59,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -229,10 +231,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -270,6 +276,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -334,6 +344,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/clients/upsclient.c b/clients/upsclient.c index 50177d1..a2fe4f5 100644 --- a/clients/upsclient.c +++ b/clients/upsclient.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "upsclient.h" #include "timehead.h" @@ -393,12 +394,17 @@ int upscli_sslcert(UPSCONN_t *ups, const char *file, const char *path, int verif #endif /* HAVE_SSL */ -int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags) +int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,struct timeval * timeout) { int sock_fd; struct addrinfo hints, *res, *ai; char sport[NI_MAXSERV]; int v; + fd_set wfds; + int ret; + int error; + socklen_t error_size; + long fd_flags; if (!ups) { return -1; @@ -466,7 +472,37 @@ int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags) continue; } + /* non blocking connect */ + if(timeout != NULL) { + fd_flags = fcntl(sock_fd, F_GETFL); + fd_flags |= O_NONBLOCK; + fcntl(sock_fd, F_SETFL, fd_flags); + } + while ((v = connect(sock_fd, ai->ai_addr, ai->ai_addrlen)) < 0) { + if(errno == EINPROGRESS) { + FD_ZERO(&wfds); + FD_SET(sock_fd, &wfds); + ret = select(sock_fd+1,NULL,&wfds,NULL, + timeout); + if (FD_ISSET(sock_fd, &wfds)) { + error_size = sizeof(error); + getsockopt(sock_fd,SOL_SOCKET,SO_ERROR, + &error,&error_size); + if( error == 0) { + /* connect successful */ + v = 0; + break; + } + errno = error; + } + else { + /* Timeout */ + v = -1; + break; + } + } + switch (errno) { case EAFNOSUPPORT: @@ -486,6 +522,13 @@ int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags) continue; } + /* switch back to blocking operation */ + if(timeout != NULL) { + fd_flags = fcntl(sock_fd, F_GETFL); + fd_flags &= ~O_NONBLOCK; + fcntl(sock_fd, F_SETFL, fd_flags); + } + ups->fd = sock_fd; ups->upserror = 0; ups->syserrno = 0; @@ -529,6 +572,11 @@ int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags) return 0; } +int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags) +{ + return upscli_tryconnect(ups,host,port,flags,NULL); +} + /* map upsd error strings back to upsclient internal numbers */ static struct { int errnum; diff --git a/clients/upsclient.h b/clients/upsclient.h index 55ffd29..0188ab4 100644 --- a/clients/upsclient.h +++ b/clients/upsclient.h @@ -65,6 +65,8 @@ typedef struct { const char *upscli_strerror(UPSCONN_t *ups); +int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags, struct timeval *tv); + int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags); /* --- functions that only use the new names --- */ diff --git a/common/Makefile.in b/common/Makefile.in index c0e19e2..298bc93 100644 --- a/common/Makefile.in +++ b/common/Makefile.in @@ -47,6 +47,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -135,10 +137,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -176,6 +182,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -240,6 +250,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/common/common.c b/common/common.c index f443cb7..e8004d7 100644 --- a/common/common.c +++ b/common/common.c @@ -244,6 +244,7 @@ int sendsignalfn(const char *pidfn, int sig) if (fgets(buf, sizeof(buf), pidf) == NULL) { upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn); + fclose(pidf); return -1; } @@ -251,6 +252,7 @@ int sendsignalfn(const char *pidfn, int sig) if (pid < 2) { upslogx(LOG_NOTICE, "Ignoring invalid pid number %d", pid); + fclose(pidf); return -1; } @@ -259,6 +261,7 @@ int sendsignalfn(const char *pidfn, int sig) if (ret < 0) { perror("kill"); + fclose(pidf); return -1; } @@ -267,9 +270,11 @@ int sendsignalfn(const char *pidfn, int sig) if (ret < 0) { perror("kill"); + fclose(pidf); return -1; } + fclose(pidf); return 0; } diff --git a/conf/Makefile.in b/conf/Makefile.in index 18708a5..f0101e9 100644 --- a/conf/Makefile.in +++ b/conf/Makefile.in @@ -47,6 +47,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -140,10 +142,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -181,6 +187,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -245,6 +255,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/configure b/configure index 071b034..4054e72 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for nut 2.6.1. +# Generated by GNU Autoconf 2.67 for nut 2.6.2. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -698,8 +698,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='nut' PACKAGE_TARNAME='nut' -PACKAGE_VERSION='2.6.1' -PACKAGE_STRING='nut 2.6.1' +PACKAGE_VERSION='2.6.2' +PACKAGE_STRING='nut 2.6.2' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -747,6 +747,8 @@ am__EXEEXT_TRUE LTLIBOBJS udevdir hotplugdir +systemdsystemshutdowndir +systemdsystemunitdir pkgconfigdir driverexecdir cgiexecdir @@ -754,6 +756,7 @@ WORDS_BIGENDIAN SUN_LIBUSB RUN_AS_GROUP RUN_AS_USER +PORT BINDIR CONFPATH STATEPATH @@ -771,8 +774,12 @@ HAL_USER LIBWRAP_LIBS LIBWRAP_CFLAGS DOC_BUILD_LIST +LIBIPMI_LIBS +LIBIPMI_CFLAGS LIBPOWERMAN_LIBS LIBPOWERMAN_CFLAGS +LIBAVAHI_LIBS +LIBAVAHI_CFLAGS LIBNEON_LIBS LIBNEON_CFLAGS LIBUSB_LIBS @@ -790,6 +797,11 @@ WITH_UDEV_FALSE WITH_UDEV_TRUE WITH_HOTPLUG_FALSE WITH_HOTPLUG_TRUE +HAVE_SYSTEMD_FALSE +HAVE_SYSTEMD_TRUE +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG WITH_PKG_CONFIG_FALSE WITH_PKG_CONFIG_TRUE SOME_DRIVERS_FALSE @@ -824,8 +836,14 @@ WITH_WRAP_FALSE WITH_WRAP_TRUE WITH_SSL_FALSE WITH_SSL_TRUE +WITH_FREEIPMI_FALSE +WITH_FREEIPMI_TRUE +WITH_IPMI_FALSE +WITH_IPMI_TRUE WITH_LIBPOWERMAN_FALSE WITH_LIBPOWERMAN_TRUE +WITH_AVAHI_FALSE +WITH_AVAHI_TRUE WITH_NEONXML_FALSE WITH_NEONXML_TRUE WITH_SNMP_FALSE @@ -960,6 +978,12 @@ with_neon_libs with_powerman with_powerman_includes with_powerman_libs +with_avahi_includes +with_avahi_libs +with_ipmi +with_freeipmi +with_freeipmi_includes +with_freeipmi_libs with_ssl with_ssl_includes with_ssl_libs @@ -986,6 +1010,7 @@ with_logfacility with_drivers enable_strip with_pkgconfig_dir +with_systemdsystemunitdir with_hotplug_dir with_udev_dir ' @@ -997,7 +1022,10 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR' # Initialize some variables set by options. @@ -1540,7 +1568,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures nut 2.6.1 to adapt to many kinds of systems. +\`configure' configures nut 2.6.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1611,7 +1639,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of nut 2.6.1:";; + short | recursive ) echo "Configuration of nut 2.6.2:";; esac cat <<\_ACEOF @@ -1633,7 +1661,8 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-all enable serial, usb, snmp, neon, powerman, cgi, dev + --with-all enable serial, usb, snmp, neon, ipmi, powerman, cgi, + dev, avahi --with-dev build and install the development files (no) --with-serial build and install serial drivers (yes) --with-usb build and install USB drivers (auto) @@ -1665,6 +1694,16 @@ Optional Packages: include flags for the libpowerman library [--with-powerman-libs=LIBS] linker flags for the libpowerman library + [--with-avahi-includes=CFLAGS] + include flags for the avahi library + [--with-avahi-libs=LIBS] + linker flags for the avahi library + --with-ipmi build and install IPMI PSU driver (auto) + --with-freeipmi enable IPMI support using FreeIPMI (auto) + [--with-freeipmi-includes=CFLAGS] + include flags for the FreeIPMI library + [--with-freeipmi-libs=LIBS] + linker flags for the FreeIPMI library --with-ssl enable SSL development code (auto) [--with-ssl-includes=CFLAGS] include flags for the OpenSSL library @@ -1680,7 +1719,7 @@ Optional Packages: --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-statepath=PATH path for ups state files (/var/state/ups) --with-altpidpath=PATH path for driver/upsd .pid files () - --with-drvpath=PATH where to install ups drivers (EPREFIX/bin) + --with-drvpath=PATH where to install UPS drivers (EPREFIX/bin) --with-cgipath=PATH where to install CGI programs (EPREFIX/cgi-bin) --with-htmlpath=PATH where to install HTML files (PREFIX/html) --with-pidpath=PATH path for .pid files (/var/run) @@ -1691,10 +1730,12 @@ Optional Packages: --with-logfacility=FACILITY facility for log messages (LOG_DAEMON) [--with-drivers=driver[,driver]] - Only use specific drivers (all) + Only build specific drivers (all) --with-pkgconfig-dir=PATH where to install pkg-config *.pc files (EPREFIX/lib/pkgconfig) + --with-systemdsystemunitdir=DIR + Directory for systemd service files (auto) --with-hotplug-dir=PATH where to install hotplug rules (/etc/hotplug) --with-udev-dir=PATH where to install udev rules (/lib/udev or /etc/udev) @@ -1707,6 +1748,11 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1774,7 +1820,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -nut configure 2.6.1 +nut configure 2.6.2 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2239,7 +2285,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by nut $as_me 2.6.1, which was +It was created by nut $as_me 2.6.2, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2767,6 +2813,7 @@ test -n "$target_alias" && } + # Look for all possible source of OS name resolution # 1) we look for a LSB release info file eval "dist_search_path=\" @@ -3308,7 +3355,7 @@ fi # Define the identity of the package. PACKAGE='nut' - VERSION='2.6.1' + VERSION='2.6.2' cat >>confdefs.h <<_ACEOF @@ -4819,6 +4866,7 @@ fi + test "${prefix}" = "NONE" && prefix="${ac_default_prefix}" test "${exec_prefix}" = "NONE" && exec_prefix='${prefix}' @@ -6630,6 +6678,42 @@ done fi +for ac_header in getopt.h +do : + ac_fn_c_check_header_compile "$LINENO" "getopt.h" "ac_cv_header_getopt_h" "$ac_includes_default +" +if test "x$ac_cv_header_getopt_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETOPT_H 1 +_ACEOF + + +$as_echo "#define NEED_GETOPT_H 1" >>confdefs.h + + +else + + +$as_echo "#define NEED_GETOPT_DECLS 1" >>confdefs.h + + +fi + +done + + +for ac_func in getopt_long +do : + ac_fn_c_check_func "$LINENO" "getopt_long" "ac_cv_func_getopt_long" +if test "x$ac_cv_func_getopt_long" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETOPT_LONG 1 +_ACEOF + +fi +done + + ac_fn_c_check_decl "$LINENO" "uu_lock" "ac_cv_have_decl_uu_lock" " #include #include @@ -6866,6 +6950,66 @@ fi done +# pthread related checks +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +$as_echo_n "checking for library containing pthread_create... " >&6; } +if test "${ac_cv_search_pthread_create+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pthread; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pthread_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_pthread_create+set}" = set; then : + break +fi +done +if test "${ac_cv_search_pthread_create+set}" = set; then : + +else + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +$as_echo "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h + +fi + + ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include #include @@ -6946,6 +7090,8 @@ if test "${with_all+set}" = set; then : if test -z "${with_powerman}"; then with_powerman="${withval}"; fi if test -z "${with_cgi}"; then with_cgi="${withval}"; fi if test -z "${with_dev}"; then with_dev="${withval}"; fi + if test -z "${with_avahi}"; then with_avahi="${withval}"; fi + if test -z "${with_ipmi}"; then with_ipmi="${withval}"; fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"${withval}\"" >&5 $as_echo "\"${withval}\"" >&6; } else @@ -7821,6 +7967,143 @@ done fi +if test -z "${nut_have_avahi_seen}"; then + nut_have_avahi_seen=yes + + CFLAGS_ORIG="${CFLAGS}" + LIBS_ORIG="${LIBS}" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avahi-core version via pkg-config (0.6.30 minimum required)" >&5 +$as_echo_n "checking for avahi-core version via pkg-config (0.6.30 minimum required)... " >&6; } + AVAHI_CORE_VERSION="`pkg-config --silence-errors --modversion avahi-core 2>/dev/null`" + if test "$?" != "0" -o -z "${AVAHI_CORE_VERSION}"; then + AVAHI_CORE_VERSION="none" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${AVAHI_CORE_VERSION} found" >&5 +$as_echo "${AVAHI_CORE_VERSION} found" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avahi-client version via pkg-config (0.6.30 minimum required)" >&5 +$as_echo_n "checking for avahi-client version via pkg-config (0.6.30 minimum required)... " >&6; } + AVAHI_CLIENT_VERSION="`pkg-config --silence-errors --modversion avahi-client 2>/dev/null`" + if test "$?" != "0" -o -z "${AVAHI_CLIENT_VERSION}"; then + AVAHI_CLIENT_VERSION="none" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${AVAHI_CLIENT_VERSION} found" >&5 +$as_echo "${AVAHI_CLIENT_VERSION} found" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avahi cflags" >&5 +$as_echo_n "checking for avahi cflags... " >&6; } + +# Check whether --with-avahi-includes was given. +if test "${with_avahi_includes+set}" = set; then : + withval=$with_avahi_includes; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-avahi-includes - see docs/configure.txt" "$LINENO" 5 + ;; + *) + CFLAGS="${withval}" + ;; + esac + +else + CFLAGS="`pkg-config --silence-errors --cflags avahi-core avahi-client 2>/dev/null`" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CFLAGS}" >&5 +$as_echo "${CFLAGS}" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for avahi ldflags" >&5 +$as_echo_n "checking for avahi ldflags... " >&6; } + +# Check whether --with-avahi-libs was given. +if test "${with_avahi_libs+set}" = set; then : + withval=$with_avahi_libs; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-avahi-libs - see docs/configure.txt" "$LINENO" 5 + ;; + *) + LIBS="${withval}" + ;; + esac + +else + LIBS="`pkg-config --silence-errors --libs avahi-core avahi-client 2>/dev/null`" +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS}" >&5 +$as_echo "${LIBS}" >&6; } + + for ac_header in avahi-common/malloc.h +do : + ac_fn_c_check_header_compile "$LINENO" "avahi-common/malloc.h" "ac_cv_header_avahi_common_malloc_h" "$ac_includes_default +" +if test "x$ac_cv_header_avahi_common_malloc_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_AVAHI_COMMON_MALLOC_H 1 +_ACEOF + nut_have_avahi=yes +else + nut_have_avahi=no +fi + +done + + for ac_func in avahi_free +do : + ac_fn_c_check_func "$LINENO" "avahi_free" "ac_cv_func_avahi_free" +if test "x$ac_cv_func_avahi_free" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_AVAHI_FREE 1 +_ACEOF + +else + nut_have_avahi=no +fi +done + + + if test "${nut_have_avahi}" = "yes"; then + for ac_header in avahi-client/client.h +do : + ac_fn_c_check_header_compile "$LINENO" "avahi-client/client.h" "ac_cv_header_avahi_client_client_h" "$ac_includes_default +" +if test "x$ac_cv_header_avahi_client_client_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_AVAHI_CLIENT_CLIENT_H 1 +_ACEOF + nut_have_avahi=yes +else + nut_have_avahi=no +fi + +done + + for ac_func in avahi_client_new +do : + ac_fn_c_check_func "$LINENO" "avahi_client_new" "ac_cv_func_avahi_client_new" +if test "x$ac_cv_func_avahi_client_new" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_AVAHI_CLIENT_NEW 1 +_ACEOF + +else + nut_have_avahi=no +fi +done + + if test "${nut_have_avahi}" = "yes"; then + LIBAVAHI_CFLAGS="${CFLAGS}" + LIBAVAHI_LIBS="${LIBS}" + fi + fi + + CFLAGS="${CFLAGS_ORIG}" + LIBS="${LIBS_ORIG}" +fi + + case ${target_os} in solaris2.1* ) @@ -7911,7 +8194,8 @@ $as_echo "${nut_with_serial}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build serial drivers: ${nut_with_serial}" >> conf_nut_report_feature @@ -7943,7 +8227,8 @@ $as_echo "${nut_with_usb}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build USB drivers: ${nut_with_usb}" >> conf_nut_report_feature @@ -7975,7 +8260,8 @@ $as_echo "${nut_with_snmp}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build SNMP drivers: ${nut_with_snmp}" >> conf_nut_report_feature @@ -8007,11 +8293,44 @@ $as_echo "${nut_with_neon}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build neon based XML driver: ${nut_with_neon}" >> conf_nut_report_feature +if test "${nut_with_neon}" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define WITH_NEON 1 +_ACEOF + +fi + + +if test "${nut_with_avahi}" = "yes" -a "${nut_have_avahi}" != "yes"; then + as_fn_error $? "\"avahi libraries not found\"" "$LINENO" 5 +fi + +if test "${nut_with_avahi}" != "no"; then + nut_with_avahi="${nut_have_avahi}" +fi + + if test "${nut_with_avahi}" = "yes"; then + WITH_AVAHI_TRUE= + WITH_AVAHI_FALSE='#' +else + WITH_AVAHI_TRUE='#' + WITH_AVAHI_FALSE= +fi + +if test "${nut_with_avahi}" = "yes"; then + +cat >>confdefs.h <<_ACEOF +#define WITH_AVAHI 1 +_ACEOF + +fi @@ -8040,13 +8359,774 @@ $as_echo "${nut_with_powerman}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build Powerman PDU client driver: ${nut_with_powerman}" >> conf_nut_report_feature +nut_ipmi_lib="" + + +# Check whether --with-ipmi was given. +if test "${with_ipmi+set}" = set; then : + withval=$with_ipmi; nut_with_ipmi="${withval}" +else + nut_with_ipmi="auto" + +fi + + + +# Check whether --with-freeipmi was given. +if test "${with_freeipmi+set}" = set; then : + withval=$with_freeipmi; nut_with_freeipmi="${withval}" +else + nut_with_freeipmi="auto" + +fi + + + +if test "${nut_with_ipmi}" != "no"; then + if test "${nut_with_freeipmi}" = "yes"; then + +if test -z "${nut_have_libfreeipmi_seen}"; then + nut_have_libfreeipmi_seen=yes + + CFLAGS_ORIG="${CFLAGS}" + LIBS_ORIG="${LIBS}" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI version via pkg-config" >&5 +$as_echo_n "checking for FreeIPMI version via pkg-config... " >&6; } + FREEIPMI_VERSION="`pkg-config --silence-errors --modversion libfreeipmi 2>/dev/null`" + if test "$?" = "0" -a -n "${FREEIPMI_VERSION}"; then + CFLAGS="`pkg-config --silence-errors --cflags libfreeipmi libipmimonitoring 2>/dev/null`" + LIBS="`pkg-config --silence-errors --libs libfreeipmi libipmimonitoring 2>/dev/null`" + else + FREEIPMI_VERSION="none" + CFLAGS="" + LIBS="-lfreeipmi -lipmimonitoring" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FREEIPMI_VERSION} found" >&5 +$as_echo "${FREEIPMI_VERSION} found" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI cflags" >&5 +$as_echo_n "checking for FreeIPMI cflags... " >&6; } + +# Check whether --with-freeipmi-includes was given. +if test "${with_freeipmi_includes+set}" = set; then : + withval=$with_freeipmi_includes; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-freeipmi-includes - see docs/configure.txt" "$LINENO" 5 + ;; + *) + CFLAGS="${withval}" + ;; + esac + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CFLAGS}" >&5 +$as_echo "${CFLAGS}" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI ldflags" >&5 +$as_echo_n "checking for FreeIPMI ldflags... " >&6; } + +# Check whether --with-freeipmi-libs was given. +if test "${with_freeipmi_libs+set}" = set; then : + withval=$with_freeipmi_libs; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-freeipmi-libs - see docs/configure.txt" "$LINENO" 5 + ;; + *) + LIBS="${withval}" + ;; + esac + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS}" >&5 +$as_echo "${LIBS}" >&6; } + + for ac_header in freeipmi/freeipmi.h +do : + ac_fn_c_check_header_compile "$LINENO" "freeipmi/freeipmi.h" "ac_cv_header_freeipmi_freeipmi_h" "$ac_includes_default +" +if test "x$ac_cv_header_freeipmi_freeipmi_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FREEIPMI_FREEIPMI_H 1 +_ACEOF + nut_have_freeipmi=yes +else + nut_have_freeipmi=no +fi + +done + + for ac_header in ipmi_monitoring.h +do : + ac_fn_c_check_header_compile "$LINENO" "ipmi_monitoring.h" "ac_cv_header_ipmi_monitoring_h" "$ac_includes_default +" +if test "x$ac_cv_header_ipmi_monitoring_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IPMI_MONITORING_H 1 +_ACEOF + +else + nut_have_freeipmi=no +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_ctx_create" >&5 +$as_echo_n "checking for library containing ipmi_ctx_create... " >&6; } +if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_ctx_create (); +int +main () +{ +return ipmi_ctx_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_ctx_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + +else + ac_cv_search_ipmi_ctx_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_ctx_create" >&5 +$as_echo "$ac_cv_search_ipmi_ctx_create" >&6; } +ac_res=$ac_cv_search_ipmi_ctx_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_ctx_find_inband" >&5 +$as_echo_n "checking for library containing ipmi_ctx_find_inband... " >&6; } +if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_ctx_find_inband (); +int +main () +{ +return ipmi_ctx_find_inband (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_ctx_find_inband=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + +else + ac_cv_search_ipmi_ctx_find_inband=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_ctx_find_inband" >&5 +$as_echo "$ac_cv_search_ipmi_ctx_find_inband" >&6; } +ac_res=$ac_cv_search_ipmi_ctx_find_inband +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_fru_parse_ctx_create" >&5 +$as_echo_n "checking for library containing ipmi_fru_parse_ctx_create... " >&6; } +if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_fru_parse_ctx_create (); +int +main () +{ +return ipmi_fru_parse_ctx_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_fru_parse_ctx_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + +else + ac_cv_search_ipmi_fru_parse_ctx_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_fru_parse_ctx_create" >&5 +$as_echo "$ac_cv_search_ipmi_fru_parse_ctx_create" >&6; } +ac_res=$ac_cv_search_ipmi_fru_parse_ctx_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_monitoring_init" >&5 +$as_echo_n "checking for library containing ipmi_monitoring_init... " >&6; } +if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_monitoring_init (); +int +main () +{ +return ipmi_monitoring_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ipmimonitoring; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_monitoring_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + +else + ac_cv_search_ipmi_monitoring_init=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_monitoring_init" >&5 +$as_echo "$ac_cv_search_ipmi_monitoring_init" >&6; } +ac_res=$ac_cv_search_ipmi_monitoring_init +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + + if test "${nut_have_freeipmi}" = "yes"; then + nut_with_ipmi="yes" + nut_ipmi_lib="(FreeIPMI)" + nut_have_libipmi="yes" + +$as_echo "#define WITH_IPMI 1" >>confdefs.h + + +$as_echo "#define WITH_FREEIPMI 1" >>confdefs.h + + LIBIPMI_CFLAGS="${CFLAGS}" + LIBIPMI_LIBS="${LIBS}" + fi + + CFLAGS="${CFLAGS_ORIG}" + LIBS="${LIBS_ORIG}" +fi + + if test "${nut_have_freeipmi}" != "yes"; then + as_fn_error $? "\"GNU FreeIPMI not found, required for IPMI support\"" "$LINENO" 5 + fi + nut_with_ipmi="yes" + else + +if test -z "${nut_have_libfreeipmi_seen}"; then + nut_have_libfreeipmi_seen=yes + + CFLAGS_ORIG="${CFLAGS}" + LIBS_ORIG="${LIBS}" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI version via pkg-config" >&5 +$as_echo_n "checking for FreeIPMI version via pkg-config... " >&6; } + FREEIPMI_VERSION="`pkg-config --silence-errors --modversion libfreeipmi 2>/dev/null`" + if test "$?" = "0" -a -n "${FREEIPMI_VERSION}"; then + CFLAGS="`pkg-config --silence-errors --cflags libfreeipmi libipmimonitoring 2>/dev/null`" + LIBS="`pkg-config --silence-errors --libs libfreeipmi libipmimonitoring 2>/dev/null`" + else + FREEIPMI_VERSION="none" + CFLAGS="" + LIBS="-lfreeipmi -lipmimonitoring" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${FREEIPMI_VERSION} found" >&5 +$as_echo "${FREEIPMI_VERSION} found" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI cflags" >&5 +$as_echo_n "checking for FreeIPMI cflags... " >&6; } + +# Check whether --with-freeipmi-includes was given. +if test "${with_freeipmi_includes+set}" = set; then : + withval=$with_freeipmi_includes; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-freeipmi-includes - see docs/configure.txt" "$LINENO" 5 + ;; + *) + CFLAGS="${withval}" + ;; + esac + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${CFLAGS}" >&5 +$as_echo "${CFLAGS}" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FreeIPMI ldflags" >&5 +$as_echo_n "checking for FreeIPMI ldflags... " >&6; } + +# Check whether --with-freeipmi-libs was given. +if test "${with_freeipmi_libs+set}" = set; then : + withval=$with_freeipmi_libs; + case "${withval}" in + yes|no) + as_fn_error $? "invalid option --with(out)-freeipmi-libs - see docs/configure.txt" "$LINENO" 5 + ;; + *) + LIBS="${withval}" + ;; + esac + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${LIBS}" >&5 +$as_echo "${LIBS}" >&6; } + + for ac_header in freeipmi/freeipmi.h +do : + ac_fn_c_check_header_compile "$LINENO" "freeipmi/freeipmi.h" "ac_cv_header_freeipmi_freeipmi_h" "$ac_includes_default +" +if test "x$ac_cv_header_freeipmi_freeipmi_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FREEIPMI_FREEIPMI_H 1 +_ACEOF + nut_have_freeipmi=yes +else + nut_have_freeipmi=no +fi + +done + + for ac_header in ipmi_monitoring.h +do : + ac_fn_c_check_header_compile "$LINENO" "ipmi_monitoring.h" "ac_cv_header_ipmi_monitoring_h" "$ac_includes_default +" +if test "x$ac_cv_header_ipmi_monitoring_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_IPMI_MONITORING_H 1 +_ACEOF + +else + nut_have_freeipmi=no +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_ctx_create" >&5 +$as_echo_n "checking for library containing ipmi_ctx_create... " >&6; } +if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_ctx_create (); +int +main () +{ +return ipmi_ctx_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_ctx_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_ctx_create+set}" = set; then : + +else + ac_cv_search_ipmi_ctx_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_ctx_create" >&5 +$as_echo "$ac_cv_search_ipmi_ctx_create" >&6; } +ac_res=$ac_cv_search_ipmi_ctx_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_ctx_find_inband" >&5 +$as_echo_n "checking for library containing ipmi_ctx_find_inband... " >&6; } +if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_ctx_find_inband (); +int +main () +{ +return ipmi_ctx_find_inband (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_ctx_find_inband=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_ctx_find_inband+set}" = set; then : + +else + ac_cv_search_ipmi_ctx_find_inband=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_ctx_find_inband" >&5 +$as_echo "$ac_cv_search_ipmi_ctx_find_inband" >&6; } +ac_res=$ac_cv_search_ipmi_ctx_find_inband +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_fru_parse_ctx_create" >&5 +$as_echo_n "checking for library containing ipmi_fru_parse_ctx_create... " >&6; } +if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_fru_parse_ctx_create (); +int +main () +{ +return ipmi_fru_parse_ctx_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' freeipmi; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_fru_parse_ctx_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_fru_parse_ctx_create+set}" = set; then : + +else + ac_cv_search_ipmi_fru_parse_ctx_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_fru_parse_ctx_create" >&5 +$as_echo "$ac_cv_search_ipmi_fru_parse_ctx_create" >&6; } +ac_res=$ac_cv_search_ipmi_fru_parse_ctx_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ipmi_monitoring_init" >&5 +$as_echo_n "checking for library containing ipmi_monitoring_init... " >&6; } +if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ipmi_monitoring_init (); +int +main () +{ +return ipmi_monitoring_init (); + ; + return 0; +} +_ACEOF +for ac_lib in '' ipmimonitoring; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ipmi_monitoring_init=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + break +fi +done +if test "${ac_cv_search_ipmi_monitoring_init+set}" = set; then : + +else + ac_cv_search_ipmi_monitoring_init=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ipmi_monitoring_init" >&5 +$as_echo "$ac_cv_search_ipmi_monitoring_init" >&6; } +ac_res=$ac_cv_search_ipmi_monitoring_init +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + nut_have_freeipmi=no +fi + + + if test "${nut_have_freeipmi}" = "yes"; then + nut_with_ipmi="yes" + nut_ipmi_lib="(FreeIPMI)" + nut_have_libipmi="yes" + +$as_echo "#define WITH_IPMI 1" >>confdefs.h + + +$as_echo "#define WITH_FREEIPMI 1" >>confdefs.h + + LIBIPMI_CFLAGS="${CFLAGS}" + LIBIPMI_LIBS="${LIBS}" + fi + + CFLAGS="${CFLAGS_ORIG}" + LIBS="${LIBS_ORIG}" +fi + + if test "${nut_have_freeipmi}" != "yes"; then + if test "${nut_with_ipmi}" = "yes"; then + as_fn_error $? "\"FreeIPMI not found, required for IPMI support\"" "$LINENO" 5 + fi + nut_with_ipmi="no" + else + nut_with_ipmi="yes" + nut_with_freeipmi="yes" + fi + fi +fi + + if test "${nut_with_ipmi}" = "yes"; then + WITH_IPMI_TRUE= + WITH_IPMI_FALSE='#' +else + WITH_IPMI_TRUE='#' + WITH_IPMI_FALSE= +fi + + if test "${nut_with_freeipmi}" = "yes"; then + WITH_FREEIPMI_TRUE= + WITH_FREEIPMI_FALSE='#' +else + WITH_FREEIPMI_TRUE='#' + WITH_FREEIPMI_FALSE= +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build IPMI driver" >&5 +$as_echo_n "checking whether to build IPMI driver... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${nut_with_ipmi} ${nut_ipmi_lib}" >&5 +$as_echo "${nut_with_ipmi} ${nut_ipmi_lib}" >&6; } + if test -z "${nut_report_feature_flag}"; then + nut_report_feature_flag="1" + ac_clean_files="${ac_clean_files} conf_nut_report_feature" + echo > conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature + fi + echo "build IPMI driver: ${nut_with_ipmi} ${nut_ipmi_lib}" >> conf_nut_report_feature + + + + # Check whether --with-ssl was given. if test "${with_ssl+set}" = set; then : @@ -8188,7 +9268,8 @@ $as_echo "${nut_with_ssl}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "enable SSL development code: ${nut_with_ssl}" >> conf_nut_report_feature @@ -8383,7 +9464,8 @@ $as_echo "${nut_with_wrap}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "enable libwrap (tcp-wrappers) support: ${nut_with_wrap}" >> conf_nut_report_feature @@ -8595,7 +9677,8 @@ $as_echo "${nut_with_cgi}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build CGI programs: ${nut_with_cgi}" >> conf_nut_report_feature @@ -8635,7 +9718,8 @@ $as_echo "${nut_with_hal}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "enable HAL support: ${nut_with_hal}" >> conf_nut_report_feature @@ -9104,7 +10188,8 @@ $as_echo "${nut_with_doc}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build and install documentation: ${nut_with_doc}" >> conf_nut_report_feature @@ -9115,7 +10200,8 @@ if test "${nut_with_doc}" = "yes"; then nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "only build specific documentation format: ${DOC_BUILD_LIST}" >> conf_nut_report_feature @@ -9601,13 +10687,13 @@ if test "${lt_cv_nm_interface+set}" = set; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:9604: $ac_compile\"" >&5) + (eval echo "\"\$as_me:10690: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:9607: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:10693: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:9610: output\"" >&5) + (eval echo "\"\$as_me:10696: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -10812,7 +11898,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 10815 "configure"' > conftest.$ac_ext + echo '#line 11901 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -12074,11 +13160,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12077: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13163: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12081: \$? = $ac_status" >&5 + echo "$as_me:13167: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12413,11 +13499,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12416: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13502: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12420: \$? = $ac_status" >&5 + echo "$as_me:13506: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -12518,11 +13604,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12521: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13607: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12525: \$? = $ac_status" >&5 + echo "$as_me:13611: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12573,11 +13659,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12576: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13662: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12580: \$? = $ac_status" >&5 + echo "$as_me:13666: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14957,7 +16043,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 14960 "configure" +#line 16046 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15053,7 +16139,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 15056 "configure" +#line 16142 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15330,7 +16416,8 @@ $as_echo "${nut_with_dev}" >&6; } nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "build and install the development files: ${nut_with_dev}" >> conf_nut_report_feature @@ -15665,7 +16752,8 @@ if test "${DRIVER_BUILD_LIST}" != "all"; then nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "only build specific drivers: ${DRIVER_BUILD_LIST}" >> conf_nut_report_feature @@ -15748,6 +16836,162 @@ else fi + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi +systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install systemd files" >&5 +$as_echo_n "checking whether to install systemd files... " >&6; } + +# Check whether --with-systemdsystemunitdir was given. +if test "${with_systemdsystemunitdir+set}" = set; then : + withval=$with_systemdsystemunitdir; + case "${withval}" in + yes|auto) + ;; + no) + systemdsystemunitdir="" + ;; + *) + systemdsystemunitdir="${withval}" + ;; + esac + +fi + +if test -n "${systemdsystemunitdir}"; then + systemdsystemshutdowndir="/lib/systemd/system-shutdown" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using ${systemdsystemunitdir}" >&5 +$as_echo "using ${systemdsystemunitdir}" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + if test "$systemdsystemunitdir" != ""; then + HAVE_SYSTEMD_TRUE= + HAVE_SYSTEMD_FALSE='#' +else + HAVE_SYSTEMD_TRUE='#' + HAVE_SYSTEMD_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install hotplug rules" >&5 $as_echo_n "checking whether to install hotplug rules... " >&6; } @@ -16004,7 +17248,14 @@ _ACEOF -ac_config_files="$ac_config_files clients/Makefile common/Makefile conf/Makefile conf/upssched.conf.sample data/html/header.html data/html/Makefile data/Makefile data/driver.list docs/Makefile docs/man/Makefile docs/website/Makefile drivers/Makefile include/Makefile lib/libupsclient-config lib/libupsclient.pc lib/Makefile scripts/augeas/Makefile scripts/augeas/nutnutconf.aug scripts/augeas/nutupsconf.aug scripts/augeas/nutupsdconf.aug scripts/augeas/nutupsdusers.aug scripts/augeas/nutupsmonconf.aug scripts/augeas/nutupsschedconf.aug scripts/augeas/nuthostsconf.aug scripts/augeas/nutupssetconf.aug scripts/hal/Makefile scripts/hal/ups-nut-device.fdi scripts/hotplug/Makefile scripts/hotplug/libhidups scripts/python/Makefile scripts/udev/Makefile scripts/udev/nut-usbups.rules scripts/Makefile server/Makefile tools/Makefile Makefile" + + + + + + + +ac_config_files="$ac_config_files clients/Makefile common/Makefile conf/Makefile conf/upssched.conf.sample data/html/header.html data/html/Makefile data/Makefile data/driver.list docs/Makefile docs/man/Makefile docs/website/Makefile drivers/Makefile include/Makefile lib/libupsclient-config lib/libupsclient.pc lib/Makefile scripts/augeas/Makefile scripts/augeas/nutnutconf.aug scripts/augeas/nutupsconf.aug scripts/augeas/nutupsdconf.aug scripts/augeas/nutupsdusers.aug scripts/augeas/nutupsmonconf.aug scripts/augeas/nutupsschedconf.aug scripts/augeas/nuthostsconf.aug scripts/augeas/nutupssetconf.aug scripts/avahi/nut.service scripts/hal/Makefile scripts/hal/ups-nut-device.fdi scripts/hotplug/Makefile scripts/hotplug/libhidups scripts/java/Makefile scripts/python/Makefile scripts/systemd/Makefile scripts/udev/Makefile scripts/udev/nut-ipmipsu.rules scripts/udev/nut-usbups.rules scripts/Makefile server/Makefile tools/Makefile tools/nut-scanner/Makefile Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -16145,10 +17396,22 @@ if test -z "${WITH_NEONXML_TRUE}" && test -z "${WITH_NEONXML_FALSE}"; then as_fn_error $? "conditional \"WITH_NEONXML\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${WITH_AVAHI_TRUE}" && test -z "${WITH_AVAHI_FALSE}"; then + as_fn_error $? "conditional \"WITH_AVAHI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${WITH_LIBPOWERMAN_TRUE}" && test -z "${WITH_LIBPOWERMAN_FALSE}"; then as_fn_error $? "conditional \"WITH_LIBPOWERMAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${WITH_IPMI_TRUE}" && test -z "${WITH_IPMI_FALSE}"; then + as_fn_error $? "conditional \"WITH_IPMI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_FREEIPMI_TRUE}" && test -z "${WITH_FREEIPMI_FALSE}"; then + as_fn_error $? "conditional \"WITH_FREEIPMI\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${WITH_SSL_TRUE}" && test -z "${WITH_SSL_FALSE}"; then as_fn_error $? "conditional \"WITH_SSL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -16181,6 +17444,10 @@ if test -z "${WITH_PKG_CONFIG_TRUE}" && test -z "${WITH_PKG_CONFIG_FALSE}"; then as_fn_error $? "conditional \"WITH_PKG_CONFIG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_SYSTEMD_TRUE}" && test -z "${HAVE_SYSTEMD_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SYSTEMD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${WITH_HOTPLUG_TRUE}" && test -z "${WITH_HOTPLUG_FALSE}"; then as_fn_error $? "conditional \"WITH_HOTPLUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -16601,7 +17868,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by nut $as_me 2.6.1, which was +This file was extended by nut $as_me 2.6.2, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16667,7 +17934,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -nut config.status 2.6.1 +nut config.status 2.6.2 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" @@ -17079,16 +18346,21 @@ do "scripts/augeas/nutupsschedconf.aug") CONFIG_FILES="$CONFIG_FILES scripts/augeas/nutupsschedconf.aug" ;; "scripts/augeas/nuthostsconf.aug") CONFIG_FILES="$CONFIG_FILES scripts/augeas/nuthostsconf.aug" ;; "scripts/augeas/nutupssetconf.aug") CONFIG_FILES="$CONFIG_FILES scripts/augeas/nutupssetconf.aug" ;; + "scripts/avahi/nut.service") CONFIG_FILES="$CONFIG_FILES scripts/avahi/nut.service" ;; "scripts/hal/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/hal/Makefile" ;; "scripts/hal/ups-nut-device.fdi") CONFIG_FILES="$CONFIG_FILES scripts/hal/ups-nut-device.fdi" ;; "scripts/hotplug/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/hotplug/Makefile" ;; "scripts/hotplug/libhidups") CONFIG_FILES="$CONFIG_FILES scripts/hotplug/libhidups" ;; + "scripts/java/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/java/Makefile" ;; "scripts/python/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/python/Makefile" ;; + "scripts/systemd/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/systemd/Makefile" ;; "scripts/udev/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/udev/Makefile" ;; + "scripts/udev/nut-ipmipsu.rules") CONFIG_FILES="$CONFIG_FILES scripts/udev/nut-ipmipsu.rules" ;; "scripts/udev/nut-usbups.rules") CONFIG_FILES="$CONFIG_FILES scripts/udev/nut-usbups.rules" ;; "scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;; "server/Makefile") CONFIG_FILES="$CONFIG_FILES server/Makefile" ;; "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "tools/nut-scanner/Makefile") CONFIG_FILES="$CONFIG_FILES tools/nut-scanner/Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; diff --git a/configure.in b/configure.in index bdbb136..f362eaf 100644 --- a/configure.in +++ b/configure.in @@ -3,7 +3,7 @@ dnl | Network UPS Tools: configure.in | dnl +------------------------------------------------------------------+ dnl NUT version number is defined here and *only* here (no more include/version) -AC_INIT(nut, 2.6.1) +AC_INIT(nut, 2.6.2) AC_CONFIG_SRCDIR(server/upsd.c) AC_CONFIG_MACRO_DIR([m4]) echo "Network UPS Tools version ${PACKAGE_VERSION}" @@ -26,6 +26,8 @@ dnl Use "./configure --enable-maintainer-mode" to keep Makefile.in and Makefile dnl in sync after SVN updates. AM_MAINTAINER_MODE +dnl PKG_PROG_PKG_CONFIG + dnl # the following is commented out, because the UPS_VERSION macro now dnl # resides in include/nut_version.h, which is generated by Makefile.am, dnl # rather than in include/config.h, which is generated by configure. The @@ -110,7 +112,7 @@ fi case ${target_os} in hpux11* ) - dnl It seems like the thread safe string functions won't be included + dnl It seems like the thread safe string functions will not be included dnl on 64 bit HP-UX unless we define _REENTRANT CFLAGS="${CFLAGS} -D_REENTRANT" ;; @@ -126,6 +128,16 @@ AC_CHECK_DECLS(optind, [], [ ], [AC_INCLUDES_DEFAULT]) ], [AC_INCLUDES_DEFAULT]) +dnl do a 2nd check to ensure inclusion of getopt.h, in case optind is known +AC_CHECK_HEADERS(getopt.h, [ + AC_DEFINE(NEED_GETOPT_H, 1, [Define if getopt.h is needed]) +], [ + AC_DEFINE(NEED_GETOPT_DECLS, 1, [Define to use explicit getopt declarations]) +], [AC_INCLUDES_DEFAULT]) + +dnl also check for getopt_long +AC_CHECK_FUNCS(getopt_long) + dnl FreeBSD serial locking compatibility - look for uu_lock in libutil.h AC_CHECK_DECLS(uu_lock, [ AC_DEFINE(HAVE_UU_LOCK, 1, [Use uu_lock for locking (FreeBSD)]) @@ -154,6 +166,11 @@ AC_SEARCH_LIBS(connect, socket) AC_HEADER_TIME AC_CHECK_HEADERS(sys/modem.h stdarg.h varargs.h sys/termios.h sys/time.h, [], [], [AC_INCLUDES_DEFAULT]) +# pthread related checks +AC_SEARCH_LIBS([pthread_create], [pthread], + [AC_DEFINE(HAVE_PTHREAD, 1, [Define to enable pthread support code])], + []) + dnl ---------------------------------------------------------------------- dnl Check for types and define possible replacements NUT_TYPE_SOCKLEN_T @@ -162,8 +179,8 @@ dnl ---------------------------------------------------------------------- dnl check for --with-all (or --without-all, or --with-all=auto) flag AC_MSG_CHECKING(for --with-all) -AC_ARG_WITH(all, - AS_HELP_STRING([--with-all], [enable serial, usb, snmp, neon, powerman, cgi, dev]), +AC_ARG_WITH(all, + AS_HELP_STRING([--with-all], [enable serial, usb, snmp, neon, ipmi, powerman, cgi, dev, avahi]), [ if test -n "${withval}"; then dnl Note: we allow "no" as a positive value, because @@ -175,6 +192,8 @@ AC_ARG_WITH(all, if test -z "${with_powerman}"; then with_powerman="${withval}"; fi if test -z "${with_cgi}"; then with_cgi="${withval}"; fi if test -z "${with_dev}"; then with_dev="${withval}"; fi + if test -z "${with_avahi}"; then with_avahi="${withval}"; fi + if test -z "${with_ipmi}"; then with_ipmi="${withval}"; fi AC_MSG_RESULT("${withval}") else AC_MSG_RESULT(not given) @@ -210,6 +229,7 @@ NUT_ARG_WITH([neon], [build and install neon based XML/HTTP driver], [auto]) NUT_CHECK_LIBNEON NUT_ARG_WITH([powerman], [build and install Powerman PDU client driver], [auto]) NUT_CHECK_LIBPOWERMAN +NUT_CHECK_LIBAVAHI dnl ---------------------------------------------------------------------- dnl additional USB-related checks @@ -282,6 +302,26 @@ fi AM_CONDITIONAL(WITH_NEONXML, test "${nut_with_neon}" = "yes") NUT_REPORT_FEATURE([build neon based XML driver], [${nut_with_neon}]) +if test "${nut_with_neon}" = "yes"; then + AC_DEFINE_UNQUOTED(WITH_NEON, 1, [Define to enable Neon XML/HTTP support]) +fi + +dnl ---------------------------------------------------------------------- +dnl checks related to --with-avahi + +dnl ${nut_with_avahi}: any value except "yes" or "no" is treated as "auto". +if test "${nut_with_avahi}" = "yes" -a "${nut_have_avahi}" != "yes"; then + AC_MSG_ERROR(["avahi libraries not found"]) +fi + +if test "${nut_with_avahi}" != "no"; then + nut_with_avahi="${nut_have_avahi}" +fi + +AM_CONDITIONAL(WITH_AVAHI, test "${nut_with_avahi}" = "yes") +if test "${nut_with_avahi}" = "yes"; then + AC_DEFINE_UNQUOTED(WITH_AVAHI, 1, [Define to enable avahi support]) +fi dnl ---------------------------------------------------------------------- @@ -299,6 +339,68 @@ fi AM_CONDITIONAL(WITH_LIBPOWERMAN, test "${nut_with_powerman}" = "yes") NUT_REPORT_FEATURE([build Powerman PDU client driver], [${nut_with_powerman}]) +dnl ---------------------------------------------------------------------- +dnl Check for with-ipmi, and --with-freeipmi (or --with-openipmi) +dnl Only one can be enabled at a time, with a preference for FreeIPMI +dnl if both are available (since it is the only one supported ATM!!) + +nut_ipmi_lib="" + +NUT_ARG_WITH([ipmi], [build and install IPMI PSU driver], [auto]) +NUT_ARG_WITH([freeipmi], [enable IPMI support using FreeIPMI], [auto]) +dnl NUT_ARG_WITH([openipmi], [enable IPMI support using OpenIPMI], [auto]) + +dnl ${nut_with_ipmi}: any value except "yes" or "no" is treated as "auto". +if test "${nut_with_ipmi}" != "no"; then + dnl check if FreeIPMI (and maybe later OpenIPMI) was explicitly requested + if test "${nut_with_freeipmi}" = "yes"; then + NUT_CHECK_LIBFREEIPMI + if test "${nut_have_freeipmi}" != "yes"; then + AC_MSG_ERROR(["GNU FreeIPMI not found, required for IPMI support"]) + fi + dnl Implies --with-ipmi + nut_with_ipmi="yes" + dnl elif test "${nut_with_openipmi}" = "yes"; then + dnl AC_MSG_ERROR(["OpenIPMI is not yet supported"]) + dnl NUT_CHECK_LIBOPENIPMI + dnl if test "${nut_have_openipmi}" != "yes"; then + dnl AC_MSG_ERROR(["OpenIPMI not found, required for IPMI support"]) + dnl fi + dnl Implies --with-ipmi + dnl nut_with_ipmi="yes" + else + dnl Prefer FreeIPMI over OpenIPMI otherwise + NUT_CHECK_LIBFREEIPMI + if test "${nut_have_freeipmi}" != "yes"; then + if test "${nut_with_ipmi}" = "yes"; then + AC_MSG_ERROR(["FreeIPMI not found, required for IPMI support"]) + fi + nut_with_ipmi="no" + dnl NUT_CHECK_OPENIPMI + dnl if test "${nut_have_openipmi}" != "yes"; then + dnl if test "${nut_with_ipmi}" = "yes"; then + dnl AC_MSG_ERROR(["GNU FreeIPMI and OpenIPMI neither found, required for IPMI support"]) + dnl fi + dnl nut_with_ipmi="no" + dnl else + dnl Implies --with-ipmi + dnl nut_with_ipmi="yes" + dnl nut_with_openipmi="yes" + dnl fi + else + dnl Implies --with-ipmi + nut_with_ipmi="yes" + nut_with_freeipmi="yes" + fi + fi +fi + +AM_CONDITIONAL(WITH_IPMI, test "${nut_with_ipmi}" = "yes") +AM_CONDITIONAL(WITH_FREEIPMI, test "${nut_with_freeipmi}" = "yes") +dnl AM_CONDITIONAL(WITH_OPENIPMI, test "${nut_with_openipmi}" = "yes") + +NUT_REPORT_FEATURE([build IPMI driver], [${nut_with_ipmi} ${nut_ipmi_lib}]) + dnl ---------------------------------------------------------------------- dnl Check for --with-ssl @@ -550,7 +652,7 @@ AC_MSG_RESULT(${ALTPIDPATH}) AC_MSG_CHECKING(driver path) AC_ARG_WITH(drvpath, - AS_HELP_STRING([--with-drvpath=PATH], [where to install ups drivers (EPREFIX/bin)]), + AS_HELP_STRING([--with-drvpath=PATH], [where to install UPS drivers (EPREFIX/bin)]), [ case "${withval}" in yes|no) @@ -709,7 +811,7 @@ AC_ARG_WITH(drivers, AS_HELP_STRING([m4_version_prereq(2.62, [@<:@--with-drivers=driver@<:@,driver@:>@@:>@], [[[[--with-drivers=driver@<:@,driver@:>@]]]])], - [Only use specific drivers (all)]), + [Only build specific drivers (all)]), [ case "${withval}" in yes|no) @@ -783,6 +885,31 @@ else fi AM_CONDITIONAL(WITH_PKG_CONFIG, test -n "${pkgconfigdir}") +PKG_PROG_PKG_CONFIG +systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd` +AC_MSG_CHECKING(whether to install systemd files) +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files (auto)]), +[ + case "${withval}" in + yes|auto) + ;; + no) + systemdsystemunitdir="" + ;; + *) + systemdsystemunitdir="${withval}" + ;; + esac +], []) +if test -n "${systemdsystemunitdir}"; then + systemdsystemshutdowndir="/lib/systemd/system-shutdown" + AC_MSG_RESULT(using ${systemdsystemunitdir}) +else + AC_MSG_RESULT(no) +fi +AM_CONDITIONAL(HAVE_SYSTEMD, test "$systemdsystemunitdir" != "") + AC_MSG_CHECKING(whether to install hotplug rules) AC_ARG_WITH(hotplug-dir, AS_HELP_STRING([--with-hotplug-dir=PATH], [where to install hotplug rules (/etc/hotplug)]), @@ -875,8 +1002,12 @@ AC_SUBST(LIBUSB_CFLAGS) AC_SUBST(LIBUSB_LIBS) AC_SUBST(LIBNEON_CFLAGS) AC_SUBST(LIBNEON_LIBS) +AC_SUBST(LIBAVAHI_CFLAGS) +AC_SUBST(LIBAVAHI_LIBS) AC_SUBST(LIBPOWERMAN_CFLAGS) AC_SUBST(LIBPOWERMAN_LIBS) +AC_SUBST(LIBIPMI_CFLAGS) +AC_SUBST(LIBIPMI_LIBS) AC_SUBST(DOC_BUILD_LIST) AC_SUBST(LIBWRAP_CFLAGS) AC_SUBST(LIBWRAP_LIBS) @@ -894,6 +1025,7 @@ AC_SUBST(SERLIBS) AC_SUBST(STATEPATH) AC_SUBST(CONFPATH) AC_SUBST(BINDIR) +AC_SUBST(PORT) AC_SUBST(RUN_AS_USER) AC_SUBST(RUN_AS_GROUP) AC_SUBST(SUN_LIBUSB) @@ -902,6 +1034,8 @@ AC_SUBST(cgiexecdir) AC_SUBST(driverexecdir) AC_SUBST(htmldir) AC_SUBST(pkgconfigdir) +AC_SUBST(systemdsystemunitdir) +AC_SUBST(systemdsystemshutdowndir) AC_SUBST(hotplugdir) AC_SUBST(udevdir) @@ -931,16 +1065,21 @@ AC_OUTPUT([ scripts/augeas/nutupsschedconf.aug scripts/augeas/nuthostsconf.aug scripts/augeas/nutupssetconf.aug + scripts/avahi/nut.service scripts/hal/Makefile scripts/hal/ups-nut-device.fdi scripts/hotplug/Makefile scripts/hotplug/libhidups + scripts/java/Makefile scripts/python/Makefile + scripts/systemd/Makefile scripts/udev/Makefile + scripts/udev/nut-ipmipsu.rules scripts/udev/nut-usbups.rules scripts/Makefile server/Makefile tools/Makefile + tools/nut-scanner/Makefile Makefile ]) diff --git a/data/Makefile.in b/data/Makefile.in index b70eda8..bb341f0 100644 --- a/data/Makefile.in +++ b/data/Makefile.in @@ -47,6 +47,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -176,10 +178,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -217,6 +223,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -281,6 +291,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/data/driver.list.in b/data/driver.list.in index d1b2d5e..642aebf 100644 --- a/data/driver.list.in +++ b/data/driver.list.in @@ -62,6 +62,8 @@ "APC" "ups" "1" "Back-UPS" "940-0023A cable" "genericups upstype=9" "APC" "ups" "1" "Back-UPS Office" "940-0119A cable" "genericups upstype=12" "APC" "ups" "1" "Back-UPS RS 500" "custom non-USB cable" "genericups upstype=20" +"APC" "ups" "3" "Smart-UPS RT XL" "AP9618 SNMP monitoring card" "snmp-ups" +"APC" "ups" "3" "(various)" "AP9618 SNMP monitoring card" "snmp-ups" "APC" "pdu" "1" "Masterswitch" "940-0020 cable" "genericups upstype=12" "APC" "pdu" "1" "AP9210" "8 outlets" "powerman-pdu (experimental)" "APC" "pdu" "1" "AP79xx" "8 to 24 outlets" "powerman-pdu (experimental)" @@ -154,6 +156,7 @@ "Cyber Power Systems" "ups" "2" "Value 400E" "USB" "usbhid-ups" "Cyber Power Systems" "ups" "2" "Value 600E" "USB" "usbhid-ups" "Cyber Power Systems" "ups" "2" "Value 800E" "USB" "usbhid-ups" +"Cyber Power Systems" "ups" "2" "CP1000AVRLCD" "USB" "usbhid-ups" "Cyber Power Systems" "ups" "2" "CP1350AVRLCD" "USB" "usbhid-ups" "Cyber Power Systems" "ups" "2" "CP1500AVRLCD" "USB" "usbhid-ups" @@ -196,6 +199,7 @@ "Dynex" "ups" "1" "975AVR" "" "genericups upstype=7" "Dynex" "ups" "2" "DX-800U" "USB" "usbhid-ups" +"Eaton" "ups" "5" "3S" "" "usbhid-ups" "Eaton" "ups" "5" "Protection Station 500/650/800 VA" "USB" "usbhid-ups" "Eaton" "ups" "5" "Ellipse ECO 650/800/1200/1600 VA" "USB" "usbhid-ups" "Eaton" "ups" "5" "Ellipse ASR USBS 600/750/1000/1500 VA" "USB cable" "usbhid-ups" @@ -603,6 +607,7 @@ "Opti-UPS" "ups" "1" "PowerES" "420E" "optiups" "Orvaldi Power Protection" "ups" "2" "various" "not 400 or 600" "blazer_ser" +"Orvaldi Power Protection" "ups" "2" "750 / 900SP" "" "blazer_usb" "Phasak" "ups" "2" "400VA / 600VA" "" "blazer_ser" @@ -627,6 +632,8 @@ "Powercom" "ups" "4" "(various)" "USB (<= 2009 models, product id: 0002)" "powercom (requires 'usbserial' kernel module)" "Powercom" "ups" "5" "(various)" "USB (2009 models, product id: 00a?)" "usbhid-ups (experimental)" +"POWEREX" "ups" "2" "VI 1000 LED" "" "blazer_usb" + "PowerGuard" "ups" "2" "PG-600" "" "blazer_ser" "PowerKinetics" "ups" "1" "9001" "" "genericups upstype=17" @@ -643,6 +650,7 @@ "PowerWalker" "ups" "2" "Line-Interactive VI 400/800" "" "blazer_ser" "PowerWalker" "ups" "2" "Line-Interactive VI 600" "" "blazer_ser" "PowerWalker" "ups" "2" "Line-Interactive VI 1400" "" "blazer_usb" +"PowerWalker" "ups" "2" "Line-Interactive VI 850 LCD" "" "blazer_usb" "Powerware" "ups" "4" "3110" "" "genericups upstype=7" "Powerware" "ups" "4" "3115" "" "genericups upstype=11" @@ -707,6 +715,7 @@ "SuperPower" "ups" "2" "HP360, Hope-550" "" "blazer_ser" +"SVEN" "ups" "2" "Power Pro+ series" "USB" "blazer_usb (USB ID ffff:0000)" "SVEN" "ups" "2" "Power Pro+ series" "USB" "blazer_usb (USB ID 05b8:0000)" "SVEN" "ups" "1" "Power Pro+ series" "USB" "richcomm_usb (USB ID 0925:1234)" "SVEN" "ups" "2" "Power Smart RM 2000" "USB" "blazer_usb (USB ID 05b8:0000)" diff --git a/data/html/Makefile.in b/data/html/Makefile.in index 3e63f89..2900752 100644 --- a/data/html/Makefile.in +++ b/data/html/Makefile.in @@ -45,6 +45,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -135,10 +137,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -176,6 +182,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -240,6 +250,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/docs/FAQ.txt b/docs/FAQ.txt index 2e6126a..f9fb43e 100644 --- a/docs/FAQ.txt +++ b/docs/FAQ.txt @@ -518,9 +518,9 @@ usbhid-ups driver uses libusb (which is available for a wide range of operating systems) and libhid (currently, a modified internal version of it). -As of NUT 2.2, usbhid-ups completely replaces the legacy hidups driver -and provide support for various manufacturers. At that time, it will -be renamed to usbhid-ups. +As of NUT 2.2, usbhid-ups completely replaces the legacy hidups driver, +and provides support for various manufacturers. At that time, newhidups was +renamed to usbhid-ups. usbhid-ups is built automatically if possible (libusb development files need to be installed) and installed by the "make install" command. diff --git a/docs/Makefile.in b/docs/Makefile.in index 1030704..0a00378 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -43,6 +43,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -149,10 +151,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -190,6 +196,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -254,6 +264,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/docs/acknowledgements.txt b/docs/acknowledgements.txt index 01afa7f..e27f78e 100644 --- a/docs/acknowledgements.txt +++ b/docs/acknowledgements.txt @@ -20,7 +20,6 @@ Active members ~~~~~~~~~~~~~~ - Arnaud Quette: project leader (since 2005), Debian packager and jack of all trades -- Arjen de Korte: senior lieutenant - Charles Lepple: senior lieutenant - Kjell Claesson: senior developer - Alexander Gordeev: junior developer @@ -34,6 +33,7 @@ Retired members ~~~~~~~~~~~~~~~ - Russell Kroll: Founder, and project leader from 1996 to 2005 +- Arjen de Korte: senior lieutenant - Peter Selinger: senior lieutenant - Carlos Rodrigues: author of the "megatec" drivers, removing the numerous drivers for Megatec / Q1 protocol. These drivers have now been replaced by @@ -87,7 +87,7 @@ They also proposes NUT as an alternative to its software for link:http://www.microdowell.com/fra/download.html[Linux / Unix]. - link:http://pcmups.com.tw[Powercom], through Alexey Morozov, has provided -link:ups-protocol.html[extensive information] on its USB/HID devices, along +link:ups-protocols.html[extensive information] on its USB/HID devices, along with development units. Appliances manufacturers diff --git a/docs/config-notes.txt b/docs/config-notes.txt index e8a3299..42b6a54 100644 --- a/docs/config-notes.txt +++ b/docs/config-notes.txt @@ -339,7 +339,15 @@ Here are the steps that occur when a critical power event happens: 1. The UPS goes on battery -2. The UPS reaches low battery (a "critical" UPS) +2. The UPS reaches low battery (a "critical" UPS), that is to say + upsc displays: ++ + ups.status: OB LB ++ +The exact behavior depends on the specific device, and is related to: + + - battery.charge and battery.charge.low + - battery.runtime and battery.runtime.low 3. The upsmon master notices and sets "FSD" - the "forced shutdown" flag to tell all slave systems that it will soon power down the load. @@ -566,9 +574,10 @@ Testing shutdowns ^^^^^^^^^^^^^^^^^ UPS equipment varies from manufacturer to manufacturer and even within -model lines. You should test the shutdown sequence on your systems before -leaving them unattended. A successful sequence is one where the OS halts -before the battery runs out, and the system restarts when power returns. +model lines. You should test the <> +on your systems before leaving them unattended. A successful sequence +is one where the OS halts before the battery runs out, and the system +restarts when power returns. The first step is to see how upsdrvctl will behave without actually turning off power. To do so, use the '-t' argument: diff --git a/docs/configure.txt b/docs/configure.txt index 180ad7d..450f894 100644 --- a/docs/configure.txt +++ b/docs/configure.txt @@ -28,6 +28,22 @@ Note that you need to install libsnmp development package or files. Build and install the XML drivers (default: auto-detect) Note that you need to install neon development package or files. + --with-powerman + +Build and install Powerman PDU client driver (default: auto-detect) +This allows to interact with the Powerman daemon, and the numerous +Power Distribution Units (PDU) supported by the project. +Note that you need to install powerman development package or files. + + --with-ipmi + --with-freeipmi + +Build and install IPMI PSU driver (default: auto-detect) +This allows to monitor numerous Power Supply Units (PSU) found +on servers. +Note that you need to install freeipmi (0.8.5 or higher) development package or +files. + --with-drivers=,,... Specify exactly which driver or drivers to build and install (this @@ -48,16 +64,6 @@ If you need to build more drivers later on, you will need to rerun configure with a different list. To make it build all of the drivers from scratch again, run 'make clean' before starting. - --with-doc= (default: no) - -Build and install NUT documentation file(s). -The possible values are "html-single" for single page HTML, "html-chunked" -for multi pages HTML, "pdf" for a PDF file or "auto" to build all the -possible previous documentation formats. -Verbose output can be enabled using: ASCIIDOC_VERBOSE=-v make - -This feature requires AsciiDoc 8.6.3 (http://www.methods.co.nz/asciidoc). - Optional features ----------------- @@ -69,6 +75,16 @@ CGI configuration files. This is not enabled by default, as they are only useful on web servers. See data/html/README for additional information on how to set up CGI programs. + --with-doc= (default: no) + +Build and install NUT documentation file(s). +The possible values are "html-single" for single page HTML, "html-chunked" +for multi pages HTML, "pdf" for a PDF file or "auto" to build all the +possible previous documentation formats. +Verbose output can be enabled using: ASCIIDOC_VERBOSE=-v make + +This feature requires AsciiDoc 8.6.3 (http://www.methods.co.nz/asciidoc). + --with-lib (default: no) Build and install the upsclient library and header files. @@ -100,12 +116,6 @@ If you own a USB unit, only protect your local system and run the Gnome or KDE desktop, this will enable a full Plug & Play usage. See docs/nut-hal.txt for additional information on how to set up and use HAL support. - - --with-powerman (default: auto-detect) - -Build and install Powerman PDU client driver. -This allows to interact with the Powerman daemon, and the numerous -Power Distribution Units (PDU) supported by the project. Other configuration options diff --git a/docs/download.txt b/docs/download.txt index d4a25c2..feb8281 100644 --- a/docs/download.txt +++ b/docs/download.txt @@ -23,10 +23,10 @@ to do so. Stable tree: 2.6 ~~~~~~~~~~~~~~~~ -- link:http://www.networkupstools.org/source/2.6/nut-2.6.1.tar.gz[nut-2.6.1.tar.gz] -- link:http://www.networkupstools.org/source/2.6/nut-2.6.1.tar.gz.sig[PGP/GPG signature] +- link:http://www.networkupstools.org/source/2.6/nut-2.6.2.tar.gz[nut-2.6.2.tar.gz] +- link:http://www.networkupstools.org/source/2.6/nut-2.6.2.tar.gz.sig[PGP/GPG signature] - SHA-256 sum: 4ba1d297a98190db0ae86eb31136c780f35e6d3f47ae845316b44eaa9245a86e -- link:http://www.networkupstools.org/source/2.6/new-2.6.1.txt[Release notes] +- link:http://www.networkupstools.org/source/2.6/new-2.6.2.txt[Release notes] - link:http://www.networkupstools.org/source/2.6/ChangeLog[ChangeLog] You can also browse the link:http://www.networkupstools.org/source/2.6/[stable source directory]. @@ -101,7 +101,7 @@ link:http://packages.gentoo.org/package/sys-power/nut[Gentoo Linux], Mandriva, link:https://admin.fedoraproject.org/pkgdb/acls/name/nut[Red Hat / Fedora], link:http://software.opensuse.org/search[Novell Suse / openSUSE], -link:https://forum.openwrt.org/viewtopic.php?id=26269[OpenWrt] +link:https://forum.openwrt.org/viewtopic.php?id=26269[OpenWrt], link:http://packages.ubuntu.com/nut[Ubuntu]. - BSD systems: @@ -114,5 +114,11 @@ link:http://pdb.finkproject.org/pdb/package.php/nut[Fink], link:http://trac.macports.org/browser/trunk/dports/sysutils/nut/Portfile[MacPorts] - Windows (complete port, Beta): -link:http://www.networkupstools.org/source/2.6/NUT-Installer-2.6.0-1.msi[Windows MSI installer 2.6.0-1] +link:http://www.networkupstools.org/source/2.6/NUT-Installer-2.6.1-1.msi[Windows MSI installer 2.6.1-1] + +Java packages +------------- + +- NUT Java support (client side, Beta) +link:http://www.networkupstools.org/package/java/jNut-0.1-SNAPSHOT.tar.gz[jNUT 0.1-SNAPSHOT] diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am index b82f7b5..3d2b15c 100644 --- a/docs/man/Makefile.am +++ b/docs/man/Makefile.am @@ -7,8 +7,9 @@ # during 'make dist' # - HTML files are built upon request, if AsciiDoc is available, # - groff update will only happen if AsciiDoc is available too, -# - all this can probably (and hopefully) by improved, but I've not -# found a way to do pattern replacement on the fly for target deps! +# - all this can probably (and hopefully) be improved, but I've not +# found a way to do pattern replacement on the fly for target deps! +# FIXME: investigate an autogen.sh hook # - Ref: http://www.gnu.org/software/hello/manual/automake/Man-pages.html # Base configuration and client manpages, always installed @@ -73,6 +74,13 @@ HTML_CLIENT_MANS = \ upsrw.html \ upssched.html +SRC_TOOL_PAGES = nut-scanner.txt + +MAN_TOOL_PAGES = nut-scanner.8 + +man8_MANS += $(MAN_TOOL_PAGES) + +HTML_TOOL_MANS = nut-scanner.html # CGI (--with-cgi) related manpages SRC_CGI_PAGES = \ @@ -124,6 +132,19 @@ SRC_DEV_PAGES = \ upscli_ssl.txt \ upscli_strerror.txt \ upscli_upserror.txt \ + nutscan_scan_snmp.txt \ + nutscan_scan_usb.txt \ + nutscan_scan_xml_http.txt \ + nutscan_scan_nut.txt \ + nutscan_scan_avahi.txt \ + nutscan_scan_ipmi.txt \ + nutscan_display_ups_conf.txt \ + nutscan_display_parsable.txt \ + nutscan_cidr_to_ip.txt \ + nutscan_new_device.txt \ + nutscan_free_device.txt \ + nutscan_add_option_to_device.txt \ + nutscan_add_device_to_device.txt \ libupsclient-config.txt \ skel.txt @@ -141,7 +162,20 @@ MAN3_DEV_PAGES = \ upscli_splitname.3 \ upscli_ssl.3 \ upscli_strerror.3 \ - upscli_upserror.3 + upscli_upserror.3 \ + nutscan_scan_snmp.3 \ + nutscan_scan_usb.3 \ + nutscan_scan_xml_http.3 \ + nutscan_scan_nut.3 \ + nutscan_scan_avahi.3 \ + nutscan_scan_ipmi.3 \ + nutscan_display_ups_conf.3 \ + nutscan_display_parsable.3 \ + nutscan_cidr_to_ip.3 \ + nutscan_new_device.3 \ + nutscan_free_device.3 \ + nutscan_add_option_to_device.3 \ + nutscan_add_device_to_device.3 MAN1_DEV_PAGES = \ libupsclient-config.1 @@ -170,6 +204,19 @@ HTML_DEV_MANS = \ upscli_ssl.html \ upscli_strerror.html \ upscli_upserror.html \ + nutscan_scan_snmp.html \ + nutscan_scan_usb.html \ + nutscan_scan_xml_http.html \ + nutscan_scan_nut.html \ + nutscan_scan_avahi.html \ + nutscan_scan_ipmi.html \ + nutscan_display_ups_conf.html \ + nutscan_display_parsable.html \ + nutscan_cidr_to_ip.html \ + nutscan_new_device.html \ + nutscan_free_device.html \ + nutscan_add_option_to_device.html \ + nutscan_add_device_to_device.html \ libupsclient-config.html \ skel.html @@ -185,6 +232,7 @@ else # (--with-serial) SRC_SERIAL_PAGES = \ apcsmart.txt \ + apcsmart-old.txt \ bcmxcp.txt \ belkin.txt \ belkinunv.txt \ @@ -222,6 +270,7 @@ SRC_SERIAL_PAGES = \ MAN_SERIAL_PAGES = \ apcsmart.8 \ + apcsmart-old.8 \ bcmxcp.8 \ belkin.8 \ belkinunv.8 \ @@ -263,6 +312,7 @@ endif HTML_SERIAL_MANS = \ apcsmart.html \ + apcsmart-old.html \ bcmxcp.html \ belkin.html \ belkinunv.html \ @@ -351,12 +401,23 @@ endif HTML_POWERMAN_MANS = powerman-pdu.html +# (--with-ipmi) +SRC_IPMIPSU_PAGES = nut-ipmipsu.txt +MAN_IPMIPSU_PAGES = nut-ipmipsu.8 + +if WITH_IPMI + man8_MANS += $(MAN_IPMIPSU_PAGES) +endif + +HTML_IPMIPSU_MANS = nut-ipmipsu.html + # SOME_DRIVERS endif MAN_MANS = \ $(MAN_CONF_PAGES) \ $(MAN_CLIENT_PAGES) \ + $(MAN_TOOL_PAGES) \ $(MAN5_CGI_PAGES) \ $(MAN8_CGI_PAGES) \ $(MAN1_DEV_PAGES) \ @@ -365,13 +426,15 @@ MAN_MANS = \ $(MAN_SNMP_PAGES) \ $(MAN_USB_LIBUSB_PAGES) \ $(MAN_NETXML_PAGES) \ - $(MAN_POWERMAN_PAGES) + $(MAN_POWERMAN_PAGES) \ + $(MAN_IPMIPSU_PAGES) # distribute everything, even those not installed by default # Note that 'dist' target requires AsciiDoc! EXTRA_DIST = \ $(SRC_CONF_PAGES) \ $(SRC_CLIENT_PAGES) \ + $(SRC_TOOL_PAGES) \ $(SRC_CGI_PAGES) \ $(SRC_DEV_PAGES) \ $(SRC_SERIAL_PAGES) \ @@ -379,19 +442,22 @@ EXTRA_DIST = \ $(SRC_USB_LIBUSB_PAGES) \ $(SRC_NETXML_PAGES) \ $(SRC_POWERMAN_PAGES) \ + $(SRC_IPMIPSU_PAGES) \ $(MAN_MANS) \ asciidoc.conf HTML_MANS = \ $(HTML_CONF_MANS) \ $(HTML_CLIENT_MANS) \ + $(HTML_TOOL_MANS) \ $(HTML_CGI_MANS) \ $(HTML_DEV_MANS) \ $(HTML_SERIAL_MANS) \ $(HTML_SNMP_MANS) \ $(HTML_USB_LIBUSB_MANS) \ $(HTML_NETXML_MANS) \ - $(HTML_POWERMAN_MANS) + $(HTML_POWERMAN_MANS) \ + $(HTML_IPMIPSU_MANS) all: diff --git a/docs/man/Makefile.in b/docs/man/Makefile.in index 81b7335..5dabc94 100644 --- a/docs/man/Makefile.in +++ b/docs/man/Makefile.in @@ -24,8 +24,9 @@ # during 'make dist' # - HTML files are built upon request, if AsciiDoc is available, # - groff update will only happen if AsciiDoc is available too, -# - all this can probably (and hopefully) by improved, but I've not -# found a way to do pattern replacement on the fly for target deps! +# - all this can probably (and hopefully) be improved, but I've not +# found a way to do pattern replacement on the fly for target deps! +# FIXME: investigate an autogen.sh hook # - Ref: http://www.gnu.org/software/hello/manual/automake/Man-pages.html VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ @@ -59,6 +60,7 @@ target_triplet = @target@ @SOME_DRIVERS_FALSE@@WITH_USB_TRUE@am__append_6 = $(MAN_USB_LIBUSB_PAGES) @SOME_DRIVERS_FALSE@@WITH_NEONXML_TRUE@am__append_7 = $(MAN_NETXML_PAGES) @SOME_DRIVERS_FALSE@@WITH_LIBPOWERMAN_TRUE@am__append_8 = $(MAN_POWERMAN_PAGES) +@SOME_DRIVERS_FALSE@@WITH_IPMI_TRUE@am__append_9 = $(MAN_IPMIPSU_PAGES) subdir = docs/man DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -68,6 +70,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -163,10 +167,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -204,6 +212,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -268,6 +280,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -326,9 +340,10 @@ MAN_CLIENT_PAGES = \ upsrw.8 \ upssched.8 -man8_MANS = $(MAN_CLIENT_PAGES) $(am__append_2) $(am__append_3) \ - $(am__append_4) $(am__append_5) $(am__append_6) \ - $(am__append_7) $(am__append_8) +man8_MANS = $(MAN_CLIENT_PAGES) $(MAN_TOOL_PAGES) $(am__append_2) \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) $(am__append_7) $(am__append_8) \ + $(am__append_9) HTML_CLIENT_MANS = \ nutupsdrv.html \ upsc.html \ @@ -340,6 +355,9 @@ HTML_CLIENT_MANS = \ upsrw.html \ upssched.html +SRC_TOOL_PAGES = nut-scanner.txt +MAN_TOOL_PAGES = nut-scanner.8 +HTML_TOOL_MANS = nut-scanner.html # CGI (--with-cgi) related manpages SRC_CGI_PAGES = \ @@ -385,6 +403,19 @@ SRC_DEV_PAGES = \ upscli_ssl.txt \ upscli_strerror.txt \ upscli_upserror.txt \ + nutscan_scan_snmp.txt \ + nutscan_scan_usb.txt \ + nutscan_scan_xml_http.txt \ + nutscan_scan_nut.txt \ + nutscan_scan_avahi.txt \ + nutscan_scan_ipmi.txt \ + nutscan_display_ups_conf.txt \ + nutscan_display_parsable.txt \ + nutscan_cidr_to_ip.txt \ + nutscan_new_device.txt \ + nutscan_free_device.txt \ + nutscan_add_option_to_device.txt \ + nutscan_add_device_to_device.txt \ libupsclient-config.txt \ skel.txt @@ -402,7 +433,20 @@ MAN3_DEV_PAGES = \ upscli_splitname.3 \ upscli_ssl.3 \ upscli_strerror.3 \ - upscli_upserror.3 + upscli_upserror.3 \ + nutscan_scan_snmp.3 \ + nutscan_scan_usb.3 \ + nutscan_scan_xml_http.3 \ + nutscan_scan_nut.3 \ + nutscan_scan_avahi.3 \ + nutscan_scan_ipmi.3 \ + nutscan_display_ups_conf.3 \ + nutscan_display_parsable.3 \ + nutscan_cidr_to_ip.3 \ + nutscan_new_device.3 \ + nutscan_free_device.3 \ + nutscan_add_option_to_device.3 \ + nutscan_add_device_to_device.3 MAN1_DEV_PAGES = \ libupsclient-config.1 @@ -425,6 +469,19 @@ HTML_DEV_MANS = \ upscli_ssl.html \ upscli_strerror.html \ upscli_upserror.html \ + nutscan_scan_snmp.html \ + nutscan_scan_usb.html \ + nutscan_scan_xml_http.html \ + nutscan_scan_nut.html \ + nutscan_scan_avahi.html \ + nutscan_scan_ipmi.html \ + nutscan_display_ups_conf.html \ + nutscan_display_parsable.html \ + nutscan_cidr_to_ip.html \ + nutscan_new_device.html \ + nutscan_free_device.html \ + nutscan_add_option_to_device.html \ + nutscan_add_device_to_device.html \ libupsclient-config.html \ skel.html @@ -432,6 +489,7 @@ HTML_DEV_MANS = \ # (--with-serial) @SOME_DRIVERS_FALSE@SRC_SERIAL_PAGES = \ @SOME_DRIVERS_FALSE@ apcsmart.txt \ +@SOME_DRIVERS_FALSE@ apcsmart-old.txt \ @SOME_DRIVERS_FALSE@ bcmxcp.txt \ @SOME_DRIVERS_FALSE@ belkin.txt \ @SOME_DRIVERS_FALSE@ belkinunv.txt \ @@ -469,6 +527,7 @@ HTML_DEV_MANS = \ @SOME_DRIVERS_FALSE@MAN_SERIAL_PAGES = \ @SOME_DRIVERS_FALSE@ apcsmart.8 \ +@SOME_DRIVERS_FALSE@ apcsmart-old.8 \ @SOME_DRIVERS_FALSE@ bcmxcp.8 \ @SOME_DRIVERS_FALSE@ belkin.8 \ @SOME_DRIVERS_FALSE@ belkinunv.8 \ @@ -506,6 +565,7 @@ HTML_DEV_MANS = \ @SOME_DRIVERS_FALSE@HTML_SERIAL_MANS = \ @SOME_DRIVERS_FALSE@ apcsmart.html \ +@SOME_DRIVERS_FALSE@ apcsmart-old.html \ @SOME_DRIVERS_FALSE@ bcmxcp.html \ @SOME_DRIVERS_FALSE@ belkin.html \ @SOME_DRIVERS_FALSE@ belkinunv.html \ @@ -577,10 +637,16 @@ HTML_DEV_MANS = \ @SOME_DRIVERS_FALSE@MAN_POWERMAN_PAGES = powerman-pdu.8 @SOME_DRIVERS_FALSE@HTML_POWERMAN_MANS = powerman-pdu.html +# (--with-ipmi) +@SOME_DRIVERS_FALSE@SRC_IPMIPSU_PAGES = nut-ipmipsu.txt +@SOME_DRIVERS_FALSE@MAN_IPMIPSU_PAGES = nut-ipmipsu.8 +@SOME_DRIVERS_FALSE@HTML_IPMIPSU_MANS = nut-ipmipsu.html + # SOME_DRIVERS MAN_MANS = \ $(MAN_CONF_PAGES) \ $(MAN_CLIENT_PAGES) \ + $(MAN_TOOL_PAGES) \ $(MAN5_CGI_PAGES) \ $(MAN8_CGI_PAGES) \ $(MAN1_DEV_PAGES) \ @@ -589,7 +655,8 @@ MAN_MANS = \ $(MAN_SNMP_PAGES) \ $(MAN_USB_LIBUSB_PAGES) \ $(MAN_NETXML_PAGES) \ - $(MAN_POWERMAN_PAGES) + $(MAN_POWERMAN_PAGES) \ + $(MAN_IPMIPSU_PAGES) # distribute everything, even those not installed by default @@ -597,6 +664,7 @@ MAN_MANS = \ EXTRA_DIST = \ $(SRC_CONF_PAGES) \ $(SRC_CLIENT_PAGES) \ + $(SRC_TOOL_PAGES) \ $(SRC_CGI_PAGES) \ $(SRC_DEV_PAGES) \ $(SRC_SERIAL_PAGES) \ @@ -604,19 +672,22 @@ EXTRA_DIST = \ $(SRC_USB_LIBUSB_PAGES) \ $(SRC_NETXML_PAGES) \ $(SRC_POWERMAN_PAGES) \ + $(SRC_IPMIPSU_PAGES) \ $(MAN_MANS) \ asciidoc.conf HTML_MANS = \ $(HTML_CONF_MANS) \ $(HTML_CLIENT_MANS) \ + $(HTML_TOOL_MANS) \ $(HTML_CGI_MANS) \ $(HTML_DEV_MANS) \ $(HTML_SERIAL_MANS) \ $(HTML_SNMP_MANS) \ $(HTML_USB_LIBUSB_MANS) \ $(HTML_NETXML_MANS) \ - $(HTML_POWERMAN_MANS) + $(HTML_POWERMAN_MANS) \ + $(HTML_IPMIPSU_MANS) CLEANFILES = *.xml *.html SUFFIXES = .txt .html .1 .3 .5 .8 diff --git a/docs/man/apcsmart-old.8 b/docs/man/apcsmart-old.8 new file mode 100644 index 0000000..3685c9b --- /dev/null +++ b/docs/man/apcsmart-old.8 @@ -0,0 +1,124 @@ +'\" t +.\" Title: apcsmart-old +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "APCSMART\-OLD" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +apcsmart-old \- Driver for American Power Conversion Smart Protocol UPS equipment +.SH "SYNOPSIS" +.sp +\fBapcsmart\-old\fR \-h +.sp +\fBapcsmart\-old\fR \-a \fIUPS_NAME\fR [\fIOPTIONS\fR] +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +.sp +This man page only documents the hardware\-specific features of the apcsmart\-old driver\&. For information about the core driver, see \fBnutupsdrv\fR(8)\&. +.sp .5v +.RE +.SH "SUPPORTED HARDWARE" +.sp +apcsmart\-old should recognize all recent APC models that use a serial protocol at 2400 bps\&. This is primarily the Smart\-UPS, Matrix\-UPS and Back\-UPS Pro lines\&. +.sp +The driver attempts to support every bell and whistle of the APC reporting interface, whether or not this is strictly sensible\&. +.sp +Some older hardware may only report a handful of variables\&. This is usually not a bug\(emthey just don\(cqt support anything else\&. +.SH "CABLING" +.sp +This driver expects to see a 940\-0024C cable or a clone by default\&. You can switch to the 940\-0095B dual\-mode cable support with the cable= definition described below\&. +.sp +If your 940\-0024C cable is broken or missing, use this diagram to build a clone: +.sp +http://www\&.networkupstools\&.org/cables/940\-0024C\&.jpg +.SH "EXTRA ARGUMENTS" +.sp +This driver supports the following optional settings in the \fBups.conf\fR(5): +.PP +\fBcable=940\-0095B\fR +.RS 4 +Configure the serial port for the APC 940\-0095B dual\-mode cable\&. +.RE +.PP +\fBsdtype=\fR\fInum\fR +.RS 4 +Use shutdown type +\fInum\fR, according to this table: +.PP +0 +.RS 4 +soft shutdown or powerdown, depending on battery status +.RE +.PP +1 +.RS 4 +soft shutdown followed by powerdown +.RE +.PP +2 +.RS 4 +instant power off +.RE +.PP +3 +.RS 4 +power off with grace period +.RE +.PP +4 +.RS 4 +"force OB" hack method for CS 350 +.RE +.RE +.sp +Modes 0 and 1 will power up the load when power returns\&. Modes 2 and 3 will keep the load turned off when the power returns\&. +.sp +Mode 4 exploits an oddity in the CS 350 models since they only seem to support the S command, but then only when running on battery\&. As a result, the driver will force the UPS to go on battery if necessary before sending the shutdown command\&. This ensures that the load gets reset\&. +.SH "BUGS" +.sp +Some older APC UPS models return bogus data in the status register during a front panel test\&. This is usually detected and discarded, but some other unexpected values have occasionally slipped through\&. +.sp +APC UPS models with both USB and serial ports require a power cycle when switching from USB communication to serial, and perhaps vice versa\&. +.SH "AUTHOR" +.sp +Nigel Metheringham (drawing heavily on the original apcsmart driver by Russell Kroll)\&. This driver was called newapc for a time and was renamed in the 1\&.5 series\&. In 2\&.6\&.2 the driver was renamed to apcsmart\-old, being superseded by updated version with new features\&. +.SH "SEE ALSO" +.SS "The core driver:" +.sp +\fBnutupsdrv\fR(8) +.SS "Internet resources:" +.sp +The NUT (Network UPS Tools) home page: http://www\&.networkupstools\&.org/ diff --git a/docs/man/apcsmart-old.txt b/docs/man/apcsmart-old.txt new file mode 100644 index 0000000..43ed048 --- /dev/null +++ b/docs/man/apcsmart-old.txt @@ -0,0 +1,103 @@ +APCSMART-OLD(8) +=============== + +NAME +---- + +apcsmart-old - Driver for American Power Conversion Smart Protocol UPS equipment + +SYNOPSIS +-------- + +*apcsmart-old* -h + +*apcsmart-old* -a 'UPS_NAME' ['OPTIONS'] + +NOTE: This man page only documents the hardware-specific features of the +apcsmart-old driver. For information about the core driver, see +linkman:nutupsdrv[8]. + +SUPPORTED HARDWARE +------------------ + +apcsmart-old should recognize all recent APC models that use a serial +protocol at 2400 bps. This is primarily the Smart-UPS, Matrix-UPS and +Back-UPS Pro lines. + +The driver attempts to support every bell and whistle of the APC +reporting interface, whether or not this is strictly sensible. + +Some older hardware may only report a handful of variables. This is +usually not a bug--they just don't support anything else. + +CABLING +------- + +This driver expects to see a 940-0024C cable or a clone by default. You +can switch to the 940-0095B dual-mode cable support with the `cable=` +definition described below. + +If your 940-0024C cable is broken or missing, use this diagram to build +a clone: + +http://www.networkupstools.org/cables/940-0024C.jpg + +EXTRA ARGUMENTS +--------------- + +This driver supports the following optional settings in the +linkman:ups.conf[5]: + +*cable=940-0095B*:: +Configure the serial port for the APC 940-0095B dual-mode cable. + +*sdtype=*'num':: +Use shutdown type 'num', according to this table: + +0;; soft shutdown or powerdown, depending on battery status + +1;; soft shutdown followed by powerdown + +2;; instant power off + +3;; power off with grace period + +4;; "force OB" hack method for CS 350 + +Modes 0 and 1 will power up the load when power returns. Modes 2 and 3 +will keep the load turned off when the power returns. + +Mode 4 exploits an oddity in the CS 350 models since they only seem to +support the S command, but then only when running on battery. As a +result, the driver will force the UPS to go on battery if necessary +before sending the shutdown command. This ensures that the load gets +reset. + +BUGS +---- + +Some older APC UPS models return bogus data in the status register during +a front panel test. This is usually detected and discarded, but some +other unexpected values have occasionally slipped through. + +APC UPS models with both USB and serial ports require a power cycle when +switching from USB communication to serial, and perhaps vice versa. + +AUTHOR +------ +Nigel Metheringham (drawing +heavily on the original apcsmart driver by Russell Kroll). This driver +was called newapc for a time and was renamed in the 1.5 series. In 2.6.2 +the driver was renamed to apcsmart-old, being superseded by updated version +with new features. + +SEE ALSO +-------- + +The core driver: +~~~~~~~~~~~~~~~~ +linkman:nutupsdrv[8] + +Internet resources: +~~~~~~~~~~~~~~~~~~~ +The NUT (Network UPS Tools) home page: http://www.networkupstools.org/ diff --git a/docs/man/apcsmart.8 b/docs/man/apcsmart.8 index 31efce5..f7a0c71 100644 --- a/docs/man/apcsmart.8 +++ b/docs/man/apcsmart.8 @@ -2,12 +2,12 @@ .\" Title: apcsmart .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "APCSMART" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "APCSMART" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -33,7 +33,7 @@ apcsmart \- Driver for American Power Conversion Smart Protocol UPS equipment .sp \fBapcsmart\fR \-h .sp -\fBapcsmart\fR \-a \fIUPS_NAME\fR [\fIOPTIONS\fR] +\fBapcsmart\fR \-a \*(AqUPS_NAME\*(Aq [\-x option=value \&...] .if n \{\ .sp .\} @@ -52,61 +52,446 @@ This man page only documents the hardware\-specific features of the apcsmart dri .RE .SH "SUPPORTED HARDWARE" .sp -apcsmart should recognize all recent APC models that use a serial protocol at 2400 bps\&. This is primarily the Smart\-UPS, Matrix\-UPS and Back\-UPS Pro lines\&. +The apcsmart driver should recognize (or at the very least work with) majority of Smart\-UPS models \- which includes Smart\-UPS, Matrix\-UPS and Back\-UPS lineups, among few other ones\&. .sp -The driver attempts to support every bell and whistle of the APC reporting interface, whether or not this is strictly sensible\&. +Currently we can roughly divide APC hardware into 3 groups (note that the division isn\*(Aqt strict by any means, and the borders between those are pretty fuzzy): +.PP +[very] "old" models +.RS 4 +These models usually have old APC logo, white color and +\fIno\fR +programmable eeprom; You won\*(Aqt find them listed anywhere on APC\(cqs site either\&. The support for those will be usually based on driver\*(Aqs compatibility tables, or if the model (firmware) is not listed in those \- the driver will try to follow the very basic subset of features, while still trying to remain useful\&. Despite "smart" tagname, they often tend to behave in pretty dumb way (see the section below about shutdown behaviour)\&. +.PP +\fBExample models:\fR .sp -Some older hardware may only report a handful of variables\&. This is usually not a bug\(emthey just don\(cqt support anything else\&. +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Smart\-UPS 2000I +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +Smart\-UPS 900I +.RE +.RE +.PP +"new" models +.RS 4 +These models usually come from late 1990s / pre\-2009 times\&. They are often referred as "3rd\&. gen"\&. For the most part, they have programmable eeprom, report supported commands and capabilites, and should work just fine with the apcsmart driver\&. +.RE +.PP +"microlink" models +.RS 4 +WARNING: these are not +\fInatively\fR +supported by apcsmart (or apcupsd for that matter, if you\(cqre wondering)\&. Around 2007 APC (now APC Schneider) decided to go back to its proprietry roots and all the new models (SMT, SMX, SURTD) use completely different protocol and cables\&. If you purchased a new APC ups, that uses cable with rj45 on the one end, and db\-9 on the other \- then you have such model\&. Your only option to support it through +\fBNUT\fR +is to purchase "legacy communications card" \- part #AP9620 (google \*(AqAP9620\*(Aq for more details)\&. Or if that\*(Aqs not an option, rely on official software\&. +.RE +.sp +Another thing to remember is that Smart protocol is not USB protocol\&. If you have ups with both USB and serial ports, then depending on how you connect it, you will need either apcsmart or usbhid\-ups driver\&. .SH "CABLING" .sp -This driver expects to see a 940\-0024C cable or a clone by default\&. You can switch to the 940\-0095B dual\-mode cable support with the cable= definition described below\&. +This driver expects to see a 940\-0024C cable or a clone by default\&. You can switch to the 940\-0095B dual\-mode cable support with the \*(Aqcable=\*(Aq definition described below\&. .sp If your 940\-0024C cable is broken or missing, use this diagram to build a clone: .sp http://www\&.networkupstools\&.org/cables/940\-0024C\&.jpg -.SH "EXTRA ARGUMENTS" .sp -This driver supports the following optional settings in the \fBups.conf\fR(5): +You can specify alternate cable in \fBups.conf\fR(5): +.sp +\fBcable\fR=940\-0095B +.sp +Alternatively, you can also provide it on the command line using: +.sp +\-x \fBcable\fR=940\-0095B +.SH "EXPLANATION OF SHUTDOWN METHODS SUPPORTED BY APC UPSES" +.sp +APC hardware supports a lot of shutdown methods, that themselves can differ in behaviour quite a bit, depending on the model\&. .PP -\fBcable=940\-0095B\fR +\fBS\fR (soft hibernate) .RS 4 -Configure the serial port for the APC 940\-0095B dual\-mode cable\&. +This is most basic command present in probably all APC models\&. It will hibernate the UPS, and subsequently wake it up when the mains supply returns\&. +\fBThe command doesn\*(Aqt work if UPS is running on mains\&.\fR +.PP +"old" models +.RS 4 +The behaviour here is unfortunately pretty primitive \- when the power returns, the ups just wakes up\&. No grace periods, no min\&. battery charge condition, etc\&. This is probably not what you want\&. .RE .PP -\fBsdtype=\fR\fInum\fR +"new" models .RS 4 -Use shutdown type -\fInum\fR, according to this table: +The behaviour here is as expected \- the power is cut off after the eeprom defined grace period\&. The ups will wake up when the power returns, after the eeprom defined delay AND if the eeprom defined min\&. battery charge level is met\&. The delay is counted from the power\*(Aqs return\&. +.RE +.RE +.PP +\fBCS\fR (aka "force OB hack") +.RS 4 +This is a trick to make UPS power down even if it\*(Aqs running on mains\&. Immediately before issuing +\fBS\fR, "simulate power failure" is issued\&. The remaining behaviour is as in +\fBS\fR +case\&. +.sp +The name came from APC CS models, where such trick was used to power down UPSes in consistent fashion using only +\fBS\fR\&. It\*(Aqs better to use +\fB@nnn\fR +command if your UPS supports it (and is not too old, see below)\&. +.RE +.PP +\fB@nnn\fR (hard hibernate) +.RS 4 +This is basic command used to hibernate UPS regardless if it\*(Aqs running on batteries or on mains\&. The option takes 3 digits argument which can be used to specify additional wakeup delay (in 6 minute units)\&. +.PP +"old" models +.RS 4 +The behaviour is \- unfortunately \- similary primitive to +\fBS\fR\&. The ups unconditionally wakes up after nnn*6 minutes \- +\fBit doesn\*(Aqt care if the power returned !\fR +If nnn = 000, then UPS will do precisely nothing\&. On those models you\*(Aqre better specifying nnn > 0, if you can estimate the kind of power problems that might be happening in your environment\&. Another thing to consider with "old" models \- you might lose the connection with the ups, until it wakes up (with +\fBS\fR, the serial connection is kept alive)\&. +.RE +.PP +"new" models +.RS 4 +All the usual variables defined in eeprom are respected (see +\fBS\fR)\&. Additionally, if nnn > 0, the nnn*6 minutes are added to eeprom defined delay\&. UPS will not power up if it\*(Aqs running on batteries, contrary to what "old" models used to do \- the combined delay is counted from the moment of power return\&. +.RE +.sp +Supposedly there exist models that take 2 digits instead of 3\&. Just in case, NUT also supports such variation\&. You have to provide exactly 2 digits to trigger it (\fBawd\fR +option, or argument to one of the supported instant commands)\&. +.RE +.PP +\fBK\fR (delayed poweroff) +.RS 4 +This is permanent poweroff \- the ups will not wake up automatically\&. On newer units, it will respect applicable eeprom variables\&. +.RE +.PP +\fBZ\fR (instant poweroff) +.RS 4 +This is also permanent poweroff \- the ups will not wake up automatically\&. The poweroff is executed immediately\&. +.RE +.SH "SHUTDOWN CONTROL BY NUT" +.sp +There\*(Aqre 3 options used to control shutdown behaviour\&. +.PP +\fBsdtype\fR=[0\-5] +.RS 4 +This option takes a single digit (0\-5) as an argument\&. See below for details\&. +.RE +.PP +\fBadvorder\fR=no|[0\-4]+ +.RS 4 +This option takes string of digits as an argument\&. Methods listed are tried in turn until one of them succeedes\&. Note that the meaning of digits is different from +\fBsdtype\fR\&. See below for details\&. +.RE +.PP +\fBawd\fR=[0\-9]{1,3} +.RS 4 +This option lets you specify additional wakeup delay used by +\fB@\fR\&. If you provide exactly 2 digits, the driver will try 2 digits variation (see previous section for more info)\&. Otherwise standard 3 digits variation is used\&. +\fBNote: the time unit is 6 minutes !\fR +.RE +.sp +Keep in mind that \fBsdtype\fR and \fBadvorder\fR are mutually exclusive\&. If \fBadvorder\fR is provided, \fBsdtype\fR is ignored\&. If \fBadvorder\fR is set to \*(Aqno\*(Aq, \fBsdtype\fR is used instead\&. +.sp +If nothing is provided, \fBNUT\fR will assume \fBsdtype\fR=0 \- which is generally fine for anything not too ancient or not too quirky\&. +.SS "SDTYPE" +.sp +The values permitted are from 0 to 5\&. Only one can be specified\&. Anything else will cause apcsmart to exit\&. .PP 0 .RS 4 -soft shutdown or powerdown, depending on battery status +issue soft hibernate (\fBS\fR) if the ups is running on batteries, otherwise issue hard hibernate (\fB@\fR) .RE .PP 1 .RS 4 -soft shutdown followed by powerdown +issue soft hibernate (\fBS\fR) (if on batteries), and if it fails (or on mains) \- try hard hibernate (\fB@\fR) .RE .PP 2 .RS 4 -instant power off +issue instant poweroff (\fBZ\fR) .RE .PP 3 .RS 4 -power off with grace period +issue delayed poweroff (\fBK\fR) .RE .PP 4 .RS 4 -"force OB" hack method for CS 350 +issue "force OB hack" (\fBCS\fR) .RE +.PP +5 +.RS 4 +issue hard hibernate (\fB@\fR) +.RE +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +.sp +Hard hibernate\*(Aqs additional wakeup delay can be provided by \fBawd\fR\&. +.sp .5v +.RE +.SS "ADVORDER" +.sp +The argument is either a word \*(Aqno\*(Aq, or a string of 1 \- 5 digits in [0 \- 4] range\&. Each digit maps to the one of shutdown methods supported by APC upses\&. Methods listed in this way are tried in order, until one of them succedes\&. +.sp +If \fBadvorder\fR is undefined or set to \*(Aqno\*(Aq, \fBsdtype\fR is used instead\&. +.sp +The mapping is as follows: +.TS +tab(:); +lt lt +lt lt +lt lt +lt lt +lt lt. +T{ +.sp +0 +T}:T{ +.sp +soft hibernate (\fBS\fR) +T} +T{ +.sp +1 +T}:T{ +.sp +hard hibernate (\fB@\fR) +T} +T{ +.sp +2 +T}:T{ +.sp +delayed poweroff (\fBK\fR) +T} +T{ +.sp +3 +T}:T{ +.sp +instant poweroff (\fBZ\fR) +T} +T{ +.sp +4 +T}:T{ +.sp +"force OB hack" (\fBCS\fR) +T} +.TE +.sp 1 +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +.sp +Hard hibernate\*(Aqs additional wakeup delay can be provided by \fBawd\fR\&. +.sp .5v +.RE +.SH "IGNORING LB STATE" +.sp +APC units \- even if they report LB mode \- will not go into shutdown automatically\&. This gives us even more control with reference to "when to actually shutdown psu"\&. Since version 2\&.6\&.2, NUT supports \fBignorelb\fR option in driver\*(Aqs section of \fBups.conf\fR(5)\&. When such option is in effect, the core driver will ignore LB state as reported by specific driver and start shutdown basing the decision \fIonly\fR on two conditions: +.sp +battery\&.charge < battery\&.charge\&.low +.sp +\fBOR\fR +.sp +battery\&.runtime < battery\&.runtime\&.low +.sp +Of course \- if any of the variables are not available, the appropriate condition is not checked\&. If you want to explicitly disable one of the conditions, simply override the right hand variable causing the condition to always evaluate to false (you can even provide negative numbers)\&. +.sp +APC upses don\*(Aqt have battery\&.charge\&.low \- you will have to define it if you want to use such condition (prefix the variable with override\&. or default\&.)\&. +.sp +"New" units have battery\&.runtime\&.low, but depending on battery quality, firmware version, calibration and ups load \- this variable can be underestimated quite a bit \- especially right after going into OB state\&. This in turn can cause LB to be asserted, which under normal conditions will cause \fBNUT\fR to initiate the shutdown\&. You might want to disable this condition entirely, when relying on \fBignorelb\fR option (this was actually the main motivation behind introduction of such feature)\&. +.sp +Simple example: +.sp +.if n \{\ +.RS 4 +.\} +.nf +[apc] + ignorelb + override\&.battery\&.charge\&.low = 15 + override\&.battery\&.runtime\&.low = \-1 +.fi +.if n \{\ +.RE +.\} +.sp +This would cause apcsmart to go into shutdown \fIonly\fR if detected battery charge < 15%\&. Runtime condition is always false in this example\&. +.sp +You could ask \- why bother ? Well, the reason is already hinted above\&. APC units can be very picky about the batteries, and their firmware can underestimate the remaining runtime (especially right after going into OB state)\&. \fBignorelb\fR option and \fBoverride\&.*\fR let you remain in control of the ups, not ups in control of you\&. +.sp +Furthermore, this allows to specify conditions similary to how it\(cqs done in apcupsd daemon, so it should be welcome by people used to that software\&. +.SH "SUPPORTED INSTANT COMMANDS" +.sp +The apcsmart driver exposes following instant commands: +.PP +shutdown\&.return +.RS 4 +executes soft hibernate +.RE +.PP +shutdown\&.return cs +.RS 4 +executes "force OB hack" +.RE +.PP +shutdown\&.return at: +.RS 4 +executes "hard hibernate" with *6 minutes additional wakeup delay ( format is the same as of +\fBawd\fR +option) +.RE +.PP +shutdown\&.stayoff +.RS 4 +executes "delayed poweroff" +.RE +.PP +load\&.off +.RS 4 +executes "instant poweroff" .RE .sp -Modes 0 and 1 will power up the load when power returns\&. Modes 2 and 3 will keep the load turned off when the power returns\&. +All the above commands must be issued 2nd time to have any effect (no less than 3 seconds, and no more than 15 seconds after the initial call)\&. Those commands are mostly useful for manual testing, when your machine is not powered by the ups you\*(Aqre testing\&. .sp -Mode 4 exploits an oddity in the CS 350 models since they only seem to support the S command, but then only when running on battery\&. As a result, the driver will force the UPS to go on battery if necessary before sending the shutdown command\&. This ensures that the load gets reset\&. +Other supported commands: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +load\&.on +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +test\&.panel\&.start +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +test\&.failure\&.start +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +test\&.battery\&.start +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +test\&.battery\&.stop +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +bypass\&.start +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +bypass\&.stop +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +calibrate\&.start +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +calibrate\&.stop +.RE .SH "BUGS" .sp Some older APC UPS models return bogus data in the status register during a front panel test\&. This is usually detected and discarded, but some other unexpected values have occasionally slipped through\&. @@ -114,11 +499,10 @@ Some older APC UPS models return bogus data in the status register during a fron APC UPS models with both USB and serial ports require a power cycle when switching from USB communication to serial, and perhaps vice versa\&. .SH "AUTHOR" .sp -Nigel Metheringham (drawing heavily on the original apcsmart driver by Russell Kroll)\&. This driver was called newapc for a time and was renamed in the 1\&.5 series\&. +Nigel Metheringham (drawing heavily on the original apcsmart driver by Russell Kroll)\&. This driver was called newapc for a time and was renamed in the 1\&.5 series\&. In 2\&.6\&.2 it was renamed to apcsmart\-old, being superseded by updated version with new features, which is maintained by Michal Soltys .SH "SEE ALSO" -.SS "The core driver:" .sp -\fBnutupsdrv\fR(8) +\fBnutupsdrv\fR(8), \fBups.conf\fR(5) .SS "Internet resources:" .sp The NUT (Network UPS Tools) home page: http://www\&.networkupstools\&.org/ diff --git a/docs/man/apcsmart.txt b/docs/man/apcsmart.txt index 33835c0..76db3f1 100644 --- a/docs/man/apcsmart.txt +++ b/docs/man/apcsmart.txt @@ -11,30 +11,63 @@ SYNOPSIS *apcsmart* -h -*apcsmart* -a 'UPS_NAME' ['OPTIONS'] +*apcsmart* -a \'UPS_NAME' [-x option=value ...] NOTE: This man page only documents the hardware-specific features of the -apcsmart driver. For information about the core driver, see +apcsmart driver. For information about the core driver, see linkman:nutupsdrv[8]. + SUPPORTED HARDWARE ------------------ -apcsmart should recognize all recent APC models that use a serial -protocol at 2400 bps. This is primarily the Smart-UPS, Matrix-UPS and -Back-UPS Pro lines. +The apcsmart driver should recognize (or at the very least work with) majority +of Smart-UPS models - which includes Smart-UPS, Matrix-UPS and Back-UPS lineups, +among few other ones. -The driver attempts to support every bell and whistle of the APC -reporting interface, whether or not this is strictly sensible. +Currently we can roughly divide APC hardware into 3 groups (note that the +division isn\'t strict by any means, and the borders between those are pretty fuzzy): -Some older hardware may only report a handful of variables. This is -usually not a bug--they just don't support anything else. +[very] "old" models:: + These models usually have old APC logo, white color and _no_ programmable + eeprom; You won\'t find them listed anywhere on APC's site either. The support + for those will be usually based on driver\'s compatibility tables, or if the + model (firmware) is not listed in those - the driver will try to follow the very + basic subset of features, while still trying to remain useful. Despite + "smart" tagname, they often tend to behave in pretty dumb way (see the + section below about shutdown behaviour). ++ +-- +.Example models: + * Smart-UPS 2000I + * Smart-UPS 900I +-- + +"new" models:: + These models usually come from late 1990s / pre-2009 times. They are often + referred as "3rd. gen". For the most part, they have programmable eeprom, + report supported commands and capabilites, and should work just fine with the + apcsmart driver. + +"microlink" models:: + WARNING: these are not _natively_ supported by apcsmart (or apcupsd for that + matter, if you\'re wondering). Around 2007 APC (now APC Schneider) decided to + go back to its proprietry roots and all the new models (SMT, SMX, SURTD) use + completely different protocol and cables. If you purchased a new APC ups, + that uses cable with rj45 on the one end, and db-9 on the other - then you + have such model. Your only option to support it through *NUT* is to + purchase "legacy communications card" - part #AP9620 (google \'AP9620' for + more details). Or if that\'s not an option, rely on official software. + +Another thing to remember is that Smart protocol is not USB protocol. If you +have ups with both USB and serial ports, then depending on how you connect it, +you will need either apcsmart or usbhid-ups driver. CABLING ------- -This driver expects to see a 940-0024C cable or a clone by default. You -can switch to the 940-0095B dual-mode cable support with the `cable=` +This driver expects to see a 940-0024C cable or a clone by default. You +can switch to the 940-0095B dual-mode cable support with the \'cable=' definition described below. If your 940-0024C cable is broken or missing, use this diagram to build @@ -42,42 +75,246 @@ a clone: http://www.networkupstools.org/cables/940-0024C.jpg -EXTRA ARGUMENTS ---------------- +You can specify alternate cable in linkman:ups.conf[5]: -This driver supports the following optional settings in the -linkman:ups.conf[5]: +*cable*=940-0095B -*cable=940-0095B*:: -Configure the serial port for the APC 940-0095B dual-mode cable. +Alternatively, you can also provide it on the command line using: -*sdtype=*'num':: -Use shutdown type 'num', according to this table: +-x *cable*=940-0095B -0;; soft shutdown or powerdown, depending on battery status +EXPLANATION OF SHUTDOWN METHODS SUPPORTED BY APC UPSES +------------------------------------------------------ -1;; soft shutdown followed by powerdown +APC hardware supports a lot of shutdown methods, that themselves can differ in +behaviour quite a bit, depending on the model. -2;; instant power off +*S* (soft hibernate):: + This is most basic command present in probably all APC models. It will + hibernate the UPS, and subsequently wake it up when the mains supply + returns. *The command doesn\'t work if UPS is running on mains.* -3;; power off with grace period + "old" models::: + The behaviour here is unfortunately pretty primitive - when the power + returns, the ups just wakes up. No grace periods, no min. battery + charge condition, etc. This is probably not what you want. -4;; "force OB" hack method for CS 350 + "new" models::: + The behaviour here is as expected - the power is cut off after the + eeprom defined grace period. The ups will wake up when the power + returns, after the eeprom defined delay AND if the eeprom defined min. + battery charge level is met. The delay is counted from the power\'s + return. -Modes 0 and 1 will power up the load when power returns. Modes 2 and 3 -will keep the load turned off when the power returns. +*CS* (aka "force OB hack"):: + This is a trick to make UPS power down even if it\'s running on mains. + Immediately before issuing *S*, "simulate power failure" is issued. The + remaining behaviour is as in *S* case. ++ +The name came from APC CS models, where such trick was used to power down +UPSes in consistent fashion using only *S*. It\'s better to use *@nnn* +command if your UPS supports it (and is not too old, see below). -Mode 4 exploits an oddity in the CS 350 models since they only seem to -support the S command, but then only when running on battery. As a -result, the driver will force the UPS to go on battery if necessary -before sending the shutdown command. This ensures that the load gets -reset. +*@nnn* (hard hibernate):: + This is basic command used to hibernate UPS regardless if it\'s + running on batteries or on mains. The option takes 3 digits argument which + can be used to specify additional wakeup delay (in 6 minute units). ++ +-- + "old" models::: + The behaviour is - unfortunately - similary primitive to *S*. The ups + unconditionally wakes up after $$nnn*6$$ minutes - *it doesn\'t care if the + power returned !* If nnn = 000, then UPS will do precisely nothing. On + those models you\'re better specifying nnn > 0, if you can estimate + the kind of power problems that might be happening in your environment. + Another thing to consider with "old" models - you might lose the + connection with the ups, until it wakes up (with *S*, the serial + connection is kept alive). + + "new" models::: + All the usual variables defined in eeprom are respected (see *S*). + Additionally, if nnn > 0, the $$nnn*6$$ minutes are added to eeprom + defined delay. UPS will not power up if it\'s running on batteries, + contrary to what "old" models used to do - the combined delay is counted + from the moment of power return. +-- ++ +Supposedly there exist models that take 2 digits instead of 3. Just in case, +NUT also supports such variation. You have to provide exactly 2 digits to +trigger it (*awd* option, or argument to one of the supported instant commands). + +*K* (delayed poweroff):: + This is permanent poweroff - the ups will not wake up automatically. On + newer units, it will respect applicable eeprom variables. + +*Z* (instant poweroff):: + This is also permanent poweroff - the ups will not wake up automatically. The + poweroff is executed immediately. + +SHUTDOWN CONTROL BY NUT +----------------------- + +There\'re 3 options used to control shutdown behaviour. + +*sdtype*=[0-5]:: + This option takes a single digit (0-5) as an argument. See below for + details. + +*advorder*=no|[0-4]+:: + This option takes string of digits as an argument. Methods listed are tried + in turn until one of them succeedes. Note that the meaning of digits is + different from *sdtype*. See below for details. + +*awd*=[0-9]{1,3}:: + This option lets you specify additional wakeup delay used by *@*. If you + provide exactly 2 digits, the driver will try 2 digits variation (see + previous section for more info). Otherwise standard 3 digits variation is + used. *Note: the time unit is 6 minutes !* + +Keep in mind that *sdtype* and *advorder* are mutually exclusive. If *advorder* +is provided, *sdtype* is ignored. If *advorder* is set to \'no', *sdtype* is +used instead. + +If nothing is provided, *NUT* will assume *sdtype*=0 - which is generally fine +for anything not too ancient or not too quirky. + +SDTYPE +~~~~~~ + +The values permitted are from 0 to 5. Only one can be specified. Anything else +will cause apcsmart to exit. + +0:: +issue soft hibernate (*S*) if the ups is running on batteries, otherwise issue +hard hibernate (*@*) +1:: +issue soft hibernate (*S*) (if on batteries), and if it fails (or on mains) - +try hard hibernate (*@*) +2:: +issue instant poweroff (*Z*) +3:: +issue delayed poweroff (*K*) +4:: +issue "force OB hack" (*CS*) +5:: +issue hard hibernate (*@*) + +NOTE: Hard hibernate\'s additional wakeup delay can be provided by *awd*. + +ADVORDER +~~~~~~~~ + +The argument is either a word \'no', or a string of 1 - 5 digits in [0 - 4] +range. Each digit maps to the one of shutdown methods supported by APC upses. +Methods listed in this way are tried in order, until one of them succedes. + +If *advorder* is undefined or set to \'no', *sdtype* is used instead. + +The mapping is as follows: + +[horizontal] +0:: soft hibernate (*S*) +1:: hard hibernate (*@*) +2:: delayed poweroff (*K*) +3:: instant poweroff (*Z*) +4:: "force OB hack" (*CS*) + +NOTE: Hard hibernate\'s additional wakeup delay can be provided by *awd*. + +IGNORING LB STATE +----------------- + +APC units - even if they report LB mode - will not go into shutdown +automatically. This gives us even more control with reference to "when to +actually shutdown psu". Since version 2.6.2, NUT supports *ignorelb* option in +driver\'s section of linkman:ups.conf[5]. When such option is in effect, +the core driver will ignore LB state as reported by specific driver and +start shutdown basing the decision _only_ on two conditions: + +battery.charge < battery.charge.low + +*OR* + +battery.runtime < battery.runtime.low + +Of course - if any of the variables are not available, the appropriate condition +is not checked. If you want to explicitly disable one of the conditions, simply +override the right hand variable causing the condition to always evaluate to +false (you can even provide negative numbers). + +APC upses don\'t have battery.charge.low - you will have to define it if you want +to use such condition (prefix the variable with override. or default.). + +"New" units have battery.runtime.low, but depending on battery quality, firmware +version, calibration and ups load - this variable can be underestimated quite a bit - +especially right after going into OB state. This in turn can cause LB to be +asserted, which under normal conditions will cause *NUT* to initiate the +shutdown. You might want to disable this condition entirely, when relying on +*ignorelb* option (this was actually the main motivation behind introduction of +such feature). + +Simple example: + +[source,conf] +---- +[apc] + ignorelb + override.battery.charge.low = 15 + override.battery.runtime.low = -1 +---- + +This would cause apcsmart to go into shutdown _only_ if detected battery charge +< 15%. Runtime condition is always false in this example. + +You could ask - why bother ? Well, the reason is already hinted above. APC units +can be very picky about the batteries, and their firmware can underestimate the +remaining runtime (especially right after going into OB state). *ignorelb* +option and *$$override.*$$* let you remain in control of the ups, not ups in control +of you. + +Furthermore, this allows to specify conditions similary to how it's done in +apcupsd daemon, so it should be welcome by people used to that software. + + +SUPPORTED INSTANT COMMANDS +-------------------------- + +The apcsmart driver exposes following instant commands: + +shutdown.return:: +executes soft hibernate +shutdown.return cs:: +executes "force OB hack" +shutdown.return at::: +executes "hard hibernate" with $$*6$$ minutes additional wakeup delay ( format +is the same as of *awd* option) +shutdown.stayoff:: +executes "delayed poweroff" +load.off:: +executes "instant poweroff" + +All the above commands must be issued 2nd time to have any effect (no less than 3 +seconds, and no more than 15 seconds after the initial call). Those commands are +mostly useful for manual testing, when your machine is not powered by the ups +you\'re testing. + +Other supported commands: + +- load.on +- test.panel.start +- test.failure.start +- test.battery.start +- test.battery.stop +- bypass.start +- bypass.stop +- calibrate.start +- calibrate.stop BUGS ---- Some older APC UPS models return bogus data in the status register during -a front panel test. This is usually detected and discarded, but some +a front panel test. This is usually detected and discarded, but some other unexpected values have occasionally slipped through. APC UPS models with both USB and serial ports require a power cycle when @@ -85,17 +322,20 @@ switching from USB communication to serial, and perhaps vice versa. AUTHOR ------ + Nigel Metheringham (drawing -heavily on the original apcsmart driver by Russell Kroll). This driver -was called newapc for a time and was renamed in the 1.5 series. +heavily on the original apcsmart driver by Russell Kroll). This driver +was called newapc for a time and was renamed in the 1.5 series. In 2.6.2 +it was renamed to apcsmart-old, being superseded by updated version with +new features, which is maintained by Michal Soltys SEE ALSO -------- -The core driver: -~~~~~~~~~~~~~~~~ -linkman:nutupsdrv[8] +linkman:nutupsdrv[8], linkman:ups.conf[5] Internet resources: ~~~~~~~~~~~~~~~~~~~ The NUT (Network UPS Tools) home page: http://www.networkupstools.org/ + +// vim: tw=80 ai si ts=8 sts=4 sw=4 et : diff --git a/docs/man/bcmxcp.8 b/docs/man/bcmxcp.8 index 503db8a..9f9d26a 100644 --- a/docs/man/bcmxcp.8 +++ b/docs/man/bcmxcp.8 @@ -2,12 +2,12 @@ .\" Title: bcmxcp .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BCMXCP" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BCMXCP" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bcmxcp_usb.8 b/docs/man/bcmxcp_usb.8 index 628435f..32154b7 100644 --- a/docs/man/bcmxcp_usb.8 +++ b/docs/man/bcmxcp_usb.8 @@ -2,12 +2,12 @@ .\" Title: bcmxcp_usb .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BCMXCP_USB" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BCMXCP_USB" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/belkin.8 b/docs/man/belkin.8 index 07b0e2c..3cdcb70 100644 --- a/docs/man/belkin.8 +++ b/docs/man/belkin.8 @@ -2,12 +2,12 @@ .\" Title: belkin .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BELKIN" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BELKIN" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/belkinunv.8 b/docs/man/belkinunv.8 index 2e1ed16..e1b771f 100644 --- a/docs/man/belkinunv.8 +++ b/docs/man/belkinunv.8 @@ -2,12 +2,12 @@ .\" Title: belkinunv .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BELKINUNV" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BELKINUNV" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestfcom.8 b/docs/man/bestfcom.8 index e57a232..5fc62ae 100644 --- a/docs/man/bestfcom.8 +++ b/docs/man/bestfcom.8 @@ -2,12 +2,12 @@ .\" Title: bestfcom .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BESTFCOM" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BESTFCOM" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestfortress.8 b/docs/man/bestfortress.8 index d169d47..e4961a5 100644 --- a/docs/man/bestfortress.8 +++ b/docs/man/bestfortress.8 @@ -2,12 +2,12 @@ .\" Title: bestfortress .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BESTFORTRESS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BESTFORTRESS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestuferrups.8 b/docs/man/bestuferrups.8 index 59f7bee..cc7e7a1 100644 --- a/docs/man/bestuferrups.8 +++ b/docs/man/bestuferrups.8 @@ -2,12 +2,12 @@ .\" Title: bestuferrups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BESTUFERRUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BESTUFERRUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/bestups.8 b/docs/man/bestups.8 index 4849183..071ef89 100644 --- a/docs/man/bestups.8 +++ b/docs/man/bestups.8 @@ -2,12 +2,12 @@ .\" Title: bestups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BESTUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BESTUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/blazer.8 b/docs/man/blazer.8 index daa7244..f45308d 100644 --- a/docs/man/blazer.8 +++ b/docs/man/blazer.8 @@ -2,12 +2,12 @@ .\" Title: blazer .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "BLAZER" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "BLAZER" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -91,6 +91,16 @@ Some UPSes will lock up if you attempt to read rating information from them\&. S Some UPSes will lock up if you attempt to read vendor information from them\&. Setting this flag will make the driver skip this step\&. .RE .PP +\fBprotocol =\fR \fIstring\fR +.RS 4 +Skip autodetection of the protocol to use and only use the one specified\&. Supported values +\fImegatec\fR, +\fImegatec/old\fR, +\fImustek\fR +and +\fIzinto\fR\&. +.RE +.PP \fBruntimecal =\fR \fIvalue,value,value,value\fR .RS 4 Parameter used in the (optional) runtime estimation\&. This takes two runtimes at different loads\&. Typically, this uses the runtime at full load and the runtime at half load\&. For instance, if your UPS has a rated runtime of 240 seconds at full load and 720 seconds at half load, you would enter diff --git a/docs/man/blazer.txt b/docs/man/blazer.txt index 4fcb055..187724a 100644 --- a/docs/man/blazer.txt +++ b/docs/man/blazer.txt @@ -78,6 +78,11 @@ Setting this flag will make the driver skip this step. Some UPSes will lock up if you attempt to read vendor information from them. Setting this flag will make the driver skip this step. +*protocol =* 'string':: + +Skip autodetection of the protocol to use and only use the one specified. +Supported values 'megatec', 'megatec/old', 'mustek' and 'zinto'. + *runtimecal =* 'value,value,value,value':: Parameter used in the (optional) runtime estimation. This takes two runtimes @@ -203,7 +208,7 @@ BATTERY CHARGE -------------- Due to popular demand, this driver will report a guesstimated *battery.charge* -and optionally *battery.runtime*, provided you specified a couple of the +and optionally *battery.runtime*, provided you specified a couple of the <<_extra_arguments,EXTRA ARGUMENTS>> listed above. If you specify both *battery.voltage.high* and *battery.voltage.low* in @@ -259,7 +264,7 @@ You need to use 'cablepower' This parameter can simply be discarded, since it was a wrong understanding of the specification. - + KNOWN PROBLEMS -------------- diff --git a/docs/man/clone.8 b/docs/man/clone.8 index 75ebf97..897f36c 100644 --- a/docs/man/clone.8 +++ b/docs/man/clone.8 @@ -2,12 +2,12 @@ .\" Title: clone .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "CLONE" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "CLONE" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/dummy-ups.8 b/docs/man/dummy-ups.8 index ba9b312..4a4482b 100644 --- a/docs/man/dummy-ups.8 +++ b/docs/man/dummy-ups.8 @@ -2,12 +2,12 @@ .\" Title: dummy-ups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "DUMMY\-UPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "DUMMY\-UPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/etapro.8 b/docs/man/etapro.8 index 7f91bbc..5ad5c47 100644 --- a/docs/man/etapro.8 +++ b/docs/man/etapro.8 @@ -2,12 +2,12 @@ .\" Title: etapro .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "ETAPRO" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "ETAPRO" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/everups.8 b/docs/man/everups.8 index 9d7538b..b0fde0f 100644 --- a/docs/man/everups.8 +++ b/docs/man/everups.8 @@ -2,12 +2,12 @@ .\" Title: everups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "EVERUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "EVERUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/gamatronic.8 b/docs/man/gamatronic.8 index 9503f1e..aba6c37 100644 --- a/docs/man/gamatronic.8 +++ b/docs/man/gamatronic.8 @@ -2,12 +2,12 @@ .\" Title: gamatronic .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "GAMATRONIC" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "GAMATRONIC" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/genericups.8 b/docs/man/genericups.8 index a0403e5..a5add29 100644 --- a/docs/man/genericups.8 +++ b/docs/man/genericups.8 @@ -2,12 +2,12 @@ .\" Title: genericups .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "GENERICUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "GENERICUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/hosts.conf.5 b/docs/man/hosts.conf.5 index 4b7245d..223cb90 100644 --- a/docs/man/hosts.conf.5 +++ b/docs/man/hosts.conf.5 @@ -2,12 +2,12 @@ .\" Title: hosts.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "HOSTS\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "HOSTS\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/isbmex.8 b/docs/man/isbmex.8 index b74b2de..8ef95ed 100644 --- a/docs/man/isbmex.8 +++ b/docs/man/isbmex.8 @@ -2,12 +2,12 @@ .\" Title: isbmex .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "ISBMEX" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "ISBMEX" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/ivtscd.8 b/docs/man/ivtscd.8 index 9d25e5a..d993ae4 100644 --- a/docs/man/ivtscd.8 +++ b/docs/man/ivtscd.8 @@ -2,12 +2,12 @@ .\" Title: ivtscd .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "IVTSCD" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "IVTSCD" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/libupsclient-config.1 b/docs/man/libupsclient-config.1 index 74f1382..5acecb2 100644 --- a/docs/man/libupsclient-config.1 +++ b/docs/man/libupsclient-config.1 @@ -2,12 +2,12 @@ .\" Title: libupsclient-config .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "LIBUPSCLIENT\-CONFIG" "1" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "LIBUPSCLIENT\-CONFIG" "1" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/liebert-esp2.8 b/docs/man/liebert-esp2.8 index 779ee90..4e1b5da 100644 --- a/docs/man/liebert-esp2.8 +++ b/docs/man/liebert-esp2.8 @@ -2,12 +2,12 @@ .\" Title: liebert-esp2 .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "LIEBERT\-ESP2" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "LIEBERT\-ESP2" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/liebert.8 b/docs/man/liebert.8 index ab2530a..af88e94 100644 --- a/docs/man/liebert.8 +++ b/docs/man/liebert.8 @@ -2,12 +2,12 @@ .\" Title: liebert .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "LIEBERT" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "LIEBERT" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/masterguard.8 b/docs/man/masterguard.8 index 7ea77e7..bd5129d 100644 --- a/docs/man/masterguard.8 +++ b/docs/man/masterguard.8 @@ -2,12 +2,12 @@ .\" Title: masterguard .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "MASTERGUARD" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "MASTERGUARD" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/metasys.8 b/docs/man/metasys.8 index 6edef80..5ccb9c5 100644 --- a/docs/man/metasys.8 +++ b/docs/man/metasys.8 @@ -2,12 +2,12 @@ .\" Title: metasys .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "METASYS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "METASYS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/mge-shut.8 b/docs/man/mge-shut.8 index bd602a1..1d0e430 100644 --- a/docs/man/mge-shut.8 +++ b/docs/man/mge-shut.8 @@ -2,12 +2,12 @@ .\" Title: mge-shut .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "MGE\-SHUT" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "MGE\-SHUT" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/mge-utalk.8 b/docs/man/mge-utalk.8 index 32462ef..76543f2 100644 --- a/docs/man/mge-utalk.8 +++ b/docs/man/mge-utalk.8 @@ -2,12 +2,12 @@ .\" Title: mge-utalk .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "MGE\-UTALK" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "MGE\-UTALK" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/microdowell.8 b/docs/man/microdowell.8 index 8a97ec4..c4eba5b 100644 --- a/docs/man/microdowell.8 +++ b/docs/man/microdowell.8 @@ -2,12 +2,12 @@ .\" Title: microdowell .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "MICRODOWELL" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "MICRODOWELL" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/netxml-ups.8 b/docs/man/netxml-ups.8 index 49eec6a..9464983 100644 --- a/docs/man/netxml-ups.8 +++ b/docs/man/netxml-ups.8 @@ -2,12 +2,12 @@ .\" Title: netxml-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "NETXML\-UPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "NETXML\-UPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nut-ipmipsu.8 b/docs/man/nut-ipmipsu.8 new file mode 100644 index 0000000..ac06a46 --- /dev/null +++ b/docs/man/nut-ipmipsu.8 @@ -0,0 +1,231 @@ +'\" t +.\" Title: nut-ipmipsu +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUT\-IPMIPSU" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nut-ipmipsu \- Driver for IPMI Power Supply Units (PSU) +.SH "SYNOPSIS" +.sp +\fBnut\-ipmipsu\fR \-h +.sp +\fBnut\-ipmipsu\fR \-a \fIPSU_NAME\fR [\fIOPTIONS\fR] +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +.sp +This driver is experimental, and still a work\-in\-progress\&. Feedback is encouraged\&. +.sp .5v +.RE +.if n \{\ +.sp +.\} +.RS 4 +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.br +.ps +1 +\fBNote\fR +.ps -1 +.br +.sp +This man page only documents the hardware\-specific features of the nut\-ipmipsu driver\&. For information about the core driver, see \fBnutupsdrv\fR(8)\&. +.sp .5v +.RE +.SH "SUPPORTED HARDWARE" +.sp +This driver should support a wide range of PSUs through local IPMI interface\&. +.sp +nut\-ipmipsu currently use the GNU FreeIPMI project, for IPMI implementation\&. +.SH "EXTRA ARGUMENTS" +.sp +This driver doesn\(cqt support any optional settings\&. +.SH "INSTALLATION" +.sp +This driver is not built by default\&. You can build it by using "configure \-\-with\-ipmi=yes"\&. +.sp +You also need to give proper permissions on the local IPMI device file (/dev/ipmi0 for example) to allow the NUT user to access it\&. +.sp +An udev rules file (nut\-ipmipsu\&.rules) is provided and automatically installed on udev enabled system\&. This file is generally installed in /etc/udev/rules\&.d/ or /lib/udev/rules\&.d/ on newer systems, to address the permission settings problem\&. For more information, refer to nut/scripts/udev/README\&. +.SH "INSTANT COMMANDS" +.sp +This driver doesn\(cqt support any instant commands\&. +.SH "IMPLEMENTATION" +.sp +The "port" value is used to identify the PSU\&. For instance, to target FRU 0x2, use the following in \fBups\&.conf\fR: +.sp +.if n \{\ +.RS 4 +.\} +.nf +[pdu] + driver = nut\-ipmipsu + port = id2 +.fi +.if n \{\ +.RE +.\} +.sp +This driver will report various information related to a PSU, including: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +manufacturer, model, serial and part numbers, +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +nominal voltage and frequency, +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +actual current and voltage, +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +status of the PSU: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} + +\fIOL\fR +means that the PSU is present and providing power, +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} + +\fIOB\fR +means that the PSU is present but not providing power (power cable removed), +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} + +\fIstale\fR +means that the PSU is not present (ie physically removed)\&. +.RE +.RE +.sp +Here is an example output for a Dell r610 server: +.sp +.if n \{\ +.RS 4 +.\} +.nf +device\&.mfr: DELL +device\&.mfr\&.date: 01/05/11 \- 08:51:00 +device\&.model: PWR SPLY,717W,RDNT +device\&.part: 0RN442A01 +device\&.serial: CN179721130031 +device\&.type: psu +driver\&.name: nut\-ipmipsu +driver\&.parameter\&.pollinterval: 2 +driver\&.parameter\&.port: id2 +driver\&.version: 2\&.6\&.1\-3139M +driver\&.version\&.data: IPMI PSU driver +driver\&.version\&.internal: 0\&.01 +input\&.current: 0\&.20 +input\&.frequency\&.high: 63 +input\&.frequency\&.low: 47 +input\&.voltage: 232\&.00 +input\&.voltage\&.maximum: 264 +input\&.voltage\&.minimum: 90 +ups\&.id: 2 +ups\&.realpower\&.nominal: 717 +ups\&.status: OL +ups\&.voltage: 12 +.fi +.if n \{\ +.RE +.\} +.SH "AUTHOR" +.sp +Arnaud Quette +.SH "SEE ALSO" +.SS "The core driver:" +.sp +\fBnutupsdrv\fR(8) +.SS "Internet resources:" +.sp +The NUT (Network UPS Tools) home page: http://www\&.networkupstools\&.org/ +.sp +GNU FreeIPMI home page: http://www\&.gnu\&.org/software/freeipmi/ diff --git a/docs/man/nut-ipmipsu.txt b/docs/man/nut-ipmipsu.txt new file mode 100644 index 0000000..cef3a14 --- /dev/null +++ b/docs/man/nut-ipmipsu.txt @@ -0,0 +1,115 @@ +NUT-IPMIPSU(8) +============== + +NAME +---- + +nut-ipmipsu - Driver for IPMI Power Supply Units (PSU) + +SYNOPSIS +-------- + +*nut-ipmipsu* -h + +*nut-ipmipsu* -a 'PSU_NAME' ['OPTIONS'] + +NOTE: This driver is experimental, and still a work-in-progress. Feedback is +encouraged. + +NOTE: This man page only documents the hardware-specific features of the +nut-ipmipsu driver. For information about the core driver, see +linkman:nutupsdrv[8]. + +SUPPORTED HARDWARE +------------------ + +This driver should support a wide range of PSUs through local IPMI interface. + +nut-ipmipsu currently use the GNU FreeIPMI project, for IPMI implementation. + + +EXTRA ARGUMENTS +--------------- + +This driver doesn't support any optional settings. + +INSTALLATION +------------ + +This driver is not built by default. You can build it by using +"configure --with-ipmi=yes". + +You also need to give proper permissions on the local IPMI device file +(/dev/ipmi0 for example) to allow the NUT user to access it. + +An udev rules file (nut-ipmipsu.rules) is provided and automatically installed +on udev enabled system. This file is generally installed in /etc/udev/rules.d/ +or /lib/udev/rules.d/ on newer systems, to address the permission settings +problem. For more information, refer to nut/scripts/udev/README. + +INSTANT COMMANDS +---------------- + +This driver doesn't support any instant commands. + +IMPLEMENTATION +-------------- + +The "port" value is used to identify the PSU. For instance, to target +FRU 0x2, use the following in *ups.conf*: + + [pdu] + driver = nut-ipmipsu + port = id2 + +This driver will report various information related to a PSU, including: + + - manufacturer, model, serial and part numbers, + - nominal voltage and frequency, + - actual current and voltage, + - status of the PSU: + + * 'OL' means that the PSU is present and providing power, + * 'OB' means that the PSU is present but not providing power (power cable removed), + * 'stale' means that the PSU is not present (ie physically removed). + +Here is an example output for a Dell r610 server: + + device.mfr: DELL + device.mfr.date: 01/05/11 - 08:51:00 + device.model: PWR SPLY,717W,RDNT + device.part: 0RN442A01 + device.serial: CN179721130031 + device.type: psu + driver.name: nut-ipmipsu + driver.parameter.pollinterval: 2 + driver.parameter.port: id2 + driver.version: 2.6.1-3139M + driver.version.data: IPMI PSU driver + driver.version.internal: 0.01 + input.current: 0.20 + input.frequency.high: 63 + input.frequency.low: 47 + input.voltage: 232.00 + input.voltage.maximum: 264 + input.voltage.minimum: 90 + ups.id: 2 + ups.realpower.nominal: 717 + ups.status: OL + ups.voltage: 12 + +AUTHOR +------ +Arnaud Quette + +SEE ALSO +-------- +The core driver: +~~~~~~~~~~~~~~~~ +linkman:nutupsdrv[8] + +Internet resources: +~~~~~~~~~~~~~~~~~~~ +The NUT (Network UPS Tools) home page: http://www.networkupstools.org/ + +GNU FreeIPMI home page: http://www.gnu.org/software/freeipmi/ diff --git a/docs/man/nut-scanner.8 b/docs/man/nut-scanner.8 new file mode 100644 index 0000000..bf8621b --- /dev/null +++ b/docs/man/nut-scanner.8 @@ -0,0 +1,186 @@ +'\" t +.\" Title: nut-scanner +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUT\-SCANNER" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nut-scanner \- scan communication buses for NUT devices +.SH "SYNOPSIS" +.sp +\fBnut\-scanner\fR \-h +.sp +\fBnut\-scanner\fR [\fIOPTIONS\fR] +.SH "DESCRIPTION" +.sp +\fBnut\-scanner\fR scans available communication buses and display any NUT compatible device it has found\&. +.SH "OPTIONS" +.PP +\fB\-h\fR +.RS 4 +Display the help text\&. +.RE +.SH "DISPLAY OPTIONS" +.PP +\fB\-N\fR | \fB\-\-disp_nut_conf\fR +.RS 4 +Display result in the +\fIups\&.conf\fR +format\&. +.RE +.PP +\fB\-P\fR | \fB\-\-disp_parsable\fR +.RS 4 +Display result in a parsable format\&. +.RE +.SH "BUS OPTIONS" +.PP +\fB\-C\fR | \fB\-\-complete_scan\fR +.RS 4 +Scan all available communication buses (default behavior) +.RE +.PP +\fB\-U\fR | \fB\-\-usb_scan\fR +.RS 4 +List all NUT compatible USB devices currently plugged in\&. +.RE +.PP +\fB\-S\fR | \fB\-\-snmp_scan\fR +.RS 4 +Scan SNMP devices\&. Require at least a +\fIstart IP\fR, and optionnaly an +\fIend IP\fR\&. See specific SNMP OPTIONS for community and security settings\&. +.RE +.PP +\fB\-M\fR | \fB\-\-xml_scan\fR +.RS 4 +Scan XML/HTTP devices\&. Broadcast a network message on the current network interfaces to retrieve XML/HTTP capable devices\&. No IP required\&. +.RE +.PP +\fB\-O\fR | \fB\-\-oldnut_scan\fR +.RS 4 +Scan NUT devices (i\&.e\&. upsd daemon) on IP ranging from +\fIstart IP\fR +to +\fIend IP\fR\&. +.RE +.PP +\fB\-A\fR | \fB\-\-avahi_scan\fR +.RS 4 +Scan NUT servers using avahi request on the current network interfaces\&. No IP required\&. +.RE +.PP +\fB\-I\fR | \fB\-\-ipmi_scan\fR +.RS 4 +Scan NUT compatible devices available via IPMI on the current host\&. +.RE +.SH "NETWORK OPTIONS" +.PP +\fB\-t\fR | \fB\-\-timeout\fR \fItimeout\fR +.RS 4 +Set the network timeout in seconds\&. Default timeout is 5 seconds\&. +.RE +.PP +\fB\-s\fR | \fB\-\-start_ip\fR \fIstart IP\fR +.RS 4 +Set the first IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut)\&. +.RE +.PP +\fB\-e\fR | \fB\-\-end_ip\fR \fIend IP\fR +.RS 4 +Set the last IP (IPv4 or IPv6) when a range of IP is required (SNMP, old_nut)\&. If this parameter is omitted, only the +\fIstart IP\fR +is scanned\&. If +\fIend IP\fR +is lesser than +\fIstart IP\fR, both parameter are internally permuted\&. +.RE +.SH "NUT DEVICE OPTION" +.PP +\fB\-p\fR | \fB\-\-port -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "NUT\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "NUT\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/nutscan_add_device_to_device.3 b/docs/man/nutscan_add_device_to_device.3 new file mode 100644 index 0000000..e8e7ab1 --- /dev/null +++ b/docs/man/nutscan_add_device_to_device.3 @@ -0,0 +1,68 @@ +'\" t +.\" Title: nutscan_add_device_to_device +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_ADD_DEVICE_T" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_add_device_to_device \- Concatenate two devices structure\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_add_device_to_device(nutscan_device_t * first, nutscan_device_t * second); +.fi +.SH "DESCRIPTION" +.sp +The nutscan_device_t contains the following variables: +.sp +.if n \{\ +.RS 4 +.\} +.nf +nutscan_device_type_t type; +char * driver; +char * port; +nutscan_options_t opt; +struct nutscan_device * prev; +struct nutscan_device * next; +.fi +.if n \{\ +.RE +.\} +.sp +This is a double linked list of device\&. Each device is described by its type, its driver name, its port and any number of optional data\&. +.sp +The \fBnutscan_add_device_to_device()\fR concatenates \fIfirst\fR and \fIsecond\fR devices to a unique device\&. No new device is created, the two linked list are simply linked to each other\&. So \fIfirst\fR and \fIsecond\fR devices are likely to be modified by this function\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_add_device_to_device()\fR functions returns a pointer to a device containg both passed devices\&. Note that it\(cqs not a new device, so it is either \fIfirst\fR or \fIsecond\fR which is returned\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3) diff --git a/docs/man/nutscan_add_device_to_device.txt b/docs/man/nutscan_add_device_to_device.txt new file mode 100644 index 0000000..7ccc3c8 --- /dev/null +++ b/docs/man/nutscan_add_device_to_device.txt @@ -0,0 +1,45 @@ +NUTSCAN_ADD_DEVICE_TO_DEVICE(3) +=============================== + +NAME +---- + +nutscan_add_device_to_device - Concatenate two devices structure. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_add_device_to_device(nutscan_device_t * first, nutscan_device_t * second); + + +DESCRIPTION +----------- + +The `nutscan_device_t` contains the following variables: + + nutscan_device_type_t type; + char * driver; + char * port; + nutscan_options_t opt; + struct nutscan_device * prev; + struct nutscan_device * next; + +This is a double linked list of device. Each device is described by its `type`, its `driver` name, its `port` and any number of optional data. + +The *nutscan_add_device_to_device()* concatenates 'first' and 'second' devices to a unique device. No new device is created, the two linked list are simply linked to each other. So 'first' and 'second' devices are likely to be modified by this function. + +RETURN VALUE +------------ + +The *nutscan_add_device_to_device()* functions returns a pointer to a device containg both passed devices. Note that it's not a new device, so it is either 'first' or 'second' which is returned. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_ups_conf[3], linkman:nutscan_display_parsable[3], +linkman:nutscan_new_device[3], linkman:nutscan_free_device[3], +linkman:nutscan_add_option_to_device[3] diff --git a/docs/man/nutscan_add_option_to_device.3 b/docs/man/nutscan_add_option_to_device.3 new file mode 100644 index 0000000..a1cb96c --- /dev/null +++ b/docs/man/nutscan_add_option_to_device.3 @@ -0,0 +1,65 @@ +'\" t +.\" Title: nutscan_add_option_to_device +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_ADD_OPTION_T" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_add_option_to_device \- Add option data to the specified device\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +void nutscan_add_option_to_device(nutscan_device_t * device,char * option_name, char * value); +.fi +.SH "DESCRIPTION" +.sp +The nutscan_device_t contains the following variables: +.sp +.if n \{\ +.RS 4 +.\} +.nf +nutscan_device_type_t type; +char * driver; +char * port; +nutscan_options_t opt; +struct nutscan_device * prev; +struct nutscan_device * next; +.fi +.if n \{\ +.RE +.\} +.sp +This is a double linked list of device\&. Each device is described by its type, its driver name, its port and any number of optional data\&. +.sp +The \fBnutscan_add_option_to_device()\fR adds an optional data in the given devcie\&. Optional data are made of an \fIoption_name\fR and an associated \fIvalue\fR\&. Copies of \fIoption_name\fR and \fIvalue\fR are stored in the device, so the caller can safely free both of them\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_device_to_device\fR(3) diff --git a/docs/man/nutscan_add_option_to_device.txt b/docs/man/nutscan_add_option_to_device.txt new file mode 100644 index 0000000..636f056 --- /dev/null +++ b/docs/man/nutscan_add_option_to_device.txt @@ -0,0 +1,40 @@ +NUTSCAN_ADD_OPTION_TO_DEVICE(3) +=============================== + +NAME +---- + +nutscan_add_option_to_device - Add option data to the specified device. + +SYNOPSIS +-------- + + #include + + void nutscan_add_option_to_device(nutscan_device_t * device,char * option_name, char * value); + + +DESCRIPTION +----------- + +The `nutscan_device_t` contains the following variables: + + nutscan_device_type_t type; + char * driver; + char * port; + nutscan_options_t opt; + struct nutscan_device * prev; + struct nutscan_device * next; + +This is a double linked list of device. Each device is described by its `type`, its `driver` name, its `port` and any number of optional data. + +The *nutscan_add_option_to_device()* adds an optional data in the given devcie. Optional data are made of an 'option_name' and an associated 'value'. Copies of 'option_name' and 'value' are stored in the device, so the caller can safely free both of them. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_ups_conf[3], linkman:nutscan_display_parsable[3], +linkman:nutscan_new_device[3], linkman:nutscan_free_device[3], +linkman:nutscan_add_device_to_device[3] diff --git a/docs/man/nutscan_cidr_to_ip.3 b/docs/man/nutscan_cidr_to_ip.3 new file mode 100644 index 0000000..a9fbdda --- /dev/null +++ b/docs/man/nutscan_cidr_to_ip.3 @@ -0,0 +1,49 @@ +'\" t +.\" Title: nutscan_cidr_to_ip +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_CIDR_TO_IP" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_cidr_to_ip \- Convert a CIDR IP to a range of IP address\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_cidr_to_ip()\fR function converts a range of IP address in the CIDR format given as a string in \fIcidr\fR, to two IPs in strings pointed by \fIstart_ip\fR and \fIstop_ip\fR which can be used as input paramters in the scanning functions of the libnutscan API\&. It is the caller\(cqs responsability to free \fIstart_ip\fR and \fIstop_ip\fR strings\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_cidr_to_ip()\fR function returns 0 if an error occured (invalid \fIcidr\fR address) or 1 if successful\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_display_ups_conf\fR(3) diff --git a/docs/man/nutscan_cidr_to_ip.txt b/docs/man/nutscan_cidr_to_ip.txt new file mode 100644 index 0000000..6ebe237 --- /dev/null +++ b/docs/man/nutscan_cidr_to_ip.txt @@ -0,0 +1,31 @@ +NUTSCAN_CIDR_TO_IP(3) +===================== + +NAME +---- + +nutscan_cidr_to_ip - Convert a CIDR IP to a range of IP address. + +SYNOPSIS +-------- + + #include + + int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip); + +DESCRIPTION +----------- + +The *nutscan_cidr_to_ip()* function converts a range of IP address in the CIDR format given as a string in 'cidr', to two IPs in strings pointed by 'start_ip' and 'stop_ip' which can be used as input paramters in the scanning functions of the libnutscan API. It is the caller's responsability to free 'start_ip' and 'stop_ip' strings. + +RETURN VALUE +------------ + +The *nutscan_cidr_to_ip()* function returns 0 if an error occured (invalid 'cidr' address) or 1 if successful. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_display_ups_conf[3] diff --git a/docs/man/nutscan_display_parsable.3 b/docs/man/nutscan_display_parsable.3 new file mode 100644 index 0000000..77222d1 --- /dev/null +++ b/docs/man/nutscan_display_parsable.3 @@ -0,0 +1,50 @@ +'\" t +.\" Title: nutscan_display_parsable +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_DISPLAY_PARS" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_display_parsable \- Display the specified `nutscan_device_t` structure on stdout\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +void nutscan_display_parsable(nutscan_device_t * device); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_display_parsable()\fR function displays all NUT devices in \fIdevice\fR to stdout\&. It displays them in a way that can be easily parsed which is: +.sp +:driver="",port=""[,="",="",\&...] +.sp + may be one of USB, SNMP, XML, NUT, IPMI or AVAHI\&. is the name of the driver\(cqs binary corresponding to this device\&. and depend on , see the corresponding driver\(cqs man page\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_display_parsable.txt b/docs/man/nutscan_display_parsable.txt new file mode 100644 index 0000000..7379d65 --- /dev/null +++ b/docs/man/nutscan_display_parsable.txt @@ -0,0 +1,34 @@ +NUTSCAN_DISPLAY_PARSABLE(3) +=========================== + +NAME +---- + +nutscan_display_parsable - Display the specified `nutscan_device_t` structure on stdout. + +SYNOPSIS +-------- + + #include + + void nutscan_display_parsable(nutscan_device_t * device); + +DESCRIPTION +----------- + +The *nutscan_display_parsable()* function displays all NUT devices in 'device' to stdout. It displays them in a way that can be easily parsed which is: + +:driver="",port=""[,="",="",...] + + may be one of USB, SNMP, XML, NUT, IPMI or AVAHI. + is the name of the driver's binary corresponding to this device. + and depend on , see the corresponding driver's man page. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_ups_conf[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_display_ups_conf.3 b/docs/man/nutscan_display_ups_conf.3 new file mode 100644 index 0000000..0bff07b --- /dev/null +++ b/docs/man/nutscan_display_ups_conf.3 @@ -0,0 +1,46 @@ +'\" t +.\" Title: nutscan_display_ups_conf +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_DISPLAY_UPS_" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_display_ups_conf \- Display the specified `nutscan_device_t` structure on stdout\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +void nutscan_display_ups_conf(nutscan_device_t * device); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_display_ups_conf()\fR function displays all NUT devices in \fIdevice\fR to stdout\&. It displays them in a way that it can be directly copied into the ups\&.conf file\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_display_ups_conf.txt b/docs/man/nutscan_display_ups_conf.txt new file mode 100644 index 0000000..8d95e07 --- /dev/null +++ b/docs/man/nutscan_display_ups_conf.txt @@ -0,0 +1,28 @@ +NUTSCAN_DISPLAY_UPS_CONF(3) +=========================== + +NAME +---- + +nutscan_display_ups_conf - Display the specified `nutscan_device_t` structure on stdout. + +SYNOPSIS +-------- + + #include + + void nutscan_display_ups_conf(nutscan_device_t * device); + +DESCRIPTION +----------- + +The *nutscan_display_ups_conf()* function displays all NUT devices in 'device' to stdout. It displays them in a way that it can be directly copied into the ups.conf file. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_free_device.3 b/docs/man/nutscan_free_device.3 new file mode 100644 index 0000000..07347d1 --- /dev/null +++ b/docs/man/nutscan_free_device.3 @@ -0,0 +1,46 @@ +'\" t +.\" Title: nutscan_free_device +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_FREE_DEVICE" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_free_device \- Free a nutscan_device_t structure created by nutscan_new_device\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +void nutscan_free_device(nutscan_device_t * device); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_free_device()\fR function free a nutscan_device_type_t structure\&. Doing so, it free the whole linked list, not only the given device\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3) diff --git a/docs/man/nutscan_free_device.txt b/docs/man/nutscan_free_device.txt new file mode 100644 index 0000000..062bb4b --- /dev/null +++ b/docs/man/nutscan_free_device.txt @@ -0,0 +1,28 @@ +NUTSCAN_FREE_DEVICE(3) +====================== + +NAME +---- + +nutscan_free_device - Free a nutscan_device_t structure created by nutscan_new_device. + +SYNOPSIS +-------- + + #include + + void nutscan_free_device(nutscan_device_t * device); + +DESCRIPTION +----------- + +The *nutscan_free_device()* function free a `nutscan_device_type_t` structure. Doing so, it free the whole linked list, not only the given device. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_display_ups_conf[3], linkman:nutscan_display_parsable[3], +linkman:nutscan_new_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3] diff --git a/docs/man/nutscan_new_device.3 b/docs/man/nutscan_new_device.3 new file mode 100644 index 0000000..7677b57 --- /dev/null +++ b/docs/man/nutscan_new_device.3 @@ -0,0 +1,49 @@ +'\" t +.\" Title: nutscan_new_device +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_NEW_DEVICE" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_new_device \- Create a new nutscan_device_t structure\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_new_device(); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_new_device()\fR function allocates a new nutscan_device_type_t structure\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_new_device()\fR function returns the newly allocated nutscan_device_type_t structure +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_scan_snmp\fR(3) \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3) \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3) \fBnutscan_add_device_to_device\fR(3) diff --git a/docs/man/nutscan_new_device.txt b/docs/man/nutscan_new_device.txt new file mode 100644 index 0000000..1b887cc --- /dev/null +++ b/docs/man/nutscan_new_device.txt @@ -0,0 +1,33 @@ +NUTSCAN_NEW_DEVICE(3) +====================== + +NAME +---- + +nutscan_new_device - Create a new nutscan_device_t structure. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_new_device(); + +DESCRIPTION +----------- + +The *nutscan_new_device()* function allocates a new `nutscan_device_type_t` structure. + +RETURN VALUE +------------ + +The *nutscan_new_device()* function returns the newly allocated `nutscan_device_type_t` structure + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_scan_snmp[3] +linkman:nutscan_display_ups_conf[3], linkman:nutscan_display_parsable[3] +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3] +linkman:nutscan_add_device_to_device[3] diff --git a/docs/man/nutscan_scan_avahi.3 b/docs/man/nutscan_scan_avahi.3 new file mode 100644 index 0000000..30be1e2 --- /dev/null +++ b/docs/man/nutscan_scan_avahi.3 @@ -0,0 +1,51 @@ +'\" t +.\" Title: nutscan_scan_avahi +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_AVAHI" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_avahi \- Scan network for NUT services via AVAHI\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_avahi(long usec_timeout); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_avahi()\fR function try to detect NUT service and its associated devcies\&. It uses the AVAHI library to do so\&. +.sp +This function waits up to \fIusec_timeout\fR microseconds before considering an IP address does not respond\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_avahi()\fR function returns a pointer to a nutscan_device_t structure containing all found devices or NULL if an error occurs or no device is found\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_scan_avahi.txt b/docs/man/nutscan_scan_avahi.txt new file mode 100644 index 0000000..77141e3 --- /dev/null +++ b/docs/man/nutscan_scan_avahi.txt @@ -0,0 +1,35 @@ +NUTSCAN_SCAN_AVAHI(3) +===================== + +NAME +---- + +nutscan_scan_avahi - Scan network for NUT services via AVAHI. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_avahi(long usec_timeout); + +DESCRIPTION +----------- + +The *nutscan_scan_avahi()* function try to detect NUT service and its associated devcies. It uses the AVAHI library to do so. + +This function waits up to 'usec_timeout' microseconds before considering an IP address does not respond. + +RETURN VALUE +------------ + +The *nutscan_scan_avahi()* function returns a pointer to a `nutscan_device_t` structure containing all found devices or NULL if an error occurs or no device is found. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_scan_ipmi.3 b/docs/man/nutscan_scan_ipmi.3 new file mode 100644 index 0000000..9776d80 --- /dev/null +++ b/docs/man/nutscan_scan_ipmi.3 @@ -0,0 +1,49 @@ +'\" t +.\" Title: nutscan_scan_ipmi +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_IPMI" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_ipmi \- Scan local IPMI devices\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_ipmi(void); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_ipmi()\fR function is not implemented yet\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_ipmi()\fR function is not implemented yet\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_scan_ipmi.txt b/docs/man/nutscan_scan_ipmi.txt new file mode 100644 index 0000000..32e9e7f --- /dev/null +++ b/docs/man/nutscan_scan_ipmi.txt @@ -0,0 +1,33 @@ +NUTSCAN_SCAN_IPMI(3) +==================== + +NAME +---- + +nutscan_scan_ipmi - Scan local IPMI devices. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_ipmi(void); + +DESCRIPTION +----------- + +The *nutscan_scan_ipmi()* function is not implemented yet. + +RETURN VALUE +------------ + +The *nutscan_scan_ipmi()* function is not implemented yet. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_snmp[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_scan_nut.3 b/docs/man/nutscan_scan_nut.3 new file mode 100644 index 0000000..62d7475 --- /dev/null +++ b/docs/man/nutscan_scan_nut.3 @@ -0,0 +1,53 @@ +'\" t +.\" Title: nutscan_scan_nut +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_NUT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_nut \- Scan network for available NUT services\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_nut(const char * startIP, const char * stopIP, const char * port, long usec_timeout); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_nut()\fR function try to detect available NUT services and their associated devices\&. It issues a NUT request on every IP ranging from \fIstartIP\fR to \fIstopIP\fR\&. \fIstartIP\fR is mandatory, \fIstopIP\fR is optional\&. Those IP may be either IPv4 or IPv6 addresses or host names\&. +.sp +A specific \fIport\fR number may be passed, or NULL to use the default NUT port\&. +.sp +This function waits up to \fIusec_timeout\fR microseconds before considering an IP address does not respond to NUT queries\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_nut()\fR function returns a pointer to a nutscan_device_t structure containing all found devices or NULL if an error occurs or no device is found\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_scan_nut.txt b/docs/man/nutscan_scan_nut.txt new file mode 100644 index 0000000..7f1941a --- /dev/null +++ b/docs/man/nutscan_scan_nut.txt @@ -0,0 +1,37 @@ +NUTSCAN_SCAN_NUT(3) +=================== + +NAME +---- + +nutscan_scan_nut - Scan network for available NUT services. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_nut(const char * startIP, const char * stopIP, const char * port, long usec_timeout); + +DESCRIPTION +----------- + +The *nutscan_scan_nut()* function try to detect available NUT services and their associated devices. It issues a NUT request on every IP ranging from 'startIP' to 'stopIP'. 'startIP' is mandatory, 'stopIP' is optional. Those IP may be either IPv4 or IPv6 addresses or host names. + +A specific 'port' number may be passed, or NULL to use the default NUT port. + +This function waits up to 'usec_timeout' microseconds before considering an IP address does not respond to NUT queries. + +RETURN VALUE +------------ + +The *nutscan_scan_nut()* function returns a pointer to a `nutscan_device_t` structure containing all found devices or NULL if an error occurs or no device is found. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_snmp[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_scan_snmp.3 b/docs/man/nutscan_scan_snmp.3 new file mode 100644 index 0000000..c4df10b --- /dev/null +++ b/docs/man/nutscan_scan_snmp.3 @@ -0,0 +1,87 @@ +'\" t +.\" Title: nutscan_scan_snmp +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_SNMP" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_snmp \- Scan network for SNMP devices\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_snmp(const char * start_ip,const char * stop_ip,long timeout, nutscan_snmp_t * sec); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_snmp()\fR function try to detect NUT compatible SNMP devices\&. It tries SNMP queries on every IP ranging from \fIstart_ip\fR to \fIstop_ip\fR\&. Those IP may be either IPv4 or IPv6 addresses or host names\&. +.sp +This function waits up to \fItimeout\fR microseconds before considering an IP address does not respond to SNMP queries\&. +.sp +A valid nutscan_snmp_t structure must be passed to this function\&. +.sp +The nutscan_snmp_t structure contains the following members which must be filled as described below: +.sp +.if n \{\ +.RS 4 +.\} +.nf +char * \*(Aqcommunity\*(Aq; +char * \*(AqsecLevel\*(Aq; +char * \*(AqsecName\*(Aq; +char * \*(AqauthPassword\*(Aq; +char * \*(AqprivPassword\*(Aq; +char * \*(AqauthProtocol\*(Aq; +char * \*(AqprivProtocol\*(Aq; +.fi +.if n \{\ +.RE +.\} +.sp +If \fIcommunity\fR is not NULL, SNMP v1 request are sent using this \fIcommunity\fR\&. +.sp +If \fIcommunity\fR is NULL and \fIsecLevel\fR is NULL, SNMP v1 is selected and \fIcommunity\fR is set to "public"\&. +.sp +In the other cases, SNMP v3 is used\&. \fIsecLevel\fR may be one of SNMP_SEC_LEVEL_NOAUTH, SNMP_SEC_LEVEL_AUTHNOPRIV or SNMP_SEC_LEVEL_AUTHPRIV\&. \fIsecName\fR is the security name and must be non NULL\&. +.sp +If \fIsecLevel\fR is set to SNMP_SEC_LEVEL_AUTHNOPRIV, \fIauthPassword\fR must be non NULL\&. +.sp +If \fIsecLevel\fR is set to SNMP_SEC_LEVEL_AUTHPRIV, \fIauthPassword\fR and \fIprivPassword\fR must be non NULL\&. +.sp +If \fIauthProtocol\fR is NULL, MD5 protocol is used\&. Else you can set \fIauthProtocol\fR to either "MD5" or "SHA"\&. +.sp +If \fIprivProtocol\fR is NULL, DES protocol is used\&. Else you can set \fIprivProtocol\fR to either "AES" or "DES"\&. +.sp +\fIpeername\fR and \fIhandle\fR are used internally and do not need any initialization\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_snmp()\fR function returns a pointer to a nutscan_device_t structure containing all found devices or NULL if an error occurs or no device is found\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3), \fBnutscan_cidr_to_ip\fR(3) diff --git a/docs/man/nutscan_scan_snmp.txt b/docs/man/nutscan_scan_snmp.txt new file mode 100644 index 0000000..1ddf714 --- /dev/null +++ b/docs/man/nutscan_scan_snmp.txt @@ -0,0 +1,63 @@ +NUTSCAN_SCAN_SNMP(3) +==================== + +NAME +---- + +nutscan_scan_snmp - Scan network for SNMP devices. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_snmp(const char * start_ip,const char * stop_ip,long timeout, nutscan_snmp_t * sec); + +DESCRIPTION +----------- + +The *nutscan_scan_snmp()* function try to detect NUT compatible SNMP devices. It tries SNMP queries on every IP ranging from 'start_ip' to 'stop_ip'. Those IP may be either IPv4 or IPv6 addresses or host names. + +This function waits up to 'timeout' microseconds before considering an IP address does not respond to SNMP queries. + +A valid `nutscan_snmp_t` structure must be passed to this function. + +The `nutscan_snmp_t` structure contains the following members which must be filled as described below: + + char * 'community'; + char * 'secLevel'; + char * 'secName'; + char * 'authPassword'; + char * 'privPassword'; + char * 'authProtocol'; + char * 'privProtocol'; + +If 'community' is not NULL, SNMP v1 request are sent using this 'community'. + +If 'community' is NULL and 'secLevel' is NULL, SNMP v1 is selected and 'community' is set to "public". + +In the other cases, SNMP v3 is used. 'secLevel' may be one of `SNMP_SEC_LEVEL_NOAUTH`, `SNMP_SEC_LEVEL_AUTHNOPRIV` or `SNMP_SEC_LEVEL_AUTHPRIV`. 'secName' is the security name and must be non NULL. + +If 'secLevel' is set to `SNMP_SEC_LEVEL_AUTHNOPRIV`, 'authPassword' must be non NULL. + +If 'secLevel' is set to `SNMP_SEC_LEVEL_AUTHPRIV`, 'authPassword' and 'privPassword' must be non NULL. + +If 'authProtocol' is NULL, MD5 protocol is used. Else you can set 'authProtocol' to either "MD5" or "SHA". + +If 'privProtocol' is NULL, DES protocol is used. Else you can set 'privProtocol' to either "AES" or "DES". + +'peername' and 'handle' are used internally and do not need any initialization. + +RETURN VALUE +------------ + +The *nutscan_scan_snmp()* function returns a pointer to a `nutscan_device_t` structure containing all found devices or NULL if an error occurs or no device is found. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3], linkman:nutscan_cidr_to_ip[3] diff --git a/docs/man/nutscan_scan_usb.3 b/docs/man/nutscan_scan_usb.3 new file mode 100644 index 0000000..e41af68 --- /dev/null +++ b/docs/man/nutscan_scan_usb.3 @@ -0,0 +1,49 @@ +'\" t +.\" Title: nutscan_scan_usb +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_USB" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_usb \- Scan NUT compatible USB devices\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_usb(); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_usb()\fR function try to detect NUT compatible USB devices\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_usb()\fR function returns a pointer to a nutscan_device_t structure containing all found devices or NULL if an error occurs or no device is found\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_snmp\fR(3), \fBnutscan_scan_xml_http\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3) diff --git a/docs/man/nutscan_scan_usb.txt b/docs/man/nutscan_scan_usb.txt new file mode 100644 index 0000000..36ee616 --- /dev/null +++ b/docs/man/nutscan_scan_usb.txt @@ -0,0 +1,33 @@ +NUTSCAN_SCAN_USB(3) +==================== + +NAME +---- + +nutscan_scan_usb - Scan NUT compatible USB devices. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_usb(); + +DESCRIPTION +----------- + +The *nutscan_scan_usb()* function try to detect NUT compatible USB devices. + +RETURN VALUE +------------ + +The *nutscan_scan_usb()* function returns a pointer to a `nutscan_device_t` structure containing all found devices or NULL if an error occurs or no device is found. + +SEE ALSO +-------- +linkman:nutscan_scan_snmp[3], linkman:nutscan_scan_xml_http[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3] diff --git a/docs/man/nutscan_scan_xml_http.3 b/docs/man/nutscan_scan_xml_http.3 new file mode 100644 index 0000000..8fa4c99 --- /dev/null +++ b/docs/man/nutscan_scan_xml_http.3 @@ -0,0 +1,49 @@ +'\" t +.\" Title: nutscan_scan_xml_http +.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] +.\" Generator: DocBook XSL Stylesheets v1.75.2 +.\" Date: 09/15/2011 +.\" Manual: NUT Manual +.\" Source: Network UPS Tools +.\" Language: English +.\" +.TH "NUTSCAN_SCAN_XML_HTT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +nutscan_scan_xml_http \- Scan network for XML/HTTP devices\&. +.SH "SYNOPSIS" +.sp +.nf +#include +.fi +.sp +.nf +nutscan_device_t * nutscan_scan_xml_http(long usec_timeout); +.fi +.SH "DESCRIPTION" +.sp +The \fBnutscan_scan_xml_http()\fR function try to detect NUT compatible XML/HTTP devices\&. It does this by issuing a broadcast message on currently configured network interfaces\&. It waits up to \fIusec_timeout\fR microseconds for a response from potential devices\&. +.SH "RETURN VALUE" +.sp +The \fBnutscan_scan_xml_http()\fR function returns a pointer to a nutscan_device_t structure containing all found devices or NULL if an error occurs or no device is found\&. +.SH "SEE ALSO" +.sp +\fBnutscan_scan_usb\fR(3), \fBnutscan_scan_snmp\fR(3), \fBnutscan_scan_nut\fR(3), \fBnutscan_scan_avahi\fR(3), \fBnutscan_scan_ipmi\fR(3), \fBnutscan_display_ups_conf\fR(3), \fBnutscan_display_parsable\fR(3), \fBnutscan_new_device\fR(3), \fBnutscan_free_device\fR(3), \fBnutscan_add_option_to_device\fR(3), \fBnutscan_add_device_to_device\fR(3) diff --git a/docs/man/nutscan_scan_xml_http.txt b/docs/man/nutscan_scan_xml_http.txt new file mode 100644 index 0000000..792e01f --- /dev/null +++ b/docs/man/nutscan_scan_xml_http.txt @@ -0,0 +1,33 @@ +NUTSCAN_SCAN_XML_HTTP(3) +======================== + +NAME +---- + +nutscan_scan_xml_http - Scan network for XML/HTTP devices. + +SYNOPSIS +-------- + + #include + + nutscan_device_t * nutscan_scan_xml_http(long usec_timeout); + +DESCRIPTION +----------- + +The *nutscan_scan_xml_http()* function try to detect NUT compatible XML/HTTP devices. It does this by issuing a broadcast message on currently configured network interfaces. It waits up to 'usec_timeout' microseconds for a response from potential devices. + +RETURN VALUE +------------ + +The *nutscan_scan_xml_http()* function returns a pointer to a `nutscan_device_t` structure containing all found devices or NULL if an error occurs or no device is found. + +SEE ALSO +-------- +linkman:nutscan_scan_usb[3], linkman:nutscan_scan_snmp[3], +linkman:nutscan_scan_nut[3], linkman:nutscan_scan_avahi[3], +linkman:nutscan_scan_ipmi[3], linkman:nutscan_display_ups_conf[3], +linkman:nutscan_display_parsable[3], linkman:nutscan_new_device[3], +linkman:nutscan_free_device[3], linkman:nutscan_add_option_to_device[3], +linkman:nutscan_add_device_to_device[3] diff --git a/docs/man/nutupsdrv.8 b/docs/man/nutupsdrv.8 index 1ddc49e..3b6ec7d 100644 --- a/docs/man/nutupsdrv.8 +++ b/docs/man/nutupsdrv.8 @@ -2,12 +2,12 @@ .\" Title: nutupsdrv .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "NUTUPSDRV" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "NUTUPSDRV" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/oneac.8 b/docs/man/oneac.8 index 1ff049f..40454ec 100644 --- a/docs/man/oneac.8 +++ b/docs/man/oneac.8 @@ -2,12 +2,12 @@ .\" Title: oneac .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "ONEAC" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "ONEAC" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/optiups.8 b/docs/man/optiups.8 index eda8030..d69ba6f 100644 --- a/docs/man/optiups.8 +++ b/docs/man/optiups.8 @@ -2,12 +2,12 @@ .\" Title: optiups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "OPTIUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "OPTIUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powercom.8 b/docs/man/powercom.8 index 7f48c2f..2c1268c 100644 --- a/docs/man/powercom.8 +++ b/docs/man/powercom.8 @@ -2,12 +2,12 @@ .\" Title: powercom .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "POWERCOM" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "POWERCOM" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powerman-pdu.8 b/docs/man/powerman-pdu.8 index 06cb22b..49b8cce 100644 --- a/docs/man/powerman-pdu.8 +++ b/docs/man/powerman-pdu.8 @@ -2,12 +2,12 @@ .\" Title: powerman-pdu .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "POWERMAN\-PDU" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "POWERMAN\-PDU" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/powerpanel.8 b/docs/man/powerpanel.8 index 0352956..1f4a216 100644 --- a/docs/man/powerpanel.8 +++ b/docs/man/powerpanel.8 @@ -2,12 +2,12 @@ .\" Title: powerpanel .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "POWERPANEL" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "POWERPANEL" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/rhino.8 b/docs/man/rhino.8 index f14f3d4..e51f0c5 100644 --- a/docs/man/rhino.8 +++ b/docs/man/rhino.8 @@ -2,12 +2,12 @@ .\" Title: rhino .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "RHINO" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "RHINO" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/richcomm_usb.8 b/docs/man/richcomm_usb.8 index 084731c..4a8ffaf 100644 --- a/docs/man/richcomm_usb.8 +++ b/docs/man/richcomm_usb.8 @@ -2,12 +2,12 @@ .\" Title: richcomm_usb .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "RICHCOMM_USB" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "RICHCOMM_USB" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/safenet.8 b/docs/man/safenet.8 index 8568660..bcb29b7 100644 --- a/docs/man/safenet.8 +++ b/docs/man/safenet.8 @@ -2,12 +2,12 @@ .\" Title: safenet .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "SAFENET" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "SAFENET" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/snmp-ups.8 b/docs/man/snmp-ups.8 index 440087d..e05f3e2 100644 --- a/docs/man/snmp-ups.8 +++ b/docs/man/snmp-ups.8 @@ -2,12 +2,12 @@ .\" Title: snmp-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "SNMP\-UPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "SNMP\-UPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/solis.8 b/docs/man/solis.8 index 93c54b9..2a6be0a 100644 --- a/docs/man/solis.8 +++ b/docs/man/solis.8 @@ -2,12 +2,12 @@ .\" Title: solis .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "SOLIS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "SOLIS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplite.8 b/docs/man/tripplite.8 index a0c59d9..b7ce915 100644 --- a/docs/man/tripplite.8 +++ b/docs/man/tripplite.8 @@ -2,12 +2,12 @@ .\" Title: tripplite .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "TRIPPLITE" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "TRIPPLITE" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplite_usb.8 b/docs/man/tripplite_usb.8 index 783b67c..cc18074 100644 --- a/docs/man/tripplite_usb.8 +++ b/docs/man/tripplite_usb.8 @@ -2,12 +2,12 @@ .\" Title: tripplite_usb .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "TRIPPLITE_USB" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "TRIPPLITE_USB" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/tripplitesu.8 b/docs/man/tripplitesu.8 index bf65a94..6e58be0 100644 --- a/docs/man/tripplitesu.8 +++ b/docs/man/tripplitesu.8 @@ -2,12 +2,12 @@ .\" Title: tripplitesu .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "TRIPPLITESU" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "TRIPPLITESU" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/ups.conf.5 b/docs/man/ups.conf.5 index 0a35a09..cf33682 100644 --- a/docs/man/ups.conf.5 +++ b/docs/man/ups.conf.5 @@ -2,12 +2,12 @@ .\" Title: ups.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPS\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPS\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsc.8 b/docs/man/upsc.8 index e6dc870..5ce07c6 100644 --- a/docs/man/upsc.8 +++ b/docs/man/upsc.8 @@ -2,12 +2,12 @@ .\" Title: upsc .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSC" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSC" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_connect.3 b/docs/man/upscli_connect.3 index 0ab6637..82d900f 100644 --- a/docs/man/upscli_connect.3 +++ b/docs/man/upscli_connect.3 @@ -2,12 +2,12 @@ .\" Title: upscli_connect .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_CONNECT" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_CONNECT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_disconnect.3 b/docs/man/upscli_disconnect.3 index f8a5a4a..0a8bbd1 100644 --- a/docs/man/upscli_disconnect.3 +++ b/docs/man/upscli_disconnect.3 @@ -2,12 +2,12 @@ .\" Title: upscli_disconnect .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_DISCONNECT" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_DISCONNECT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_fd.3 b/docs/man/upscli_fd.3 index 96d807b..cfebf69 100644 --- a/docs/man/upscli_fd.3 +++ b/docs/man/upscli_fd.3 @@ -2,12 +2,12 @@ .\" Title: upscli_fd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_FD" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_FD" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_get.3 b/docs/man/upscli_get.3 index 3f6a545..8f046cc 100644 --- a/docs/man/upscli_get.3 +++ b/docs/man/upscli_get.3 @@ -2,12 +2,12 @@ .\" Title: upscli_get .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_GET" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_GET" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_list_next.3 b/docs/man/upscli_list_next.3 index 783d393..1091d3c 100644 --- a/docs/man/upscli_list_next.3 +++ b/docs/man/upscli_list_next.3 @@ -2,12 +2,12 @@ .\" Title: upscli_list_next .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_LIST_NEXT" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_LIST_NEXT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_list_start.3 b/docs/man/upscli_list_start.3 index 941e868..626ae30 100644 --- a/docs/man/upscli_list_start.3 +++ b/docs/man/upscli_list_start.3 @@ -2,12 +2,12 @@ .\" Title: upscli_list_start .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_LIST_START" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_LIST_START" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_readline.3 b/docs/man/upscli_readline.3 index 8f2a741..16842e5 100644 --- a/docs/man/upscli_readline.3 +++ b/docs/man/upscli_readline.3 @@ -2,12 +2,12 @@ .\" Title: upscli_readline .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_READLINE" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_READLINE" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_sendline.3 b/docs/man/upscli_sendline.3 index 13efe30..1a45cde 100644 --- a/docs/man/upscli_sendline.3 +++ b/docs/man/upscli_sendline.3 @@ -2,12 +2,12 @@ .\" Title: upscli_sendline .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_SENDLINE" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_SENDLINE" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_splitaddr.3 b/docs/man/upscli_splitaddr.3 index cd38178..afbcaf4 100644 --- a/docs/man/upscli_splitaddr.3 +++ b/docs/man/upscli_splitaddr.3 @@ -2,12 +2,12 @@ .\" Title: upscli_splitaddr .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_SPLITADDR" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_SPLITADDR" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_splitname.3 b/docs/man/upscli_splitname.3 index 5180536..5cfdb4e 100644 --- a/docs/man/upscli_splitname.3 +++ b/docs/man/upscli_splitname.3 @@ -2,12 +2,12 @@ .\" Title: upscli_splitname .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_SPLITNAME" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_SPLITNAME" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_ssl.3 b/docs/man/upscli_ssl.3 index 2256b60..b93159b 100644 --- a/docs/man/upscli_ssl.3 +++ b/docs/man/upscli_ssl.3 @@ -2,12 +2,12 @@ .\" Title: upscli_ssl .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_SSL" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_SSL" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_strerror.3 b/docs/man/upscli_strerror.3 index ffc4d1f..49408f4 100644 --- a/docs/man/upscli_strerror.3 +++ b/docs/man/upscli_strerror.3 @@ -2,12 +2,12 @@ .\" Title: upscli_strerror .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_STRERROR" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_STRERROR" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscli_upserror.3 b/docs/man/upscli_upserror.3 index cd96ba4..9d284ab 100644 --- a/docs/man/upscli_upserror.3 +++ b/docs/man/upscli_upserror.3 @@ -2,12 +2,12 @@ .\" Title: upscli_upserror .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLI_UPSERROR" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLI_UPSERROR" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsclient.3 b/docs/man/upsclient.3 index ece6715..0e09cee 100644 --- a/docs/man/upsclient.3 +++ b/docs/man/upsclient.3 @@ -2,12 +2,12 @@ .\" Title: upsclient .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCLIENT" "3" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCLIENT" "3" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscmd.8 b/docs/man/upscmd.8 index b26db9f..2523231 100644 --- a/docs/man/upscmd.8 +++ b/docs/man/upscmd.8 @@ -2,12 +2,12 @@ .\" Title: upscmd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCMD" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCMD" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upscode2.8 b/docs/man/upscode2.8 index b2edf82..50e8fd1 100644 --- a/docs/man/upscode2.8 +++ b/docs/man/upscode2.8 @@ -2,12 +2,12 @@ .\" Title: upscode2 .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSCODE2" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSCODE2" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.8 b/docs/man/upsd.8 index 6be6ba0..5e93141 100644 --- a/docs/man/upsd.8 +++ b/docs/man/upsd.8 @@ -2,12 +2,12 @@ .\" Title: upsd .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSD" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSD" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.conf.5 b/docs/man/upsd.conf.5 index 9bd303f..d1ce79f 100644 --- a/docs/man/upsd.conf.5 +++ b/docs/man/upsd.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsd.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSD\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSD\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsd.users.5 b/docs/man/upsd.users.5 index 11e41ee..008776e 100644 --- a/docs/man/upsd.users.5 +++ b/docs/man/upsd.users.5 @@ -2,12 +2,12 @@ .\" Title: upsd.users .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSD\&.USERS" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSD\&.USERS" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsdrvctl.8 b/docs/man/upsdrvctl.8 index 8223a68..35ced3a 100644 --- a/docs/man/upsdrvctl.8 +++ b/docs/man/upsdrvctl.8 @@ -2,12 +2,12 @@ .\" Title: upsdrvctl .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSDRVCTL" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSDRVCTL" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsimage.cgi.8 b/docs/man/upsimage.cgi.8 index 1b42870..6165ca2 100644 --- a/docs/man/upsimage.cgi.8 +++ b/docs/man/upsimage.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsimage.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSIMAGE\&.CGI" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSIMAGE\&.CGI" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upslog.8 b/docs/man/upslog.8 index 869f16a..2e5df76 100644 --- a/docs/man/upslog.8 +++ b/docs/man/upslog.8 @@ -2,12 +2,12 @@ .\" Title: upslog .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSLOG" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSLOG" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsmon.8 b/docs/man/upsmon.8 index d508ccb..5322a56 100644 --- a/docs/man/upsmon.8 +++ b/docs/man/upsmon.8 @@ -2,12 +2,12 @@ .\" Title: upsmon .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSMON" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSMON" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsmon.conf.5 b/docs/man/upsmon.conf.5 index 3f70b14..558df48 100644 --- a/docs/man/upsmon.conf.5 +++ b/docs/man/upsmon.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsmon.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSMON\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSMON\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsrw.8 b/docs/man/upsrw.8 index 85a37bb..2634aeb 100644 --- a/docs/man/upsrw.8 +++ b/docs/man/upsrw.8 @@ -2,12 +2,12 @@ .\" Title: upsrw .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSRW" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSRW" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upssched.8 b/docs/man/upssched.8 index 069855c..6b2b056 100644 --- a/docs/man/upssched.8 +++ b/docs/man/upssched.8 @@ -2,12 +2,12 @@ .\" Title: upssched .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSCHED" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSCHED" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upssched.conf.5 b/docs/man/upssched.conf.5 index 7953be4..58e4e91 100644 --- a/docs/man/upssched.conf.5 +++ b/docs/man/upssched.conf.5 @@ -2,12 +2,12 @@ .\" Title: upssched.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSCHED\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSCHED\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsset.cgi.8 b/docs/man/upsset.cgi.8 index f2f7230..b1f4249 100644 --- a/docs/man/upsset.cgi.8 +++ b/docs/man/upsset.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsset.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSET\&.CGI" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSET\&.CGI" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsset.conf.5 b/docs/man/upsset.conf.5 index 385f0e8..2a496f3 100644 --- a/docs/man/upsset.conf.5 +++ b/docs/man/upsset.conf.5 @@ -2,12 +2,12 @@ .\" Title: upsset.conf .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSET\&.CONF" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSET\&.CONF" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsstats.cgi.8 b/docs/man/upsstats.cgi.8 index e51e116..0214efc 100644 --- a/docs/man/upsstats.cgi.8 +++ b/docs/man/upsstats.cgi.8 @@ -2,12 +2,12 @@ .\" Title: upsstats.cgi .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSTATS\&.CGI" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSTATS\&.CGI" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/upsstats.html.5 b/docs/man/upsstats.html.5 index 6159d5b..a60dc38 100644 --- a/docs/man/upsstats.html.5 +++ b/docs/man/upsstats.html.5 @@ -2,12 +2,12 @@ .\" Title: upsstats.html .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "UPSSTATS\&.HTML" "5" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "UPSSTATS\&.HTML" "5" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/usbhid-ups.8 b/docs/man/usbhid-ups.8 index 551ba96..4735057 100644 --- a/docs/man/usbhid-ups.8 +++ b/docs/man/usbhid-ups.8 @@ -2,12 +2,12 @@ .\" Title: usbhid-ups .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "USBHID\-UPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "USBHID\-UPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/man/victronups.8 b/docs/man/victronups.8 index d635204..0982885 100644 --- a/docs/man/victronups.8 +++ b/docs/man/victronups.8 @@ -2,12 +2,12 @@ .\" Title: victronups .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets v1.75.2 -.\" Date: 05/31/2011 +.\" Date: 09/15/2011 .\" Manual: NUT Manual .\" Source: Network UPS Tools .\" Language: English .\" -.TH "VICTRONUPS" "8" "05/31/2011" "Network UPS Tools" "NUT Manual" +.TH "VICTRONUPS" "8" "09/15/2011" "Network UPS Tools" "NUT Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- diff --git a/docs/new-clients.txt b/docs/new-clients.txt index da2e3ac..5a10e5c 100644 --- a/docs/new-clients.txt +++ b/docs/new-clients.txt @@ -123,3 +123,13 @@ multiple UPS units). print $other_ups{MFR}, " ", $other_ups{MODEL}, "\n"; +Java +---- + +This chapter presents the new Java support for NUT, called jNut. + +include::../scripts/java/README[] + +include::../scripts/java/jNut/README[] + +include::../scripts/java/jNutList/README[] diff --git a/docs/nut-names.txt b/docs/nut-names.txt index f99c13d..147e78c 100644 --- a/docs/nut-names.txt +++ b/docs/nut-names.txt @@ -320,7 +320,7 @@ battery: Any battery details | battery.packs | Number of battery packs | 001 | battery.packs.bad | Number of bad battery packs | 000 | battery.type | Battery chemistry (opaque - (opaque string) | PbAc + string) | PbAc | battery.protection | Prevent deep discharge of battery | yes | battery.energysave | Switch off when running on diff --git a/docs/stable-hcl.txt b/docs/stable-hcl.txt index b522d89..0599d3c 100644 --- a/docs/stable-hcl.txt +++ b/docs/stable-hcl.txt @@ -126,15 +126,17 @@ that we have missed listing some that are supported, or made an error. So that this list can be as accurate as possible, please report any omissions to the -link:http://lists.alioth.debian.org/mailman/listinfo/nut-upsuser[NUT Users] -mailing list, with *[HCL]* in the subject and including the following -information: +link:http://lists.alioth.debian.org/mailman/listinfo/nut-upsdev[NUT Developers] +mailing list, including the following information: -- Device manufacturer and name, -- upsc output (upsrw and upscmd outputs are also welcome), -- link:docs/user-manual.chunked/ar01s06.html#Shutdown_design[shutdown sequence] +- mail subject: [HCL] supported by +replacing Manufacturer, Device and driver by your specific values, +- mail body: + - Device manufacturer and name, + - upsc output (upsrw and upscmd outputs are also welcome), + - link:docs/user-manual.chunked/ar01s06.html#Shutdown_design[shutdown sequence] testing results, -- a link to an online description is also appreciated. + - a link to an online description is also appreciated. *Pointing the present HCL* @@ -153,9 +155,9 @@ The form of the URL is the following: |========================================================================== | | | support-level | a number from '1' to '5' -.3+^.^| device-type | 'ups' for uninterruptible power supply - | 'pdu' for power distribution unit - | 'scd' for solar controller device +.3+^.^| device-type | - 'ups' for uninterruptible power supply + | - 'pdu' for power distribution unit + | - 'scd' for solar controller device | manufacturer | a manufacturer name from the selection list | model | a model name from the selection list .3+^.^| connection | 'USB' diff --git a/docs/website/Makefile.in b/docs/website/Makefile.in index d6ed1f3..b0c7efa 100644 --- a/docs/website/Makefile.in +++ b/docs/website/Makefile.in @@ -43,6 +43,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -109,10 +111,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -150,6 +156,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -214,6 +224,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/docs/website/news.txt b/docs/website/news.txt index 46cbc6a..05ae5fc 100644 --- a/docs/website/news.txt +++ b/docs/website/news.txt @@ -1,3 +1,7 @@ +- September 15, 2011: 2.6.2 released +- September 2, 2011: link:download.html#_java_packages[jNUT (NUT Java support) 0.1-SNAPSHOT released] +- July 4, 2011: link:download.html#_binary_packages[Beta NUT 2.6.1-1 package for Windows released] +- June 8, 2011: link:http://www.dell.com/us/business/p/powervault-nx3500/pd[Dell PowerVault NX3500] use NUT for power protection - June 1, 2011: 2.6.1 released - May 19, 2011: link:download.html#_binary_packages[Beta NUT 2.6.0-1 package for Windows released] - January 14, 2011: 2.6.0 released @@ -8,4 +12,4 @@ - May 12, 2010: link:http://www.lestat.st/informatique/projets/nut-monitor-en[NUT-Monitor] 1.2 released - March 22, 2010: link:http://knut.prynych.cz[KNutClient] 1.0 - February 23, 2010: 2.4.3 released -- February 19, 2010: 2.4.2 released +- February 19, 2010: 2.4.2 released diff --git a/docs/website/projects.txt b/docs/website/projects.txt index afba115..53faad5 100644 --- a/docs/website/projects.txt +++ b/docs/website/projects.txt @@ -11,7 +11,8 @@ Graphical desktop clients link:http://sourceforge.net/projects/gknut/[GKrellM NUT] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Simple UPS monitoring plugin for GKrellM. Uses NUT (Network UPS Tools) for UPS connection. +Simple UPS monitoring plugin for GKrellM. Uses NUT (Network UPS Tools) for UPS +connection. link:http://knut.prynych.cz[KNutClient] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -22,7 +23,8 @@ link:http://www.lestat.st/en/informatique/projets/nut-monitor[NUT-Monitor] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ NUT-Monitor is a graphical application to monitor and manage UPSes connected to -a NUT server. This application is written in Python and PyGTK, and uses the <> class. +a NUT server. This application is written in Python and PyGTK, and uses the +<> class. NOTE: NUT-Monitor is part of NUT since version NUT 2.4.1. It will further evolve toward the NUT Control Center. @@ -30,7 +32,8 @@ It will further evolve toward the NUT Control Center. link:http://download.mgeops.com/explore/eng/ptp/ptp_sol.htm?sol=PSP[Eaton - Personal Solution Pac] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -NUT configuration and monitoring software for Eaton (previously MGE Office Protection Systems) units. +NUT configuration and monitoring software for Eaton (previously MGE Office +Protection Systems) units. link:http://www.amautacorp.com/staff/Rudd-O/ups-monitor/[UPS Monitor] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -123,32 +126,45 @@ link:http://www.lestat.st/informatique/projets/pynut-en[PyNUT] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PyNUT is an abstraction class written in Python to access NUT (Network UPS -Tools) server and execute commands without needing to know the communication protocol. +Tools) server and execute commands without needing to know the communication +protocol. + +NOTE: PyNUT is part of NUT since version NUT 2.4.1. link:http://bugs.debian.org/343530[RRDtool logging support] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This patch adds link:http://oss.oetiker.ch/rrdtool[RRDtool] logging support to NUT. +This patch adds link:http://oss.oetiker.ch/rrdtool[RRDtool] logging support to +NUT. link:http://home.tele2.fr/elrik/[ups_control] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A developing Python wrapper to upsc which can generate mails and shutdown the machine. +A developing Python wrapper to upsc which can generate mails and shutdown the +machine. link:http://search.cpan.org/search?dist=ups-nut[UPS::Nut] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A Perl module to talk to an UPS via NUT (Network UPS Tools) upsd. +NOTE: UPS::Nut is part of NUT since version NUT 2.6.1. Hardware projects involving NUT ------------------------------- +link:http://www.dell.com/us/business/p/powervault-nx3500/pd[Dell PowerVault NX3500] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Dell is using NUT to protect the new PowerVault NX3500 storage devices. + link:http://www.opengear.com/UPS.html[OpenGear] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Opengear provides an advanced NUT integration into many models. -There is also a link:http://www.opengear.com/Videos/Network-UPS-Tools/Network-UPS-Tools.html[video presentation] of the NUT integration. +There is also a +link:http://www.opengear.com/Videos/Network-UPS-Tools/Network-UPS-Tools.html[video presentation] +of the NUT integration. For more information on Opengear's contributions to NUT, have a look at the link:acknowledgements.html[acknowledgements information]. @@ -163,8 +179,8 @@ its devices. Alcatel Lucent IPBX ~~~~~~~~~~~~~~~~~~~ -Alcatel has been working for years with us (Patrick Agrain and Arnaud) to improve -NUT integration into some of their IPBX. +Alcatel has been working for years with us (Patrick Agrain and Arnaud) to +improve NUT integration into some of their IPBX. link:http://www.readynas.com/?page_id=92[Netgear ReadyNAS] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -182,6 +198,7 @@ Notes ------- - Client authors: send updates on your releases to the NUT users mailing list. -We will also put a link to you in the news section of the top page when things change. +We will also put a link to you in the news section of the top page when things +change. - If you know of a project which should be listed, please send in the URL. diff --git a/docs/website/web-layout.conf b/docs/website/web-layout.conf index 29a4406..4cab7b0 100644 --- a/docs/website/web-layout.conf +++ b/docs/website/web-layout.conf @@ -153,11 +153,11 @@ ifndef::textonly[] src="http://jigsaw.w3.org/css-validator/images/vcss-blue" alt="Valid CSS!" /> - + Get Firefox! - + src='http://www.mozilla.org/contribute/buttons/110x32bubble_b.png' + alt='Firefox Download Button' /> + endif::textonly[] endif::badges[] diff --git a/drivers/Makefile.am b/drivers/Makefile.am index 2391963..9690da5 100644 --- a/drivers/Makefile.am +++ b/drivers/Makefile.am @@ -29,13 +29,16 @@ endif if WITH_LIBPOWERMAN AM_CFLAGS += $(LIBPOWERMAN_CFLAGS) endif +if WITH_IPMI + AM_CFLAGS += $(LIBIPMI_CFLAGS) +endif -SERIAL_DRIVERLIST = apcsmart bcmxcp belkin belkinunv bestfcom \ +SERIAL_DRIVERLIST = bcmxcp belkin belkinunv bestfcom \ bestfortress bestuferrups bestups dummy-ups etapro everups \ gamatronic genericups isbmex liebert liebert-esp2 masterguard metasys \ mge-shut mge-utalk microdowell newmge-shut oneac optiups powercom rhino \ safenet skel solis tripplite tripplitesu upscode2 victronups powerpanel \ - blazer_ser clone clone-outlet ivtscd + blazer_ser clone clone-outlet ivtscd apcsmart apcsmart-old SNMP_DRIVERLIST = snmp-ups USB_LIBUSB_DRIVERLIST = usbhid-ups bcmxcp_usb tripplite_usb \ blazer_usb richcomm_usb @@ -71,6 +74,9 @@ endif if WITH_LIBPOWERMAN driverexec_PROGRAMS += powerman-pdu endif +if WITH_IPMI + driverexec_PROGRAMS += nut-ipmipsu +endif else driverexec_PROGRAMS += skel endif @@ -86,7 +92,8 @@ upsdrvctl_SOURCES = upsdrvctl.c upsdrvctl_LDADD = $(LDADD_COMMON) # serial drivers: all of them use standard LDADD and CFLAGS -apcsmart_SOURCES = apcsmart.c +apcsmart_SOURCES = apcsmart.c apcsmart_tabs.c +apcsmart_old_SOURCES = apcsmart-old.c bcmxcp_SOURCES = bcmxcp.c bcmxcp_ser.c bcmxcp_LDADD = $(LDADD) -lm belkin_SOURCES = belkin.c @@ -200,20 +207,28 @@ netxml_ups_LDADD = $(LDADD_DRIVERS) $(LIBNEON_LIBS) powerman_pdu_SOURCES = powerman-pdu.c powerman_pdu_LDADD = $(LDADD) $(LIBPOWERMAN_LIBS) +# IPMI PSU +nut_ipmipsu_SOURCES = nut-ipmipsu.c +if WITH_FREEIPMI + nut_ipmipsu_SOURCES += nut-libfreeipmi.c +endif +nut_ipmipsu_LDADD = $(LDADD) $(LIBIPMI_LIBS) + # ---------------------------------------------------------------------- # List of header files. The purpose of this list is not dependency # tracking (which is automatic), but to ensure these files are # distributed by "make dist". -dist_noinst_HEADERS = apc-mib.h apc-hid.h apcsmart.h baytech-mib.h bcmxcp.h \ +dist_noinst_HEADERS = apc-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ bcmxcp_io.h belkin.h belkin-hid.h bestpower-mib.h blazer.h cps-hid.h dstate.h \ dstate-hal.h dummy-ups.h eaton-mib.h explore-hid.h gamatronic.h genericups.h \ hidparser.h hidtypes.h ietf-mib.h libhid.h libshut.h libusb.h liebert-hid.h \ main.h main-hal.h mge-hid.h mge-mib.h mge-shut.h mge-utalk.h \ - mge-xml.h microdowell.h netvision-mib.h netxml-ups.h oneac.h \ + mge-xml.h microdowell.h netvision-mib.h netxml-ups.h nut-ipmi.h oneac.h \ powercom.h powerpanel.h powerp-bin.h powerp-txt.h powerware-mib.h raritan-pdu-mib.h \ safenet.h serial.h snmp-ups.h solis.h tripplite.h tripplite-hid.h \ - upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h + upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \ + apcsmart.h apcsmart_tabs.h apcsmart-old.h # Define a dummy library so that Automake builds rules for the # corresponding object files. This library is not actually built, diff --git a/drivers/Makefile.in b/drivers/Makefile.in index 80e5e13..08758d2 100644 --- a/drivers/Makefile.in +++ b/drivers/Makefile.in @@ -43,26 +43,29 @@ target_triplet = @target@ @WITH_SNMP_TRUE@am__append_3 = $(LIBNETSNMP_CFLAGS) @WITH_NEONXML_TRUE@am__append_4 = $(LIBNEON_CFLAGS) @WITH_LIBPOWERMAN_TRUE@am__append_5 = $(LIBPOWERMAN_CFLAGS) +@WITH_IPMI_TRUE@am__append_6 = $(LIBIPMI_CFLAGS) EXTRA_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_4) \ $(am__EXEEXT_5) @SOME_DRIVERS_FALSE@driverexec_PROGRAMS = $(am__EXEEXT_6) \ @SOME_DRIVERS_FALSE@ $(am__EXEEXT_7) $(am__EXEEXT_8) \ @SOME_DRIVERS_FALSE@ $(am__EXEEXT_9) $(am__EXEEXT_10) \ -@SOME_DRIVERS_FALSE@ upsdrvctl$(EXEEXT) +@SOME_DRIVERS_FALSE@ $(am__EXEEXT_11) upsdrvctl$(EXEEXT) @SOME_DRIVERS_TRUE@driverexec_PROGRAMS = $(DRIVER_BUILD_LIST) \ @SOME_DRIVERS_TRUE@ $(am__EXEEXT_6) $(am__EXEEXT_7) \ @SOME_DRIVERS_TRUE@ $(am__EXEEXT_8) $(am__EXEEXT_9) \ -@SOME_DRIVERS_TRUE@ $(am__EXEEXT_10) skel$(EXEEXT) \ -@SOME_DRIVERS_TRUE@ upsdrvctl$(EXEEXT) -@SOME_DRIVERS_FALSE@@WITH_SERIAL_TRUE@am__append_6 = $(SERIAL_DRIVERLIST) -@SOME_DRIVERS_FALSE@@WITH_SNMP_TRUE@am__append_7 = $(SNMP_DRIVERLIST) -@SOME_DRIVERS_FALSE@@WITH_USB_TRUE@am__append_8 = $(USB_LIBUSB_DRIVERLIST) +@SOME_DRIVERS_TRUE@ $(am__EXEEXT_10) $(am__EXEEXT_11) \ +@SOME_DRIVERS_TRUE@ skel$(EXEEXT) upsdrvctl$(EXEEXT) +@SOME_DRIVERS_FALSE@@WITH_SERIAL_TRUE@am__append_7 = $(SERIAL_DRIVERLIST) +@SOME_DRIVERS_FALSE@@WITH_SNMP_TRUE@am__append_8 = $(SNMP_DRIVERLIST) +@SOME_DRIVERS_FALSE@@WITH_USB_TRUE@am__append_9 = $(USB_LIBUSB_DRIVERLIST) @SOME_DRIVERS_FALSE@@WITH_HAL_TRUE@halexec_PROGRAMS = \ -@SOME_DRIVERS_FALSE@@WITH_HAL_TRUE@ $(am__EXEEXT_11) -@SOME_DRIVERS_FALSE@@WITH_NEONXML_TRUE@am__append_9 = $(NEONXML_DRIVERLIST) -@SOME_DRIVERS_FALSE@@WITH_LIBPOWERMAN_TRUE@am__append_10 = powerman-pdu -@WITH_SSL_TRUE@am__append_11 = $(LIBSSL_CFLAGS) -@WITH_SSL_TRUE@am__append_12 = $(LIBSSL_LIBS) +@SOME_DRIVERS_FALSE@@WITH_HAL_TRUE@ $(am__EXEEXT_12) +@SOME_DRIVERS_FALSE@@WITH_NEONXML_TRUE@am__append_10 = $(NEONXML_DRIVERLIST) +@SOME_DRIVERS_FALSE@@WITH_LIBPOWERMAN_TRUE@am__append_11 = powerman-pdu +@SOME_DRIVERS_FALSE@@WITH_IPMI_TRUE@am__append_12 = nut-ipmipsu +@WITH_SSL_TRUE@am__append_13 = $(LIBSSL_CFLAGS) +@WITH_SSL_TRUE@am__append_14 = $(LIBSSL_LIBS) +@WITH_FREEIPMI_TRUE@am__append_15 = nut-libfreeipmi.c subdir = drivers DIST_COMMON = $(dist_noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in @@ -73,6 +76,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -103,19 +108,19 @@ libnuthalmain_a_LIBADD = am_libnuthalmain_a_OBJECTS = main-hal.$(OBJEXT) dstate-hal.$(OBJEXT) \ usb-common.$(OBJEXT) libnuthalmain_a_OBJECTS = $(am_libnuthalmain_a_OBJECTS) -am__EXEEXT_1 = apcsmart$(EXEEXT) bcmxcp$(EXEEXT) belkin$(EXEEXT) \ - belkinunv$(EXEEXT) bestfcom$(EXEEXT) bestfortress$(EXEEXT) \ - bestuferrups$(EXEEXT) bestups$(EXEEXT) dummy-ups$(EXEEXT) \ - etapro$(EXEEXT) everups$(EXEEXT) gamatronic$(EXEEXT) \ - genericups$(EXEEXT) isbmex$(EXEEXT) liebert$(EXEEXT) \ - liebert-esp2$(EXEEXT) masterguard$(EXEEXT) metasys$(EXEEXT) \ - mge-shut$(EXEEXT) mge-utalk$(EXEEXT) microdowell$(EXEEXT) \ - newmge-shut$(EXEEXT) oneac$(EXEEXT) optiups$(EXEEXT) \ - powercom$(EXEEXT) rhino$(EXEEXT) safenet$(EXEEXT) \ - skel$(EXEEXT) solis$(EXEEXT) tripplite$(EXEEXT) \ - tripplitesu$(EXEEXT) upscode2$(EXEEXT) victronups$(EXEEXT) \ - powerpanel$(EXEEXT) blazer_ser$(EXEEXT) clone$(EXEEXT) \ - clone-outlet$(EXEEXT) ivtscd$(EXEEXT) +am__EXEEXT_1 = bcmxcp$(EXEEXT) belkin$(EXEEXT) belkinunv$(EXEEXT) \ + bestfcom$(EXEEXT) bestfortress$(EXEEXT) bestuferrups$(EXEEXT) \ + bestups$(EXEEXT) dummy-ups$(EXEEXT) etapro$(EXEEXT) \ + everups$(EXEEXT) gamatronic$(EXEEXT) genericups$(EXEEXT) \ + isbmex$(EXEEXT) liebert$(EXEEXT) liebert-esp2$(EXEEXT) \ + masterguard$(EXEEXT) metasys$(EXEEXT) mge-shut$(EXEEXT) \ + mge-utalk$(EXEEXT) microdowell$(EXEEXT) newmge-shut$(EXEEXT) \ + oneac$(EXEEXT) optiups$(EXEEXT) powercom$(EXEEXT) \ + rhino$(EXEEXT) safenet$(EXEEXT) skel$(EXEEXT) solis$(EXEEXT) \ + tripplite$(EXEEXT) tripplitesu$(EXEEXT) upscode2$(EXEEXT) \ + victronups$(EXEEXT) powerpanel$(EXEEXT) blazer_ser$(EXEEXT) \ + clone$(EXEEXT) clone-outlet$(EXEEXT) ivtscd$(EXEEXT) \ + apcsmart$(EXEEXT) apcsmart-old$(EXEEXT) am__EXEEXT_2 = snmp-ups$(EXEEXT) am__EXEEXT_3 = usbhid-ups$(EXEEXT) bcmxcp_usb$(EXEEXT) \ tripplite_usb$(EXEEXT) blazer_usb$(EXEEXT) \ @@ -127,19 +132,25 @@ am__EXEEXT_5 = netxml-ups$(EXEEXT) @SOME_DRIVERS_FALSE@@WITH_USB_TRUE@am__EXEEXT_8 = $(am__EXEEXT_3) @SOME_DRIVERS_FALSE@@WITH_NEONXML_TRUE@am__EXEEXT_9 = $(am__EXEEXT_5) @SOME_DRIVERS_FALSE@@WITH_LIBPOWERMAN_TRUE@am__EXEEXT_10 = powerman-pdu$(EXEEXT) +@SOME_DRIVERS_FALSE@@WITH_IPMI_TRUE@am__EXEEXT_11 = \ +@SOME_DRIVERS_FALSE@@WITH_IPMI_TRUE@ nut-ipmipsu$(EXEEXT) am__installdirs = "$(DESTDIR)$(driverexecdir)" \ "$(DESTDIR)$(halexecdir)" -am__EXEEXT_11 = hald-addon-usbhid-ups$(EXEEXT) \ +am__EXEEXT_12 = hald-addon-usbhid-ups$(EXEEXT) \ hald-addon-bcmxcp_usb$(EXEEXT) \ hald-addon-tripplite_usb$(EXEEXT) \ hald-addon-blazer_usb$(EXEEXT) PROGRAMS = $(driverexec_PROGRAMS) $(halexec_PROGRAMS) -am_apcsmart_OBJECTS = apcsmart.$(OBJEXT) +am_apcsmart_OBJECTS = apcsmart.$(OBJEXT) apcsmart_tabs.$(OBJEXT) apcsmart_OBJECTS = $(am_apcsmart_OBJECTS) apcsmart_LDADD = $(LDADD) am__DEPENDENCIES_1 = am__DEPENDENCIES_2 = $(LDADD_DRIVERS) $(am__DEPENDENCIES_1) serial.o apcsmart_DEPENDENCIES = $(am__DEPENDENCIES_2) +am_apcsmart_old_OBJECTS = apcsmart-old.$(OBJEXT) +apcsmart_old_OBJECTS = $(am_apcsmart_old_OBJECTS) +apcsmart_old_LDADD = $(LDADD) +apcsmart_old_DEPENDENCIES = $(am__DEPENDENCIES_2) am_bcmxcp_OBJECTS = bcmxcp.$(OBJEXT) bcmxcp_ser.$(OBJEXT) bcmxcp_OBJECTS = $(am_bcmxcp_OBJECTS) am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) @@ -283,6 +294,11 @@ newmge_shut_DEPENDENCIES = $(am__DEPENDENCIES_3) newmge_shut_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(newmge_shut_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__nut_ipmipsu_SOURCES_DIST = nut-ipmipsu.c nut-libfreeipmi.c +@WITH_FREEIPMI_TRUE@am__objects_2 = nut-libfreeipmi.$(OBJEXT) +am_nut_ipmipsu_OBJECTS = nut-ipmipsu.$(OBJEXT) $(am__objects_2) +nut_ipmipsu_OBJECTS = $(am_nut_ipmipsu_OBJECTS) +nut_ipmipsu_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) am_oneac_OBJECTS = oneac.$(OBJEXT) oneac_OBJECTS = $(am_oneac_OBJECTS) oneac_LDADD = $(LDADD) @@ -366,21 +382,22 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libdummy_a_SOURCES) $(libnuthalmain_a_SOURCES) \ - $(apcsmart_SOURCES) $(bcmxcp_SOURCES) $(bcmxcp_usb_SOURCES) \ - $(belkin_SOURCES) $(belkinunv_SOURCES) $(bestfcom_SOURCES) \ - bestfortress.c $(bestuferrups_SOURCES) $(bestups_SOURCES) \ - $(blazer_ser_SOURCES) $(blazer_usb_SOURCES) $(clone_SOURCES) \ - $(clone_outlet_SOURCES) $(dummy_ups_SOURCES) $(etapro_SOURCES) \ - $(everups_SOURCES) $(gamatronic_SOURCES) $(genericups_SOURCES) \ - $(hald_addon_bcmxcp_usb_SOURCES) \ + $(apcsmart_SOURCES) $(apcsmart_old_SOURCES) $(bcmxcp_SOURCES) \ + $(bcmxcp_usb_SOURCES) $(belkin_SOURCES) $(belkinunv_SOURCES) \ + $(bestfcom_SOURCES) bestfortress.c $(bestuferrups_SOURCES) \ + $(bestups_SOURCES) $(blazer_ser_SOURCES) $(blazer_usb_SOURCES) \ + $(clone_SOURCES) $(clone_outlet_SOURCES) $(dummy_ups_SOURCES) \ + $(etapro_SOURCES) $(everups_SOURCES) $(gamatronic_SOURCES) \ + $(genericups_SOURCES) $(hald_addon_bcmxcp_usb_SOURCES) \ $(hald_addon_blazer_usb_SOURCES) \ $(hald_addon_tripplite_usb_SOURCES) \ $(hald_addon_usbhid_ups_SOURCES) $(isbmex_SOURCES) \ $(ivtscd_SOURCES) $(liebert_SOURCES) $(liebert_esp2_SOURCES) \ $(masterguard_SOURCES) $(metasys_SOURCES) $(mge_shut_SOURCES) \ $(mge_utalk_SOURCES) $(microdowell_SOURCES) \ - $(netxml_ups_SOURCES) $(newmge_shut_SOURCES) $(oneac_SOURCES) \ - $(optiups_SOURCES) $(powercom_SOURCES) $(powerman_pdu_SOURCES) \ + $(netxml_ups_SOURCES) $(newmge_shut_SOURCES) \ + $(nut_ipmipsu_SOURCES) $(oneac_SOURCES) $(optiups_SOURCES) \ + $(powercom_SOURCES) $(powerman_pdu_SOURCES) \ $(powerpanel_SOURCES) $(rhino_SOURCES) $(richcomm_usb_SOURCES) \ $(safenet_SOURCES) $(skel_SOURCES) $(snmp_ups_SOURCES) \ $(solis_SOURCES) $(tripplite_SOURCES) $(tripplite_usb_SOURCES) \ @@ -388,20 +405,21 @@ SOURCES = $(libdummy_a_SOURCES) $(libnuthalmain_a_SOURCES) \ $(upsdrvctl_SOURCES) $(usbhid_ups_SOURCES) \ $(victronups_SOURCES) DIST_SOURCES = $(libdummy_a_SOURCES) $(libnuthalmain_a_SOURCES) \ - $(apcsmart_SOURCES) $(bcmxcp_SOURCES) $(bcmxcp_usb_SOURCES) \ - $(belkin_SOURCES) $(belkinunv_SOURCES) $(bestfcom_SOURCES) \ - bestfortress.c $(bestuferrups_SOURCES) $(bestups_SOURCES) \ - $(blazer_ser_SOURCES) $(blazer_usb_SOURCES) $(clone_SOURCES) \ - $(clone_outlet_SOURCES) $(dummy_ups_SOURCES) $(etapro_SOURCES) \ - $(everups_SOURCES) $(gamatronic_SOURCES) $(genericups_SOURCES) \ - $(hald_addon_bcmxcp_usb_SOURCES) \ + $(apcsmart_SOURCES) $(apcsmart_old_SOURCES) $(bcmxcp_SOURCES) \ + $(bcmxcp_usb_SOURCES) $(belkin_SOURCES) $(belkinunv_SOURCES) \ + $(bestfcom_SOURCES) bestfortress.c $(bestuferrups_SOURCES) \ + $(bestups_SOURCES) $(blazer_ser_SOURCES) $(blazer_usb_SOURCES) \ + $(clone_SOURCES) $(clone_outlet_SOURCES) $(dummy_ups_SOURCES) \ + $(etapro_SOURCES) $(everups_SOURCES) $(gamatronic_SOURCES) \ + $(genericups_SOURCES) $(hald_addon_bcmxcp_usb_SOURCES) \ $(hald_addon_blazer_usb_SOURCES) \ $(hald_addon_tripplite_usb_SOURCES) \ $(hald_addon_usbhid_ups_SOURCES) $(isbmex_SOURCES) \ $(ivtscd_SOURCES) $(liebert_SOURCES) $(liebert_esp2_SOURCES) \ $(masterguard_SOURCES) $(metasys_SOURCES) $(mge_shut_SOURCES) \ $(mge_utalk_SOURCES) $(microdowell_SOURCES) \ - $(netxml_ups_SOURCES) $(newmge_shut_SOURCES) $(oneac_SOURCES) \ + $(netxml_ups_SOURCES) $(newmge_shut_SOURCES) \ + $(am__nut_ipmipsu_SOURCES_DIST) $(oneac_SOURCES) \ $(optiups_SOURCES) $(powercom_SOURCES) $(powerman_pdu_SOURCES) \ $(powerpanel_SOURCES) $(rhino_SOURCES) $(richcomm_usb_SOURCES) \ $(safenet_SOURCES) $(skel_SOURCES) $(snmp_ups_SOURCES) \ @@ -457,10 +475,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -498,6 +520,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -562,6 +588,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -586,13 +614,14 @@ LDADD = $(LDADD_DRIVERS_SERIAL) # files. In any case, CFLAGS are only -I options, so there is no harm, # but only add them if we really use the target. AM_CFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2) \ - $(am__append_3) $(am__append_4) $(am__append_5) -SERIAL_DRIVERLIST = apcsmart bcmxcp belkin belkinunv bestfcom \ + $(am__append_3) $(am__append_4) $(am__append_5) \ + $(am__append_6) +SERIAL_DRIVERLIST = bcmxcp belkin belkinunv bestfcom \ bestfortress bestuferrups bestups dummy-ups etapro everups \ gamatronic genericups isbmex liebert liebert-esp2 masterguard metasys \ mge-shut mge-utalk microdowell newmge-shut oneac optiups powercom rhino \ safenet skel solis tripplite tripplitesu upscode2 victronups powerpanel \ - blazer_ser clone clone-outlet ivtscd + blazer_ser clone clone-outlet ivtscd apcsmart apcsmart-old SNMP_DRIVERLIST = snmp-ups USB_LIBUSB_DRIVERLIST = usbhid-ups bcmxcp_usb tripplite_usb \ @@ -613,7 +642,8 @@ upsdrvctl_SOURCES = upsdrvctl.c upsdrvctl_LDADD = $(LDADD_COMMON) # serial drivers: all of them use standard LDADD and CFLAGS -apcsmart_SOURCES = apcsmart.c +apcsmart_SOURCES = apcsmart.c apcsmart_tabs.c +apcsmart_old_SOURCES = apcsmart-old.c bcmxcp_SOURCES = bcmxcp.c bcmxcp_ser.c bcmxcp_LDADD = $(LDADD) -lm belkin_SOURCES = belkin.c @@ -659,9 +689,9 @@ victronups_SOURCES = victronups.c # dummy dummy_ups_SOURCES = dummy-ups.c dummy_ups_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/clients \ - $(am__append_11) + $(am__append_13) dummy_ups_LDADD = $(LDADD_DRIVERS) ../clients/libupsclient.la \ - $(am__append_12) + $(am__append_14) # Clone drivers clone_SOURCES = clone.c @@ -721,19 +751,24 @@ netxml_ups_LDADD = $(LDADD_DRIVERS) $(LIBNEON_LIBS) powerman_pdu_SOURCES = powerman-pdu.c powerman_pdu_LDADD = $(LDADD) $(LIBPOWERMAN_LIBS) +# IPMI PSU +nut_ipmipsu_SOURCES = nut-ipmipsu.c $(am__append_15) +nut_ipmipsu_LDADD = $(LDADD) $(LIBIPMI_LIBS) + # ---------------------------------------------------------------------- # List of header files. The purpose of this list is not dependency # tracking (which is automatic), but to ensure these files are # distributed by "make dist". -dist_noinst_HEADERS = apc-mib.h apc-hid.h apcsmart.h baytech-mib.h bcmxcp.h \ +dist_noinst_HEADERS = apc-mib.h apc-hid.h baytech-mib.h bcmxcp.h \ bcmxcp_io.h belkin.h belkin-hid.h bestpower-mib.h blazer.h cps-hid.h dstate.h \ dstate-hal.h dummy-ups.h eaton-mib.h explore-hid.h gamatronic.h genericups.h \ hidparser.h hidtypes.h ietf-mib.h libhid.h libshut.h libusb.h liebert-hid.h \ main.h main-hal.h mge-hid.h mge-mib.h mge-shut.h mge-utalk.h \ - mge-xml.h microdowell.h netvision-mib.h netxml-ups.h oneac.h \ + mge-xml.h microdowell.h netvision-mib.h netxml-ups.h nut-ipmi.h oneac.h \ powercom.h powerpanel.h powerp-bin.h powerp-txt.h powerware-mib.h raritan-pdu-mib.h \ safenet.h serial.h snmp-ups.h solis.h tripplite.h tripplite-hid.h \ - upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h + upshandler.h usb-common.h usbhid-ups.h powercom-hid.h compaq-mib.h idowell-hid.h \ + apcsmart.h apcsmart_tabs.h apcsmart-old.h # Define a dummy library so that Automake builds rules for the @@ -879,6 +914,9 @@ clean-halexecPROGRAMS: apcsmart$(EXEEXT): $(apcsmart_OBJECTS) $(apcsmart_DEPENDENCIES) @rm -f apcsmart$(EXEEXT) $(LINK) $(apcsmart_OBJECTS) $(apcsmart_LDADD) $(LIBS) +apcsmart-old$(EXEEXT): $(apcsmart_old_OBJECTS) $(apcsmart_old_DEPENDENCIES) + @rm -f apcsmart-old$(EXEEXT) + $(LINK) $(apcsmart_old_OBJECTS) $(apcsmart_old_LDADD) $(LIBS) bcmxcp$(EXEEXT): $(bcmxcp_OBJECTS) $(bcmxcp_DEPENDENCIES) @rm -f bcmxcp$(EXEEXT) $(LINK) $(bcmxcp_OBJECTS) $(bcmxcp_LDADD) $(LIBS) @@ -975,6 +1013,9 @@ netxml-ups$(EXEEXT): $(netxml_ups_OBJECTS) $(netxml_ups_DEPENDENCIES) newmge-shut$(EXEEXT): $(newmge_shut_OBJECTS) $(newmge_shut_DEPENDENCIES) @rm -f newmge-shut$(EXEEXT) $(newmge_shut_LINK) $(newmge_shut_OBJECTS) $(newmge_shut_LDADD) $(LIBS) +nut-ipmipsu$(EXEEXT): $(nut_ipmipsu_OBJECTS) $(nut_ipmipsu_DEPENDENCIES) + @rm -f nut-ipmipsu$(EXEEXT) + $(LINK) $(nut_ipmipsu_OBJECTS) $(nut_ipmipsu_LDADD) $(LIBS) oneac$(EXEEXT): $(oneac_OBJECTS) $(oneac_DEPENDENCIES) @rm -f oneac$(EXEEXT) $(LINK) $(oneac_OBJECTS) $(oneac_LDADD) $(LIBS) @@ -1038,7 +1079,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apc-hid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apc-mib.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apcsmart-old.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apcsmart.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apcsmart_tabs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/baytech-mib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcmxcp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bcmxcp_ser.Po@am__quote@ @@ -1094,6 +1137,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newmge_shut-libshut.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newmge_shut-mge-hid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newmge_shut-usbhid-ups.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nut-ipmipsu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nut-libfreeipmi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oneac.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/optiups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/powercom-hid.Po@am__quote@ diff --git a/drivers/apc-mib.c b/drivers/apc-mib.c index c934685..6b44fd6 100644 --- a/drivers/apc-mib.c +++ b/drivers/apc-mib.c @@ -27,6 +27,17 @@ #define APCC_MIB_VERSION "1.1" +/* Other APC sysOID: + * + * examples found on the Net and other sources: + * 'enterprises.apc.products.system.smartUPS.smartUPS700' + * '.1.3.6.1.4.1.318.1.3.4.5': ApcRPDU, + * '.1.3.6.1.4.1.318.1.3.4.4': ApcMSP + */ + +/* TODO: find the right sysOID for this MIB + * Ie ".1.3.6.1.4.1.318.1.1.1" or ".1.3.6.1.4.1.318" or? */ + /* info elements */ #define APCC_OID_BATT_STATUS ".1.3.6.1.4.1.318.1.1.1.2.1.1.0" diff --git a/drivers/apcsmart-old.c b/drivers/apcsmart-old.c new file mode 100644 index 0000000..5c06372 --- /dev/null +++ b/drivers/apcsmart-old.c @@ -0,0 +1,1501 @@ +/* + apcsmart.c - driver for APC smart protocol units (originally "newapc") + + Copyright (C) 1999 Russell Kroll + (C) 2000 Nigel Metheringham + + 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 +*/ + +#include "main.h" +#include "serial.h" +#include "apcsmart-old.h" + +#define DRIVER_NAME "APC Smart protocol driver" +#define DRIVER_VERSION "2.1" + +static upsdrv_info_t table_info = { + "APC command table", + APC_TABLE_VERSION, + NULL, + 0, + { NULL } +}; + +/* driver description structure */ +upsdrv_info_t upsdrv_info = { + DRIVER_NAME, + DRIVER_VERSION, + "Russell Kroll \n" + "Nigel Metheringham \n" + "Michal Soltys ", + DRV_STABLE, + { &table_info, NULL } +}; + +#define ALT_CABLE_1 "940-0095B" + + static int ups_status = 0, quirk_capability_overflow = 0; + +static apc_vartab_t *vartab_lookup_char(char cmdchar) +{ + int i; + + for (i = 0; apc_vartab[i].name != NULL; i++) + if (apc_vartab[i].cmd == cmdchar) + return &apc_vartab[i]; + + return NULL; +} + +static apc_vartab_t *vartab_lookup_name(const char *var) +{ + int i; + + for (i = 0; apc_vartab[i].name != NULL; i++) + if (!strcasecmp(apc_vartab[i].name, var)) + return &apc_vartab[i]; + + return NULL; +} + +/* FUTURE: change to use function pointers */ + +/* convert APC formatting to NUT formatting */ +static const char *convert_data(apc_vartab_t *cmd_entry, const char *upsval) +{ + static char tmp[128]; + int tval; + + switch(cmd_entry->flags & APC_FORMATMASK) { + case APC_F_PERCENT: + case APC_F_VOLT: + case APC_F_AMP: + case APC_F_CELSIUS: + case APC_F_HEX: + case APC_F_DEC: + case APC_F_SECONDS: + case APC_F_LEAVE: + + /* no conversion for any of these */ + return upsval; + + case APC_F_HOURS: + /* convert to seconds */ + + tval = 60 * 60 * strtol(upsval, NULL, 10); + + snprintf(tmp, sizeof(tmp), "%d", tval); + return tmp; + + case APC_F_MINUTES: + /* Convert to seconds - NUT standard time measurement */ + tval = 60 * strtol(upsval, NULL, 10); + /* Ignore errors - Theres not much we can do */ + snprintf(tmp, sizeof(tmp), "%d", tval); + return tmp; + + case APC_F_REASON: + switch (upsval[0]) { + case 'R': return "unacceptable utility voltage rate of change"; + case 'H': return "high utility voltage"; + case 'L': return "low utility voltage"; + case 'T': return "line voltage notch or spike"; + case 'O': return "no transfers yet since turnon"; + case 'S': return "simulated power failure or UPS test"; + default: return upsval; + } + } + + upslogx(LOG_NOTICE, "Unable to handle conversion of %s", cmd_entry->name); + return upsval; +} + +static void ups_status_set(void) +{ + status_init(); + if (ups_status & APC_STAT_CAL) + status_set("CAL"); /* calibration */ + if (ups_status & APC_STAT_TRIM) + status_set("TRIM"); /* SmartTrim */ + if (ups_status & APC_STAT_BOOST) + status_set("BOOST"); /* SmartBoost */ + if (ups_status & APC_STAT_OL) + status_set("OL"); /* on line */ + if (ups_status & APC_STAT_OB) + status_set("OB"); /* on battery */ + if (ups_status & APC_STAT_OVER) + status_set("OVER"); /* overload */ + if (ups_status & APC_STAT_LB) + status_set("LB"); /* low battery */ + if (ups_status & APC_STAT_RB) + status_set("RB"); /* replace batt */ + + if (ups_status == 0) + status_set("OFF"); + + status_commit(); +} + +static void alert_handler(char ch) +{ + switch (ch) { + case '!': /* clear OL, set OB */ + upsdebugx(4, "alert_handler: OB"); + ups_status &= ~APC_STAT_OL; + ups_status |= APC_STAT_OB; + break; + + case '$': /* clear OB, set OL */ + upsdebugx(4, "alert_handler: OL"); + ups_status &= ~APC_STAT_OB; + ups_status |= APC_STAT_OL; + break; + + case '%': /* set LB */ + upsdebugx(4, "alert_handler: LB"); + ups_status |= APC_STAT_LB; + break; + + case '+': /* clear LB */ + upsdebugx(4, "alert_handler: not LB"); + ups_status &= ~APC_STAT_LB; + break; + + case '#': /* set RB */ + upsdebugx(4, "alert_handler: RB"); + ups_status |= APC_STAT_RB; + break; + + case '?': /* set OVER */ + upsdebugx(4, "alert_handler: OVER"); + ups_status |= APC_STAT_OVER; + break; + + case '=': /* clear OVER */ + upsdebugx(4, "alert_handler: not OVER"); + ups_status &= ~APC_STAT_OVER; + break; + + default: + upsdebugx(4, "alert_handler got 0x%02x (unhandled)", ch); + break; + } + + ups_status_set(); +} + +static int read_buf(char *buf, size_t buflen) +{ + int ret; + + ret = ser_get_line_alert(upsfd, buf, buflen, ENDCHAR, POLL_IGNORE, + POLL_ALERT, alert_handler, SER_WAIT_SEC, SER_WAIT_USEC); + + if (ret < 1) { + ser_comm_fail("%s", ret ? strerror(errno) : "timeout"); + return ret; + } + + ser_comm_good(); + return ret; +} + +static int poll_data(apc_vartab_t *vt) +{ + int ret; + char tmp[SMALLBUF]; + + if ((vt->flags & APC_PRESENT) == 0) + return 1; + + upsdebugx(4, "poll_data: %s", vt->name); + + ret = ser_send_char(upsfd, vt->cmd); + + if (ret != 1) { + upslogx(LOG_ERR, "poll_data: ser_send_char failed"); + dstate_datastale(); + return 0; + } + + if (read_buf(tmp, sizeof(tmp)) < 1) { + dstate_datastale(); + return 0; + } + + /* no longer supported by the hardware somehow */ + if (!strcmp(tmp, "NA")) { + dstate_delinfo(vt->name); + return 1; + } + + dstate_setinfo(vt->name, "%s", convert_data(vt, tmp)); + dstate_dataok(); + + return 1; +} + +/* check for support or just update a named variable */ +static int query_ups(const char *var, int first) +{ + int ret; + char temp[256]; + const char *ptr; + apc_vartab_t *vt; + + vt = vartab_lookup_name(var); + + if (!vt) { + upsdebugx(1, "query_ups: unknown variable %s", var); + return 0; + } + + /* + * not first run and already known to not be supported ? + */ + if (!first && !(vt->flags & APC_PRESENT)) + return 0; + + /* empty the input buffer (while allowing the alert handler to run) */ + ret = ser_get_line_alert(upsfd, temp, sizeof(temp), ENDCHAR, + POLL_IGNORE, POLL_ALERT, alert_handler, 0, 0); + + ret = ser_send_char(upsfd, vt->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "query_ups: ser_send_char failed"); + return 0; + } + + ret = ser_get_line_alert(upsfd, temp, sizeof(temp), ENDCHAR, + POLL_IGNORE, POLL_ALERT, alert_handler, SER_WAIT_SEC, + SER_WAIT_USEC); + + if ((ret < 1) && (first == 0)) { + ser_comm_fail("%s", ret ? strerror(errno) : "timeout"); + return 0; + } + + ser_comm_good(); + + if ((ret < 1) || (!strcmp(temp, "NA"))) /* not supported */ + return 0; + + vt->flags |= APC_PRESENT; + ptr = convert_data(vt, temp); + dstate_setinfo(vt->name, "%s", ptr); + + return 1; /* success */ +} + +static void do_capabilities(void) +{ + const char *ptr, *entptr; + char upsloc, temp[512], cmd, loc, etmp[16], *endtemp; + int nument, entlen, i, matrix, ret, valid; + apc_vartab_t *vt; + + upsdebugx(1, "APC - About to get capabilities string"); + /* If we can do caps, then we need the Firmware revision which has + the locale descriptor as the last character (ugh) + */ + ptr = dstate_getinfo("ups.firmware"); + if (ptr) + upsloc = ptr[strlen(ptr) - 1]; + else + upsloc = 0; + + /* get capability string */ + ret = ser_send_char(upsfd, APC_CAPABILITY); /* ^Z */ + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_capabilities: ser_send_char failed"); + return; + } + + /* note different IGN set since ^Z returns things like # */ + ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, + MINIGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + + if ((ret < 1) || (!strcmp(temp, "NA"))) { + + /* Early Smart-UPS, not as smart as later ones */ + /* This should never happen since we only call + this if the REQ_CAPABILITIES command is supported + */ + upslogx(LOG_ERR, "ERROR: APC cannot do capabilities but said it could!"); + return; + } + + /* recv always puts a \0 at the end, so this is safe */ + /* however it assumes a zero byte cannot be embedded */ + endtemp = &temp[0] + strlen(temp); + + if (temp[0] != '#') { + upsdebugx(1, "Unrecognized capability start char %c", temp[0]); + upsdebugx(1, "Please report this error [%s]", temp); + upslogx(LOG_ERR, "ERROR: unknown capability start char %c!", + temp[0]); + + return; + } + + if (temp[1] == '#') { /* Matrix-UPS */ + matrix = 1; + ptr = &temp[0]; + } + else { + ptr = &temp[1]; + matrix = 0; + } + + /* command char, location, # of entries, entry length */ + + while (ptr[0] != '\0') { + if (matrix) + ptr += 2; /* jump over repeating ## */ + + /* check for idiocy */ + if (ptr >= endtemp) { + + /* if we expected this, just ignore it */ + if (quirk_capability_overflow) + return; + + fatalx(EXIT_FAILURE, + "Capability string has overflowed\n" + "Please report this error\n" + "ERROR: capability overflow!" + ); + } + + cmd = ptr[0]; + loc = ptr[1]; + nument = ptr[2] - 48; + entlen = ptr[3] - 48; + entptr = &ptr[4]; + + vt = vartab_lookup_char(cmd); + valid = vt && ((loc == upsloc) || (loc == '4')); + + /* mark this as writable */ + if (valid) { + upsdebugx(1, "Supported capability: %02x (%c) - %s", + cmd, loc, vt->name); + + dstate_setflags(vt->name, ST_FLAG_RW); + + /* make sure setvar knows what this is */ + vt->flags |= APC_RW | APC_ENUM; + } + + for (i = 0; i < nument; i++) { + if (valid) { + snprintf(etmp, entlen + 1, "%s", entptr); + dstate_addenum(vt->name, "%s", convert_data(vt, etmp)); + } + + entptr += entlen; + } + + ptr = entptr; + } +} + +static int update_status(void) +{ + int ret; + char buf[SMALLBUF]; + + upsdebugx(4, "update_status"); + + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + + ret = ser_send_char(upsfd, APC_STATUS); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "update_status: ser_send_char failed"); + dstate_datastale(); + return 0; + } + + ret = read_buf(buf, sizeof(buf)); + + if ((ret < 1) || (!strcmp(buf, "NA"))) { + dstate_datastale(); + return 0; + } + + ups_status = strtol(buf, 0, 16) & 0xff; + ups_status_set(); + + dstate_dataok(); + + return 1; +} + +static void oldapcsetup(void) +{ + int ret = 0; + + /* really old models ignore REQ_MODEL, so find them first */ + ret = query_ups("ups.model", 1); + + if (ret != 1) { + /* force the model name */ + dstate_setinfo("ups.model", "Smart-UPS"); + } + + /* see if this might be an old Matrix-UPS instead */ + if (query_ups("output.current", 1)) + dstate_setinfo("ups.model", "Matrix-UPS"); + + query_ups("ups.serial", 1); + query_ups("input.voltage", 1); /* This one may fail... no problem */ + + update_status(); + + /* If we have come down this path then we dont do capabilities and + other shiny features + */ +} + +static void protocol_verify(unsigned char cmd) +{ + int i, found; + + /* see if it's a variable */ + for (i = 0; apc_vartab[i].name != NULL; i++) { + + /* 1:1 here, so the first match is the only match */ + + if (apc_vartab[i].cmd == cmd) { + upsdebugx(3, "UPS supports variable [%s]", + apc_vartab[i].name); + + /* load initial data */ + apc_vartab[i].flags |= APC_PRESENT; + poll_data(&apc_vartab[i]); + + /* handle special data for our two strings */ + if (apc_vartab[i].flags & APC_STRING) { + dstate_setflags(apc_vartab[i].name, + ST_FLAG_RW | ST_FLAG_STRING); + dstate_setaux(apc_vartab[i].name, APC_STRLEN); + + apc_vartab[i].flags |= APC_RW; + } + + return; + } + } + + /* check the command list */ + + /* some cmdchars map onto multiple commands (start and stop) */ + + found = 0; + + for (i = 0; apc_cmdtab[i].name != NULL; i++) { + if (apc_cmdtab[i].cmd == cmd) { + upsdebugx(2, "UPS supports command [%s]", + apc_cmdtab[i].name); + + dstate_addcmd(apc_cmdtab[i].name); + + apc_cmdtab[i].flags |= APC_PRESENT; + found = 1; + } + } + + if (found) + return; + + if (isprint(cmd)) + upsdebugx(1, "protocol_verify: 0x%02x [%c] unrecognized", + cmd, cmd); + else + upsdebugx(1, "protocol_verify: 0x%02x unrecognized", cmd); +} + +/* some hardware is a special case - hotwire the list of cmdchars */ +static int firmware_table_lookup(void) +{ + int ret; + unsigned int i, j; + char buf[SMALLBUF]; + + upsdebugx(1, "Attempting firmware lookup using command 'V'"); + + ret = ser_send_char(upsfd, 'V'); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_send_char failed"); + return 0; + } + + ret = ser_get_line(upsfd, buf, sizeof(buf), ENDCHAR, IGNCHARS, + SER_WAIT_SEC, SER_WAIT_USEC); + + /* + * Some UPSes support both 'V' and 'b'. As 'b' doesn't always return + * firmware version, we attempt that only if 'V' doesn't work. + */ + if ((ret < 1) || (!strcmp(buf, "NA"))) { + upsdebugx(1, "Attempting firmware lookup using command 'b'"); + ret = ser_send_char(upsfd, 'b'); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_send_char failed"); + return 0; + } + + ret = ser_get_line(upsfd, buf, sizeof(buf), ENDCHAR, IGNCHARS, + SER_WAIT_SEC, SER_WAIT_USEC); + + if (ret < 1) { + upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_get_line failed"); + return 0; + } + } + + upsdebugx(2, "Firmware: [%s]", buf); + + /* this will be reworked if we get a lot of these things */ + if (!strcmp(buf, "451.2.I")) { + quirk_capability_overflow = 1; + return 0; + } + + for (i = 0; compat_tab[i].firmware != NULL; i++) { + if (!strcmp(compat_tab[i].firmware, buf)) { + + upsdebugx(2, "Matched - cmdchars: %s", + compat_tab[i].cmdchars); + + if (strspn(compat_tab[i].firmware, "05")) { + dstate_setinfo("ups.model", "Matrix-UPS"); + } else { + dstate_setinfo("ups.model", "Smart-UPS"); + } + + /* matched - run the cmdchars from the table */ + for (j = 0; j < strlen(compat_tab[i].cmdchars); j++) + protocol_verify(compat_tab[i].cmdchars[j]); + + return 1; /* matched */ + } + } + + upsdebugx(2, "Not found in table - trying normal method"); + return 0; +} + +static void getbaseinfo(void) +{ + unsigned int i; + int ret = 0; + char *alrts, *cmds, temp[512]; + + /* + * try firmware lookup first; we could start with 'a', but older models + * sometimes return other things than a command set + */ + if (firmware_table_lookup() == 1) + return; + + upsdebugx(1, "APC - Attempting to find command set"); + /* Initially we ask the UPS what commands it takes + If this fails we are going to need an alternate + strategy - we can deal with that if it happens + */ + + ret = ser_send_char(upsfd, APC_CMDSET); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "getbaseinfo: ser_send_char failed"); + return; + } + + ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, IGNCHARS, + SER_WAIT_SEC, SER_WAIT_USEC); + + if ((ret < 1) || (!strcmp(temp, "NA"))) { + /* We have an old dumb UPS - go to specific code for old stuff */ + oldapcsetup(); + return; + } + + upsdebugx(1, "APC - Parsing out command set"); + /* We have the version.alert.cmdchars string + NB the alert chars are normally in IGNCHARS + so will have been pretty much edited out. + You will need to change the ser_get_line above if + you want to check those out too.... + */ + alrts = strchr(temp, '.'); + if (alrts == NULL) { + fatalx(EXIT_FAILURE, "Unable to split APC version string"); + } + *alrts++ = 0; + + cmds = strchr(alrts, '.'); + if (cmds == NULL) { + fatalx(EXIT_FAILURE, "Unable to find APC command string"); + } + *cmds++ = 0; + + for (i = 0; i < strlen(cmds); i++) + protocol_verify(cmds[i]); + + /* if capabilities are supported, add them here */ + if (strchr(cmds, APC_CAPABILITY)) + do_capabilities(); + + upsdebugx(1, "APC - UPS capabilities determined"); +} + +/* check for calibration status and either start or stop */ +static int do_cal(int start) +{ + char temp[256]; + int tval, ret; + + ret = ser_send_char(upsfd, APC_STATUS); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + ret = read_buf(temp, sizeof(temp)); + + /* if we can't check the current calibration status, bail out */ + if ((ret < 1) || (!strcmp(temp, "NA"))) + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + + tval = strtol(temp, 0, 16); + + if (tval & APC_STAT_CAL) { /* calibration currently happening */ + if (start == 1) { + /* requested start while calibration still running */ + upslogx(LOG_INFO, "Runtime calibration already in progress"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + /* stop requested */ + + upslogx(LOG_INFO, "Stopping runtime calibration"); + + ret = ser_send_char(upsfd, APC_CMD_CALTOGGLE); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + ret = read_buf(temp, sizeof(temp)); + + if ((ret < 1) || (!strcmp(temp, "NA")) || (!strcmp(temp, "NO"))) { + upslogx(LOG_WARNING, "Stop calibration failed: %s", + temp); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + return STAT_INSTCMD_HANDLED; /* FUTURE: success */ + } + + /* calibration not happening */ + + if (start == 0) { /* stop requested */ + upslogx(LOG_INFO, "Runtime calibration not occurring"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + upslogx(LOG_INFO, "Starting runtime calibration"); + + ret = ser_send_char(upsfd, APC_CMD_CALTOGGLE); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + ret = read_buf(temp, sizeof(temp)); + + if ((ret < 1) || (!strcmp(temp, "NA")) || (!strcmp(temp, "NO"))) { + upslogx(LOG_WARNING, "Start calibration failed: %s", temp); + return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ + } + + return STAT_INSTCMD_HANDLED; /* FUTURE: success */ +} + +/* get the UPS talking to us in smart mode */ +static int smartmode(void) +{ + int ret, tries; + char temp[256]; + + for (tries = 0; tries < 5; tries++) { + + ret = ser_send_char(upsfd, APC_GOSMART); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "smartmode: ser_send_char failed"); + return 0; + } + + ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, + IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + + if (ret > 0) + if (!strcmp(temp, "SM")) + return 1; /* success */ + + sleep(1); /* wait before trying again */ + + /* it failed, so try to bail out of menus on newer units */ + + ret = ser_send_char(upsfd, 27); /* ESC */ + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "smartmode: ser_send_char failed"); + return 0; + } + + /* eat the response (might be NA, might be something else) */ + ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, + IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + } + + return 0; /* failure */ +} + +/* + * all shutdown commands should respond with 'OK' or '*' + */ +static int sdok(void) +{ + char temp[16]; + + ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + upsdebugx(4, "sdok: got \"%s\"", temp); + + if (!strcmp(temp, "*") || !strcmp(temp, "OK")) { + upsdebugx(4, "Last issued shutdown command succeeded"); + return 1; + } + + upsdebugx(1, "Last issued shutdown command failed"); + return 0; +} + +/* soft hibernate: S - working only when OB, otherwise ignored */ +static int sdcmd_S(int dummy) +{ + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + + upsdebugx(1, "Issuing soft hibernate"); + ser_send_char(upsfd, APC_CMD_SOFTDOWN); + + return sdok(); +} + +/* soft hibernate, hack version for CS 350 */ +static int sdcmd_CS(int tval) +{ + upsdebugx(1, "Using CS 350 'force OB' shutdown method"); + if (tval & APC_STAT_OL) { + upsdebugx(1, "On-line - forcing OB temporarily"); + ser_send_char(upsfd, 'U'); + usleep(UPSDELAY); + } + return sdcmd_S(tval); +} + +/* + * hard hibernate: @nnn / @nn + * note: works differently for older and new models, see help function for + * detailed info + */ +static int sdcmd_ATn(int cnt) +{ + int n = 0, mmax, ret; + const char *strval; + char timer[4]; + + mmax = cnt == 2 ? 99 : 999; + + if ((strval = getval("wugrace"))) { + errno = 0; + n = strtol(strval, NULL, 10); + if (errno || n < 0 || n > mmax) + n = 0; + } + + snprintf(timer, sizeof(timer), "%.*d", cnt, n); + + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + upsdebugx(1, "Issuing hard hibernate with %d minutes additional wakeup delay", n*6); + + ser_send_char(upsfd, APC_CMD_GRACEDOWN); + usleep(CMDLONGDELAY); + ser_send_pace(upsfd, UPSDELAY, "%s", timer); + + ret = sdok(); + if (ret || cnt == 3) + return ret; + + /* + * "tricky" part - we tried @nn variation and it (unsurprisingly) + * failed; we have to abort the sequence with something bogus to have + * the clean state; newer upses will respond with 'NO', older will be + * silent (YMMV); + */ + ser_send_char(upsfd, APC_CMD_GRACEDOWN); + usleep(UPSDELAY); + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + + return 0; +} + +/* shutdown: K - delayed poweroff */ +static int sdcmd_K(int dummy) +{ + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + upsdebugx(1, "Issuing delayed poweroff"); + + ser_send_char(upsfd, APC_CMD_SHUTDOWN); + usleep(CMDLONGDELAY); + ser_send_char(upsfd, APC_CMD_SHUTDOWN); + + return sdok(); +} + +/* shutdown: Z - immediate poweroff */ +static int sdcmd_Z(int dummy) +{ + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + upsdebugx(1, "Issuing immediate poweroff"); + + ser_send_char(upsfd, APC_CMD_OFF); + usleep(CMDLONGDELAY); + ser_send_char(upsfd, APC_CMD_OFF); + + return sdok(); +} + +static int (*sdlist[])(int) = { + sdcmd_S, + sdcmd_ATn, /* for @nnn version */ + sdcmd_K, + sdcmd_Z, + sdcmd_CS, + sdcmd_ATn, /* for @nn version */ +}; + +#define SDIDX_S 0 +#define SDIDX_AT3N 1 +#define SDIDX_K 2 +#define SDIDX_Z 3 +#define SDIDX_CS 4 +#define SDIDX_AT2N 5 + +#define SDCNT 6 + +static void upsdrv_shutdown_simple(int status) +{ + unsigned int sdtype = 0; + char *strval; + + if ((strval = getval("sdtype"))) { + errno = 0; + sdtype = strtol(strval, NULL, 10); + if (errno || sdtype < 0 || sdtype > 6) + sdtype = 0; + } + + switch (sdtype) { + + case 6: /* hard hibernate */ + sdcmd_ATn(3); + break; + case 5: /* "hack nn" hard hibernate */ + sdcmd_ATn(2); + break; + case 4: /* special hack for CS 350 and similar models */ + sdcmd_CS(status); + break; + + case 3: /* delayed poweroff */ + sdcmd_K(0); + break; + + case 2: /* instant poweroff */ + sdcmd_Z(0); + break; + case 1: + /* + * Send a combined set of shutdown commands which can work + * better if the UPS gets power during shutdown process + * Specifically it sends both the soft shutdown 'S' and the + * hard hibernate '@nnn' commands + */ + upsdebugx(1, "UPS - currently %s - sending soft/hard hibernate commands", + (status & APC_STAT_OL) ? "on-line" : "on battery"); + + /* S works only when OB */ + if ((status & APC_STAT_OB) && sdcmd_S(0)) + break; + sdcmd_ATn(3); + break; + + default: + /* + * Send @nnn or S, depending on OB / OL status + */ + if (status & APC_STAT_OL) /* on line */ + sdcmd_ATn(3); + else + sdcmd_S(0); + } +} + +static void upsdrv_shutdown_advanced(int status) +{ + const char *strval; + const char deforder[] = {48 + SDIDX_S, + 48 + SDIDX_AT3N, + 48 + SDIDX_K, + 48 + SDIDX_Z, + 0}; + size_t i; + int n; + + strval = getval("advorder"); + + /* sanitize advorder */ + + if (!strval || !strlen(strval) || strlen(strval) > SDCNT) + strval = deforder; + for (i = 0; i < strlen(strval); i++) { + if (strval[i] - 48 < 0 || strval[i] - 48 >= SDCNT) { + strval = deforder; + break; + } + } + + /* + * try each method in the list with a little bit of handling in certain + * cases + */ + + for (i = 0; i < strlen(strval); i++) { + switch (strval[i] - 48) { + case SDIDX_CS: + n = status; + break; + case SDIDX_AT3N: + n = 3; + break; + case SDIDX_AT2N: + default: + n = 2; + } + + if (sdlist[strval[i] - 48](n)) + break; /* finish if command succeeded */ + } +} + +/* power down the attached load immediately */ +void upsdrv_shutdown(void) +{ + char temp[32]; + int ret, status; + + if (!smartmode()) + upsdebugx(1, "SM detection failed. Trying a shutdown command anyway"); + + /* check the line status */ + + ret = ser_send_char(upsfd, APC_STATUS); + + if (ret == 1) { + ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, + IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + + if (ret < 1) { + upsdebugx(1, "Status read failed ! Assuming on battery state"); + status = APC_STAT_LB | APC_STAT_OB; + } else { + status = strtol(temp, 0, 16); + } + + } else { + upsdebugx(1, "Status request failed; assuming on battery state"); + status = APC_STAT_LB | APC_STAT_OB; + } + + if (testvar("advorder") && strcasecmp(getval("advorder"), "no")) + upsdrv_shutdown_advanced(status); + else + upsdrv_shutdown_simple(status); +} + +/* 940-0095B support: set DTR, lower RTS */ +static void init_serial_0095B(void) +{ + ser_set_dtr(upsfd, 1); + ser_set_rts(upsfd, 0); +} + +static void update_info_normal(void) +{ + int i; + + upsdebugx(3, "update_info_normal: starting"); + + for (i = 0; apc_vartab[i].name != NULL; i++) { + if ((apc_vartab[i].flags & APC_POLL) == 0) + continue; + + if (!poll_data(&apc_vartab[i])) { + upsdebugx(3, "update_info_normal: poll_data (%s) failed - " + "aborting scan", apc_vartab[i].name); + return; + } + } + + upsdebugx(3, "update_info_normal: done"); +} + +static void update_info_all(void) +{ + int i; + + upsdebugx(3, "update_info_all: starting"); + + for (i = 0; apc_vartab[i].name != NULL; i++) { + if (!poll_data(&apc_vartab[i])) { + upsdebugx(3, "update_info_all: poll_data (%s) failed - " + "aborting scan", apc_vartab[i].name); + return; + } + } + + upsdebugx(3, "update_info_all: done"); +} + +static int setvar_enum(apc_vartab_t *vt, const char *val) +{ + int i, ret; + char orig[256], temp[256]; + const char *ptr; + + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + ret = ser_send_char(upsfd, vt->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + ret = read_buf(orig, sizeof(orig)); + + if ((ret < 1) || (!strcmp(orig, "NA"))) + return STAT_SET_HANDLED; /* FUTURE: failed */ + + ptr = convert_data(vt, orig); + + /* suppress redundant changes - easier on the eeprom */ + if (!strcmp(ptr, val)) { + upslogx(LOG_INFO, "Ignoring enum SET %s='%s' (unchanged value)", + vt->name, val); + + return STAT_SET_HANDLED; /* FUTURE: no change */ + } + + for (i = 0; i < 6; i++) { + ret = ser_send_char(upsfd, APC_NEXTVAL); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + /* this should return either OK (if rotated) or NO (if not) */ + ret = read_buf(temp, sizeof(temp)); + + if ((ret < 1) || (!strcmp(temp, "NA"))) + return STAT_SET_HANDLED; /* FUTURE: failed */ + + /* sanity checks */ + if (!strcmp(temp, "NO")) + return STAT_SET_HANDLED; /* FUTURE: failed */ + if (strcmp(temp, "OK") != 0) + return STAT_SET_HANDLED; /* FUTURE: failed */ + + /* see what it rotated onto */ + ret = ser_send_char(upsfd, vt->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + ret = read_buf(temp, sizeof(temp)); + + if ((ret < 1) || (!strcmp(temp, "NA"))) + return STAT_SET_HANDLED; /* FUTURE: failed */ + + ptr = convert_data(vt, temp); + + upsdebugx(1, "Rotate value: got [%s], want [%s]", + ptr, val); + + if (!strcmp(ptr, val)) { /* got it */ + upslogx(LOG_INFO, "SET %s='%s'", vt->name, val); + + /* refresh data from the hardware */ + query_ups(vt->name, 0); + + return STAT_SET_HANDLED; /* FUTURE: success */ + } + + /* check for wraparound */ + if (!strcmp(ptr, orig)) { + upslogx(LOG_ERR, "setvar: variable %s wrapped", + vt->name); + + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + } + + upslogx(LOG_ERR, "setvar: gave up after 6 tries for %s", + vt->name); + + /* refresh data from the hardware */ + query_ups(vt->name, 0); + + return STAT_SET_HANDLED; +} + +static int setvar_string(apc_vartab_t *vt, const char *val) +{ + unsigned int i; + int ret; + char temp[256]; + + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + ret = ser_send_char(upsfd, vt->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + ret = read_buf(temp, sizeof(temp)); + + if ((ret < 1) || (!strcmp(temp, "NA"))) + return STAT_SET_HANDLED; /* FUTURE: failed */ + + /* suppress redundant changes - easier on the eeprom */ + if (!strcmp(temp, val)) { + upslogx(LOG_INFO, "Ignoring string SET %s='%s' (unchanged value)", + vt->name, val); + + return STAT_SET_HANDLED; /* FUTURE: no change */ + } + + ret = ser_send_char(upsfd, APC_NEXTVAL); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + usleep(UPSDELAY); + + for (i = 0; i < strlen(val); i++) { + ret = ser_send_char(upsfd, val[i]); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + usleep(UPSDELAY); + } + + /* pad to 8 chars with CRs */ + for (i = strlen(val); i < APC_STRLEN; i++) { + ret = ser_send_char(upsfd, 13); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + usleep(UPSDELAY); + } + + ret = read_buf(temp, sizeof(temp)); + + if (ret < 1) { + upslogx(LOG_ERR, "setvar_string: short final read"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + if (!strcmp(temp, "NO")) { + upslogx(LOG_ERR, "setvar_string: got NO at final read"); + return STAT_SET_HANDLED; /* FUTURE: failed */ + } + + /* refresh data from the hardware */ + query_ups(vt->name, 0); + + upslogx(LOG_INFO, "SET %s='%s'", vt->name, val); + + return STAT_SET_HANDLED; /* FUTURE: failed */ +} + +static int setvar(const char *varname, const char *val) +{ + apc_vartab_t *vt; + + vt = vartab_lookup_name(varname); + + if (!vt) + return STAT_SET_UNKNOWN; + + if ((vt->flags & APC_RW) == 0) { + upslogx(LOG_WARNING, "setvar: [%s] is not writable", varname); + return STAT_SET_UNKNOWN; + } + + if (vt->flags & APC_ENUM) + return setvar_enum(vt, val); + + if (vt->flags & APC_STRING) + return setvar_string(vt, val); + + upslogx(LOG_WARNING, "setvar: Unknown type for [%s]", varname); + return STAT_SET_UNKNOWN; +} + +/* actually send the instcmd's char to the ups */ +static int do_cmd(apc_cmdtab_t *ct) +{ + int ret; + char buf[SMALLBUF]; + + ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + ret = ser_send_char(upsfd, ct->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + } + + /* some commands have to be sent twice with a 1.5s gap */ + if (ct->flags & APC_REPEAT) { + usleep(CMDLONGDELAY); + + ret = ser_send_char(upsfd, ct->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); + return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + } + } + + ret = read_buf(buf, sizeof(buf)); + + if (ret < 1) + return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + + if (strcmp(buf, "OK") != 0) { + upslogx(LOG_WARNING, "Got [%s] after command [%s]", + buf, ct->name); + + return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + } + + upslogx(LOG_INFO, "Command: %s", ct->name); + return STAT_INSTCMD_HANDLED; /* FUTURE: success */ +} + +/* some commands must be repeated in a window to execute */ +static int instcmd_chktime(apc_cmdtab_t *ct) +{ + double elapsed; + time_t now; + static time_t last = 0; + + time(&now); + + elapsed = difftime(now, last); + last = now; + + /* you have to hit this in a small window or it fails */ + if ((elapsed < MINCMDTIME) || (elapsed > MAXCMDTIME)) { + upsdebugx(1, "instcmd_chktime: outside window for %s (%2.0f)", + ct->name, elapsed); + return STAT_INSTCMD_HANDLED; /* FUTURE: again */ + } + + return do_cmd(ct); +} + +static int instcmd(const char *cmdname, const char *extra) +{ + int i; + apc_cmdtab_t *ct; + + ct = NULL; + + for (i = 0; apc_cmdtab[i].name != NULL; i++) + if (!strcasecmp(apc_cmdtab[i].name, cmdname)) + ct = &apc_cmdtab[i]; + + if (!ct) { + upslogx(LOG_WARNING, "instcmd: unknown command [%s]", cmdname); + return STAT_INSTCMD_UNKNOWN; + } + + if ((ct->flags & APC_PRESENT) == 0) { + upslogx(LOG_WARNING, "instcmd: command [%s] is not supported", + cmdname); + return STAT_INSTCMD_UNKNOWN; + } + + if (!strcasecmp(cmdname, "calibrate.start")) + return do_cal(1); + + if (!strcasecmp(cmdname, "calibrate.stop")) + return do_cal(0); + + if (ct->flags & APC_NASTY) + return instcmd_chktime(ct); + + /* nothing special here */ + return do_cmd(ct); +} + +/* install pointers to functions for msg handlers called from msgparse */ +static void setuphandlers(void) +{ + upsh.setvar = setvar; + upsh.instcmd = instcmd; +} + +/* functions that interface with main.c */ + +void upsdrv_makevartable(void) +{ + addvar(VAR_VALUE, "cable", "Specify alternate cable (940-0095B)"); + addvar(VAR_VALUE, "wugrace", "Hard hibernate's wakeup grace"); + addvar(VAR_VALUE, "sdtype", "Specify simple shutdown method (0-6)"); + addvar(VAR_VALUE, "advorder", "Enable advanced shutdown control"); +} + +void upsdrv_initups(void) +{ + char *cable; + + upsfd = ser_open(device_path); + ser_set_speed(upsfd, device_path, B2400); + + cable = getval("cable"); + + if (cable && !strcasecmp(cable, ALT_CABLE_1)) + init_serial_0095B(); + + /* make sure we wake up if the UPS sends alert chars to us */ + extrafd = upsfd; +} + +void upsdrv_help(void) +{ +} + +void upsdrv_initinfo(void) +{ + const char *pmod, *pser; + + if (!smartmode()) { + fatalx(EXIT_FAILURE, + "Unable to detect an APC Smart protocol UPS on port %s\n" + "Check the cabling, port name or model name and try again", device_path + ); + } + + /* manufacturer ID - hardcoded in this particular module */ + dstate_setinfo("ups.mfr", "APC"); + + getbaseinfo(); + + if (!(pmod = dstate_getinfo("ups.model"))) + pmod = "\"unknown model\""; + if (!(pser = dstate_getinfo("ups.serial"))) + pser = "unknown serial"; + + upsdebugx(1, "Detected %s [%s] on %s", pmod, pser, device_path); + + setuphandlers(); +} + +void upsdrv_updateinfo(void) +{ + static time_t last_full = 0; + time_t now; + + /* try to wake up a dead ups once in awhile */ + if ((dstate_is_stale()) && (!smartmode())) { + ser_comm_fail("Communications with UPS lost - check cabling"); + + /* reset this so a full update runs when the UPS returns */ + last_full = 0; + return; + } + + ser_comm_good(); + + if (!update_status()) + return; + + time(&now); + + /* refresh all variables hourly */ + /* does not catch measure-ups II insertion/removal */ + if (difftime(now, last_full) > 3600) { + last_full = now; + update_info_all(); + return; + } + + update_info_normal(); +} + +void upsdrv_cleanup(void) +{ + /* try to bring the UPS out of smart mode */ + ser_send_char(upsfd, APC_GODUMB); + + ser_close(upsfd, device_path); +} diff --git a/drivers/apcsmart-old.h b/drivers/apcsmart-old.h new file mode 100644 index 0000000..f143cfa --- /dev/null +++ b/drivers/apcsmart-old.h @@ -0,0 +1,291 @@ +/* apcsmart.h - command table for APC smart protocol units + + Copyright (C) 1999 Russell Kroll + (C) 2000 Nigel Metheringham + + 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 +*/ + +#include +#include +#include "serial.h" +#include "timehead.h" + +#define APC_TABLE_VERSION "version 2.2" + +/* Basic UPS reply line structure */ +#define ENDCHAR 10 /* APC ends responses with LF */ + +/* characters ignored by default */ +#define IGNCHARS "\015+$|!~%?=#&" /* special characters to ignore */ + +/* these one is used only during startup, due to ^Z sending certain characters such as # */ +#define MINIGNCHARS "\015+$|!" /* minimum set of special characters to ignore */ + +/* normal polls: characters we don't want to parse (including a few alerts) */ +#define POLL_IGNORE "\015&|" + +/* alert characters we care about - OL, OB, LB, not LB, RB, OVER, not OVER */ +#define POLL_ALERT "$!%+#?=" + +#define UPSDELAY 50000 /* slow down multicharacter commands */ +#define CMDLONGDELAY 1500000 /* some commands need a 1.5s gap for safety */ + +#define SER_WAIT_SEC 3 /* wait up to 3.0 sec for ser_get calls */ +#define SER_WAIT_USEC 0 + +/* dangerous instant commands must be reconfirmed within a 12 second window */ +#define MINCMDTIME 3 +#define MAXCMDTIME 15 + +/* it only does two strings, and they're both the same length */ +#define APC_STRLEN 8 + +/* --------------- */ + +/* status bits */ + +#define APC_STAT_CAL 1 /* calibration */ +#define APC_STAT_TRIM 2 /* SmartTrim */ +#define APC_STAT_BOOST 4 /* SmartBoost */ +#define APC_STAT_OL 8 /* on line */ +#define APC_STAT_OB 16 /* on battery */ +#define APC_STAT_OVER 32 /* overload */ +#define APC_STAT_LB 64 /* low battery */ +#define APC_STAT_RB 128 /* replace battery */ + +/* serial protocol: special commands - initialization and such */ +#define APC_STATUS 'Q' +#define APC_GOSMART 'Y' +#define APC_GODUMB 'R' +#define APC_CMDSET 'a' +#define APC_CAPABILITY 26 /* ^Z */ +#define APC_NEXTVAL '-' + +/* --------------- */ + +/* Driver command table flag values */ + +#define APC_POLL 0x0001 /* Poll this variable regularly */ +#define APC_PRESENT 0x0004 /* Capability seen on this UPS */ + +#define APC_RW 0x0010 /* read-write variable */ +#define APC_ENUM 0x0020 /* enumerated type */ +#define APC_STRING 0x0040 /* string */ + +#define APC_NASTY 0x0100 /* Nasty command - take care */ +#define APC_REPEAT 0x0200 /* Command needs sending twice */ + +#define APC_FORMATMASK 0xFF0000 /* Mask for apc data formats */ + +#define APC_F_PERCENT 0x020000 /* Data in a percent format */ +#define APC_F_VOLT 0x030000 /* Data in a voltage format */ +#define APC_F_AMP 0x040000 /* Data in a current/amp format */ +#define APC_F_CELSIUS 0x050000 /* Data in a temp/C format */ +#define APC_F_HEX 0x060000 /* Data in a hex number format */ +#define APC_F_DEC 0x070000 /* Data in a decimal format */ +#define APC_F_SECONDS 0x100000 /* Time in seconds */ +#define APC_F_MINUTES 0x110000 /* Time in minutes */ +#define APC_F_HOURS 0x120000 /* Time in hours */ +#define APC_F_REASON 0x130000 /* Reason of transfer */ +#define APC_F_LEAVE 0 /* Just pass this through */ + +typedef struct { + const char *name; /* the variable name */ + unsigned int flags; /* various flags */ + char cmd; /* command character */ +} apc_vartab_t; + +apc_vartab_t apc_vartab[] = { + + { "ups.firmware.old", 0, 'V' }, + { "ups.firmware", 0, 'b' }, + { "ups.firmware.aux", 0, 'v' }, + { "ups.model", 0, 0x01 }, + + { "ups.serial", 0, 'n' }, + { "ups.mfr.date", 0, 'm' }, + + { "ups.temperature", APC_POLL|APC_F_CELSIUS, 'C' }, + { "ups.load", APC_POLL|APC_F_PERCENT, 'P' }, + + { "ups.test.interval", APC_F_HOURS, 'E' }, + { "ups.test.result", APC_POLL, 'X' }, + + { "ups.delay.start", APC_F_SECONDS, 'r' }, + { "ups.delay.shutdown", APC_F_SECONDS, 'p' }, + + { "ups.id", APC_STRING, 'c' }, + + { "ups.contacts", APC_POLL|APC_F_HEX, 'i' }, + { "ups.display.language", + 0, 0x0C }, + + { "input.voltage", APC_POLL|APC_F_VOLT, 'L' }, + { "input.frequency", APC_POLL|APC_F_DEC, 'F' }, + { "input.sensitivity", 0, 's' }, + { "input.quality", APC_POLL|APC_F_HEX, '9' }, + + { "input.transfer.low", APC_F_VOLT, 'l' }, + { "input.transfer.high", + APC_F_VOLT, 'u' }, + { "input.transfer.reason", + APC_POLL|APC_F_REASON, 'G' }, + + { "input.voltage.maximum", + APC_POLL|APC_F_VOLT, 'M' }, + { "input.voltage.minimum", + APC_POLL|APC_F_VOLT, 'N' }, + + { "output.current", APC_POLL|APC_F_AMP, '/' }, + { "output.voltage", APC_POLL|APC_F_VOLT, 'O' }, + { "output.voltage.nominal", + APC_F_VOLT, 'o' }, + + { "ambient.humidity", APC_POLL|APC_F_PERCENT, 'h' }, + { "ambient.humidity.high", + APC_F_PERCENT, '{' }, + { "ambient.humidity.low", + APC_F_PERCENT, '}' }, + + { "ambient.temperature", + APC_POLL|APC_F_CELSIUS, 't' }, + { "ambient.temperature.high", + APC_F_CELSIUS, '[' }, + { "ambient.temperature.low", + APC_F_CELSIUS, ']' }, + + { "battery.date", APC_STRING, 'x' }, + + { "battery.charge", APC_POLL|APC_F_PERCENT, 'f' }, + { "battery.charge.restart", + APC_F_PERCENT, 'e' }, + + { "battery.voltage", APC_POLL|APC_F_VOLT, 'B' }, + { "battery.voltage.nominal", + 0, 'g' }, + + { "battery.runtime", APC_POLL|APC_F_MINUTES, 'j' }, + { "battery.runtime.low", + APC_F_MINUTES, 'q' }, + + { "battery.packs", APC_F_DEC, '>' }, + { "battery.packs.bad", APC_F_DEC, '<' }, + { "battery.alarm.threshold", + 0, 'k' }, + /* todo: + + I = alarm enable (hex field) - split into alarm.n.enable + J = alarm status (hex field) - split into alarm.n.status + + 0x15 = output voltage selection (APC_F_VOLT) + 0x5C = load power (APC_POLL|APC_F_PERCENT) + + */ + + {NULL, 0, 0}, +}; + +/* ------ instant commands ------ */ + +#define APC_CMD_FPTEST 'A' +#define APC_CMD_CALTOGGLE 'D' +#define APC_CMD_SHUTDOWN 'K' +#define APC_CMD_SOFTDOWN 'S' +#define APC_CMD_GRACEDOWN '@' +#define APC_CMD_SIMPWF 'U' +#define APC_CMD_BTESTTOGGLE 'W' +#define APC_CMD_OFF 'Z' + +#define APC_CMD_ON 0x0E /* ^N */ +#define APC_CMD_BYPTOGGLE '^' + +typedef struct { + const char *name; + int flags; + char cmd; +} apc_cmdtab_t; + +apc_cmdtab_t apc_cmdtab[] = +{ + { "load.off", APC_NASTY|APC_REPEAT, APC_CMD_OFF }, + { "load.on", APC_REPEAT, APC_CMD_ON }, + + { "test.panel.start", 0, APC_CMD_FPTEST }, + + { "test.failure.start", 0, APC_CMD_SIMPWF }, + + { "test.battery.start", 0, APC_CMD_BTESTTOGGLE }, + { "test.battery.stop", 0, APC_CMD_BTESTTOGGLE }, + + { "shutdown.return.grace", + APC_NASTY, APC_CMD_GRACEDOWN }, + { "shutdown.return", APC_NASTY, APC_CMD_SOFTDOWN }, + { "shutdown.stayoff", APC_NASTY|APC_REPEAT, APC_CMD_SHUTDOWN }, + + { "calibrate.start", 0, APC_CMD_CALTOGGLE }, + { "calibrate.stop", 0, APC_CMD_CALTOGGLE }, + + { "bypass.start", 0, APC_CMD_BYPTOGGLE }, + { "bypass.stop", 0, APC_CMD_BYPTOGGLE }, + + { NULL, 0, 0 } +}; + +/* compatibility with hardware that doesn't do APC_CMDSET ('a') */ + +struct { + const char *firmware; + const char *cmdchars; + int flags; +} compat_tab[] = { + /* APC Matrix */ + { "0XI", "789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, + { "0XM", "789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, + { "0ZI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + { "5UI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + { "5ZM", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + /* APC600 */ + { "6QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* SmartUPS 900 */ + { "7QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* SmartUPS 900I */ + { "7II", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + /* SmartUPS 2000I */ + { "9II", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + { "9GI", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + /* SmartUPS 1250 */ + { "8QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* CS 350 */ + { "5.4.D", "\1ABPQRSUYbdfgjmnx9", 0 }, + /* Smart-UPS 600 */ + { "D9", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D8", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D7", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D6", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D5", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D4", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + + { NULL, NULL, 0 }, +}; diff --git a/drivers/apcsmart.c b/drivers/apcsmart.c index f30f625..4094eea 100644 --- a/drivers/apcsmart.c +++ b/drivers/apcsmart.c @@ -1,38 +1,36 @@ /* - apcsmart.c - driver for APC smart protocol units (originally "newapc") + * apcsmart.c - driver for APC smart protocol units (originally "newapc") + * + * Copyright (C) 1999 Russell Kroll + * (C) 2000 Nigel Metheringham + * (C) 2011 Michal Soltys + * + * 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 + */ - Copyright (C) 1999 Russell Kroll - (C) 2000 Nigel Metheringham - - 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 -*/ +#include +#include +#include +#include #include "main.h" #include "serial.h" +#include "timehead.h" + #include "apcsmart.h" - -#define DRIVER_NAME "APC Smart protocol driver" -#define DRIVER_VERSION "2.1" - -static upsdrv_info_t table_info = { - "APC command table", - APC_TABLE_VERSION, - NULL, - 0, - { NULL } -}; +#include "apcsmart_tabs.h" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -42,12 +40,33 @@ upsdrv_info_t upsdrv_info = { "Nigel Metheringham \n" "Michal Soltys ", DRV_STABLE, - { &table_info, NULL } + { &apc_tab_info, NULL } }; -#define ALT_CABLE_1 "940-0095B" +static int ups_status = 0; - static int ups_status = 0, quirk_capability_overflow = 0; +/* some forwards */ + +static int sdcmd_S(const void *); +static int sdcmd_AT(const void *); +static int sdcmd_K(const void *); +static int sdcmd_Z(const void *); +static int sdcmd_CS(const void *); + +static int (*sdlist[])(const void *) = { + sdcmd_S, + sdcmd_AT, + sdcmd_K, + sdcmd_Z, + sdcmd_CS, +}; + +#define SDIDX_S 0 +#define SDIDX_AT 1 +#define SDIDX_K 2 +#define SDIDX_Z 3 +#define SDIDX_CS 4 +#define SDCNT ((int)(sizeof(sdlist)/sizeof(sdlist[0]))) static apc_vartab_t *vartab_lookup_char(char cmdchar) { @@ -65,7 +84,8 @@ static apc_vartab_t *vartab_lookup_name(const char *var) int i; for (i = 0; apc_vartab[i].name != NULL; i++) - if (!strcasecmp(apc_vartab[i].name, var)) + if (!(apc_vartab[i].flags & APC_DEPR) && + !strcasecmp(apc_vartab[i].name, var)) return &apc_vartab[i]; return NULL; @@ -73,13 +93,33 @@ static apc_vartab_t *vartab_lookup_name(const char *var) /* FUTURE: change to use function pointers */ +static int rexhlp(const char *rex, const char *val) +{ + int ret; + regex_t mbuf; + + regcomp(&mbuf, rex, REG_EXTENDED|REG_NOSUB); + ret = regexec(&mbuf, val, 0,0,0); + regfree(&mbuf); + return ret; +} + /* convert APC formatting to NUT formatting */ +/* TODO: handle errors better */ static const char *convert_data(apc_vartab_t *cmd_entry, const char *upsval) { - static char tmp[128]; - int tval; + static char temp[APC_LBUF]; + int tval; - switch(cmd_entry->flags & APC_FORMATMASK) { + /* this should never happen */ + if (strlen(upsval) >= sizeof(temp)) { + upslogx(LOG_CRIT, "length of [%s] too long", cmd_entry->name); + strncpy(temp, upsval, sizeof(temp) - 1); + temp[sizeof(temp) - 1] = '\0'; + return temp; + } + + switch(cmd_entry->flags & APC_F_MASK) { case APC_F_PERCENT: case APC_F_VOLT: case APC_F_AMP: @@ -88,24 +128,24 @@ static const char *convert_data(apc_vartab_t *cmd_entry, const char *upsval) case APC_F_DEC: case APC_F_SECONDS: case APC_F_LEAVE: - /* no conversion for any of these */ - return upsval; + strcpy(temp, upsval); + return temp; case APC_F_HOURS: /* convert to seconds */ tval = 60 * 60 * strtol(upsval, NULL, 10); - snprintf(tmp, sizeof(tmp), "%d", tval); - return tmp; + snprintf(temp, sizeof(temp), "%d", tval); + return temp; case APC_F_MINUTES: /* Convert to seconds - NUT standard time measurement */ tval = 60 * strtol(upsval, NULL, 10); - /* Ignore errors - Theres not much we can do */ - snprintf(tmp, sizeof(tmp), "%d", tval); - return tmp; + /* Ignore errors - there's not much we can do */ + snprintf(temp, sizeof(temp), "%d", tval); + return temp; case APC_F_REASON: switch (upsval[0]) { @@ -115,12 +155,86 @@ static const char *convert_data(apc_vartab_t *cmd_entry, const char *upsval) case 'T': return "line voltage notch or spike"; case 'O': return "no transfers yet since turnon"; case 'S': return "simulated power failure or UPS test"; - default: return upsval; + default: + strcpy(temp, upsval); + return temp; } } - upslogx(LOG_NOTICE, "Unable to handle conversion of %s", cmd_entry->name); - return upsval; + upslogx(LOG_NOTICE, "Unable to handle conversion of [%s]", cmd_entry->name); + strcpy(temp, upsval); + return temp; +} + +static void apc_ser_set(void) +{ + struct termios tio, tio_chk; + char *cable; + + /* + * this must be called before the rest, as ser_set_speed() performs + * early initialization of the port, apart from changing speed + */ + ser_set_speed(upsfd, device_path, B2400); + + memset(&tio, 0, sizeof(tio)); + errno = 0; + + if (tcgetattr(upsfd, &tio)) + fatal_with_errno(EXIT_FAILURE, "tcgetattr(%s)", device_path); + + /* set port mode: common stuff, canonical processing */ + + tio.c_cflag |= (CS8 | CLOCAL | CREAD); + + tio.c_lflag |= ICANON; + tio.c_lflag &= ~ISIG; + + tio.c_iflag |= (IGNCR | IGNPAR); + tio.c_iflag &= ~(IXON | IXOFF); + + tio.c_oflag = 0; + + tio.c_cc[VEOL] = '*'; /* specially handled in apc_read() */ + +#ifdef _POSIX_VDISABLE + tio.c_cc[VERASE] = _POSIX_VDISABLE; + tio.c_cc[VKILL] = _POSIX_VDISABLE; + tio.c_cc[VEOF] = _POSIX_VDISABLE; + tio.c_cc[VEOL2] = _POSIX_VDISABLE; +#endif + +#if 0 + /* unused in canonical mode: */ + tio.c_cc[VMIN] = 1; + tio.c_cc[VTIME] = 0; +#endif + + if (tcflush(upsfd, TCIOFLUSH)) + fatal_with_errno(EXIT_FAILURE, "tcflush(%s)", device_path); + + /* + * warn: + * Note, that tcsetattr() returns success if /any/ of the requested + * changes could be successfully carried out. Thus the more complicated + * test. + */ + if (tcsetattr(upsfd, TCSANOW, &tio)) + fatal_with_errno(EXIT_FAILURE, "tcsetattr(%s)", device_path); + + memset(&tio_chk, 0, sizeof(tio_chk)); + if (tcgetattr(upsfd, &tio_chk)) + fatal_with_errno(EXIT_FAILURE, "tcgetattr(%s)", device_path); + if (memcmp(&tio_chk, &tio, sizeof(tio))) + fatalx(EXIT_FAILURE, "unable to set the required attributes (%s)", device_path); + + cable = getval("cable"); + if (cable && !strcasecmp(cable, ALT_CABLE_1)) { + if (ser_set_dtr(upsfd, 1) == -1) + fatalx(EXIT_FAILURE, "ser_set_dtr() failed (%s)", device_path); + if (ser_set_rts(upsfd, 0) == -1) + fatalx(EXIT_FAILURE, "ser_set_rts() failed (%s)", device_path); + } } static void ups_status_set(void) @@ -197,114 +311,461 @@ static void alert_handler(char ch) ups_status_set(); } -static int read_buf(char *buf, size_t buflen) +/* + * we need a tiny bit different processing due to '*' and canonical mode; the + * function is subtly different from generic ser_get_line_alert() + */ +static int apc_read(char *buf, size_t buflen, int flags) { - int ret; + const char *iset = IGN_CHARS, *aset = ""; + size_t count = 0; + int i, ret, sec = 3, usec = 0; + char temp[APC_LBUF]; - ret = ser_get_line_alert(upsfd, buf, buflen, ENDCHAR, POLL_IGNORE, - POLL_ALERT, alert_handler, SER_WAIT_SEC, SER_WAIT_USEC); + if (upsfd == -1) + return 0; + if (flags & SER_D0) { + sec = 0; usec = 0; + } + if (flags & SER_DX) { + sec = 0; usec = 200000; + } + if (flags & SER_D1) { + sec = 1; usec = 500000; + } + if (flags & SER_D3) { + sec = 3; usec = 0; + } + if (flags & SER_AA) { + iset = IGN_AACHARS; + aset = ALERT_CHARS; + } + if (flags & SER_CC) { + iset = IGN_CCCHARS; + aset = ""; + sec = 6; usec = 0; + } + if (flags & SER_CS) { + iset = IGN_CSCHARS; + aset = ""; + sec = 6; usec = 0; + } - if (ret < 1) { - ser_comm_fail("%s", ret ? strerror(errno) : "timeout"); - return ret; + memset(buf, '\0', buflen); + + while (count < buflen - 1) { + errno = 0; + ret = select_read(upsfd, temp, sizeof(temp), sec, usec); + + /* error or no timeout allowed */ + if (ret < 0 || (ret == 0 && !(flags & SER_TO))) { + ser_comm_fail("%s", ret ? strerror(errno) : "timeout"); + return ret; + } + /* ok, timeout is acceptable */ + if (ret == 0 && (flags & SER_TO)) { + /* + * but it doesn't imply ser_comm_good + * + * to be more precise - we might be in comm_fail + * condition, trying to "nudge" the UPS with some + * command obviously expecting timeout if the comm is + * still lost. This would result with filling logs with + * confusing comm lost/comm re-established pairs. Thus + * - just return here. + */ + return count; + } + + /* parse input */ + for (i = 0; i < ret; i++) { + /* standard "line received" condition */ + if ((count == buflen - 1) || (temp[i] == ENDCHAR)) { + ser_comm_good(); + return count; + } + /* + * '*' is set as a secondary EOL; convert to 'OK' only as a + * reply to shutdown command in sdok(); otherwise next + * select_read() will continue normally + */ + if ((flags & SER_HA) && temp[i] == '*') { + /* + * a bit paranoid, but remember '*' is not real EOL; + * there could be some firmware in existence, that + * would send both string: 'OK\n' and alert: '*'. + * Just in case, try to flush the input with small 1 sec. + * timeout + */ + memset(buf, '\0', buflen); + errno = 0; + ret = select_read(upsfd, temp, sizeof(temp), 1, 0); + if (ret < 0) { + ser_comm_fail("%s", strerror(errno)); + return ret; + } + buf[0] = 'O'; + buf[1] = 'K'; + ser_comm_good(); + return 2; + } + /* ignore set */ + if (strchr(iset, temp[i]) || temp[i] == '*') { + continue; + } + /* alert set */ + if (strchr(aset, temp[i])) { + alert_handler(temp[i]); + continue; + } + + buf[count++] = temp[i]; + } } ser_comm_good(); - return ret; + return count; +} +static int apc_write(unsigned char code) +{ + errno = 0; + if (upsfd == -1) + return 0; + return ser_send_char(upsfd, code); +} + +/* + * We have to watch out for NA, here; + * This is generally safe, as otherwise we will just timeout. The reason we do + * it, is that under certain conditions an ups might respond with NA for + * something it would normally handle (e.g. calling @ while being in powered + * off or hibernated state. If we keep sending the "arguments" after getting + * NA, they will be interpreted as commands, which is quite a bug :) + * Furthermore later flushes might not work properly, if the reply to those + * commands are generated with some delay. + * + * We also set errno to something usable, so outside upslog calls don't output + * confusing "success". + */ +static int apc_write_long(const char *code) +{ + char temp[APC_LBUF]; + int ret; + errno = 0; + + if (upsfd == -1) + return 0; + + ret = ser_send_char(upsfd, *code); + if (ret != 1) + return ret; + /* peek for the answer - anything at this point is failure */ + ret = apc_read(temp, sizeof(temp), SER_DX|SER_TO); + if (ret) { + errno = ECANCELED; + return -1; + } + + return ser_send_pace(upsfd, 50000, "%s", code + 1); +} + +static int apc_write_rep(unsigned char code) +{ + char temp[APC_LBUF]; + int ret; + errno = 0; + + if (upsfd == -1) + return 0; + + ret = ser_send_char(upsfd, code); + if (ret != 1) + return ret; + /* peek for the answer - anything at this point is failure */ + ret = apc_read(temp, sizeof(temp), SER_DX|SER_TO); + if (ret) { + errno = ECANCELED; + return -1; + } + + usleep(1300000); + ret = ser_send_char(upsfd, code); + if (ret != 1) + return ret; + return 2; +} + +/* all flags other than SER_AA are ignored */ +static void apc_flush(int flags) +{ + char temp[APC_LBUF]; + + if (flags & SER_AA) { + tcflush(upsfd, TCOFLUSH); + while(apc_read(temp, sizeof(temp), SER_D0|SER_TO|SER_AA)); + } else { + tcflush(upsfd, TCIOFLUSH); + /* tcflush(upsfd, TCIFLUSH); */ + /* while(apc_read(temp, sizeof(temp), SER_D0|SER_TO)); */ + } +} + +static const char *preread_data(apc_vartab_t *vt) +{ + int ret; + char temp[APC_LBUF]; + + upsdebugx(4, "preread_data: %s", vt->name); + + apc_flush(0); + ret = apc_write(vt->cmd); + + if (ret != 1) { + upslogx(LOG_ERR, "preread_data: apc_write failed"); + return 0; + } + + ret = apc_read(temp, sizeof(temp), SER_TO); + + if (ret < 0) { + upslogx(LOG_ERR, "preread_data: apc_read failed"); + return 0; + } + + if (!ret || !strcmp(temp, "NA")) { + upslogx(LOG_ERR, "preread_data: %s timed out or not supported", vt->name); + return 0; + } + + return convert_data(vt, temp); +} + +static void remove_var(const char *cal, apc_vartab_t *vt) +{ + const char *fmt; + char info[256]; + + if (isprint(vt->cmd)) + fmt = "[%c]"; + else + fmt = "[0x%02x]"; + + snprintf(info, sizeof(info), "%s%s%s", + "%s: verified variable [%s] (APC: ", + fmt, + ") returned NA" + ); + upsdebugx(1, info, cal, vt->name, vt->cmd); + + snprintf(info, sizeof(info), "%s%s%s", + "%s: removing [%s] (APC: ", + fmt, + ")" + ); + upsdebugx(1, info, cal, vt->name, vt->cmd); + + vt->flags &= ~APC_PRESENT; + dstate_delinfo(vt->name); } static int poll_data(apc_vartab_t *vt) { int ret; - char tmp[SMALLBUF]; + char temp[APC_LBUF]; - if ((vt->flags & APC_PRESENT) == 0) + if (!(vt->flags & APC_PRESENT)) return 1; upsdebugx(4, "poll_data: %s", vt->name); - ret = ser_send_char(upsfd, vt->cmd); + apc_flush(SER_AA); + ret = apc_write(vt->cmd); if (ret != 1) { - upslogx(LOG_ERR, "poll_data: ser_send_char failed"); + upslogx(LOG_ERR, "poll_data: apc_write failed"); dstate_datastale(); return 0; } - if (read_buf(tmp, sizeof(tmp)) < 1) { + if (apc_read(temp, sizeof(temp), SER_AA) < 1) { dstate_datastale(); return 0; } - /* no longer supported by the hardware somehow */ - if (!strcmp(tmp, "NA")) { - dstate_delinfo(vt->name); - return 1; - } + /* automagically no longer supported by the hardware somehow */ + if (!strcmp(temp, "NA")) + remove_var("poll_data", vt); - dstate_setinfo(vt->name, "%s", convert_data(vt, tmp)); + dstate_setinfo(vt->name, "%s", convert_data(vt, temp)); dstate_dataok(); return 1; } -/* check for support or just update a named variable */ -static int query_ups(const char *var, int first) +static int dfa_fwnew(const char *val) { - int ret; - char temp[256]; - const char *ptr; - apc_vartab_t *vt; + int ret; + regex_t mbuf; + /* must be xx.yy.zz */ + const char rex[] = "^[[:alnum:]]+\\.[[:alnum:]]+\\.[[:alnum:]]+$"; - vt = vartab_lookup_name(var); - - if (!vt) { - upsdebugx(1, "query_ups: unknown variable %s", var); - return 0; - } - - /* - * not first run and already known to not be supported ? - */ - if (!first && !(vt->flags & APC_PRESENT)) - return 0; - - /* empty the input buffer (while allowing the alert handler to run) */ - ret = ser_get_line_alert(upsfd, temp, sizeof(temp), ENDCHAR, - POLL_IGNORE, POLL_ALERT, alert_handler, 0, 0); - - ret = ser_send_char(upsfd, vt->cmd); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "query_ups: ser_send_char failed"); - return 0; - } - - ret = ser_get_line_alert(upsfd, temp, sizeof(temp), ENDCHAR, - POLL_IGNORE, POLL_ALERT, alert_handler, SER_WAIT_SEC, - SER_WAIT_USEC); - - if ((ret < 1) && (first == 0)) { - ser_comm_fail("%s", ret ? strerror(errno) : "timeout"); - return 0; - } - - ser_comm_good(); - - if ((ret < 1) || (!strcmp(temp, "NA"))) /* not supported */ - return 0; - - vt->flags |= APC_PRESENT; - ptr = convert_data(vt, temp); - dstate_setinfo(vt->name, "%s", ptr); - - return 1; /* success */ + regcomp(&mbuf, rex, REG_EXTENDED|REG_NOSUB); + ret = regexec(&mbuf, val, 0,0,0); + regfree(&mbuf); + return ret; } -static void do_capabilities(void) +static int dfa_cmdset(const char *val) +{ + int ret; + regex_t mbuf; + /* + * must be #.alerts.commands ; we'll be a bit lax here + */ + const char rex[] = "^[0-9]\\.[^.]*\\.[^.]+$"; + + regcomp(&mbuf, rex, REG_EXTENDED|REG_NOSUB); + ret = regexec(&mbuf, val, 0,0,0); + regfree(&mbuf); + return ret; +} + +static int valid_cmd(char cmd, const char *val) +{ + char info[256], *fmt; + int ret; + + switch (cmd) { + case APC_FW_NEW: + ret = dfa_fwnew(val); + break; + case APC_CMDSET: + ret = dfa_cmdset(val); + break; + default: + return 1; + } + + if (ret) { + if (isprint(cmd)) + fmt = "[%c]"; + else + fmt = "[0x%02x]"; + + snprintf(info, sizeof(info), "%s%s%s", + "valid_cmd: cmd ", + fmt, + " failed regex match" + ); + upslogx(LOG_WARNING, info, cmd); + } + + return !ret; +} + +/* + * query_ups() is called before any APC_PRESENT flags are determined; + * only for the variable provided + */ +static int query_ups(const char *var) +{ + int i, j; + const char *temp; + apc_vartab_t *vt, *vtn; + + /* + * at first run we know nothing about variable; we have to handle + * APC_MULTI gracefully as well + */ + for (i = 0; apc_vartab[i].name != NULL; i++) { + vt = &apc_vartab[i]; + if (strcmp(vt->name, var) || vt->flags & APC_DEPR) + continue; + + /* found, [try to] get it */ + + temp = preread_data(vt); + if (!temp || !valid_cmd(vt->cmd, temp)) { + if (vt->flags & APC_MULTI) { + vt->flags |= APC_DEPR; + continue; + } + upsdebugx(1, "query_ups: unknown variable %s", var); + break; + } + + vt->flags |= APC_PRESENT; + dstate_setinfo(vt->name, "%s", temp); + dstate_dataok(); + + /* supported, deprecate all the remaining ones */ + if (vt->flags & APC_MULTI) + for (j = i + 1; apc_vartab[j].name != NULL; j++) { + vtn = &apc_vartab[j]; + if (strcmp(vtn->name, vt->name)) + continue; + vtn->flags |= APC_DEPR; + vtn->flags &= ~APC_PRESENT; + } + + return 1; /* success */ + } + + return 0; +} + +/* + * This function iterates over vartab, deprecating nut:apc 1:n variables. We + * prefer earliest present variable. All the other ones must be marked as + * deprecated and as not present. + * This is intended to call after verifying the presence of variables. + * Otherwise it would take a while to execute due to preread_data() + */ +static void deprecate_vars(void) +{ + int i, j; + const char *temp; + apc_vartab_t *vt, *vtn; + + for (i = 0; apc_vartab[i].name != NULL; i++) { + vt = &apc_vartab[i]; + if (vt->flags & APC_DEPR) + /* already handled */ + continue; + + if (!(vt->flags & APC_MULTI)) + continue; + if (!(vt->flags & APC_PRESENT)) { + vt->flags |= APC_DEPR; + continue; + } + /* pre-read data, we have to verify it */ + temp = preread_data(vt); + if (!temp || !valid_cmd(vt->cmd, temp)) { + upslogx(LOG_ERR, "deprecate_vars: [%s] is unreadable or invalid, deprecating", vt->name); + vt->flags |= APC_DEPR; + vt->flags &= ~APC_PRESENT; + continue; + } + + /* multi & present, deprecate all the remaining ones */ + for (j = i + 1; apc_vartab[j].name != NULL; j++) { + vtn = &apc_vartab[j]; + if (strcmp(vtn->name, vt->name)) + continue; + vtn->flags |= APC_DEPR; + vtn->flags &= ~APC_PRESENT; + } + + dstate_setinfo(vt->name, "%s", temp); + dstate_dataok(); + } +} + +static void do_capabilities(int qco) { const char *ptr, *entptr; - char upsloc, temp[512], cmd, loc, etmp[16], *endtemp; + char upsloc, temp[APC_LBUF], cmd, loc, etmp[APC_SBUF], *endtemp; int nument, entlen, i, matrix, ret, valid; apc_vartab_t *vt; @@ -319,16 +780,18 @@ static void do_capabilities(void) upsloc = 0; /* get capability string */ - ret = ser_send_char(upsfd, APC_CAPABILITY); /* ^Z */ + apc_flush(0); + ret = apc_write(APC_CAPS); if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_capabilities: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "do_capabilities: apc_write failed"); return; } - - /* note different IGN set since ^Z returns things like # */ - ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, - MINIGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + /* + * note - apc_read() needs larger timeout grace and different + * ignore set due to certain characters like '#' being received + */ + ret = apc_read(temp, sizeof(temp), SER_CC|SER_TO); if ((ret < 1) || (!strcmp(temp, "NA"))) { @@ -336,7 +799,7 @@ static void do_capabilities(void) /* This should never happen since we only call this if the REQ_CAPABILITIES command is supported */ - upslogx(LOG_ERR, "ERROR: APC cannot do capabilities but said it could!"); + upslogx(LOG_ERR, "ERROR: APC cannot do capabilities but said it could !"); return; } @@ -345,9 +808,9 @@ static void do_capabilities(void) endtemp = &temp[0] + strlen(temp); if (temp[0] != '#') { - upsdebugx(1, "Unrecognized capability start char %c", temp[0]); - upsdebugx(1, "Please report this error [%s]", temp); - upslogx(LOG_ERR, "ERROR: unknown capability start char %c!", + upsdebugx(1, "unrecognized capability start char %c", temp[0]); + upsdebugx(1, "please report this error [%s]", temp); + upslogx(LOG_ERR, "ERROR: unknown capability start char %c!", temp[0]); return; @@ -372,12 +835,12 @@ static void do_capabilities(void) if (ptr >= endtemp) { /* if we expected this, just ignore it */ - if (quirk_capability_overflow) + if (qco) return; - fatalx(EXIT_FAILURE, - "Capability string has overflowed\n" - "Please report this error\n" + fatalx(EXIT_FAILURE, + "capability string has overflowed\n" + "please report this error\n" "ERROR: capability overflow!" ); } @@ -393,7 +856,7 @@ static void do_capabilities(void) /* mark this as writable */ if (valid) { - upsdebugx(1, "Supported capability: %02x (%c) - %s", + upsdebugx(1, "supported capability: %02x (%c) - %s", cmd, loc, vt->name); dstate_setflags(vt->name, ST_FLAG_RW); @@ -418,21 +881,20 @@ static void do_capabilities(void) static int update_status(void) { int ret; - char buf[SMALLBUF]; + char buf[APC_LBUF]; upsdebugx(4, "update_status"); - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - - ret = ser_send_char(upsfd, APC_STATUS); + apc_flush(SER_AA); + ret = apc_write(APC_STATUS); if (ret != 1) { - upslog_with_errno(LOG_ERR, "update_status: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "update_status: apc_write failed"); dstate_datastale(); return 0; } - ret = read_buf(buf, sizeof(buf)); + ret = apc_read(buf, sizeof(buf), SER_AA); if ((ret < 1) || (!strcmp(buf, "NA"))) { dstate_datastale(); @@ -449,70 +911,108 @@ static int update_status(void) static void oldapcsetup(void) { - int ret = 0; - /* really old models ignore REQ_MODEL, so find them first */ - ret = query_ups("ups.model", 1); - - if (ret != 1) { + if (!query_ups("ups.model")) { /* force the model name */ dstate_setinfo("ups.model", "Smart-UPS"); } /* see if this might be an old Matrix-UPS instead */ - if (query_ups("output.current", 1)) + if (query_ups("output.current")) dstate_setinfo("ups.model", "Matrix-UPS"); - query_ups("ups.serial", 1); - query_ups("input.voltage", 1); /* This one may fail... no problem */ + query_ups("ups.firmware"); + query_ups("ups.serial"); + query_ups("input.voltage"); + query_ups("battery.charge"); + query_ups("battery.voltage"); + query_ups("input.voltage"); + query_ups("output.voltage"); + query_ups("ups.temperature"); + query_ups("ups.load"); update_status(); - /* If we have come down this path then we dont do capabilities and - other shiny features - */ + /* + * If we have come down this path then we dont do capabilities and + * other shiny features. + */ } static void protocol_verify(unsigned char cmd) { - int i, found; + int i, found; + const char *fmt, *temp; + char info[256]; - /* see if it's a variable */ + /* don't bother with cmd/var we don't care about */ + if (strchr(APC_UNR_CMDS, cmd)) + return; + + if (isprint(cmd)) + fmt = "[%c]"; + else + fmt = "[0x%02x]"; + + /* + * see if it's a variable + * note: some nut variables map onto multiple APC ones (firmware) + */ for (i = 0; apc_vartab[i].name != NULL; i++) { - - /* 1:1 here, so the first match is the only match */ - if (apc_vartab[i].cmd == cmd) { - upsdebugx(3, "UPS supports variable [%s]", - apc_vartab[i].name); + if (apc_vartab[i].flags & APC_MULTI) { + /* APC_MULTI are handled by deprecate_vars() */ + apc_vartab[i].flags |= APC_PRESENT; + return; + } + + temp = preread_data(&apc_vartab[i]); + if (!temp || !valid_cmd(cmd, temp)) { + snprintf(info, sizeof(info), "%s%s%s", + "UPS variable [%s] - APC: ", + fmt, + " invalid or unreadable" + ); + upsdebugx(3, info, apc_vartab[i].name, cmd); + return; + } - /* load initial data */ apc_vartab[i].flags |= APC_PRESENT; - poll_data(&apc_vartab[i]); + + snprintf(info, sizeof(info), "%s%s", + "UPS supports variable [%s] - APC: ", + fmt + ); + upsdebugx(3, info, apc_vartab[i].name, cmd); + + dstate_setinfo(apc_vartab[i].name, "%s", temp); + dstate_dataok(); /* handle special data for our two strings */ if (apc_vartab[i].flags & APC_STRING) { - dstate_setflags(apc_vartab[i].name, + dstate_setflags(apc_vartab[i].name, ST_FLAG_RW | ST_FLAG_STRING); dstate_setaux(apc_vartab[i].name, APC_STRLEN); apc_vartab[i].flags |= APC_RW; } - return; } } - /* check the command list */ - - /* some cmdchars map onto multiple commands (start and stop) */ - + /* + * check the command list + * some APC commands map onto multiple nut ones (start and stop) + */ found = 0; - for (i = 0; apc_cmdtab[i].name != NULL; i++) { if (apc_cmdtab[i].cmd == cmd) { - upsdebugx(2, "UPS supports command [%s]", - apc_cmdtab[i].name); + + snprintf(info, sizeof(info), "%s%s", + "UPS supports command [%s] - APC: ", + fmt + ); + upsdebugx(3, info, apc_cmdtab[i].name, cmd); dstate_addcmd(apc_cmdtab[i].name); @@ -524,11 +1024,12 @@ static void protocol_verify(unsigned char cmd) if (found) return; - if (isprint(cmd)) - upsdebugx(1, "protocol_verify: 0x%02x [%c] unrecognized", - cmd, cmd); - else - upsdebugx(1, "protocol_verify: 0x%02x unrecognized", cmd); + snprintf(info, sizeof(info), "%s%s%s", + "protocol_verify - APC: ", + fmt, + " unrecognized" + ); + upsdebugx(1, info, cmd); } /* some hardware is a special case - hotwire the list of cmdchars */ @@ -536,152 +1037,144 @@ static int firmware_table_lookup(void) { int ret; unsigned int i, j; - char buf[SMALLBUF]; + char buf[APC_LBUF]; - upsdebugx(1, "Attempting firmware lookup using command 'V'"); + upsdebugx(1, "attempting firmware lookup using command 'V'"); - ret = ser_send_char(upsfd, 'V'); + apc_flush(0); + ret = apc_write(APC_FW_OLD); if (ret != 1) { - upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "firmware_table_lookup: apc_write failed"); return 0; } - ret = ser_get_line(upsfd, buf, sizeof(buf), ENDCHAR, IGNCHARS, - SER_WAIT_SEC, SER_WAIT_USEC); + ret = apc_read(buf, sizeof(buf), SER_TO); /* * Some UPSes support both 'V' and 'b'. As 'b' doesn't always return * firmware version, we attempt that only if 'V' doesn't work. */ if ((ret < 1) || (!strcmp(buf, "NA"))) { - upsdebugx(1, "Attempting firmware lookup using command 'b'"); - ret = ser_send_char(upsfd, 'b'); + upsdebugx(1, "attempting firmware lookup using command 'b'"); + ret = apc_write(APC_FW_NEW); if (ret != 1) { - upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "firmware_table_lookup: apc_write failed"); return 0; } - ret = ser_get_line(upsfd, buf, sizeof(buf), ENDCHAR, IGNCHARS, - SER_WAIT_SEC, SER_WAIT_USEC); + ret = apc_read(buf, sizeof(buf), SER_TO); if (ret < 1) { - upslog_with_errno(LOG_ERR, "firmware_table_lookup: ser_get_line failed"); + upslog_with_errno(LOG_ERR, "firmware_table_lookup: apc_read failed"); return 0; } } - upsdebugx(2, "Firmware: [%s]", buf); + upsdebugx(2, "firmware: [%s]", buf); /* this will be reworked if we get a lot of these things */ - if (!strcmp(buf, "451.2.I")) { - quirk_capability_overflow = 1; - return 0; - } + if (!strcmp(buf, "451.2.I")) + /* quirk_capability_overflow */ + return 2; - for (i = 0; compat_tab[i].firmware != NULL; i++) { - if (!strcmp(compat_tab[i].firmware, buf)) { + for (i = 0; apc_compattab[i].firmware != NULL; i++) { + if (!strcmp(apc_compattab[i].firmware, buf)) { - upsdebugx(2, "Matched - cmdchars: %s", - compat_tab[i].cmdchars); + upsdebugx(2, "matched - cmdchars: %s", + apc_compattab[i].cmdchars); - if (strspn(compat_tab[i].firmware, "05")) { + if (strspn(apc_compattab[i].firmware, "05")) { dstate_setinfo("ups.model", "Matrix-UPS"); } else { dstate_setinfo("ups.model", "Smart-UPS"); } /* matched - run the cmdchars from the table */ - for (j = 0; j < strlen(compat_tab[i].cmdchars); j++) - protocol_verify(compat_tab[i].cmdchars[j]); + for (j = 0; j < strlen(apc_compattab[i].cmdchars); j++) + protocol_verify(apc_compattab[i].cmdchars[j]); + deprecate_vars(); return 1; /* matched */ } } - upsdebugx(2, "Not found in table - trying normal method"); - return 0; + return 0; } static void getbaseinfo(void) { unsigned int i; - int ret = 0; - char *alrts, *cmds, temp[512]; + int ret, qco; + char *cmds, temp[APC_LBUF]; /* * try firmware lookup first; we could start with 'a', but older models * sometimes return other things than a command set */ - if (firmware_table_lookup() == 1) + qco = firmware_table_lookup(); + if (qco == 1) + /* found compat */ return; - upsdebugx(1, "APC - Attempting to find command set"); - /* Initially we ask the UPS what commands it takes - If this fails we are going to need an alternate - strategy - we can deal with that if it happens - */ + upsdebugx(2, "firmware not found in compatibility table - trying normal method"); + upsdebugx(1, "APC - attempting to find command set"); + /* + * Initially we ask the UPS what commands it takes If this fails we are + * going to need an alternate strategy - we can deal with that if it + * happens + */ - ret = ser_send_char(upsfd, APC_CMDSET); + apc_flush(0); + ret = apc_write(APC_CMDSET); if (ret != 1) { - upslog_with_errno(LOG_ERR, "getbaseinfo: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "getbaseinfo: apc_write failed"); return; } - ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, IGNCHARS, - SER_WAIT_SEC, SER_WAIT_USEC); + ret = apc_read(temp, sizeof(temp), SER_CS|SER_TO); - if ((ret < 1) || (!strcmp(temp, "NA"))) { + if ((ret < 1) || (!strcmp(temp, "NA")) || !valid_cmd(APC_CMDSET, temp)) { /* We have an old dumb UPS - go to specific code for old stuff */ + upsdebugx(1, "APC - trying to handle unknown model"); oldapcsetup(); return; } - upsdebugx(1, "APC - Parsing out command set"); - /* We have the version.alert.cmdchars string - NB the alert chars are normally in IGNCHARS - so will have been pretty much edited out. - You will need to change the ser_get_line above if - you want to check those out too.... - */ - alrts = strchr(temp, '.'); - if (alrts == NULL) { - fatalx(EXIT_FAILURE, "Unable to split APC version string"); - } - *alrts++ = 0; - - cmds = strchr(alrts, '.'); - if (cmds == NULL) { - fatalx(EXIT_FAILURE, "Unable to find APC command string"); - } - *cmds++ = 0; - - for (i = 0; i < strlen(cmds); i++) + upsdebugx(1, "APC - Parsing out supported cmds and vars"); + /* + * returned set is verified for validity above, so just extract + * what's interesting for us + */ + cmds = strrchr(temp, '.'); + for (i = 1; i < strlen(cmds); i++) protocol_verify(cmds[i]); + deprecate_vars(); /* if capabilities are supported, add them here */ - if (strchr(cmds, APC_CAPABILITY)) - do_capabilities(); - - upsdebugx(1, "APC - UPS capabilities determined"); + if (strchr(cmds, APC_CAPS)) { + do_capabilities(qco); + upsdebugx(1, "APC - UPS capabilities determined"); + } } /* check for calibration status and either start or stop */ static int do_cal(int start) { - char temp[256]; + char temp[APC_LBUF]; int tval, ret; - ret = ser_send_char(upsfd, APC_STATUS); + apc_flush(SER_AA); + ret = apc_write(APC_STATUS); if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "do_cal: apc_write failed"); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); /* if we can't check the current calibration status, bail out */ if ((ret < 1) || (!strcmp(temp, "NA"))) @@ -692,25 +1185,25 @@ static int do_cal(int start) if (tval & APC_STAT_CAL) { /* calibration currently happening */ if (start == 1) { /* requested start while calibration still running */ - upslogx(LOG_INFO, "Runtime calibration already in progress"); + upslogx(LOG_INFO, "runtime calibration already in progress"); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } /* stop requested */ - upslogx(LOG_INFO, "Stopping runtime calibration"); + upslogx(LOG_INFO, "stopping runtime calibration"); - ret = ser_send_char(upsfd, APC_CMD_CALTOGGLE); + ret = apc_write(APC_CMD_CALTOGGLE); if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "do_cal: apc_write failed"); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); if ((ret < 1) || (!strcmp(temp, "NA")) || (!strcmp(temp, "NO"))) { - upslogx(LOG_WARNING, "Stop calibration failed: %s", + upslogx(LOG_WARNING, "stop calibration failed: %s", temp); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } @@ -721,65 +1214,91 @@ static int do_cal(int start) /* calibration not happening */ if (start == 0) { /* stop requested */ - upslogx(LOG_INFO, "Runtime calibration not occurring"); + upslogx(LOG_INFO, "runtime calibration not occurring"); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } - upslogx(LOG_INFO, "Starting runtime calibration"); + upslogx(LOG_INFO, "starting runtime calibration"); - ret = ser_send_char(upsfd, APC_CMD_CALTOGGLE); + ret = apc_write(APC_CMD_CALTOGGLE); if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_cal: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "do_cal: apc_write failed"); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); if ((ret < 1) || (!strcmp(temp, "NA")) || (!strcmp(temp, "NO"))) { - upslogx(LOG_WARNING, "Start calibration failed: %s", temp); + upslogx(LOG_WARNING, "start calibration failed: %s", temp); return STAT_INSTCMD_HANDLED; /* FUTURE: failure */ } return STAT_INSTCMD_HANDLED; /* FUTURE: success */ } +#if 0 /* get the UPS talking to us in smart mode */ static int smartmode(void) { - int ret, tries; - char temp[256]; + int ret; + char temp[APC_LBUF]; - for (tries = 0; tries < 5; tries++) { + apc_flush(0); + ret = apc_write(APC_GOSMART); + if (ret != 1) { + upslog_with_errno(LOG_ERR, "smartmode: apc_write failed"); + return 0; + } + ret = apc_read(temp, sizeof(temp), 0); - ret = ser_send_char(upsfd, APC_GOSMART); + if ((ret < 1) || (!strcmp(temp, "NA")) || (!strcmp(temp, "NO"))) { + upslogx(LOG_CRIT, "enabling smartmode failed !"); + return 0; + } + + return 1; +} +#endif + +/* + * get the UPS talking to us in smart mode + * note: this is weird overkill, but possibly excused due to some obscure + * hardware/firmware combinations; simpler version commmented out above, for + * now let's keep minimally adjusted old one + */ +static int smartmode(int cnt) +{ + int ret, tries; + char temp[APC_LBUF]; + + for (tries = 0; tries < cnt; tries++) { + + apc_flush(0); + ret = apc_write(APC_GOSMART); if (ret != 1) { - upslog_with_errno(LOG_ERR, "smartmode: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "smartmode: issuing 'Y' failed"); return 0; } + ret = apc_read(temp, sizeof(temp), SER_D1); + if (ret > 0 && !strcmp(temp, "SM")) + return 1; /* success */ + if (ret < 0) { + /* error, so we didn't timeout - wait a bit before retry */ + sleep(1); + } - ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, - IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); - - if (ret > 0) - if (!strcmp(temp, "SM")) - return 1; /* success */ - - sleep(1); /* wait before trying again */ - - /* it failed, so try to bail out of menus on newer units */ - - ret = ser_send_char(upsfd, 27); /* ESC */ + apc_flush(0); + ret = apc_write(27); /* ESC */ if (ret != 1) { - upslog_with_errno(LOG_ERR, "smartmode: ser_send_char failed"); + upslog_with_errno(LOG_ERR, "smartmode: issuing ESC failed"); return 0; } /* eat the response (might be NA, might be something else) */ - ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, - IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + apc_read(temp, sizeof(temp), SER_TO|SER_D1); } return 0; /* failure */ @@ -787,158 +1306,178 @@ static int smartmode(void) /* * all shutdown commands should respond with 'OK' or '*' + * apc_read() handles conversion to 'OK' so we care only about that one + * ign allows for timeout without assuming an error */ -static int sdok(void) +static int sdok(int ign) { - char temp[16]; + int ret; + char temp[APC_SBUF]; - ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); - upsdebugx(4, "sdok: got \"%s\"", temp); - - if (!strcmp(temp, "*") || !strcmp(temp, "OK")) { - upsdebugx(4, "Last issued shutdown command succeeded"); - return 1; + /* + * older upses on failed commands might just timeout, we cut down + * timeout grace though + * furthermore, command 'Z' will not reply with anything + */ + ret = apc_read(temp, sizeof(temp), SER_HA|SER_D1|SER_TO); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdok: apc_read failed"); + return STAT_INSTCMD_FAILED; } - upsdebugx(1, "Last issued shutdown command failed"); - return 0; + upsdebugx(4, "sdok: got \"%s\"", temp); + + if ((!ret && ign) || !strcmp(temp, "OK")) { + upsdebugx(4, "sdok: last issued shutdown cmd succeeded"); + return STAT_INSTCMD_HANDLED; + } + + upsdebugx(1, "sdok: last issued shutdown cmd failed"); + return STAT_INSTCMD_FAILED; } /* soft hibernate: S - working only when OB, otherwise ignored */ -static int sdcmd_S(int dummy) +static int sdcmd_S(const void *foo) { - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + int ret; - upsdebugx(1, "Issuing soft hibernate"); - ser_send_char(upsfd, APC_CMD_SOFTDOWN); + apc_flush(0); + upsdebugx(1, "issuing soft hibernate"); + ret = apc_write(APC_CMD_SOFTDOWN); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_S: issuing 'S' failed"); + return STAT_INSTCMD_FAILED; + } - return sdok(); + return sdok(0); } -/* soft hibernate, hack version for CS 350 */ -static int sdcmd_CS(int tval) +/* soft hibernate, hack version for CS 350 & co. */ +static int sdcmd_CS(const void *foo) { - upsdebugx(1, "Using CS 350 'force OB' shutdown method"); - if (tval & APC_STAT_OL) { - upsdebugx(1, "On-line - forcing OB temporarily"); - ser_send_char(upsfd, 'U'); - usleep(UPSDELAY); + int ret; + char temp[APC_SBUF]; + + upsdebugx(1, "using CS 350 'force OB' shutdown method"); + if (ups_status & APC_STAT_OL) { + apc_flush(0); + upsdebugx(1, "status OL - forcing OB temporarily"); + ret = apc_write(APC_CMD_SIMPWF); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_CS: issuing 'U' failed"); + return STAT_INSTCMD_FAILED; + } + /* eat response */ + ret = apc_read(temp, sizeof(temp), SER_D1); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_CS: 'U' returned nothing ?"); + return STAT_INSTCMD_FAILED; + } } - return sdcmd_S(tval); + return sdcmd_S(0); } /* * hard hibernate: @nnn / @nn - * note: works differently for older and new models, see help function for - * detailed info + * note: works differently for older and new models, see manual page for + * thorough explanation */ -static int sdcmd_ATn(int cnt) +static int sdcmd_AT(const void *str) { - int n = 0, mmax, ret; - const char *strval; - char timer[4]; + int ret, cnt, padto, i; + const char *awd = str; + char temp[APC_SBUF], *ptr; - mmax = cnt == 2 ? 99 : 999; + if (!awd) + awd = "000"; - if ((strval = getval("wugrace"))) { - errno = 0; - n = strtol(strval, NULL, 10); - if (errno || n < 0 || n > mmax) - n = 0; + cnt = strlen(awd); + padto = cnt == 2 ? 2 : 3; + + temp[0] = APC_CMD_GRACEDOWN; + ptr = temp + 1; + for (i = cnt; i < padto ; i++) { + *ptr++ = '0'; + } + strcpy(ptr, awd); + + upsdebugx(1, "issuing '@' with %d minutes of additional wakeup delay", (int)strtol(awd, NULL, 10)*6); + + apc_flush(0); + ret = apc_write_long(temp); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_AT: issuing '@' with %d digits failed", padto); + return STAT_INSTCMD_FAILED; } - snprintf(timer, sizeof(timer), "%.*d", cnt, n); - - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - upsdebugx(1, "Issuing hard hibernate with %d minutes additional wakeup delay", n*6); - - ser_send_char(upsfd, APC_CMD_GRACEDOWN); - usleep(CMDLONGDELAY); - ser_send_pace(upsfd, UPSDELAY, "%s", timer); - - ret = sdok(); - if (ret || cnt == 3) + ret = sdok(0); + if (ret == STAT_INSTCMD_HANDLED || padto == 3) return ret; + upslog_with_errno(LOG_ERR, "sdcmd_AT: command '@' with 2 digits doesn't work - try 3 digits"); /* * "tricky" part - we tried @nn variation and it (unsurprisingly) * failed; we have to abort the sequence with something bogus to have * the clean state; newer upses will respond with 'NO', older will be * silent (YMMV); */ - ser_send_char(upsfd, APC_CMD_GRACEDOWN); - usleep(UPSDELAY); - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); + apc_write(APC_CMD_GRACEDOWN); + /* eat response, allow it to timeout */ + apc_read(temp, sizeof(temp), SER_D1|SER_TO); - return 0; + return STAT_INSTCMD_FAILED; } /* shutdown: K - delayed poweroff */ -static int sdcmd_K(int dummy) +static int sdcmd_K(const void *foo) { - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - upsdebugx(1, "Issuing delayed poweroff"); + int ret; - ser_send_char(upsfd, APC_CMD_SHUTDOWN); - usleep(CMDLONGDELAY); - ser_send_char(upsfd, APC_CMD_SHUTDOWN); + upsdebugx(1, "issuing 'K'"); - return sdok(); + apc_flush(0); + ret = apc_write_rep(APC_CMD_SHUTDOWN); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_K: issuing 'K' failed"); + return STAT_INSTCMD_FAILED; + } + + return sdok(0); } /* shutdown: Z - immediate poweroff */ -static int sdcmd_Z(int dummy) +static int sdcmd_Z(const void *foo) { - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - upsdebugx(1, "Issuing immediate poweroff"); + int ret; - ser_send_char(upsfd, APC_CMD_OFF); - usleep(CMDLONGDELAY); - ser_send_char(upsfd, APC_CMD_OFF); + upsdebugx(1, "issuing 'Z'"); - return sdok(); + apc_flush(0); + ret = apc_write_rep(APC_CMD_OFF); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "sdcmd_Z: issuing 'Z' failed"); + return STAT_INSTCMD_FAILED; + } + + /* note: ups will not reply anything after this command */ + return sdok(1); } -static int (*sdlist[])(int) = { - sdcmd_S, - sdcmd_ATn, /* for @nnn version */ - sdcmd_K, - sdcmd_Z, - sdcmd_CS, - sdcmd_ATn, /* for @nn version */ -}; - -#define SDIDX_S 0 -#define SDIDX_AT3N 1 -#define SDIDX_K 2 -#define SDIDX_Z 3 -#define SDIDX_CS 4 -#define SDIDX_AT2N 5 - -#define SDCNT 6 - -static void upsdrv_shutdown_simple(int status) +static void upsdrv_shutdown_simple(void) { unsigned int sdtype = 0; - char *strval; + const char *val; - if ((strval = getval("sdtype"))) { - errno = 0; - sdtype = strtol(strval, NULL, 10); - if (errno || sdtype < 0 || sdtype > 6) - sdtype = 0; - } + if ((val = getval("sdtype"))) + sdtype = strtol(val, NULL, 10); switch (sdtype) { - case 6: /* hard hibernate */ - sdcmd_ATn(3); - break; - case 5: /* "hack nn" hard hibernate */ - sdcmd_ATn(2); + case 5: /* hard hibernate */ + sdcmd_AT(getval("awd")); break; case 4: /* special hack for CS 350 and similar models */ - sdcmd_CS(status); + sdcmd_CS(0); break; case 3: /* delayed poweroff */ @@ -956,68 +1495,48 @@ static void upsdrv_shutdown_simple(int status) * hard hibernate '@nnn' commands */ upsdebugx(1, "UPS - currently %s - sending soft/hard hibernate commands", - (status & APC_STAT_OL) ? "on-line" : "on battery"); + (ups_status & APC_STAT_OL) ? "on-line" : "on battery"); /* S works only when OB */ - if ((status & APC_STAT_OB) && sdcmd_S(0)) + if ((ups_status & APC_STAT_OB) && sdcmd_S(0) == STAT_INSTCMD_HANDLED) break; - sdcmd_ATn(3); + sdcmd_AT(getval("awd")); break; default: /* * Send @nnn or S, depending on OB / OL status */ - if (status & APC_STAT_OL) /* on line */ - sdcmd_ATn(3); + if (ups_status & APC_STAT_OL) /* on line */ + sdcmd_AT(getval("awd")); else sdcmd_S(0); } } -static void upsdrv_shutdown_advanced(int status) +static void upsdrv_shutdown_advanced(void) { - const char *strval; - const char deforder[] = {48 + SDIDX_S, - 48 + SDIDX_AT3N, - 48 + SDIDX_K, - 48 + SDIDX_Z, - 0}; - size_t i; - int n; + const void *arg; + const char *val; + size_t i, len; - strval = getval("advorder"); - - /* sanitize advorder */ - - if (!strval || !strlen(strval) || strlen(strval) > SDCNT) - strval = deforder; - for (i = 0; i < strlen(strval); i++) { - if (strval[i] - 48 < 0 || strval[i] - 48 >= SDCNT) { - strval = deforder; - break; - } - } + val = getval("advorder"); + len = strlen(val); /* * try each method in the list with a little bit of handling in certain * cases */ - - for (i = 0; i < strlen(strval); i++) { - switch (strval[i] - 48) { - case SDIDX_CS: - n = status; + for (i = 0; i < len; i++) { + switch (val[i] - '0') { + case SDIDX_AT: + arg = getval("awd"); break; - case SDIDX_AT3N: - n = 3; - break; - case SDIDX_AT2N: default: - n = 2; + arg = NULL; } - if (sdlist[strval[i] - 48](n)) + if (sdlist[val[i] - '0'](arg) == STAT_INSTCMD_HANDLED) break; /* finish if command succeeded */ } } @@ -1025,43 +1544,35 @@ static void upsdrv_shutdown_advanced(int status) /* power down the attached load immediately */ void upsdrv_shutdown(void) { - char temp[32]; - int ret, status; + char temp[APC_LBUF]; + int ret; - if (!smartmode()) + if (!smartmode(1)) upsdebugx(1, "SM detection failed. Trying a shutdown command anyway"); /* check the line status */ - ret = ser_send_char(upsfd, APC_STATUS); + ret = apc_write(APC_STATUS); if (ret == 1) { - ret = ser_get_line(upsfd, temp, sizeof(temp), ENDCHAR, - IGNCHARS, SER_WAIT_SEC, SER_WAIT_USEC); + ret = apc_read(temp, sizeof(temp), SER_D1); if (ret < 1) { - upsdebugx(1, "Status read failed ! Assuming on battery state"); - status = APC_STAT_LB | APC_STAT_OB; + upsdebugx(1, "status read failed ! assuming on battery state"); + ups_status = APC_STAT_LB | APC_STAT_OB; } else { - status = strtol(temp, 0, 16); + ups_status = strtol(temp, 0, 16); } } else { - upsdebugx(1, "Status request failed; assuming on battery state"); - status = APC_STAT_LB | APC_STAT_OB; + upsdebugx(1, "status request failed; assuming on battery state"); + ups_status = APC_STAT_LB | APC_STAT_OB; } if (testvar("advorder") && strcasecmp(getval("advorder"), "no")) - upsdrv_shutdown_advanced(status); + upsdrv_shutdown_advanced(); else - upsdrv_shutdown_simple(status); -} - -/* 940-0095B support: set DTR, lower RTS */ -static void init_serial_0095B(void) -{ - ser_set_dtr(upsfd, 1); - ser_set_rts(upsfd, 0); + upsdrv_shutdown_simple(); } static void update_info_normal(void) @@ -1104,75 +1615,76 @@ static void update_info_all(void) static int setvar_enum(apc_vartab_t *vt, const char *val) { int i, ret; - char orig[256], temp[256]; + char orig[APC_LBUF], temp[APC_LBUF]; const char *ptr; - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - ret = ser_send_char(upsfd, vt->cmd); + apc_flush(SER_AA); + ret = apc_write(vt->cmd); if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + upslog_with_errno(LOG_ERR, "setvar_enum: apc_write failed"); + return STAT_SET_FAILED; } - ret = read_buf(orig, sizeof(orig)); + ret = apc_read(orig, sizeof(orig), SER_AA); if ((ret < 1) || (!strcmp(orig, "NA"))) - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; ptr = convert_data(vt, orig); /* suppress redundant changes - easier on the eeprom */ if (!strcmp(ptr, val)) { - upslogx(LOG_INFO, "Ignoring enum SET %s='%s' (unchanged value)", + upslogx(LOG_INFO, "ignoring enum SET %s='%s' (unchanged value)", vt->name, val); return STAT_SET_HANDLED; /* FUTURE: no change */ } for (i = 0; i < 6; i++) { - ret = ser_send_char(upsfd, APC_NEXTVAL); + ret = apc_write(APC_NEXTVAL); if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + upslog_with_errno(LOG_ERR, "setvar_enum: apc_write failed"); + return STAT_SET_FAILED; } /* this should return either OK (if rotated) or NO (if not) */ - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); if ((ret < 1) || (!strcmp(temp, "NA"))) - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; /* sanity checks */ if (!strcmp(temp, "NO")) - return STAT_SET_HANDLED; /* FUTURE: failed */ - if (strcmp(temp, "OK") != 0) - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; + if (strcmp(temp, "OK")) + return STAT_SET_FAILED; /* see what it rotated onto */ - ret = ser_send_char(upsfd, vt->cmd); + ret = apc_write(vt->cmd); if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_enum: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + upslog_with_errno(LOG_ERR, "setvar_enum: apc_write failed"); + return STAT_SET_FAILED; } - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); if ((ret < 1) || (!strcmp(temp, "NA"))) - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; ptr = convert_data(vt, temp); - upsdebugx(1, "Rotate value: got [%s], want [%s]", + upsdebugx(1, "rotate value: got [%s], want [%s]", ptr, val); if (!strcmp(ptr, val)) { /* got it */ upslogx(LOG_INFO, "SET %s='%s'", vt->name, val); /* refresh data from the hardware */ - query_ups(vt->name, 0); + poll_data(vt); + /* query_ups(vt->name, 0); */ return STAT_SET_HANDLED; /* FUTURE: success */ } @@ -1182,15 +1694,16 @@ static int setvar_enum(apc_vartab_t *vt, const char *val) upslogx(LOG_ERR, "setvar: variable %s wrapped", vt->name); - return STAT_SET_HANDLED; /* FUTURE: failed */ - } + return STAT_SET_FAILED; + } } upslogx(LOG_ERR, "setvar: gave up after 6 tries for %s", vt->name); /* refresh data from the hardware */ - query_ups(vt->name, 0); + poll_data(vt); + /* query_ups(vt->name, 0); */ return STAT_SET_HANDLED; } @@ -1199,79 +1712,69 @@ static int setvar_string(apc_vartab_t *vt, const char *val) { unsigned int i; int ret; - char temp[256]; + char temp[APC_LBUF], *ptr; - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - ret = ser_send_char(upsfd, vt->cmd); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + /* sanitize length */ + if (strlen(val) > APC_STRLEN) { + upslogx(LOG_ERR, "setvar_string: value (%s) too long", val); + return STAT_SET_FAILED; } - ret = read_buf(temp, sizeof(temp)); + apc_flush(SER_AA); + ret = apc_write(vt->cmd); + + if (ret != 1) { + upslog_with_errno(LOG_ERR, "setvar_string: apc_write failed"); + return STAT_SET_FAILED; + } + + ret = apc_read(temp, sizeof(temp), SER_AA); if ((ret < 1) || (!strcmp(temp, "NA"))) - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; /* suppress redundant changes - easier on the eeprom */ if (!strcmp(temp, val)) { - upslogx(LOG_INFO, "Ignoring string SET %s='%s' (unchanged value)", + upslogx(LOG_INFO, "ignoring string SET %s='%s' (unchanged value)", vt->name, val); return STAT_SET_HANDLED; /* FUTURE: no change */ } - ret = ser_send_char(upsfd, APC_NEXTVAL); + /* length sanitized above */ + temp[0] = APC_NEXTVAL; + strcpy(temp + 1, val); + ptr = temp + strlen(temp); + for (i = strlen(val); i < APC_STRLEN; i++) + *ptr++ = '\015'; /* pad with CRs */ + *ptr = 0; - if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + ret = apc_write_long(ptr); + + if ((size_t)ret != strlen(ptr)) { + upslog_with_errno(LOG_ERR, "setvar_string: apc_write_long failed"); + return STAT_SET_FAILED; } - usleep(UPSDELAY); - - for (i = 0; i < strlen(val); i++) { - ret = ser_send_char(upsfd, val[i]); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ - } - - usleep(UPSDELAY); - } - - /* pad to 8 chars with CRs */ - for (i = strlen(val); i < APC_STRLEN; i++) { - ret = ser_send_char(upsfd, 13); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "setvar_string: ser_send_char failed"); - return STAT_SET_HANDLED; /* FUTURE: failed */ - } - - usleep(UPSDELAY); - } - - ret = read_buf(temp, sizeof(temp)); + ret = apc_read(temp, sizeof(temp), SER_AA); if (ret < 1) { upslogx(LOG_ERR, "setvar_string: short final read"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; } if (!strcmp(temp, "NO")) { upslogx(LOG_ERR, "setvar_string: got NO at final read"); - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_FAILED; } /* refresh data from the hardware */ - query_ups(vt->name, 0); + poll_data(vt); + /* query_ups(vt->name, 0); */ upslogx(LOG_INFO, "SET %s='%s'", vt->name, val); - return STAT_SET_HANDLED; /* FUTURE: failed */ + return STAT_SET_HANDLED; /* FUTURE: success */ } static int setvar(const char *varname, const char *val) @@ -1298,50 +1801,69 @@ static int setvar(const char *varname, const char *val) return STAT_SET_UNKNOWN; } -/* actually send the instcmd's char to the ups */ -static int do_cmd(apc_cmdtab_t *ct) +/* load on */ +static int do_loadon(void) { - int ret; - char buf[SMALLBUF]; + int ret; + apc_flush(0); + upsdebugx(1, "issuing load-on command"); - ser_flush_in(upsfd, IGNCHARS, nut_debug_level); - ret = ser_send_char(upsfd, ct->cmd); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + ret = apc_write_rep(APC_CMD_ON); + if (ret < 0) { + upslog_with_errno(LOG_ERR, "do_loadon: apc_write_rep failed"); + return STAT_INSTCMD_FAILED; } - /* some commands have to be sent twice with a 1.5s gap */ + /* + * ups will not reply anything after this command, but might + * generate brief OVER condition (which will be corrected on + * the next status update) + */ + + upsdebugx(1, "load-on command (apc:^N) executed"); + return STAT_INSTCMD_HANDLED; +} + +/* actually send the instcmd's char to the ups */ +static int do_cmd(const apc_cmdtab_t *ct) +{ + int ret; + char temp[APC_LBUF]; + const char *strerr; + + apc_flush(SER_AA); + if (ct->flags & APC_REPEAT) { - usleep(CMDLONGDELAY); - - ret = ser_send_char(upsfd, ct->cmd); - - if (ret != 1) { - upslog_with_errno(LOG_ERR, "do_cmd: ser_send_char failed"); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ - } + ret = apc_write_rep(ct->cmd); + strerr = "apc_write_rep"; + } else { + ret = apc_write(ct->cmd); + strerr = "apc_write"; } - ret = read_buf(buf, sizeof(buf)); + if (ret < 1) { + upslog_with_errno(LOG_ERR, "do_cmd: %s failed", strerr); + return STAT_INSTCMD_FAILED; + } + + ret = apc_read(temp, sizeof(temp), SER_AA); if (ret < 1) - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; - if (strcmp(buf, "OK") != 0) { - upslogx(LOG_WARNING, "Got [%s] after command [%s]", - buf, ct->name); + if (strcmp(temp, "OK")) { + upslogx(LOG_WARNING, "got [%s] after command [%s]", + temp, ct->name); - return STAT_INSTCMD_HANDLED; /* FUTURE: failed */ + return STAT_INSTCMD_FAILED; } - upslogx(LOG_INFO, "Command: %s", ct->name); - return STAT_INSTCMD_HANDLED; /* FUTURE: success */ + upslogx(LOG_INFO, "command: %s", ct->name); + return STAT_INSTCMD_HANDLED; } /* some commands must be repeated in a window to execute */ -static int instcmd_chktime(apc_cmdtab_t *ct) +static int instcmd_chktime(apc_cmdtab_t *ct, const char *ext) { double elapsed; time_t now; @@ -1354,48 +1876,89 @@ static int instcmd_chktime(apc_cmdtab_t *ct) /* you have to hit this in a small window or it fails */ if ((elapsed < MINCMDTIME) || (elapsed > MAXCMDTIME)) { - upsdebugx(1, "instcmd_chktime: outside window for %s (%2.0f)", - ct->name, elapsed); - return STAT_INSTCMD_HANDLED; /* FUTURE: again */ + upsdebugx(1, "instcmd_chktime: outside window for [%s %s] (%2.0f)", + ct->name, ext ? ext : "\b", elapsed); + return 0; } - return do_cmd(ct); + return 1; } -static int instcmd(const char *cmdname, const char *extra) +static int instcmd(const char *cmd, const char *ext) { - int i; - apc_cmdtab_t *ct; + int i; + apc_cmdtab_t *ct = NULL; - ct = NULL; - - for (i = 0; apc_cmdtab[i].name != NULL; i++) - if (!strcasecmp(apc_cmdtab[i].name, cmdname)) - ct = &apc_cmdtab[i]; + for (i = 0; apc_cmdtab[i].name != NULL; i++) { + /* main command must match */ + if (strcasecmp(apc_cmdtab[i].name, cmd)) + continue; + /* extra was provided - check it */ + if (ext && *ext) { + if (!apc_cmdtab[i].ext) + continue; + if (strlen(apc_cmdtab[i].ext) > 2) { + if (rexhlp(apc_cmdtab[i].ext, ext)) + continue; + } else { + if (strcasecmp(apc_cmdtab[i].ext, ext)) + continue; + } + } else if (apc_cmdtab[i].ext) + continue; + ct = &apc_cmdtab[i]; + break; + } if (!ct) { - upslogx(LOG_WARNING, "instcmd: unknown command [%s]", cmdname); - return STAT_INSTCMD_UNKNOWN; + upslogx(LOG_WARNING, "instcmd: unknown command [%s %s]", cmd, + ext ? ext : "\b"); + return STAT_INSTCMD_INVALID; } - if ((ct->flags & APC_PRESENT) == 0) { - upslogx(LOG_WARNING, "instcmd: command [%s] is not supported", - cmdname); - return STAT_INSTCMD_UNKNOWN; + if (!(ct->flags & APC_PRESENT)) { + upslogx(LOG_WARNING, "instcmd: command [%s %s] recognized, but" + " not supported by your UPS model", cmd, + ext ? ext : "\b"); + return STAT_INSTCMD_INVALID; } - if (!strcasecmp(cmdname, "calibrate.start")) + /* first verify if the command is "nasty" */ + if ((ct->flags & APC_NASTY) && !instcmd_chktime(ct, ext)) + return STAT_INSTCMD_HANDLED; /* future: again */ + + /* we're good to go, handle special stuff first, then generic cmd */ + + if (!strcasecmp(cmd, "calibrate.start")) return do_cal(1); - if (!strcasecmp(cmdname, "calibrate.stop")) + if (!strcasecmp(cmd, "calibrate.stop")) return do_cal(0); - if (ct->flags & APC_NASTY) - return instcmd_chktime(ct); + if (!strcasecmp(cmd, "load.on")) + return do_loadon(); + + if (!strcasecmp(cmd, "load.off")) + return sdcmd_Z(0); + + if (!strcasecmp(cmd, "shutdown.stayoff")) + return sdcmd_K(0); + + if (!strcasecmp(cmd, "shutdown.return")) { + if (!ext || !*ext) + return sdcmd_S(0); + + /* ext length is guaranteed by regex match above */ + if (!strncasecmp(ext, "at", 2)) + return sdcmd_AT(ext + 3); + + if (!strncasecmp(ext, "cs", 2)) + return sdcmd_CS(0); + } /* nothing special here */ return do_cmd(ct); -} +} /* install pointers to functions for msg handlers called from msgparse */ static void setuphandlers(void) @@ -1408,26 +1971,53 @@ static void setuphandlers(void) void upsdrv_makevartable(void) { - addvar(VAR_VALUE, "cable", "Specify alternate cable (940-0095B)"); - addvar(VAR_VALUE, "wugrace", "Hard hibernate's wakeup grace"); - addvar(VAR_VALUE, "sdtype", "Specify simple shutdown method (0-6)"); - addvar(VAR_VALUE, "advorder", "Enable advanced shutdown control"); + addvar(VAR_VALUE, "cable", "specify alternate cable (940-0095B)"); + addvar(VAR_VALUE, "awd", "hard hibernate's additional wakeup delay"); + addvar(VAR_VALUE, "sdtype", "specify simple shutdown method (0 - " APC_SDMAX ")"); + addvar(VAR_VALUE, "advorder", "enable advanced shutdown control"); } void upsdrv_initups(void) { - char *cable; + size_t i, len; + char *val; - upsfd = ser_open(device_path); - ser_set_speed(upsfd, device_path, B2400); + upsfd = extrafd = ser_open(device_path); + apc_ser_set(); - cable = getval("cable"); + /* sanitize awd (additional waekup delay of '@' command) */ + if ((val = getval("awd")) && rexhlp(APC_AWDFMT, val)) { + fatalx(EXIT_FAILURE, "invalid value (%s) for option 'awd'", val); + } - if (cable && !strcasecmp(cable, ALT_CABLE_1)) - init_serial_0095B(); + /* sanitize sdtype */ + if ((val = getval("sdtype")) && rexhlp(APC_SDFMT, val)) { + fatalx(EXIT_FAILURE, "invalid value (%s) for option 'sdtype'", val); + } - /* make sure we wake up if the UPS sends alert chars to us */ - extrafd = upsfd; + /* sanitize advorder */ + if ((val = getval("advorder")) && strcasecmp(val, "no")) { + len = strlen(val); + + if (!len || len > SDCNT) + fatalx(EXIT_FAILURE, "invalid length of 'advorder' option (%s)", val); + for (i = 0; i < len; i++) { + if (val[i] < '0' || val[i] >= '0' + SDCNT) { + fatalx(EXIT_FAILURE, "invalid characters in 'advorder' option (%s)", val); + } + } + } +} + +void upsdrv_cleanup(void) +{ + char temp[APC_LBUF]; + + apc_flush(0); + /* try to bring the UPS out of smart mode */ + apc_write(APC_GODUMB); + apc_read(temp, sizeof(temp), SER_TO); + ser_close(upsfd, device_path); } void upsdrv_help(void) @@ -1438,10 +2028,10 @@ void upsdrv_initinfo(void) { const char *pmod, *pser; - if (!smartmode()) { - fatalx(EXIT_FAILURE, - "Unable to detect an APC Smart protocol UPS on port %s\n" - "Check the cabling, port name or model name and try again", device_path + if (!smartmode(5)) { + fatalx(EXIT_FAILURE, + "unable to detect an APC Smart protocol UPS on port %s\n" + "check the cabling, port name or model name and try again", device_path ); } @@ -1455,26 +2045,35 @@ void upsdrv_initinfo(void) if (!(pser = dstate_getinfo("ups.serial"))) pser = "unknown serial"; - upsdebugx(1, "Detected %s [%s] on %s", pmod, pser, device_path); + upsdebugx(1, "detected %s [%s] on %s", pmod, pser, device_path); setuphandlers(); } void upsdrv_updateinfo(void) { - static time_t last_full = 0; - time_t now; + static int last_worked = 0; + static time_t last_full = 0; + time_t now; /* try to wake up a dead ups once in awhile */ - if ((dstate_is_stale()) && (!smartmode())) { - ser_comm_fail("Communications with UPS lost - check cabling"); + if (dstate_is_stale()) { + if (!last_worked) + upsdebugx(LOG_DEBUG, "upsdrv_updateinfo: comm lost"); /* reset this so a full update runs when the UPS returns */ last_full = 0; - return; - } - ser_comm_good(); + if (++last_worked < 10) + return; + + /* become aggressive after a few tries */ + upsdebugx(LOG_DEBUG, "upsdrv_updateinfo: nudging ups with 'Y', iteration #%d ...", last_worked); + if (!smartmode(1)) + return; + + last_worked = 0; + } if (!update_status()) return; @@ -1491,11 +2090,3 @@ void upsdrv_updateinfo(void) update_info_normal(); } - -void upsdrv_cleanup(void) -{ - /* try to bring the UPS out of smart mode */ - ser_send_char(upsfd, APC_GODUMB); - - ser_close(upsfd, device_path); -} diff --git a/drivers/apcsmart.h b/drivers/apcsmart.h index f143cfa..e10c5fe 100644 --- a/drivers/apcsmart.h +++ b/drivers/apcsmart.h @@ -1,50 +1,88 @@ -/* apcsmart.h - command table for APC smart protocol units +/* + * apcsmart.h - common defines for apcsmart driver + * + * Copyright (C) 1999 Russell Kroll + * (C) 2000 Nigel Metheringham + * (C) 2011 Michal Soltys + * + * 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 + */ - Copyright (C) 1999 Russell Kroll - (C) 2000 Nigel Metheringham +#ifndef __apcsmart_h__ +#define __apcsmart_h__ - 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. +#define DRIVER_NAME "APC Smart protocol driver" +#define DRIVER_VERSION "3.0" - 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. +#define ALT_CABLE_1 "940-0095B" - 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 -*/ +/* + * alerts and other stuff for quick reference: + * + * $ OL + * ! OB + * % LB + * + not LB anymore + * # RB + * ? OVER + * = not OVER anymore + * * powering down now (only older models ?), handled by upsread() + * otherwise ignored (it doesn't have to be in ignore sets) + * + * | eeprom change + * & check alarm register for fail + * ~ ??? + */ -#include -#include -#include "serial.h" -#include "timehead.h" - -#define APC_TABLE_VERSION "version 2.2" +/* + * old ones for reference: + * #define IGNCHARS "\015+$|!~%?=#&" + * #define POLL_IGNORE "\015&|" + * #define POLL_ALERT "$!%+#?=" + * #define MINIGNCHARS "\015+$|!" + * notice ~ that was present in IGNCHARS, but not in POLL_IGNORE - this kinda + * didn't make sense (?); new versions doesn't filter ~, but keep that in mind + * in case something obscure surfaces + * due to switch to ICANON tty mode, we removed \015 from ignored characters, + * as it's handled by IGNCR at read() level + */ /* Basic UPS reply line structure */ -#define ENDCHAR 10 /* APC ends responses with LF */ +#define ENDCHAR 10 /* APC ends responses with LF (and CR, but it's IGNCRed) */ -/* characters ignored by default */ -#define IGNCHARS "\015+$|!~%?=#&" /* special characters to ignore */ +/* what to ignore during alert aware serial reads */ +#define IGN_AACHARS "|&" -/* these one is used only during startup, due to ^Z sending certain characters such as # */ -#define MINIGNCHARS "\015+$|!" /* minimum set of special characters to ignore */ +/* what alert_handler() should care about */ +#define ALERT_CHARS "$!%+#?=" -/* normal polls: characters we don't want to parse (including a few alerts) */ -#define POLL_IGNORE "\015&|" +/* characters ignored by alertless reads */ +#define IGN_CHARS IGN_AACHARS ALERT_CHARS -/* alert characters we care about - OL, OB, LB, not LB, RB, OVER, not OVER */ -#define POLL_ALERT "$!%+#?=" +/* + * these ones are used only during capability read, due to ^Z sending certain + * characters such as #; it seems it could be equal to just IGN_CHARS w/o # + * old: #define IGN_CCCHARS "|$!+" + */ +#define IGN_CCCHARS "|&$!%+?=" /* capability check ignore set */ -#define UPSDELAY 50000 /* slow down multicharacter commands */ -#define CMDLONGDELAY 1500000 /* some commands need a 1.5s gap for safety */ - -#define SER_WAIT_SEC 3 /* wait up to 3.0 sec for ser_get calls */ -#define SER_WAIT_USEC 0 +/* + * command set 'a' command reports everything - protocol number, alerts and + * supported commands + */ +#define IGN_CSCHARS "" /* command set ignore set */ /* dangerous instant commands must be reconfirmed within a 12 second window */ #define MINCMDTIME 3 @@ -53,239 +91,61 @@ /* it only does two strings, and they're both the same length */ #define APC_STRLEN 8 +#define SER_D0 0x001 /* 0 sec., for flushes */ +#define SER_DX 0x002 /* 200 ms for long/repeated cmds, in case of unexpected NAs */ +#define SER_D1 0x004 /* 1.5 sec. */ +#define SER_D3 0x008 /* 3 sec. (default) */ +#define SER_AA 0x010 /* alert aware set */ +#define SER_CC 0x020 /* capability check ign set */ +#define SER_CS 0x040 /* command set ign set */ +#define SER_TO 0x080 /* timeout allowed */ +#define SER_HA 0x100 /* handle asterisk */ + + +/* sets of the above (don't test against them, obviously */ + +/* + * Some cmd codes to ignore (nut doesn't expose those, though the driver might + * use them internally (e.g. [a]). If you decide to support them at some + * point, remember about removing them from here ! + */ +#define APC_UNR_CMDS "\032\177~')-+8QRYayz" + /* --------------- */ /* status bits */ -#define APC_STAT_CAL 1 /* calibration */ -#define APC_STAT_TRIM 2 /* SmartTrim */ -#define APC_STAT_BOOST 4 /* SmartBoost */ -#define APC_STAT_OL 8 /* on line */ -#define APC_STAT_OB 16 /* on battery */ -#define APC_STAT_OVER 32 /* overload */ -#define APC_STAT_LB 64 /* low battery */ -#define APC_STAT_RB 128 /* replace battery */ +#define APC_STAT_CAL 0x01 /* calibration */ +#define APC_STAT_TRIM 0x02 /* SmartTrim */ +#define APC_STAT_BOOST 0x04 /* SmartBoost */ +#define APC_STAT_OL 0x08 /* on line */ +#define APC_STAT_OB 0x10 /* on battery */ +#define APC_STAT_OVER 0x20 /* overload */ +#define APC_STAT_LB 0x40 /* low battery */ +#define APC_STAT_RB 0x80 /* replace battery */ -/* serial protocol: special commands - initialization and such */ +/* + * serial protocol: special commands - initialization and such + * these are not exposed as instant commands + */ #define APC_STATUS 'Q' #define APC_GOSMART 'Y' #define APC_GODUMB 'R' #define APC_CMDSET 'a' -#define APC_CAPABILITY 26 /* ^Z */ +#define APC_CAPS '\032' /* ^Z */ #define APC_NEXTVAL '-' +#define APC_FW_OLD 'V' +#define APC_FW_NEW 'b' -/* --------------- */ +#define APC_LBUF 512 +#define APC_SBUF 32 -/* Driver command table flag values */ +/* default a.w.d. value / regex format for command '@' */ +#define APC_AWDDEF "000" +#define APC_AWDFMT "^[0-9]{1,3}$" -#define APC_POLL 0x0001 /* Poll this variable regularly */ -#define APC_PRESENT 0x0004 /* Capability seen on this UPS */ +/* maximum number of supported sdtype methods + regex format*/ +#define APC_SDMAX "5" +#define APC_SDFMT "^[0-5]$" -#define APC_RW 0x0010 /* read-write variable */ -#define APC_ENUM 0x0020 /* enumerated type */ -#define APC_STRING 0x0040 /* string */ - -#define APC_NASTY 0x0100 /* Nasty command - take care */ -#define APC_REPEAT 0x0200 /* Command needs sending twice */ - -#define APC_FORMATMASK 0xFF0000 /* Mask for apc data formats */ - -#define APC_F_PERCENT 0x020000 /* Data in a percent format */ -#define APC_F_VOLT 0x030000 /* Data in a voltage format */ -#define APC_F_AMP 0x040000 /* Data in a current/amp format */ -#define APC_F_CELSIUS 0x050000 /* Data in a temp/C format */ -#define APC_F_HEX 0x060000 /* Data in a hex number format */ -#define APC_F_DEC 0x070000 /* Data in a decimal format */ -#define APC_F_SECONDS 0x100000 /* Time in seconds */ -#define APC_F_MINUTES 0x110000 /* Time in minutes */ -#define APC_F_HOURS 0x120000 /* Time in hours */ -#define APC_F_REASON 0x130000 /* Reason of transfer */ -#define APC_F_LEAVE 0 /* Just pass this through */ - -typedef struct { - const char *name; /* the variable name */ - unsigned int flags; /* various flags */ - char cmd; /* command character */ -} apc_vartab_t; - -apc_vartab_t apc_vartab[] = { - - { "ups.firmware.old", 0, 'V' }, - { "ups.firmware", 0, 'b' }, - { "ups.firmware.aux", 0, 'v' }, - { "ups.model", 0, 0x01 }, - - { "ups.serial", 0, 'n' }, - { "ups.mfr.date", 0, 'm' }, - - { "ups.temperature", APC_POLL|APC_F_CELSIUS, 'C' }, - { "ups.load", APC_POLL|APC_F_PERCENT, 'P' }, - - { "ups.test.interval", APC_F_HOURS, 'E' }, - { "ups.test.result", APC_POLL, 'X' }, - - { "ups.delay.start", APC_F_SECONDS, 'r' }, - { "ups.delay.shutdown", APC_F_SECONDS, 'p' }, - - { "ups.id", APC_STRING, 'c' }, - - { "ups.contacts", APC_POLL|APC_F_HEX, 'i' }, - { "ups.display.language", - 0, 0x0C }, - - { "input.voltage", APC_POLL|APC_F_VOLT, 'L' }, - { "input.frequency", APC_POLL|APC_F_DEC, 'F' }, - { "input.sensitivity", 0, 's' }, - { "input.quality", APC_POLL|APC_F_HEX, '9' }, - - { "input.transfer.low", APC_F_VOLT, 'l' }, - { "input.transfer.high", - APC_F_VOLT, 'u' }, - { "input.transfer.reason", - APC_POLL|APC_F_REASON, 'G' }, - - { "input.voltage.maximum", - APC_POLL|APC_F_VOLT, 'M' }, - { "input.voltage.minimum", - APC_POLL|APC_F_VOLT, 'N' }, - - { "output.current", APC_POLL|APC_F_AMP, '/' }, - { "output.voltage", APC_POLL|APC_F_VOLT, 'O' }, - { "output.voltage.nominal", - APC_F_VOLT, 'o' }, - - { "ambient.humidity", APC_POLL|APC_F_PERCENT, 'h' }, - { "ambient.humidity.high", - APC_F_PERCENT, '{' }, - { "ambient.humidity.low", - APC_F_PERCENT, '}' }, - - { "ambient.temperature", - APC_POLL|APC_F_CELSIUS, 't' }, - { "ambient.temperature.high", - APC_F_CELSIUS, '[' }, - { "ambient.temperature.low", - APC_F_CELSIUS, ']' }, - - { "battery.date", APC_STRING, 'x' }, - - { "battery.charge", APC_POLL|APC_F_PERCENT, 'f' }, - { "battery.charge.restart", - APC_F_PERCENT, 'e' }, - - { "battery.voltage", APC_POLL|APC_F_VOLT, 'B' }, - { "battery.voltage.nominal", - 0, 'g' }, - - { "battery.runtime", APC_POLL|APC_F_MINUTES, 'j' }, - { "battery.runtime.low", - APC_F_MINUTES, 'q' }, - - { "battery.packs", APC_F_DEC, '>' }, - { "battery.packs.bad", APC_F_DEC, '<' }, - { "battery.alarm.threshold", - 0, 'k' }, - /* todo: - - I = alarm enable (hex field) - split into alarm.n.enable - J = alarm status (hex field) - split into alarm.n.status - - 0x15 = output voltage selection (APC_F_VOLT) - 0x5C = load power (APC_POLL|APC_F_PERCENT) - - */ - - {NULL, 0, 0}, -}; - -/* ------ instant commands ------ */ - -#define APC_CMD_FPTEST 'A' -#define APC_CMD_CALTOGGLE 'D' -#define APC_CMD_SHUTDOWN 'K' -#define APC_CMD_SOFTDOWN 'S' -#define APC_CMD_GRACEDOWN '@' -#define APC_CMD_SIMPWF 'U' -#define APC_CMD_BTESTTOGGLE 'W' -#define APC_CMD_OFF 'Z' - -#define APC_CMD_ON 0x0E /* ^N */ -#define APC_CMD_BYPTOGGLE '^' - -typedef struct { - const char *name; - int flags; - char cmd; -} apc_cmdtab_t; - -apc_cmdtab_t apc_cmdtab[] = -{ - { "load.off", APC_NASTY|APC_REPEAT, APC_CMD_OFF }, - { "load.on", APC_REPEAT, APC_CMD_ON }, - - { "test.panel.start", 0, APC_CMD_FPTEST }, - - { "test.failure.start", 0, APC_CMD_SIMPWF }, - - { "test.battery.start", 0, APC_CMD_BTESTTOGGLE }, - { "test.battery.stop", 0, APC_CMD_BTESTTOGGLE }, - - { "shutdown.return.grace", - APC_NASTY, APC_CMD_GRACEDOWN }, - { "shutdown.return", APC_NASTY, APC_CMD_SOFTDOWN }, - { "shutdown.stayoff", APC_NASTY|APC_REPEAT, APC_CMD_SHUTDOWN }, - - { "calibrate.start", 0, APC_CMD_CALTOGGLE }, - { "calibrate.stop", 0, APC_CMD_CALTOGGLE }, - - { "bypass.start", 0, APC_CMD_BYPTOGGLE }, - { "bypass.stop", 0, APC_CMD_BYPTOGGLE }, - - { NULL, 0, 0 } -}; - -/* compatibility with hardware that doesn't do APC_CMDSET ('a') */ - -struct { - const char *firmware; - const char *cmdchars; - int flags; -} compat_tab[] = { - /* APC Matrix */ - { "0XI", "789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, - { "0XM", "789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, - { "0ZI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, - { "5UI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, - { "5ZM", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, - /* APC600 */ - { "6QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "6QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "6TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "6TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - /* SmartUPS 900 */ - { "7QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "7QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "7TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "7TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - /* SmartUPS 900I */ - { "7II", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, - /* SmartUPS 2000I */ - { "9II", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, - { "9GI", "79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, - /* SmartUPS 1250 */ - { "8QD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "8QI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "8TD", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - { "8TI", "79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, - /* CS 350 */ - { "5.4.D", "\1ABPQRSUYbdfgjmnx9", 0 }, - /* Smart-UPS 600 */ - { "D9", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - { "D8", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - { "D7", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - { "D6", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - { "D5", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - { "D4", "789ABCEFGKLMNOPQRSUVWXYZ", 0 }, - - { NULL, NULL, 0 }, -}; +#endif diff --git a/drivers/apcsmart_tabs.c b/drivers/apcsmart_tabs.c new file mode 100644 index 0000000..7b5c3cd --- /dev/null +++ b/drivers/apcsmart_tabs.c @@ -0,0 +1,155 @@ +/* apcsmart_tabs.c - common tables for APC smart protocol units + * + * Copyright (C) 1999 Russell Kroll + * (C) 2000 Nigel Metheringham + * (C) 2011 Michal Soltys + * + * 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 + */ + +#include "apcsmart_tabs.h" + +/* APC_MULTI variables *must* be listed in order of preference */ +apc_vartab_t apc_vartab[] = { + + { "ups.temperature", 'C', APC_POLL|APC_F_CELSIUS }, + { "ups.load", 'P', APC_POLL|APC_F_PERCENT }, + { "ups.test.interval", 'E', APC_F_HOURS }, + { "ups.test.result", 'X', APC_POLL }, + { "ups.delay.start", 'r', APC_F_SECONDS }, + { "ups.delay.shutdown", 'p', APC_F_SECONDS }, + { "ups.id", 'c', APC_STRING }, + { "ups.contacts", 'i', APC_POLL|APC_F_HEX }, + { "ups.display.language", '\014', 0 }, + { "input.voltage", 'L', APC_POLL|APC_F_VOLT }, + { "input.frequency", 'F', APC_POLL|APC_F_DEC }, + { "input.sensitivity", 's', 0 }, + { "input.quality", '9', APC_POLL|APC_F_HEX }, + { "input.transfer.low", 'l', APC_F_VOLT }, + { "input.transfer.high", 'u', APC_F_VOLT }, + { "input.transfer.reason", 'G', APC_POLL|APC_F_REASON }, + { "input.voltage.maximum", 'M', APC_POLL|APC_F_VOLT }, + { "input.voltage.minimum", 'N', APC_POLL|APC_F_VOLT }, + { "output.current", '/', APC_POLL|APC_F_AMP }, + { "output.voltage", 'O', APC_POLL|APC_F_VOLT }, + { "output.voltage.nominal", 'o', APC_F_VOLT }, + { "ambient.humidity", 'h', APC_POLL|APC_F_PERCENT }, + { "ambient.humidity.high", '{', APC_F_PERCENT }, + { "ambient.humidity.low", '}', APC_F_PERCENT }, + { "ambient.temperature", 't', APC_POLL|APC_F_CELSIUS }, + { "ambient.temperature.high", '[', APC_F_CELSIUS }, + { "ambient.temperature.low", ']', APC_F_CELSIUS }, + { "battery.date", 'x', APC_STRING }, + { "battery.charge", 'f', APC_POLL|APC_F_PERCENT }, + { "battery.charge.restart", 'e', APC_F_PERCENT }, + { "battery.voltage", 'B', APC_POLL|APC_F_VOLT }, + { "battery.voltage.nominal", 'g', 0 }, + { "battery.runtime", 'j', APC_POLL|APC_F_MINUTES }, + { "battery.runtime.low", 'q', APC_F_MINUTES }, + { "battery.packs", '>', APC_F_DEC }, + { "battery.packs.bad", '<', APC_F_DEC }, + { "battery.alarm.threshold", 'k', 0 }, + { "ups.serial", 'n', 0 }, + { "ups.mfr.date", 'm', 0 }, + { "ups.model", '\001', 0 }, + { "ups.firmware.aux", 'v', 0 }, + { "ups.firmware", 'b', APC_MULTI }, + { "ups.firmware", 'V', APC_MULTI }, + + { 0, 0, 0 } + /* todo: + + I = alarm enable (hex field) - split into alarm.n.enable + J = alarm status (hex field) - split into alarm.n.status + + 0x15 = output voltage selection (APC_F_VOLT) + 0x5C = load power (APC_POLL|APC_F_PERCENT) + + */ +}; + +/* + * apc commands mapped to nut's instant commands extra values are either + * exactly 2-char prefix, or longer than 2-char extended regex + */ +apc_cmdtab_t apc_cmdtab[] = { + { "test.panel.start", 0, APC_CMD_FPTEST, 0 }, + { "test.failure.start", 0, APC_CMD_SIMPWF, 0 }, + { "test.battery.start", 0, APC_CMD_BTESTTOGGLE, 0 }, + { "test.battery.stop", 0, APC_CMD_BTESTTOGGLE, 0 }, + { "shutdown.return", "^at:[0-9]{1,3}$", + APC_CMD_GRACEDOWN, APC_NASTY }, + { "shutdown.return", "cs", APC_CMD_SOFTDOWN, APC_NASTY }, + { "shutdown.return", 0, APC_CMD_SOFTDOWN, APC_NASTY }, + { "shutdown.stayoff", 0, APC_CMD_SHUTDOWN, APC_NASTY|APC_REPEAT }, + { "load.off", 0, APC_CMD_OFF, APC_NASTY|APC_REPEAT }, + { "load.on", 0, APC_CMD_ON, APC_REPEAT }, + { "bypass.start", 0, APC_CMD_BYPTOGGLE, 0 }, + { "bypass.stop", 0, APC_CMD_BYPTOGGLE, 0 }, + { "calibrate.start", 0, APC_CMD_CALTOGGLE, 0 }, + { "calibrate.stop", 0, APC_CMD_CALTOGGLE, 0 }, + + { 0, 0, 0, 0 } +}; + +/* compatibility with hardware that doesn't do APC_CMDSET ('a') */ +apc_compattab_t apc_compattab[] = { + /* APC Matrix */ + { "0XI", "@789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, + { "0XM", "@789ABCDEFGKLMNOPQRSTUVWXYZcefgjklmnopqrsuwxz/<>\\^\014\026", 0 }, + { "0ZI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + { "5UI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + { "5ZM", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz/<>", 0 }, + /* APC600 */ + { "6QD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6QI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6TD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "6TI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* SmartUPS 900 */ + { "7QD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7QI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7TD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "7TI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* SmartUPS 900I */ + { "7II", "@79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + /* SmartUPS 2000I */ + { "9II", "@79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + { "9GI", "@79ABCEFGKLMNOPQSUVWXYZcfg", 0 }, + /* SmartUPS 1250 */ + { "8QD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8QI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8TD", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + { "8TI", "@79ABCDEFGKLMNOPQRSUVWXYZcefgjklmnopqrsuxz", 0 }, + /* CS 350 */ + { "5.4.D", "@\1ABPQRSUYbdfgjmnx9", 0 }, + /* Smart-UPS 600 */ + { "D9", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D8", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D7", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D6", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D5", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + { "D4", "@789ABCEFGKLMNOPQRSUVWXYZ", 0 }, + + { 0, 0, 0 } +}; + +upsdrv_info_t apc_tab_info = { + "APC command table", + APC_TABLE_VERSION, + 0, + 0, + { 0 } +}; + diff --git a/drivers/apcsmart_tabs.h b/drivers/apcsmart_tabs.h new file mode 100644 index 0000000..c49ce9e --- /dev/null +++ b/drivers/apcsmart_tabs.h @@ -0,0 +1,100 @@ +/* + * apcsmart_tabs.h - tables for apcsmart driver + * + * Copyright (C) 1999 Russell Kroll + * (C) 2000 Nigel Metheringham + * (C) 2011 Michal Soltys + * + * 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 + */ + +#ifndef __apcsmart_tabs_h__ +#define __apcsmart_tabs_h__ + +#include "main.h" + +#define APC_TABLE_VERSION "version 3.0" + +/* common flags */ + +#define APC_PRESENT 0x00000001 /* capability seen on this UPS */ + +/* instant commands' flags */ + +#define APC_NASTY 0x00000002 /* Nasty command - must be reconfirmed */ +#define APC_REPEAT 0x00000004 /* Command needs sending twice */ + +/* variables' flags */ + +#define APC_POLL 0x00000100 /* poll this variable regularly */ +#define APC_RW 0x00000200 /* read-write variable */ +#define APC_ENUM 0x00000400 /* enumerated type variable */ +#define APC_STRING 0x00000800 /* string variable */ +#define APC_MULTI 0x00001000 /* there're other vars like that */ +#define APC_DEPR 0x00002000 /* deprecated variable */ + +/* variables' format */ + +#define APC_F_MASK 0xFF000000 /* Mask for apc data formats */ +#define APC_F_PERCENT 0x01000000 /* Data in a percent format */ +#define APC_F_VOLT 0x02000000 /* Data in a voltage format */ +#define APC_F_AMP 0x03000000 /* Data in a current/amp format */ +#define APC_F_CELSIUS 0x04000000 /* Data in a temp/C format */ +#define APC_F_HEX 0x05000000 /* Data in a hex number format */ +#define APC_F_DEC 0x06000000 /* Data in a decimal format */ +#define APC_F_SECONDS 0x07000000 /* Time in seconds */ +#define APC_F_MINUTES 0x08000000 /* Time in minutes */ +#define APC_F_HOURS 0x09000000 /* Time in hours */ +#define APC_F_REASON 0x10000000 /* Reason of transfer */ +#define APC_F_LEAVE 0x00000000 /* Just pass this through */ + +/* instant commands */ + +#define APC_CMD_OFF 'Z' +#define APC_CMD_ON '\016' /* ^N */ +#define APC_CMD_FPTEST 'A' +#define APC_CMD_SIMPWF 'U' +#define APC_CMD_BTESTTOGGLE 'W' +#define APC_CMD_GRACEDOWN '@' +#define APC_CMD_SOFTDOWN 'S' +#define APC_CMD_SHUTDOWN 'K' +#define APC_CMD_CALTOGGLE 'D' +#define APC_CMD_BYPTOGGLE '^' + + +typedef struct { + const char *name; /* the variable name */ + char cmd; /* variable character */ + unsigned int flags; /* various flags */ +} apc_vartab_t; + +typedef struct { + const char *name, *ext; + char cmd; + int flags; +} apc_cmdtab_t; + +typedef struct { + const char *firmware; + const char *cmdchars; + int flags; +} apc_compattab_t; + +extern apc_vartab_t apc_vartab[]; +extern apc_cmdtab_t apc_cmdtab[]; +extern apc_compattab_t apc_compattab[]; +extern upsdrv_info_t apc_tab_info; + +#endif diff --git a/drivers/bcmxcp.c b/drivers/bcmxcp.c index d2e0f5c..1bc8b78 100644 --- a/drivers/bcmxcp.c +++ b/drivers/bcmxcp.c @@ -19,6 +19,9 @@ ojw0000 2007Apr5 Oliver Wilcock - modified to control individual load segments (outlet.2.shutdown.return) on Powerware PW5125. + Modified to support setvar for outlet.n.delay.start by Rich Wrenn (RFW) 9-3-11. + Modified to support setvar for outlet.n.delay.shutdown by Arnaud Quette, 9-12-11 + 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 @@ -109,18 +112,22 @@ TODO List: Implement support for Password Authorization (XCP spec, §4.3.2) - Implement support for settable variables (upsh.setvar) + Complete support for settable variables (upsh.setvar) */ #include "main.h" #include /* For ldexp() */ #include /*for FLT_MAX */ +#include "nut_stdint.h" /* for uint8_t, uint16_t, uint32_t, ... */ #include "bcmxcp_io.h" #include "bcmxcp.h" #define DRIVER_NAME "BCMXCP UPS driver" -#define DRIVER_VERSION "0.24" +#define DRIVER_VERSION "0.25" + +#define MAX_NUT_NAME_LENGTH 128 +#define NUT_OUTLET_POSITION 7 /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -148,6 +155,7 @@ static void init_ups_alarm_map(const unsigned char *map, unsigned char len); static void decode_meter_map_entry(const unsigned char *entry, const unsigned char format, char* value); static int init_outlet(unsigned char len); static int instcmd(const char *cmdname, const char *extra); +static int setvar (const char *varname, const char *val); const char *FreqTol[3] = {"+/-2%", "+/-5%", "+/-7"}; @@ -881,8 +889,8 @@ int init_outlet(unsigned char len) res = command_read_sequence(PW_OUT_MON_BLOCK_REQ, answer); if (res <= 0) fatal_with_errno(EXIT_FAILURE, "Could not communicate with the ups"); -else - upsdebugx(1, "init_outlet(%i), res=%i", len, res); + else + upsdebugx(1, "init_outlet(%i), res=%i", len, res); num_outlet = answer[iIndex++]; upsdebugx(2, "Number of outlets: %d\n", num_outlet); @@ -906,12 +914,16 @@ else upsdebugx(2, "Auto delay off: %d\n", auto_dly_off); snprintf(outlet_name, sizeof(outlet_name)-1, "outlet.%d.delay.shutdown", num); dstate_setinfo(outlet_name, "%d", auto_dly_off); + dstate_setflags(outlet_name, ST_FLAG_RW | ST_FLAG_STRING); + dstate_setaux(outlet_name, 5); auto_dly_on = get_word(answer+iIndex); iIndex += 2; upsdebugx(2, "Auto delay on: %d\n", auto_dly_on); snprintf(outlet_name, sizeof(outlet_name)-1, "outlet.%d.delay.start", num); dstate_setinfo(outlet_name, "%d", auto_dly_on); + dstate_setflags(outlet_name, ST_FLAG_RW | ST_FLAG_STRING); + dstate_setaux(outlet_name, 5); } return num_outlet; @@ -1221,6 +1233,7 @@ void upsdrv_initinfo(void) dstate_addcmd("test.battery.start"); upsh.instcmd = instcmd; + upsh.setvar = setvar; return; } @@ -1465,9 +1478,11 @@ void upsdrv_shutdown(void) static int instcmd(const char *cmdname, const char *extra) { - unsigned char answer[5], cbuf[6]; - + unsigned char answer[128], cbuf[6]; + char varname[32]; + const char *varvalue = NULL; int res, sec; + int sddelay = 0x03; /* outlet off in 3 seconds, by default */ upsdebugx(1, "entering instcmd(%s)", cmdname); @@ -1480,9 +1495,15 @@ static int instcmd(const char *cmdname, const char *extra) sleep(1); /* Need to. Have to wait at least 0,25 sec max 16 sec */ + /* Get the shutdown delay, if any */ + snprintf(varname, sizeof(varname)-1, "outlet.%c.delay.shutdown", cmdname[7]); + if ((varvalue = dstate_getinfo(varname)) != NULL) { + sddelay = atoi(dstate_getinfo(varname)); + } + cbuf[0] = PW_LOAD_OFF_RESTART; - cbuf[1] = 0x03; /* outlet off in 3 seconds */ - cbuf[2] = 0x00; /* high byte of the 2 byte time argument */ + cbuf[1] = sddelay & 0xff; + cbuf[2] = sddelay >> 8; /* high byte of the 2 byte time argument */ cbuf[3] = ( '1' == cmdname[7] ? 0x01 : 0x02); /* which outlet load segment? Assumes '1' or '2' at position 8 of the command string. */ /* ojw00000 the following copied from command "shutdown.return" below 2007Apr5 */ @@ -1586,7 +1607,7 @@ static int instcmd(const char *cmdname, const char *extra) break; } case 0x33: { - upslogx(LOG_NOTICE, "[%s] disbled by front panel", cmdname); + upslogx(LOG_NOTICE, "[%s] disabled by front panel", cmdname); return STAT_INSTCMD_UNKNOWN; break; } @@ -1596,7 +1617,8 @@ static int instcmd(const char *cmdname, const char *extra) break; } default: { - upslogx(LOG_NOTICE, "[%s] not supported", cmdname); + upslogx(LOG_NOTICE, "[%s] not supported (code %c)", + cmdname, (unsigned char) answer[0]); return STAT_INSTCMD_UNKNOWN; break; } @@ -1667,3 +1689,96 @@ void upsdrv_makevartable(void) addvar(VAR_VALUE, "baud_rate", "Specify communication speed (ex: 9600)"); } +int setvar (const char *varname, const char *val) +{ + unsigned char answer[128], cbuf[5]; + char namebuf[MAX_NUT_NAME_LENGTH]; + int res, sec, outlet_num; + int onOff_setting = PW_AUTO_OFF_DELAY; + + upsdebugx(1, "entering setvar(%s, %s)", varname, val); + + strncpy(namebuf, varname, sizeof(namebuf)); + namebuf[NUT_OUTLET_POSITION] = 'n'; /* Assumes a maximum of 9 outlets */ + + if ( (strcasecmp(namebuf, "outlet.n.delay.start")) && + (strcasecmp(namebuf, "outlet.n.delay.shutdown")) ) { + return STAT_SET_UNKNOWN; + } + + if (outlet_block_len <= 8) { + return STAT_SET_INVALID; + } + + if (!strcasecmp(namebuf, "outlet.n.delay.start")) { + onOff_setting = PW_AUTO_ON_DELAY; + } + + send_write_command(AUTHOR, 4); + /* Need to. Have to wait at least 0.25 sec max 16 sec */ + sleep (1); + + outlet_num = varname[NUT_OUTLET_POSITION] - '0'; + if (outlet_num < 1 || outlet_num > 9) { + return STAT_SET_INVALID; + } + + sec = atoi(val); + /* Check value: + * 0-32767 are valid values + * -1 means no Automatic off or restart + * for Auto Off Delay: + * 0-30 are valid but ill-advised */ + if (sec < -1 || sec > 0x7FFF) { + return STAT_SET_INVALID; + } + + cbuf[0] = PW_SET_OUTLET_COMMAND; /* Cmd */ + cbuf[1] = onOff_setting; /* Set Auto Off (1) or On (2) Delay */ + cbuf[2] = outlet_num; /* Outlet number */ + cbuf[3] = sec&0xff; /* Delay in seconds LSB */ + cbuf[4] = sec>>8; /* Delay in seconds MSB */ + + res = command_write_sequence(cbuf, 5, answer); + if (res <= 0) { + upslogx(LOG_ERR, "Short read from UPS"); + dstate_datastale(); + return -1; + } + + switch ((unsigned char) answer[0]) { + + case 0x31: { + upslogx(LOG_NOTICE,"Outlet %d %s delay set to %d sec", + outlet_num, (onOff_setting == PW_AUTO_ON_DELAY)?"start":"shutdown", sec); + dstate_setinfo(varname, "%d", sec); + return STAT_SET_HANDLED; + break; + } + case 0x33: { + upslogx(LOG_NOTICE, "Set [%s] failed due to UPS busy", varname); + /* TODO: we should probably retry... */ + return STAT_SET_UNKNOWN; + break; + } + case 0x35: { + upslogx(LOG_NOTICE, "Set [%s %s] failed due to parameter out of range", varname, val); + return STAT_SET_UNKNOWN; + break; + } + case 0x36: { + upslogx(LOG_NOTICE, "Set [%s %s] failed due to invalid parameter", varname, val); + return STAT_SET_UNKNOWN; + break; + } + default: { + upslogx(LOG_NOTICE, "Set [%s] not supported", varname); + return STAT_SET_FAILED; + break; + } + } + + return STAT_SET_INVALID; +} + + diff --git a/drivers/bcmxcp.h b/drivers/bcmxcp.h index bb811f4..beb19fe 100644 --- a/drivers/bcmxcp.h +++ b/drivers/bcmxcp.h @@ -42,6 +42,24 @@ #define PW_INIT_BAT_TEST (unsigned char)0xB1 /* Initiate battery test command. length 3 */ #define PW_INIT_SYS_TEST (unsigned char)0xB2 /* Initiate general system test command. length 2 */ +/* Define the XCP ACK block responses */ +#define XCPRESP_ACK 0x31 /* Accepted and executed */ +#define XCPRESP_NOT_IMPL 0x32 /* Recognized, but not implemented */ +#define XCPRESP_BUSY 0x33 /* Recognized, but Busy and not executed */ +#define XCPRESP_UNRECOGN 0x34 /* Unrecognized cmd */ +#define XCPRESP_OUT_RANGE 0x35 /* Parameter was out of range; not executed */ +#define XCPRESP_PRM_INVLD 0x36 /* Parameter invalid; not executed */ +#define XCPRESP_PRM_ADJST 0x37 /* Parameter adjusted to nearest good value */ +#define XCPRESP_PRM_RDONLY 0x38 /* Parameter is Read-only - cannot be written (at this privilege level) */ + +/* Outlet operations */ +#define PW_ALL_OUTLETS 0 +#define PW_AUTO_OFF_DELAY 1 +#define PW_AUTO_ON_DELAY 2 +/* 0 means Abort countdown */ +#define PW_TURN_OFF_DELAY 3 +#define PW_TURN_ON_DELAY 4 + /* Config block offsets */ #define BCMXCP_CONFIG_BLOCK_MACHINE_TYPE_CODE 0 #define BCMXCP_CONFIG_BLOCK_MODEL_NUMBER 2 diff --git a/drivers/bcmxcp_ser.c b/drivers/bcmxcp_ser.c index b03e0c1..0c7e6b3 100644 --- a/drivers/bcmxcp_ser.c +++ b/drivers/bcmxcp_ser.c @@ -197,7 +197,7 @@ int get_answer(unsigned char *data, unsigned char command) static int command_sequence(unsigned char *command, int command_length, unsigned char *answer) { int bytes_read, retry = 0; - + while (retry++ < PW_MAX_TRY) { if (retry == PW_MAX_TRY) { diff --git a/drivers/bestfcom.c b/drivers/bestfcom.c index 859ea7c..8a85e6d 100644 --- a/drivers/bestfcom.c +++ b/drivers/bestfcom.c @@ -260,13 +260,10 @@ void upsdrv_updateinfo(void) double ampsout=0.0, vbatt=0.0, battpercent=0.0, loadpercent=0.0, upstemp=0.0, acfreq=0.0; - char date[9], time[9], tmp[32]; + char tmp[32]; upsdebugx(3, "f response: %d %s", (int)strlen(fstring), fstring); - date[0]='\0'; - time[0]='\0'; - /* Inverter status. 0=off 1=on */ inverter = bcd2i(&fstring[16], 2); diff --git a/drivers/bestpower-mib.c b/drivers/bestpower-mib.c index d3bcc57..29c1926 100644 --- a/drivers/bestpower-mib.c +++ b/drivers/bestpower-mib.c @@ -29,6 +29,10 @@ * http://powerquality.eaton.com/Support/Software-Drivers/Downloads/connectivity-firmware/bestpwr2.mib */ +/* TODO: find the right sysOID for this MIB + * #define BESTPOWER_SYSOID ".1.3.6.1.4.1.2947???" + */ + static info_lkp_t bestpower_power_status[] = { { 1, "OL" }, { 2, "OB" }, diff --git a/drivers/blazer.c b/drivers/blazer.c index 5179be5..0b3cc8f 100644 --- a/drivers/blazer.c +++ b/drivers/blazer.c @@ -75,6 +75,7 @@ static const struct { { "megatec", "Q1\r", "F\r", "I\r" }, { "mustek", "QS\r", "F\r", "I\r" }, { "megatec/old", "D\r", "F\r", "I\r" }, + { "zinto", "Q1\r", "F\r", "FW?\r" }, { NULL } }; @@ -472,6 +473,8 @@ void blazer_makevartable(void) addvar(VAR_FLAG, "norating", "Skip reading rating information from UPS"); addvar(VAR_FLAG, "novendor", "Skip reading vendor information from UPS"); + + addvar(VAR_FLAG, "protocol", "Preselect communication protocol (skip autodetection)"); } @@ -594,12 +597,18 @@ static void blazer_initbattery(void) void blazer_initinfo(void) { + const char *protocol = getval("protocol"); int retry; for (proto = 0; command[proto].status; proto++) { int ret; + if (protocol && strcasecmp(protocol, command[proto].name)) { + upsdebugx(2, "Skipping %s protocol...", command[proto].name); + continue; + } + upsdebugx(2, "Trying %s protocol...", command[proto].name); for (retry = 1; retry <= MAXTRIES; retry++) { diff --git a/drivers/eaton-mib.c b/drivers/eaton-mib.c index 18fcf55..5d01a28 100644 --- a/drivers/eaton-mib.c +++ b/drivers/eaton-mib.c @@ -33,6 +33,7 @@ */ #define APHEL1_OID_MIB ".1.3.6.1.4.1.17373" +#define APHEL1_SYSOID APHEL1_OID_MIB #define APHEL1_OID_MODEL_NAME ".1.3.6.1.4.1.17373.3.1.1.0" #define APHEL1_OID_FIRMREV ".1.3.6.1.4.1.17373.3.1.2.0" #define APHEL1_OID_DEVICE_NAME ".1.3.6.1.4.1.17373.3.1.3.0" @@ -83,9 +84,9 @@ static snmp_info_t eaton_aphel_genesisII_mib[] = { /* APHEL PDU-MIB - Revelation MIB (Managed ePDU) * ********************************************* */ -#define AR_BASE_OID ".1.3.6.1.4.1.534.6.6.6" - -#define APHEL2_OID_MODEL_NAME AR_OID_MODEL_NAME +#define AR_BASE_OID ".1.3.6.1.4.1.534.6.6.6" +#define APHEL2_SYSOID AR_BASE_OID +#define APHEL2_OID_MODEL_NAME AR_OID_MODEL_NAME #define AR_OID_MODEL_NAME AR_BASE_OID ".1.1.12.0" #define AR_OID_DEVICE_NAME AR_BASE_OID ".1.1.13.0" @@ -207,5 +208,138 @@ static snmp_info_t eaton_aphel_revelation_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; -mib2nut_info_t aphel_genesisII = { "aphel_genesisII", EATON_APHEL_MIB_VERSION, "", APHEL1_OID_MODEL_NAME, eaton_aphel_genesisII_mib }; -mib2nut_info_t aphel_revelation = { "aphel_revelation", EATON_APHEL_MIB_VERSION, "", APHEL2_OID_MODEL_NAME, eaton_aphel_revelation_mib }; +/* Eaton PDU-MIB - Marlin MIB + * ************************** */ + +#define EATON_MARLIN_MIB_VERSION "0.05" +#define EATON_MARLIN_SYSOID ".1.3.6.1.4.1.534.6.6.7" +#define EATON_MARLIN_OID_MODEL_NAME ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0" + +static info_lkp_t marlin_outlet_status_info[] = { + { 0, "off" }, + { 1, "on" }, + { 2, "pendingOff" }, /* transitional status */ + { 3, "pendingOn" }, /* transitional status */ + { 0, NULL } +}; + +/* Snmp2NUT lookup table for Eaton Marlin MIB */ +static snmp_info_t eaton_marlin_mib[] = { + /* Device page */ + { "device.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "device.model", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0", + "Eaton Powerware ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.4.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "device.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + /* FIXME: need RFC validation on this variable + * { "device.part", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.3.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, */ + + /* UPS page */ + { "ups.mfr", ST_FLAG_STRING, SU_INFOSIZE, NULL, "EATON", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "ups.model", ST_FLAG_STRING, SU_INFOSIZE, "1.3.6.1.4.1.534.6.6.7.1.2.1.2.0", + "Eaton Powerware ePDU", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + + /* FIXME: use unitName.0 (ePDU)? + * { "ups.id", ST_FLAG_STRING, SU_INFOSIZE, AR_OID_DEVICE_NAME, + "unknown", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, */ + { "ups.serial", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.4.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + { "ups.firmware", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.5.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL }, + { "ups.type", ST_FLAG_STRING, SU_INFOSIZE, NULL, "pdu", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + /* TODO: + * The below possibly requires (?) the use of + * int snprint_hexstring(char *buf, size_t buf_len, const u_char *, size_t); + * { "ups.macaddr", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.2.1.2.2.1.6.2", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + * + date reformating callback + * 2011-8-29,16:27:25.0,+1:0 + * Hex-STRING: 07 DB 08 1D 10 0C 36 00 2B 01 00 00 + * { "ups.date", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.8.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + * { "ups.time", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.1.2.1.8.0", + "", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + */ + + /* Input page */ + { "input.phases", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.20.0", NULL, SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* inputType.0.1 singlePhase (1) iso.3.6.1.4.1.534.6.6.7.3.1.1.2.0.1 */ + { "input.frequency", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.3.1.1.3.0.1", NULL, 0, NULL, NULL }, + { "input.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.1", NULL, 0, NULL, NULL }, + /* FIXME: check multiplier */ + { "input.current", 0, 0.01, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.1", NULL, 0, NULL, NULL }, + + /* Ambient page */ + /* We use critical levels, for both temperature and humidity, + * since warning levels are also available! */ + { "ambient.temperature", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.4.0.1", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.low", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.temperature.high", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.1.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.4.0.1", NULL, SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.low", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.7.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + { "ambient.humidity.high", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.7.2.1.9.0.1", NULL, SU_FLAG_NEGINVALID | SU_FLAG_OK, NULL, NULL }, + + /* Outlet page */ + { "outlet.id", 0, 1, NULL, "0", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, NULL, "All outlets", + SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK, NULL, NULL }, + { "outlet.count", 0, 1, ".1.3.6.1.4.1.534.6.6.7.1.2.1.22.0", "0", SU_FLAG_STATIC | SU_FLAG_OK, NULL, NULL }, + /* The below ones are the same as the input.* equivalent */ + { "outlet.frequency", 0, 0.1, ".1.3.6.1.4.1.534.6.6.7.3.1.1.3.0.1", NULL, 0, NULL, NULL }, + { "outlet.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.3.2.1.3.0.1.1", NULL, 0, NULL, NULL }, + { "outlet.current", 0, 0.01, ".1.3.6.1.4.1.534.6.6.7.3.3.1.4.0.1.1", NULL, 0, NULL, NULL }, + /* There is also a .2 available (ie .1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.2) */ + { "outlet.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.4.0.1.2", NULL, 0, NULL, NULL }, + /* There is also a .2 available (ie .1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.2) */ + { "outlet.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.3.4.1.3.0.1.1", NULL, 0, NULL, NULL }, + + /* outlet template definition + * Indexes start from 1, ie outlet.1 => .1 */ + { "outlet.%i.switchable", 0, 1, ".1.3.6.1.4.1.534.6.6.7.6.6.1.3.0.%i", "yes", SU_FLAG_STATIC | SU_OUTLET, NULL, NULL }, + /* Note: the first definition is used to determine the base index (ie 0 or 1) */ + { "outlet.%i.desc", ST_FLAG_RW | ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.1.1.3.0.%i", NULL, SU_FLAG_STATIC | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, + { "outlet.%i.status", ST_FLAG_STRING, SU_INFOSIZE, ".1.3.6.1.4.1.534.6.6.7.6.6.1.2.0.%i", + NULL, SU_FLAG_OK | SU_OUTLET, &marlin_outlet_status_info[0], NULL }, + /* FIXME: or use ".1.3.6.1.4.1.534.6.6.7.6.1.1.2.0.1", though it's related to groups! */ + { "outlet.%i.id", 0, 1, NULL, "%i", SU_FLAG_STATIC | SU_FLAG_ABSENT | SU_FLAG_OK | SU_OUTLET, NULL, NULL }, + { "outlet.%i.current", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.4.1.3.0.%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.realpower", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.6.5.1.3.0.%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.voltage", 0, 0.001, ".1.3.6.1.4.1.534.6.6.7.6.3.1.2.0.%i", NULL, SU_OUTLET, NULL, NULL }, + { "outlet.%i.power", 0, 1.0, ".1.3.6.1.4.1.534.6.6.7.6.5.1.2.0.%i", NULL, SU_OUTLET, NULL, NULL }, + + /* TODO: handle statistics + * outletWh.0.1 + * outletWhTimer.0.1 + */ + + /* instant commands. */ + /* Notes: + * - load.cycle might be replaced by / mapped on shutdown.reboot + * - outletControl{Off,On,Reboot}Cmd values: + * 0-n : Timer + * -1 : Cancel + * we currently use "0", so instant On | Off | Reboot... */ + /* no counterpart found! + { "outlet.load.off", 0, DO_OFF, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "outlet.load.on", 0, DO_ON, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, + { "outlet.load.cycle", 0, DO_CYCLE, AR_OID_OUTLET_STATUS ".0", NULL, SU_TYPE_CMD, NULL, NULL }, */ + + /* TODO: handle delays */ + { "outlet.%i.load.off", 0, 0, ".1.3.6.1.4.1.534.6.6.7.6.6.1.3.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + { "outlet.%i.load.on", 0, 0, ".1.3.6.1.4.1.534.6.6.7.6.6.1.4.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + { "outlet.%i.load.cycle", 0, 0, ".1.3.6.1.4.1.534.6.6.7.6.6.1.5.0.%i", NULL, SU_TYPE_CMD | SU_OUTLET, NULL, NULL }, + + /* end of structure. */ + { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } +}; + +mib2nut_info_t aphel_genesisII = { "aphel_genesisII", EATON_APHEL_MIB_VERSION, "", APHEL1_OID_MODEL_NAME, eaton_aphel_genesisII_mib, APHEL1_SYSOID }; +mib2nut_info_t aphel_revelation = { "aphel_revelation", EATON_APHEL_MIB_VERSION, "", APHEL2_OID_MODEL_NAME, eaton_aphel_revelation_mib, APHEL2_SYSOID }; +mib2nut_info_t eaton_marlin = { "eaton_epdu", EATON_MARLIN_MIB_VERSION, "", EATON_MARLIN_OID_MODEL_NAME, eaton_marlin_mib, EATON_MARLIN_SYSOID }; + diff --git a/drivers/eaton-mib.h b/drivers/eaton-mib.h index 60b463c..4997066 100644 --- a/drivers/eaton-mib.h +++ b/drivers/eaton-mib.h @@ -6,5 +6,6 @@ extern mib2nut_info_t aphel_genesisII; extern mib2nut_info_t aphel_revelation; +extern mib2nut_info_t eaton_marlin; #endif /* EATON_MIB_H */ diff --git a/drivers/ietf-mib.c b/drivers/ietf-mib.c index ee1247d..0cc3192 100644 --- a/drivers/ietf-mib.c +++ b/drivers/ietf-mib.c @@ -30,6 +30,7 @@ /* SNMP OIDs set */ #define IETF_OID_UPS_MIB "1.3.6.1.2.1.33.1." +#define IETF_SYSOID ".1.3.6.1.2.1.33" /* #define DEBUG */ @@ -273,4 +274,4 @@ static snmp_info_t ietf_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t ietf = { "ietf", IETF_MIB_VERSION, IETF_OID_UPS_MIB "4.1.0", IETF_OID_UPS_MIB "1.1.0", ietf_mib }; +mib2nut_info_t ietf = { "ietf", IETF_MIB_VERSION, IETF_OID_UPS_MIB "4.1.0", IETF_OID_UPS_MIB "1.1.0", ietf_mib, IETF_SYSOID }; diff --git a/drivers/main.c b/drivers/main.c index aafee68..66caa36 100644 --- a/drivers/main.c +++ b/drivers/main.c @@ -358,7 +358,6 @@ void do_upsconf_args(char *confupsname, char *var, char *val) } /* everything else must be for the driver */ - storeval(var, val); } @@ -556,10 +555,6 @@ int main(int argc, char **argv) "Error: you must specify a port name in ups.conf. Try -h for help."); } - pidfn = xmalloc(SMALLBUF); - - snprintf(pidfn, SMALLBUF, "%s/%s-%s.pid", altpidpath(), progname, upsname); - upsdebugx(1, "debug level is '%d'", nut_debug_level); new_uid = get_user_pwent(user); @@ -574,7 +569,39 @@ int main(int argc, char **argv) if ((!do_forceshutdown) && (chdir(dflt_statepath()))) fatal_with_errno(EXIT_FAILURE, "Can't chdir to %s", dflt_statepath()); - setup_signals(); + /* Setup signals to communicate with driver once backgrounded. */ + if ((nut_debug_level == 0) && (!do_forceshutdown)) { + char buffer[SMALLBUF]; + + setup_signals(); + + snprintf(buffer, sizeof(buffer), "%s/%s-%s.pid", altpidpath(), progname, upsname); + + /* Try to prevent that driver is started multiple times. If a PID file */ + /* already exists, send a TERM signal to the process and try if it goes */ + /* away. If not, retry a couple of times. */ + for (i = 0; i < 3; i++) { + struct stat st; + + if (stat(buffer, &st) != 0) { + /* PID file not found */ + break; + } + + if (sendsignalfn(buffer, SIGTERM) != 0) { + /* Can't send signal to PID, assume invalid file */ + break; + } + + upslogx(LOG_WARNING, "Duplicate driver instance detected! Terminating other driver!"); + + /* Allow driver some time to quit */ + sleep(5); + } + + pidfn = xstrdup(buffer); + writepid(pidfn); /* before backgrounding */ + } /* clear out callback handler data */ memset(&upsh, '\0', sizeof(upsh)); @@ -643,7 +670,7 @@ int main(int argc, char **argv) if (nut_debug_level == 0) { background(); - writepid(pidfn); + writepid(pidfn); /* PID changes when backgrounding */ } while (!exit_flag) { diff --git a/drivers/mge-hid.c b/drivers/mge-hid.c index ccf1c9a..7c07703 100644 --- a/drivers/mge-hid.c +++ b/drivers/mge-hid.c @@ -26,7 +26,7 @@ #include "usbhid-ups.h" #include "mge-hid.h" -#define MGE_HID_VERSION "MGE HID 1.21" +#define MGE_HID_VERSION "MGE HID 1.27" /* (prev. MGE Office Protection Systems, prev. MGE UPS SYSTEMS) */ /* Eaton */ @@ -59,8 +59,12 @@ static usb_device_id_t mge_usb_device_table[] = { #endif typedef enum { - MGE_DEFAULT = 0, - MGE_EVOLUTION = 0x100, /* MGE Evolution series */ + MGE_DEFAULT_OFFLINE = 0, + MGE_PEGASUS = 0x100, + MGE_3S = 0x110, + /* All offline models have type value < 200! */ + MGE_DEFAULT = 0x200, /* for line-interactive and online models */ + MGE_EVOLUTION = 0x300, /* MGE Evolution series */ MGE_EVOLUTION_650, MGE_EVOLUTION_850, MGE_EVOLUTION_1150, @@ -70,14 +74,29 @@ typedef enum { MGE_EVOLUTION_2000, MGE_EVOLUTION_S_2500, MGE_EVOLUTION_S_3000, - MGE_PULSAR_M = 0x200, /* MGE Pulsar M series */ + MGE_PULSAR_M = 0x400, /* MGE Pulsar M series */ MGE_PULSAR_M_2200, MGE_PULSAR_M_3000, - MGE_PULSAR_M_3000_XL, - MGE_PEGASUS = 0x400 + MGE_PULSAR_M_3000_XL } models_type_t; +/* Default to line-interactive or online (ie, not offline). + * This is then overriden for offline, through mge_model_names */ static models_type_t mge_type = MGE_DEFAULT; + +/* Countries definition, for region specific settings and features */ +typedef enum { + COUNTRY_UNKNOWN = -1, + COUNTRY_EUROPE = 0, + COUNTRY_US, + /* Special European models, which also supports 200 / 208 V */ + COUNTRY_EUROPE_208, + COUNTRY_WORLDWIDE, + COUNTRY_AUSTRALIA, +} country_code_t; + +static int country_code = COUNTRY_UNKNOWN; + static char mge_scratch_buf[20]; /* The HID path 'UPS.PowerSummary.Time' reports Unix time (ie the number of @@ -279,14 +298,19 @@ info_lkp_t mge_onbatt_info[] = { { 0, "online", NULL }, { 0, NULL, NULL } }; -/* allow limiting to ups.model ~= Protection Station */ + +/* allow limiting to ups.model = Protection Station, Ellipse Eco + * and 3S (US 750 and AUS 700 only!) */ static const char *eaton_check_pegasus_fun(double value) { switch (mge_type & 0xFF00) /* Ignore model byte */ { case MGE_PEGASUS: break; - + case MGE_3S: + /* Only consider non European models */ + if (country_code != COUNTRY_EUROPE) + break; default: return NULL; } @@ -302,6 +326,22 @@ static info_lkp_t pegasus_threshold_info[] = { { 0, NULL, NULL } }; +/* Determine country using UPS.PowerSummary.Country. + * If not present: + * if PowerConverter.Output.Voltage >= 200 => "Europe" + * else default to "US" */ +static const char *eaton_check_country_fun(double value) +{ + country_code = value; + /* Return NULL, not to get the value published! */ + return NULL; +} + +static info_lkp_t eaton_check_country_info[] = { + { 0, "dummy", eaton_check_country_fun }, + { 0, NULL, NULL } +}; + /* Limit nominal output voltage according to HV or LV models */ static const char *nominal_output_voltage_fun(double value) { @@ -330,6 +370,7 @@ static const char *nominal_output_voltage_fun(double value) } break; + /* line-interactive and online support 200/208 and 220/230/240*/ /* HV models */ /* 208V */ case 200: @@ -339,6 +380,12 @@ static const char *nominal_output_voltage_fun(double value) case 200: case 208: break; + /* 230V */ + case 220: + case 230: + case 240: + if ((mge_type & 0xFF00) >= MGE_DEFAULT) + break; default: return NULL; } @@ -351,6 +398,16 @@ static const char *nominal_output_voltage_fun(double value) case 240: switch ((long)value) { + case 200: + case 208: + /* line-interactive and online also support 200 / 208 V + * So break on offline models */ + if ((mge_type & 0xFF00) < MGE_DEFAULT) + return NULL; + /* FIXME: Some European models ("5130 RT 3000") also + * support both HV values */ + if (country_code == COUNTRY_EUROPE_208) + break; case 220: case 230: case 240: @@ -369,6 +426,7 @@ static const char *nominal_output_voltage_fun(double value) } static info_lkp_t nominal_output_voltage_info[] = { + /* line-interactive, starting with Evolution, support both HV values */ /* HV models */ /* 208V */ { 200, "200", nominal_output_voltage_fun }, @@ -560,34 +618,34 @@ typedef struct { static models_name_t mge_model_names [] = { /* Ellipse models */ - { "ELLIPSE", "300", MGE_DEFAULT, "ellipse 300" }, - { "ELLIPSE", "500", MGE_DEFAULT, "ellipse 500" }, - { "ELLIPSE", "650", MGE_DEFAULT, "ellipse 650" }, - { "ELLIPSE", "800", MGE_DEFAULT, "ellipse 800" }, - { "ELLIPSE", "1200", MGE_DEFAULT, "ellipse 1200" }, + { "ELLIPSE", "300", MGE_DEFAULT_OFFLINE, "ellipse 300" }, + { "ELLIPSE", "500", MGE_DEFAULT_OFFLINE, "ellipse 500" }, + { "ELLIPSE", "650", MGE_DEFAULT_OFFLINE, "ellipse 650" }, + { "ELLIPSE", "800", MGE_DEFAULT_OFFLINE, "ellipse 800" }, + { "ELLIPSE", "1200", MGE_DEFAULT_OFFLINE, "ellipse 1200" }, /* Ellipse Premium models */ - { "ellipse", "PR500", MGE_DEFAULT, "ellipse premium 500" }, - { "ellipse", "PR650", MGE_DEFAULT, "ellipse premium 650" }, - { "ellipse", "PR800", MGE_DEFAULT, "ellipse premium 800" }, - { "ellipse", "PR1200", MGE_DEFAULT, "ellipse premium 1200" }, + { "ellipse", "PR500", MGE_DEFAULT_OFFLINE, "ellipse premium 500" }, + { "ellipse", "PR650", MGE_DEFAULT_OFFLINE, "ellipse premium 650" }, + { "ellipse", "PR800", MGE_DEFAULT_OFFLINE, "ellipse premium 800" }, + { "ellipse", "PR1200", MGE_DEFAULT_OFFLINE, "ellipse premium 1200" }, /* Ellipse "Pro" */ - { "ELLIPSE", "600", MGE_DEFAULT, "Ellipse 600" }, - { "ELLIPSE", "750", MGE_DEFAULT, "Ellipse 750" }, - { "ELLIPSE", "1000", MGE_DEFAULT, "Ellipse 1000" }, - { "ELLIPSE", "1500", MGE_DEFAULT, "Ellipse 1500" }, + { "ELLIPSE", "600", MGE_DEFAULT_OFFLINE, "Ellipse 600" }, + { "ELLIPSE", "750", MGE_DEFAULT_OFFLINE, "Ellipse 750" }, + { "ELLIPSE", "1000", MGE_DEFAULT_OFFLINE, "Ellipse 1000" }, + { "ELLIPSE", "1500", MGE_DEFAULT_OFFLINE, "Ellipse 1500" }, - /* Ellipse "MAX" (TBR) */ -/* { "Ellipse MAX", "600", MGE_DEFAULT, NULL }, */ -/* { "Ellipse MAX", "850", MGE_DEFAULT, NULL }, */ -/* { "Ellipse MAX", "1100", MGE_DEFAULT, NULL }, */ -/* { "Ellipse MAX", "1500", MGE_DEFAULT, NULL }, */ + /* Ellipse MAX */ + { "Ellipse MAX", "600", MGE_DEFAULT_OFFLINE, NULL }, + { "Ellipse MAX", "850", MGE_DEFAULT_OFFLINE, NULL }, + { "Ellipse MAX", "1100", MGE_DEFAULT_OFFLINE, NULL }, + { "Ellipse MAX", "1500", MGE_DEFAULT_OFFLINE, NULL }, /* Protection Center */ - { "PROTECTIONCENTER", "420", MGE_DEFAULT, "Protection Center 420" }, - { "PROTECTIONCENTER", "500", MGE_DEFAULT, "Protection Center 500" }, - { "PROTECTIONCENTER", "675", MGE_DEFAULT, "Protection Center 675" }, + { "PROTECTIONCENTER", "420", MGE_DEFAULT_OFFLINE, "Protection Center 420" }, + { "PROTECTIONCENTER", "500", MGE_DEFAULT_OFFLINE, "Protection Center 500" }, + { "PROTECTIONCENTER", "675", MGE_DEFAULT_OFFLINE, "Protection Center 675" }, /* Protection Station, supports Eco control */ { "Protection Station", "500", MGE_PEGASUS, NULL }, @@ -600,6 +658,12 @@ static models_name_t mge_model_names [] = { "Ellipse ECO", "1200", MGE_PEGASUS, NULL }, { "Ellipse ECO", "1600", MGE_PEGASUS, NULL }, + /* 3S, also supports Eco control on some models (AUS 700 and US 750)*/ + { "3S", "450", MGE_DEFAULT_OFFLINE, NULL }, /* US only */ + { "3S", "550", MGE_DEFAULT_OFFLINE, NULL }, /* US 120V + EU 230V + AUS 240V */ + { "3S", "700", MGE_3S, NULL }, /* EU 230V + AUS 240V (w/ eco control) */ + { "3S", "750", MGE_3S, NULL }, /* US 120V (w/ eco control) */ + /* Evolution models */ { "Evolution", "500", MGE_DEFAULT, "Pulsar Evolution 500" }, { "Evolution", "800", MGE_DEFAULT, "Pulsar Evolution 800" }, @@ -695,6 +759,10 @@ static models_name_t mge_model_names [] = static hid_info_t mge_hid2nut[] = { + /* Device collection */ + /* Just declared to call *hid2info */ + { "device.country", ST_FLAG_STRING, 20, "UPS.PowerSummary.Country", NULL, "Europe", HU_FLAG_STATIC, eaton_check_country_info }, + /* Battery page */ { "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", NULL, "%.0f", 0, NULL }, { "battery.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerSummary.RemainingCapacityLimitSetting", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, @@ -704,6 +772,7 @@ static hid_info_t mge_hid2nut[] = { "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", NULL, "%.0f", 0, NULL }, { "battery.runtime.low", ST_FLAG_RW | ST_FLAG_STRING, 10, "UPS.PowerSummary.RemainingTimeLimit", NULL, "%.0f", 0, NULL }, { "battery.runtime.elapsed", 0, 0, "UPS.StatisticSystem.Input.[1].Statistic.[1].Time", NULL, "%.0f", HU_FLAG_QUICK_POLL, NULL }, + { "battery.runtime.low", ST_FLAG_RW | ST_FLAG_STRING, 10, "UPS.PowerSummary.RemainingTimeLimit", NULL, "%.0f", 0, NULL }, { "battery.temperature", 0, 0, "UPS.BatterySystem.Battery.Temperature", NULL, "%s", 0, kelvin_celsius_conversion }, { "battery.type", 0, 0, "UPS.PowerSummary.iDeviceChemistry", NULL, "%s", HU_FLAG_STATIC, stringid_conversion }, { "battery.voltage", 0, 0, "UPS.BatterySystem.Voltage", NULL, "%.1f", 0, NULL }, @@ -765,6 +834,7 @@ static hid_info_t mge_hid2nut[] = { "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.Overload", NULL, NULL, 0, overload_info }, { "BOOL", 0, 0, "UPS.PowerSummary.PresentStatus.NeedReplacement", NULL, NULL, 0, replacebatt_info }, /* FIXME: on Dell, the above requires an "AND" with "UPS.BatterySystem.Battery.Test = 3 " */ + { "BOOL", 0, 0, "UPS.LCMSystem.LCMAlarm.[2].PresentStatus.TimerExpired", NULL, NULL, 0, replacebatt_info }, { "BOOL", 0, 0, "UPS.PowerConverter.Input.[1].PresentStatus.Buck", NULL, NULL, 0, trim_info }, { "BOOL", 0, 0, "UPS.PowerConverter.Input.[1].PresentStatus.Boost", NULL, NULL, 0, boost_info }, { "BOOL", 0, 0, "UPS.PowerConverter.Input.[1].PresentStatus.VoltageOutOfRange", NULL, NULL, 0, vrange_info }, @@ -867,6 +937,13 @@ static hid_info_t mge_hid2nut[] = * on the master outlet used to automatically power off the slave outlets. * Values: 10, 25 (default) or 60 VA. */ { "outlet.power", ST_FLAG_RW | ST_FLAG_STRING, 6, "UPS.OutletSystem.Outlet.[1].ConfigApparentPower", NULL, "%s", HU_FLAG_SEMI_STATIC | HU_FLAG_ENUM, pegasus_threshold_info }, + + { "outlet.power", 0, 0, "UPS.OutletSystem.Outlet.[1].ApparentPower", NULL, "%.0f", 0, NULL }, + { "outlet.realpower", 0, 0, "UPS.OutletSystem.Outlet.[1].ActivePower", NULL, "%.0f", 0, NULL }, + { "outlet.current", 0, 0, "UPS.OutletSystem.Outlet.[1].Current", NULL, "%.2f", 0, NULL }, + { "outlet.powerfactor", 0, 0, "UPS.OutletSystem.Outlet.[1].PowerFactor", NULL, "%.2f", 0, NULL }, // "%s", 0, mge_powerfactor_conversion }, + + /* First outlet */ { "outlet.1.id", 0, 0, "UPS.OutletSystem.Outlet.[2].OutletID", NULL, "%.0f", HU_FLAG_STATIC, NULL }, { "outlet.1.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, "UPS.OutletSystem.Outlet.[2].OutletID", NULL, "PowerShare Outlet 1", HU_FLAG_ABSENT, NULL }, { "outlet.1.switchable", 0, 0, "UPS.OutletSystem.Outlet.[2].PresentStatus.Switchable", NULL, "%s", HU_FLAG_STATIC, yes_no_info }, @@ -876,6 +953,11 @@ static hid_info_t mge_hid2nut[] = { "outlet.1.autoswitch.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 3, "UPS.OutletSystem.Outlet.[2].RemainingCapacityLimit", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, { "outlet.1.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.OutletSystem.Outlet.[2].ShutdownTimer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, { "outlet.1.delay.start", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.OutletSystem.Outlet.[2].StartupTimer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, + { "outlet.1.power", 0, 0, "UPS.OutletSystem.Outlet.[2].ApparentPower", NULL, "%.0f", 0, NULL }, + { "outlet.1.realpower", 0, 0, "UPS.OutletSystem.Outlet.[2].ActivePower", NULL, "%.0f", 0, NULL }, + { "outlet.1.current", 0, 0, "UPS.OutletSystem.Outlet.[2].Current", NULL, "%.2f", 0, NULL }, + { "outlet.1.powerfactor", 0, 0, "UPS.OutletSystem.Outlet.[2].PowerFactor", NULL, "%.2f", 0, NULL }, // "%s", 0, mge_powerfactor_conversion }, + /* Second outlet */ { "outlet.2.id", 0, 0, "UPS.OutletSystem.Outlet.[3].OutletID", NULL, "%.0f", HU_FLAG_STATIC, NULL }, { "outlet.2.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, "UPS.OutletSystem.Outlet.[3].OutletID", NULL, "PowerShare Outlet 2", HU_FLAG_ABSENT, NULL }, /* needed for Pegasus to enable master/slave mode */ @@ -884,6 +966,10 @@ static hid_info_t mge_hid2nut[] = { "outlet.2.autoswitch.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 3, "UPS.OutletSystem.Outlet.[3].RemainingCapacityLimit", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, { "outlet.2.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.OutletSystem.Outlet.[3].ShutdownTimer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, { "outlet.2.delay.start", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.OutletSystem.Outlet.[3].StartupTimer", NULL, "%.0f", HU_FLAG_SEMI_STATIC, NULL }, + { "outlet.2.power", 0, 0, "UPS.OutletSystem.Outlet.[3].ApparentPower", NULL, "%.0f", 0, NULL }, + { "outlet.2.realpower", 0, 0, "UPS.OutletSystem.Outlet.[3].ActivePower", NULL, "%.0f", 0, NULL }, + { "outlet.2.current", 0, 0, "UPS.OutletSystem.Outlet.[3].Current", NULL, "%.2f", 0, NULL }, + { "outlet.2.powerfactor", 0, 0, "UPS.OutletSystem.Outlet.[3].PowerFactor", NULL, "%.2f", 0, NULL }, // "%s", 0, mge_powerfactor_conversion }, /* instant commands. */ /* splited into subset while waiting for extradata support diff --git a/drivers/mge-mib.c b/drivers/mge-mib.c index 817f168..a7d3731 100644 --- a/drivers/mge-mib.c +++ b/drivers/mge-mib.c @@ -28,8 +28,12 @@ #define MGE_MIB_VERSION "0.4" +/* TODO: + * - MGE PDU MIB and sysOID (".1.3.6.1.4.1.705.2") */ + /* SNMP OIDs set */ #define MGE_BASE_OID ".1.3.6.1.4.1.705.1" +#define MGE_SYSOID MGE_BASE_OID #define MGE_OID_MODEL_NAME MGE_BASE_OID ".1.1.0" static info_lkp_t mge_lowbatt_info[] = { @@ -156,4 +160,4 @@ static snmp_info_t mge_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t mge = { "mge", MGE_MIB_VERSION, "", MGE_OID_MODEL_NAME, mge_mib }; +mib2nut_info_t mge = { "mge", MGE_MIB_VERSION, "", MGE_OID_MODEL_NAME, mge_mib, MGE_SYSOID }; diff --git a/drivers/mge-utalk.c b/drivers/mge-utalk.c index c6114c7..616e2ad 100644 --- a/drivers/mge-utalk.c +++ b/drivers/mge-utalk.c @@ -465,7 +465,8 @@ void upsdrv_shutdown(void) { char buf[BUFFLEN]; /* static time_t lastcmd = 0; */ - + memset(buf, 0, sizeof(buf)); + if (sdtype == SD_RETURN) { /* enable automatic restart */ mge_command(buf, sizeof(buf), "Sx 5"); diff --git a/drivers/netvision-mib.c b/drivers/netvision-mib.c index e225d64..91e4d35 100644 --- a/drivers/netvision-mib.c +++ b/drivers/netvision-mib.c @@ -25,6 +25,8 @@ #define NETVISION_MIB_VERSION "0.1" +#define NETVISION_SYSOID ".1.3.6.1.4.1.4555.1.1.1" + /* SNMP OIDs set */ #define NETVISION_OID_UPS_MIB ".1.3.6.1.4.1.4555.1.1.1.1" #define NETVISION_OID_UPSIDENTMODEL ".1.3.6.1.4.1.4555.1.1.1.1.1.1.0" @@ -118,4 +120,4 @@ static snmp_info_t netvision_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } }; -mib2nut_info_t netvision = { "netvision", NETVISION_MIB_VERSION, "", NETVISION_OID_UPSIDENTMODEL, netvision_mib }; +mib2nut_info_t netvision = { "netvision", NETVISION_MIB_VERSION, "", NETVISION_OID_UPSIDENTMODEL, netvision_mib, NETVISION_SYSOID }; diff --git a/drivers/nut-ipmi.h b/drivers/nut-ipmi.h new file mode 100644 index 0000000..56fde19 --- /dev/null +++ b/drivers/nut-ipmi.h @@ -0,0 +1,57 @@ +/* nut-ipmi.h - Abstract IPMI interface, to allow using different IPMI backends + * + * Copyright (C) 2011 - Arnaud Quette + * + * 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 + * + */ + +typedef enum { + PSU_STATUS_UNKNOWN = 1, + PSU_PRESENT, /* = status OL */ + PSU_ABSENT, /* = status stale */ + PSU_POWER_FAILURE /* = status OFF */ +} psu_status_t; + +/* Abstract structure to store information */ +typedef struct IPMIDevice_s { + int ipmi_id; /* FRU ID */ + char* manufacturer; /* Manufacturer Name */ + char* product; /* Product Name */ + char* serial; /* Product serial number */ + char* part; /* Part Number */ + char* date; /* Manufacturing Date/Time */ + int overall_capacity; /* realpower.nominal? */ + int input_minvoltage; + int input_maxvoltage; + int input_minfreq; + int input_maxfreq; + int voltage; /* psu.voltage or device.voltage */ + unsigned int sensors_count; /* number of sensors IDs in sensors_id_list */ + unsigned int sensors_id_list[20]; /* ID of sensors linked to this FRU */ + + /* measurements... */ + int status; /* values from psu_status_t */ + double input_voltage; + double input_current; + double temperature; +} IPMIDevice_t; + +/* Generic functions, to implement in the backends */ +int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev); +void nut_ipmi_close(void); +int nut_ipmi_monitoring_init(); +int ipmi_get_sensors_status(IPMIDevice_t *ipmi_dev); diff --git a/drivers/nut-ipmipsu.c b/drivers/nut-ipmipsu.c new file mode 100644 index 0000000..18cb355 --- /dev/null +++ b/drivers/nut-ipmipsu.c @@ -0,0 +1,240 @@ +/* nut-ipmipsu.c - Driver for IPMI Power Supply Units (PSU) + * + * Copyright (C) 2011 - Arnaud Quette + * + * 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 + * + * TODO list: + * - PSU sensor monitoring (how to find the right one?) + * - dump all value at init, so that we can check for other interesting data + */ + +#include "main.h" +#include "nut-ipmi.h" + +#define DRIVER_NAME "IPMI PSU driver" +#define DRIVER_VERSION "0.06" + +/* driver description structure */ +upsdrv_info_t upsdrv_info = { + DRIVER_NAME, + DRIVER_VERSION, + "Arnaud Quette \n", + DRV_EXPERIMENTAL, + { NULL } +}; + +/* Note on device.status + * OL: present and providing power + * OFF: present but not providing power (power cable removed) + * stale: not present (PSU removed) + * => should we prefer RB, MISSING, ABSENT, ??? + */ + +/* Abstract structure to allow different IPMI implementation + * We currently use FreeIPMI, but OpenIPMI and others are serious + * candidates! */ +IPMIDevice_t ipmi_dev; + +/* Currently used to store FRU ID, but will probably evolve... */ +int ipmi_id = -1; + +void upsdrv_initinfo(void) +{ + /* try to detect the PSU here - call fatal_with_errno(EXIT_FAILURE, ) if it fails */ + upsdebugx(1, "upsdrv_initinfo..."); + + /* print what we detected during IPMI open */ + upsdebugx(1, "Detected a PSU: %s/%s", + ipmi_dev.manufacturer ? ipmi_dev.manufacturer : "unknown", + ipmi_dev.product ? ipmi_dev.product : "unknown"); + + dstate_setinfo("driver.version.data", "%s", DRIVER_NAME); + dstate_setinfo("driver.version.internal", DRIVER_VERSION); + + dstate_setinfo ("device.type", "psu"); + + /* Publish information from the IPMI structure */ + if (ipmi_dev.manufacturer) + dstate_setinfo("device.mfr", "%s", ipmi_dev.manufacturer); + + if (ipmi_dev.product) + dstate_setinfo("device.model", "%s", ipmi_dev.product); + + if (ipmi_dev.serial) + dstate_setinfo("device.serial", "%s", ipmi_dev.serial); + + if (ipmi_dev.part) + dstate_setinfo("device.part", "%s", ipmi_dev.part); + + if (ipmi_dev.date) + dstate_setinfo("device.mfr.date", "%s", ipmi_dev.date); + + /* FIXME: move to device.id */ + dstate_setinfo("ups.id", "%i", ipmi_id); + /* FIXME: move to device.realpower.nominal */ + if (ipmi_dev.overall_capacity != -1) + dstate_setinfo("ups.realpower.nominal", "%i", ipmi_dev.overall_capacity); + + if (ipmi_dev.input_minvoltage != -1) + dstate_setinfo("input.voltage.minimum", "%i", ipmi_dev.input_minvoltage); + + if (ipmi_dev.input_maxvoltage != -1) + dstate_setinfo("input.voltage.maximum", "%i", ipmi_dev.input_maxvoltage); + + if (ipmi_dev.input_minfreq != -1) + dstate_setinfo("input.frequency.low", "%i", ipmi_dev.input_minfreq); + + if (ipmi_dev.input_maxfreq != -1) + dstate_setinfo("input.frequency.high", "%i", ipmi_dev.input_maxfreq); + + /* FIXME: move to device.voltage */ + if (ipmi_dev.voltage != -1) + dstate_setinfo("ups.voltage", "%i", ipmi_dev.voltage); + + if (nut_ipmi_monitoring_init() != 0) + fatalx(EXIT_FAILURE, "Can't initialize IPMI monitoring"); + + if (nut_ipmi_get_sensors_status(&ipmi_dev) != 0) { + upsdebugx(1, "Error while updating sensors values"); + dstate_datastale(); + } + else { + dstate_dataok(); + } + + /* upsh.instcmd = instcmd; */ +} + +void upsdrv_updateinfo(void) +{ + upsdebugx(1, "upsdrv_updateinfo..."); + + /* FIXME: implement sensors monitoring */ + + if (nut_ipmi_get_sensors_status(&ipmi_dev) != 0) { + upsdebugx(1, "Error while updating sensors values"); + dstate_datastale(); + } + else { + dstate_dataok(); + } + + /* + * poll_interval = 2; + */ +} + +void upsdrv_shutdown(void) +{ + fatalx(EXIT_FAILURE, "shutdown not supported"); +} + +/* +static int instcmd(const char *cmdname, const char *extra) +{ + if (!strcasecmp(cmdname, "test.battery.stop")) { + ser_send_buf(upsfd, ...); + return STAT_INSTCMD_HANDLED; + } + + upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname); + return STAT_INSTCMD_UNKNOWN; +} +*/ + +/* +static int setvar(const char *varname, const char *val) +{ + if (!strcasecmp(varname, "ups.test.interval")) { + ser_send_buf(upsfd, ...); + return STAT_SET_HANDLED; + } + + upslogx(LOG_NOTICE, "setvar: unknown variable [%s]", varname); + return STAT_SET_UNKNOWN; +} +*/ + +void upsdrv_help(void) +{ +} + +/* list flags and values that you want to receive via -x */ +void upsdrv_makevartable(void) +{ + /* FIXME: need more params. + addvar(VAR_VALUE, "username", "Remote server username"); + addvar(VAR_VALUE, "password", "Remote server password"); + addvar(VAR_VALUE, "authtype", + "Authentication type to use during lan session activation"); + addvar(VAR_VALUE, "type", + "Type of the device to match ('psu' for \"Power Supply\")"); + + addvar(VAR_VALUE, "serial", "Serial number to match a specific device"); + addvar(VAR_VALUE, "fruid", "FRU identifier to match a specific device"); + addvar(VAR_VALUE, "sensorid", "Sensor identifier to match a specific device"); */ +} + +void upsdrv_initups(void) +{ + upsdebugx(1, "upsdrv_initups..."); + + /* port can be expressed using: + * "id?" for device (FRU) ID 0x? + * "psu?" for PSU number ? + */ + if (!strncmp( device_path, "id", 2)) + { + ipmi_id = atoi(device_path+2); + upsdebugx(2, "Device ID 0x%i", ipmi_id); + } + /* else... to select PSU number X */ + + /* Clear the interface structure */ + ipmi_dev.ipmi_id = -1; + ipmi_dev.manufacturer = NULL; + ipmi_dev.product = NULL; + ipmi_dev.serial = NULL; + ipmi_dev.part = NULL; + ipmi_dev.date = NULL; + ipmi_dev.overall_capacity = -1; + ipmi_dev.input_minvoltage = -1; + ipmi_dev.input_maxvoltage = -1; + ipmi_dev.input_minfreq = -1; + ipmi_dev.input_maxfreq = -1; + ipmi_dev.voltage = -1; + ipmi_dev.sensors_count = 0; + ipmi_dev.status = -1; + ipmi_dev.input_voltage = -1; + ipmi_dev.input_current = -1; + ipmi_dev.temperature = -1; + + /* Open IPMI using the above */ + nut_ipmi_open(ipmi_id, &ipmi_dev); + + /* the upsh handlers can't be done here, as they get initialized + * shortly after upsdrv_initups returns to main. + */ + + /* don't try to detect the UPS here */ +} + +void upsdrv_cleanup(void) +{ + upsdebugx(1, "upsdrv_cleanup..."); + nut_ipmi_close(); +} diff --git a/drivers/nut-libfreeipmi.c b/drivers/nut-libfreeipmi.c new file mode 100644 index 0000000..f83b77a --- /dev/null +++ b/drivers/nut-libfreeipmi.c @@ -0,0 +1,935 @@ +/* nut-libfreeipmi.c - NUT IPMI backend, using FreeIPMI + * + * Copyright (C) + * 2011 - Arnaud Quette + * 2011 - Albert Chu + * + * Based on the sample codes 'ipmi-fru-example.c', 'frulib.c' and + * 'ipmimonitoring-sensors.c', from FreeIPMI + * + * 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 + * + */ + +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "nut-ipmi.h" +#include "dstate.h" + +/* FreeIPMI defines */ +#define IPMI_FRU_STR_BUFLEN 1024 +/* haven't seen a motherboard with more than 2-3 so far, + * 64 should be more than enough */ +#define IPMI_FRU_CUSTOM_FIELDS 64 + +/* FreeIPMI contexts and configuration*/ +ipmi_ctx_t ipmi_ctx = NULL; +ipmi_fru_parse_ctx_t fru_parse_ctx = NULL; +ipmi_sdr_cache_ctx_t sdr_cache_ctx = NULL; +ipmi_sdr_parse_ctx_t sdr_parse_ctx = NULL; +ipmi_monitoring_ctx_t mon_ctx = NULL; +struct ipmi_monitoring_ipmi_config ipmi_config; + +/* FIXME: freeipmi auto selects a cache based on the hostname you are + * connecting too, but this is probably fine for you + */ +#define CACHE_LOCATION "/tmp/sdrcache" + +/* Support functions */ +static const char* libfreeipmi_getfield (uint8_t language_code, + ipmi_fru_parse_field_t *field); + +static void libfreeipmi_cleanup(); + +static int libfreeipmi_get_psu_info (const void *areabuf, + uint8_t area_length, IPMIDevice_t *ipmi_dev); + +static int libfreeipmi_get_board_info (const void *areabuf, + uint8_t area_length, IPMIDevice_t *ipmi_dev); + +static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev); + + +/******************************************************************************* + * Implementation + ******************************************************************************/ +int nut_ipmi_open(int ipmi_id, IPMIDevice_t *ipmi_dev) +{ + int ret = -1; + uint8_t areabuf[IPMI_FRU_PARSE_AREA_SIZE_MAX+1]; + unsigned int area_type = 0; + unsigned int area_length = 0; + + upsdebugx(1, "nut-libfreeipmi: nutipmi_open()..."); + + /* Initialize the FreeIPMI library. */ + if (!(ipmi_ctx = ipmi_ctx_create ())) + { + /* we have to force cleanup, since exit handler is not yet installed */ + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_ctx_create"); + } + + if ((ret = ipmi_ctx_find_inband (ipmi_ctx, + NULL, + 0, /* don't disable auto-probe */ + 0, + 0, + NULL, + 0, /* workaround flags, none by default */ + 0 /* flags */ + )) < 0) + { + libfreeipmi_cleanup(); + fatalx(EXIT_FAILURE, "ipmi_ctx_find_inband: %s", + ipmi_ctx_errormsg (ipmi_ctx)); + } + if (!ret) + { + libfreeipmi_cleanup(); + fatalx(EXIT_FAILURE, "could not find inband device"); + } + + upsdebugx(1, "FreeIPMI initialized..."); + + /* Parse FRU information */ + if (!(fru_parse_ctx = ipmi_fru_parse_ctx_create (ipmi_ctx))) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_ctx_create()"); + } + + /* lots of motherboards calculate checksums incorrectly */ + if (ipmi_fru_parse_ctx_set_flags (fru_parse_ctx, IPMI_FRU_PARSE_FLAGS_SKIP_CHECKSUM_CHECKS) < 0) + { + libfreeipmi_cleanup(); + fatalx(EXIT_FAILURE, "ipmi_fru_parse_ctx_set_flags: %s\n", + ipmi_fru_parse_ctx_strerror (ipmi_fru_parse_ctx_errnum (fru_parse_ctx))); + } + + /* Now open the requested (local) PSU */ + if (ipmi_fru_parse_open_device_id (fru_parse_ctx, ipmi_id) < 0) + { + libfreeipmi_cleanup(); + fatalx(EXIT_FAILURE, "ipmi_fru_parse_open_device_id: %s\n", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + } + + /* Set IPMI identifier */ + ipmi_dev->ipmi_id = ipmi_id; + + do + { + /* clear fields */ + area_type = 0; + area_length = 0; + memset (areabuf, '\0', IPMI_FRU_PARSE_AREA_SIZE_MAX + 1); + + /* parse FRU buffer */ + if (ipmi_fru_parse_read_data_area (fru_parse_ctx, + &area_type, + &area_length, + areabuf, + IPMI_FRU_PARSE_AREA_SIZE_MAX) < 0) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, + "ipmi_fru_parse_open_device_id: %s\n", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + } + + if (area_length) + { + switch (area_type) + { + /* get generic board information */ + case IPMI_FRU_PARSE_AREA_TYPE_BOARD_INFO_AREA: + + if(libfreeipmi_get_board_info (areabuf, area_length, + ipmi_dev) < 0) + { + upsdebugx(1, "Can't retrieve board information"); + } + break; + /* get specific PSU information */ + case IPMI_FRU_PARSE_AREA_TYPE_MULTIRECORD_POWER_SUPPLY_INFORMATION: + + if(libfreeipmi_get_psu_info (areabuf, area_length, ipmi_dev) < 0) + { + upsdebugx(1, "Can't retrieve PSU information"); + } + break; + default: + upsdebugx (5, "FRU: discarding FRU Area Type Read: %02Xh", area_type); + break; + } + } + } while ((ret = ipmi_fru_parse_next (fru_parse_ctx)) == 1); + + /* check for errors */ + if (ret < 0) { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_fru_parse_next: %s", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + } + else { + /* Get all related sensors information */ + libfreeipmi_get_sensors_info (ipmi_dev); + } + + /* cleanup context */ + libfreeipmi_cleanup(); + + return (0); +} + +void nut_ipmi_close(void) +{ + upsdebugx(1, "nutipmi_close..."); + + libfreeipmi_cleanup(); +} + +static const char* libfreeipmi_getfield (uint8_t language_code, + ipmi_fru_parse_field_t *field) +{ + static char strbuf[IPMI_FRU_PARSE_AREA_STRING_MAX + 1]; + unsigned int strbuflen = IPMI_FRU_PARSE_AREA_STRING_MAX; + + if (!field->type_length_field_length) + return NULL; + + memset (strbuf, '\0', IPMI_FRU_PARSE_AREA_STRING_MAX + 1); + + if (ipmi_fru_parse_type_length_field_to_string (fru_parse_ctx, + field->type_length_field, + field->type_length_field_length, + language_code, + strbuf, + &strbuflen) < 0) + { + upsdebugx (2, "ipmi_fru_parse_type_length_field_to_string: %s", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + return NULL; + } + + if (strbuflen) + return strbuf; + + return NULL; +} + +/* Get voltage value from the IPMI voltage code */ +static float libfreeipmi_get_voltage (uint8_t voltage_code) +{ + if (voltage_code == IPMI_FRU_VOLTAGE_12V) + return 12; + else if (voltage_code == IPMI_FRU_VOLTAGE_MINUS12V) + return -12; + else if (voltage_code == IPMI_FRU_VOLTAGE_5V) + return 5; + else if (voltage_code == IPMI_FRU_VOLTAGE_3_3V) + return 3.3; + else + return 0; +} + +/* Cleanup IPMI contexts */ +static void libfreeipmi_cleanup() +{ + /* cleanup */ + if (fru_parse_ctx) { + ipmi_fru_parse_close_device_id (fru_parse_ctx); + ipmi_fru_parse_ctx_destroy (fru_parse_ctx); + } + + if (sdr_cache_ctx) { + ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx); + } + + if (sdr_parse_ctx) { + ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx); + } + + if (ipmi_ctx) { + ipmi_ctx_close (ipmi_ctx); + ipmi_ctx_destroy (ipmi_ctx); + } + + if (mon_ctx) { + ipmi_monitoring_ctx_destroy (mon_ctx); + } +} + +/* Get generic board information (manufacturer and model names, serial, ...) + * from IPMI FRU */ +static int libfreeipmi_get_psu_info (const void *areabuf, + uint8_t area_length, + IPMIDevice_t *ipmi_dev) +{ + /* FIXME: directly use ipmi_dev fields */ + unsigned int overall_capacity; + unsigned int low_end_input_voltage_range_1; + unsigned int high_end_input_voltage_range_1; + unsigned int low_end_input_frequency_range; + unsigned int high_end_input_frequency_range; + unsigned int voltage_1; + + /* FIXME: check for the interest and capability to use these data */ + unsigned int peak_va; + unsigned int inrush_current; + unsigned int inrush_interval; + unsigned int low_end_input_voltage_range_2; + unsigned int high_end_input_voltage_range_2; + unsigned int ac_dropout_tolerance; + unsigned int predictive_fail_support; + unsigned int power_factor_correction; + unsigned int autoswitch; + unsigned int hot_swap_support; + unsigned int tachometer_pulses_per_rotation_predictive_fail_polarity; + unsigned int peak_capacity; + unsigned int hold_up_time; + unsigned int voltage_2; + unsigned int total_combined_wattage; + unsigned int predictive_fail_tachometer_lower_threshold; + + upsdebugx(1, "entering libfreeipmi_get_psu_info()"); + + if (ipmi_fru_parse_multirecord_power_supply_information (fru_parse_ctx, + areabuf, + area_length, + &overall_capacity, + &peak_va, + &inrush_current, + &inrush_interval, + &low_end_input_voltage_range_1, + &high_end_input_voltage_range_1, + &low_end_input_voltage_range_2, + &high_end_input_voltage_range_2, + &low_end_input_frequency_range, + &high_end_input_frequency_range, + &ac_dropout_tolerance, + &predictive_fail_support, + &power_factor_correction, + &autoswitch, + &hot_swap_support, + &tachometer_pulses_per_rotation_predictive_fail_polarity, + &peak_capacity, + &hold_up_time, + &voltage_1, + &voltage_2, + &total_combined_wattage, + &predictive_fail_tachometer_lower_threshold) < 0) + { + fatalx(EXIT_FAILURE, "ipmi_fru_parse_multirecord_power_supply_information: %s", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + } + + ipmi_dev->overall_capacity = overall_capacity; + + /* Voltages are in mV! */ + ipmi_dev->input_minvoltage = low_end_input_voltage_range_1 / 1000; + ipmi_dev->input_maxvoltage = high_end_input_voltage_range_1 / 1000; + + ipmi_dev->input_minfreq = low_end_input_frequency_range; + ipmi_dev->input_maxfreq = high_end_input_frequency_range; + + ipmi_dev->voltage = libfreeipmi_get_voltage(voltage_1); + + return (0); +} + +/* Get specific PSU information from IPMI FRU */ +static int libfreeipmi_get_board_info (const void *areabuf, + uint8_t area_length, IPMIDevice_t *ipmi_dev) +{ + uint8_t language_code; + uint32_t mfg_date_time; + ipmi_fru_parse_field_t board_manufacturer; + ipmi_fru_parse_field_t board_product_name; + ipmi_fru_parse_field_t board_serial_number; + ipmi_fru_parse_field_t board_part_number; + ipmi_fru_parse_field_t board_fru_file_id; + ipmi_fru_parse_field_t board_custom_fields[IPMI_FRU_CUSTOM_FIELDS]; + const char *string = NULL; + time_t timetmp; + struct tm mfg_date_time_tm; + char mfg_date_time_buf[IPMI_FRU_STR_BUFLEN + 1]; + + upsdebugx(1, "entering libfreeipmi_get_board_info()"); + + /* clear fields */ + memset (&board_manufacturer, '\0', sizeof (ipmi_fru_parse_field_t)); + memset (&board_product_name, '\0', sizeof (ipmi_fru_parse_field_t)); + memset (&board_serial_number, '\0', sizeof (ipmi_fru_parse_field_t)); + memset (&board_fru_file_id, '\0', sizeof (ipmi_fru_parse_field_t)); + memset (&board_custom_fields[0], '\0', + sizeof (ipmi_fru_parse_field_t) * IPMI_FRU_CUSTOM_FIELDS); + + /* parse FRU buffer */ + if (ipmi_fru_parse_board_info_area (fru_parse_ctx, + areabuf, + area_length, + &language_code, + &mfg_date_time, + &board_manufacturer, + &board_product_name, + &board_serial_number, + &board_part_number, + &board_fru_file_id, + board_custom_fields, + IPMI_FRU_CUSTOM_FIELDS) < 0) + { + libfreeipmi_cleanup(); + fatalx(EXIT_FAILURE, "ipmi_fru_parse_board_info_area: %s", + ipmi_fru_parse_ctx_errormsg (fru_parse_ctx)); + } + + + if (IPMI_FRU_LANGUAGE_CODE_VALID (language_code)) { + upsdebugx (5, "FRU Board Language: %s", ipmi_fru_language_codes[language_code]); + } + else { + upsdebugx (5, "FRU Board Language Code: %02Xh", language_code); + } + + /* Posix says individual calls need not clear/set all portions of + * 'struct tm', thus passing 'struct tm' between functions could + * have issues. So we need to memset */ + memset (&mfg_date_time_tm, '\0', sizeof (struct tm)); + timetmp = mfg_date_time; + localtime_r (&timetmp, &mfg_date_time_tm); + memset (mfg_date_time_buf, '\0', IPMI_FRU_STR_BUFLEN + 1); + strftime (mfg_date_time_buf, IPMI_FRU_STR_BUFLEN, "%D - %T", &mfg_date_time_tm); + + /* Store values */ + ipmi_dev->date = xstrdup(mfg_date_time_buf); + upsdebugx(2, "FRU Board Manufacturing Date/Time: %s", ipmi_dev->date); + + if ((string = libfreeipmi_getfield (language_code, &board_manufacturer)) != NULL) + ipmi_dev->manufacturer = xstrdup(string); + else + ipmi_dev->manufacturer = xstrdup("Generic IPMI manufacturer"); + + if ((string = libfreeipmi_getfield (language_code, &board_product_name)) != NULL) + ipmi_dev->product = xstrdup(string); + else + ipmi_dev->product = xstrdup("Generic PSU"); + + if ((string = libfreeipmi_getfield (language_code, &board_serial_number)) != NULL) + ipmi_dev->serial = xstrdup(string); + else + ipmi_dev->serial = NULL; + + if ((string = libfreeipmi_getfield (language_code, &board_part_number)) != NULL) + ipmi_dev->part = xstrdup(string); + else + ipmi_dev->part = NULL; + + return (0); +} + + +/* Get the sensors list & values, specific to the given FRU ID + * Return -1 on error, or the number of sensors found otherwise */ +static int libfreeipmi_get_sensors_info (IPMIDevice_t *ipmi_dev) +{ + uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH]; + uint8_t record_type, logical_physical_fru_device, logical_fru_device_device_slave_address; + uint8_t tmp_entity_id, tmp_entity_instance; + int sdr_record_len; + uint16_t record_count; + int found_device_id = 0; + uint16_t record_id; + uint8_t entity_id, entity_instance; + int i; + + if (ipmi_ctx == NULL) + return (-1); + + /* Clear the sensors list */ + ipmi_dev->sensors_count = 0; + memset(ipmi_dev->sensors_id_list, 0, sizeof(ipmi_dev->sensors_id_list)); + + if (!(sdr_cache_ctx = ipmi_sdr_cache_ctx_create ())) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_ctx_create()"); + } + + if (!(sdr_parse_ctx = ipmi_sdr_parse_ctx_create ())) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_parse_ctx_create()"); + } + + if (ipmi_sdr_cache_open (sdr_cache_ctx, ipmi_ctx, CACHE_LOCATION) < 0) + { + if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + } + } + + if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) == IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST) + { + if (ipmi_sdr_cache_create (sdr_cache_ctx, + ipmi_ctx, CACHE_LOCATION, + IPMI_SDR_CACHE_CREATE_FLAGS_DEFAULT, + IPMI_SDR_CACHE_VALIDATION_FLAGS_DEFAULT, + NULL, NULL) < 0) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_create: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + } + + if (ipmi_sdr_cache_open (sdr_cache_ctx, + ipmi_ctx, CACHE_LOCATION) < 0) + { + if (ipmi_sdr_cache_ctx_errnum (sdr_cache_ctx) != IPMI_SDR_CACHE_ERR_CACHE_READ_CACHE_DOES_NOT_EXIST) + { + libfreeipmi_cleanup(); + fatal_with_errno(EXIT_FAILURE, "ipmi_sdr_cache_open: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + } + } + } + + if (ipmi_sdr_cache_record_count (sdr_cache_ctx, &record_count) < 0) + { + fprintf (stderr, + "ipmi_sdr_cache_record_count: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + goto cleanup; + } + + for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx)) + { + memset (sdr_record, '\0', IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH); + if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx, + sdr_record, + IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH)) < 0) + { + fprintf (stderr, "ipmi_sdr_cache_record_read: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + goto cleanup; + } + + if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx, + sdr_record, + sdr_record_len, + NULL, + &record_type) < 0) + { + fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s", + ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx)); + goto cleanup; + } + + if (record_type != IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD) + continue; + + if (ipmi_sdr_parse_fru_device_locator_parameters (sdr_parse_ctx, + sdr_record, + sdr_record_len, + NULL, + &logical_fru_device_device_slave_address, + NULL, + NULL, + &logical_physical_fru_device, + NULL) < 0) + { + fprintf (stderr, "ipmi_sdr_parse_fru_device_locator_parameters: %s", + ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx)); + goto cleanup; + } + + if (logical_physical_fru_device + && logical_fru_device_device_slave_address == ipmi_dev->ipmi_id) + { + found_device_id++; + + if (ipmi_sdr_parse_fru_entity_id_and_instance (sdr_parse_ctx, + sdr_record, + sdr_record_len, + &entity_id, + &entity_instance) < 0) + { + fprintf (stderr, + "ipmi_sdr_parse_fru_entity_id_and_instance: %s", + ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx)); + goto cleanup; + } + break; + } + } + + if (!found_device_id) + { + fprintf (stderr, "Couldn't find device id %d", ipmi_dev->ipmi_id); + goto cleanup; + } + else + upsdebugx(1, "Found device id %d", ipmi_dev->ipmi_id); + + if (ipmi_sdr_cache_first (sdr_cache_ctx) < 0) + { + fprintf (stderr, "ipmi_sdr_cache_first: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + goto cleanup; + } + + for (i = 0; i < record_count; i++, ipmi_sdr_cache_next (sdr_cache_ctx)) + { + /* uint8_t sdr_record[IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH]; + uint8_t record_type, tmp_entity_id, tmp_entity_instance; + int sdr_record_len; */ + + memset (sdr_record, '\0', IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH); + if ((sdr_record_len = ipmi_sdr_cache_record_read (sdr_cache_ctx, + sdr_record, + IPMI_SDR_CACHE_MAX_SDR_RECORD_LENGTH)) < 0) + { + fprintf (stderr, "ipmi_sdr_cache_record_read: %s", + ipmi_sdr_cache_ctx_errormsg (sdr_cache_ctx)); + goto cleanup; + } + + if (ipmi_sdr_parse_record_id_and_type (sdr_parse_ctx, + sdr_record, + sdr_record_len, + &record_id, + &record_type) < 0) + { + fprintf (stderr, "ipmi_sdr_parse_record_id_and_type: %s", + ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx)); + goto cleanup; + } + + upsdebugx (5, "Checking record %i (/%i)", record_id, record_count); + + if (record_type != IPMI_SDR_FORMAT_FULL_SENSOR_RECORD + && record_type != IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD + && record_type != IPMI_SDR_FORMAT_EVENT_ONLY_RECORD) { + continue; + } + + if (ipmi_sdr_parse_entity_id_instance_type (sdr_parse_ctx, + sdr_record, + sdr_record_len, + &tmp_entity_id, + &tmp_entity_instance, + NULL) < 0) + { + fprintf (stderr, "ipmi_sdr_parse_entity_instance_type: %s", + ipmi_sdr_parse_ctx_errormsg (sdr_parse_ctx)); + goto cleanup; + } + + if (tmp_entity_id == entity_id + && tmp_entity_instance == entity_instance) + { + upsdebugx (1, "Found record id = %u for device id %u", + record_id, ipmi_dev->ipmi_id); + + /* Add it to the tracked list */ + ipmi_dev->sensors_id_list[ipmi_dev->sensors_count] = record_id; + ipmi_dev->sensors_count++; + } + } + + +cleanup: + /* Cleanup */ + if (sdr_cache_ctx) { + ipmi_sdr_cache_ctx_destroy (sdr_cache_ctx); + } + + if (sdr_parse_ctx) { + ipmi_sdr_parse_ctx_destroy (sdr_parse_ctx); + } + + return ipmi_dev->sensors_count; +} + + +/* +=> Nominal conditions + + +Record ID, Sensor Name, Sensor Number, Sensor Type, Sensor State, Sensor Reading, Sensor Units, Sensor Event/Reading Type Code, Sensor Event Bitmask, Sensor Event String +52, Presence, 84, Entity Presence, Nominal, N/A, N/A, 6Fh, 1h, 'Entity Present' +57, Status, 100, Power Supply, Nominal, N/A, N/A, 6Fh, 1h, 'Presence detected' +116, Current, 148, Current, Nominal, 0.20, A, 1h, C0h, 'OK' +118, Voltage, 150, Voltage, Nominal, 236.00, V, 1h, C0h, 'OK' + +=> Power failure conditions + +Record ID, Sensor Name, Sensor Number, Sensor Type, Sensor State, Sensor Reading, Sensor Units, Sensor Event/Reading Type Code, Sensor Event Bitmask, Sensor Event String +52, Presence, 84, Entity Presence, Nominal, N/A, N/A, 6Fh, 1h, 'Entity Present' +57, Status, 100, Power Supply, Critical, N/A, N/A, 6Fh, 9h, 'Presence detected' 'Power Supply input lost (AC/DC)' + +=> PSU removed + +Record ID, Sensor Name, Sensor Number, Sensor Type, Sensor State, Sensor Reading, Sensor Units, Sensor Event/Reading Type Code, Sensor Event Bitmask, Sensor Event String +52, Presence, 84, Entity Presence, Critical, N/A, N/A, 6Fh, 2h, 'Entity Absent' +57, Status, 100, Power Supply, Critical, N/A, N/A, 6Fh, 8h, 'Power Supply input lost (AC/DC)' + +*/ + +int nut_ipmi_monitoring_init() +{ + int errnum; + + if (ipmi_monitoring_init (0, &errnum) < 0) { + upsdebugx (1, "ipmi_monitoring_init() error: %s", ipmi_monitoring_ctx_strerror (errnum)); + return -1; + } + + if (!(mon_ctx = ipmi_monitoring_ctx_create ())) { + upsdebugx (1, "ipmi_monitoring_ctx_create() failed"); + return -1; + } + + /* FIXME: replace "/tmp" by a proper place, using mkdtemp() or similar */ + if (ipmi_monitoring_ctx_sdr_cache_directory (mon_ctx, "/tmp") < 0) { + upsdebugx (1, "ipmi_monitoring_ctx_sdr_cache_directory() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + return -1; + } + + if (ipmi_monitoring_ctx_sensor_config_file (mon_ctx, NULL) < 0) { + upsdebugx (1, "ipmi_monitoring_ctx_sensor_config_file() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + return -1; + } + return 0; +} + +int nut_ipmi_get_sensors_status(IPMIDevice_t *ipmi_dev) +{ + /* It seems we don't need more! */ + unsigned int sensor_reading_flags = IPMI_MONITORING_SENSOR_READING_FLAGS_IGNORE_NON_INTERPRETABLE_SENSORS; + int sensor_count, i, str_count; + int psu_status = PSU_STATUS_UNKNOWN; + int retval = 0; + + if (mon_ctx == NULL) { + upsdebugx (1, "Monitoring context not initialized!"); + return -1; + } + + /* Monitor only the list of sensors found previously */ + if ((sensor_count = ipmi_monitoring_sensor_readings_by_record_id (mon_ctx, + NULL, /* hostname is NULL for In-band communication */ + NULL, /* FIXME: needed? ipmi_config */ + sensor_reading_flags, + ipmi_dev->sensors_id_list, + ipmi_dev->sensors_count, + NULL, + NULL)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_readings_by_record_id() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + return -1; + } + + for (i = 0; i < sensor_count; i++, ipmi_monitoring_sensor_iterator_next (mon_ctx)) + { + int record_id, sensor_type; + int sensor_bitmask_type = -1; + /* int sensor_reading_type, sensor_state; */ + char **sensor_bitmask_strings = NULL; + void *sensor_reading = NULL; + + if ((record_id = ipmi_monitoring_sensor_read_record_id (mon_ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_record_id() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + continue; + } + + if ((sensor_type = ipmi_monitoring_sensor_read_sensor_type (mon_ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_sensor_type() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + continue; + } + + /* should we consider this for ALARM? + * IPMI_MONITORING_STATE_NOMINAL + * IPMI_MONITORING_STATE_WARNING + * IPMI_MONITORING_STATE_CRITICAL + * if ((sensor_state = ipmi_monitoring_sensor_read_sensor_state (mon_ctx)) < 0) + * ... */ + + if ((sensor_reading = ipmi_monitoring_sensor_read_sensor_reading (mon_ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_sensor_reading() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + } + + /* This can be needed to interpret sensor_reading format! + if ((sensor_reading_type = ipmi_monitoring_sensor_read_sensor_reading_type (ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_sensor_reading_type() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + } */ + + if ((sensor_bitmask_type = ipmi_monitoring_sensor_read_sensor_bitmask_type (mon_ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_sensor_bitmask_type() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + continue; + } + + if ((sensor_bitmask_strings = ipmi_monitoring_sensor_read_sensor_bitmask_strings (mon_ctx)) < 0) + { + upsdebugx (1, "ipmi_monitoring_sensor_read_sensor_bitmask_strings() error: %s", + ipmi_monitoring_ctx_errormsg (mon_ctx)); + continue; + } + + /* Only the few possibly interesting sensors are considered */ + switch (sensor_type) + { + case IPMI_MONITORING_SENSOR_TYPE_TEMPERATURE: + ipmi_dev->temperature = *((double *)sensor_reading); + upsdebugx (3, "Temperature: %.2f", *((double *)sensor_reading)); + dstate_setinfo("ambient.temperature", "%.2f", *((double *)sensor_reading)); + break; + case IPMI_MONITORING_SENSOR_TYPE_VOLTAGE: + ipmi_dev->voltage = *((double *)sensor_reading); + upsdebugx (3, "Voltage: %.2f", *((double *)sensor_reading)); + dstate_setinfo("input.voltage", "%.2f", *((double *)sensor_reading)); + break; + case IPMI_MONITORING_SENSOR_TYPE_CURRENT: + ipmi_dev->input_current = *((double *)sensor_reading); + upsdebugx (3, "Current: %.2f", *((double *)sensor_reading)); + dstate_setinfo("input.current", "%.2f", *((double *)sensor_reading)); + break; + + case IPMI_MONITORING_SENSOR_TYPE_POWER_SUPPLY: + /* Possible values: + * 'Presence detected' + * 'Power Supply input lost (AC/DC)' => maps to status:OFF */ + upsdebugx (3, "Power Supply: status string"); + if (sensor_bitmask_type == IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN) { + upsdebugx(3, "No status string"); + } + str_count = 0; + while (sensor_bitmask_strings[str_count]) + { + upsdebugx (3, "\t'%s'", sensor_bitmask_strings[str_count]); + if (!strncmp("Power Supply input lost (AC/DC)", + sensor_bitmask_strings[str_count], + strlen("Power Supply input lost (AC/DC)"))) { + /* Don't override PSU absence! */ + if (psu_status != PSU_ABSENT) { + psu_status = PSU_POWER_FAILURE; /* = status OFF */ + } + } + str_count++; + } + break; + case IPMI_MONITORING_SENSOR_TYPE_ENTITY_PRESENCE: + /* Possible values: + * 'Entity Present' => maps to status:OL + * 'Entity Absent' (PSU has been removed!) => declare staleness */ + upsdebugx (3, "Entity Presence: status string"); + if (sensor_bitmask_type == IPMI_MONITORING_SENSOR_BITMASK_TYPE_UNKNOWN) { + upsdebugx(3, "No status string"); + } + str_count = 0; + while (sensor_bitmask_strings[str_count]) + { + upsdebugx (3, "\t'%s'", sensor_bitmask_strings[str_count]); + if (!strncmp("Entity Present", + sensor_bitmask_strings[str_count], + strlen("Entity Present"))) { + psu_status = PSU_PRESENT; + } + else if (!strncmp("Entity Absent", + sensor_bitmask_strings[str_count], + strlen("Entity Absent"))) { + psu_status = PSU_ABSENT; + } + str_count++; + } + break; + /* Not sure of the values of these, so get as much as possible... */ + case IPMI_MONITORING_SENSOR_TYPE_POWER_UNIT: + upsdebugx (3, "Power Unit: status string"); + str_count = 0; + while (sensor_bitmask_strings[str_count]) + { + upsdebugx (3, "\t'%s'", sensor_bitmask_strings[str_count]); + str_count++; + } + break; + case IPMI_MONITORING_SENSOR_TYPE_SYSTEM_ACPI_POWER_STATE: + upsdebugx (3, "System ACPI Power State: status string"); + str_count = 0; + while (sensor_bitmask_strings[str_count]) + { + upsdebugx (3, "\t'%s'", sensor_bitmask_strings[str_count]); + str_count++; + } + break; + case IPMI_MONITORING_SENSOR_TYPE_BATTERY: + upsdebugx (3, "Battery: status string"); + str_count = 0; + while (sensor_bitmask_strings[str_count]) + { + upsdebugx (3, "\t'%s'", sensor_bitmask_strings[str_count]); + str_count++; + } + break; + } + } + + /* Process status if needed */ + if (psu_status != PSU_STATUS_UNKNOWN) { + + status_init(); + + switch (psu_status) + { + case PSU_PRESENT: + status_set("OL"); + break; + case PSU_ABSENT: + status_set("OFF"); + /* Declare stale */ + retval = -1; + break; + case PSU_POWER_FAILURE: + status_set("OFF"); + break; + } + + status_commit(); + } + + return retval; +} diff --git a/drivers/powerware-mib.c b/drivers/powerware-mib.c index 6f2fb09..7c4d45b 100644 --- a/drivers/powerware-mib.c +++ b/drivers/powerware-mib.c @@ -26,6 +26,17 @@ #define PW_MIB_VERSION "0.6.1" +/* TODO: more sysOID and MIBs support: + * + * Powerware UPS (Ingrasys X-SLOT and BD-SLOT): ".1.3.6.1.4.1.534.1" + * Powerware PXGX cards: ".1.3.6.1.4.1.534.2.12" + * PXGX 2000 cards (UPS): Get xupsIdentModel (".1.3.6.1.4.1.534.1.1.2.0") + * PXGX 1000 cards (PDU/RPP/RPM): Get pduNumPanels ".1.3.6.1.4.1.534.6.6.4.1.1.1.4.0" + */ + +/* Powerware UPS (Ingrasys X-SLOT and BD-SLOT) */ +#define POWERWARE_SYSOID ".1.3.6.1.4.1.534.1" + /* SNMP OIDs set */ #define PW_OID_MFR_NAME "1.3.6.1.4.1.534.1.1.1.0" /* XUPS-MIB::xupsIdentManufacturer.0 */ #define PW_OID_MODEL_NAME "1.3.6.1.4.1.534.1.1.2.0" /* XUPS-MIB::xupsIdentModel.0 */ @@ -313,4 +324,4 @@ static snmp_info_t pw_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL } } ; -mib2nut_info_t powerware = { "pw", PW_MIB_VERSION, "", PW_OID_MODEL_NAME, pw_mib }; +mib2nut_info_t powerware = { "pw", PW_MIB_VERSION, "", PW_OID_MODEL_NAME, pw_mib, POWERWARE_SYSOID }; diff --git a/drivers/raritan-pdu-mib.c b/drivers/raritan-pdu-mib.c index 5147b3d..fd832c1 100644 --- a/drivers/raritan-pdu-mib.c +++ b/drivers/raritan-pdu-mib.c @@ -28,8 +28,10 @@ #define RARITAN_MIB_VERSION "0.4" /* Raritan MIB - * this one uses the Revelation MIB, with a different entry point */ + * this one uses the same MIB as Eaton Revelation, + * but with a different entry point */ #define RARITAN_BASE_OID ".1.3.6.1.4.1.13742" +#define RARITAN_SYSOID RARITAN_BASE_OID #define RARITAN_OID_MODEL_NAME ".1.3.6.1.4.1.13742.1.1.12.0" #define DO_OFF 0 @@ -119,4 +121,4 @@ static snmp_info_t raritan_mib[] = { { NULL, 0, 0, NULL, NULL, 0, NULL, NULL } }; -mib2nut_info_t raritan = { "raritan", RARITAN_MIB_VERSION, "", RARITAN_OID_MODEL_NAME, raritan_mib }; +mib2nut_info_t raritan = { "raritan", RARITAN_MIB_VERSION, "", RARITAN_OID_MODEL_NAME, raritan_mib, RARITAN_SYSOID }; diff --git a/drivers/snmp-ups.c b/drivers/snmp-ups.c index 344f514..1ca6eda 100644 --- a/drivers/snmp-ups.c +++ b/drivers/snmp-ups.c @@ -3,7 +3,7 @@ * Based on NetSNMP API (Simple Network Management Protocol V1-2) * * Copyright (C) - * 2002 - 2010 Arnaud Quette + * 2002 - 2011 Arnaud Quette * 2002 - 2006 Dmitry Frolov * J.W. Hoogervorst * Niels Baggesen @@ -53,6 +53,7 @@ static mib2nut_info_t *mib2nut[] = { &powerware, &aphel_genesisII, &aphel_revelation, + &eaton_marlin, &raritan, &baytech, &compaq, @@ -79,7 +80,7 @@ const char *mibvers; static void disable_transfer_oids(void); #define DRIVER_NAME "Generic SNMP UPS driver" -#define DRIVER_VERSION "0.50" +#define DRIVER_VERSION "0.56" /* driver description structure */ upsdrv_info_t upsdrv_info = { @@ -101,6 +102,9 @@ time_t lastpoll = 0; * automatically guessed at the first pass */ int outlet_index_base = -1; +/* sysOID location */ +#define SYSOID_OID ".1.3.6.1.2.1.1.2.0" + /* --------------------------------------------- * driver functions implementations * --------------------------------------------- */ @@ -144,6 +148,7 @@ void upsdrv_updateinfo(void) upsdebugx(1,"SNMP UPS driver : entering upsdrv_updateinfo()"); /* only update every pollfreq */ + /* FIXME: update status (SU_STATUS_*), à la usbhid-ups, in between */ if (time(NULL) > (lastpoll + pollfreq)) { status_init(); @@ -257,12 +262,20 @@ void upsdrv_cleanup(void) void nut_snmp_init(const char *type, const char *hostname) { + char *ns_options = NULL; const char *community, *version; const char *secLevel = NULL, *authPassword, *privPassword; const char *authProtocol, *privProtocol; upsdebugx(2, "SNMP UPS driver : entering nut_snmp_init(%s)", type); + /* Force numeric OIDs resolution (ie, do not resolve to textual names) + * This is mostly for the convenience of debug output */ + ns_options = snmp_out_toggle_options("n"); + if (ns_options != NULL) { + upsdebugx(2, "Failed to enable numeric OIDs resolution"); + } + /* Initialize the SNMP library */ init_snmp(type); @@ -316,9 +329,11 @@ void nut_snmp_init(const char *type, const char *hostname) case SNMP_SEC_LEVEL_AUTHNOPRIV: if (authPassword == NULL) fatalx(EXIT_FAILURE, "authPassword is required for SNMPv3 in %s mode", secLevel); + break; case SNMP_SEC_LEVEL_AUTHPRIV: if ((authPassword == NULL) || (privPassword == NULL)) fatalx(EXIT_FAILURE, "authPassword and privPassword are required for SNMPv3 in %s mode", secLevel); + break; default: case SNMP_SEC_LEVEL_NOAUTH: /* nothing else needed */ @@ -342,12 +357,15 @@ void nut_snmp_init(const char *type, const char *hostname) /* set the authentication key to a MD5/SHA1 hashed version of our * passphrase (must be at least 8 characters long) */ - if (generate_Ku(g_snmp_sess.securityAuthProto, + if(g_snmp_sess.securityLevel != SNMP_SEC_LEVEL_NOAUTH) { + if (generate_Ku(g_snmp_sess.securityAuthProto, g_snmp_sess.securityAuthProtoLen, - (u_char *) privPassword, strlen(privPassword), + (u_char *) authPassword, strlen(authPassword), g_snmp_sess.securityAuthKey, - &g_snmp_sess.securityAuthKeyLen) != SNMPERR_SUCCESS) { - fatalx(EXIT_FAILURE, "Error generating Ku from authentication pass phrase"); + &g_snmp_sess.securityAuthKeyLen) != + SNMPERR_SUCCESS) { + fatalx(EXIT_FAILURE, "Error generating Ku from authentication pass phrase"); + } } privProtocol = testvar(SU_VAR_PRIVPROT) ? getval(SU_VAR_PRIVPROT) : "DES"; @@ -362,6 +380,20 @@ void nut_snmp_init(const char *type, const char *hostname) } else fatalx(EXIT_FAILURE, "Bad SNMPv3 authProtocol: %s", authProtocol); + + /* set the privacy key to a MD5/SHA1 hashed version of our + * passphrase (must be at least 8 characters long) */ + if(g_snmp_sess.securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { + g_snmp_sess.securityPrivKeyLen = USM_PRIV_KU_LEN; + if (generate_Ku(g_snmp_sess.securityAuthProto, + g_snmp_sess.securityAuthProtoLen, + (u_char *) privPassword, strlen(privPassword), + g_snmp_sess.securityPrivKey, + &g_snmp_sess.securityPrivKeyLen) != + SNMPERR_SUCCESS) { + fatalx(EXIT_FAILURE, "Error generating Ku from privacy pass phrase"); + } + } } else fatalx(EXIT_FAILURE, "Bad SNMP version: %s", version); @@ -447,6 +479,8 @@ bool_t nut_snmp_get_str(const char *OID, char *buf, size_t buf_len, info_lkp_t * size_t len = 0; struct snmp_pdu *pdu; + upsdebugx(3, "Entering nut_snmp_get_str()"); + /* zero out buffer. */ memset(buf, 0, buf_len); @@ -483,11 +517,13 @@ bool_t nut_snmp_get_str(const char *OID, char *buf, size_t buf_len, info_lkp_t * /* convert timeticks to seconds */ len = snprintf(buf, buf_len, "%ld", *pdu->variables->val.integer / 100); break; + case ASN_OBJECT_ID: + len = snprint_objid (buf, buf_len, pdu->variables->val.objid, pdu->variables->val_len / sizeof(oid)); + break; default: - upslogx(LOG_ERR, "[%s] unhandled ASN 0x%x received from %s", + upsdebugx(2, "[%s] unhandled ASN 0x%x received from %s", upsname?upsname:device_name, pdu->variables->type, OID); return FALSE; - break; } snmp_free_pdu(pdu); @@ -673,13 +709,19 @@ void su_setinfo(snmp_info_t *su_info_p, const char *value) if (SU_TYPE(su_info_p) == SU_TYPE_CMD) return; - if (strcasecmp(su_info_p->info_type, "ups.status")) { + if (strcasecmp(su_info_p->info_type, "ups.status")) + { if (value != NULL) dstate_setinfo(su_info_p->info_type, "%s", value); else dstate_setinfo(su_info_p->info_type, "%s", su_info_p->dfl); + dstate_setflags(su_info_p->info_type, su_info_p->info_flags); dstate_setaux(su_info_p->info_type, su_info_p->info_len); + + /* Commit the current value, to avoid staleness with huge + * data collections on slow devices */ + dstate_dataok(); } } @@ -713,36 +755,119 @@ snmp_info_t *su_find_info(const char *type) return NULL; } +/* Try to find the MIB using sysOID matching. + * Return a pointer to a mib2nut definition if found, NULL otherwise */ +mib2nut_info_t *match_sysoid() +{ + char sysOID_buf[LARGEBUF]; + oid device_sysOID[MAX_OID_LEN]; + size_t device_sysOID_len = MAX_OID_LEN; + oid mib2nut_sysOID[MAX_OID_LEN]; + size_t mib2nut_sysOID_len = MAX_OID_LEN; + int i; + + /* Retrieve sysOID value of this device */ + if (nut_snmp_get_str(SYSOID_OID, sysOID_buf, sizeof(sysOID_buf), NULL)) + { + upsdebugx(1, "match_sysoid: device sysOID value = %s", sysOID_buf); + + /* Build OIDs for comparison */ + if (!read_objid(sysOID_buf, device_sysOID, &device_sysOID_len)) + { + upsdebugx(2, "match_sysoid: can't build device_sysOID %s: %s", + sysOID_buf, snmp_api_errstring(snmp_errno)); + + return FALSE; + } + + /* Now, iterate on mib2nut definitions */ + for (i = 0; mib2nut[i] != NULL; i++) + { + upsdebugx(1, "match_sysoid: checking MIB %s", mib2nut[i]->mib_name); + + if (mib2nut[i]->sysOID == NULL) + continue; + + /* Clear variables */ + memset(mib2nut_sysOID, 0, MAX_OID_LEN); + mib2nut_sysOID_len = MAX_OID_LEN; + + if (!read_objid(mib2nut[i]->sysOID, mib2nut_sysOID, &mib2nut_sysOID_len)) + { + upsdebugx(2, "match_sysoid: can't build OID %s: %s", + sysOID_buf, snmp_api_errstring(snmp_errno)); + + /* Try to continue anyway! */ + continue; + } + /* Now compare these */ + upsdebugx(1, "match_sysoid: comparing %s with %s", sysOID_buf, mib2nut[i]->sysOID); + if (!netsnmp_oid_equals(device_sysOID, device_sysOID_len, mib2nut_sysOID, mib2nut_sysOID_len)) + { + upsdebugx(2, "match_sysoid: sysOID matches MIB '%s'!", mib2nut[i]->mib_name); + return mib2nut[i]; + } + } + /* Yell all to call for user report */ + upslogx(LOG_ERR, "No matching MIB found for sysOID '%s'! " \ + "Please report it to NUT developers, with the 'mib' paramater for your devices", + sysOID_buf); + } + else + upsdebugx(2, "Can't get sysOID value"); + + return NULL; +} + /* Load the right snmp_info_t structure matching mib parameter */ bool_t load_mib2nut(const char *mib) { int i; char buf[LARGEBUF]; + mib2nut_info_t *m2n = NULL; upsdebugx(2, "SNMP UPS driver : entering load_mib2nut(%s)", mib); - /* FIXME: first try SysOID (.1.3.6.1.2.1.1.2) - * to speed up detection if mib==auto - * This is an indirection on the MIB's entry point - * examples: - * APHEL-GENESIS-II-MIB => .iso.org.dod.internet.private.enterprises.17373 - * APHEL Revelation MIB => .iso.org.dod.internet.private.enterprises.534.6.6.6 - */ - for (i = 0; mib2nut[i] != NULL; i++) { - if (strcmp(mib, "auto") && strcmp(mib, mib2nut[i]->mib_name)) { - continue; + /* First, try to match against sysOID, if no MIB was provided. + * This should speed up init stage + * (Note: sysOID points the device main MIB entry point) */ + if (!strcmp(mib, "auto")) + { + upsdebugx(1, "trying the new match_sysoid() method"); + m2n = match_sysoid(); + } + + /* Otherwise, revert to the classic method */ + if (m2n == NULL) + { + for (i = 0; mib2nut[i] != NULL; i++) { + /* Is there already a MIB name provided? */ + if (strcmp(mib, "auto") && strcmp(mib, mib2nut[i]->mib_name)) { + continue; + } + upsdebugx(1, "load_mib2nut: trying classic method with '%s' mib", mib2nut[i]->mib_name); + + /* Classic method: test an OID specific to this MIB */ + if (!nut_snmp_get_str(mib2nut[i]->oid_auto_check, buf, sizeof(buf), NULL)) { + continue; + } + /* MIB found */ + m2n = mib2nut[i]; + break; } - upsdebugx(1, "load_mib2nut: trying %s mib", mib2nut[i]->mib_name); - if (!nut_snmp_get_str(mib2nut[i]->oid_auto_check, buf, sizeof(buf), NULL)) { - continue; - } - snmp_info = mib2nut[i]->snmp_info; - OID_pwr_status = mib2nut[i]->oid_pwr_status; - mibname = mib2nut[i]->mib_name; - mibvers = mib2nut[i]->mib_version; + } + + /* Store the result, if any */ + if (m2n != NULL) + { + snmp_info = m2n->snmp_info; + OID_pwr_status = m2n->oid_pwr_status; + mibname = m2n->mib_name; + mibvers = m2n->mib_version; upsdebugx(1, "load_mib2nut: using %s mib", mibname); return TRUE; } + /* Did we find something or is it really an unknown mib */ if (strcmp(mib, "auto") != 0) { fatalx(EXIT_FAILURE, "Unknown mibs value: %s", mib); @@ -852,17 +977,25 @@ void free_info(snmp_info_t *su_info_p) int base_snmp_outlet_index(const char *OID_template) { int base_index = outlet_index_base; + char test_OID[SU_INFOSIZE]; if (outlet_index_base == -1) { /* not initialised yet */ - char test_OID[SU_INFOSIZE]; - for (base_index = 0 ; base_index < 2 ; base_index++) { - sprintf(test_OID, OID_template, base_index); - if (nut_snmp_get(test_OID) != NULL) - break; + /* Workaround for Eaton Marlin, while waiting for a FW fix and + * a driver rewrite (advanced hooks) */ + if ((mibname != NULL) && (!strncmp(mibname, "eaton_epdu", 11))) + { + upsdebugx(3, "Appying Eaton Marlin workaround"); + outlet_index_base = base_index = 1; + } else { + for (base_index = 0 ; base_index < 2 ; base_index++) { + sprintf(test_OID, OID_template, base_index); + if (nut_snmp_get(test_OID) != NULL) + break; + } + outlet_index_base = base_index; } - outlet_index_base = base_index; } upsdebugx(3, "base_snmp_outlet_index: %i", outlet_index_base); return base_index; @@ -1066,8 +1199,9 @@ bool_t snmp_ups_walk(int mode) instantiate_info(su_info_p, &cur_info_p); for (cur_outlet_number = base_snmp_outlet_index(su_info_p->OID) ; - cur_outlet_number < outlet_count ; cur_outlet_number++) { - + cur_outlet_number < (outlet_count + base_snmp_outlet_index(su_info_p->OID)) ; + cur_outlet_number++) + { cur_nut_index = cur_outlet_number + base_nut_outlet_offset(); sprintf((char*)cur_info_p.info_type, su_info_p->info_type, cur_nut_index); diff --git a/drivers/snmp-ups.h b/drivers/snmp-ups.h index a42c15e..d130428 100644 --- a/drivers/snmp-ups.h +++ b/drivers/snmp-ups.h @@ -75,6 +75,10 @@ for each OID request we made), instead of sending many small packets #include #include +/* Force numeric OIDs by disabling MIB loading */ +#define DISABLE_MIB_LOADING 1 + + #define DEFAULT_POLLFREQ 30 /* in seconds */ /* use explicit booleans */ @@ -193,11 +197,13 @@ typedef struct { #define SU_ERR_RATE 100 /* only print every nth error once limiting starts */ typedef struct { - const char *mib_name; - const char *mib_version; - const char *oid_pwr_status; - const char *oid_auto_check; - snmp_info_t *snmp_info; /* pointer to the good Snmp2Nut lookup data */ + const char *mib_name; + const char *mib_version; + const char *oid_pwr_status; + const char *oid_auto_check; /* FIXME: rename to SysOID */ + snmp_info_t *snmp_info; /* pointer to the good Snmp2Nut lookup data */ + const char *sysOID; /* OID to match against sysOID, aka MIB + * main entry point */ } mib2nut_info_t; diff --git a/drivers/usb-common.c b/drivers/usb-common.c index e51f3cf..e459872 100644 --- a/drivers/usb-common.c +++ b/drivers/usb-common.c @@ -116,7 +116,7 @@ int USBNewExactMatcher(USBDeviceMatcher_t **matcher, USBDevice_t *hd) USBDevice_t *data; m = malloc(sizeof(*m)); - if (!matcher) { + if (!m) { return -1; } diff --git a/include/Makefile.in b/include/Makefile.in index 6767600..c9db7a7 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -44,6 +44,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -110,10 +112,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -151,6 +157,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -215,6 +225,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/include/config.h.in b/include/config.h.in index ae5bb0a..f0a94b6 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -36,6 +36,18 @@ /* Define to 1 if you have the `atexit' function. */ #undef HAVE_ATEXIT +/* Define to 1 if you have the header file. */ +#undef HAVE_AVAHI_CLIENT_CLIENT_H + +/* Define to 1 if you have the `avahi_client_new' function. */ +#undef HAVE_AVAHI_CLIENT_NEW + +/* Define to 1 if you have the header file. */ +#undef HAVE_AVAHI_COMMON_MALLOC_H + +/* Define to 1 if you have the `avahi_free' function. */ +#undef HAVE_AVAHI_FREE + /* Define to 1 if you have the `cfsetispeed' function. */ #undef HAVE_CFSETISPEED @@ -77,6 +89,9 @@ /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK +/* Define to 1 if you have the header file. */ +#undef HAVE_FREEIPMI_FREEIPMI_H + /* Define to 1 if you have the header file. */ #undef HAVE_GDFONTMB_H @@ -86,6 +101,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_GETOPT_H +/* Define to 1 if you have the `getopt_long' function. */ +#undef HAVE_GETOPT_LONG + /* Define to 1 if you have the `getpassphrase' function. */ #undef HAVE_GETPASSPHRASE @@ -101,6 +119,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_IPMI_MONITORING_H + /* Define if you have Boutell's libgd installed */ #undef HAVE_LIBGD @@ -149,6 +170,9 @@ /* Define to 1 if you have the `pm_connect' function. */ #undef HAVE_PM_CONNECT +/* Define to enable pthread support code */ +#undef HAVE_PTHREAD + /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV @@ -325,6 +349,18 @@ /* Version number of package */ #undef VERSION +/* Define to enable avahi support */ +#undef WITH_AVAHI + +/* Define to enable IPMI support using FreeIPMI */ +#undef WITH_FREEIPMI + +/* Define to enable IPMI support */ +#undef WITH_IPMI + +/* Define to enable Neon XML/HTTP support */ +#undef WITH_NEON + /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD diff --git a/include/nut_version.h b/include/nut_version.h index 42cfb0c..cfd5f09 100644 --- a/include/nut_version.h +++ b/include/nut_version.h @@ -1,3 +1,3 @@ /* Autogenerated file. Do not change. */ /* This file was generated by "make". */ -#define NUT_VERSION_MACRO "2.6.1-3015:3023" +#define NUT_VERSION_MACRO "2.6.2-3235:3238" diff --git a/include/parseconf.h b/include/parseconf.h index 00d4d8d..d85c89d 100644 --- a/include/parseconf.h +++ b/include/parseconf.h @@ -20,6 +20,8 @@ #ifndef PARSECONF_H_SEEN #define PARSECONF_H_SEEN 1 +#include + #ifdef __cplusplus /* *INDENT-OFF* */ extern "C" { diff --git a/lib/Makefile.in b/lib/Makefile.in index 73e3a58..aa13f0c 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -48,6 +48,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -138,10 +140,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -179,6 +185,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -243,6 +253,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/m4/nut_check_libavahi.m4 b/m4/nut_check_libavahi.m4 new file mode 100644 index 0000000..034d31a --- /dev/null +++ b/m4/nut_check_libavahi.m4 @@ -0,0 +1,78 @@ +dnl Check for LIBAVAHI compiler flags. On success, set nut_have_neon="yes" +dnl and set LIBAVAHI_CFLAGS and LIBAVAHI_LIBS. On failure, set +dnl nut_have_avahi="no". This macro can be run multiple times, but will +dnl do the checking only once. + +AC_DEFUN([NUT_CHECK_LIBAVAHI], +[ +if test -z "${nut_have_avahi_seen}"; then + nut_have_avahi_seen=yes + + dnl save CFLAGS and LIBS + CFLAGS_ORIG="${CFLAGS}" + LIBS_ORIG="${LIBS}" + + dnl See which version of the avahi library (if any) is installed + AC_MSG_CHECKING(for avahi-core version via pkg-config (0.6.30 minimum required)) + AVAHI_CORE_VERSION="`pkg-config --silence-errors --modversion avahi-core 2>/dev/null`" + if test "$?" != "0" -o -z "${AVAHI_CORE_VERSION}"; then + AVAHI_CORE_VERSION="none" + fi + AC_MSG_RESULT(${AVAHI_CORE_VERSION} found) + + AC_MSG_CHECKING(for avahi-client version via pkg-config (0.6.30 minimum required)) + AVAHI_CLIENT_VERSION="`pkg-config --silence-errors --modversion avahi-client 2>/dev/null`" + if test "$?" != "0" -o -z "${AVAHI_CLIENT_VERSION}"; then + AVAHI_CLIENT_VERSION="none" + fi + AC_MSG_RESULT(${AVAHI_CLIENT_VERSION} found) + + AC_MSG_CHECKING(for avahi cflags) + AC_ARG_WITH(avahi-includes, + AS_HELP_STRING([@<:@--with-avahi-includes=CFLAGS@:>@], [include flags for the avahi library]), + [ + case "${withval}" in + yes|no) + AC_MSG_ERROR(invalid option --with(out)-avahi-includes - see docs/configure.txt) + ;; + *) + CFLAGS="${withval}" + ;; + esac + ], [CFLAGS="`pkg-config --silence-errors --cflags avahi-core avahi-client 2>/dev/null`"]) + AC_MSG_RESULT([${CFLAGS}]) + + AC_MSG_CHECKING(for avahi ldflags) + AC_ARG_WITH(avahi-libs, + AS_HELP_STRING([@<:@--with-avahi-libs=LIBS@:>@], [linker flags for the avahi library]), + [ + case "${withval}" in + yes|no) + AC_MSG_ERROR(invalid option --with(out)-avahi-libs - see docs/configure.txt) + ;; + *) + LIBS="${withval}" + ;; + esac + ], [LIBS="`pkg-config --silence-errors --libs avahi-core avahi-client 2>/dev/null`"]) + AC_MSG_RESULT([${LIBS}]) + + dnl check if avahi-core is usable + AC_CHECK_HEADERS(avahi-common/malloc.h, [nut_have_avahi=yes], [nut_have_avahi=no], [AC_INCLUDES_DEFAULT]) + AC_CHECK_FUNCS(avahi_free, [], [nut_have_avahi=no]) + + if test "${nut_have_avahi}" = "yes"; then + dnl check if avahi-client is usable + AC_CHECK_HEADERS(avahi-client/client.h, [nut_have_avahi=yes], [nut_have_avahi=no], [AC_INCLUDES_DEFAULT]) + AC_CHECK_FUNCS(avahi_client_new, [], [nut_have_avahi=no]) + if test "${nut_have_avahi}" = "yes"; then + LIBAVAHI_CFLAGS="${CFLAGS}" + LIBAVAHI_LIBS="${LIBS}" + fi + fi + + dnl restore original CFLAGS and LIBS + CFLAGS="${CFLAGS_ORIG}" + LIBS="${LIBS_ORIG}" +fi +]) diff --git a/m4/nut_check_libfreeipmi.m4 b/m4/nut_check_libfreeipmi.m4 new file mode 100644 index 0000000..0800886 --- /dev/null +++ b/m4/nut_check_libfreeipmi.m4 @@ -0,0 +1,85 @@ +dnl Check for FreeIPMI (LIBFREEIPMI) compiler flags. On success, set +dnl nut_have_freeipmi="yes" and nut_ipmi_lib="FreeIPMI", and define WITH_IPMI, +dnl WITH_FREEIPMI, LIBIPMI_CFLAGS and LIBIPMI_LIBS. On failure, set +dnl nut_have_freeipmi="no". +dnl This macro can be run multiple times, but will do the checking only once. + +AC_DEFUN([NUT_CHECK_LIBFREEIPMI], +[ +if test -z "${nut_have_libfreeipmi_seen}"; then + nut_have_libfreeipmi_seen=yes + + dnl save CFLAGS and LIBS + CFLAGS_ORIG="${CFLAGS}" + LIBS_ORIG="${LIBS}" + + AC_MSG_CHECKING(for FreeIPMI version via pkg-config) + dnl pkg-config support requires Freeipmi 1.0.5, released on Thu Jun 30 2011 + dnl but NUT should only require 0.8.5 or 1.0.1 (comment from upstream Al Chu) + FREEIPMI_VERSION="`pkg-config --silence-errors --modversion libfreeipmi 2>/dev/null`" + if test "$?" = "0" -a -n "${FREEIPMI_VERSION}"; then + CFLAGS="`pkg-config --silence-errors --cflags libfreeipmi libipmimonitoring 2>/dev/null`" + LIBS="`pkg-config --silence-errors --libs libfreeipmi libipmimonitoring 2>/dev/null`" + else + FREEIPMI_VERSION="none" + CFLAGS="" + LIBS="-lfreeipmi -lipmimonitoring" + fi + AC_MSG_RESULT(${FREEIPMI_VERSION} found) + + dnl allow overriding FreeIPMI settings if the user knows best + AC_MSG_CHECKING(for FreeIPMI cflags) + AC_ARG_WITH(freeipmi-includes, + AS_HELP_STRING([@<:@--with-freeipmi-includes=CFLAGS@:>@], [include flags for the FreeIPMI library]), + [ + case "${withval}" in + yes|no) + AC_MSG_ERROR(invalid option --with(out)-freeipmi-includes - see docs/configure.txt) + ;; + *) + CFLAGS="${withval}" + ;; + esac + ], []) + AC_MSG_RESULT([${CFLAGS}]) + + AC_MSG_CHECKING(for FreeIPMI ldflags) + AC_ARG_WITH(freeipmi-libs, + AS_HELP_STRING([@<:@--with-freeipmi-libs=LIBS@:>@], [linker flags for the FreeIPMI library]), + [ + case "${withval}" in + yes|no) + AC_MSG_ERROR(invalid option --with(out)-freeipmi-libs - see docs/configure.txt) + ;; + *) + LIBS="${withval}" + ;; + esac + ], []) + AC_MSG_RESULT([${LIBS}]) + + dnl check if freeipmi is usable with our current flags + AC_CHECK_HEADERS(freeipmi/freeipmi.h, [nut_have_freeipmi=yes], [nut_have_freeipmi=no], [AC_INCLUDES_DEFAULT]) + AC_CHECK_HEADERS(ipmi_monitoring.h, [], [nut_have_freeipmi=no], [AC_INCLUDES_DEFAULT]) + AC_SEARCH_LIBS([ipmi_ctx_create], [freeipmi], [], [nut_have_freeipmi=no]) + dnl when version cannot be tested (prior to 1.0.5, with no pkg-config) + dnl we have to check for some specific functions + AC_SEARCH_LIBS([ipmi_ctx_find_inband], [freeipmi], [], [nut_have_freeipmi=no]) + AC_SEARCH_LIBS([ipmi_fru_parse_ctx_create], [freeipmi], [], [nut_have_freeipmi=no]) + AC_SEARCH_LIBS([ipmi_monitoring_init], [ipmimonitoring], [], [nut_have_freeipmi=no]) + + if test "${nut_have_freeipmi}" = "yes"; then + nut_with_ipmi="yes" + nut_ipmi_lib="(FreeIPMI)" + nut_have_libipmi="yes" + AC_DEFINE(WITH_IPMI, 1, [Define to enable IPMI support]) + AC_DEFINE(WITH_FREEIPMI, 1, [Define to enable IPMI support using FreeIPMI]) + LIBIPMI_CFLAGS="${CFLAGS}" + LIBIPMI_LIBS="${LIBS}" + fi + + dnl restore original CFLAGS and LIBS + CFLAGS="${CFLAGS_ORIG}" + LIBS="${LIBS_ORIG}" +fi +]) diff --git a/m4/nut_check_os.m4 b/m4/nut_check_os.m4 index e913a47..c735712 100644 --- a/m4/nut_check_os.m4 +++ b/m4/nut_check_os.m4 @@ -44,6 +44,7 @@ AC_DEFUN_ONCE([NUT_OS_FUNCTIONS], AC_DEFUN([NUT_CHECK_OS], [ + m4_pattern_allow([^PKG_TARGET$]) # Look for all possible source of OS name resolution # 1) we look for a LSB release info file eval "dist_search_path=\" diff --git a/m4/nut_report_feature.m4 b/m4/nut_report_feature.m4 index e8d73b6..fc57470 100644 --- a/m4/nut_report_feature.m4 +++ b/m4/nut_report_feature.m4 @@ -5,7 +5,8 @@ AC_DEFUN([NUT_REPORT], nut_report_feature_flag="1" ac_clean_files="${ac_clean_files} conf_nut_report_feature" echo > conf_nut_report_feature - echo -e "Configuration summary:\n======================" >> conf_nut_report_feature + echo "Configuration summary:" >> conf_nut_report_feature + echo "======================" >> conf_nut_report_feature fi echo "$1: $2" >> conf_nut_report_feature ]) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 4a3f064..2e0ed23 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -1,4 +1,5 @@ EXTRA_DIST = README \ +avahi/nut.service.in \ HP-UX/Makefile \ HP-UX/nut-drvctl \ HP-UX/nut-drvctl.sh \ @@ -22,4 +23,4 @@ upower/95-upower-hid.rules \ Windows/halt.c \ Windows/Makefile -SUBDIRS = augeas hal hotplug python udev +SUBDIRS = augeas hal hotplug java python systemd udev diff --git a/scripts/Makefile.in b/scripts/Makefile.in index 895ca91..97182e1 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -43,6 +43,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -149,10 +151,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -190,6 +196,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -254,6 +264,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -264,6 +276,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ udevdir = @udevdir@ EXTRA_DIST = README \ +avahi/nut.service.in \ HP-UX/Makefile \ HP-UX/nut-drvctl \ HP-UX/nut-drvctl.sh \ @@ -287,7 +300,7 @@ upower/95-upower-hid.rules \ Windows/halt.c \ Windows/Makefile -SUBDIRS = augeas hal hotplug python udev +SUBDIRS = augeas hal hotplug java python systemd udev all: all-recursive .SUFFIXES: diff --git a/scripts/README b/scripts/README index d795fe9..0b1b981 100644 --- a/scripts/README +++ b/scripts/README @@ -7,7 +7,9 @@ specific USB devices, - UPower (previously DeviceKit-power) rules file, - Python Client module and application, - Perl client module, -- Augeas support lenses and modules for NUT. +- Augeas support lenses and modules for NUT, +- Java client library and test application, +- systemd support files. They have either been contributed by users of the software, or by the NUT Team itself. diff --git a/scripts/augeas/Makefile.in b/scripts/augeas/Makefile.in index f35554d..f9f6293 100644 --- a/scripts/augeas/Makefile.in +++ b/scripts/augeas/Makefile.in @@ -48,6 +48,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -116,10 +118,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -157,6 +163,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -221,6 +231,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/scripts/augeas/README b/scripts/augeas/README index 1f12136..3be147e 100644 --- a/scripts/augeas/README +++ b/scripts/augeas/README @@ -203,3 +203,59 @@ Test the conformity testing module Existing configuration files can be tested for conformity. To do so, use: $ augparse -I ./ ./test_nut.aug + + +Complete configuration wizard example +------------------------------------- + +Here is a Python example that generate a complete and usable standalone configuration: + +-------------------------------------------------------------------------------- +import augeas + +device_name="dev1" +driver_name="usbhid-ups" +port_name="auto" + +a = augeas.augeas() + +# Generate nut.conf +a.set("/files/etc/nut/nut.conf/MODE", "standalone") + +# Generate ups.conf +# FIXME: chroot, driverpath? +a.set(("/files/etc/nut/ups.conf/%s/driver" % device_name), driver_name) +a.set(("/files/etc/nut/ups.conf/%s/port" % device_name), port_name) + +# Generate upsd.conf +a.set("/files/etc/nut/upsd.conf/#comment[1]", "just to touch the file!") + +# Generate upsd.users +user = "admin" +a.set(("/files/etc/nut/upsd.users/%s/password" % user), "dummypass") +a.set(("/files/etc/nut/upsd.users/%s/actions/SET" % user), "") +# FIXME: instcmds lens should be fixed, as per the above rule +a.set(("/files/etc/nut/upsd.users/%s/instcmds" % user), "ALL") + +monuser = "monuser" +monpasswd = "******" +a.set(("/files/etc/nut/upsd.users/%s/password" % monuser), monpasswd) +a.set(("/files/etc/nut/upsd.users/%s/upsmon" % monuser), "master") + +# Generate upsmon.conf +a.set("/files/etc/nut/upsmon.conf/MONITOR/system/upsname", device_name) +# Note: we prefer to omit localhost, not to be bound to a specific +# entry in /etc/hosts, and thus be more generic +#a.set("/files/etc/nut/upsmon.conf/MONITOR/system/hostname", "localhost") +a.set("/files/etc/nut/upsmon.conf/MONITOR/powervalue", "1") +a.set("/files/etc/nut/upsmon.conf/MONITOR/username", monuser) +a.set("/files/etc/nut/upsmon.conf/MONITOR/password", monpasswd) +a.set("/files/etc/nut/upsmon.conf/MONITOR/type", "master") + +# FIXME: glitch on the generated content +a.set("/files/etc/nut/upsmon.conf/SHUTDOWNCMD", "/sbin/shutdown -h +0") + +# save config +a.save() +a.close() +-------------------------------------------------------------------------------- diff --git a/scripts/augeas/nutupsconf.aug.in b/scripts/augeas/nutupsconf.aug.in index 1c5918e..ed087fe 100644 --- a/scripts/augeas/nutupsconf.aug.in +++ b/scripts/augeas/nutupsconf.aug.in @@ -54,6 +54,8 @@ let ups_fields = "driver" | "advorder" | "authPassword" | "authProtocol" + | "authtype" + | "awd" | "batteryPercentage" | "battext" | "baud_rate" @@ -70,6 +72,7 @@ let ups_fields = "driver" | "fake_lowbatt" | "flash" | "frequency" + | "fruid" | "full_update" | "houroff" | "houron" @@ -120,6 +123,7 @@ let ups_fields = "driver" | "sdtype" | "secLevel" | "secName" + | "sensorid" | "serial" | "serialnumber" | "shutdownArguments" @@ -139,6 +143,7 @@ let ups_fields = "driver" | "usd" | "use_crlf" | "use_pre_lf" + | "username" | "validationSequence" | "vendor" | "vendorid" diff --git a/scripts/avahi/nut.service.in b/scripts/avahi/nut.service.in new file mode 100644 index 0000000..5c2eb3e --- /dev/null +++ b/scripts/avahi/nut.service.in @@ -0,0 +1,34 @@ + + + + + + + + + + %h + + + _nut._tcp + @PORT@ + + + diff --git a/scripts/hal/Makefile.in b/scripts/hal/Makefile.in index ed3dc02..646ff23 100644 --- a/scripts/hal/Makefile.in +++ b/scripts/hal/Makefile.in @@ -45,6 +45,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -134,10 +136,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -175,6 +181,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -239,6 +249,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/scripts/hal/ups-nut-device.fdi.in b/scripts/hal/ups-nut-device.fdi.in index 609c17d..30c6f12 100644 --- a/scripts/hal/ups-nut-device.fdi.in +++ b/scripts/hal/ups-nut-device.fdi.in @@ -194,6 +194,24 @@ ups + + + + battery + battery + hald-addon-blazer_usb + ups + + + + + + battery + battery + hald-addon-blazer_usb + ups + + @@ -255,6 +273,15 @@ ups + + + + battery + battery + hald-addon-richcomm_usb + ups + + @@ -515,6 +542,15 @@ ups + + + + battery + battery + hald-addon-blazer_usb + ups + + @@ -526,6 +562,15 @@ ups + + + + battery + battery + hald-addon-blazer_usb + ups + + diff --git a/scripts/hotplug/Makefile.in b/scripts/hotplug/Makefile.in index ae6a80f..9bbde22 100644 --- a/scripts/hotplug/Makefile.in +++ b/scripts/hotplug/Makefile.in @@ -47,6 +47,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -139,10 +141,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -180,6 +186,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -244,6 +254,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/scripts/hotplug/libhid.usermap b/scripts/hotplug/libhid.usermap index 9b301a6..4eba6e3 100644 --- a/scripts/hotplug/libhid.usermap +++ b/scripts/hotplug/libhid.usermap @@ -64,6 +64,10 @@ libhidups 0x0003 0x051d 0x0003 0x0000 0x0000 0x00 libhidups 0x0003 0x0592 0x0002 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # PW 9140 libhidups 0x0003 0x0592 0x0004 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Agiler UPS +libhidups 0x0003 0x05b8 0x0000 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Belkin F6C1200-UNV +libhidups 0x0003 0x0665 0x5161 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Phoenixtec # various models @@ -84,6 +88,8 @@ libhidups 0x0003 0x0764 0x0005 0x0000 0x0000 0x00 libhidups 0x0003 0x0764 0x0501 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # OR2200LCDRM2U libhidups 0x0003 0x0764 0x0601 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Sweex 1000VA +libhidups 0x0003 0x0925 0x1234 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # TrippLite # e.g. OMNIVS1000, SMART550USB, ... @@ -160,7 +166,11 @@ libhidups 0x0003 0x0d9f 0x00a4 0x0000 0x0000 0x00 libhidups 0x0003 0x0d9f 0x00a5 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # PowerCOM BNT - Black Knight Pro libhidups 0x0003 0x0d9f 0x00a6 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# Unitek Alpha 1200Sx +libhidups 0x0003 0x0f03 0x0001 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 # Liebert # Liebert PowerSure PSA UPS libhidups 0x0003 0x10af 0x0001 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 +# GE EP series +libhidups 0x0003 0x14f0 0x00c9 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000 diff --git a/scripts/java/Makefile.am b/scripts/java/Makefile.am new file mode 100644 index 0000000..83f5c1d --- /dev/null +++ b/scripts/java/Makefile.am @@ -0,0 +1,15 @@ +# TODO: Java / Maven build integration + +EXTRA_DIST = README \ +jNut/pom.xml \ +jNut/README \ +jNut/src/main/java/org/networkupstools/jnut/Client.java \ +jNut/src/main/java/org/networkupstools/jnut/Command.java \ +jNut/src/main/java/org/networkupstools/jnut/Device.java \ +jNut/src/main/java/org/networkupstools/jnut/NutException.java \ +jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java \ +jNut/src/main/java/org/networkupstools/jnut/Variable.java \ +jNut/src/test/java/org/networkupstools/jnut/ClientTest.java \ +jNutList/pom.xml \ +jNutList/README \ +jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java diff --git a/scripts/java/Makefile.in b/scripts/java/Makefile.in new file mode 100644 index 0000000..8e5a589 --- /dev/null +++ b/scripts/java/Makefile.in @@ -0,0 +1,441 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# TODO: Java / Maven build integration +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = scripts/java +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nut_arg_with.m4 \ + $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ + $(top_srcdir)/m4/nut_check_libgd.m4 \ + $(top_srcdir)/m4/nut_check_libhal.m4 \ + $(top_srcdir)/m4/nut_check_libneon.m4 \ + $(top_srcdir)/m4/nut_check_libnetsnmp.m4 \ + $(top_srcdir)/m4/nut_check_libpowerman.m4 \ + $(top_srcdir)/m4/nut_check_libssl.m4 \ + $(top_srcdir)/m4/nut_check_libusb.m4 \ + $(top_srcdir)/m4/nut_check_libwrap.m4 \ + $(top_srcdir)/m4/nut_check_os.m4 \ + $(top_srcdir)/m4/nut_config_libhal.m4 \ + $(top_srcdir)/m4/nut_report_feature.m4 \ + $(top_srcdir)/m4/nut_type_socklen_t.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +A2X = @A2X@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFPATH = @CONFPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBLATEX = @DBLATEX@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOC_BUILD_LIST = @DOC_BUILD_LIST@ +DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@ +DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@ +DRIVER_MAN_LIST = @DRIVER_MAN_LIST@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@ +HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@ +HAL_FDI_PATH = @HAL_FDI_PATH@ +HAL_USER = @HAL_USER@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBGD_CFLAGS = @LIBGD_CFLAGS@ +LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ +LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ +LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ +LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ +LIBNEON_LIBS = @LIBNEON_LIBS@ +LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ +LIBNETSNMP_LIBS = @LIBNETSNMP_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@ +LIBPOWERMAN_LIBS = @LIBPOWERMAN_LIBS@ +LIBS = @LIBS@ +LIBSSL_CFLAGS = @LIBSSL_CFLAGS@ +LIBSSL_LIBS = @LIBSSL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NETLIBS = @NETLIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS_NAME = @OS_NAME@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ +RANLIB = @RANLIB@ +RUN_AS_GROUP = @RUN_AS_GROUP@ +RUN_AS_USER = @RUN_AS_USER@ +SED = @SED@ +SERLIBS = @SERLIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STATEPATH = @STATEPATH@ +STRIP = @STRIP@ +SUN_LIBUSB = @SUN_LIBUSB@ +VERSION = @VERSION@ +WORDS_BIGENDIAN = @WORDS_BIGENDIAN@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cgiexecdir = @cgiexecdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverexecdir = @driverexecdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hotplugdir = @hotplugdir@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +udevdir = @udevdir@ +EXTRA_DIST = README \ +jNut/pom.xml \ +jNut/README \ +jNut/src/main/java/org/networkupstools/jnut/Client.java \ +jNut/src/main/java/org/networkupstools/jnut/Command.java \ +jNut/src/main/java/org/networkupstools/jnut/Device.java \ +jNut/src/main/java/org/networkupstools/jnut/NutException.java \ +jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java \ +jNut/src/main/java/org/networkupstools/jnut/Variable.java \ +jNut/src/test/java/org/networkupstools/jnut/ClientTest.java \ +jNutList/pom.xml \ +jNutList/README \ +jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/java/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu scripts/java/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/scripts/java/README b/scripts/java/README new file mode 100644 index 0000000..95d1bee --- /dev/null +++ b/scripts/java/README @@ -0,0 +1,14 @@ +Java NUT Client files +~~~~~~~~~~~~~~~~~~~~~ + +This directory contains various NUT Client related java source files, written by +Emilien Kia, sponsored by Eaton, and released under GPL v2. + +* "jNut": this directory contains maven project and source files for jNut, +which is a Java abstraction bundle to access NUT server(s). +You can use it in Java programs to access NUT's upsd data server in a simple +way, without having to know the NUT protocol. + +* "jNutList": this directory contains maven project and source files for +jNutList, a simple Java example program using jNut which connect to an UPSD, +lists its ups and their variables and commands. diff --git a/scripts/java/jNut/README b/scripts/java/jNut/README new file mode 100644 index 0000000..3c75e24 --- /dev/null +++ b/scripts/java/jNut/README @@ -0,0 +1,71 @@ +jNut library +~~~~~~~~~~~~ + +This directory contains source files for the jNut library, +which is a Java abstraction bundle to access NUT server(s). +You can use it in Java programs to access NUT's upsd data server in a simple +way, without having to know the NUT protocol. + +jNut building requirements +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +jNut requires to be build : +- A Java JDK 6 correctly set in environment (ie bin folder in path) +- A Maven 3 installation set in environment (ie bin folder in path) with +sufficient configuration (internet connection, local repository) to let maven +get all plugins to make processes. + +jNut is written in Java SE 1.4 and is tuned to be compiled to Java 1.4 code +level so most of environment can use it. + +jNut building +^^^^^^^^^^^^^ + +Once JDK and Maven installed and configured, just go into the jNut directory +and type: + + mvn install + +The produced package called 'jNut-x.x-xxx.jar' is located in 'target' +subdirectory. + +jNut javadoc +^^^^^^^^^^^^ + +You can generate jNut javadoc by typing: + + mvn javadoc:javadoc + +Documentation will be generated in 'target/site/apidocs' subdirectory and its +entry point is located at 'target/site/apidocs/index.html'. + +Workspace cleaning +^^^^^^^^^^^^^^^^^^ + +The jNut workspace can be cleaned by removing the 'target' subdirectory or by +typing: + + mvn clean + +Unit test notes +^^^^^^^^^^^^^^^ + +jNut sources embed some unit tests in the 'src/test/java' subdirectory. +These tests are based on JUnit and are executed between compilation and +packaging phases at each build. + +Implementation notes +^^^^^^^^^^^^^^^^^^^^ + +Currently, jNut is not thread safe. It is not protected against concurrent +queries but queries to different clients can be done in parallel as there are +done on different sockets. + +Moreover, jNut have no connection preservation system so servers can break down +connections due to timeout. +Application using retrieved data must forget them when a disconnection occurs. +If the application want to maintain the connection, it must implement a +ping-pong mecanism itself. + +At present time, jNut do not support SSL connection. It is planned for near +future. diff --git a/scripts/java/jNut/pom.xml b/scripts/java/jNut/pom.xml new file mode 100644 index 0000000..a2c0e5c --- /dev/null +++ b/scripts/java/jNut/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + org.networkupstools + jNut + 0.1-SNAPSHOT + jar + + jNut + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.4 + 1.4 + + + + + + diff --git a/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java new file mode 100644 index 0000000..474f812 --- /dev/null +++ b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Client.java @@ -0,0 +1,619 @@ +/* Client.java + + Copyright (C) 2011 Eaton + + 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 +*/ +package org.networkupstools.jnut; + +import java.io.IOException; +import java.net.UnknownHostException; +import java.util.ArrayList; + +/** + * A jNut client is start point to dialog to UPSD. + * It can connect to an UPSD then retrieve its device list. + * It support authentication by login/password. + *

+ * You can directly create and connect a client by using the + * Client(String host, int port, String login, String passwd) constructor + * or use a three phase construction: + *

    + *
  • empty constructor + *
  • setting host, port, login and password with setters + *
  • call empty connect() + *
+ *

+ * Objects retrieved by Client are attached (directly or indirectly) to it. + * If the connection is closed, attached objects must not be used anymore (GC). + *

+ * Note: The jNut Client does not support any reconnection nor ping mechanism, + * so the calling application must know the UPSD can timeout the connection. + *

+ * Note: Retrieved values are not valid along the time, they are valid at the + * precise moment they are retrieved. + * + * @author Emilien Kia + */ +public class Client { + + /** + * Host to which connect. + * Network name or IP. + * Default to "127.0.0.1" + */ + private String host = "127.0.0.1"; + + /** + * IP port. + * Default to 3493 + */ + private int port = 3493; + + /** + * Login to use to connect to UPSD. + */ + private String login = null; + + /** + * Password to use to connect to UPSD. + */ + private String passwd = null; + + /** + * Communication socket + */ + private StringLineSocket socket = null; + + + /** + * Get the host name or address to which client is (or will be) connected. + * @return Host name or address. + */ + public String getHost() { + return host; + } + + /** + * Set the host name (or address) to which the client will intend to connect to at next connection. + * @param host New host name or address. + */ + public void setHost(String host) { + this.host = host; + } + + /** + * Get the login with which the client is (or will be connected). + * @return The login. + */ + public String getLogin() { + return login; + } + + /** + * Set the login with which the client will intend to connect. + * @param login New login. + */ + public void setLogin(String login) { + this.login = login; + } + + /** + * Get the password with which the client is (or will be connected). + * @return The password. + */ + public String getPasswd() { + return passwd; + } + + /** + * Set the password with which the client will intend to connect. + * @param passwd New password. + */ + public void setPasswd(String passwd) { + this.passwd = passwd; + } + + /** + * Get the port to which client is (or will be) connected. + * @return Port number. + */ + public int getPort() { + return port; + } + + /** + * Set the port to which client is (or will be) connected. + * @param port Port number. + */ + public void setPort(int port) { + this.port = port; + } + + + + /** + * Default constructor. + */ + public Client() + { + } + + /** + * Connection constructor. + * Construct the Client object and intend to connect. + * Throw an exception if cannot connect. + * @param host Host to which connect. + * @param port IP port. + * @param login Login to use to connect to UPSD. + * @param passwd Password to use to connect to UPSD. + */ + public Client(String host, int port, String login, String passwd) throws IOException, UnknownHostException, NutException + { + connect(host, port, login, passwd); + } + + /** + * Intent to connect and authenticate to an UPSD with specified parameters. + * Throw an exception if cannot connect. + * @param host Host to which connect. + * @param port IP port. + * @param login Login to use to connect to UPSD. + * @param passwd Password to use to connect to UPSD. + */ + public void connect(String host, int port, String login, String passwd) throws IOException, UnknownHostException, NutException + { + this.host = host; + this.port = port; + this.login = login; + this.passwd = passwd; + connect(); + } + + /** + * Intent to connect to an UPSD with specified parameters without authentication. + * Throw an exception if cannot connect. + * @param host Host to which connect. + * @param port IP port. + */ + public void connect(String host, int port) throws IOException, UnknownHostException, NutException + { + this.host = host; + this.port = port; + connect(); + } + + /** + * Connection to UPSD with already specified parameters. + * Throw an exception if cannot connect. + */ + public void connect() throws IOException, UnknownHostException, NutException + { + // Force disconnect if another connection is alive. + if(socket!=null) + disconnect(); + + socket = new StringLineSocket(host, port); + + authenticate(); + } + + /** + * Intend to authenticate with specified login and password, overriding + * already defined ones. + * @param login + * @param passwd + * @throws IOException + * @throws NutException + */ + public void authenticate(String login, String passwd) throws IOException, NutException + { + this.login = login; + this.passwd = passwd; + authenticate(); + } + + /** + * Intend to authenticate with alread set login and password. + * @throws IOException + * @throws NutException + */ + public void authenticate() throws IOException, NutException + { + // Send login + if(login!=null && !login.isEmpty()) + { + String res = query("USERNAME", login); + if(!res.startsWith("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Client.connect (USERNAME) : " + res); + } + } + // Send password + if(passwd!=null && !passwd.isEmpty()) + { + String res = query("PASSWORD", passwd); + if(!res.startsWith("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Client.connect (PASSWORD) : " + res); + } + } + } + + /** + * Test if the client is connected to the UPSD. + * Note: it does not detect if the connection have been closed by server. + * @return True if connected. + */ + public boolean isConnected() + { + return socket!=null && socket.isConnected(); + } + + /** + * Disconnect. + */ + public void disconnect() + { + if(socket!=null) + { + try + { + if(socket.isConnected()) + socket.close(); + } + catch(IOException e) + { + e.printStackTrace(); + } + socket = null; + } + } + + /** + * Log out. + */ + public void logout() + { + if(socket!=null) + { + try + { + if(socket.isConnected()) + { + socket.write("LOGOUT"); + socket.close(); + } + } + catch(IOException e) + { + e.printStackTrace(); + } + socket = null; + } + } + + /** + * Merge an array of stings into on string, with a space ' ' separator. + * @param str First string to merge + * @param strings Additionnal strings to merge + * @param sep Separator. + * @return The merged string, empty if no source string. + */ + static String merge(String str, String[] strings) + { + String res = str; + if(strings!=null) + { + for(int n=0; n ""'. + * @param source String source to split. + * @return String couple with name and value. + */ + static String[] splitNameValueString(String source) + { + int pos = source.indexOf(' '); + if(pos<1) + return null; + String name = source.substring(0, pos); + String value = extractDoublequotedValue(source.substring(pos+1)); + if(value==null) + return null; + String[] res = new String[2]; + res[0] = name; + res[1] = value; + return res; + } + + /** + * Intend to extract a value from its doublequoted and escaped representation. + * @param source Source string to convert. + * @return Extracted value + */ + static String extractDoublequotedValue(String source) + { + // Test doublequote at begin and end of string, then remove them. + if(!(source.startsWith("\"") && source.endsWith("\""))) + return null; + source = source.substring(1, source.length()-1); + // Unescape it. + return unescape(source); + } + + /** + * Escape string with backslashes. + * @param str String to escape. + * @return Escaped string. + */ + static String escape(String str) + { + // Replace a backslash by two backslash (regexp) + str = str.replaceAll("\\\\", "\\\\\\\\"); + // Replace a doublequote by backslash-doublequote (regexp) + str = str.replaceAll("\"", "\\\\\""); + return str; + } + + /** + * Unescape string with backslashes. + * @param str String to unescape. + * @return Unescaped string. + */ + static String unescape(String str) + { + // Replace a backslash-doublequote by doublequote (regexp) + str = str.replaceAll("\\\\\"", "\""); + // Replace two backslash by a backslash (regexp) + str = str.replaceAll("\\\\\\\\", "\\\\"); + return str; + } + + /** + * Detect an UPSD ERR line. + * If found, parse it, construct and throw an NutException + * @param str Line to analyse. + * @throws NutException + */ + private void detectError(String str) throws NutException + { + if(str.startsWith("ERR ")) + { + String[] arr = str.split(" ", 3); + switch(arr.length) + { + case 2: + throw new NutException(arr[1]); + case 3: + throw new NutException(arr[1], arr[2]); + default: + throw new NutException(); + } + } + } + + /** + * Send a query line then read the response. + * Helper around query(String). + * @param query Query to send. + * @param subquery Sub query to send. + * @return The reply. + * @throws IOException + */ + protected String query(String query, String subquery) throws IOException, NutException + { + return query(query + " " + subquery); + } + + /** + * Send a query line then read the response. + * Helper around query(String, String ...). + * @param query Query to send. + * @param subquery Sub query to send. + * @param params Optionnal additionnal parameters. + * @return The reply. + * @throws IOException + */ + protected String query(String query, String subquery, String[] params) throws IOException, NutException + { + return query(query + " " + subquery, params); + } + + /** + * Send a query line then read the response. + * @param query Query to send. + * @param params Optionnal additionnal parameters. + * @return The reply. + * @throws IOException + */ + protected String query(String query, String [] params) throws IOException, NutException + { + query = merge(query, params); + return query(query); + } + + /** + * Send a query line then read the response. + * @param query Query to send. + * @return The reply. + * @throws IOException + */ + protected String query(String query) throws IOException, NutException + { + if(!isConnected()) + return null; + + socket.write(query); + String res = socket.read(); + detectError(res); + return res; + } + + /** + * Send a GET query line then read the reply and validate the response. + * @param subcmd GET subcommand to send. + * @param param Extra parameters + * @return GET result return by UPSD, without the subcommand and param prefix. + * @throws IOException + */ + protected String get(String subcmd, String param) throws IOException, NutException + { + String[] params = {param}; + return get(subcmd, params); + } + + /** + * Send a GET query line then read the reply and validate the response. + * @param subcmd GET subcommand to send. + * @param params Eventual extra parameters. + * @return GET result return by UPSD, without the subcommand and param prefix. + * @throws IOException + */ + protected String get(String subcmd, String [] params) throws IOException, NutException + { + if(!isConnected()) + return null; + + subcmd = merge(subcmd, params); + socket.write("GET " + subcmd); + String res = socket.read(); + if(res==null) + return null; + detectError(res); + if(res.startsWith(subcmd + " ")) + { + return res.substring(subcmd.length()+1); + } + else + { + return null; + } + } + + /** + * Send a LIST query line then read replies and validate them. + * @param subcmd LIST subcommand to send. + * @return LIST results return by UPSD, without the subcommand and param prefix. + * @throws IOException + */ + protected String[] list(String subcmd) throws IOException, NutException + { + return list(subcmd, (String[])null); + } + + /** + * Send a LIST query line then read replies and validate them. + * @param subcmd LIST subcommand to send. + * @param param Extra parameters. + * @return LIST results return by UPSD, without the subcommand and param prefix. + * @throws IOException + */ + protected String[] list(String subcmd, String param) throws IOException, NutException + { + String[] params = {param}; + return list(subcmd, params); + } + + /** + * Send a LIST query line then read replies and validate them. + * @param subcmd LIST subcommand to send. + * @param params Eventual extra parameters. + * @return LIST results return by UPSD, without the subcommand and param prefix. + * @throws IOException + */ + protected String[] list(String subcmd, String [] params) throws IOException, NutException + { + if(!isConnected()) + return null; + + subcmd = merge(subcmd, params); + socket.write("LIST " + subcmd); + String res = socket.read(); + if(res==null) + return null; + detectError(res); + if(!res.startsWith("BEGIN LIST " + subcmd)) + return null; + + ArrayList/**/ list = new ArrayList/**/(); + int sz = subcmd.length()+1; + while(true) + { + res = socket.read(); + detectError(res); + if(!res.startsWith(subcmd + " ")) + break; + list.add(res.substring(sz)); + } + if(!res.equals("END LIST " + subcmd)) + return null; + + return (String[])list.toArray(new String[list.size()]); + } + + + /** + * Returns the list of available devices from the NUT server. + * @return List of devices, empty if nothing, + * null if not connected or failed. + * + */ + public Device[] getDeviceList() throws IOException, NutException + { + String[] res = list("UPS"); + if(res==null) + return null; + + ArrayList/**/ list = new ArrayList/**/(); + for(int i=0; i + * It can be used to retrieve description and execute commands. + * A Command object can be retrieved from Device instance and can not be constructed directly. + * + * @author Emilien Kia + */ +public class Command { + /** + * Device to which command is attached + */ + Device device = null; + + /** + * Command name + */ + String name = null; + + /** + * Internally create a command. + * @param name Command name. + * @param device Device to which the command is attached. + */ + protected Command(String name, Device device) + { + this.device = device; + this.name = name; + } + + /** + * Return the device to which the command can be executed. + * @return Attached device. + */ + public Device getDevice() { + return device; + } + + /** + * Return the command name. + * @return Command name. + */ + public String getName() { + return name; + } + + /** + * Retrieve the command description from UPSD and store it in cache. + * @return Command description + * @throws IOException + */ + public String getDescription() throws IOException, NutException { + if(device!=null && device.getClient()!=null) + { + String[] params = {device.getName(), name}; + String res = device.getClient().get("CMDDESC", params); + return res!=null?Client.extractDoublequotedValue(res):null; + } + return null; + } + + /** + * Execute the instant command. + * @throws IOException + */ + public void execute() throws IOException, NutException { + if(device!=null && device.getClient()!=null) + { + String[] params = {device.getName(), name}; + String res = device.getClient().query("INSTCMD", params); + if(!res.equals("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Command.execute : " + res); + } + } + } +} diff --git a/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java new file mode 100644 index 0000000..8f4fdc1 --- /dev/null +++ b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Device.java @@ -0,0 +1,279 @@ +/* Device.java + + Copyright (C) 2011 Eaton + + 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 +*/ +package org.networkupstools.jnut; + +import java.io.IOException; +import java.util.ArrayList; + +/** + * Class representing a device attached to a Client. + *

+ * It can retrieve its description, its number of logins, its variable and command lists. + * A Device object can be retrieved from Client instance and can not be constructed directly. + * + * @author Emilien Kia + */ +public class Device { + + /** + * Client to which device is attached + */ + Client client = null; + + /** + * Device name + */ + String name = null; + + /** + * Internally create a device. + * @param name Device name. + * @param client Client to which the device is attached. + */ + protected Device(String name, Client client) + { + this.client = client; + this.name = name; + } + + /** + * Return the client to which the device is connected. + * @return Attached client. + */ + public Client getClient() { + return client; + } + + /** + * Return the device name. + * @return Device name. + */ + public String getName() { + return name; + } + + /** + * Retrieve the device description from UPSD and store it in cache. + * @return Device description + * @throws IOException + */ + public String getDescription() throws IOException, NutException { + if(client!=null) + { + return client.get("UPSDESC", name); + } + return null; + } + + /** + * Log in to the ups. + *

+ * Use this to log the fact that a system is drawing power from this UPS. + * The upsmon master will wait until the count of attached systems reaches + * 1 - itself. This allows the slaves to shut down first. + *

+ * NOTE: You probably shouldn't send this command unless you are upsmon, + * or a upsmon replacement. + * @throws IOException + * @throws NutException + */ + public void login() throws IOException, NutException { + if(client!=null) + { + String res = client.query("LOGIN", name); + if(!res.startsWith("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Device.login : " + res); + } + } + } + + /** + * This function doesn't do much by itself. It is used by upsmon to make + * sure that master-level functions like FSD are available if necessary + * @throws IOException + * @throws NutException + */ + public void master() throws IOException, NutException { + if(client!=null) + { + String res = client.query("MASTER", name); + if(!res.startsWith("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Device.master : " + res); + } + } + } + + /** + * Set the "forced shutdown" flag. + *

+ * upsmon in master mode is the primary user of this function. It sets this + * "forced shutdown" flag on any UPS when it plans to power it off. This is + * done so that slave systems will know about it and shut down before the + * power disappears. + *

+ * Setting this flag makes "FSD" appear in a STATUS request for this UPS. + * Finding "FSD" in a status request should be treated just like a "OB LB". + *

+ * It should be noted that FSD is currently a latch - once set, there is + * no way to clear it short of restarting upsd or dropping then re-adding + * it in the ups.conf. This may cause issues when upsd is running on a + * system that is not shut down due to the UPS event. + * @throws IOException + * @throws NutException + */ + public void setForcedShutdown() throws IOException, NutException { + if(client!=null) + { + String res = client.query("FSD", name); + if(!res.startsWith("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Device.setForcedShutdown : " + res); + } + } + } + + /** + * Return the number of clients which have done LOGIN for this UPS. + * Force to retrieve it from UPSD and store it in cache. + * @return Number of clients, -1 if error. + * @throws IOException + */ + public int getNumLogin() throws IOException, NutException { + if(client!=null) + { + String res = client.get("NUMLOGINS", name); + return res!=null?Integer.parseInt(res):-1; + } + return -1; + } + + + /** + * Return the list of device variables from the NUT server. + * @return List of variables, empty if nothing, + * null if not connected or failed. + * @throws IOException + */ + public Variable[] getVariableList() throws IOException, NutException { + if(client==null) + return null; + + String[] res = client.list("VAR", name); + if(res==null) + return null; + + ArrayList/**/ list = new ArrayList/**/(); + for(int i=0; i*/ list = new ArrayList/**/(); + for(int i=0; i*/ list = new ArrayList/**/(); + for(int i=0; i + * Instance are thrown when an UPSD returns an error with an "ERR" directive. + * Moreover it can ben thrown with some extra errors like: + *

    + *
  • UNKNOWN-RESPONSE : The response is not understood + *
+ *

+ * A Nut exception has a (standard java exception message) message which correspond + * to error code returns by UPSD (like 'ACCESS-DENIED', 'UNKNOWN-UPS' ...). + * An extra string embed a more descriptive english message. + * + * @author Emilien Kia + */ +public class NutException extends java.lang.Exception{ + + public static String UnknownResponse = "UNKNOWN-RESPONSE"; + + public static String DriverNotConnected = "DRIVER-NOT-CONNECTED"; + + public String extra = ""; + + public NutException() + { + } + + public NutException(String message) + { + super(message); + } + + public NutException(String message, String extra) + { + super(message); + this.extra = extra; + } + + public NutException(Throwable cause) + { + super(cause); + } + + public NutException(String message, Throwable cause) + { + super(message, cause); + } + + public NutException(String message, String extra, Throwable cause) + { + super(message, cause); + this.extra = extra; + } + + /** + * Returns the extra message. + * @return Extra message if any. + */ + public String getExtra() { + return extra; + } + + /** + * Set the extra message. + * @param extra The new extra message. + */ + public void setExtra(String extra) { + this.extra = extra; + } + + /** + * Test is the exception corresponds to the specified name. + * @param name Name to test + * @return True if exception corresponds. + */ + public boolean is(String name) { + return getMessage()!=null&&getMessage().equals(name); + } + + /** + * Format an exception message. + * @return Exception message + */ + public String toString() { + return "[" + getClass().getSimpleName() + "]" + getMessage() + " : " + getExtra(); + } +} diff --git a/scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java new file mode 100644 index 0000000..fe39b71 --- /dev/null +++ b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/StringLineSocket.java @@ -0,0 +1,137 @@ +/* StringLineSocket.java + + Copyright (C) 2011 Eaton + + 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 +*/ +package org.networkupstools.jnut; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.Socket; +import java.net.UnknownHostException; + +/** + * Class representing a socket, internally used to communicate with UPSD. + * Abstract some stream mechanisms. + * + * @author Emilien Kia + */ +class StringLineSocket { + + /** + * Real internal TCP socket. + */ + Socket socket = null; + + /** + * Writer to the socket. + */ + private OutputStreamWriter writer = null; + + /** + * Reader from the socket. + */ + private BufferedReader reader = null; + + /** + * Create a new line socket. + */ + public StringLineSocket(){ + + } + + /** + * Create a new line socket and connect it. + * @param host Host to connect to + * @param port Port to connect to + * @throws UnknownHostException + * @throws IOException + */ + public StringLineSocket(String host, int port) throws UnknownHostException, IOException{ + connect(host, port); + } + + /** + * Connect a new line socket. + * @param host Host to connect to + * @param port Port to connect to + * @throws UnknownHostException + * @throws IOException + */ + public void connect(String host, int port) throws UnknownHostException, IOException{ + socket = new Socket(host, port); + if(socket!=null) + { + reader = new BufferedReader(new InputStreamReader( + socket.getInputStream())); + writer = new OutputStreamWriter(socket.getOutputStream()); + } + } + + /** + * Close the socket. + */ + public void close() throws IOException{ + if(socket!=null){ + writer.close(); + reader.close(); + socket.close(); + socket = null; + writer = null; + reader = null; + } + } + + /** + * Test if the soecket is connected. + * @return True if connected. + */ + public boolean isConnected() { + return socket!=null && socket.isConnected() && !socket.isClosed(); + } + + /** + * Write a line follow by a '\n' character. + * @param line + * @throws IOException + */ + public void write(String line) throws IOException + { + if(isConnected()) + { + writer.write(line + "\n"); + writer.flush(); + } + } + + /** + * Read a line terminated by a '\n'. + * @return The line without the ending '\n' + * @throws IOException + */ + public String read() throws IOException + { + if(isConnected()) + { + String res = reader.readLine(); + return res; + } + return ""; + } + +} diff --git a/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java new file mode 100644 index 0000000..07c7c37 --- /dev/null +++ b/scripts/java/jNut/src/main/java/org/networkupstools/jnut/Variable.java @@ -0,0 +1,120 @@ +/* Variable.java + + Copyright (C) 2011 Eaton + + 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 +*/ +package org.networkupstools.jnut; + +import java.io.IOException; + +/** + * Class representing a variable of a device. + *

+ * It can be used to get and set its value (if possible). + * A Variable object can be retrieved from Device instance and can not be constructed directly. + * + * @author Emilien Kia + */ +public class Variable { + /** + * Device to which variable is attached + */ + Device device = null; + + /** + * Variable name + */ + String name = null; + + /** + * Internally create a variable. + * @param name Variable name. + * @param device Device to which the variable is attached. + */ + protected Variable(String name, Device device) + { + this.device = device; + this.name = name; + } + + /** + * Return the device to which the variable is related. + * @return Attached device. + */ + public Device getDevice() { + return device; + } + + /** + * Return the variable name. + * @return Command name. + */ + public String getName() { + return name; + } + + /** + * Retrieve the variable value from UPSD and store it in cache. + * @return Variable value + * @throws IOException + */ + public String getValue() throws IOException, NutException { + if(device!=null && device.getClient()!=null) + { + String[] params = {device.getName(), name}; + String res = device.getClient().get("VAR", params); + return res!=null?Client.extractDoublequotedValue(res):null; + } + return null; + } + + /** + * Retrieve the variable description from UPSD and store it in cache. + * @return Variable description + * @throws IOException + */ + public String getDescription() throws IOException, NutException { + if(device!=null && device.getClient()!=null) + { + String[] params = {device.getName(), name}; + String res = device.getClient().get("DESC", params); + return res!=null?Client.extractDoublequotedValue(res):null; + } + return null; + } + + /** + * Set the variable value. + * Note the new value can be applied with a little delay depending of UPSD and connection. + * @param value New value for the variable + * @throws IOException + */ + public void setValue(String value) throws IOException, NutException { + if(device!=null && device.getClient()!=null) + { + String[] params = {"VAR", device.getName(), + name, " \"" + Client.escape(value) + "\""}; + String res = device.getClient().query("SET", params); + if(!res.equals("OK")) + { + // Normaly response should be OK or ERR and nothing else. + throw new NutException(NutException.UnknownResponse, "Unknown response in Variable.setValue : " + res); + } + } + } + + // TODO Add query for type and enum values +} diff --git a/scripts/java/jNut/src/test/java/org/networkupstools/jnut/ClientTest.java b/scripts/java/jNut/src/test/java/org/networkupstools/jnut/ClientTest.java new file mode 100644 index 0000000..73f6296 --- /dev/null +++ b/scripts/java/jNut/src/test/java/org/networkupstools/jnut/ClientTest.java @@ -0,0 +1,95 @@ +package org.networkupstools.jnut; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class ClientTest extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public ClientTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ClientTest.class ); + } + + /** + * Escape function test. + */ + public void testEscape() + { + assertEquals("Empty string", "", Client.escape("")); + assertEquals("Simple string", "hello", Client.escape("hello")); + assertEquals("Internal doublequote", "he\\\"llo", Client.escape("he\"llo")); + assertEquals("Internal backslash", "he\\\\llo", Client.escape("he\\llo")); + assertEquals("Internal backslash and doublequote", "he\\\\\\\"llo", Client.escape("he\\\"llo")); + assertEquals("Initial and final doublequote", "\\\"hello\\\"", Client.escape("\"hello\"")); + } + + /** + * Unescape function test. + */ + public void testUnescape() + { + assertEquals("Empty string", "", Client.unescape("")); + assertEquals("Simple string", "hello", Client.unescape("hello")); + assertEquals("Internal doublequote", "he\"llo", Client.unescape("he\\\"llo")); + assertEquals("Internal backslash", "he\\llo", Client.unescape("he\\\\llo")); + assertEquals("Internal backslash and doublequote", "he\\\"llo", Client.unescape("he\\\\\\\"llo")); + assertEquals("Initial and final doublequote", "\"hello\"", Client.unescape("\\\"hello\\\"")); + } + + /** + * extractDoublequotedValue function test. + */ + public void testExtractDoublequotedValue() + { + assertNull("Empty string", Client.extractDoublequotedValue("")); + assertNull("Non doublequoted string", Client.extractDoublequotedValue("hello")); + assertNull("No begining doublequote", Client.extractDoublequotedValue("hello\"")); + assertNull("No ending doublequote", Client.extractDoublequotedValue("\"hello")); + assertEquals("Simple string", "hello", Client.extractDoublequotedValue("\"hello\"")); + assertEquals("String with doublequote", "he\"llo", Client.extractDoublequotedValue("\"he\\\"llo\"")); + assertEquals("String with backslash", "he\\llo", Client.extractDoublequotedValue("\"he\\\\llo\"")); + assertEquals("String with backslash and doublequote", "he\\\"llo", Client.extractDoublequotedValue("\"he\\\\\\\"llo\"")); + } + + /** + * splitNameValueString function test. + */ + public void testSplitNameValueString() + { + String[] res; + assertNull("Empty string", Client.splitNameValueString("")); + assertNull("One word string", Client.splitNameValueString("name")); + assertNull("Non doublequoted string", Client.extractDoublequotedValue("name value")); + assertNull("No begining doublequote", Client.extractDoublequotedValue("name value\"")); + assertNull("No ending doublequote", Client.extractDoublequotedValue("name \"value")); + res = Client.splitNameValueString("name \"value\""); + assertEquals("Simple name/value (name)", "name", res[0]); + assertEquals("Simple name/value (value)", "value", res[1]); + res = Client.splitNameValueString("name \"complex value\""); + assertEquals("Simple name / complex value (name)", "name", res[0]); + assertEquals("Simple name / complex value (value)", "complex value", res[1]); + res = Client.splitNameValueString("name \"complex\\\\value\""); + assertEquals("Simple name / backslash value (name)", "name", res[0]); + assertEquals("Simple name / backslash value (value)", "complex\\value", res[1]); + res = Client.splitNameValueString("name \"complex\\\"value\""); + assertEquals("Simple name / doublequote value (name)", "name", res[0]); + assertEquals("Simple name / doublequote value (value)", "complex\"value", res[1]); + } +} diff --git a/scripts/java/jNutList/README b/scripts/java/jNutList/README new file mode 100644 index 0000000..4e52bb8 --- /dev/null +++ b/scripts/java/jNutList/README @@ -0,0 +1,30 @@ +jNutList example application +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This directory contains source files for the jNutList application. +It allows to connect to an UPSD then retrieve devices and their variables. +It is a little example application to show how to use jNut. + +jNutList building +^^^^^^^^^^^^^^^^^ + +As jNut, jNutList is a maven project so a maven environment must be set. +Please reffer to jNut building notes. + +jNutList running +^^^^^^^^^^^^^^^^ + +jNutList can be run launching it in a console: + + java -jar jNutList-x.x-xxx-jar-with-dependencies.jar + +Some parameters can be passed : + + java -jar jNutList-x.x-jar-with-dependencies.jar host port login password + +For example: + + java -jar jNutList-x.x-jar-with-dependencies.jar localhost 3493 admin passwd + +By default, host is localhost, port is 3493 and login and password are not +specified. diff --git a/scripts/java/jNutList/pom.xml b/scripts/java/jNutList/pom.xml new file mode 100644 index 0000000..3558aad --- /dev/null +++ b/scripts/java/jNutList/pom.xml @@ -0,0 +1,62 @@ + + 4.0.0 + + org.networkupstools + jNutList + 0.1-SNAPSHOT + jar + + jNutList + http://maven.apache.org + + + UTF-8 + + + + + junit + junit + 3.8.1 + test + + + ${project.groupId} + jNut + 0.1-SNAPSHOT + + + + + + + + maven-assembly-plugin + 2.2.1 + + + jar-with-dependencies + + + + org.networkupstools.jnutlist.AppList + + + + + + make-assembly + package + + single + + + + + + + + diff --git a/scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java b/scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java new file mode 100644 index 0000000..a15452d --- /dev/null +++ b/scripts/java/jNutList/src/main/java/org/networkupstools/jnutlist/AppList.java @@ -0,0 +1,112 @@ +/* AppList.java + + Copyright (C) 2011 Eaton + + 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 +*/ +package org.networkupstools.jnutlist; + +import java.io.IOException; +import java.net.UnknownHostException; +import org.networkupstools.jnut.*; + + +public class AppList +{ + + public static void main( String[] args ) + { + String host = args.length>=1?args[0]:"localhost"; + int port = args.length>=2?Integer.valueOf(args[1]).intValue():3493; + String login = args.length>=3?args[2]:""; + String pass = args.length>=4?args[3]:""; + + System.out.println( "jNutList connecting to " + login+":"+pass+"@"+host+":"+port ); + + Client client = new Client(); + try { + client.connect(host, port, login, pass); + Device[] devs = client.getDeviceList(); + if(devs!=null) + { + for(int d=0; d $@ + +nutshutdown: nutshutdown.in + sed -e 's,@sbindir\@,$(sbindir),g' $< > $@ + +systemdsystemunit_DATA = \ + nut-driver.service \ + nut-monitor.service \ + nut-server.service + +systemdsystemshutdown_SCRIPTS = nutshutdown + +else +EXTRA_DIST += nut-driver.service.in nut-monitor.service.in \ + nut-server.service.in nutshutdown.in +endif + diff --git a/scripts/systemd/Makefile.in b/scripts/systemd/Makefile.in new file mode 100644 index 0000000..9f9f633 --- /dev/null +++ b/scripts/systemd/Makefile.in @@ -0,0 +1,531 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@HAVE_SYSTEMD_FALSE@am__append_1 = nut-driver.service.in nut-monitor.service.in \ +@HAVE_SYSTEMD_FALSE@ nut-server.service.in nutshutdown.in + +subdir = scripts/systemd +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nut_arg_with.m4 \ + $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ + $(top_srcdir)/m4/nut_check_libgd.m4 \ + $(top_srcdir)/m4/nut_check_libhal.m4 \ + $(top_srcdir)/m4/nut_check_libneon.m4 \ + $(top_srcdir)/m4/nut_check_libnetsnmp.m4 \ + $(top_srcdir)/m4/nut_check_libpowerman.m4 \ + $(top_srcdir)/m4/nut_check_libssl.m4 \ + $(top_srcdir)/m4/nut_check_libusb.m4 \ + $(top_srcdir)/m4/nut_check_libwrap.m4 \ + $(top_srcdir)/m4/nut_check_os.m4 \ + $(top_srcdir)/m4/nut_config_libhal.m4 \ + $(top_srcdir)/m4/nut_report_feature.m4 \ + $(top_srcdir)/m4/nut_type_socklen_t.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(systemdsystemshutdowndir)" \ + "$(DESTDIR)$(systemdsystemunitdir)" +SCRIPTS = $(systemdsystemshutdown_SCRIPTS) +SOURCES = +DIST_SOURCES = +DATA = $(systemdsystemunit_DATA) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +A2X = @A2X@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFPATH = @CONFPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBLATEX = @DBLATEX@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOC_BUILD_LIST = @DOC_BUILD_LIST@ +DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@ +DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@ +DRIVER_MAN_LIST = @DRIVER_MAN_LIST@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@ +HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@ +HAL_FDI_PATH = @HAL_FDI_PATH@ +HAL_USER = @HAL_USER@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBGD_CFLAGS = @LIBGD_CFLAGS@ +LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ +LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ +LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ +LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ +LIBNEON_LIBS = @LIBNEON_LIBS@ +LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ +LIBNETSNMP_LIBS = @LIBNETSNMP_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@ +LIBPOWERMAN_LIBS = @LIBPOWERMAN_LIBS@ +LIBS = @LIBS@ +LIBSSL_CFLAGS = @LIBSSL_CFLAGS@ +LIBSSL_LIBS = @LIBSSL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NETLIBS = @NETLIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS_NAME = @OS_NAME@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ +RANLIB = @RANLIB@ +RUN_AS_GROUP = @RUN_AS_GROUP@ +RUN_AS_USER = @RUN_AS_USER@ +SED = @SED@ +SERLIBS = @SERLIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STATEPATH = @STATEPATH@ +STRIP = @STRIP@ +SUN_LIBUSB = @SUN_LIBUSB@ +VERSION = @VERSION@ +WORDS_BIGENDIAN = @WORDS_BIGENDIAN@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cgiexecdir = @cgiexecdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverexecdir = @driverexecdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hotplugdir = @hotplugdir@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +udevdir = @udevdir@ +EXTRA_DIST = README $(am__append_1) +@HAVE_SYSTEMD_TRUE@systemdsystemunit_DATA = \ +@HAVE_SYSTEMD_TRUE@ nut-driver.service \ +@HAVE_SYSTEMD_TRUE@ nut-monitor.service \ +@HAVE_SYSTEMD_TRUE@ nut-server.service + +@HAVE_SYSTEMD_TRUE@systemdsystemshutdown_SCRIPTS = nutshutdown +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/systemd/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu scripts/systemd/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-systemdsystemshutdownSCRIPTS: $(systemdsystemshutdown_SCRIPTS) + @$(NORMAL_INSTALL) + test -z "$(systemdsystemshutdowndir)" || $(MKDIR_P) "$(DESTDIR)$(systemdsystemshutdowndir)" + @list='$(systemdsystemshutdown_SCRIPTS)'; test -n "$(systemdsystemshutdowndir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(systemdsystemshutdowndir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(systemdsystemshutdowndir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-systemdsystemshutdownSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(systemdsystemshutdown_SCRIPTS)'; test -n "$(systemdsystemshutdowndir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(systemdsystemshutdowndir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(systemdsystemshutdowndir)" && rm -f $$files + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-systemdsystemunitDATA: $(systemdsystemunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(systemdsystemunitdir)" || $(MKDIR_P) "$(DESTDIR)$(systemdsystemunitdir)" + @list='$(systemdsystemunit_DATA)'; test -n "$(systemdsystemunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemdsystemunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(systemdsystemunitdir)" || exit $$?; \ + done + +uninstall-systemdsystemunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(systemdsystemunit_DATA)'; test -n "$(systemdsystemunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(systemdsystemunitdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(systemdsystemunitdir)" && rm -f $$files +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(SCRIPTS) $(DATA) +installdirs: + for dir in "$(DESTDIR)$(systemdsystemshutdowndir)" "$(DESTDIR)$(systemdsystemunitdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-systemdsystemshutdownSCRIPTS \ + install-systemdsystemunitDATA + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-systemdsystemshutdownSCRIPTS \ + uninstall-systemdsystemunitDATA + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + install-systemdsystemshutdownSCRIPTS \ + install-systemdsystemunitDATA installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am uninstall uninstall-am \ + uninstall-systemdsystemshutdownSCRIPTS \ + uninstall-systemdsystemunitDATA + + +@HAVE_SYSTEMD_TRUE@%.service: %.service.in +@HAVE_SYSTEMD_TRUE@ sed -e 's,@sbindir\@,$(sbindir),g' $< > $@ + +@HAVE_SYSTEMD_TRUE@nutshutdown: nutshutdown.in +@HAVE_SYSTEMD_TRUE@ sed -e 's,@sbindir\@,$(sbindir),g' $< > $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/scripts/systemd/README b/scripts/systemd/README new file mode 100644 index 0000000..c8930ab --- /dev/null +++ b/scripts/systemd/README @@ -0,0 +1,8 @@ +This directory contains the NUT support files for systemd, the System and +Service Manager. + +These files are automatically installed, upon detection (at configure time) +of a systemd enabled system. + +Contributed by Michal Hlavinka + diff --git a/scripts/systemd/nut-driver.service.in b/scripts/systemd/nut-driver.service.in new file mode 100644 index 0000000..eef3480 --- /dev/null +++ b/scripts/systemd/nut-driver.service.in @@ -0,0 +1,10 @@ +[Unit] +Description=Network UPS Tools - power device driver controller +After=local-fs.target network.target +StopWhenUnneeded=yes + +[Service] +ExecStart=/sbin/upsdrvctl start +ExecStop=/sbin/upsdrvctl stop +Type=forking + diff --git a/scripts/systemd/nut-monitor.service.in b/scripts/systemd/nut-monitor.service.in new file mode 100644 index 0000000..8a7f3b2 --- /dev/null +++ b/scripts/systemd/nut-monitor.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Network UPS Tools - power device monitor and shutdown controller +After=local-fs.target network.target nut-server.service + +[Service] +ExecStart=/usr/sbin/upsmon +PIDFile=/var/run/nut/upsmon.pid +Type=forking + +[Install] +WantedBy=multi-user.target diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in new file mode 100644 index 0000000..38b1322 --- /dev/null +++ b/scripts/systemd/nut-server.service.in @@ -0,0 +1,12 @@ +[Unit] +Description=Network UPS Tools - power devices information server +After=local-fs.target network.target nut-driver.service +Requires=nut-driver.service +Before=nut-monitor.service + +[Service] +ExecStart=/usr/sbin/upsd +Type=forking + +[Install] +WantedBy=multi-user.target diff --git a/scripts/systemd/nutshutdown.in b/scripts/systemd/nutshutdown.in new file mode 100644 index 0000000..3406592 --- /dev/null +++ b/scripts/systemd/nutshutdown.in @@ -0,0 +1,2 @@ +#!/bin/sh +upsmon -K >/dev/null 2>&1 && upsdrvctl shutdown diff --git a/scripts/udev/Makefile.am b/scripts/udev/Makefile.am index d288cc2..fcd6eeb 100644 --- a/scripts/udev/Makefile.am +++ b/scripts/udev/Makefile.am @@ -1,7 +1,13 @@ if WITH_UDEV udevrulesdir = $(udevdir)/rules.d - udevrules_DATA = 52-nut-usbups.rules + udevrules_DATA = +if WITH_USB + udevrules_DATA += 52-nut-usbups.rules +endif +if WITH_IPMI + udevrules_DATA += 52-nut-ipmipsu.rules +endif endif EXTRA_DIST = README @@ -9,7 +15,10 @@ EXTRA_DIST = README 52-nut-usbups.rules: nut-usbups.rules cp nut-usbups.rules 52-nut-usbups.rules -DISTCLEANFILES = nut-usbups.rules -CLEANFILES = 52-nut-usbups.rules +52-nut-ipmipsu.rules: nut-ipmipsu.rules + cp nut-ipmipsu.rules 52-nut-ipmipsu.rules + +DISTCLEANFILES = nut-usbups.rules nut-ipmipsu.rules +CLEANFILES = 52-nut-usbups.rules 52-nut-ipmipsu.rules # we should never remove this one, apart from a distclean-check #MAINTAINERCLEANFILES = nut-usbups.rules.in diff --git a/scripts/udev/Makefile.in b/scripts/udev/Makefile.in index 678ff5c..55c58b3 100644 --- a/scripts/udev/Makefile.in +++ b/scripts/udev/Makefile.in @@ -35,9 +35,11 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ +@WITH_UDEV_TRUE@@WITH_USB_TRUE@am__append_1 = 52-nut-usbups.rules +@WITH_IPMI_TRUE@@WITH_UDEV_TRUE@am__append_2 = 52-nut-ipmipsu.rules subdir = scripts/udev DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(srcdir)/nut-usbups.rules.in + $(srcdir)/nut-ipmipsu.rules.in $(srcdir)/nut-usbups.rules.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ @@ -45,6 +47,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -62,7 +66,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/config.h -CONFIG_CLEAN_FILES = nut-usbups.rules +CONFIG_CLEAN_FILES = nut-ipmipsu.rules nut-usbups.rules CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = @@ -134,10 +138,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -175,6 +183,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -239,6 +251,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -249,10 +263,10 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ udevdir = @udevdir@ @WITH_UDEV_TRUE@udevrulesdir = $(udevdir)/rules.d -@WITH_UDEV_TRUE@udevrules_DATA = 52-nut-usbups.rules +@WITH_UDEV_TRUE@udevrules_DATA = $(am__append_1) $(am__append_2) EXTRA_DIST = README -DISTCLEANFILES = nut-usbups.rules -CLEANFILES = 52-nut-usbups.rules +DISTCLEANFILES = nut-usbups.rules nut-ipmipsu.rules +CLEANFILES = 52-nut-usbups.rules 52-nut-ipmipsu.rules all: all-am .SUFFIXES: @@ -286,6 +300,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): +nut-ipmipsu.rules: $(top_builddir)/config.status $(srcdir)/nut-ipmipsu.rules.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ nut-usbups.rules: $(top_builddir)/config.status $(srcdir)/nut-usbups.rules.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ @@ -468,6 +484,9 @@ uninstall-am: uninstall-udevrulesDATA 52-nut-usbups.rules: nut-usbups.rules cp nut-usbups.rules 52-nut-usbups.rules + +52-nut-ipmipsu.rules: nut-ipmipsu.rules + cp nut-ipmipsu.rules 52-nut-ipmipsu.rules # we should never remove this one, apart from a distclean-check #MAINTAINERCLEANFILES = nut-usbups.rules.in diff --git a/scripts/udev/README b/scripts/udev/README index 06d2e17..a3b5567 100644 --- a/scripts/udev/README +++ b/scripts/udev/README @@ -1,17 +1,18 @@ -Desc: Udev script for NUT USB drivers +Desc: Udev script for NUT USB and IPMI drivers File: scripts/udev/README -Date: 27 January 2008 +Date: 25 July 2011 Auth: Arnaud Quette This document introduces the Linux udev script for NUT USB -drivers (usbhid-ups, bcmxcp_usb, tripplite_usb, ...). +drivers (usbhid-ups, bcmxcp_usb, tripplite_usb, ...) and IPMI driver +(nut-ipmipsu). These are needed on Linux systems running udev (recommended as of kernel 2.6.3, and mandatory as of 2.6.14 and higher). This script ensure that the right privileges are set on the -usb devices files to allow the NUT driver to operate (ie -allowing the nut user to read AND write to the UPS device). +USB and IPMI devices files to allow the NUT driver to operate (ie +allowing the nut user to read AND write to the device). Note that the old style hotplug files, available in the scripts/hotplug directory, are not needed if your kernel supports @@ -21,21 +22,23 @@ Installation ------------ For most users, these files will be automatically installed in -/etc/udev (or /lib/udev) upon "make install", if that directory exists. You can +/etc/udev (or /lib/udev) upon "make install", if that directory exists and if +the feature (USB and / or IPMI) has been enabled at configure time. You can specify an alternate directory with ./configure --with-udev-dir=DIR. Manual installation ------------------- -To install them manually, copy nut-usbups.rules to /etc/udev/rules.d -(or /lib/udev/rules.d on newer systems) using the command +To install them manually, copy the rules file(s) to /etc/udev/rules.d +(or /lib/udev/rules.d on newer systems) using the command(s): $ cp -f nut-usbups.rules /etc/udev/rules.d/52-nut-usbups.rules +$ cp -f nut-ipmipsu.rules /etc/udev/rules.d/52-nut-ipmipsu.rules You will need to refresh the bus to avoid a reboot for these rules to be active. You can do so using: $ udevadm trigger --subsystem-match=usb_device -You can then plug your UPS USB cord, or unplug / replug it to -refresh the device permission, and start NUT. +For USB devices, you can then plug your UPS USB cord, or unplug / replug +it to refresh the device permission, and start NUT. diff --git a/scripts/udev/nut-ipmipsu.rules.in b/scripts/udev/nut-ipmipsu.rules.in new file mode 100644 index 0000000..0d3e969 --- /dev/null +++ b/scripts/udev/nut-ipmipsu.rules.in @@ -0,0 +1,4 @@ +# This file is generated and installed by the Network UPS Tools package. +# It sets the correct device permissions for nut-ipmipsu driver. + +KERNEL=="ipmi*", MODE="664", GROUP="@RUN_AS_GROUP@" diff --git a/scripts/udev/nut-usbups.rules.in b/scripts/udev/nut-usbups.rules.in index 9331e60..6537eec 100644 --- a/scripts/udev/nut-usbups.rules.in +++ b/scripts/udev/nut-usbups.rules.in @@ -66,6 +66,10 @@ ATTR{idVendor}=="051d", ATTR{idProduct}=="0003", MODE="664", GROUP="@RUN_AS_GROU ATTR{idVendor}=="0592", ATTR{idProduct}=="0002", MODE="664", GROUP="@RUN_AS_GROUP@" # PW 9140 - usbhid-ups ATTR{idVendor}=="0592", ATTR{idProduct}=="0004", MODE="664", GROUP="@RUN_AS_GROUP@" +# Agiler UPS - blazer_usb +ATTR{idVendor}=="05b8", ATTR{idProduct}=="0000", MODE="664", GROUP="@RUN_AS_GROUP@" +# Belkin F6C1200-UNV - blazer_usb +ATTR{idVendor}=="0665", ATTR{idProduct}=="5161", MODE="664", GROUP="@RUN_AS_GROUP@" # Phoenixtec # various models - bcmxcp_usb @@ -86,6 +90,8 @@ ATTR{idVendor}=="0764", ATTR{idProduct}=="0005", MODE="664", GROUP="@RUN_AS_GROU ATTR{idVendor}=="0764", ATTR{idProduct}=="0501", MODE="664", GROUP="@RUN_AS_GROUP@" # OR2200LCDRM2U - usbhid-ups ATTR{idVendor}=="0764", ATTR{idProduct}=="0601", MODE="664", GROUP="@RUN_AS_GROUP@" +# Sweex 1000VA - richcomm_usb +ATTR{idVendor}=="0925", ATTR{idProduct}=="1234", MODE="664", GROUP="@RUN_AS_GROUP@" # TrippLite # e.g. OMNIVS1000, SMART550USB, ... - tripplite_usb @@ -162,9 +168,13 @@ ATTR{idVendor}=="0d9f", ATTR{idProduct}=="00a4", MODE="664", GROUP="@RUN_AS_GROU ATTR{idVendor}=="0d9f", ATTR{idProduct}=="00a5", MODE="664", GROUP="@RUN_AS_GROUP@" # PowerCOM BNT - Black Knight Pro - usbhid-ups ATTR{idVendor}=="0d9f", ATTR{idProduct}=="00a6", MODE="664", GROUP="@RUN_AS_GROUP@" +# Unitek Alpha 1200Sx - blazer_usb +ATTR{idVendor}=="0f03", ATTR{idProduct}=="0001", MODE="664", GROUP="@RUN_AS_GROUP@" # Liebert # Liebert PowerSure PSA UPS - usbhid-ups ATTR{idVendor}=="10af", ATTR{idProduct}=="0001", MODE="664", GROUP="@RUN_AS_GROUP@" +# GE EP series - blazer_usb +ATTR{idVendor}=="14f0", ATTR{idProduct}=="00c9", MODE="664", GROUP="@RUN_AS_GROUP@" LABEL="nut-usbups_rules_end" diff --git a/server/Makefile.in b/server/Makefile.in index 6decd15..994e64a 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -52,6 +52,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -153,10 +155,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -194,6 +200,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -258,6 +268,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ diff --git a/tools/Makefile.am b/tools/Makefile.am index c46f27c..fbe4e34 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,10 +1,37 @@ -EXTRA_DIST = nut-usbinfo.pl nut-hclinfo.py device-recorder.sh svn2cl.authors +# Force build in ./ before nut-scanner, to have nutscan-{usb,snmp}.h +# built before going into the nut-scanner sub-directory +SUBDIRS = . nut-scanner + +EXTRA_DIST = nut-usbinfo.pl nut-hclinfo.py device-recorder.sh svn2cl.authors nut-snmpinfo.py + +all: nut-scanner-deps + +nut-scanner-deps: + @if python -c 1; then \ + echo "Regenerating the SNMP helper files."; \ + $(top_srcdir)/tools/nut-snmpinfo.py; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Python is not available."; \ + echo "Skipping the SNMP helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi + + @if perl -e 1; then \ + echo "Regenerating the USB helper files."; \ + $(top_srcdir)/tools/nut-usbinfo.pl; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Perl is not available."; \ + echo "Skipping the USB helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi website: @if python -c pass; then \ echo "Regenerating the HTML and JSON formated HCL tables."; \ - ./nut-hclinfo.py; \ + $(top_srcdir)/tools/nut-hclinfo.py; \ else \ echo "----------------------------------------------------------------------"; \ echo "Warning: Python is not available."; \ @@ -12,8 +39,20 @@ website: echo "----------------------------------------------------------------------"; \ fi -# only call the USB info script upon "make dist", and if Perl is present +# call the USB info script upon "make dist", and if Perl is present +# call the SNMP info script upon "make dist", and if Python is present +# and call both for building nut-scanner dist-hook: + @if python -c 1; then \ + echo "Regenerating the SNMP helper files."; \ + $(distdir)/nut-snmpinfo.py; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Python is not available."; \ + echo "Skipping the SNMP helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi + @if perl -e 1; then \ echo "Regenerating the USB helper files."; \ $(distdir)/nut-usbinfo.pl; \ @@ -23,3 +62,5 @@ dist-hook: echo "Skipping the USB helper files regeneration."; \ echo "----------------------------------------------------------------------"; \ fi + +.PHONY: nut-scanner-deps nut-scanner-snmp-deps nut-scanner-usb-deps diff --git a/tools/Makefile.in b/tools/Makefile.in index 103b72d..404d40b 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -43,6 +43,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/m4/nut_arg_with.m4 \ $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ $(top_srcdir)/m4/nut_check_libgd.m4 \ $(top_srcdir)/m4/nut_check_libhal.m4 \ $(top_srcdir)/m4/nut_check_libneon.m4 \ @@ -64,7 +66,47 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" A2X = @A2X@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -109,10 +151,14 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ LIBGD_CFLAGS = @LIBGD_CFLAGS@ LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ LIBNEON_LIBS = @LIBNEON_LIBS@ LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ @@ -150,6 +196,10 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ RANLIB = @RANLIB@ RUN_AS_GROUP = @RUN_AS_GROUP@ RUN_AS_USER = @RUN_AS_USER@ @@ -214,6 +264,8 @@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ @@ -223,8 +275,12 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ udevdir = @udevdir@ -EXTRA_DIST = nut-usbinfo.pl nut-hclinfo.py device-recorder.sh svn2cl.authors -all: all-am + +# Force build in ./ before nut-scanner, to have nutscan-{usb,snmp}.h +# built before going into the nut-scanner sub-directory +SUBDIRS = . nut-scanner +EXTRA_DIST = nut-usbinfo.pl nut-hclinfo.py device-recorder.sh svn2cl.authors nut-snmpinfo.py +all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @@ -263,12 +319,141 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique tags: TAGS -TAGS: +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi ctags: CTAGS -CTAGS: +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -300,22 +485,51 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am -check: check-am +check: check-recursive all-am: Makefile -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -installcheck: installcheck-am +installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ @@ -332,91 +546,117 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -clean: clean-am +clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am -distclean: distclean-am +distclean: distclean-recursive -rm -f Makefile -distclean-am: clean-am distclean-generic +distclean-am: clean-am distclean-generic distclean-tags -dvi: dvi-am +dvi: dvi-recursive dvi-am: -html: html-am +html: html-recursive html-am: -info: info-am +info: info-recursive info-am: install-data-am: -install-dvi: install-dvi-am +install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: -install-html: install-html-am +install-html: install-html-recursive install-html-am: -install-info: install-info-am +install-info: install-info-recursive install-info-am: install-man: -install-pdf: install-pdf-am +install-pdf: install-pdf-recursive install-pdf-am: -install-ps: install-ps-am +install-ps: install-ps-recursive install-ps-am: installcheck-am: -maintainer-clean: maintainer-clean-am +maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic -mostlyclean: mostlyclean-am +mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool -pdf: pdf-am +pdf: pdf-recursive pdf-am: -ps: ps-am +ps: ps-recursive ps-am: uninstall-am: -.MAKE: install-am install-strip +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - dist-hook distclean distclean-generic distclean-libtool \ - distdir dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive dist-hook distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am +all: nut-scanner-deps + +nut-scanner-deps: + @if python -c 1; then \ + echo "Regenerating the SNMP helper files."; \ + $(top_srcdir)/tools/nut-snmpinfo.py; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Python is not available."; \ + echo "Skipping the SNMP helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi + + @if perl -e 1; then \ + echo "Regenerating the USB helper files."; \ + $(top_srcdir)/tools/nut-usbinfo.pl; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Perl is not available."; \ + echo "Skipping the USB helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi + website: @if python -c pass; then \ echo "Regenerating the HTML and JSON formated HCL tables."; \ - ./nut-hclinfo.py; \ + $(top_srcdir)/tools/nut-hclinfo.py; \ else \ echo "----------------------------------------------------------------------"; \ echo "Warning: Python is not available."; \ @@ -424,8 +664,20 @@ website: echo "----------------------------------------------------------------------"; \ fi -# only call the USB info script upon "make dist", and if Perl is present +# call the USB info script upon "make dist", and if Perl is present +# call the SNMP info script upon "make dist", and if Python is present +# and call both for building nut-scanner dist-hook: + @if python -c 1; then \ + echo "Regenerating the SNMP helper files."; \ + $(distdir)/nut-snmpinfo.py; \ + else \ + echo "----------------------------------------------------------------------"; \ + echo "Warning: Python is not available."; \ + echo "Skipping the SNMP helper files regeneration."; \ + echo "----------------------------------------------------------------------"; \ + fi + @if perl -e 1; then \ echo "Regenerating the USB helper files."; \ $(distdir)/nut-usbinfo.pl; \ @@ -436,6 +688,8 @@ dist-hook: echo "----------------------------------------------------------------------"; \ fi +.PHONY: nut-scanner-deps nut-scanner-snmp-deps nut-scanner-usb-deps + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/tools/nut-scanner/Makefile.am b/tools/nut-scanner/Makefile.am new file mode 100644 index 0000000..005ba0c --- /dev/null +++ b/tools/nut-scanner/Makefile.am @@ -0,0 +1,46 @@ +BUILT_SOURCES = nutscan-usb.h nutscan-snmp.h + +nutscan-usb.h nutscan-snmp.h: + cd ..; $(MAKE) $(AM_MAKEFLAGS) nut-scanner-deps + +lib_LTLIBRARIES = libnutscan.la +libnutscan_la_SOURCES = scan_nut.c scan_ipmi.c \ + nutscan-device.c nutscan-ip.c nutscan-display.c +libnutscan_la_LIBADD = ../../clients/libupsclient.la $(NETLIBS) +libnutscan_la_LDFLAGS = -version-info 1:0:0 +libnutscan_la_CFLAGS = -I$(top_srcdir)/clients -I$(top_srcdir)/include + +bin_PROGRAMS = nut-scanner +nut_scanner_SOURCES = nut-scanner.c +nut_scanner_CFLAGS = -I$(top_srcdir)/clients -I$(top_srcdir)/include +nut_scanner_LDADD = libnutscan.la + +if WITH_SSL + libnutscan_la_CFLAGS += $(LIBSSL_CFLAGS) + libnutscan_la_LIBADD += $(LIBSSL_LIBS) +endif +if WITH_USB + libnutscan_la_SOURCES += scan_usb.c + libnutscan_la_CFLAGS += $(LIBUSB_CFLAGS) + libnutscan_la_LIBADD += $(LIBUSB_LIBS) +endif +if WITH_SNMP + libnutscan_la_SOURCES += scan_snmp.c + libnutscan_la_CFLAGS += $(LIBNETSNMP_CFLAGS) + libnutscan_la_LIBADD += $(LIBNETSNMP_LIBS) +endif +if WITH_NEONXML + libnutscan_la_SOURCES += scan_xml_http.c + libnutscan_la_CFLAGS += $(LIBNEON_CFLAGS) + libnutscan_la_LIBADD += $(LIBNEON_LIBS) +endif +if WITH_AVAHI + libnutscan_la_SOURCES += scan_avahi.c + libnutscan_la_CFLAGS += $(LIBAVAHI_CFLAGS) + libnutscan_la_LIBADD += $(LIBAVAHI_LIBS) +endif + +dist_noinst_HEADERS = nut-scan.h nutscan-usb.h nutscan-snmp.h nutscan-device.h nutscan-ip.h + +CLEANFILES = nutscan-usb.h nutscan-snmp.h + diff --git a/tools/nut-scanner/Makefile.in b/tools/nut-scanner/Makefile.in new file mode 100644 index 0000000..a489329 --- /dev/null +++ b/tools/nut-scanner/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = nut-scanner$(EXEEXT) +@WITH_SSL_TRUE@am__append_1 = $(LIBSSL_CFLAGS) +@WITH_SSL_TRUE@am__append_2 = $(LIBSSL_LIBS) +@WITH_USB_TRUE@am__append_3 = scan_usb.c +@WITH_USB_TRUE@am__append_4 = $(LIBUSB_CFLAGS) +@WITH_USB_TRUE@am__append_5 = $(LIBUSB_LIBS) +@WITH_SNMP_TRUE@am__append_6 = scan_snmp.c +@WITH_SNMP_TRUE@am__append_7 = $(LIBNETSNMP_CFLAGS) +@WITH_SNMP_TRUE@am__append_8 = $(LIBNETSNMP_LIBS) +@WITH_NEONXML_TRUE@am__append_9 = scan_xml_http.c +@WITH_NEONXML_TRUE@am__append_10 = $(LIBNEON_CFLAGS) +@WITH_NEONXML_TRUE@am__append_11 = $(LIBNEON_LIBS) +@WITH_AVAHI_TRUE@am__append_12 = scan_avahi.c +@WITH_AVAHI_TRUE@am__append_13 = $(LIBAVAHI_CFLAGS) +@WITH_AVAHI_TRUE@am__append_14 = $(LIBAVAHI_LIBS) +subdir = tools/nut-scanner +DIST_COMMON = $(dist_noinst_HEADERS) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nut_arg_with.m4 \ + $(top_srcdir)/m4/nut_check_asciidoc.m4 \ + $(top_srcdir)/m4/nut_check_libavahi.m4 \ + $(top_srcdir)/m4/nut_check_libfreeipmi.m4 \ + $(top_srcdir)/m4/nut_check_libgd.m4 \ + $(top_srcdir)/m4/nut_check_libhal.m4 \ + $(top_srcdir)/m4/nut_check_libneon.m4 \ + $(top_srcdir)/m4/nut_check_libnetsnmp.m4 \ + $(top_srcdir)/m4/nut_check_libpowerman.m4 \ + $(top_srcdir)/m4/nut_check_libssl.m4 \ + $(top_srcdir)/m4/nut_check_libusb.m4 \ + $(top_srcdir)/m4/nut_check_libwrap.m4 \ + $(top_srcdir)/m4/nut_check_os.m4 \ + $(top_srcdir)/m4/nut_config_libhal.m4 \ + $(top_srcdir)/m4/nut_report_feature.m4 \ + $(top_srcdir)/m4/nut_type_socklen_t.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +@WITH_SSL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +@WITH_USB_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) +@WITH_SNMP_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) +@WITH_NEONXML_TRUE@am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) +@WITH_AVAHI_TRUE@am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) +libnutscan_la_DEPENDENCIES = ../../clients/libupsclient.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ + $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4) \ + $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_6) +am__libnutscan_la_SOURCES_DIST = scan_nut.c scan_ipmi.c \ + nutscan-device.c nutscan-ip.c nutscan-display.c scan_usb.c \ + scan_snmp.c scan_xml_http.c scan_avahi.c +@WITH_USB_TRUE@am__objects_1 = libnutscan_la-scan_usb.lo +@WITH_SNMP_TRUE@am__objects_2 = libnutscan_la-scan_snmp.lo +@WITH_NEONXML_TRUE@am__objects_3 = libnutscan_la-scan_xml_http.lo +@WITH_AVAHI_TRUE@am__objects_4 = libnutscan_la-scan_avahi.lo +am_libnutscan_la_OBJECTS = libnutscan_la-scan_nut.lo \ + libnutscan_la-scan_ipmi.lo libnutscan_la-nutscan-device.lo \ + libnutscan_la-nutscan-ip.lo libnutscan_la-nutscan-display.lo \ + $(am__objects_1) $(am__objects_2) $(am__objects_3) \ + $(am__objects_4) +libnutscan_la_OBJECTS = $(am_libnutscan_la_OBJECTS) +libnutscan_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libnutscan_la_CFLAGS) \ + $(CFLAGS) $(libnutscan_la_LDFLAGS) $(LDFLAGS) -o $@ +PROGRAMS = $(bin_PROGRAMS) +am_nut_scanner_OBJECTS = nut_scanner-nut-scanner.$(OBJEXT) +nut_scanner_OBJECTS = $(am_nut_scanner_OBJECTS) +nut_scanner_DEPENDENCIES = libnutscan.la +nut_scanner_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(nut_scanner_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libnutscan_la_SOURCES) $(nut_scanner_SOURCES) +DIST_SOURCES = $(am__libnutscan_la_SOURCES_DIST) \ + $(nut_scanner_SOURCES) +HEADERS = $(dist_noinst_HEADERS) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +A2X = @A2X@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BINDIR = @BINDIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONFPATH = @CONFPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DBLATEX = @DBLATEX@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DOC_BUILD_LIST = @DOC_BUILD_LIST@ +DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@ +DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@ +DRIVER_MAN_LIST = @DRIVER_MAN_LIST@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@ +HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@ +HAL_FDI_PATH = @HAL_FDI_PATH@ +HAL_USER = @HAL_USER@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBAVAHI_CFLAGS = @LIBAVAHI_CFLAGS@ +LIBAVAHI_LIBS = @LIBAVAHI_LIBS@ +LIBGD_CFLAGS = @LIBGD_CFLAGS@ +LIBGD_LDFLAGS = @LIBGD_LDFLAGS@ +LIBHAL_CFLAGS = @LIBHAL_CFLAGS@ +LIBHAL_LIBS = @LIBHAL_LIBS@ +LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@ +LIBIPMI_LIBS = @LIBIPMI_LIBS@ +LIBNEON_CFLAGS = @LIBNEON_CFLAGS@ +LIBNEON_LIBS = @LIBNEON_LIBS@ +LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@ +LIBNETSNMP_LIBS = @LIBNETSNMP_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@ +LIBPOWERMAN_LIBS = @LIBPOWERMAN_LIBS@ +LIBS = @LIBS@ +LIBSSL_CFLAGS = @LIBSSL_CFLAGS@ +LIBSSL_LIBS = @LIBSSL_LIBS@ +LIBTOOL = @LIBTOOL@ +LIBUSB_CFLAGS = @LIBUSB_CFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@ +LIBWRAP_LIBS = @LIBWRAP_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NETLIBS = @NETLIBS@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS_NAME = @OS_NAME@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PORT = @PORT@ +RANLIB = @RANLIB@ +RUN_AS_GROUP = @RUN_AS_GROUP@ +RUN_AS_USER = @RUN_AS_USER@ +SED = @SED@ +SERLIBS = @SERLIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STATEPATH = @STATEPATH@ +STRIP = @STRIP@ +SUN_LIBUSB = @SUN_LIBUSB@ +VERSION = @VERSION@ +WORDS_BIGENDIAN = @WORDS_BIGENDIAN@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cgiexecdir = @cgiexecdir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverexecdir = @driverexecdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +hotplugdir = @hotplugdir@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +systemdsystemshutdowndir = @systemdsystemshutdowndir@ +systemdsystemunitdir = @systemdsystemunitdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +udevdir = @udevdir@ +BUILT_SOURCES = nutscan-usb.h nutscan-snmp.h +lib_LTLIBRARIES = libnutscan.la +libnutscan_la_SOURCES = scan_nut.c scan_ipmi.c nutscan-device.c \ + nutscan-ip.c nutscan-display.c $(am__append_3) $(am__append_6) \ + $(am__append_9) $(am__append_12) +libnutscan_la_LIBADD = ../../clients/libupsclient.la $(NETLIBS) \ + $(am__append_2) $(am__append_5) $(am__append_8) \ + $(am__append_11) $(am__append_14) +libnutscan_la_LDFLAGS = -version-info 1:0:0 +libnutscan_la_CFLAGS = -I$(top_srcdir)/clients -I$(top_srcdir)/include \ + $(am__append_1) $(am__append_4) $(am__append_7) \ + $(am__append_10) $(am__append_13) +nut_scanner_SOURCES = nut-scanner.c +nut_scanner_CFLAGS = -I$(top_srcdir)/clients -I$(top_srcdir)/include +nut_scanner_LDADD = libnutscan.la +dist_noinst_HEADERS = nut-scan.h nutscan-usb.h nutscan-snmp.h nutscan-device.h nutscan-ip.h +CLEANFILES = nutscan-usb.h nutscan-snmp.h +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/nut-scanner/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu tools/nut-scanner/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libnutscan.la: $(libnutscan_la_OBJECTS) $(libnutscan_la_DEPENDENCIES) + $(libnutscan_la_LINK) -rpath $(libdir) $(libnutscan_la_OBJECTS) $(libnutscan_la_LIBADD) $(LIBS) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +nut-scanner$(EXEEXT): $(nut_scanner_OBJECTS) $(nut_scanner_DEPENDENCIES) + @rm -f nut-scanner$(EXEEXT) + $(nut_scanner_LINK) $(nut_scanner_OBJECTS) $(nut_scanner_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-nutscan-device.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-nutscan-display.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-nutscan-ip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_avahi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_ipmi.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_nut.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_snmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_usb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnutscan_la-scan_xml_http.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nut_scanner-nut-scanner.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libnutscan_la-scan_nut.lo: scan_nut.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_nut.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_nut.Tpo -c -o libnutscan_la-scan_nut.lo `test -f 'scan_nut.c' || echo '$(srcdir)/'`scan_nut.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_nut.Tpo $(DEPDIR)/libnutscan_la-scan_nut.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_nut.c' object='libnutscan_la-scan_nut.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_nut.lo `test -f 'scan_nut.c' || echo '$(srcdir)/'`scan_nut.c + +libnutscan_la-scan_ipmi.lo: scan_ipmi.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_ipmi.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_ipmi.Tpo -c -o libnutscan_la-scan_ipmi.lo `test -f 'scan_ipmi.c' || echo '$(srcdir)/'`scan_ipmi.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_ipmi.Tpo $(DEPDIR)/libnutscan_la-scan_ipmi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_ipmi.c' object='libnutscan_la-scan_ipmi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_ipmi.lo `test -f 'scan_ipmi.c' || echo '$(srcdir)/'`scan_ipmi.c + +libnutscan_la-nutscan-device.lo: nutscan-device.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-nutscan-device.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-nutscan-device.Tpo -c -o libnutscan_la-nutscan-device.lo `test -f 'nutscan-device.c' || echo '$(srcdir)/'`nutscan-device.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-nutscan-device.Tpo $(DEPDIR)/libnutscan_la-nutscan-device.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nutscan-device.c' object='libnutscan_la-nutscan-device.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-nutscan-device.lo `test -f 'nutscan-device.c' || echo '$(srcdir)/'`nutscan-device.c + +libnutscan_la-nutscan-ip.lo: nutscan-ip.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-nutscan-ip.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-nutscan-ip.Tpo -c -o libnutscan_la-nutscan-ip.lo `test -f 'nutscan-ip.c' || echo '$(srcdir)/'`nutscan-ip.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-nutscan-ip.Tpo $(DEPDIR)/libnutscan_la-nutscan-ip.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nutscan-ip.c' object='libnutscan_la-nutscan-ip.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-nutscan-ip.lo `test -f 'nutscan-ip.c' || echo '$(srcdir)/'`nutscan-ip.c + +libnutscan_la-nutscan-display.lo: nutscan-display.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-nutscan-display.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-nutscan-display.Tpo -c -o libnutscan_la-nutscan-display.lo `test -f 'nutscan-display.c' || echo '$(srcdir)/'`nutscan-display.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-nutscan-display.Tpo $(DEPDIR)/libnutscan_la-nutscan-display.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nutscan-display.c' object='libnutscan_la-nutscan-display.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-nutscan-display.lo `test -f 'nutscan-display.c' || echo '$(srcdir)/'`nutscan-display.c + +libnutscan_la-scan_usb.lo: scan_usb.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_usb.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_usb.Tpo -c -o libnutscan_la-scan_usb.lo `test -f 'scan_usb.c' || echo '$(srcdir)/'`scan_usb.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_usb.Tpo $(DEPDIR)/libnutscan_la-scan_usb.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_usb.c' object='libnutscan_la-scan_usb.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_usb.lo `test -f 'scan_usb.c' || echo '$(srcdir)/'`scan_usb.c + +libnutscan_la-scan_snmp.lo: scan_snmp.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_snmp.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_snmp.Tpo -c -o libnutscan_la-scan_snmp.lo `test -f 'scan_snmp.c' || echo '$(srcdir)/'`scan_snmp.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_snmp.Tpo $(DEPDIR)/libnutscan_la-scan_snmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_snmp.c' object='libnutscan_la-scan_snmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_snmp.lo `test -f 'scan_snmp.c' || echo '$(srcdir)/'`scan_snmp.c + +libnutscan_la-scan_xml_http.lo: scan_xml_http.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_xml_http.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_xml_http.Tpo -c -o libnutscan_la-scan_xml_http.lo `test -f 'scan_xml_http.c' || echo '$(srcdir)/'`scan_xml_http.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_xml_http.Tpo $(DEPDIR)/libnutscan_la-scan_xml_http.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_xml_http.c' object='libnutscan_la-scan_xml_http.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_xml_http.lo `test -f 'scan_xml_http.c' || echo '$(srcdir)/'`scan_xml_http.c + +libnutscan_la-scan_avahi.lo: scan_avahi.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -MT libnutscan_la-scan_avahi.lo -MD -MP -MF $(DEPDIR)/libnutscan_la-scan_avahi.Tpo -c -o libnutscan_la-scan_avahi.lo `test -f 'scan_avahi.c' || echo '$(srcdir)/'`scan_avahi.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libnutscan_la-scan_avahi.Tpo $(DEPDIR)/libnutscan_la-scan_avahi.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scan_avahi.c' object='libnutscan_la-scan_avahi.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnutscan_la_CFLAGS) $(CFLAGS) -c -o libnutscan_la-scan_avahi.lo `test -f 'scan_avahi.c' || echo '$(srcdir)/'`scan_avahi.c + +nut_scanner-nut-scanner.o: nut-scanner.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nut_scanner_CFLAGS) $(CFLAGS) -MT nut_scanner-nut-scanner.o -MD -MP -MF $(DEPDIR)/nut_scanner-nut-scanner.Tpo -c -o nut_scanner-nut-scanner.o `test -f 'nut-scanner.c' || echo '$(srcdir)/'`nut-scanner.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/nut_scanner-nut-scanner.Tpo $(DEPDIR)/nut_scanner-nut-scanner.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nut-scanner.c' object='nut_scanner-nut-scanner.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nut_scanner_CFLAGS) $(CFLAGS) -c -o nut_scanner-nut-scanner.o `test -f 'nut-scanner.c' || echo '$(srcdir)/'`nut-scanner.c + +nut_scanner-nut-scanner.obj: nut-scanner.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nut_scanner_CFLAGS) $(CFLAGS) -MT nut_scanner-nut-scanner.obj -MD -MP -MF $(DEPDIR)/nut_scanner-nut-scanner.Tpo -c -o nut_scanner-nut-scanner.obj `if test -f 'nut-scanner.c'; then $(CYGPATH_W) 'nut-scanner.c'; else $(CYGPATH_W) '$(srcdir)/nut-scanner.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/nut_scanner-nut-scanner.Tpo $(DEPDIR)/nut_scanner-nut-scanner.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nut-scanner.c' object='nut_scanner-nut-scanner.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nut_scanner_CFLAGS) $(CFLAGS) -c -o nut_scanner-nut-scanner.obj `if test -f 'nut-scanner.c'; then $(CYGPATH_W) 'nut-scanner.c'; else $(CYGPATH_W) '$(srcdir)/nut-scanner.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) +install-binPROGRAMS: install-libLTLIBRARIES + +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS install-libLTLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libLTLIBRARIES clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-libLTLIBRARIES + + +nutscan-usb.h nutscan-snmp.h: + cd ..; $(MAKE) $(AM_MAKEFLAGS) nut-scanner-deps + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tools/nut-scanner/nut-scan.h b/tools/nut-scanner/nut-scan.h new file mode 100644 index 0000000..c5ce748 --- /dev/null +++ b/tools/nut-scanner/nut-scan.h @@ -0,0 +1,65 @@ +/* nut-scan.h: detect NUT services + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#ifndef NUT_SCAN_H +#define NUT_SCAN_H + +#include +#include + +/* SNMP structure */ +typedef struct nutscan_snmp { + char * community; + char * secLevel; + char * secName; + char * authPassword; + char * privPassword; + char * authProtocol; + char * privProtocol; + char * peername; + void * handle; +} nutscan_snmp_t; + +/* Scanning */ +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H +nutscan_device_t * nutscan_scan_snmp(const char * start_ip,const char * stop_ip,long usec_timeout, nutscan_snmp_t * sec); +#endif + +#ifdef HAVE_USB_H +nutscan_device_t * nutscan_scan_usb(); +#endif + +#ifdef WITH_NEON +nutscan_device_t * nutscan_scan_xml_http(long usec_timeout); +#endif + +nutscan_device_t * nutscan_scan_nut(const char * startIP, const char * stopIP, const char * port, long usec_timeout); + +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H +nutscan_device_t * nutscan_scan_avahi(long usec_timeout); +#endif + +#ifdef HAVE_FREEIPMI_FREEIPMI_H +nutscan_device_t * nutscan_scan_ipmi(void); +#endif + +/* Displaying */ +void nutscan_display_ups_conf(nutscan_device_t * device); +void nutscan_display_parsable(nutscan_device_t * device); + +#endif diff --git a/tools/nut-scanner/nut-scanner.c b/tools/nut-scanner/nut-scanner.c new file mode 100644 index 0000000..b42dbca --- /dev/null +++ b/tools/nut-scanner/nut-scanner.c @@ -0,0 +1,415 @@ +/* nut-scanner.c: a tool to detect NUT supported devices + * + * Copyright (C) 2011 - Arnaud Quette + * + * 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 + */ + +#include +#include +#include +#include "common.h" +#include +#include +#ifdef HAVE_PTHREAD +#include +#endif + +#include "nut-scan.h" + +#define DEFAULT_TIMEOUT 5 + +const char optstring[] = "?ht:s:e:c:l:u:W:X:w:x:p:CUSMOAm:NPqI"; + +#ifdef HAVE_GETOPT_LONG +const struct option longopts[] = + {{ "timeout",required_argument,NULL,'t' }, + { "start_ip",required_argument,NULL,'s' }, + { "end_ip",required_argument,NULL,'e' }, + { "mask_cidr",required_argument,NULL,'m' }, + { "community",required_argument,NULL,'c' }, + { "secLevel",required_argument,NULL,'l' }, + { "secName",required_argument,NULL,'u' }, + { "authPassword",required_argument,NULL,'W' }, + { "privPassword",required_argument,NULL,'X' }, + { "authProtocol",required_argument,NULL,'w' }, + { "privProtocol",required_argument,NULL,'x' }, + { "port",required_argument,NULL,'p' }, + { "complete_scan",no_argument,NULL,'C' }, + { "usb_scan",no_argument,NULL,'U' }, + { "snmp_scan",no_argument,NULL,'S' }, + { "xml_scan",no_argument,NULL,'M' }, + { "oldnut_scan",no_argument,NULL,'O' }, + { "avahi_scan",no_argument,NULL,'A' }, + { "ipmi_scan",no_argument,NULL,'I' }, + { "disp_nut_conf",no_argument,NULL,'N' }, + { "disp_parsable",no_argument,NULL,'P' }, + { "quiet",no_argument,NULL,'q' }, + { "help",no_argument,NULL,'h' }, + {NULL,0,NULL,0}}; +#else +#define getopt_long(a,b,c,d,e) getopt(a,b,c) +#endif /* HAVE_GETOPT_LONG */ + +static nutscan_device_t *dev[TYPE_END]; +static pthread_t thread[TYPE_END]; + +static long timeout = DEFAULT_TIMEOUT*1000*1000; /* in usec */ +static char * start_ip = NULL; +static char * end_ip = NULL; +static char * port = NULL; + +#ifdef HAVE_PTHREAD +#ifdef HAVE_USB_H +static void * run_usb(void * arg) +{ + dev[TYPE_USB] = nutscan_scan_usb(); + return NULL; +} +#endif +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H +static void * run_snmp(void * arg) +{ + nutscan_snmp_t * sec = (nutscan_snmp_t *)arg; + + dev[TYPE_SNMP] = nutscan_scan_snmp(start_ip,end_ip,timeout,sec); + return NULL; +} +#endif +#ifdef WITH_NEON +static void * run_xml(void * arg) +{ + dev[TYPE_XML] = nutscan_scan_xml_http(timeout); + return NULL; +} +#endif + +static void * run_nut_old(void * arg) +{ + dev[TYPE_NUT] = nutscan_scan_nut(start_ip,end_ip,port,timeout); + return NULL; +} + +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H +static void * run_avahi(void * arg) +{ + dev[TYPE_AVAHI] = nutscan_scan_avahi(timeout); + return NULL; +} +#endif +#ifdef HAVE_FREEIPMI_FREEIPMI_H +static void * run_ipmi(void * arg) +{ + dev[TYPE_IPMI] = nutscan_scan_ipmi(); + return NULL; +} +#endif +#endif /* HAVE_PTHREAD */ +static int printq(int quiet,const char *fmt, ...) +{ + va_list ap; + int ret; + + if(quiet) { + return 0; + } + + va_start(ap, fmt); + ret = vprintf(fmt, ap); + va_end(ap); + + return ret; +} + +int main(int argc, char *argv[]) +{ + nutscan_snmp_t sec; + int opt_ret; + char * cidr = NULL; + int allow_all = 0; + int allow_usb = 0; + int allow_snmp = 0; + int allow_xml = 0; + int allow_oldnut = 0; + int allow_avahi = 0; + int allow_ipmi = 0; + int quiet = 0; + void (*display_func)(nutscan_device_t * device); + + memset(&sec,0,sizeof(sec)); + + display_func = nutscan_display_ups_conf; + + while((opt_ret = getopt_long(argc, argv, optstring, longopts, NULL))!=-1) { + + switch(opt_ret) { + case 't': + timeout = atol(optarg)*1000*1000; /*in usec*/ + if( timeout == 0 ) { + fprintf(stderr,"Illegal timeout value, using default %ds\n", DEFAULT_TIMEOUT); + timeout = DEFAULT_TIMEOUT*1000*1000; + } + break; + case 's': + start_ip = strdup(optarg); + end_ip = start_ip; + break; + case 'e': + end_ip = strdup(optarg); + break; + case 'm': + cidr = strdup(optarg); + break; +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + case 'c': + sec.community = strdup(optarg); + break; + case 'l': + sec.secLevel = strdup(optarg); + break; + case 'u': + sec.secName = strdup(optarg); + break; + case 'W': + sec.authPassword = strdup(optarg); + break; + case 'X': + sec.privPassword = strdup(optarg); + break; + case 'w': + sec.authProtocol = strdup(optarg); + break; + case 'x': + sec.privProtocol = strdup(optarg); + break; +#endif + case 'p': + port = strdup(optarg); + break; + case 'C': + allow_all = 1; + break; +#ifdef HAVE_USB_H + case 'U': + allow_usb = 1; + break; +#endif +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + case 'S': + allow_snmp = 1; + break; +#endif +#ifdef WITH_NEON + case 'M': + allow_xml = 1; + break; +#endif + case 'O': + allow_oldnut = 1; + break; +#ifdef WITH_AVAHI + case 'A': + allow_avahi = 1; + break; +#endif +#ifdef HAVE_FREEIPMI_FREEIPMI_H + case 'I': + allow_ipmi = 1; + break; +#endif + case 'N': + display_func = nutscan_display_ups_conf; + break; + case 'P': + display_func = nutscan_display_parsable; + break; + case 'q': + quiet = 1; + break; + case 'h': + case '?': + default: + puts("nut-scanner : detecting available UPS.\n"); + puts("OPTIONS:"); + printf(" -C, --complete_scan : Scan all available devices (default).\n"); +#ifdef HAVE_USB_H + printf(" -U, --usb_scan : Scan USB devices.\n"); +#endif +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + printf(" -S, --snmp_scan : Scan SNMP devices.\n"); +#endif +#ifdef WITH_NEON + printf(" -M, --xml_scan : Scan XML/HTTP devices.\n"); +#endif + printf(" -O, --oldnut_scan : Scan NUT devices (old method).\n"); +#ifdef WITH_AVAHI + printf(" -A, --avahi_scan : Scan NUT devices (avahi method).\n"); +#endif +#ifdef HAVE_FREEIPMI_FREEIPMI_H + printf(" -I, --ipmi_scan : Scan IPMI devices.\n"); +#endif + printf(" -t, --timeout : network operation timeout (default %d).\n",DEFAULT_TIMEOUT); + printf(" -s, --start_ip : First IP address to scan.\n"); + printf(" -e, --end_ip : Last IP address to scan.\n"); + +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + printf("\nSNMP v1 specific options:\n"); + printf(" -c, --community : Set SNMP v1 community name (default = public)\n"); + + printf("\nSNMP v3 specific options:\n"); + printf(" -l, --secLevel : Set the securityLevel used for SNMPv3 messages (allowed values: noAuthNoPriv,authNoPriv,authPriv)\n"); + printf(" -u, --secName : Set the securityName used for authenticated SNMPv3 messages (mandatory if you set secLevel. No default)\n"); + printf(" -a, --authProtocol : Set the authentication protocol (MD5 or SHA) used for authenticated SNMPv3 messages (default=MD5)\n"); + printf(" -A, --authPassword : Set the authentication pass phrase used for authenticated SNMPv3 messages (mandatory if you set secLevel to authNoPriv or authPriv)\n"); + printf(" -x, --privProtocol : Set the privacy protocol (DES or AES) used for encrypted SNMPv3 messages (default=DES)\n"); + printf(" -X, --privPassword : Set the privacy pass phrase used for encrypted SNMPv3 messages (mandatory if you set secLevel to authPriv)\n"); +#endif + + printf("\nNUT device specific options:\n"); + printf(" -p, --port : Port number of remote NUT devices\n"); + printf("\ndisplay specific options:\n"); + printf(" -N, --disp_nut_conf : Display result in the ups.conf format\n"); + printf(" -P, --disp_parsable : Display result in a parsable format\n"); + return 0; + } + + } + + if( cidr ) { + nutscan_cidr_to_ip(cidr, &start_ip, &end_ip); + } + + if( !allow_usb && !allow_snmp && !allow_xml && !allow_oldnut && + !allow_avahi && !allow_ipmi ) { + allow_all = 1; + } + +#ifdef HAVE_USB_H + if( allow_all || allow_usb) { + printq(quiet,"Scanning USB bus.\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_USB],NULL,run_usb,NULL); +#else + dev[TYPE_USB] = nutscan_scan_usb(); +#endif + } +#endif /* HAVE_USB_H */ + +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + if( allow_all || allow_snmp) { + if( start_ip == NULL ) { + printq(quiet,"No start IP, skipping SNMP\n"); + } + else { + printq(quiet,"Scanning SNMP bus.\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_SNMP],NULL,run_snmp,&sec); +#else + dev[TYPE_SNMP] = nutscan_scan_snmp(start_ip,end_ip,timeout,&sec); +#endif + } + } +#endif /* HAVE_NET_SNMP_NET_SNMP_CONFIG_H */ + +#ifdef WITH_NEON + if( allow_all || allow_xml) { + printq(quiet,"Scanning XML/HTTP bus.\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_XML],NULL,run_xml,NULL); +#else + dev[TYPE_XML] = nutscan_scan_xml_http(timeout); +#endif + } +#endif + + if( allow_all || allow_oldnut) { + if( start_ip == NULL ) { + printq(quiet,"No start IP, skipping NUT bus (old connect method)\n"); + } + else { + printq(quiet,"Scanning NUT bus (old connect method).\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_NUT],NULL,run_nut_old,NULL); +#else + dev[TYPE_NUT] = nutscan_scan_nut(start_ip,end_ip,port,timeout); +#endif + } + } + +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H + if( allow_all || allow_avahi) { + printq(quiet,"Scanning NUT bus (avahi method).\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_AVAHI],NULL,run_avahi,NULL); +#else + dev[TYPE_AVAHI] = nutscan_scan_avahi(); +#endif + } +#endif + +#ifdef HAVE_FREEIPMI_FREEIPMI_H + if( allow_all || allow_ipmi) { + printq(quiet,"Scanning IPMI bus.\n"); +#ifdef HAVE_PTHREAD + pthread_create(&thread[TYPE_IPMI],NULL,run_ipmi,NULL); +#else + dev[TYPE_IPMI] = nutscan_scan_ipmi(); +#endif + } +#endif + +#ifdef HAVE_PTHREAD +#ifdef HAVE_USB_H + pthread_join(thread[TYPE_USB],NULL); +#endif +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + pthread_join(thread[TYPE_SNMP],NULL); +#endif +#ifdef WITH_NEON + pthread_join(thread[TYPE_XML],NULL); +#endif + pthread_join(thread[TYPE_NUT],NULL); +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H + pthread_join(thread[TYPE_AVAHI],NULL); +#endif +#ifdef HAVE_FREEIPMI_FREEIPMI_H + pthread_join(thread[TYPE_IPMI],NULL); +#endif +#endif /* HAVE_PTHREAD */ + +#ifdef HAVE_USB_H + display_func(dev[TYPE_USB]); + nutscan_free_device(dev[TYPE_USB]); +#endif +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + display_func(dev[TYPE_SNMP]); + nutscan_free_device(dev[TYPE_SNMP]); +#endif +#ifdef WITH_NEON + display_func(dev[TYPE_XML]); + nutscan_free_device(dev[TYPE_XML]); +#endif + display_func(dev[TYPE_NUT]); + nutscan_free_device(dev[TYPE_NUT]); +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H + display_func(dev[TYPE_AVAHI]); + nutscan_free_device(dev[TYPE_AVAHI]); +#endif +#ifdef HAVE_FREEIPMI_FREEIPMI_H + display_func(dev[TYPE_IPMI]); + nutscan_free_device(dev[TYPE_IPMI]); +#endif + return EXIT_SUCCESS; +} diff --git a/tools/nut-scanner/nutscan-device.c b/tools/nut-scanner/nutscan-device.c new file mode 100644 index 0000000..b536398 --- /dev/null +++ b/tools/nut-scanner/nutscan-device.c @@ -0,0 +1,183 @@ +/* device.c: manipulation of a container describing a NUT device + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#include "nutscan-device.h" +#include +#include + +nutscan_device_t * nutscan_new_device() +{ + nutscan_device_t * device; + + device = malloc(sizeof(nutscan_device_t)); + if( device==NULL) { + return NULL; + } + + memset(device,0,sizeof(nutscan_device_t)); + + return device; +} + +static void deep_free_device(nutscan_device_t * device) +{ + nutscan_options_t * current; + nutscan_options_t * old; + + if(device==NULL) { + return; + } + if(device->driver) { + free(device->driver); + } + if(device->port) { + free(device->port); + } + + current = &device->opt; + + if(current->option != NULL) { + free(current->option); + } + + if(current->value != NULL) { + free(current->value); + } + + current = current->next; + while (current != NULL) { + if(current->option != NULL) { + free(current->option); + } + + if(current->value != NULL) { + free(current->value); + } + old = current; + current = current->next; + free(old); + }; + + if(device->prev) { + device->prev->next = device->next; + } + if(device->next) { + device->next->prev = device->prev; + } + + free(device); +} + +void nutscan_free_device(nutscan_device_t * device) +{ + if(device==NULL) { + return; + } + while(device->prev != NULL) { + deep_free_device(device->prev); + } + while(device->next != NULL) { + deep_free_device(device->next); + } + + free(device); +} + +void nutscan_add_option_to_device(nutscan_device_t * device,char * option, char * value) +{ + nutscan_options_t * opt; + + opt = &(device->opt); + /* search for last entry */ + if( opt->option != NULL ) { + while( opt->next != NULL ) { + opt = opt->next; + } + + opt->next = malloc(sizeof(nutscan_options_t)); + opt = opt->next; + memset(opt,0,sizeof(nutscan_options_t)); + } + + if( option != NULL ) { + opt->option = strdup(option); + } + else { + opt->option = NULL; + } + + if( value != NULL ) { + opt->value = strdup(value); + } + else { + opt->value = NULL; + } +} + +nutscan_device_t * nutscan_add_device_to_device(nutscan_device_t * first, nutscan_device_t * second) +{ + nutscan_device_t * dev1=NULL; + nutscan_device_t * dev2=NULL; + + /* Get end of first device */ + if( first != NULL) { + dev1 = first; + while(dev1->next != NULL) { + dev1 = dev1->next; + } + } + else { + if( second == NULL ) { + return NULL; + } + /* return end of second */ + dev2 = second; + while(dev2->next != NULL) { + dev2 = dev2->next; + } + return dev2; + } + + /* Get start of second */ + if( second != NULL ) { + dev2 = second; + while(dev2->prev != NULL) { + dev2 = dev2->prev; + } + } + else { + /* return end of first */ + dev1 = first; + while(dev1->next != NULL) { + dev1 = dev1->next; + + } + return dev1; + } + + /* join both */ + dev1->next = dev2; + dev2->prev = dev1; + + /* return end of both */ + while(dev2->next != NULL) { + dev2 = dev2->next; + } + + return dev2; +} diff --git a/tools/nut-scanner/nutscan-device.h b/tools/nut-scanner/nutscan-device.h new file mode 100644 index 0000000..d96f9f3 --- /dev/null +++ b/tools/nut-scanner/nutscan-device.h @@ -0,0 +1,52 @@ +/* device.h: definition of a container describing a NUT device + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#ifndef SCAN_DEVICE +#define SCAN_DEVICE + +typedef enum nutscan_device_type { + TYPE_NONE=0, + TYPE_USB, + TYPE_SNMP, + TYPE_XML, + TYPE_NUT, + TYPE_IPMI, + TYPE_AVAHI, + TYPE_END +} nutscan_device_type_t; + +typedef struct nutscan_options { + char * option; + char * value; + struct nutscan_options* next; +} nutscan_options_t; + +typedef struct nutscan_device { + nutscan_device_type_t type; + char * driver; + char * port; + nutscan_options_t opt; + struct nutscan_device * prev; + struct nutscan_device * next; +} nutscan_device_t; + +nutscan_device_t * nutscan_new_device(); +void nutscan_free_device(nutscan_device_t * device); +void nutscan_add_option_to_device(nutscan_device_t * device,char * option, char * value); +nutscan_device_t * nutscan_add_device_to_device(nutscan_device_t * first, nutscan_device_t * second); +#endif diff --git a/tools/nut-scanner/nutscan-display.c b/tools/nut-scanner/nutscan-display.c new file mode 100644 index 0000000..1cbbfc8 --- /dev/null +++ b/tools/nut-scanner/nutscan-display.c @@ -0,0 +1,112 @@ +/* display.c: format and display scanned devices + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "common.h" +#include +#include "nutscan-device.h" + +char nutscan_device_type_string[TYPE_END][6] = { + "NONE", + "USB", + "SNMP", + "XML", + "NUT", + "IPMI", + "AVAHI" }; + +void nutscan_display_ups_conf(nutscan_device_t * device) +{ + nutscan_device_t * current_dev = device; + nutscan_options_t * opt; + static int nutdev_num = 1; + + if(device==NULL) { + return; + } + + /* Find start of the list */ + while(current_dev->prev != NULL) { + current_dev = current_dev->prev; + } + + /* Display each devices */ + do { + printf("[nutdev%i]\n\tdriver = \"%s\"\n\tport = \"%s\"\n", + nutdev_num, current_dev->driver, + current_dev->port); + + opt = &(current_dev->opt); + + do { + if( opt->option != NULL ) { + printf("\t%s",opt->option); + if( opt->value != NULL ) { + printf(" = \"%s\"", opt->value); + } + printf("\n"); + } + opt = opt->next; + } while( opt != NULL ); + + nutdev_num++; + + current_dev = current_dev->next; + } + while( current_dev != NULL ); +} + +void nutscan_display_parsable(nutscan_device_t * device) +{ + nutscan_device_t * current_dev = device; + nutscan_options_t * opt; + + if(device==NULL) { + return; + } + + /* Find start of the list */ + while(current_dev->prev != NULL) { + current_dev = current_dev->prev; + } + + /* Display each devices */ + do { + printf("%s:driver=\"%s\",port=\"%s\"", + nutscan_device_type_string[current_dev->type], + current_dev->driver, + current_dev->port); + + opt = &(current_dev->opt); + + do { + if( opt->option != NULL ) { + printf(",%s",opt->option); + if( opt->value != NULL ) { + printf("=\"%s\"", opt->value); + } + } + opt = opt->next; + } while( opt != NULL ); + printf("\n"); + + current_dev = current_dev->next; + } + while( current_dev != NULL ); +} + diff --git a/tools/nut-scanner/nutscan-ip.c b/tools/nut-scanner/nutscan-ip.c new file mode 100644 index 0000000..97fbffb --- /dev/null +++ b/tools/nut-scanner/nutscan-ip.c @@ -0,0 +1,219 @@ +/* ip.c: iterator for IPv4 or IPv6 addresses + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "nutscan-ip.h" +#include +#include "common.h" + +static void increment_IPv6(struct in6_addr * addr) +{ + int i; + + for( i=15 ; i>= 0 ; i--) { + addr->s6_addr[i]++; + if( addr->s6_addr[i] != 0) { + break; + } + } +} + +static void invert_IPv6(struct in6_addr * addr1, struct in6_addr * addr2) +{ + struct in6_addr addr; + + memcpy(addr.s6_addr,addr1->s6_addr,sizeof(addr.s6_addr)); + memcpy(addr1->s6_addr,addr2->s6_addr,sizeof(addr.s6_addr)); + memcpy(addr2->s6_addr,addr.s6_addr,sizeof(addr.s6_addr)); +} + +/* Return the first ip or NULL if error */ +char * nutscan_ip_iter_init(nutscan_ip_iter_t * ip, const char * startIP, const char * stopIP) +{ + int addr; + int i; + char buf[SMALLBUF]; + + if( startIP == NULL ) { + return NULL; + } + + if(stopIP == NULL ) { + stopIP = startIP; + } + + ip->type = IPv4; + /* Detecting IPv4 vs IPv6 */ + if(!inet_aton(startIP, &ip->start)) { + /*Try IPv6 detection */ + ip->type = IPv6; + if(!inet_pton(AF_INET6, startIP, &ip->start6)){ + fprintf(stderr,"Invalid address : %s\n",startIP); + return NULL; + } + } + + /* Compute stop IP */ + if( ip->type == IPv4 ) { + if(!inet_aton(stopIP, &ip->stop)) { + fprintf(stderr,"Invalid address : %s\n",stopIP); + return NULL; + } + } + else { + if(!inet_pton(AF_INET6, stopIP, &ip->stop6)){ + fprintf(stderr,"Invalid address : %s\n",stopIP); + return NULL; + } + } + + /* Make sure start IP is lesser than stop IP */ + if( ip->type == IPv4 ) { + if( ntohl(ip->start.s_addr) > ntohl(ip->stop.s_addr) ) { + addr = ip->start.s_addr; + ip->start.s_addr = ip->stop.s_addr; + ip->stop.s_addr = addr; + } + return strdup(inet_ntoa(ip->start)); + } + else { /* IPv6 */ + for( i=0; i<16; i++ ) { + if( ip->start6.s6_addr[i] !=ip->stop6.s6_addr[i] ) { + if(ip->start6.s6_addr[i]>ip->stop6.s6_addr[i]){ + invert_IPv6(&ip->start6,&ip->stop6); + } + break; + } + } + return strdup(inet_ntop(AF_INET6,&ip->start6,buf,sizeof(buf))); + } + + +} + +/* return the next IP +return NULL if there is no more IP +*/ +char * nutscan_ip_iter_inc(nutscan_ip_iter_t * ip) +{ + char buf[SMALLBUF]; + + if( ip->type == IPv4 ) { + /* Check if this is the last address to scan */ + if(ip->start.s_addr == ip->stop.s_addr) { + return NULL; + } + /* increment the address (need to pass address in host + byte order, then pass back in network byte order */ + ip->start.s_addr = htonl((ntohl(ip->start.s_addr)+1)); + + return strdup(inet_ntoa(ip->start)); + } + else { + /* Check if this is the last address to scan */ + if( memcmp(&ip->start6.s6_addr, &ip->stop6.s6_addr, + sizeof(ip->start6.s6_addr)) == 0 ) { + return NULL; + } + + increment_IPv6(&ip->start6); + + return strdup(inet_ntop(AF_INET6,&ip->start6,buf,sizeof(buf))); + } +} + +int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip) +{ + char * cidr_tok; + char * first_ip; + char * mask; + char * saveptr = NULL; + nutscan_ip_iter_t ip; + int mask_val; + int mask_byte; + long mask_bit; + char buf[SMALLBUF]; + + *start_ip = NULL; + *stop_ip = NULL; + + cidr_tok = strdup(cidr); + first_ip = strdup(strtok_r(cidr_tok,"/",&saveptr)); + if( first_ip == NULL) { + return 0; + } + mask = strtok_r(NULL,"/",&saveptr); + if( mask == NULL ) { + return 0; + } + free(cidr_tok); + + mask_val = atoi(mask); + + /* Detecting IPv4 vs IPv6 */ + ip.type = IPv4; + if(!inet_aton(first_ip, &ip.start)) { + /*Try IPv6 detection */ + ip.type = IPv6; + if(!inet_pton(AF_INET6, first_ip, &ip.start6)){ + free(first_ip); + return 0; + } + } + + if( ip.type == IPv4 ) { + + if( mask_val > 0 ) { + mask_val --; + mask_bit = 0x80000000; + mask_bit >>= mask_val; + mask_bit--; + } + else { + mask_bit = 0xffffffff; + } + ip.stop.s_addr = htonl(ntohl(ip.start.s_addr)|mask_bit); + ip.start.s_addr = htonl(ntohl(ip.start.s_addr)&(~mask_bit)); + + *start_ip = strdup(inet_ntoa(ip.start)); + *stop_ip = strdup(inet_ntoa(ip.stop)); + free(first_ip); + return 1; + } + else { + inet_pton(AF_INET6, first_ip, &ip.stop6); + + mask_byte = mask_val / 8; + if( mask_byte < 16 ) { + memset( &(ip.stop6.s6_addr[mask_byte+1]), 0xFF, 15 - mask_byte); + memset( &(ip.start6.s6_addr[mask_byte+1]), 0x00, 15 - mask_byte); + + mask_bit = (0x100 >> mask_val%8)-1; + ip.stop6.s6_addr[mask_byte] |= mask_bit; + ip.start6.s6_addr[mask_byte] &= (~mask_bit); + } + + inet_ntop(AF_INET6,&ip.start6,buf,sizeof(buf)); + *start_ip = strdup(buf); + inet_ntop(AF_INET6,&ip.stop6,buf,sizeof(buf)); + *stop_ip = strdup(buf); + } + + free(first_ip); + return 1; +} diff --git a/tools/nut-scanner/nutscan-ip.h b/tools/nut-scanner/nutscan-ip.h new file mode 100644 index 0000000..01f329f --- /dev/null +++ b/tools/nut-scanner/nutscan-ip.h @@ -0,0 +1,42 @@ +/* ip.h: iterator for IPv4 or IPv6 addresses + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#ifndef SCAN_IP +#define SCAN_IP + +#include +#include +#include + +enum network_type { + IPv4, + IPv6 +}; + +typedef struct nutscan_ip_iter { + enum network_type type; + struct in_addr start; + struct in_addr stop; + struct in6_addr start6; + struct in6_addr stop6; +} nutscan_ip_iter_t; + +char * nutscan_ip_iter_init(nutscan_ip_iter_t *, const char * startIP, const char * stopIP); +char * nutscan_ip_iter_inc(nutscan_ip_iter_t *); +int nutscan_cidr_to_ip(const char * cidr, char ** start_ip, char ** stop_ip); +#endif diff --git a/tools/nut-scanner/nutscan-snmp.h b/tools/nut-scanner/nutscan-snmp.h new file mode 100644 index 0000000..a08a892 --- /dev/null +++ b/tools/nut-scanner/nutscan-snmp.h @@ -0,0 +1,45 @@ +/* nutscan-snmp + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#ifndef DEVSCAN_SNMP_H +#define DEVSCAN_SNMP_H + +typedef struct { + char * oid; + char * mib; + char * sysoid; +} snmp_device_id_t; + +/* SNMP IDs device table */ +static snmp_device_id_t snmp_device_table[] = { + { ".1.3.6.1.4.1.2947.1.1.2.0" , "bestpower", NULL}, + { ".1.3.6.1.4.1.13742.1.1.12.0" , "raritan", ".1.3.6.1.4.1.13742"}, + { "1.3.6.1.2.1.33.1.1.1.0" , "ietf", ".1.3.6.1.2.1.33"}, + { ".1.3.6.1.4.1.17373.3.1.1.0" , "aphel_genesisII", ".1.3.6.1.4.1.17373"}, + { ".1.3.6.1.4.1.534.6.6.6.1.1.12.0" , "aphel_revelation", ".1.3.6.1.4.1.534.6.6.6"}, + { ".1.3.6.1.4.1.534.6.6.7.1.2.1.2.0" , "eaton_epdu", ".1.3.6.1.4.1.534.6.6.7"}, + { "1.3.6.1.4.1.534.1.1.2.0" , "pw", ".1.3.6.1.4.1.534.1"}, + { ".1.3.6.1.4.1.705.1.1.1.0" , "mge", ".1.3.6.1.4.1.705.1"}, + { ".1.3.6.1.4.1.318.1.1.1.1.1.1.0" , "apcc", NULL}, + { ".1.3.6.1.4.1.4779.1.3.5.2.1.24.1" , "baytech", NULL}, + { "1.3.6.1.4.1.232.165.3.1.1.0" , "cpqpower", NULL}, + { ".1.3.6.1.4.1.4555.1.1.1.1.1.1.0" , "netvision", ".1.3.6.1.4.1.4555.1.1.1"}, + /* Terminating entry */ + { NULL, NULL, NULL} +}; +#endif /* DEVSCAN_SNMP_H */ diff --git a/tools/nut-scanner/nutscan-usb.h b/tools/nut-scanner/nutscan-usb.h new file mode 100644 index 0000000..6065e33 --- /dev/null +++ b/tools/nut-scanner/nutscan-usb.h @@ -0,0 +1,111 @@ +/* nutscan-usb + * Copyright (C) 2011 - Arnaud Quette + * + * 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 + */ + +#ifndef DEVSCAN_USB_H +#define DEVSCAN_USB_H + +#include +#include "nut_stdint.h" /* for uint16_t */ + +typedef struct { + uint16_t vendorID; + uint16_t productID; + char* driver_name; +} usb_device_id_t; + +/* USB IDs device table */ +static usb_device_id_t usb_device_table[] = { + + { 0x03f0, 0x1f01, "bcmxcp_usb" }, + { 0x03f0, 0x1f02, "bcmxcp_usb" }, + { 0x03f0, 0x1f06, "usbhid-ups" }, + { 0x03f0, 0x1f08, "usbhid-ups" }, + { 0x03f0, 0x1f09, "usbhid-ups" }, + { 0x03f0, 0x1f0a, "usbhid-ups" }, + { 0x03f0, 0x1fe0, "usbhid-ups" }, + { 0x03f0, 0x1fe1, "usbhid-ups" }, + { 0x0463, 0x0001, "usbhid-ups" }, + { 0x0463, 0xffff, "usbhid-ups" }, + { 0x047c, 0xffff, "usbhid-ups" }, + { 0x050d, 0x0375, "usbhid-ups" }, + { 0x050d, 0x0551, "usbhid-ups" }, + { 0x050d, 0x0750, "usbhid-ups" }, + { 0x050d, 0x0751, "usbhid-ups" }, + { 0x050d, 0x0900, "usbhid-ups" }, + { 0x050d, 0x0910, "usbhid-ups" }, + { 0x050d, 0x0912, "usbhid-ups" }, + { 0x050d, 0x0980, "usbhid-ups" }, + { 0x050d, 0x1100, "usbhid-ups" }, + { 0x051d, 0x0002, "usbhid-ups" }, + { 0x051d, 0x0003, "usbhid-ups" }, + { 0x0592, 0x0002, "bcmxcp_usb" }, + { 0x0592, 0x0004, "usbhid-ups" }, + { 0x05b8, 0x0000, "blazer_usb" }, + { 0x0665, 0x5161, "blazer_usb" }, + { 0x06da, 0x0002, "bcmxcp_usb" }, + { 0x06da, 0x0003, "blazer_usb" }, + { 0x06da, 0xffff, "usbhid-ups" }, + { 0x075d, 0x0300, "usbhid-ups" }, + { 0x0764, 0x0005, "usbhid-ups" }, + { 0x0764, 0x0501, "usbhid-ups" }, + { 0x0764, 0x0601, "usbhid-ups" }, + { 0x0925, 0x1234, "richcomm_usb" }, + { 0x09ae, 0x0001, "tripplite_usb" }, + { 0x09ae, 0x1003, "usbhid-ups" }, + { 0x09ae, 0x1007, "usbhid-ups" }, + { 0x09ae, 0x1008, "usbhid-ups" }, + { 0x09ae, 0x1009, "usbhid-ups" }, + { 0x09ae, 0x1010, "usbhid-ups" }, + { 0x09ae, 0x2005, "usbhid-ups" }, + { 0x09ae, 0x2007, "usbhid-ups" }, + { 0x09ae, 0x2008, "usbhid-ups" }, + { 0x09ae, 0x2009, "usbhid-ups" }, + { 0x09ae, 0x2010, "usbhid-ups" }, + { 0x09ae, 0x2011, "usbhid-ups" }, + { 0x09ae, 0x2012, "usbhid-ups" }, + { 0x09ae, 0x2013, "usbhid-ups" }, + { 0x09ae, 0x2014, "usbhid-ups" }, + { 0x09ae, 0x3008, "usbhid-ups" }, + { 0x09ae, 0x3009, "usbhid-ups" }, + { 0x09ae, 0x3010, "usbhid-ups" }, + { 0x09ae, 0x3011, "usbhid-ups" }, + { 0x09ae, 0x3012, "usbhid-ups" }, + { 0x09ae, 0x3013, "usbhid-ups" }, + { 0x09ae, 0x3014, "usbhid-ups" }, + { 0x09ae, 0x3015, "usbhid-ups" }, + { 0x09ae, 0x4001, "usbhid-ups" }, + { 0x09ae, 0x4002, "usbhid-ups" }, + { 0x09ae, 0x4003, "usbhid-ups" }, + { 0x09ae, 0x4004, "usbhid-ups" }, + { 0x09ae, 0x4005, "usbhid-ups" }, + { 0x09ae, 0x4006, "usbhid-ups" }, + { 0x09ae, 0x4007, "usbhid-ups" }, + { 0x09ae, 0x4008, "usbhid-ups" }, + { 0x0d9f, 0x00a2, "usbhid-ups" }, + { 0x0d9f, 0x00a3, "usbhid-ups" }, + { 0x0d9f, 0x00a4, "usbhid-ups" }, + { 0x0d9f, 0x00a5, "usbhid-ups" }, + { 0x0d9f, 0x00a6, "usbhid-ups" }, + { 0x0f03, 0x0001, "blazer_usb" }, + { 0x10af, 0x0001, "usbhid-ups" }, + { 0x14f0, 0x00c9, "blazer_usb" }, + /* Terminating entry */ + { -1, -1, NULL } +}; +#endif /* DEVSCAN_USB_H */ + diff --git a/tools/nut-scanner/scan_avahi.c b/tools/nut-scanner/scan_avahi.c new file mode 100644 index 0000000..6c4a74e --- /dev/null +++ b/tools/nut-scanner/scan_avahi.c @@ -0,0 +1,338 @@ +/* scan_avahi.c: detect NUT avahi services + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#include "common.h" + +#ifdef HAVE_AVAHI_CLIENT_CLIENT_H +#include "nut-scan.h" + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +static AvahiSimplePoll *simple_poll = NULL; +static nutscan_device_t * dev_ret = NULL; +static long avahi_usec_timeout = 0; + +static void update_device(const char * host_name,const char *ip, uint16_t port,char * text, int proto) +{ + nutscan_device_t * dev = NULL; + + char * t = NULL; + char * t_saveptr = NULL; + char * phrase = NULL; + char * phrase_saveptr = NULL; + char * word = NULL; + char * value = NULL; + char * device = NULL; + char * device_saveptr = NULL; + int device_found = 0; + char buf[6]; + int buf_size; + + if( text == NULL ) { + return; + } + + t = strdup(text); + phrase = strtok_r(t,"\"",&t_saveptr); + while(phrase != NULL ) { + word = strtok_r(phrase,"=",&phrase_saveptr); + if( word == NULL ) { + phrase = strtok_r(NULL,"\"",&t_saveptr); + continue; + } + value = strtok_r(NULL,"=",&phrase_saveptr); + if( value == NULL ) { + phrase = strtok_r(NULL,"\"",&t_saveptr); + continue; + } + + if( strcmp(word,"device_list") != 0 ) { + phrase = strtok_r(NULL,"\"",&t_saveptr); + continue; + } + + device = strtok_r(value,";",&device_saveptr); + while( device != NULL ) { + device_found = 1; + dev = nutscan_new_device(); + dev->type = TYPE_NUT; + dev->driver = strdup("nutclient"); + if( proto == AVAHI_PROTO_INET) { + nutscan_add_option_to_device(dev,"desc","IPv4"); + } + if( proto == AVAHI_PROTO_INET6 ) { + nutscan_add_option_to_device(dev,"desc","IPv6"); + } + + if( port != PORT) { + /* +5+1+1+1 is for : + - port number (max 65535 so 5 characters), + - '@' and ':' characters + - terminating 0 */ + buf_size = strlen(device)+strlen(host_name)+ + 5+1+1+1; + dev->port=malloc(buf_size); + if(dev->port) { + snprintf(dev->port,buf_size,"%s@%s:%u", + device,host_name,port); + } + } + else { + /*+1+1 is for '@' character and terminating 0 */ + buf_size = strlen(device)+strlen(host_name)+1+1; + dev->port=malloc(buf_size); + if(dev->port) { + snprintf(dev->port,buf_size,"%s@%s", + device,host_name); + } + } + if( dev->port ) { + dev_ret = nutscan_add_device_to_device(dev_ret,dev); + } + else { + nutscan_free_device(dev); + } + device = strtok_r(NULL,";",&device_saveptr); + }; + + phrase = strtok_r(NULL,"\"",&t_saveptr); + }; + free(t); + + /* If no device published in avahi data, try to get the device by + connecting directly to upsd */ + if( !device_found) { + snprintf(buf,sizeof(buf),"%u",port); + dev = nutscan_scan_nut(ip,ip,buf,avahi_usec_timeout); + if(dev) { + dev_ret = nutscan_add_device_to_device(dev_ret,dev); + } + /* add an upsd entry without associated device */ + else { + dev = nutscan_new_device(); + dev->type = TYPE_NUT; + dev->driver = strdup("nutclient"); + if( proto == AVAHI_PROTO_INET) { + nutscan_add_option_to_device(dev,"desc","IPv4"); + } + if( proto == AVAHI_PROTO_INET6 ) { + nutscan_add_option_to_device(dev,"desc","IPv6"); + } + if( port != PORT) { + /*+1+1 is for ':' character and terminating 0 */ + /*buf is the string containing the port number*/ + buf_size = strlen(host_name)+strlen(buf)+1+1; + dev->port=malloc(buf_size); + if(dev->port) { + snprintf(dev->port,buf_size,"%s:%s", + host_name,buf); + } + } + else { + dev->port=strdup(host_name); + } + if( dev->port ) { + dev_ret = nutscan_add_device_to_device(dev_ret,dev); + } + else { + nutscan_free_device(dev); + } + } + } +} + +static void resolve_callback( + AvahiServiceResolver *r, + AVAHI_GCC_UNUSED AvahiIfIndex interface, + AVAHI_GCC_UNUSED AvahiProtocol protocol, + AvahiResolverEvent event, + const char *name, + const char *type, + const char *domain, + const char *host_name, + const AvahiAddress *address, + uint16_t port, + AvahiStringList *txt, + AvahiLookupResultFlags flags, + AVAHI_GCC_UNUSED void* userdata) { + + assert(r); + + /* Called whenever a service has been resolved successfully or timed out */ + + switch (event) { + case AVAHI_RESOLVER_FAILURE: + fprintf(stderr, "(Resolver) Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(avahi_service_resolver_get_client(r)))); + break; + + case AVAHI_RESOLVER_FOUND: { + char a[AVAHI_ADDRESS_STR_MAX], *t; + +/* fprintf(stderr, "Service '%s' of type '%s' in domain '%s':\n", name, type, domain); */ + + avahi_address_snprint(a, sizeof(a), address); + t = avahi_string_list_to_string(txt); +/* + fprintf(stderr, + "\t%s:%u (%s)\n" + "\tTXT=%s\n" + "\tcookie is %u\n" + "\tis_local: %i\n" + "\tour_own: %i\n" + "\twide_area: %i\n" + "\tmulticast: %i\n" + "\tcached: %i\n", + host_name, port, a, + t, + avahi_string_list_get_service_cookie(txt), + !!(flags & AVAHI_LOOKUP_RESULT_LOCAL), + !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN), + !!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA), + !!(flags & AVAHI_LOOKUP_RESULT_MULTICAST), + !!(flags & AVAHI_LOOKUP_RESULT_CACHED)); +*/ + update_device(host_name,a,port,t,address->proto); + avahi_free(t); + } + } + + avahi_service_resolver_free(r); +} + +static void browse_callback( + AvahiServiceBrowser *b, + AvahiIfIndex interface, + AvahiProtocol protocol, + AvahiBrowserEvent event, + const char *name, + const char *type, + const char *domain, + AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, + void* userdata) { + + AvahiClient *c = userdata; + assert(b); + + /* Called whenever a new services becomes available on the LAN or is removed from the LAN */ + + switch (event) { + case AVAHI_BROWSER_FAILURE: + + fprintf(stderr, "(Browser) %s\n", avahi_strerror(avahi_client_errno(avahi_service_browser_get_client(b)))); + avahi_simple_poll_quit(simple_poll); + return; + + case AVAHI_BROWSER_NEW: +/* fprintf(stderr, "(Browser) NEW: service '%s' of type '%s' in domain '%s'\n", name, type, domain); */ + + /* We ignore the returned resolver object. In the callback + function we free it. If the server is terminated before + the callback function is called the server will free + the resolver for us. */ + + if (!(avahi_service_resolver_new(c, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolve_callback, c))) + fprintf(stderr, "Failed to resolve service '%s': %s\n", name, avahi_strerror(avahi_client_errno(c))); + + break; + + case AVAHI_BROWSER_REMOVE: + fprintf(stderr, "(Browser) REMOVE: service '%s' of type '%s' in domain '%s'\n", name, type, domain); + break; + + case AVAHI_BROWSER_ALL_FOR_NOW: + avahi_simple_poll_quit(simple_poll); + case AVAHI_BROWSER_CACHE_EXHAUSTED: +/* fprintf(stderr, "(Browser) %s\n", event == AVAHI_BROWSER_CACHE_EXHAUSTED ? "CACHE_EXHAUSTED" : "ALL_FOR_NOW"); */ + break; + } +} + +static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) { + assert(c); + + /* Called whenever the client or server state changes */ + + if (state == AVAHI_CLIENT_FAILURE) { + fprintf(stderr, "Server connection failure: %s\n", avahi_strerror(avahi_client_errno(c))); + avahi_simple_poll_quit(simple_poll); + } +} + +nutscan_device_t * nutscan_scan_avahi(long usec_timeout) +{ + /* Example service publication + * $ avahi-publish -s nut _upsd._tcp 3493 txtvers=1 protovers=1.0.0 device_list="dev1;dev2" + */ + AvahiClient *client = NULL; + AvahiServiceBrowser *sb = NULL; + int error; + int ret = 1; + + avahi_usec_timeout = usec_timeout; + + /* Allocate main loop object */ + if (!(simple_poll = avahi_simple_poll_new())) { + fprintf(stderr, "Failed to create simple poll object.\n"); + goto fail; + } + + /* Allocate a new client */ + client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, NULL, &error); + + /* Check wether creating the client object succeeded */ + if (!client) { + fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error)); + goto fail; + } + + /* Create the service browser */ + if (!(sb = avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_upsd._tcp", NULL, 0, browse_callback, client))) { + fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client))); + goto fail; + } + + /* Run the main loop */ + avahi_simple_poll_loop(simple_poll); + + ret = 0; + +fail: + + /* Cleanup things */ + if (sb) + avahi_service_browser_free(sb); + + if (client) + avahi_client_free(client); + + if (simple_poll) + avahi_simple_poll_free(simple_poll); + + return dev_ret; +} +#endif /* HAVE_AVAHI_CLIENT_CLIENT_H */ diff --git a/tools/nut-scanner/scan_ipmi.c b/tools/nut-scanner/scan_ipmi.c new file mode 100644 index 0000000..145e281 --- /dev/null +++ b/tools/nut-scanner/scan_ipmi.c @@ -0,0 +1,29 @@ +/* scan_ipmi.c: detect NUT supported Power Supply Units + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ +#include "common.h" + +#ifdef HAVE_FREEIPMI_FREEIPMI_H +#include "nut-scan.h" + +/* TODO */ +nutscan_device_t * nutscan_scan_ipmi() +{ + return NULL; +} +#endif /* HAVE_FREEIPMI_FREEIPMI_H */ diff --git a/tools/nut-scanner/scan_nut.c b/tools/nut-scanner/scan_nut.c new file mode 100644 index 0000000..bed4d1c --- /dev/null +++ b/tools/nut-scanner/scan_nut.c @@ -0,0 +1,194 @@ +/* scan_nut.c: detect remote NUT services + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "common.h" +#include "upsclient.h" +#include "nut-scan.h" +#ifdef HAVE_PTHREAD +#include +#endif + + +static nutscan_device_t * dev_ret = NULL; +#ifdef HAVE_PTHREAD +static pthread_mutex_t dev_mutex; +#endif + +struct scan_nut_arg { + char * hostname; + long timeout; +}; + +/* FIXME: SSL support */ +static void * list_nut_devices(void * arg) +{ + struct scan_nut_arg * nut_arg = (struct scan_nut_arg*)arg; + char *target_hostname = nut_arg->hostname; + struct timeval tv; + int port; + unsigned int numq, numa; + const char *query[4]; + char **answer; + char *hostname = NULL; + UPSCONN_t *ups = malloc(sizeof(*ups)); + nutscan_device_t * dev = NULL; + int buf_size; + + tv.tv_sec = nut_arg->timeout / (1000*1000); + tv.tv_usec = nut_arg->timeout % (1000*1000); + + query[0] = "UPS"; + numq = 1; + + if (upscli_splitaddr(target_hostname, &hostname, &port) != 0) { + free(target_hostname); + free(nut_arg); + return NULL; + } + if (upscli_tryconnect(ups, hostname, port,UPSCLI_CONN_TRYSSL,&tv) < 0) { + free(target_hostname); + free(nut_arg); + return NULL; + } + + if(upscli_list_start(ups, numq, query) < 0) { + free(target_hostname); + free(nut_arg); + return NULL; + } + + while (upscli_list_next(ups, numq, query, &numa, &answer) == 1) { + /* UPS */ + if (numa < 3) { + free(target_hostname); + free(nut_arg); + return NULL; + } + /* FIXME: check for duplication by getting driver.port and device.serial + * for comparison with other busses results */ + /* FIXME: + * - also print answer[2] if != "Unavailable"? + * - for upsmon.conf or ups.conf (using dummy-ups)? */ + if (numa >= 3) { + dev = nutscan_new_device(); + dev->type = TYPE_NUT; + dev->driver = strdup("nutclient"); + /* +1+1 is for '@' character and terminnating 0 */ + buf_size = strlen(answer[1])+strlen(hostname)+1+1; + dev->port = malloc(buf_size); + if( dev->port ) { + snprintf(dev->port,buf_size,"%s@%s",answer[1], + hostname); +#ifdef HAVE_PTHREAD + pthread_mutex_lock(&dev_mutex); +#endif + dev_ret = nutscan_add_device_to_device(dev_ret,dev); +#ifdef HAVE_PTHREAD + pthread_mutex_unlock(&dev_mutex); +#endif + } + + } + } + + free(target_hostname); + free(nut_arg); + return NULL; +} + +nutscan_device_t * nutscan_scan_nut(const char* startIP, const char* stopIP, const char* port,long usec_timeout) +{ + nutscan_ip_iter_t ip; + char * ip_str = NULL; + char * ip_dest = NULL; + char buf[SMALLBUF]; + struct sigaction oldact; + int change_action_handler = 0; + int i; + struct scan_nut_arg *nut_arg; + +#ifdef HAVE_PTHREAD + pthread_t thread; + pthread_t * thread_array = NULL; + int thread_count = 0; + + pthread_mutex_init(&dev_mutex,NULL); +#endif + + /* Ignore SIGPIPE if the caller hasn't set a handler for it yet */ + if( sigaction(SIGPIPE, NULL, &oldact) == 0 ) { + if( oldact.sa_handler == SIG_DFL ) { + change_action_handler = 1; + signal(SIGPIPE,SIG_IGN); + } + } + + ip_str = nutscan_ip_iter_init(&ip,startIP,stopIP); + + while( ip_str != NULL ) + { + if( port ) { + if( ip.type == IPv4 ) { + snprintf(buf,sizeof(buf),"%s:%s",ip_str,port); + } + else { + snprintf(buf,sizeof(buf),"[%s]:%s",ip_str,port); + } + + ip_dest = strdup(buf); + } + else { + ip_dest = strdup(ip_str); + } + + if((nut_arg = malloc(sizeof(struct scan_nut_arg))) == NULL ) { + free(ip_dest); + break; + } + + nut_arg->timeout = usec_timeout; + nut_arg->hostname = ip_dest; +#ifdef HAVE_PTHREAD + if (pthread_create(&thread,NULL,list_nut_devices,(void*)nut_arg)==0){ + thread_count++; + thread_array = realloc(thread_array, + thread_count*sizeof(pthread_t)); + thread_array[thread_count-1] = thread; + } +#else + list_nut_devices(nut_arg); +#endif + free(ip_str); + ip_str = nutscan_ip_iter_inc(&ip); + } + +#ifdef HAVE_PTHREAD + for ( i=0; i < thread_count ; i++) { + pthread_join(thread_array[i],NULL); + } + pthread_mutex_destroy(&dev_mutex); + free(thread_array); +#endif + + if(change_action_handler) { + signal(SIGPIPE,SIG_DFL); + } + + return dev_ret; +} diff --git a/tools/nut-scanner/scan_snmp.c b/tools/nut-scanner/scan_snmp.c new file mode 100644 index 0000000..e6ffc54 --- /dev/null +++ b/tools/nut-scanner/scan_snmp.c @@ -0,0 +1,520 @@ +/* scan_snmp.c: detect NUT supported SNMP devices + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "common.h" + +#ifdef HAVE_NET_SNMP_NET_SNMP_CONFIG_H + +#include "nut-scan.h" +#include +#include +#include +#include +#include + +/* workaround for buggy Net-SNMP config + * from drivers/snmp-ups.h */ +#ifdef PACKAGE_BUGREPORT +#undef PACKAGE_BUGREPORT +#endif + +#ifdef PACKAGE_NAME +#undef PACKAGE_NAME +#endif + +#ifdef PACKAGE_VERSION +#undef PACKAGE_VERSION +#endif + +#ifdef PACKAGE_STRING +#undef PACKAGE_STRING +#endif + +#ifdef PACKAGE_TARNAME +#undef PACKAGE_TARNAME +#endif + +#include +#include +#ifdef HAVE_PTHREAD +#include +#endif +#include "nutscan-snmp.h" + + +#define SysOID ".1.3.6.1.2.1.1.2.0" + +static nutscan_device_t * dev_ret = NULL; +#ifdef HAVE_PTHREAD +static pthread_mutex_t dev_mutex; +static pthread_t * thread_array = NULL; +static int thread_count = 0; +#endif +long g_usec_timeout ; + +static void scan_snmp_add_device(nutscan_snmp_t * sec, struct snmp_pdu *response,char * mib) +{ + nutscan_device_t * dev = NULL; + struct snmp_session * session; + char * buf; + + session = snmp_sess_session(sec->handle); + /* SNMP device found */ + dev = nutscan_new_device(); + dev->type = TYPE_SNMP; + dev->driver = strdup("snmp-ups"); + dev->port = strdup(session->peername); + buf = malloc( response->variables->val_len + 1 ); + if( buf ) { + memcpy(buf,response->variables->val.string, + response->variables->val_len); + buf[response->variables->val_len]=0; + nutscan_add_option_to_device(dev,"desc",buf); + free(buf); + } + nutscan_add_option_to_device(dev,"mibs",mib); + /* SNMP v3 */ + if( session->community == NULL || session->community[0] == 0) { + if( sec->secLevel ) { + nutscan_add_option_to_device(dev,"secLevel", + sec->secLevel); + } + if( sec->secName ) { + nutscan_add_option_to_device(dev,"secName", + sec->secName); + } + if( sec->authPassword ) { + nutscan_add_option_to_device(dev,"authPassword", + sec->authPassword); + } + if( sec->privPassword ) { + nutscan_add_option_to_device(dev,"privPassword", + sec->privPassword); + } + if( sec->authProtocol ) { + nutscan_add_option_to_device(dev,"authProtocol", + sec->authProtocol); + } + if( sec->privProtocol ) { + nutscan_add_option_to_device(dev,"privProtocol", + sec->privProtocol); + } + } + else { + buf = malloc( session->community_len + 1 ); + if( buf ) { + memcpy(buf,session->community, + session->community_len); + buf[session->community_len]=0; + nutscan_add_option_to_device(dev,"community",buf); + free(buf); + } + } + +#ifdef HAVE_PTHREAD + pthread_mutex_lock(&dev_mutex); +#endif + dev_ret = nutscan_add_device_to_device(dev_ret,dev); +#ifdef HAVE_PTHREAD + pthread_mutex_unlock(&dev_mutex); +#endif + +} + +static struct snmp_pdu * scan_snmp_get_manufacturer(char* oid_str,void* handle) +{ + size_t name_len; + oid name[MAX_OID_LEN]; + struct snmp_pdu *pdu, *response = NULL; + int status; + int index = 0; + + /* create and send request. */ + name_len = MAX_OID_LEN; + if (!snmp_parse_oid(oid_str, name, &name_len)) { + index++; + return NULL; + } + + pdu = snmp_pdu_create(SNMP_MSG_GET); + + if (pdu == NULL) { + index++; + return NULL; + } + + snmp_add_null_var(pdu, name, name_len); + + status = snmp_sess_synch_response(handle,pdu, &response); + if( response == NULL ) { + index++; + return NULL; + } + + if(status!=STAT_SUCCESS||response->errstat!=SNMP_ERR_NOERROR|| + response->variables == NULL || + response->variables->name == NULL || + snmp_oid_compare(response->variables->name, + response->variables->name_length, + name, name_len) != 0 || + response->variables->val.string == NULL ) { + snmp_free_pdu(response); + index++; + return NULL; + } + + return response; +} + +static void try_all_oid(void * arg) +{ + struct snmp_pdu *response = NULL; + int index = 0; + nutscan_snmp_t * sec = (nutscan_snmp_t *)arg; + + while(snmp_device_table[index].oid != NULL) { + + response = scan_snmp_get_manufacturer(snmp_device_table[index].oid,sec->handle); + if( response == NULL ) { + index++; + continue; + } + + scan_snmp_add_device(sec,response,snmp_device_table[index].mib); + + snmp_free_pdu(response); + response = NULL; + + index++; + } +} + +static int init_session(struct snmp_session * snmp_sess, nutscan_snmp_t * sec) +{ + snmp_sess_init(snmp_sess); + + snmp_sess->peername = sec->peername; + + if( sec->community != NULL || sec->secLevel == NULL ) { + snmp_sess->version = SNMP_VERSION_1; + if( sec->community != NULL ) { + snmp_sess->community = (unsigned char *)sec->community; + snmp_sess->community_len = strlen(sec->community); + } + else { + snmp_sess->community = (unsigned char *)"public"; + snmp_sess->community_len = strlen("public"); + } + } + else { /* SNMP v3 */ + snmp_sess->version = SNMP_VERSION_3; + + /* Security level */ + if (strcmp(sec->secLevel, "noAuthNoPriv") == 0) + snmp_sess->securityLevel = SNMP_SEC_LEVEL_NOAUTH; + else if (strcmp(sec->secLevel, "authNoPriv") == 0) + snmp_sess->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV; + else if (strcmp(sec->secLevel, "authPriv") == 0) + snmp_sess->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; + else { + fprintf(stderr,"Bad SNMPv3 securityLevel: %s\n", + sec->secLevel); + return 0; + } + + /* Security name */ + if( sec->secName == NULL ) { + fprintf(stderr,"securityName is required for SNMPv3\n"); + return 0; + } + snmp_sess->securityName = strdup(sec->secName); + snmp_sess->securityNameLen = strlen(snmp_sess->securityName); + + /* Everything is ready for NOAUTH */ + if( snmp_sess->securityLevel == SNMP_SEC_LEVEL_NOAUTH ) { + return 1; + } + + /* Process mandatory fields, based on the security level */ + switch (snmp_sess->securityLevel) { + case SNMP_SEC_LEVEL_AUTHNOPRIV: + if (sec->authPassword == NULL) { + fprintf(stderr, + "authPassword is required for SNMPv3 in %s mode\n", + sec->secLevel); + return 0; + } + break; + case SNMP_SEC_LEVEL_AUTHPRIV: + if ((sec->authPassword == NULL) || + (sec->privPassword == NULL)) { + fprintf(stderr, + "authPassword and privPassword are required for SNMPv3 in %s mode\n", + sec->secLevel); + return 0; + } + break; + default: + /* nothing else needed */ + break; + } + + /* Process authentication protocol and key */ + snmp_sess->securityAuthKeyLen = USM_AUTH_KU_LEN; + + /* default to MD5 */ + snmp_sess->securityAuthProto = usmHMACMD5AuthProtocol; + snmp_sess->securityAuthProtoLen =sizeof(usmHMACMD5AuthProtocol)/ + sizeof(oid); + + if( sec->authProtocol ) { + if (strcmp(sec->authProtocol, "SHA") == 0) { + snmp_sess->securityAuthProto = + usmHMACSHA1AuthProtocol; + snmp_sess->securityAuthProtoLen = + sizeof(usmHMACSHA1AuthProtocol)/ + sizeof(oid); + } + else { + if (strcmp(sec->authProtocol, "MD5") != 0) { + fprintf(stderr, + "Bad SNMPv3 authProtocol: %s", + sec->authProtocol); + return 0; + } + } + } + + /* set the authentication key to a MD5/SHA1 hashed version of + * our passphrase (must be at least 8 characters long) */ + if (generate_Ku(snmp_sess->securityAuthProto, + snmp_sess->securityAuthProtoLen, + (u_char *) sec->authPassword, + strlen(sec->authPassword), + snmp_sess->securityAuthKey, + &snmp_sess->securityAuthKeyLen) + != SNMPERR_SUCCESS) { + fprintf(stderr, + "Error generating Ku from authentication pass phrase\n"); + return 0; + } + + /* Everything is ready for AUTHNOPRIV */ + if( snmp_sess->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV ) { + return 1; + } + + /* default to DES */ + snmp_sess->securityPrivProto=usmDESPrivProtocol; + snmp_sess->securityPrivProtoLen = + sizeof(usmDESPrivProtocol)/sizeof(oid); + + if( sec->privProtocol ) { + if (strcmp(sec->privProtocol, "AES") == 0) { + snmp_sess->securityPrivProto=usmAESPrivProtocol; + snmp_sess->securityPrivProtoLen = + sizeof(usmAESPrivProtocol)/sizeof(oid); + } + else { + if (strcmp(sec->privProtocol, "DES") != 0) { + fprintf(stderr, + "Bad SNMPv3 authProtocol: %s\n" + ,sec->authProtocol); + return 0; + } + } + } + + /* set the private key to a MD5/SHA hashed version of + * our passphrase (must be at least 8 characters long) */ + snmp_sess->securityPrivKeyLen = USM_PRIV_KU_LEN; + if (generate_Ku(snmp_sess->securityAuthProto, + snmp_sess->securityAuthProtoLen, + (u_char *) sec->privPassword, + strlen(sec->privPassword), + snmp_sess->securityPrivKey, + &snmp_sess->securityPrivKeyLen) + != SNMPERR_SUCCESS) { + fprintf(stderr, + "Error generating Ku from private pass phrase\n"); + return 0; + } + + } + + return 1; +} + +static void * try_SysOID(void * arg) +{ + struct snmp_session snmp_sess; + void * handle; + struct snmp_pdu *pdu, *response = NULL; + oid name[MAX_OID_LEN]; + size_t name_len = MAX_OID_LEN; + nutscan_snmp_t * sec = (nutscan_snmp_t *)arg; + int index = 0; + int sysoid_found = 0; + + /* Initialize session */ + if( !init_session(&snmp_sess,sec) ) { + goto try_SysOID_free; + } + + snmp_sess.retries = 0; + snmp_sess.timeout = g_usec_timeout; + + /* Open the session */ + handle = snmp_sess_open(&snmp_sess); /* establish the session */ + if (handle == NULL) { + fprintf(stderr,"Failed to open SNMP session for %s.\n", + sec->peername); + goto try_SysOID_free; + } + + /* create and send request. */ + if (!snmp_parse_oid(SysOID, name, &name_len)) { + fprintf(stderr,"SNMP errors: %s\n", + snmp_api_errstring(snmp_errno)); + snmp_sess_close(handle); + goto try_SysOID_free; + } + + pdu = snmp_pdu_create(SNMP_MSG_GET); + + if (pdu == NULL) { + fprintf(stderr,"Not enough memory\n"); + snmp_sess_close(handle); + goto try_SysOID_free; + } + + snmp_add_null_var(pdu, name, name_len); + + snmp_sess_synch_response(handle, + pdu, &response); + + if (response) { + sec->handle = handle; + + /* SNMP device found */ + /* SysOID is supposed to give the required MIB. */ + + /* Check if the received OID match with a known sysOID */ + if(response->variables != NULL && + response->variables->val.objid != NULL){ + while(snmp_device_table[index].oid != NULL) { + if(snmp_device_table[index].sysoid == NULL ) { + index++; + continue; + } + name_len = MAX_OID_LEN; + if (!snmp_parse_oid( + snmp_device_table[index].sysoid, + name, &name_len)) { + index++; + continue; + } + + if ( snmp_oid_compare( + response->variables->val.objid, + response->variables->val_len/sizeof(oid), + name, name_len) == 0 ) { + /* we have found a relevent sysoid */ + snmp_free_pdu(response); + response = scan_snmp_get_manufacturer( + snmp_device_table[index].oid, + handle); + scan_snmp_add_device(sec,response, + snmp_device_table[index].mib); + sysoid_found = 1; + } + index++; + } + } + + /* try a list of known OID */ + if( !sysoid_found ) { + try_all_oid(sec); + } + + snmp_free_pdu(response); + response = NULL; + } + + snmp_sess_close(handle); + +try_SysOID_free: + if( sec->peername ) { + free(sec->peername); + } + free(sec); + + return NULL; +} + +nutscan_device_t * nutscan_scan_snmp(const char * start_ip, const char * stop_ip,long usec_timeout, nutscan_snmp_t * sec) +{ + int i; + nutscan_snmp_t * tmp_sec; + nutscan_ip_iter_t ip; + char * ip_str = NULL; +#ifdef HAVE_PTHREAD + pthread_t thread; + + pthread_mutex_init(&dev_mutex,NULL); +#endif + + g_usec_timeout = usec_timeout; + + /* Initialize the SNMP library */ + init_snmp("nut-scanner"); + + ip_str = nutscan_ip_iter_init(&ip, start_ip, stop_ip); + + while(ip_str != NULL) { + tmp_sec = malloc(sizeof(nutscan_snmp_t)); + memcpy(tmp_sec, sec, sizeof(nutscan_snmp_t)); + tmp_sec->peername = ip_str; + +#ifdef HAVE_PTHREAD + if (pthread_create(&thread,NULL,try_SysOID,(void*)tmp_sec)==0){ + thread_count++; + thread_array = realloc(thread_array, + thread_count*sizeof(pthread_t)); + thread_array[thread_count-1] = thread; + } +#else + try_SysOID((void *)tmp_sec); +#endif + ip_str = nutscan_ip_iter_inc(&ip); + }; + +#ifdef HAVE_PTHREAD + for ( i=0; i < thread_count ; i++) { + pthread_join(thread_array[i],NULL); + } + pthread_mutex_destroy(&dev_mutex); + free(thread_array); +#endif + + return dev_ret; +} +#endif /* HAVE_NET_SNMP_NET_SNMP_CONFIG_H */ + + diff --git a/tools/nut-scanner/scan_usb.c b/tools/nut-scanner/scan_usb.c new file mode 100644 index 0000000..8ce8759 --- /dev/null +++ b/tools/nut-scanner/scan_usb.c @@ -0,0 +1,168 @@ +/* scan_usb.c: detect NUT supported USB devices + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "common.h" +#ifdef HAVE_USB_H +#include "upsclient.h" +#include "nutscan-usb.h" +#include +#include +#include "nutscan-device.h" + +static char* is_usb_device_supported(usb_device_id_t *usb_device_id_list, + int dev_VendorID, int dev_ProductID) +{ + usb_device_id_t *usbdev; + + for (usbdev=usb_device_id_list; usbdev->driver_name != NULL; usbdev++) { + if ( (usbdev->vendorID == dev_VendorID) + && (usbdev->productID == dev_ProductID) ) { + + return usbdev->driver_name; + } + } + + return NULL; +} + +/* return NULL if error */ +nutscan_device_t * nutscan_scan_usb() +{ + int ret; + char string[256]; + char *driver_name = NULL; + char *serialnumber = NULL; + char *device_name = NULL; + char *vendor_name = NULL; + struct usb_device *dev; + struct usb_bus *bus; + usb_dev_handle *udev; + + nutscan_device_t * nut_dev = NULL; + nutscan_device_t * current_nut_dev = NULL; + + /* libusb base init */ + usb_init(); + usb_find_busses(); + usb_find_devices(); + + for (bus = usb_busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if ((driver_name = + is_usb_device_supported(usb_device_table, + dev->descriptor.idVendor, + dev->descriptor.idProduct)) != NULL) { + + /* open the device */ + udev = usb_open(dev); + if (!udev) { + fprintf(stderr,"Failed to open device, \ + skipping. (%s)\n", + usb_strerror()); + continue; + } + + /* get serial number */ + if (dev->descriptor.iSerialNumber) { + ret = usb_get_string_simple(udev, + dev->descriptor.iSerialNumber, + string, sizeof(string)); + if (ret > 0) { + serialnumber = strdup(string); + } + } + /* get product name */ + if (dev->descriptor.iProduct) { + ret = usb_get_string_simple(udev, + dev->descriptor.iProduct, + string, sizeof(string)); + if (ret > 0) { + device_name = strdup(string); + } + } + + /* get vendor name */ + if (dev->descriptor.iManufacturer) { + ret = usb_get_string_simple(udev, + dev->descriptor.iManufacturer, + string, sizeof(string)); + if (ret > 0) { + vendor_name = strdup(string); + } + } + + nut_dev = nutscan_new_device(); + if(nut_dev == NULL) { + fprintf(stderr,"Memory allocation \ + error\n"); + nutscan_free_device(current_nut_dev); + free(serialnumber); + free(device_name); + free(vendor_name); + return NULL; + } + + nut_dev->type = TYPE_USB; + if(driver_name) { + nut_dev->driver = strdup(driver_name); + } + nut_dev->port = strdup("auto"); + sprintf(string,"%04X",dev->descriptor.idVendor); + nutscan_add_option_to_device(nut_dev,"vendorid", + string); + sprintf(string,"%04X", + dev->descriptor.idProduct); + nutscan_add_option_to_device(nut_dev,"productid", + string); + if(device_name) { + nutscan_add_option_to_device(nut_dev, + "product", + device_name); + free(device_name); + } + if(serialnumber) { + nutscan_add_option_to_device(nut_dev, + "serial", + serialnumber); + free(serialnumber); + } + if(vendor_name) { + nutscan_add_option_to_device(nut_dev, + "vendor", + vendor_name); + free(vendor_name); + } + nutscan_add_option_to_device(nut_dev,"bus", + bus->dirname); + + current_nut_dev = nutscan_add_device_to_device( + current_nut_dev, + nut_dev); + + memset (string, 0, sizeof(string)); + + usb_close(udev); + } + } + } + + return current_nut_dev; +} +#endif /* HAVE_USB_H */ + diff --git a/tools/nut-scanner/scan_xml_http.c b/tools/nut-scanner/scan_xml_http.c new file mode 100644 index 0000000..7c68a65 --- /dev/null +++ b/tools/nut-scanner/scan_xml_http.c @@ -0,0 +1,160 @@ +/* scan_xml_http.c: detect NUT supported XML HTTP devices + * + * Copyright (C) 2011 - Frederic Bohe + * + * 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 + */ + +#include "common.h" +#ifdef WITH_NEON +#include +#include +#include +#include +#include +#include +#include +#include +#include "nutscan-device.h" + +static int startelm_cb(void *userdata, int parent, const char *nspace, const char *name, const char **atts) { + nutscan_device_t * dev = (nutscan_device_t *)userdata; + char buf[SMALLBUF]; + int i = 0; + while( atts[i] != NULL ) { + if(strcmp(atts[i],"type") == 0) { + snprintf(buf,sizeof(buf),"%s",atts[i+1]); + nutscan_add_option_to_device(dev,"desc",buf); + return 0; + } + i=i+2; + } + return 0; +} + +nutscan_device_t * nutscan_scan_xml_http(long usec_timeout) +{ + char *scanMsg = ""; + int port = 4679; + int peerSocket; + int sockopt_on = 1; + struct sockaddr_in sockAddress; + socklen_t sockAddressLength = sizeof(sockAddress); + memset(&sockAddress, 0, sizeof(sockAddress)); + fd_set fds; + struct timeval timeout; + int ret; + char buf[SMALLBUF]; + char string[SMALLBUF]; + ssize_t recv_size; + + nutscan_device_t * nut_dev = NULL; + nutscan_device_t * current_nut_dev = NULL; + + + if((peerSocket = socket(AF_INET, SOCK_DGRAM, 0)) != -1) + { + /* Initialize socket */ + sockAddress.sin_family = AF_INET; + sockAddress.sin_addr.s_addr = INADDR_BROADCAST; + sockAddress.sin_port = htons(port); + setsockopt(peerSocket, SOL_SOCKET, SO_BROADCAST, &sockopt_on, + sizeof(sockopt_on)); + + /* Send scan request */ + if(sendto(peerSocket, scanMsg, strlen(scanMsg), 0, + (struct sockaddr *)&sockAddress, + sockAddressLength) <= 0) + { + fprintf(stderr,"Error sending Eaton \n"); + } + else + { + FD_ZERO(&fds); + FD_SET(peerSocket,&fds); + + timeout.tv_sec = usec_timeout / 1000000; + timeout.tv_usec = usec_timeout % 1000000; + + while ((ret=select(peerSocket+1,&fds,NULL,NULL, + &timeout) )) { + + timeout.tv_sec = usec_timeout / 1000000; + timeout.tv_usec = usec_timeout % 1000000; + + if( ret == -1 ) { + fprintf(stderr, + "Error waiting on \ + socket: %d\n",errno); + break; + } + + sockAddressLength = sizeof(struct sockaddr_in); + recv_size = recvfrom(peerSocket,buf, + sizeof(buf),0, + (struct sockaddr *)&sockAddress, + &sockAddressLength); + + if(recv_size==-1) { + fprintf(stderr, + "Error reading \ + socket: %d\n",errno); + continue; + } + + + if( inet_ntop(AF_INET, + &(sockAddress.sin_addr), + string,sizeof(buf)) == NULL ) { + fprintf(stderr, + "Error converting IP address \ + : %d\n",errno); + continue; + } + + nut_dev = nutscan_new_device(); + if(nut_dev == NULL) { + fprintf(stderr,"Memory allocation \ + error\n"); + return NULL; + } + + nut_dev->type = TYPE_XML; + /* Try to read device type */ + ne_xml_parser *parser = ne_xml_create(); + ne_xml_push_handler(parser, startelm_cb, NULL, + NULL, nut_dev); + ne_xml_parse(parser, buf, strlen(buf)); + ne_xml_destroy(parser); + + nut_dev->driver = strdup("netxml-ups"); + sprintf(buf,"http://%s",string); + nut_dev->port = strdup(buf); + + current_nut_dev = nutscan_add_device_to_device( + current_nut_dev,nut_dev); + + } + } + } + else + { + fprintf(stderr,"Error creating socket\n"); + } + + + return current_nut_dev; +} +#endif /* WITH_NEON */ diff --git a/tools/nut-snmpinfo.py b/tools/nut-snmpinfo.py new file mode 100755 index 0000000..8489db1 --- /dev/null +++ b/tools/nut-snmpinfo.py @@ -0,0 +1,137 @@ +#!/usr/bin/env python +# Copyright (C) 2011 - Frederic Bohe +# +# 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 + +# This program extracts all SNMP information related to NUT snmp-ups +# drivers. + +import glob +import re + +output_file_name="./nut-scanner/nutscan-snmp.h" +output_file = open(output_file_name,'w') + +#expand #define constant +def expand_define(filename,constant): + ret_line = "" + f = open(filename, 'r') + for line in f: + if constant in line and "#define" in line: + line_without_carriage_return = re.sub("[\n\r]", "", line) + line_with_single_blank = re.sub("[ \t]+", " ", line_without_carriage_return) + define_line = line_with_single_blank.split(" "); + #define_line[0] = "#define" + #define_line[1] = const name + #define_line[2...] = const value (may be other const name) + if constant in define_line[1]: + define_line.pop(0) #remove #define + define_line.pop(0) #remove the constant name + for elem in define_line: + if elem[0] == "\"": + clean_elem = re.sub("\"", "", elem) + ret_line = ret_line + clean_elem + else: + ret_line = ret_line + expand_define(filename,elem); + return ret_line + + +output_file.write( "/* nutscan-snmp\n" ) +output_file.write( " * Copyright (C) 2011 - Frederic Bohe \n" ) +output_file.write( " *\n" ) +output_file.write( " * This program is free software; you can redistribute it and/or modify\n" ) +output_file.write( " * it under the terms of the GNU General Public License as published by\n" ) +output_file.write( " * the Free Software Foundation; either version 2 of the License, or\n" ) +output_file.write( " * (at your option) any later version.\n" ) +output_file.write( " *\n" ) +output_file.write( " * This program is distributed in the hope that it will be useful,\n" ) +output_file.write( " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" ) +output_file.write( " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" ) +output_file.write( " * GNU General Public License for more details.\n" ) +output_file.write( " *\n" ) +output_file.write( " * You should have received a copy of the GNU General Public License\n" ) +output_file.write( " * along with this program; if not, write to the Free Software\n" ) +output_file.write( " * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" ) +output_file.write( " */\n" ) +output_file.write( "\n" ) +output_file.write( "#ifndef DEVSCAN_SNMP_H\n" ) +output_file.write( "#define DEVSCAN_SNMP_H\n" ) +output_file.write( "\n" ) +output_file.write( "typedef struct {\n" ) +output_file.write( " char * oid;\n" ) +output_file.write( " char * mib;\n" ) +output_file.write( " char * sysoid;\n" ) +output_file.write( "} snmp_device_id_t;\n" ) +output_file.write( "\n" ) +output_file.write( "/* SNMP IDs device table */\n" ) +output_file.write( "static snmp_device_id_t snmp_device_table[] = {\n" ) + +for filename in glob.glob('../drivers/*-mib.c'): + list_of_line = file(filename,'r').read().split(';') + for line in list_of_line: + if "mib2nut_info_t" in line: + #clean up line + line2 = re.sub("[\n\t\r}]", "", line) + # split line + line = line2.split("{",1) + #line[1] is the part between {} + line2 = line[1].split(",") + mib = line2[0] + #line2[3] is the OID of the device model name which + #could be made of #define const and string. + source_oid = line2[3] + #line2[5] is the SysOID of the device which + #could be made of #define const and string. + if len(line2) >= 6: + source_sysoid = line2[5] + else: + source_sysoid = "NULL" + + #decode source_oid + line = source_oid.lstrip(" ") + line2 = line.split(" ") + + oid = "" + for elem in line2: + if elem[0] == "\"": + clean_elem = re.sub("\"", "", elem) + oid = oid+clean_elem + else: + oid = oid + expand_define(filename,elem); + + #decode source_sysoid + line = source_sysoid.lstrip(" ") + line = line.rstrip(" ") + line2 = line.split(" ") + + sysoid = "" + for elem in line2: + if elem[0] == "\"": + clean_elem = re.sub("\"", "", elem) + sysoid = sysoid+clean_elem + else: + sysoid = sysoid + expand_define(filename,elem); + + if sysoid == "": + sysoid = "NULL" + else: + sysoid = "\"" + sysoid + "\"" + + output_file.write( "\t{ \"" + oid + "\" , " + mib + ", " + sysoid + "},\n" ) + +output_file.write( " /* Terminating entry */\n" ) +output_file.write( " { NULL, NULL, NULL}\n" ) +output_file.write( "};\n" ) +output_file.write( "#endif /* DEVSCAN_SNMP_H */\n" ) diff --git a/tools/nut-usbinfo.pl b/tools/nut-usbinfo.pl index 606d89d..7833086 100755 --- a/tools/nut-usbinfo.pl +++ b/tools/nut-usbinfo.pl @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# Current Version : 1.0 -# Copyright (C) 2008 - 2010 +# Current Version : 1.1 +# Copyright (C) 2008 - 2011 # Arnaud Quette # dloic (loic.dardant AT gmail DOT com) # @@ -43,6 +43,26 @@ my $tmpOutputUPower; # mfr header flag my $upowerMfrHeaderDone = 0; +# NUT device scanner - C header +my $outputDevScanner = "./nut-scanner/nutscan-usb.h"; + +my $GPL_header = "\ + * Copyright (C) 2011 - Arnaud Quette \ + *\ + * 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"; + # array of products indexed by vendorID my %vendor; @@ -94,6 +114,16 @@ sub gen_usb_files print $outputUPower '# if usbraw device, ignore'."\n".'KERNEL!="hiddev*", GOTO="up_hid_end"'."\n\n"; print $outputUPower '# if an interface, ignore'."\n".'ENV{DEVTYPE}=="usb_interface", GOTO="up_hid_end"'."\n\n"; + # Device scanner header + open my $outputDevScanner, ">$outputDevScanner" || die "error $outputDevScanner : $!"; + print $outputDevScanner '/* nutscan-usb'.$GPL_header."\n */\n\n"; + print $outputDevScanner "#ifndef DEVSCAN_USB_H\n#define DEVSCAN_USB_H\n\n"; + print $outputDevScanner "#include \n"; + print $outputDevScanner "#include \"nut_stdint.h\"\t/* for uint16_t */\n\n"; + # vid, pid, driver + print $outputDevScanner "typedef struct {\n\tuint16_t\tvendorID;\n\tuint16_t\tproductID;\n\tchar*\tdriver_name;\n} usb_device_id_t;\n\n"; + print $outputDevScanner "/* USB IDs device table */\nstatic usb_device_id_t usb_device_table[] = {\n\n"; + # generate the file in alphabetical order (first for VendorID, then for ProductID) foreach my $vendorId (sort { lc $a cmp lc $b } keys %vendorName) { @@ -154,6 +184,9 @@ sub gen_usb_files $tmpOutputUPower = $tmpOutputUPower."\", ATTRS{idProduct}==\"".removeHexPrefix($productId)."\","; $tmpOutputUPower = $tmpOutputUPower.' ENV{UPOWER_BATTERY_TYPE}="ups"'."\n"; } + + # Device scanner entry + print $outputDevScanner "\t{ ".$vendorId.', '.$productId.", \"".$vendor{$vendorId}{$productId}{"driver"}."\" },\n"; } # HAL vendor footer print $outHAL " \n"; @@ -171,6 +204,9 @@ sub gen_usb_files print $outputUPower $tmpOutputUPower; # ...and print footer print $outputUPower "\n".'LABEL="up_hid_end"'."\n"; + + # Device scanner footer + print $outputDevScanner "\t/* Terminating entry */\n\t{ -1, -1, NULL }\n};\n#endif /* DEVSCAN_USB_H */\n\n"; } sub find_usbdevs @@ -231,8 +267,9 @@ sub find_usbdevs } } - # store data (to be optimized) - if (($vendorName{$VendorID} eq "") && ($VendorName)) + # store date (to be optimized) + # and don't overwritte actual vendor names with empty values + if( (!$vendorName{$VendorID}) or (($vendorName{$VendorID} eq "") and ($VendorName ne "")) ) { $vendorName{$VendorID}=trim($VendorName); } diff --git a/tools/svn2cl.authors b/tools/svn2cl.authors index bc5252f..99086b3 100644 --- a/tools/svn2cl.authors +++ b/tools/svn2cl.authors @@ -1,5 +1,13 @@ +esr-guest:Eric S. Raymond +lestat-guest:David Goncalves +agordeev-guest:Alexander Gordeev +emilienkia-guest:Emilien Kia +prachi-guest:Prachi Gandhi +praveenkumar-guest:Praveen Kumar +msoltyspl-guest:Michal Soltys +keyson-guest:Kjell Claesson +chetanagarwal-guest:Chetan Agarwal +fbohe-guest:Frederic Bohe +aquette:Arnaud Quette clepple-guest:Charles Lepple adkorte-guest:Arjen de Korte -aquette:Arnaud Quette -lestat-guest:David Goncalves -chetanagarwal-guest: Chetan Agarwal