Compare commits
No commits in common. "pristine-tar" and "nll-2.8.0" have entirely different histories.
pristine-t
...
nll-2.8.0
1059 changed files with 363538 additions and 11 deletions
38
.drone.yml
Normal file
38
.drone.yml
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Build Bullseye
|
||||||
|
image: debian:bullseye
|
||||||
|
volumes:
|
||||||
|
- name: finished_files
|
||||||
|
path: /deb_files
|
||||||
|
commands:
|
||||||
|
- apt update
|
||||||
|
- apt -y upgrade
|
||||||
|
- apt -y install --no-install-recommends build-essential equivs devscripts git rename
|
||||||
|
- git clean -f -d -x
|
||||||
|
- mk-build-deps --install --tool='apt-get -o Debug::pkgProblemResolver=yes --no-install-recommends --yes' debian/control
|
||||||
|
- dpkg-buildpackage -b -uc
|
||||||
|
- rename 's/\.deb/_bullseye\.deb/' ../*.deb
|
||||||
|
- mkdir -p /deb_files/bullseye/
|
||||||
|
- cp ../*.deb /deb_files/bullseye/
|
||||||
|
- find /deb_files/
|
||||||
|
|
||||||
|
- name: gitea_release
|
||||||
|
image: plugins/gitea-release
|
||||||
|
volumes:
|
||||||
|
- name: finished_files
|
||||||
|
path: /deb_files
|
||||||
|
settings:
|
||||||
|
api_key:
|
||||||
|
from_secret: GITEA_KEY
|
||||||
|
base_url: https://git.neulandlabor.de/
|
||||||
|
files:
|
||||||
|
- /deb_files/bullseye/*
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: finished_files
|
||||||
|
temp: {}
|
176
AUTHORS
Normal file
176
AUTHORS
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
# The NUT AUTHORS file. Don't be shy. If you have contributed to this
|
||||||
|
# project in some way, send me a patch to add yourself to this file.
|
||||||
|
#
|
||||||
|
# Everyone deserves credit, including those who haven't added any code.
|
||||||
|
# Ideas, clues, and helping out on the mailing lists all count too.
|
||||||
|
#
|
||||||
|
# This is a blatant ripoff of the fields found in the Linux kernel's CREDITS
|
||||||
|
# file. If we need more data, those fields can always be added later.
|
||||||
|
#
|
||||||
|
# N = name, E = email, W = web address, D = description, P = PGP info,
|
||||||
|
# S = snailmail address, etc.
|
||||||
|
#
|
||||||
|
# This file is supposed to be roughly alpha-sorted by the last name, but
|
||||||
|
# if you want to hide at the bottom, that's fine by me. Just clarify
|
||||||
|
# your preference when submitting changes to this file.
|
||||||
|
|
||||||
|
N: Stephen Brown
|
||||||
|
E: steve@datalimbo.net
|
||||||
|
W: http://www.datalimbo.net/
|
||||||
|
D: Hacked genericups to add TrippLite Lan2.x support (Internet Office 700)
|
||||||
|
|
||||||
|
N: Bill Carlson
|
||||||
|
E: wcarlson@wkks.org
|
||||||
|
W: http://wkks.org/
|
||||||
|
D: Fixed the GD/configure problem
|
||||||
|
|
||||||
|
N: Ben Collver
|
||||||
|
E: collver@softhome.net
|
||||||
|
W: http://superfluous.oddbox.org
|
||||||
|
D: Beginning support for HPUX 10.20 and Windows 2000
|
||||||
|
|
||||||
|
N: Luca Filipozzi
|
||||||
|
E: lfilipoz@debian.org
|
||||||
|
D: Original Debian maintainer for nut package. Minor patches to source.
|
||||||
|
|
||||||
|
N: Matthew Gabeler-Lee
|
||||||
|
E: msg2@po.cwru.edu
|
||||||
|
W: http://cheetah.cwru.edu
|
||||||
|
D: Added custom formatting to upslog
|
||||||
|
D: Helped get apcsmart working with old SmartUPS models
|
||||||
|
|
||||||
|
N: David Goncalves
|
||||||
|
E: david@lestat.st
|
||||||
|
W: http://www.lestat.st
|
||||||
|
D: Python client support (PyNUT module and NUT-Monitor application)
|
||||||
|
|
||||||
|
N: Bruno Hall
|
||||||
|
D: Contributed UPS compatibility information
|
||||||
|
|
||||||
|
N: Bo Kersey - VirCIO - Managed Server Solutions
|
||||||
|
E: bo@vircio.com
|
||||||
|
W: http://www.vircio.com/
|
||||||
|
D: Provided a Best Fortress for development of a Best driver (bestups)
|
||||||
|
|
||||||
|
N: Russell Kroll
|
||||||
|
E: rkroll@exploits.org
|
||||||
|
W: http://www.networkupstools.org/
|
||||||
|
D: Original NUT author and coordinator
|
||||||
|
P: 1024D/9DC0E77E 6A5C 7D2D 7945 C022 6104 D421 D61D C97F 9DC0 E77E
|
||||||
|
|
||||||
|
N: Rick Lyons
|
||||||
|
E: rick@powerup.com.au
|
||||||
|
D: Support for Liebert UPSes using MultiLink cable
|
||||||
|
|
||||||
|
N: Jeremy Maccelari
|
||||||
|
E: visualn@iafrica.com, jeremy@visuals.co.za
|
||||||
|
W: http://www.visuals.co.za
|
||||||
|
D: Support for Mustek UPSes
|
||||||
|
|
||||||
|
N: Philippe Marzouk
|
||||||
|
E: philm@users.sourceforge.net
|
||||||
|
D: Support for MGE Pulsar Ellipse UPSes ; co author of mge-shut
|
||||||
|
|
||||||
|
N: Theodor A. Milkov
|
||||||
|
E: zimage@delbg.com
|
||||||
|
W: http://www.delbg.com/~zimage/
|
||||||
|
D: Adding support for Repotec's RPT-800A, RPT-162A to genericups driver.
|
||||||
|
|
||||||
|
N: Mark Powell
|
||||||
|
E: medp@primagraphics.co.uk
|
||||||
|
D: Ported to SunOS4
|
||||||
|
|
||||||
|
N: Arnaud Quette
|
||||||
|
E: aquette.dev@gmail.com
|
||||||
|
E: arnaud.quette@mgeups.com
|
||||||
|
E: aquette@debian.org
|
||||||
|
W: http://arnaud.quette.free.fr/
|
||||||
|
D: Primary coordinator ; author of snmp-ups, mge-shut, usbhid-ups ;
|
||||||
|
D: co author of mge-utalk, hidups, SNMP UPS Agent ; contributor to blazer,
|
||||||
|
D: bestferrups, nut core, and many others ; coordination with MGE UPS
|
||||||
|
D: SYSTEMS, linux-usb developers (for hidups), Net SNMP and packagers
|
||||||
|
D: (Mandriva, Debian, SuSE, ...)...
|
||||||
|
P: 1024D/204DDF1B 1371 07DF 3CF3 9160 7905 144B DB64 14CA 204D DF1B
|
||||||
|
|
||||||
|
N: Lars Balker Rasmussen
|
||||||
|
E: lbr@mjolner.dk
|
||||||
|
D: Solaris and minor patches
|
||||||
|
|
||||||
|
N: David Santinoli
|
||||||
|
E: david@santinoli.com
|
||||||
|
W: http://www.santinoli.com
|
||||||
|
D: Support for Online P-series in genericups driver
|
||||||
|
|
||||||
|
N: Jacob Schmier
|
||||||
|
E: j.schmier@live.com
|
||||||
|
D: support for Universal-Mount ON Series UPS family in oneac driver
|
||||||
|
|
||||||
|
N: Peter Selinger
|
||||||
|
E: selinger@users.sourceforge.net
|
||||||
|
W: http://www.mathstat.dal.ca/~selinger/
|
||||||
|
D: wrote belkinunv driver, contributions to usbhid-ups
|
||||||
|
P: 1024D/CA31696A 12A2 4B3C 3790 B688 E484 7A98 A68B CC37 CA31 696A
|
||||||
|
|
||||||
|
N: Kirill Smelkov
|
||||||
|
E: kirr@mns.spb.ru
|
||||||
|
D: Author of al175
|
||||||
|
|
||||||
|
N: John Stone
|
||||||
|
E: johns@megapixel.com
|
||||||
|
W: http://www.megapixel.com/
|
||||||
|
D: Support for Best MicroFerrups UPS
|
||||||
|
|
||||||
|
N: Technorama Ltd.
|
||||||
|
E: oss-list-ups@technorama.net
|
||||||
|
D: common driver core design, redundant code elimination, security fixes
|
||||||
|
D: other misc patches and improvements throughout
|
||||||
|
|
||||||
|
N: Jason Thomas
|
||||||
|
E: jason@topic.com.au
|
||||||
|
W: http://www.topic.com.au/
|
||||||
|
D: Hacked up the UPSonic Driver.
|
||||||
|
|
||||||
|
N: Simon Rozman
|
||||||
|
E: simon@rozman.net
|
||||||
|
W: http://simon.rozman.net/
|
||||||
|
D: Hacked powercom to add Socomec Sycon Egys 420 VA support
|
||||||
|
|
||||||
|
N: Len J White
|
||||||
|
E: lwhite@darkfires.net
|
||||||
|
|
||||||
|
N: Walt Holman
|
||||||
|
E: walt_h@lorettotel.net
|
||||||
|
D: Hacked up the cpsups driver for CyberPower text protocol UPSes
|
||||||
|
|
||||||
|
N: Fabio Di Niro
|
||||||
|
E: blaxwan@users.sourceforge.net
|
||||||
|
D: Author of metasys driver, support for Meta System UPS
|
||||||
|
|
||||||
|
N: Arjen de Korte
|
||||||
|
E: arjen@de-korte.org
|
||||||
|
D: Author of safenet driver
|
||||||
|
P: 1024R/AEF3BA11 664E 032C 9DB5 CB9B 7AFE 7EC1 EE88 BC57
|
||||||
|
|
||||||
|
N: Håvard Lygre
|
||||||
|
E: hklygre@online.no
|
||||||
|
D: First stab at upscode2 driver for NUT 1.4
|
||||||
|
|
||||||
|
N: Niels Baggesen
|
||||||
|
E: niels@baggesen.net
|
||||||
|
D: upgraded the upscode2 driver to NUT-2, and extended it heavily.
|
||||||
|
|
||||||
|
N: Niklas Edmundsson
|
||||||
|
E: nikke@acc.umu.se
|
||||||
|
D: 3-phase work, updates for upscode2
|
||||||
|
|
||||||
|
N: Olli Savia
|
||||||
|
E: ops@iki.fi
|
||||||
|
D: pwmib support for snmp-ups
|
||||||
|
|
||||||
|
N: Kjell Claesson
|
||||||
|
E: Kjell.claesson@epost.tidanet.se
|
||||||
|
D: Author of bcmxcp driver, 3-phase work.
|
||||||
|
|
||||||
|
N: Giuseppe Corbelli
|
||||||
|
E: giuseppe.corbelli@copanitalia.com
|
||||||
|
D: Author of asem driver
|
12
COPYING
Normal file
12
COPYING
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
Most files are licensed under the GNU General Public License (GPL) version 2,
|
||||||
|
or (at your option) any later version. See "LICENSE-GPL2" in the root of this
|
||||||
|
distribution.
|
||||||
|
|
||||||
|
The files in the scripts/python/ directory are released under GNU General
|
||||||
|
Public License (GPL) version 3, or (at your option) any later version. See
|
||||||
|
"LICENSE-GPL3" in the root of this distribution.
|
||||||
|
|
||||||
|
The Perl client module (scripts/perl/Nut.pm) is released under the same
|
||||||
|
license as Perl itself. That is to say either GPL version 1 or (at your option)
|
||||||
|
any later version, or the "Artistic License".
|
368
INSTALL
Normal file
368
INSTALL
Normal file
|
@ -0,0 +1,368 @@
|
||||||
|
Installation Instructions
|
||||||
|
*************************
|
||||||
|
|
||||||
|
Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
|
Copying and distribution of this file, with or without modification,
|
||||||
|
are permitted in any medium without royalty provided the copyright
|
||||||
|
notice and this notice are preserved. This file is offered as-is,
|
||||||
|
without warranty of any kind.
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
Briefly, the shell command './configure && make && make install'
|
||||||
|
should configure, build, and install this package. The following
|
||||||
|
more-detailed instructions are generic; see the 'README' file for
|
||||||
|
instructions specific to this package. Some packages provide this
|
||||||
|
'INSTALL' file but do not implement all of the features documented
|
||||||
|
below. The lack of an optional feature in a given package is not
|
||||||
|
necessarily a bug. More recommendations for GNU packages can be found
|
||||||
|
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||||
|
|
||||||
|
The 'configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a 'Makefile' in each directory of the package.
|
||||||
|
It may also create one or more '.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script 'config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, and a
|
||||||
|
file 'config.log' containing compiler output (useful mainly for
|
||||||
|
debugging 'configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called 'config.cache' and
|
||||||
|
enabled with '--cache-file=config.cache' or simply '-C') that saves the
|
||||||
|
results of its tests to speed up reconfiguring. Caching is disabled by
|
||||||
|
default to prevent problems with accidental use of stale cache files.
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how 'configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the 'README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point 'config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file 'configure.ac' (or 'configure.in') is used to create
|
||||||
|
'configure' by a program called 'autoconf'. You need 'configure.ac' if
|
||||||
|
you want to change it or regenerate 'configure' using a newer version of
|
||||||
|
'autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. 'cd' to the directory containing the package's source code and type
|
||||||
|
'./configure' to configure the package for your system.
|
||||||
|
|
||||||
|
Running 'configure' might take a while. While running, it prints
|
||||||
|
some messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type 'make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type 'make check' to run any self-tests that come with
|
||||||
|
the package, generally using the just-built uninstalled binaries.
|
||||||
|
|
||||||
|
4. Type 'make install' to install the programs and any data files and
|
||||||
|
documentation. When installing into a prefix owned by root, it is
|
||||||
|
recommended that the package be configured and built as a regular
|
||||||
|
user, and only the 'make install' phase executed with root
|
||||||
|
privileges.
|
||||||
|
|
||||||
|
5. Optionally, type 'make installcheck' to repeat any self-tests, but
|
||||||
|
this time using the binaries in their final installed location.
|
||||||
|
This target does not install anything. Running this target as a
|
||||||
|
regular user, particularly if the prior 'make install' required
|
||||||
|
root privileges, verifies that the installation completed
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
6. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing 'make clean'. To also remove the
|
||||||
|
files that 'configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type 'make distclean'. There is
|
||||||
|
also a 'make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
7. Often, you can also type 'make uninstall' to remove the installed
|
||||||
|
files again. In practice, not all packages have tested that
|
||||||
|
uninstallation works correctly, even though it is required by the
|
||||||
|
GNU Coding Standards.
|
||||||
|
|
||||||
|
8. Some packages, particularly those that use Automake, provide 'make
|
||||||
|
distcheck', which can by used by developers to test that all other
|
||||||
|
targets like 'make install' and 'make uninstall' work correctly.
|
||||||
|
This target is generally not run by end users.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the 'configure' script does not know about. Run './configure --help'
|
||||||
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give 'configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here is
|
||||||
|
an example:
|
||||||
|
|
||||||
|
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you can use GNU 'make'. 'cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the 'configure' script. 'configure' automatically checks for the source
|
||||||
|
code in the directory that 'configure' is in and in '..'. This is known
|
||||||
|
as a "VPATH" build.
|
||||||
|
|
||||||
|
With a non-GNU 'make', it is safer to compile the package for one
|
||||||
|
architecture at a time in the source code directory. After you have
|
||||||
|
installed the package for one architecture, use 'make distclean' before
|
||||||
|
reconfiguring for another architecture.
|
||||||
|
|
||||||
|
On MacOS X 10.5 and later systems, you can create libraries and
|
||||||
|
executables that work on multiple system types--known as "fat" or
|
||||||
|
"universal" binaries--by specifying multiple '-arch' options to the
|
||||||
|
compiler but only a single '-arch' option to the preprocessor. Like
|
||||||
|
this:
|
||||||
|
|
||||||
|
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||||
|
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||||
|
CPP="gcc -E" CXXCPP="g++ -E"
|
||||||
|
|
||||||
|
This is not guaranteed to produce working output in all cases, you
|
||||||
|
may have to build one architecture at a time and combine the results
|
||||||
|
using the 'lipo' tool if you have problems.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, 'make install' installs the package's commands under
|
||||||
|
'/usr/local/bin', include files under '/usr/local/include', etc. You
|
||||||
|
can specify an installation prefix other than '/usr/local' by giving
|
||||||
|
'configure' the option '--prefix=PREFIX', where PREFIX must be an
|
||||||
|
absolute file name.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
|
||||||
|
PREFIX as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like '--bindir=DIR' to specify different values for particular
|
||||||
|
kinds of files. Run 'configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them. In general, the default
|
||||||
|
for these options is expressed in terms of '${prefix}', so that
|
||||||
|
specifying just '--prefix' will affect all of the other directory
|
||||||
|
specifications that were not explicitly provided.
|
||||||
|
|
||||||
|
The most portable way to affect installation locations is to pass the
|
||||||
|
correct locations to 'configure'; however, many packages provide one or
|
||||||
|
both of the following shortcuts of passing variable assignments to the
|
||||||
|
'make install' command line to change installation locations without
|
||||||
|
having to reconfigure or recompile.
|
||||||
|
|
||||||
|
The first method involves providing an override variable for each
|
||||||
|
affected directory. For example, 'make install
|
||||||
|
prefix=/alternate/directory' will choose an alternate location for all
|
||||||
|
directory configuration variables that were expressed in terms of
|
||||||
|
'${prefix}'. Any directories that were specified during 'configure',
|
||||||
|
but not in terms of '${prefix}', must each be overridden at install time
|
||||||
|
for the entire installation to be relocated. The approach of makefile
|
||||||
|
variable overrides for each directory variable is required by the GNU
|
||||||
|
Coding Standards, and ideally causes no recompilation. However, some
|
||||||
|
platforms have known limitations with the semantics of shared libraries
|
||||||
|
that end up requiring recompilation when using this method, particularly
|
||||||
|
noticeable in packages that use GNU Libtool.
|
||||||
|
|
||||||
|
The second method involves providing the 'DESTDIR' variable. For
|
||||||
|
example, 'make install DESTDIR=/alternate/directory' will prepend
|
||||||
|
'/alternate/directory' before all installation names. The approach of
|
||||||
|
'DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||||
|
does not work on platforms that have drive letters. On the other hand,
|
||||||
|
it does better at avoiding recompilation issues, and works well even
|
||||||
|
when some directory options were not specified in terms of '${prefix}'
|
||||||
|
at 'configure' time.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving 'configure' the
|
||||||
|
option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Some packages pay attention to '--enable-FEATURE' options to
|
||||||
|
'configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to '--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like 'gnu-as' or 'x' (for the X Window System). The
|
||||||
|
'README' should mention any '--enable-' and '--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, 'configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the 'configure' options '--x-includes=DIR' and
|
||||||
|
'--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Some packages offer the ability to configure how verbose the
|
||||||
|
execution of 'make' will be. For these packages, running './configure
|
||||||
|
--enable-silent-rules' sets the default to minimal output, which can be
|
||||||
|
overridden with 'make V=1'; while running './configure
|
||||||
|
--disable-silent-rules' sets the default to verbose, which can be
|
||||||
|
overridden with 'make V=0'.
|
||||||
|
|
||||||
|
Particular systems
|
||||||
|
==================
|
||||||
|
|
||||||
|
On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
|
||||||
|
is not installed, it is recommended to use the following options in
|
||||||
|
order to use an ANSI C compiler:
|
||||||
|
|
||||||
|
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||||
|
|
||||||
|
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||||
|
|
||||||
|
HP-UX 'make' updates targets which have the same time stamps as their
|
||||||
|
prerequisites, which makes it generally unusable when shipped generated
|
||||||
|
files such as 'configure' are involved. Use GNU 'make' instead.
|
||||||
|
|
||||||
|
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||||
|
parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
|
||||||
|
workaround. If GNU CC is not installed, it is therefore recommended to
|
||||||
|
try
|
||||||
|
|
||||||
|
./configure CC="cc"
|
||||||
|
|
||||||
|
and if that doesn't work, try
|
||||||
|
|
||||||
|
./configure CC="cc -nodtk"
|
||||||
|
|
||||||
|
On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
|
||||||
|
directory contains several dysfunctional programs; working variants of
|
||||||
|
these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
|
||||||
|
in your 'PATH', put it _after_ '/usr/bin'.
|
||||||
|
|
||||||
|
On Haiku, software installed for all users goes in '/boot/common',
|
||||||
|
not '/usr/local'. It is recommended to use the following options:
|
||||||
|
|
||||||
|
./configure --prefix=/boot/common
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features 'configure' cannot figure out
|
||||||
|
automatically, but needs to determine by the type of machine the package
|
||||||
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
|
_same_ architectures, 'configure' can figure that out, but if it prints
|
||||||
|
a message saying it cannot guess the machine type, give it the
|
||||||
|
'--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as 'sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS
|
||||||
|
KERNEL-OS
|
||||||
|
|
||||||
|
See the file 'config.sub' for the possible values of each field. If
|
||||||
|
'config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the option '--target=TYPE' to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with '--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for 'configure' scripts to share,
|
||||||
|
you can create a site shell script called 'config.site' that gives
|
||||||
|
default values for variables like 'CC', 'cache_file', and 'prefix'.
|
||||||
|
'configure' looks for 'PREFIX/share/config.site' if it exists, then
|
||||||
|
'PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
'CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all 'configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to 'configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the 'configure' command line, using 'VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
causes the specified 'gcc' to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
|
||||||
|
Autoconf limitation. Until the limitation is lifted, you can use this
|
||||||
|
workaround:
|
||||||
|
|
||||||
|
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||||
|
|
||||||
|
'configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
'configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
'--help'
|
||||||
|
'-h'
|
||||||
|
Print a summary of all of the options to 'configure', and exit.
|
||||||
|
|
||||||
|
'--help=short'
|
||||||
|
'--help=recursive'
|
||||||
|
Print a summary of the options unique to this package's
|
||||||
|
'configure', and exit. The 'short' variant lists options used only
|
||||||
|
in the top level, while the 'recursive' variant lists options also
|
||||||
|
present in any nested packages.
|
||||||
|
|
||||||
|
'--version'
|
||||||
|
'-V'
|
||||||
|
Print the version of Autoconf used to generate the 'configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
'--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally 'config.cache'. FILE defaults to '/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
'--config-cache'
|
||||||
|
'-C'
|
||||||
|
Alias for '--cache-file=config.cache'.
|
||||||
|
|
||||||
|
'--quiet'
|
||||||
|
'--silent'
|
||||||
|
'-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to '/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
'--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
'configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
'--prefix=DIR'
|
||||||
|
Use DIR as the installation prefix. *note Installation Names:: for
|
||||||
|
more details, including other options available for fine-tuning the
|
||||||
|
installation locations.
|
||||||
|
|
||||||
|
'--no-create'
|
||||||
|
'-n'
|
||||||
|
Run the configure checks, but stop before creating any output
|
||||||
|
files.
|
||||||
|
|
||||||
|
'configure' also accepts some other, not widely useful, options. Run
|
||||||
|
'configure --help' for more details.
|
350
INSTALL.nut
Normal file
350
INSTALL.nut
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
Installation instructions
|
||||||
|
=========================
|
||||||
|
|
||||||
|
This chapter describes the various methods for installing Network UPS Tools.
|
||||||
|
|
||||||
|
Whenever it is possible, prefer <<Installing_packages, installing from packages>>.
|
||||||
|
Packagers have done an excellent and hard work at improving NUT integration into
|
||||||
|
their system. On the other hand, distributions and appliances tend to package
|
||||||
|
"official releases" of projects such as NUT, and so do not deliver latest and
|
||||||
|
greatest fixes, new drivers, bugs and other features.
|
||||||
|
|
||||||
|
[[Installing_source]]
|
||||||
|
Installing from source
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
These are the essential steps for compiling and installing this software.
|
||||||
|
|
||||||
|
The NUT linkdoc:packager-guide[Packager Guide], which presents the best
|
||||||
|
practices for installing and integrating NUT, is also a good reading.
|
||||||
|
|
||||||
|
The link:config-prereqs.txt[Prerequisites for building NUT on different OSes]
|
||||||
|
document suggests prerequisite packages with tools and dependencies
|
||||||
|
available and needed to build and test as much as possible of NUT on
|
||||||
|
numerous platforms, written from perspective of CI testing (if you
|
||||||
|
are interested in getting updated drivers for a particular device,
|
||||||
|
you might select a sub-set of those suggestions).
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
.Keep in mind that...
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
- the paths shown below are the default values you get by just calling
|
||||||
|
configure by itself. If you have used --prefix or similar, things will be
|
||||||
|
different. Also, if you didn't install this program from source yourself, the
|
||||||
|
paths will probably have a number of differences.
|
||||||
|
|
||||||
|
- by default, your system probably won't find the man pages, since they
|
||||||
|
install to /usr/local/ups/man. You can fix this by editing your MANPATH, or
|
||||||
|
just do this:
|
||||||
|
|
||||||
|
man -M /usr/local/ups/man <man page>
|
||||||
|
|
||||||
|
- if your favorite system offers up to date binary packages, you should always
|
||||||
|
prefer these over a source installation. Along with the known advantages of such
|
||||||
|
systems for installation, upgrade and removal, there are many integration issues
|
||||||
|
that have been addressed.
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
Prepare your system
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
System User creation
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Create at least one system user and a group for running this software. You
|
||||||
|
might call them "ups" and "nut". The exact names aren't important as
|
||||||
|
long as you are consistent.
|
||||||
|
|
||||||
|
The process for doing this varies from one system to the next, and
|
||||||
|
explaining how to add users is beyond the scope of this document.
|
||||||
|
|
||||||
|
For the purposes of this document, the user name and group name
|
||||||
|
will be 'ups' and 'nut' respectively.
|
||||||
|
|
||||||
|
Be sure the new user is a member of the new group! If you forget to
|
||||||
|
do this, you will have problems later on when you try to start upsd.
|
||||||
|
|
||||||
|
|
||||||
|
Build and install
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
[[Configuration]]
|
||||||
|
Configuration
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Configure the source tree for your system. Add the '--with-user' and
|
||||||
|
'--with-group' switch to set the user name and group that you created
|
||||||
|
above.
|
||||||
|
|
||||||
|
./configure --with-user=ups --with-group=nut
|
||||||
|
|
||||||
|
If you need any other switches for configure, add them here. For example:
|
||||||
|
|
||||||
|
* to build and install USB drivers, add '--with-usb' (note that you
|
||||||
|
need to install libusb development package or files).
|
||||||
|
|
||||||
|
* to build and install SNMP drivers, add '--with-snmp' (note that
|
||||||
|
you need to install libsnmp development package or files).
|
||||||
|
|
||||||
|
* to build and install CGI scripts, add '--with-cgi'.
|
||||||
|
|
||||||
|
See <<Configure_options,Configure options>> from the User Manual,
|
||||||
|
docs/configure.txt or './configure --help' for all the available
|
||||||
|
options.
|
||||||
|
|
||||||
|
If you alter paths with additional switches, be sure to use those
|
||||||
|
new paths while reading the rest of the steps.
|
||||||
|
|
||||||
|
Reference: <<Configure_options,Configure options>> from the
|
||||||
|
User Manual.
|
||||||
|
|
||||||
|
|
||||||
|
Build the programs
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
This will build the NUT client and server programs and the
|
||||||
|
selected drivers. It will also build any other features that were
|
||||||
|
selected during <<Configuration,configuration>> step above.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
[NOTE]
|
||||||
|
=====================================================================
|
||||||
|
|
||||||
|
you should now gain privileges for installing software if necessary:
|
||||||
|
|
||||||
|
su
|
||||||
|
|
||||||
|
=====================================================================
|
||||||
|
|
||||||
|
Install the files to a system level directory:
|
||||||
|
|
||||||
|
make install
|
||||||
|
|
||||||
|
This will install the compiled programs and man pages, as well as
|
||||||
|
some data files required by NUT. Any optional features selected
|
||||||
|
during configuration will also be installed.
|
||||||
|
|
||||||
|
This will also install sample versions of the NUT configuration
|
||||||
|
files. Sample files are installed with names like ups.conf.sample
|
||||||
|
so they will not overwrite any existing real config files you may
|
||||||
|
have created.
|
||||||
|
|
||||||
|
If you are packaging this software, then you will probably want to
|
||||||
|
use the DESTDIR variable to redirect the build into another place,
|
||||||
|
i.e.:
|
||||||
|
|
||||||
|
make DESTDIR=/tmp/package install
|
||||||
|
make DESTDIR=/tmp/package install-conf
|
||||||
|
|
||||||
|
[[StatePath]]
|
||||||
|
State path creation
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Create the state path directory for the driver(s) and server to use
|
||||||
|
for storing UPS status data and other auxiliary files, and make it
|
||||||
|
group-writable by the group of the system user you created.
|
||||||
|
|
||||||
|
mkdir -p /var/state/ups
|
||||||
|
chmod 0770 /var/state/ups
|
||||||
|
chown root:nut /var/state/ups
|
||||||
|
|
||||||
|
[[Ownership]]
|
||||||
|
Ownership and permissions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Set ownership data and permissions on your serial or USB ports
|
||||||
|
that go to your UPS hardware. Be sure to limit access to just
|
||||||
|
the user you created earlier.
|
||||||
|
|
||||||
|
These examples assume the second serial port (ttyS1) on a typical
|
||||||
|
Slackware system. On FreeBSD, that would be cuaa1. Serial ports
|
||||||
|
vary greatly, so yours may be called something else.
|
||||||
|
|
||||||
|
chmod 0660 /dev/ttyS1
|
||||||
|
chown root:nut /dev/ttyS1
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
FIXME: TBR
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
The setup for USB ports is slightly more complicated. Device files
|
||||||
|
for USB devices, such as /proc/bus/usb/002/001, are usually
|
||||||
|
created "on the fly" when a device is plugged in, and disappear
|
||||||
|
when the device is disconnected. Moreover, the names of these
|
||||||
|
device files can change randomly. To set up the correct
|
||||||
|
permissions for the USB device, you may need to set up (operating
|
||||||
|
system dependent) hotplugging scripts. Sample scripts and
|
||||||
|
information are provided in the scripts/hotplug and
|
||||||
|
scripts/udev directories. For most users, the hotplugging scripts
|
||||||
|
will be installed automatically by "make install".
|
||||||
|
|
||||||
|
(If you want to try if a driver works without setting up
|
||||||
|
hotplugging, you can add the "-u root" option to upsd, upsmon, and
|
||||||
|
drivers; this should allow you to follow the below
|
||||||
|
instructions. However, don't forget to set up the correct
|
||||||
|
permissions later!).
|
||||||
|
|
||||||
|
NOTE: if you are using something like udev or devd, make sure
|
||||||
|
these permissions stay set across a reboot. If they revert to the
|
||||||
|
old values, your drivers may fail to start.
|
||||||
|
|
||||||
|
|
||||||
|
You are now ready to configure NUT, and start testing and using it.
|
||||||
|
|
||||||
|
You can jump directly to the <<Configuration_notes,NUT configuration>>.
|
||||||
|
|
||||||
|
|
||||||
|
[[Installing_packages]]
|
||||||
|
Installing from packages
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
This chapter describes the specific installation steps when using
|
||||||
|
binary packages that exist on various major systems.
|
||||||
|
|
||||||
|
[[Debian]]
|
||||||
|
Debian, Ubuntu and other derivatives
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
NOTE: NUT is packaged and well maintained in these systems.
|
||||||
|
The official Debian packager is part of the NUT Team.
|
||||||
|
|
||||||
|
Using your preferred method (apt-get, aptitude, Synaptic, ...), install
|
||||||
|
the 'nut' package, and optionally the following:
|
||||||
|
|
||||||
|
- 'nut-cgi', if you need the CGI (HTML) option,
|
||||||
|
- 'nut-snmp', if you need the snmp-ups driver,
|
||||||
|
- 'nut-xml', for the netxml-ups driver,
|
||||||
|
- 'nut-powerman-pdu', to control the PowerMan daemon (PDU management)
|
||||||
|
- 'nut-dev', if you need the development files.
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
- nut-client
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Configuration files are located in /etc/nut.
|
||||||
|
linkman:nut.conf[5] must be edited to be able to invoke /etc/init.d/nut
|
||||||
|
|
||||||
|
NOTE: Ubuntu users can access the APT URL installation by clicking on link:apt://nut[this link].
|
||||||
|
|
||||||
|
|
||||||
|
[[Mandriva]]
|
||||||
|
Mandriva
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
NOTE: NUT is packaged and well maintained in these systems.
|
||||||
|
The official Mandriva packager is part of the NUT Team.
|
||||||
|
|
||||||
|
Using your preferred method (urpmi, RPMdrake, ...), install one of the two below
|
||||||
|
packages:
|
||||||
|
|
||||||
|
- 'nut-server' if you have a 'standalone' or 'netserver' installation,
|
||||||
|
- 'nut' if you have a 'netclient' installation.
|
||||||
|
|
||||||
|
Optionally, you can also install the following:
|
||||||
|
|
||||||
|
- 'nut-cgi', if you need the CGI (HTML) option,
|
||||||
|
- 'nut-devel', if you need the development files.
|
||||||
|
|
||||||
|
|
||||||
|
[[SUSE]]
|
||||||
|
SUSE / openSUSE
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
NOTE: NUT is packaged and well maintained in these systems.
|
||||||
|
The official SUSE packager is part of the NUT Team.
|
||||||
|
|
||||||
|
Install the 'nut-classic' package, and optionally the following:
|
||||||
|
|
||||||
|
- 'nut-drivers-net', if you need the snmp-ups or the netxml-ups drivers,
|
||||||
|
- 'nut-cgi', if you need the CGI (HTML) option,
|
||||||
|
- 'nut-devel', if you need the development files,
|
||||||
|
|
||||||
|
NOTE: SUSE and openSUSE users can use the
|
||||||
|
link:http://software.opensuse.org/search?baseproject=ALL&p=1&q=nut[one-click install method]
|
||||||
|
to install NUT.
|
||||||
|
|
||||||
|
|
||||||
|
[[RedHat]]
|
||||||
|
Red Hat, Fedora and CentOS
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
NOTE: NUT is packaged and well maintained in these systems.
|
||||||
|
The official Red Hat packager is part of the NUT Team.
|
||||||
|
|
||||||
|
Using your preferred method (yum, Add/Remove Software, ...), install one of the
|
||||||
|
two below packages:
|
||||||
|
|
||||||
|
- 'nut' if you have a 'standalone' or 'netserver' installation,
|
||||||
|
- 'nut-client' if you have a 'netclient' installation.
|
||||||
|
|
||||||
|
Optionally, you can also install the following:
|
||||||
|
|
||||||
|
- 'nut-cgi', if you need the CGI (HTML) option,
|
||||||
|
- 'nut-xml', if you need the netxml-ups driver,
|
||||||
|
- 'nut-devel', if you need the development files.
|
||||||
|
|
||||||
|
|
||||||
|
[[FreeBSD]]
|
||||||
|
FreeBSD
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
You can either install NUT as a binary package or as a port.
|
||||||
|
|
||||||
|
Binary package
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
To install NUT as a package execute:
|
||||||
|
|
||||||
|
# pkg install nut
|
||||||
|
|
||||||
|
Port
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
The port is located under +sysutils/nut+.
|
||||||
|
Use +make config+ to select configuration options, e.g. to build the optional CGI scripts.
|
||||||
|
To install it, use:
|
||||||
|
|
||||||
|
# make install clean
|
||||||
|
|
||||||
|
USB UPS on FreeBSD
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
For USB UPS devices the NUT package/port installs devd rules in +/usr/local/etc/devd/nut-usb.conf+ to set USB device permissions. 'devd' needs to be restarted for these rules to apply:
|
||||||
|
|
||||||
|
# service devd restart
|
||||||
|
|
||||||
|
(Re-)connect the device after restarting 'devd' and check that the USB device has the proper
|
||||||
|
permissions. Check the last entries of the system message buffer. You should
|
||||||
|
find an entry like
|
||||||
|
|
||||||
|
# dmesg | tail
|
||||||
|
[...]
|
||||||
|
ugen0.2: <INNO TECH USB to Serial> at usbus0
|
||||||
|
|
||||||
|
The device file must be owned by group +uucp+ and must be group
|
||||||
|
read-/writable. In the example from above this would be
|
||||||
|
|
||||||
|
# ls -Ll /dev/ugen0.2
|
||||||
|
crw-rw---- 1 root uucp 0xa5 Mar 12 10:33 /dev/ugen0.2
|
||||||
|
|
||||||
|
If the permissions are not correct, verify that your device is registered in
|
||||||
|
+/usr/local/etc/devd/nut-usb.conf+. The vendor and product id can be found
|
||||||
|
using:
|
||||||
|
|
||||||
|
# usbconfig -u 0 -a 2 dump_device_desc
|
||||||
|
|
||||||
|
where +-u+ specifies the USB bus number and +-a+ specifies the USB device index.
|
||||||
|
|
||||||
|
|
||||||
|
You are now ready to configure NUT, and start testing and using it.
|
||||||
|
|
||||||
|
You can jump directly to the
|
||||||
|
<<Configuration_notes,NUT configuration>>.
|
339
LICENSE-GPL2
Normal file
339
LICENSE-GPL2
Normal file
|
@ -0,0 +1,339 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
676
LICENSE-GPL3
Normal file
676
LICENSE-GPL3
Normal file
|
@ -0,0 +1,676 @@
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
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 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
|
|
66
MAINTAINERS
Normal file
66
MAINTAINERS
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
In the tradition of stealing ideas for top-level files from the Linux
|
||||||
|
kernel tree, here is the NUT MAINTAINERS file. This file is intended to
|
||||||
|
help patch contributors route their changes to the right people.
|
||||||
|
|
||||||
|
Note: just because something isn't listed in here doesn't mean it's not
|
||||||
|
being maintained. It just means that the maintainer hasn't sent me a
|
||||||
|
patch to update this file yet.
|
||||||
|
|
||||||
|
Note 2: there are always other people who work on a project beyond those
|
||||||
|
who are listed here. Omission from this list should not be taken as a
|
||||||
|
slight. Those who are listed below are merely volunteering to be the
|
||||||
|
"lightning rods" for patches to certain parts of the tree.
|
||||||
|
|
||||||
|
Fields
|
||||||
|
======
|
||||||
|
|
||||||
|
P: Person
|
||||||
|
M: Mail patches to this address
|
||||||
|
W: Web address
|
||||||
|
S: Status:
|
||||||
|
|
||||||
|
Supported = someone is paid to do this
|
||||||
|
Maintained = someone keeps it running
|
||||||
|
|
||||||
|
(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.
|
||||||
|
|
||||||
|
Drivers
|
||||||
|
=======
|
||||||
|
|
||||||
|
P: Russell Kroll
|
||||||
|
M: rkroll@exploits.org
|
||||||
|
S: Maintained: apcsmart, belkin, bestups, cyberpower, dummycons,
|
||||||
|
fentonups, driver core (main.c), upsdrvctl
|
||||||
|
|
||||||
|
P: Arnaud Quette
|
||||||
|
M: aquette.dev@gmail.com
|
||||||
|
M: ArnaudQuette@eaton.com
|
||||||
|
S: Maintained or Supported: dummy-ups, usbhid-ups, mge-shut
|
||||||
|
mge-utalk, snmp-ups, ...
|
||||||
|
|
||||||
|
P: Fabio Di Niro
|
||||||
|
M: blaxwan@users.sourceforge.net
|
||||||
|
S: Maintained: metasys
|
||||||
|
|
||||||
|
P: Kirill Smelkov
|
||||||
|
M: kirr@mns.spb.ru
|
||||||
|
S: Maintained: al175
|
||||||
|
|
||||||
|
Packaging
|
||||||
|
=========
|
||||||
|
|
||||||
|
P: Nigel Metheringham
|
||||||
|
M: Nigel.Metheringham@dev.InTechnology.co.uk
|
||||||
|
S: Maintained: nut.spec.in (for Red Hat RPM builds)
|
||||||
|
|
||||||
|
P: Arnaud Quette
|
||||||
|
M: aquette@debian.org
|
||||||
|
S: Maintained: Official Debian packages
|
||||||
|
|
||||||
|
Everything else
|
||||||
|
===============
|
||||||
|
|
||||||
|
No other categories have been created yet.
|
348
Makefile.am
Normal file
348
Makefile.am
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
# top-level Makefile for NUT
|
||||||
|
|
||||||
|
# include directory for aclocal
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
# subdirectories to build and distribute. The order matters, as
|
||||||
|
# several subdirectories depend on stuff in "common" or tools being built first
|
||||||
|
SUBDIRS = include common clients conf data docs drivers tools \
|
||||||
|
lib scripts server tests
|
||||||
|
|
||||||
|
# Automatically update the libtool script if it becomes out-of-date
|
||||||
|
# See https://www.gnu.org/software/libtool/manual/html_node/LT_005fINIT.html
|
||||||
|
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||||
|
libtool: $(LIBTOOL_DEPS)
|
||||||
|
$(SHELL) ./config.status libtool
|
||||||
|
|
||||||
|
# COPYING is included automatically.
|
||||||
|
EXTRA_DIST = INSTALL.nut LICENSE-GPL2 LICENSE-GPL3 MAINTAINERS UPGRADING
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# flags to pass to ./configure when calling "make distcheck" and "make
|
||||||
|
# distcheck-light". Try to check as many features as possible! Also
|
||||||
|
# need to give augeas-lenses-dir, hotplug-dir and udev-dir, so that
|
||||||
|
# staged install does not fail.
|
||||||
|
|
||||||
|
DISTCHECK_FLAGS = --with-all --with-ssl --with-doc=auto
|
||||||
|
DISTCHECK_LIGHT_FLAGS = --with-all=auto --with-ssl=auto --with-doc=auto
|
||||||
|
DISTCHECK_VALGRIND_FLAGS = --with-all=auto --with-ssl=auto --with-doc=skip --with-valgrind CXXFLAGS='$(CXXFLAGS) -g' CFLAGS='$(CFLAGS) -g'
|
||||||
|
|
||||||
|
DISTCHECK_CONFIGURE_FLAGS = ${DISTCHECK_FLAGS} \
|
||||||
|
--with-systemdsystemunitdir='$${prefix}/lib/systemd/system' \
|
||||||
|
--with-systemdshutdowndir='$${prefix}/lib/systemd/system-shutdown' \
|
||||||
|
--with-systemdtmpfilesdir='$${prefix}/usr/lib/tmpfiles.d' \
|
||||||
|
--with-augeas-lenses-dir='$${prefix}/usr/share/augeas/lenses' \
|
||||||
|
--with-hotplug-dir='$${prefix}/etc/hotplug' \
|
||||||
|
--with-udev-dir='$${prefix}/etc/udev' \
|
||||||
|
--with-devd-dir='$${prefix}/etc/devd'
|
||||||
|
|
||||||
|
distcheck-light:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DISTCHECK_FLAGS="$(DISTCHECK_LIGHT_FLAGS)" distcheck
|
||||||
|
|
||||||
|
# Make a distcheck (and check in particular) with enabled valgrind and debug info
|
||||||
|
memcheck distcheck-valgrind:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DISTCHECK_FLAGS="$(DISTCHECK_VALGRIND_FLAGS)" distcheck
|
||||||
|
|
||||||
|
# workaround the dist generated files that are also part of the distribution
|
||||||
|
# Note that distcleancheck is disabled for now, while waiting for a proper
|
||||||
|
# solution, that do not break older unix systems
|
||||||
|
#distcleancheck_listfiles = \
|
||||||
|
# find . -type f -exec sh -c 'test -f $(srcdir)/{} || echo {}' ';'
|
||||||
|
distcleancheck:
|
||||||
|
@:
|
||||||
|
|
||||||
|
# Quick alias for root dir recipe:
|
||||||
|
realclean: maintainer-clean
|
||||||
|
|
||||||
|
# Files made by our targets:
|
||||||
|
CLEANFILES = *-spellchecked cppcheck*.xml
|
||||||
|
DISTCLEANFILES = ChangeLog
|
||||||
|
|
||||||
|
# Most of the files generated by custom rules in the configure script
|
||||||
|
# or by autogen.sh are cleaned by the Makefile.am in their directories.
|
||||||
|
# Files below are re-created by running `configure` script and may be
|
||||||
|
# wiped by a `make distclean`:
|
||||||
|
DISTCLEANFILES += config.log configure~
|
||||||
|
#???# configure.ac~
|
||||||
|
DISTCLEANFILES += include/config.h.in~
|
||||||
|
|
||||||
|
# Files made by autotools and common rituals of the configure script,
|
||||||
|
# these are needed to run the configure script itself so are not wiped
|
||||||
|
# by a mere `make distclean`; most of these are copied by autotools
|
||||||
|
# from their installation, or made by `automake` etc. on the system
|
||||||
|
# which generates `configure`; rebuilding NUT after deleting these
|
||||||
|
# requires `autogen.sh` script to be re-run (and tools available):
|
||||||
|
MAINTAINERCLEANFILES = INSTALL
|
||||||
|
MAINTAINERCLEANFILES += aclocal.m4 config.guess config.sub
|
||||||
|
MAINTAINERCLEANFILES += configure
|
||||||
|
MAINTAINERCLEANFILES += depcomp install-sh ltmain.sh test-driver
|
||||||
|
MAINTAINERCLEANFILES += m4/libtool.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4
|
||||||
|
MAINTAINERCLEANFILES += Makefile.in .dirstamp include/config.h.in
|
||||||
|
|
||||||
|
# Executed after default rules
|
||||||
|
maintainer-clean-local:
|
||||||
|
rm -f missing || true
|
||||||
|
|
||||||
|
# Do not let $SUBDIRS/Makefile rules delete their local .deps because
|
||||||
|
# this breaks our ability to clean up (e.g. some common/.../*.Plo files
|
||||||
|
# are included by generated Makefiles from other subdirectories, so they
|
||||||
|
# should be available during their clean-up). Just in case, we make sure
|
||||||
|
# here that their sub-distcleans complete first.
|
||||||
|
distclean-local:
|
||||||
|
@for DIR in $(SUBDIRS) ; do \
|
||||||
|
if test -f "$${DIR}/Makefile" ; then \
|
||||||
|
echo " DISTCLEAN in $${DIR}" >&2 ; \
|
||||||
|
( cd "$${DIR}" && $(MAKE) -s distclean ) || exit ; \
|
||||||
|
fi ; \
|
||||||
|
done
|
||||||
|
rm -rf .inst tmp autom4te.cache
|
||||||
|
find "$(builddir)" -type d -name '.deps' | while read DIR ; do rm -rf "$${DIR}" ; done
|
||||||
|
|
||||||
|
# Hook the documentation building and validating recipes
|
||||||
|
# Note: these are optionally available (as determined during configure runs)
|
||||||
|
spellcheck spellcheck-interactive:
|
||||||
|
@RES=0; \
|
||||||
|
(cd $(builddir)/docs && $(MAKE) -s $@) || RES=$$? ; \
|
||||||
|
(cd $(builddir)/docs/man && $(MAKE) -s $@) || RES=$$? ; \
|
||||||
|
(cd $(builddir)/conf && $(MAKE) -s $@) || RES=$$? ; \
|
||||||
|
(cd $(builddir)/data && $(MAKE) -s $@) || RES=$$? ; \
|
||||||
|
exit $$RES
|
||||||
|
|
||||||
|
# Note: the "all-docs" and "check-docs" targets may require tools not
|
||||||
|
# found by `configure` script (and so avoided by conventional recipes)
|
||||||
|
# such as PDF generators, so it should only be called at developer's
|
||||||
|
# discretion, choice and risk. The "check-man" targets covers source
|
||||||
|
# texts, man pages and HTML rendering of man pages, as enabled by tools.
|
||||||
|
doc spellcheck-sortdict \
|
||||||
|
all-docs check-docs \
|
||||||
|
man all-man man-man check-man man-html all-html:
|
||||||
|
cd $(builddir)/docs && $(MAKE) $@
|
||||||
|
|
||||||
|
check-NIT check-NIT-devel:
|
||||||
|
cd $(builddir)/tests/NIT && $(MAKE) $@
|
||||||
|
|
||||||
|
# This target adds syntax-checking for committed shell script files,
|
||||||
|
# to avoid surprises and delays in finding fatal typos after packaging
|
||||||
|
###
|
||||||
|
### Note: currently, shellcheck target calls check-scripts-syntax
|
||||||
|
### so when both are invoked at once, in the end the check is only
|
||||||
|
### executed once. Later it is anticipated that shellcheck would
|
||||||
|
### be implemented by requiring, configuring and calling the tool
|
||||||
|
### named "shellcheck" for even more code inspection and details.
|
||||||
|
### Still, there remains value in also checking the script syntax
|
||||||
|
### by the very version of the shell interpreter that would run
|
||||||
|
### these scripts in production usage of the resulting packages.
|
||||||
|
###
|
||||||
|
check-scripts-syntax:
|
||||||
|
@echo 'NOTE: modern bash complains about scripts using backticks (warning not error), which we ignore in NUT codebase for portability reasons: `...` obsolete, use $$(...)'
|
||||||
|
@RUNBASH=bash; if [ -x /bin/bash ]; then RUNBASH=/bin/bash ; else if [ -x /usr/bin/env ] ; then RUNBASH="/usr/bin/env bash"; fi; fi ; \
|
||||||
|
for F in `git ls-files || find . -type f` ; do \
|
||||||
|
case "`file "$$F"`" in \
|
||||||
|
*"Bourne-Again shell script"*) ( set -x ; $$RUNBASH -n "$$F" ; ) ;; \
|
||||||
|
*"POSIX shell script"*|*"shell script"*) ( set -x ; /bin/sh -n "$$F" ; ) ;; \
|
||||||
|
esac || { RES=$$? ; echo "ERROR: Syntax check failed for script file: $$F" >&2 ; exit $$RES ; } ; \
|
||||||
|
done
|
||||||
|
@echo 'SUCCESS: Shell scripts syntax is acceptable, no fatal issues were found'
|
||||||
|
|
||||||
|
shellcheck-disclaimer:
|
||||||
|
@echo "==============================================================================="
|
||||||
|
@echo "NOTICE: 'make shellcheck' is currently an alias for 'make check-scripts-syntax'"
|
||||||
|
@echo "Later it may become a call to the real shellcheck tool (if available on the"
|
||||||
|
@echo "build system during the configure phase)"
|
||||||
|
@echo "==============================================================================="
|
||||||
|
|
||||||
|
# Note: currently not part of shellcheck target, because the script below
|
||||||
|
# can test the logic with numerous SHELL_PROGS in a CI setting, and because
|
||||||
|
# check-scripts-syntax probably has checked the basic syntax above already.
|
||||||
|
shellcheck-nde:
|
||||||
|
cd $(srcdir)/tests && SERVICE_FRAMEWORK="selftest" ./nut-driver-enumerator-test.sh
|
||||||
|
|
||||||
|
shellcheck: shellcheck-disclaimer check-scripts-syntax
|
||||||
|
|
||||||
|
CPPCHECK = @CPPCHECK@
|
||||||
|
if HAVE_CPPCHECK
|
||||||
|
cppcheck: cppcheck-cxx11.xml cppcheck-c99.xml
|
||||||
|
|
||||||
|
# Let the analysis get regenerated due to any change in source;
|
||||||
|
# but note that with our different make implementations to support,
|
||||||
|
# we can not either $(shell find ...) nor blindly say e.g. *.cpp
|
||||||
|
# for each FS structure layer because e.g. there are no ./*.cpp
|
||||||
|
# in the root dir of the codebase (and so make complains there is
|
||||||
|
# `No rule to make target `*.cpp', needed by `cppcheck-cxx11.xml'`)
|
||||||
|
#
|
||||||
|
# Note that the actual `cppcheck` scan finds all files it likes
|
||||||
|
# (so if CPPCHECK_SRC_* misses something, it just won't trigger
|
||||||
|
# automagically a rebuild of the XML in developer working cycles).
|
||||||
|
CPPCHECK_SRC_H = $(top_srcdir)/*/*.h $(top_srcdir)/*/*/*.h
|
||||||
|
# CPPCHECK_SRC_H += $(top_srcdir)/*.h
|
||||||
|
|
||||||
|
CPPCHECK_SRC_C = $(top_srcdir)/*/*.c $(top_srcdir)/*/*/*.c
|
||||||
|
# CPPCHECK_SRC_C += $(top_srcdir)/*.cpp
|
||||||
|
|
||||||
|
CPPCHECK_SRC_CXX = $(top_srcdir)/*/*.cpp
|
||||||
|
# CPPCHECK_SRC_CXX += $(top_srcdir)/*.cpp $(top_srcdir)/*/*/*.cpp
|
||||||
|
|
||||||
|
cppcheck-cxx11.xml: $(CPPCHECK_SRC_CXX) $(CPPCHECK_SRC_H)
|
||||||
|
$(CPPCHECK) --std=c++11 --enable=all --inconclusive --xml --xml-version=2 . 2>$@
|
||||||
|
|
||||||
|
cppcheck-c99.xml: $(CPPCHECK_SRC_C) $(CPPCHECK_SRC_H)
|
||||||
|
$(CPPCHECK) --std=c99 --enable=all --inconclusive --xml --xml-version=2 . 2>$@
|
||||||
|
else !HAVE_CPPCHECK
|
||||||
|
cppcheck:
|
||||||
|
@echo "CPPCHECK analysis not available since 'cppcheck' was not found."
|
||||||
|
endif !HAVE_CPPCHECK
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Automatically generate the ChangeLog from Git logs:
|
||||||
|
MAINTAINERCLEANFILES += ChangeLog
|
||||||
|
|
||||||
|
# Older boundary of the ChangeLog commits range
|
||||||
|
# It can be a tag ('v2.2.0'), a commit hash, a date, ...
|
||||||
|
# See gitrevisions for more information on specifying ranges
|
||||||
|
GITLOG_START_POINT=v2.6.0
|
||||||
|
|
||||||
|
# Force ChangeLog regeneration upon make dist (due to nonexistant 'dummy-stamp'),
|
||||||
|
# in case it has already been generated previously
|
||||||
|
# Note that the script is hard-coded to generate "ChangeLog" in the current dir
|
||||||
|
dummy-stamp:
|
||||||
|
ChangeLog: tools/gitlog2changelog.py dummy-stamp
|
||||||
|
cd $(top_builddir) && \
|
||||||
|
./tools/gitlog2changelog.py $(GITLOG_START_POINT) || \
|
||||||
|
{ echo "gitlog2changelog.py failed to generate the ChangeLog. See https://github.com/networkupstools/nut/commits/master" > $@ ; }
|
||||||
|
|
||||||
|
nut_version.h include/nut_version.h:
|
||||||
|
cd $(abs_top_builddir)/include && $(MAKE) nut_version.h
|
||||||
|
|
||||||
|
tools/gitlog2changelog.py: tools/gitlog2changelog.py.in
|
||||||
|
cd $(@D) && $(MAKE) -s $(@F)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# Maintainers targets: distribution signature and hashes
|
||||||
|
nut-@PACKAGE_VERSION@.tar.gz: dist
|
||||||
|
nut-@PACKAGE_VERSION@.tar.gz.sig: dist-sig
|
||||||
|
nut-@PACKAGE_VERSION@.tar.gz.md5 nut-@PACKAGE_VERSION@.tar.gz.sha256: dist-hash
|
||||||
|
|
||||||
|
dist-sig: nut-@PACKAGE_VERSION@.tar.gz
|
||||||
|
rm -f nut-@PACKAGE_VERSION@.tar.gz.sig
|
||||||
|
gpg --detach-sign nut-@PACKAGE_VERSION@.tar.gz
|
||||||
|
|
||||||
|
dist-hash: nut-@PACKAGE_VERSION@.tar.gz
|
||||||
|
md5sum nut-@PACKAGE_VERSION@.tar.gz > nut-@PACKAGE_VERSION@.tar.gz.md5
|
||||||
|
sha256sum nut-@PACKAGE_VERSION@.tar.gz > nut-@PACKAGE_VERSION@.tar.gz.sha256
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# targets from old build system (pre-automake).
|
||||||
|
# supported for a period of time for backward "compatibility".
|
||||||
|
|
||||||
|
WARN="----------------------------------------------------------------------"
|
||||||
|
|
||||||
|
build:
|
||||||
|
@echo $(WARN)
|
||||||
|
@echo "Warning: 'make build' is deprecated. Use 'make all' instead."
|
||||||
|
@echo $(WARN)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) all
|
||||||
|
install-bin:
|
||||||
|
@echo $(WARN)
|
||||||
|
@echo "Warning: 'make install-bin' is deprecated."
|
||||||
|
@echo "Use 'make install-exec' instead for a similar effect."
|
||||||
|
@echo $(WARN)
|
||||||
|
cd common; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
cd drivers; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
cd server; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
cd clients; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
install-man: install-data-recursive
|
||||||
|
@echo $(WARN)
|
||||||
|
@echo "Warning: 'make install-man' is deprecated."
|
||||||
|
@echo "Use 'cd man; make install' instead."
|
||||||
|
@echo $(WARN)
|
||||||
|
cd man; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
install-conf:
|
||||||
|
@echo $(WARN)
|
||||||
|
@echo "Warning: 'make install-conf' is deprecated."
|
||||||
|
@echo "Use 'cd conf; make install' instead."
|
||||||
|
@echo $(WARN)
|
||||||
|
cd conf; $(MAKE) $(AM_MAKEFLAGS) install
|
||||||
|
# The target install-data already has a standardized meaning under automake
|
||||||
|
install-dirs:
|
||||||
|
@echo $(WARN)
|
||||||
|
@echo "Warning: 'make install-dirs' is deprecated."
|
||||||
|
@echo "Use 'make installdirs' instead."
|
||||||
|
@echo $(WARN)
|
||||||
|
$(MAKE) installdirs
|
||||||
|
cgi build-cgi install-cgi install-cgi-dir install-cgi-bin \
|
||||||
|
install-cgi-man install-cgi-conf install-cgi-html:
|
||||||
|
@echo "Error: 'make $@' no longer exists."
|
||||||
|
@echo "Use './configure --with-cgi' instead."
|
||||||
|
install-lib:
|
||||||
|
@echo "Error: 'make $@' no longer exists."
|
||||||
|
@echo "Use './configure --with-dev' instead."
|
||||||
|
usb build-usb install-usb:
|
||||||
|
@echo "Error: 'make $@' no longer exists."
|
||||||
|
@echo "Use './configure --with-usb' instead."
|
||||||
|
snmp build-snmp install-snmp install-snmp-mgr install-snmp-man:
|
||||||
|
@echo "Error: 'make $@' no longer exists."
|
||||||
|
@echo "Use './configure --with-snmp' instead."
|
||||||
|
setver:
|
||||||
|
@echo "Error: 'make setver' no longer exists."
|
||||||
|
@echo "Edit configure.ac to set version number."
|
||||||
|
|
||||||
|
# Clean the dist tarball and packages
|
||||||
|
MAINTAINERCLEANFILES_DISTBALL = nut-*.tar.gz
|
||||||
|
# HP-UX:
|
||||||
|
MAINTAINERCLEANFILES_PACKAGES = NUT_HPUX_package@PACKAGE_VERSION@.depot
|
||||||
|
# AIX as below, and RedHat-compatible (cover binary and source packages):
|
||||||
|
MAINTAINERCLEANFILES_PACKAGES += nut*rpm
|
||||||
|
# Debian-compatible (cover binary and source packages):
|
||||||
|
MAINTAINERCLEANFILES_PACKAGES += nut*deb
|
||||||
|
# Solaris SVR4 package archives:
|
||||||
|
MAINTAINERCLEANFILES_PACKAGES += NUT_solaris_*_package@PACKAGE_VERSION@.local.gz
|
||||||
|
# Newer Solaris IPS (aka "pkg(5)" format archives)
|
||||||
|
MAINTAINERCLEANFILES_PACKAGES += *.p5p
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES += $(MAINTAINERCLEANFILES_DISTBALL)
|
||||||
|
MAINTAINERCLEANFILES += $(MAINTAINERCLEANFILES_PACKAGES)
|
||||||
|
|
||||||
|
package: dist
|
||||||
|
DESTDIR="$(abs_builddir)/_install_pkgprotodir" ; export DESTDIR; \
|
||||||
|
rm -rf "$$DESTDIR"; \
|
||||||
|
case "`uname -s`" in \
|
||||||
|
"HP-UX") \
|
||||||
|
( cd scripts/HP-UX && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$DESTDIR" package && \
|
||||||
|
mv NUT_HPUX_package.depot $(abs_top_builddir)/NUT_HPUX_package@PACKAGE_VERSION@.depot ) ;; \
|
||||||
|
"SunOS") \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$DESTDIR" install && \
|
||||||
|
( cd scripts/Solaris && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$DESTDIR" package ) && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$DESTDIR" uninstall && \
|
||||||
|
rm -rf "$$DESTDIR" || \
|
||||||
|
{ echo "FAILED to produce SunOS packages, inspect '$$DESTDIR' for clues" >&2 ; exit 1; } ;; \
|
||||||
|
"AIX") \
|
||||||
|
if test -d /usr/src/packages/SPECS -a -w /usr/src/packages/SPECS ; then : ; else echo "Can not write to /usr/src/packages/SPECS" >&2 ; exit 1; fi ; \
|
||||||
|
if test -d /usr/src/packages/SOURCES -a -w /usr/src/packages/SOURCES ; then : ; else echo "Can not write to /usr/src/packages/SOURCES" >&2 ; exit 1; fi ; \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) dist && \
|
||||||
|
cp scripts/Aix/nut-aix.spec /usr/src/packages/SPECS && \
|
||||||
|
cp scripts/Aix/nut.init nut-@PACKAGE_VERSION@.tar.gz /usr/src/packages/SOURCES && \
|
||||||
|
rpm -ba /usr/src/packages/SPECS/nut-aix.spec && \
|
||||||
|
mv /usr/src/packages/RPMS/nut*rpm $(abs_top_builddir)/ ;; \
|
||||||
|
*) echo "Unsupported OS for 'make $@' (no recipe bound)" >&2; exit 1;; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
print-MAINTAINERCLEANFILES print-REALCLEANFILES:
|
||||||
|
@echo $(MAINTAINERCLEANFILES)
|
||||||
|
|
||||||
|
print-DISTCLEANFILES:
|
||||||
|
@echo $(DISTCLEANFILES)
|
||||||
|
|
||||||
|
# TODO: Recursive mode to consider patterns defined in sub-dir makefiles
|
||||||
|
git-realclean-check:
|
||||||
|
@if test -e .git && (command -v git); then \
|
||||||
|
git status --ignored || while read F ; do \
|
||||||
|
for P in $(MAINTAINERCLEANFILES) ; do \
|
||||||
|
case "$$F" in \
|
||||||
|
*/$$P) exit 1 ;; \
|
||||||
|
esac ; \
|
||||||
|
done; \
|
||||||
|
done ; \
|
||||||
|
fi
|
1286
Makefile.in
Normal file
1286
Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
592
README
Normal file
592
README
Normal file
|
@ -0,0 +1,592 @@
|
||||||
|
Network UPS Tools Overview
|
||||||
|
===========================
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Network UPS Tools is a collection of programs which provide a common
|
||||||
|
interface for monitoring and administering UPS, PDU and SCD hardware.
|
||||||
|
It uses a layered approach to connect all of the parts.
|
||||||
|
|
||||||
|
Drivers are provided for a wide assortment of equipment. They
|
||||||
|
understand the specific language of each device and map it back to a
|
||||||
|
compatibility layer. This means both an expensive high end UPS, a simple
|
||||||
|
"power strip" PDU, or any other power device can be handled transparently with
|
||||||
|
a uniform management interface.
|
||||||
|
|
||||||
|
This information is cached by the network server `upsd`, which then
|
||||||
|
answers queries from the clients. upsd contains a number of access
|
||||||
|
control features to limit the abilities of the clients. Only authorized
|
||||||
|
hosts may monitor or control your hardware if you wish. Since the
|
||||||
|
notion of monitoring over the network is built into the software, you
|
||||||
|
can hang many systems off one large UPS, and they will all shut down
|
||||||
|
together. You can also use NUT to power on, off or cycle your data center
|
||||||
|
nodes, individually or globally through PDU outlets.
|
||||||
|
|
||||||
|
Clients such as `upsmon` check on the status of the hardware and do things
|
||||||
|
when necessary. The most important task is shutting down the operating
|
||||||
|
system cleanly before the UPS runs out of power. Other programs are
|
||||||
|
also provided to log information regularly, monitor status through your
|
||||||
|
web browser, and more.
|
||||||
|
|
||||||
|
|
||||||
|
Installing
|
||||||
|
----------
|
||||||
|
|
||||||
|
If you are installing these programs for the first time, go read the
|
||||||
|
<<_installation_instructions,installation instructions>>
|
||||||
|
to find out how to do that. This document contains more information on what all
|
||||||
|
of this stuff does.
|
||||||
|
|
||||||
|
|
||||||
|
Upgrading
|
||||||
|
---------
|
||||||
|
|
||||||
|
When upgrading from an older version, always check the
|
||||||
|
<<Upgrading_notes,upgrading notes>> to see what may have
|
||||||
|
changed. Compatibility issues and other changes will be listed there to ease
|
||||||
|
the process.
|
||||||
|
|
||||||
|
|
||||||
|
Configuring and using
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Once NUT is installed, refer to the
|
||||||
|
<<Configuration_notes,configuration notes>> for directions.
|
||||||
|
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
This is just an overview of the software. You should read the man pages,
|
||||||
|
included example configuration files, and auxiliary documentation for the parts
|
||||||
|
that you intend to use.
|
||||||
|
|
||||||
|
|
||||||
|
Network Information
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
These programs are designed to share information over the network. In
|
||||||
|
the examples below, `localhost` is used as the hostname. This can also
|
||||||
|
be an IP address or a fully qualified domain name. You can specify a
|
||||||
|
port number if your upsd process runs on another port.
|
||||||
|
|
||||||
|
In the case of the program `upsc`, to view the variables on the UPS called
|
||||||
|
sparky on the `upsd` server running on the local machine, you'd do this:
|
||||||
|
|
||||||
|
/usr/local/ups/bin/upsc sparky@localhost
|
||||||
|
|
||||||
|
The default port number is 3493. You can change this with
|
||||||
|
"configure --with-port" at compile-time. To make a client talk to upsd
|
||||||
|
on a specific port, add it after the hostname with a colon, like this:
|
||||||
|
|
||||||
|
/usr/local/ups/bin/upsc sparky@localhost:1234
|
||||||
|
|
||||||
|
This is handy when you have a mixed environment and some of the systems
|
||||||
|
are on different ports.
|
||||||
|
|
||||||
|
The general form for UPS identifiers is this:
|
||||||
|
|
||||||
|
<upsname>[@<hostname>[:<port>]]
|
||||||
|
|
||||||
|
Keep this in mind when viewing the examples below.
|
||||||
|
|
||||||
|
|
||||||
|
Manifest
|
||||||
|
--------
|
||||||
|
|
||||||
|
This package is broken down into several categories:
|
||||||
|
|
||||||
|
- *drivers* - These programs talk directly to your UPS hardware.
|
||||||
|
- *server* - upsd serves data from the drivers to the network.
|
||||||
|
- *clients* - They talk to upsd and do things with the status data.
|
||||||
|
- *cgi-bin* - Special class of clients that you can use with your web server.
|
||||||
|
- *scripts* - Contains various scripts, like the Perl and Python binding,
|
||||||
|
integration bits and applications.
|
||||||
|
|
||||||
|
Drivers
|
||||||
|
-------
|
||||||
|
|
||||||
|
These programs provide support for specific UPS models. They understand
|
||||||
|
the protocols and port specifications which define status information
|
||||||
|
and convert it to a form that upsd can understand.
|
||||||
|
|
||||||
|
To configure drivers, edit ups.conf. For this example, we'll have a UPS
|
||||||
|
called "sparky" that uses the apcsmart driver and is connected to
|
||||||
|
`/dev/ttyS1`. That's the second serial port on most Linux-based systems.
|
||||||
|
The entry in `ups.conf` looks like this:
|
||||||
|
|
||||||
|
[sparky]
|
||||||
|
driver = apcsmart
|
||||||
|
port = /dev/ttyS1
|
||||||
|
|
||||||
|
To start and stop drivers, use upsdrvctl of upsdrvsvcctl (installed on
|
||||||
|
operating systems with a service management framework supported by NUT).
|
||||||
|
By default, it will start or stop every UPS in the config file:
|
||||||
|
|
||||||
|
/usr/local/ups/sbin/upsdrvctl start
|
||||||
|
/usr/local/ups/sbin/upsdrvctl stop
|
||||||
|
|
||||||
|
However, you can also just start or stop one by adding its name:
|
||||||
|
|
||||||
|
/usr/local/ups/sbin/upsdrvctl start sparky
|
||||||
|
/usr/local/ups/sbin/upsdrvctl stop sparky
|
||||||
|
|
||||||
|
On operating systems with a supported service management framework,
|
||||||
|
you might wrap your NUT drivers into individual services instances
|
||||||
|
with:
|
||||||
|
|
||||||
|
/usr/local/ups/sbin/upsdrvsvcctl resync
|
||||||
|
|
||||||
|
and then manage those service instances with commands like:
|
||||||
|
|
||||||
|
/usr/local/ups/sbin/upsdrvsvcctl start sparky
|
||||||
|
/usr/local/ups/sbin/upsdrvsvcctl stop sparky
|
||||||
|
|
||||||
|
To find the driver name for your device, refer to the section below
|
||||||
|
called "HARDWARE SUPPORT TABLE".
|
||||||
|
|
||||||
|
Extra Settings
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Some drivers may require additional settings to properly communicate
|
||||||
|
with your hardware. If it doesn't detect your UPS by default, check the
|
||||||
|
driver's man page or help (-h) to see which options are available.
|
||||||
|
|
||||||
|
For example, the usbhid-ups driver allows you to use USB serial numbers to
|
||||||
|
distinguish between units via the "serial" configuration option. To use this
|
||||||
|
feature, just add another line to your ups.conf section for that UPS:
|
||||||
|
|
||||||
|
[sparky]
|
||||||
|
driver = usbhid-ups
|
||||||
|
port = auto
|
||||||
|
serial = 1234567890
|
||||||
|
|
||||||
|
Hardware Compatibility List
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The <<HCL,Hardware Compatibility List>> is available in the source directory
|
||||||
|
('nut-X.Y.Z/data/driver.list'), and is generally distributed with packages.
|
||||||
|
For example, it is available on Debian systems as:
|
||||||
|
|
||||||
|
/usr/share/nut/driver.list
|
||||||
|
|
||||||
|
This table is also available link:http://www.networkupstools.org/stable-hcl.html[online].
|
||||||
|
|
||||||
|
|
||||||
|
If your driver has vanished, see the link:FAQ.html[FAQ] and
|
||||||
|
<<Upgrading_notes,Upgrading notes>>.
|
||||||
|
|
||||||
|
Generic Device Drivers
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
NUT provides several generic drivers that support a variety of very similar models.
|
||||||
|
|
||||||
|
- The `genericups` driver supports many serial models that use the same basic
|
||||||
|
principle to communicate with the computer. This is known as "contact
|
||||||
|
closure", and basically involves raising or lowering signals to indicate
|
||||||
|
power status.
|
||||||
|
+
|
||||||
|
This type of UPS tends to be cheaper, and only provides the very simplest
|
||||||
|
data about power and battery status. Advanced features like battery
|
||||||
|
charge readings and such require a "smart" UPS and a driver which
|
||||||
|
supports it.
|
||||||
|
+
|
||||||
|
See the linkman:genericups[8] man page for more information.
|
||||||
|
|
||||||
|
- The `usbhid-ups` driver attempts to communicate with USB HID Power Device
|
||||||
|
Class (PDC) UPSes. These units generally implement the same basic protocol,
|
||||||
|
with minor variations in the exact set of supported attributes. This driver
|
||||||
|
also applies several correction factors when the UPS firmware reports values
|
||||||
|
with incorrect scale factors.
|
||||||
|
+
|
||||||
|
See the linkman:usbhid-ups[8] man page for more information.
|
||||||
|
|
||||||
|
- The `blazer_ser` and `blazer_usb` drivers supports the Megatec / Q1
|
||||||
|
protocol that is used in many brands (Blazer, Energy Sistem, Fenton
|
||||||
|
Technologies, Mustek and many others).
|
||||||
|
+
|
||||||
|
See the linkman:blazer[8] man page for more information.
|
||||||
|
|
||||||
|
- The `snmp-ups` driver handles various SNMP enabled devices, from many
|
||||||
|
different manufacturers. In SNMP terms, `snmp-ups` is a manager, that
|
||||||
|
monitors SNMP agents.
|
||||||
|
+
|
||||||
|
See the linkman:snmp-ups[8] man page for more information.
|
||||||
|
|
||||||
|
- The `powerman-pdu` is a bridge to the PowerMan daemon, thus handling all
|
||||||
|
PowerMan supported devices. The PowerMan project supports several serial
|
||||||
|
and networked PDU, along with Blade and IPMI enabled servers.
|
||||||
|
+
|
||||||
|
See the linkman:powerman-pdu[8] man page for more
|
||||||
|
information.
|
||||||
|
|
||||||
|
- The `apcupsd-ups` driver is a bridge to the Apcupsd daemon, thus handling
|
||||||
|
all Apcupsd supported devices. The Apcupsd project supports many serial,
|
||||||
|
USB and networked APC UPS.
|
||||||
|
+
|
||||||
|
See the linkman:apcupsd-ups[8] man page for more information.
|
||||||
|
|
||||||
|
UPS Shutdowns
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
upsdrvctl can also shut down (power down) all of your UPS hardware.
|
||||||
|
|
||||||
|
WARNING: if you play around with this command, expect your filesystems
|
||||||
|
to die. Don't power off your computers unless they're ready for it:
|
||||||
|
|
||||||
|
/usr/local/ups/sbin/upsdrvctl shutdown
|
||||||
|
/usr/local/ups/sbin/upsdrvctl shutdown sparky
|
||||||
|
|
||||||
|
You should read the <<UPS_shutdown,Configuring automatic UPS shutdowns>>
|
||||||
|
chapter to learn more about when to use this feature. If called at the wrong
|
||||||
|
time, you may cause data loss by turning off a system with a filesystem
|
||||||
|
mounted read-write.
|
||||||
|
|
||||||
|
Power distribution unit management
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
NUT also provides an advanced support for power distribution units.
|
||||||
|
|
||||||
|
You should read the <<outlet_management,NUT outlets management and PDU notes>>
|
||||||
|
chapter to learn more about when to use this feature.
|
||||||
|
|
||||||
|
Network Server
|
||||||
|
--------------
|
||||||
|
|
||||||
|
`upsd` is responsible for passing data from the drivers to the client
|
||||||
|
programs via the network. It should be run immediately after `upsdrvctl`
|
||||||
|
in your system's startup scripts.
|
||||||
|
|
||||||
|
`upsd` should be kept running whenever possible, as it is the only source
|
||||||
|
of status information for the monitoring clients like `upsmon`.
|
||||||
|
|
||||||
|
|
||||||
|
Monitoring client
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
`upsmon` provides the essential feature that you expect to find in UPS
|
||||||
|
monitoring software: safe shutdowns when the power fails.
|
||||||
|
|
||||||
|
In the layered scheme of NUT software, it is a client. It has this
|
||||||
|
separate section in the documentation since it is so important.
|
||||||
|
|
||||||
|
You configure it by telling it about UPSes that you want to monitor in
|
||||||
|
upsmon.conf. Each UPS can be defined as one of two possible types:
|
||||||
|
a "primary" or "secondary".
|
||||||
|
|
||||||
|
Primary
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
The monitored UPS possibly supplies power to this system running `upsmon`,
|
||||||
|
but more importantly -- this system can manage the UPS (typically, this
|
||||||
|
instance of `upsmon` runs on the same system as the `upsd` and driver(s)):
|
||||||
|
it is capable and responsible for shutting it down when the battery is
|
||||||
|
depleted (or in another approach, lingering to deplete it or to tell the
|
||||||
|
UPS to reboot its load after too much time has elapsed and this system
|
||||||
|
is still alive -- meaning wall power returned at a "wrong" moment).
|
||||||
|
|
||||||
|
The shutdown of this (primary) system itself, as well as eventually an
|
||||||
|
UPS shutdown, occurs after any secondary systems ordered to shut down
|
||||||
|
first have disconnected, or a critical urgency threshold was passed.
|
||||||
|
|
||||||
|
If your UPS is plugged directly into a system's serial or USB port, the
|
||||||
|
`upsmon` process on that system should define its relation to that UPS
|
||||||
|
as a primary. It may be more complicated for higher-end UPSes with a
|
||||||
|
shared network management capability (typically via SNMP) or several
|
||||||
|
serial/USB ports that can be used simultaneously, and depends on what
|
||||||
|
vendors and drivers implement. Setups with several competing primaries
|
||||||
|
(for redundancy) are technically possible, if each one runs its own
|
||||||
|
full stack of NUT, but results can be random (currently NUT does not
|
||||||
|
provide a way to coordinate several entities managing the same device).
|
||||||
|
|
||||||
|
For a typical home user, there's one computer connected to one UPS.
|
||||||
|
That means you would run on the same computer the whole NUT stack --
|
||||||
|
a suitable driver, `upsd`, and `upsmon` in primary mode.
|
||||||
|
|
||||||
|
Secondary
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
The monitored UPS may supply power to the system running `upsmon` (or
|
||||||
|
alternatively, it may be a monitoring station with zero PSUs fed by
|
||||||
|
that UPS), but more importantly, this system can't manage the UPS --
|
||||||
|
e.g. shut it down directly (through a locally running NUT driver).
|
||||||
|
|
||||||
|
Use this mode when you run multiple computers on the same UPS.
|
||||||
|
Obviously, only one can be connected to the serial or USB port
|
||||||
|
on a typical UPS, and that system is the primary. Everything
|
||||||
|
else is a secondary.
|
||||||
|
|
||||||
|
For a typical home user, there's one computer connected to one UPS.
|
||||||
|
That means you run a driver, `upsd`, and `upsmon` in primary mode.
|
||||||
|
|
||||||
|
Additional Information
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
More information on configuring upsmon can be found in these places:
|
||||||
|
|
||||||
|
- The linkman:upsmon[8] man page
|
||||||
|
- <<BigServers,Typical setups for big servers>>
|
||||||
|
- <<UPS_shutdown,Configuring automatic UPS shutdowns>> chapter
|
||||||
|
- The stock `upsmon.conf` that comes with the package
|
||||||
|
|
||||||
|
|
||||||
|
Clients
|
||||||
|
-------
|
||||||
|
|
||||||
|
Clients talk to upsd over the network and do useful things with the data
|
||||||
|
from the drivers. There are tools for command line access, and a few
|
||||||
|
special clients which can be run through your web server as CGI
|
||||||
|
programs.
|
||||||
|
|
||||||
|
For more details on specific programs, refer to their man pages.
|
||||||
|
|
||||||
|
upsc
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
`upsc` is a simple client that will display the values of variables known
|
||||||
|
to `upsd` and your UPS drivers. It will list every variable by default,
|
||||||
|
or just one if you specify an additional argument. This can be useful
|
||||||
|
in shell scripts for monitoring something without writing your own
|
||||||
|
network code.
|
||||||
|
|
||||||
|
`upsc` is a quick way to find out if your driver(s) and upsd are working
|
||||||
|
together properly. Just run `upsc <ups>` to see what's going on, i.e.:
|
||||||
|
|
||||||
|
morbo:~$ upsc sparky@localhost
|
||||||
|
ambient.humidity: 035.6
|
||||||
|
ambient.humidity.alarm.maximum: NO,NO
|
||||||
|
ambient.humidity.alarm.minimum: NO,NO
|
||||||
|
ambient.temperature: 25.14
|
||||||
|
...
|
||||||
|
|
||||||
|
If you are interested in writing a simple client that monitors `upsd`,
|
||||||
|
the source code for `upsc` is a good way to learn about using the
|
||||||
|
upsclient functions.
|
||||||
|
|
||||||
|
See the linkman:upsc[8] man page and
|
||||||
|
<<nut-names,NUT command and variable naming scheme>> for more information.
|
||||||
|
|
||||||
|
upslog
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
`upslog` will write status information from `upsd` to a file at set
|
||||||
|
intervals. You can use this to generate graphs or reports with other
|
||||||
|
programs such as `gnuplot`.
|
||||||
|
|
||||||
|
upsrw
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
`upsrw` allows you to display and change the read/write variables in your
|
||||||
|
UPS hardware. Not all devices or drivers implement this, so this may
|
||||||
|
not have any effect on your system.
|
||||||
|
|
||||||
|
A driver that supports read/write variables will give results like this:
|
||||||
|
|
||||||
|
$ upsrw sparky@localhost
|
||||||
|
|
||||||
|
( many skipped )
|
||||||
|
|
||||||
|
[ups.test.interval]
|
||||||
|
Interval between self tests
|
||||||
|
Type: ENUM
|
||||||
|
Option: "1209600"
|
||||||
|
Option: "604800" SELECTED
|
||||||
|
Option: "0"
|
||||||
|
|
||||||
|
( more skipped )
|
||||||
|
|
||||||
|
On the other hand, one that doesn't support them won't print anything:
|
||||||
|
|
||||||
|
$ upsrw fenton@gearbox
|
||||||
|
|
||||||
|
( nothing )
|
||||||
|
|
||||||
|
`upsrw` requires administrator powers to change settings in the hardware.
|
||||||
|
Refer to linkman:upsd.users[5] for information on defining
|
||||||
|
users in `upsd`.
|
||||||
|
|
||||||
|
upscmd
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
Some UPS hardware and drivers support the notion of an instant command -
|
||||||
|
a feature such as starting a battery test, or powering off the load.
|
||||||
|
You can use upscmd to list or invoke instant commands if your
|
||||||
|
hardware/drivers support them.
|
||||||
|
|
||||||
|
Use the -l command to list them, like this:
|
||||||
|
|
||||||
|
$ upscmd -l sparky@localhost
|
||||||
|
Instant commands supported on UPS [sparky@localhost]:
|
||||||
|
|
||||||
|
load.on - Turn on the load immediately
|
||||||
|
test.panel.start - Start testing the UPS panel
|
||||||
|
calibrate.start - Start run time calibration
|
||||||
|
calibrate.stop - Stop run time calibration
|
||||||
|
...
|
||||||
|
|
||||||
|
`upscmd` requires administrator powers to start instant commands.
|
||||||
|
To define users and passwords in `upsd`, see
|
||||||
|
linkman:upsd.users[5].
|
||||||
|
|
||||||
|
|
||||||
|
CGI Programs
|
||||||
|
------------
|
||||||
|
|
||||||
|
The CGI programs are clients that run through your web server. They
|
||||||
|
allow you to see UPS status and perform certain administrative commands
|
||||||
|
from any web browser. Javascript and cookies are not required.
|
||||||
|
|
||||||
|
These programs are not installed or compiled by default. To compile
|
||||||
|
and install them, first run `configure --with-cgi`, then do `make` and
|
||||||
|
`make install`. If you receive errors about "gd" during configure, go
|
||||||
|
get it and install it before continuing.
|
||||||
|
|
||||||
|
You can get the source here:
|
||||||
|
|
||||||
|
http://www.libgd.org/
|
||||||
|
|
||||||
|
In the event that you need libpng or zlib in order to compile gd,
|
||||||
|
they can be found at these URLs:
|
||||||
|
|
||||||
|
http://www.libpng.org/pub/png/pngcode.html
|
||||||
|
|
||||||
|
http://www.gzip.org/zlib/
|
||||||
|
|
||||||
|
|
||||||
|
Access Restrictions
|
||||||
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The CGI programs use hosts.conf to see if they are allowed to talk to a
|
||||||
|
host. This keeps malicious visitors from creating queries from your web
|
||||||
|
server to random hosts on the Internet.
|
||||||
|
|
||||||
|
If you get error messages that say "Access to that host is not
|
||||||
|
authorized", you're probably missing an entry in your hosts.conf.
|
||||||
|
|
||||||
|
upsstats
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
`upsstats` generates web pages from HTML templates, and plugs in status
|
||||||
|
information in the right places. It looks like a distant relative of
|
||||||
|
APC's old Powerchute interface. You can use it to monitor several
|
||||||
|
systems or just focus on one.
|
||||||
|
|
||||||
|
It also can generate IMG references to `upsimage`.
|
||||||
|
|
||||||
|
upsimage
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
This is usually called by upsstats via IMG SRC tags to draw either the
|
||||||
|
utility or outgoing voltage, battery charge percent, or load percent.
|
||||||
|
|
||||||
|
upsset
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
`upsset` provides several useful administration functions through a web
|
||||||
|
interface. You can use `upsset` to kick off instant commands on your UPS
|
||||||
|
hardware like running a battery test. You can also use it to change
|
||||||
|
variables in your UPS that accept user-specified values.
|
||||||
|
|
||||||
|
Essentially, `upsset` provides the functions of `upsrw` and `upscmd`, but
|
||||||
|
with a happy pointy-clicky interface.
|
||||||
|
|
||||||
|
`upsset` will not run until you convince it that you have secured your
|
||||||
|
system. You *must* secure your CGI path so that random interlopers
|
||||||
|
can't run this program remotely. See the `upsset.conf` file. Once you
|
||||||
|
have secured the directory, you can enable this program in that
|
||||||
|
configuration file. It is not active by default.
|
||||||
|
|
||||||
|
|
||||||
|
Version Numbering
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The version numbers work like this: if the middle number is odd, it's a
|
||||||
|
development tree, otherwise it is the stable tree.
|
||||||
|
|
||||||
|
The past stable trees were 1.0, 1.2, 1.4, 2.0, 2.2 and 2.4, with the
|
||||||
|
latest stable tree designated 2.6. The development trees were 1.1, 1.3,
|
||||||
|
1.5, 2.1 and 2.3. As of the 2.4 release, there is no real development
|
||||||
|
branch anymore since the code is available through a revision control
|
||||||
|
system (namely Subversion) and snapshots. Since 2.7 line of releases,
|
||||||
|
sources are tracked in Git revision control system, with the project
|
||||||
|
ecosystem being hosted on GitHub, and improvements or other contributions
|
||||||
|
merged through common pull request approach and custom NUT CI testing
|
||||||
|
on multiple platforms.
|
||||||
|
|
||||||
|
Major release jumps are mostly due to large changes to the features
|
||||||
|
list. There have also been a number of architectural changes which
|
||||||
|
may not be noticeable to most users, but which can impact developers.
|
||||||
|
|
||||||
|
|
||||||
|
Backwards and Forwards Compatibility
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
The old network code spans a range from about 0.41.1 when TCP support
|
||||||
|
was introduced up to the recent 1.4 series. It used variable names
|
||||||
|
like STATUS, UTILITY, and LOADPCT. Many of these names go back to the
|
||||||
|
earliest prototypes of this software from 1997. At that point there
|
||||||
|
was no way to know that so many drivers would come along and introduce
|
||||||
|
so many new variables and commands. The resulting mess grew out of
|
||||||
|
control over the years.
|
||||||
|
|
||||||
|
During the 1.3 development cycle, all variables and instant commands
|
||||||
|
were renamed to fit into a tree-like structure. There are major groups,
|
||||||
|
like input, output and battery. Members of those groups have been
|
||||||
|
arranged to make sense - input.voltage and output.voltage compliment
|
||||||
|
each other. The old names were UTILITY and OUTVOLT. The benefits in
|
||||||
|
this change are obvious.
|
||||||
|
|
||||||
|
The 1.4 clients can talk to either type of server, and can handle either
|
||||||
|
naming scheme. 1.4 servers have a compatibility mode where they can
|
||||||
|
answer queries for both names, even though the drivers are internally
|
||||||
|
using the new format.
|
||||||
|
|
||||||
|
When 1.4 clients talk to 1.4 or 2.0 (or more recent) servers, they will
|
||||||
|
use the new names.
|
||||||
|
|
||||||
|
Here's a table to make it easier to visualize:
|
||||||
|
|
||||||
|
[options="header"]
|
||||||
|
|=============================================
|
||||||
|
| 4+| Server version
|
||||||
|
| *Client version* | 1.0 | 1.2 | 1.4 | 2.0+
|
||||||
|
| 1.0 | yes | yes | yes | no
|
||||||
|
| 1.2 | yes | yes | yes | no
|
||||||
|
| 1.4 | yes | yes | yes | yes
|
||||||
|
| 2.0+ | no | no | yes | yes
|
||||||
|
|=============================================
|
||||||
|
|
||||||
|
Version 2.0, and more recent, do not contain backwards compatibility for
|
||||||
|
the old protocol and variable/command names. As a result, 2.0 clients can't
|
||||||
|
talk to anything older than a 1.4 server. If you ask a 2.0 client to
|
||||||
|
fetch "STATUS", it will fail. You'll have to ask for "ups.status"
|
||||||
|
instead.
|
||||||
|
|
||||||
|
Authors of separate monitoring programs should have used the 1.4 series
|
||||||
|
to write support for the new variables and command names. Client
|
||||||
|
software can easily support both versions as long as they like. If upsd
|
||||||
|
returns 'ERR UNKNOWN-COMMAND' to a GET request, you need to use REQ.
|
||||||
|
|
||||||
|
|
||||||
|
Support / Help / etc.
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
If you are in need of help, refer to the
|
||||||
|
<<Support_Request,Support instructions>> in the user manual.
|
||||||
|
|
||||||
|
|
||||||
|
Hacking / Development Info
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Additional documentation can be found in:
|
||||||
|
|
||||||
|
- the linkdoc:developer-guide[Developer Guide],
|
||||||
|
- the linkdoc:packager-guide[Packager Guide].
|
||||||
|
|
||||||
|
|
||||||
|
Acknowledgements / Contributions
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
The many people who have participated in creating and improving NUT are
|
||||||
|
listed in the user manual <<Acknowledgements,acknowledgements appendix>>.
|
118
TODO
Normal file
118
TODO
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
NUT roadmap and ideas for future expansion
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
Here are some ideas that have come up over the years but haven't
|
||||||
|
been implemented yet. This may be a good place to start if you're
|
||||||
|
looking for a rainy day hacking project.
|
||||||
|
|
||||||
|
|
||||||
|
Roadmap
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
2.6
|
||||||
|
^^^
|
||||||
|
|
||||||
|
This release is focused on the website and documentation rewrite, using
|
||||||
|
the excellent link:https://asciidoc.org/[AsciiDoc].
|
||||||
|
|
||||||
|
2.8
|
||||||
|
^^^
|
||||||
|
|
||||||
|
This branch will focus on configuration and user interface improvements.
|
||||||
|
|
||||||
|
3.0
|
||||||
|
^^^
|
||||||
|
|
||||||
|
This major transition will mark the final switch to a complete power
|
||||||
|
device broker.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Non-network "upsmon"
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Some systems don't want a daemon listening to the network. This can be
|
||||||
|
for security reasons, or perhaps because the system has been squashed
|
||||||
|
down and doesn't have TCP/IP available. For these situations you could
|
||||||
|
run a driver and program that sits on top of the driver socket to do
|
||||||
|
local monitoring.
|
||||||
|
|
||||||
|
This also makes monitoring extremely easy to automate - you don't need
|
||||||
|
to worry about usernames, passwords or firewalling. Just start a driver
|
||||||
|
and drop this program on top of it.
|
||||||
|
|
||||||
|
- Parse ups.conf and open the state socket for a driver
|
||||||
|
- Send DUMPALL and enter a select loop
|
||||||
|
- Parse SETINFOs that change ups.status
|
||||||
|
- When you get OB LB, shut down
|
||||||
|
|
||||||
|
Completely unprivileged upsmon
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
upsmon currently retains root in a forked process so it can call the
|
||||||
|
shutdown command. The only reason it needs root on most systems is that
|
||||||
|
only privileged users can signal init or send a message on /dev/initctl.
|
||||||
|
|
||||||
|
In the case of systems running sysvinit (Slackware, others?), upsmon
|
||||||
|
could just open /dev/initctl while it has root and then drop it
|
||||||
|
completely. When it's time to shut down, fire a control structure at
|
||||||
|
init across the lingering socket and tell it to enter runlevel 0.
|
||||||
|
|
||||||
|
This has been shown to work in local tests, but it's not portable. It
|
||||||
|
could only be offered as an option for those systems which run that
|
||||||
|
flavor of init. It also needs to be tested to see what happens to
|
||||||
|
the lingering fd over time, such as when init restarts after an upgrade.
|
||||||
|
|
||||||
|
For other systems, there is always the possibility of having a suid
|
||||||
|
program which does nothing but prod init into starting a shutdown. Lock
|
||||||
|
down the group access so only upsmon's unprivileged user can access it,
|
||||||
|
and make that your SHUTDOWNCMD. Then it could drop root completely.
|
||||||
|
|
||||||
|
Chrooted upsmon
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
upsmon could run the network monitoring part in a chroot jail if it had
|
||||||
|
a pipe to another process running outside for NOTIFY dispatches. Such a
|
||||||
|
pipe would have to be constructed extremely carefully so an attacker
|
||||||
|
could not compromise it from the jailed process.
|
||||||
|
|
||||||
|
A state machine with a tightly defined sequence could do this safely.
|
||||||
|
All it has to do is dispatch the UPS name and event type.
|
||||||
|
|
||||||
|
[start] [type] [length] <name> [stop]
|
||||||
|
|
||||||
|
Monitor program with interpreted language
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Once in awhile, I get requests for a way to shut down based on the UPS
|
||||||
|
temperature, or ambient humidity, or at a certain battery charge level,
|
||||||
|
or any number of things other than an "OB LB" status. It should be
|
||||||
|
obvious that adding a way to monitor all of that in upsmon would bloat
|
||||||
|
upsmon for all those people who really don't need anything like that.
|
||||||
|
|
||||||
|
A separate program that interprets a list of rules and uses it to
|
||||||
|
monitor the UPS equipment is the way to solve this. If you have a
|
||||||
|
condition that needs to be tested, add a rule.
|
||||||
|
|
||||||
|
Some of the tools that such a language would need include simple
|
||||||
|
greater-than/less-than testing (if battery.charge < 20), equivalence
|
||||||
|
testing (if ups.model = "SMART-UPS 700"), and some way to set and clear
|
||||||
|
timers.
|
||||||
|
|
||||||
|
Due to the expected size and limited audience for such a program, it
|
||||||
|
might have to be distributed separately.
|
||||||
|
|
||||||
|
NOTE: Python may be a good candidate.
|
||||||
|
|
||||||
|
Sandbox
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- check to refresh and integrate the https://alioth.debian.org/pm/?group_id=30602[tasks] list
|
||||||
|
and https://alioth.debian.org/tracker/?atid=411545&group_id=30602&func=browse[feature requests] list from Alioth
|
||||||
|
- add "Generic ?Ascii? driver": I've got to think more about that, but the recent
|
||||||
|
solar panel driver, and the powerman internal approach of a generic engine with
|
||||||
|
a scripting interface is a cool idea.
|
||||||
|
Ref http://powerman.svn.sourceforge.net/viewvc/powerman/trunk/etc/apcpdu.dev?revision=969&view=markup
|
||||||
|
- integrate the (future) new powerman LUA engine (maybe/must-be used for the driver above?)
|
||||||
|
for native PDU support
|
||||||
|
- see how we can help and collaborate with DeviceKit-power
|
432
UPGRADING
Normal file
432
UPGRADING
Normal file
|
@ -0,0 +1,432 @@
|
||||||
|
ifdef::txt[]
|
||||||
|
Upgrading notes
|
||||||
|
===============
|
||||||
|
endif::txt[]
|
||||||
|
|
||||||
|
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.7.4 to 2.8.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- Note to distribution packagers: this version hopefully learns from many
|
||||||
|
past mistakes, so many custom patches may be no longer needed. If some
|
||||||
|
remain, please consider making pull requests for upstream NUT codebase
|
||||||
|
to share the fixes consistently across the ecosystem. Also note that
|
||||||
|
some new types of drivers (so package groups with unique dependencies)
|
||||||
|
could have appeared since your packaging was written (e.g. with modbus),
|
||||||
|
as well as new features in systemd integration (`nut-driver@instances`
|
||||||
|
and the `nut-driver-enumerator` to manage their population), as well as
|
||||||
|
updated Python 2 and Python 3 support (again, maybe dictating different
|
||||||
|
package groups) as detailed below.
|
||||||
|
|
||||||
|
- Due to changes needed to resolve build warnings, mostly about mismatching
|
||||||
|
data types for some variables, some structure definitions and API signatures
|
||||||
|
of several routines had to be changed for argument types, return types,
|
||||||
|
or both. Primarily this change concerns internal implementation details
|
||||||
|
(may impact update of NUT forks with custom drivers using those), but a
|
||||||
|
few changes also happened in header files installed for builds configured
|
||||||
|
`--with-dev` and so may impact `upsclient` and `nutclient` (C++) consumers.
|
||||||
|
At the very least, binaries for those consumers should be rebuilt to remain
|
||||||
|
stable with NUT 2.8.0 and not mismatch int-type sizes and other arguments.
|
||||||
|
|
||||||
|
- libusb-1.0: NUT now defaults to building against libusb-1.0 API version
|
||||||
|
if the configure script finds the development headers, falling back to
|
||||||
|
libusb-0.1 if not. Please report any regressions.
|
||||||
|
|
||||||
|
- apcupsd-ups: When monitoring a remote apcupsd server, interpret "SHUTTING
|
||||||
|
DOWN" as a NUT "LB" status. If you were relying on the previous behavior
|
||||||
|
(for instance, in a monitor-only situation), please adjust your upsmon
|
||||||
|
settings. Reference: https://github.com/networkupstools/nut/issues/460
|
||||||
|
|
||||||
|
- Packagers: the AsciiDoc detection has been reworked to allow NUT to be built
|
||||||
|
from source without requiring asciidoc/a2x (using pre-built man pages from
|
||||||
|
the distribution tarball, for instance). Please double-check that we did not
|
||||||
|
break anything (see docs/configure.txt for options).
|
||||||
|
|
||||||
|
- Driver core: options added for standalone mode (scanning for devices without
|
||||||
|
requiring ups.conf) - see docs/man/nutupsdrv.txt for details.
|
||||||
|
|
||||||
|
- oldmge-shut has been removed, and replaced by mge-shut.
|
||||||
|
|
||||||
|
- New drivers for devices with "Qx" (also known as "Megatec Q*") family of
|
||||||
|
protocols should be developed as sub-drivers in the `nutdrv_qx` framework
|
||||||
|
for USB and Serial connected devices, not as updates/clones of older e.g.
|
||||||
|
`blazer` family and `bestups`. Sources, man pages and start-up messages
|
||||||
|
of such older drivers were marked with "OBSOLETION WARNING".
|
||||||
|
|
||||||
|
- liebert-esp2: some multi-phase variable names have been updated to match the
|
||||||
|
rest of NUT.
|
||||||
|
|
||||||
|
- netxml-ups: if you have old firmware, or were relying on values being off by
|
||||||
|
a factor of 10, consider the `do_convert_deci` flag. See
|
||||||
|
docs/man/netxml-ups.txt for details.
|
||||||
|
|
||||||
|
- snmp-ups: detection of Net-SNMP has been updated to use `pkg-config` by
|
||||||
|
default (if present), rather than `net-snmp-config(-32|-64)` script(s) as
|
||||||
|
the only option available previously. The scripts tend to specify a lot
|
||||||
|
of options (sometimes platform-specific) in suggested `CFLAGS` and `LIBS`
|
||||||
|
compared to the packaged `pkg-config` information which also works and is
|
||||||
|
more portable. If this change bites your distribution, please bring it up
|
||||||
|
in https://github.com/networkupstools/nut/issues or better yet, post a PR.
|
||||||
|
Also note that `./configure --with-netsnmp-config(=yes)` should set up the
|
||||||
|
preference of the detected script over `pkg-config` information, if both
|
||||||
|
are available, and `--with-netsnmp-config=/path/name` would as well.
|
||||||
|
|
||||||
|
- snmp-ups: bit mask values for flags in earlier codebase were defined in a
|
||||||
|
way that caused logically different items to have same numeric values.
|
||||||
|
This was fixed to surely use different definitions (so changing numbers
|
||||||
|
behind some of those macro symbols), and testing with UPS, ePDU and ATS
|
||||||
|
hardware which was available did not expose any practical differences.
|
||||||
|
|
||||||
|
- usbhid-ups: numeric data conversion from wire protocol to CPU representation
|
||||||
|
in GetValue() was completely reworked, aiming to be correct on all CPU types.
|
||||||
|
That said, regressions are possible and feedback is welcome.
|
||||||
|
|
||||||
|
- nut-scanner: Packagers, take note of the changes to the library
|
||||||
|
search code in common/common.c. Please file an issue if this does not work
|
||||||
|
with your platform.
|
||||||
|
|
||||||
|
- dummy-ups can now specify `mode` as a driver argument, and separates the
|
||||||
|
notion of `dummy-once` (new default for `*.dev` files that do not change)
|
||||||
|
vs. `dummy-loop` (legacy default for `*.seq` and others) [issue #1385]
|
||||||
|
|
||||||
|
* Note this can break third-party test scripts which expected `*.dev`
|
||||||
|
files to work as a looping sequence with a `TIMER` keywords to change
|
||||||
|
values slowly; now such files should get processed to the end once.
|
||||||
|
Specify `mode=dummy-loop` driver option or rename the data file used
|
||||||
|
in the `port` option for legacy behavior.
|
||||||
|
Use/Test-cases which modified such files content externally should
|
||||||
|
not be impacted.
|
||||||
|
|
||||||
|
- Python: scripts have been updated to work with Python 3 as well as 2.
|
||||||
|
|
||||||
|
* PyNUT module (protocol binding) supports both Python generations.
|
||||||
|
|
||||||
|
* NUT-Monitor (desktop UI client) got separated into two projects:
|
||||||
|
one with support for Python2 and GTK2, and another for Python3 and Qt5.
|
||||||
|
On operating systems that serve both environments, either of these
|
||||||
|
implementation should be usable. For distributions that deprecated
|
||||||
|
and removed Python2 support, it is a point to consider in NUT packages
|
||||||
|
and their build-time and installation dependencies.
|
||||||
|
The historic filenames for desktop integration (`NUT-Monitor` script
|
||||||
|
and `nut-monitor.desktop`) are still delivered, but now cover a wrapper
|
||||||
|
script which detects the environment capabilities and launches the best
|
||||||
|
suitable UI implementation (if both are available).
|
||||||
|
|
||||||
|
- apcsmart: updates to CS "hack" (see docs/man/apcsmart.txt for details)
|
||||||
|
|
||||||
|
- upsdebugx(): added `[D#]` prefix to log entries with level > 0
|
||||||
|
so if any scripts or other tools relied on parsing those messages
|
||||||
|
making some assumptions, they should be updated
|
||||||
|
|
||||||
|
- upsdebugx() and related methods are now macros, optionally calling similarly
|
||||||
|
named implementations like s_upsdebugx() as a slight optimization; this may
|
||||||
|
show up in linking of binaries for some customized build scenarios
|
||||||
|
|
||||||
|
- libraries, tools and protocol now support a `TRACKING` ID to be used with
|
||||||
|
an `INSTCMD` or `SET VAR` requests; for details see docs/net-protocol.txt
|
||||||
|
and docs/sock-protocol.txt
|
||||||
|
|
||||||
|
- upsrw: display the variable type beside ENUM / RANGE
|
||||||
|
|
||||||
|
- Augeas: new `--with-augeas-lenses-dir` configure option.
|
||||||
|
|
||||||
|
Changes from 2.7.3 to 2.7.4
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- scripts/systemd/nut-server.service.in: Restore systemd relationship since it
|
||||||
|
was preventing upsd from starting whenever one or more drivers, among several,
|
||||||
|
was failing to start
|
||||||
|
|
||||||
|
- Fix UPower device matching for recent kernels, since hiddev* devices now have
|
||||||
|
class "usbmisc", rather than "usb"
|
||||||
|
|
||||||
|
- macosx-ups: the "port" driver option no longer has any effect
|
||||||
|
|
||||||
|
- Network protocol information: default to type NUMBER for variables that are
|
||||||
|
not flagged as STRING . This point is subject to improvements or change in
|
||||||
|
the next release 2.7.5. Refer to docs/net-protocol.txt for more information
|
||||||
|
|
||||||
|
Changes from 2.7.2 to 2.7.3
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The linkman:nutdrv_qx[8] driver will eventually supersede linkman:bestups[8].
|
||||||
|
It has been tested on a U-series Patriot Pro II. Please test the new driver
|
||||||
|
on your hardware during your next maintenance window, and report any bugs.
|
||||||
|
|
||||||
|
- If you are upgrading from a new install of 2.7.1 or 2.7.2, double-check the
|
||||||
|
value of POWERDOWNFLAG in $prefix/etc/upsmon.conf - it has been restored to
|
||||||
|
/etc/killpower as in 2.6.5 and earlier.
|
||||||
|
|
||||||
|
- If you use upslog with a large sleep value, you may be interested in adding
|
||||||
|
`killall -SIGUSR1 upslog` to any OB/OL script actions. This will force
|
||||||
|
upslog to write a log entry to catch short power transients.
|
||||||
|
|
||||||
|
- Be sure that your SSL keys are readable by the NUT system user. The SSL
|
||||||
|
subsystem is now initialized after `upsd` forks, to work around issues in the
|
||||||
|
NSS library.
|
||||||
|
|
||||||
|
- The systemd nut-server.service does not Require nut-driver to be started
|
||||||
|
successfully. This was previously preventing upsd startup, even for just
|
||||||
|
one driver failure among many. This also matches the behavior of sysV
|
||||||
|
initscripts.
|
||||||
|
|
||||||
|
Changes from 2.7.1 to 2.7.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- upsdrvctl is now installed to $prefix/sbin rather than $driverexec.
|
||||||
|
This usually means moving from /bin to /sbin, apart from few exceptions.
|
||||||
|
In all cases, please adapt your scripts.
|
||||||
|
|
||||||
|
- FreeDesktop Hardware Abstraction Layer (HAL) support was removed.
|
||||||
|
Please adapt your packaging files, if you used to distribute the
|
||||||
|
nut-hal-drivers package.
|
||||||
|
|
||||||
|
- This is a good time to point out that for stricter packaging systems, it may
|
||||||
|
be beneficial to add "--enable-option-checking=fatal" to the ./configure
|
||||||
|
command line, in order to quickly pick up any other removed option flags.
|
||||||
|
|
||||||
|
Changes from 2.6.5 to 2.7.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The linkman:apcsmart[8] driver has been replaced by a new implementation. There is a new
|
||||||
|
parameter, 'ttymode', which may help if you have a non-standard serial port,
|
||||||
|
or Windows. In case of issues with this new version, users can revert to
|
||||||
|
apcsmart-old.
|
||||||
|
|
||||||
|
- The linkman:nutdrv_qx[8] driver will eventually supersede blazer_ser and blazer_usb.
|
||||||
|
Options are not exactly the same, but are documented in the nutdrv_qx man
|
||||||
|
page.
|
||||||
|
|
||||||
|
- Mozilla NSS support has been added. The OpenSSL configuration options should
|
||||||
|
be unchanged, but please refer to the linkman:upsd.conf[5] and
|
||||||
|
linkman:upsmon.conf[5] documentation in case we missed something.
|
||||||
|
|
||||||
|
- linkman:upsrw[8] now prints out the maximum size of variables. Hopefully you
|
||||||
|
are not parsing the output of upsrw - it would be easier to use one of the
|
||||||
|
NUT libraries, or implement the network protocol yourself.
|
||||||
|
|
||||||
|
- The jNut source is now here: https://github.com/networkupstools/jNut
|
||||||
|
|
||||||
|
Changes from 2.6.4 to 2.6.5
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- users are encouraged to update to NUT 2.6.5, to fix a regression in
|
||||||
|
upssched.
|
||||||
|
- mge-shut driver has been replaced by a new implementation (newmge-shut).
|
||||||
|
In case of issue with this new version, users can revert to oldmge-shut.
|
||||||
|
|
||||||
|
Changes from 2.6.3 to 2.6.4
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- users are encouraged to update to NUT 2.6.4, to fix upsd vulnerability
|
||||||
|
(CVE-2012-2944: upsd can be remotely crashed).
|
||||||
|
- users of the bestups driver are encouraged to switch to blazer_ser,
|
||||||
|
since bestups will soon be deprecated.
|
||||||
|
|
||||||
|
Changes from 2.6.2 to 2.6.3
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
|
||||||
|
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
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
|
||||||
|
Changes from 2.4.3 to 2.6.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- users of the megatec and megatec_usb drivers must respectively switch to
|
||||||
|
blazer_ser and blazer_usb.
|
||||||
|
- users of the liebertgxt2 driver are advised that the driver name has changed
|
||||||
|
to liebert-esp2.
|
||||||
|
|
||||||
|
Changes from 2.4.2 to 2.4.3
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
|
||||||
|
Changes from 2.4.1 to 2.4.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The default subdriver for the blazer_usb driver USB id 06da:0003 has changed.
|
||||||
|
If you use such a device and it is no longer working with this driver, override
|
||||||
|
the 'subdriver' default in 'ups.conf' (see man 8 blazer).
|
||||||
|
- NUT ACL and the allowfrom mechanism has been replaced in 2.4.0 by the LISTEN
|
||||||
|
directive and tcp-wrappers respectively. This information was missing below, so
|
||||||
|
a double note has been added.
|
||||||
|
|
||||||
|
Changes from 2.4.0 to 2.4.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
|
||||||
|
Changes from 2.2.2 to 2.4.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The nut.conf file has been introduced to standardize startup configuration
|
||||||
|
across the various systems.
|
||||||
|
- The cpsups and nitram drivers have been replaced by the powerpanel driver,
|
||||||
|
and removed from the tree. The cyberpower driver may suffer the same in the
|
||||||
|
future.
|
||||||
|
- The al175 and energizerups drivers have been removed from the tree, since
|
||||||
|
these were tagged broken for a long time.
|
||||||
|
- Developers of external client application using libupsclient must rename
|
||||||
|
their "UPSCONN" client structure to "UPSCONN_t".
|
||||||
|
- The upsd server will now disconnect clients that remain silent for more than
|
||||||
|
60 seconds.
|
||||||
|
- The files under scripts/python/client are distributed under GPL 3+, whereas
|
||||||
|
the rest of the files are distributed under GPL 2+. Refer to COPYING for more
|
||||||
|
information.
|
||||||
|
- The generated udev rules file has been renamed with dash only, no underscore
|
||||||
|
anymore (ie 52-nut-usbups.rules instead of 52_nut-usbups.rules)
|
||||||
|
|
||||||
|
Changes from 2.2.1 to 2.2.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The configure option "--with-lib" has been replaced by "--with-dev".
|
||||||
|
This enable the additional build and distribution of the static
|
||||||
|
version of libupsclient, along with the pkg-config helper and manual
|
||||||
|
pages. The default configure option is to distribute only the shared
|
||||||
|
version of libupsclient. This can be overridden by using the
|
||||||
|
"--disable-shared" configure option (distribute static only binaries).
|
||||||
|
- The UPS poweroff handling of the usbhid-ups driver has been reworked.
|
||||||
|
Though regression is not expected, users of this driver are
|
||||||
|
encouraged to test this feature by calling "upsmon -c fsd" and
|
||||||
|
report any issue on the NUT mailing lists.
|
||||||
|
|
||||||
|
Changes from 2.2.0 to 2.2.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
(The below message is repeated due to previous omission)
|
||||||
|
- Developers of external client application using libupsclient are
|
||||||
|
encouraged to rename their "UPSCONN" client structure to "UPSCONN_t"
|
||||||
|
since the former will disappear by the release of NUT 2.4.
|
||||||
|
|
||||||
|
Changes from 2.0.5 to 2.2.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- users of the newhidups driver are advised that the driver name has changed
|
||||||
|
to usbhid-ups.
|
||||||
|
- users of the hidups driver must switch to usbhid-ups.
|
||||||
|
- users of the following drivers (powermust, blazer, fentonups, mustek,
|
||||||
|
esupssmart, ippon, sms) must switch to megatec, which replaces
|
||||||
|
all these drivers. Please refer to doc/megatec.txt for details.
|
||||||
|
- users of the mge-shut driver are encouraged to test newmge-shut, which
|
||||||
|
is an alternate driver scheduled to replace mge-shut,
|
||||||
|
- users of the cpsups driver are encouraged to switch to powerpanel which
|
||||||
|
is scheduled to replace cpsups,
|
||||||
|
- packagers will have to rework the whole nut packaging due to the
|
||||||
|
major changes in the build system (completely modified, and now using
|
||||||
|
automake). Refer to packaging/debian/ for an example of migration.
|
||||||
|
- specifying '-a <id>' is now mandatory when starting a driver manually,
|
||||||
|
ie not using upsdrvctl.
|
||||||
|
- Developers of external client application using libupsclient are
|
||||||
|
encouraged to rename the "UPSCONN" client structure to "UPSCONN_t"
|
||||||
|
since the former will disappear by the release of NUT 2.4.
|
||||||
|
|
||||||
|
Changes from 2.0.4 to 2.0.5
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- users of the newhidups driver: the driver is now more strict about
|
||||||
|
refusing to connect to unknown devices. If your device was
|
||||||
|
previously supported, but fails to be recognized now, add
|
||||||
|
'productid=XXXX' to ups.conf. Please report the device to the NUT
|
||||||
|
developer's mailing list.
|
||||||
|
|
||||||
|
Changes from 2.0.3 to 2.0.4
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
- users of the following drivers (powermust, blazer, fentonups, mustek,
|
||||||
|
esupssmart, ippon, sms, masterguard) are encouraged to switch to megatec,
|
||||||
|
which should replace all these drivers by nut 2.2. For more information,
|
||||||
|
please refer to doc/megatec.txt
|
||||||
|
|
||||||
|
Changes from 2.0.2 to 2.0.3
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- nothing that affects upgraded systems.
|
||||||
|
- hidups users are encouraged to switch to newhidups, as hidups will be
|
||||||
|
removed by nut 2.2.
|
||||||
|
|
||||||
|
Changes from 2.0.1 to 2.0.2
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The newhidups driver, which is the long run USB support approach,
|
||||||
|
needs hotplug files installed to setup the right permissions on
|
||||||
|
device file to operate. Check newhidups manual page for more information.
|
||||||
|
|
||||||
|
Changes from 2.0.0 to 2.0.1
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The cyberpower1100 driver is now called cpsups since it supports
|
||||||
|
more than just one model. If you use this driver, be sure to remove
|
||||||
|
the old binary and update your ups.conf 'driver=' setting with the
|
||||||
|
new name.
|
||||||
|
|
||||||
|
- The upsstats.html template page has been changed slightly to reflect
|
||||||
|
better HTML compliance, so you may want to update your installed copy
|
||||||
|
accordingly. If you've customized your file, don't just copy the new
|
||||||
|
one over it, or your changes will be lost!
|
||||||
|
|
||||||
|
Changes from 1.4.0 to 2.0.0
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
- The sample config files are no longer installed by default. If you
|
||||||
|
want to install them, use 'make install-conf' for the main programs,
|
||||||
|
and 'make install-cgi-conf' for the CGI programs.
|
||||||
|
|
||||||
|
- ACCESS is no longer supported in upsd.conf. Use ACCEPT and REJECT.
|
||||||
|
Old way:
|
||||||
|
|
||||||
|
ACCESS grant all adminbox
|
||||||
|
ACCESS grant all webserver
|
||||||
|
ACCESS deny all all
|
||||||
|
|
||||||
|
New way:
|
||||||
|
|
||||||
|
ACCEPT adminbox
|
||||||
|
ACCEPT webserver
|
||||||
|
REJECT all
|
||||||
|
|
||||||
|
Note that ACCEPT and REJECT can take multiple arguments, so this
|
||||||
|
will also work:
|
||||||
|
|
||||||
|
ACCEPT adminbox webserver
|
||||||
|
REJECT all
|
||||||
|
|
||||||
|
- The drivers no longer support sddelay in ups.conf or -d on the
|
||||||
|
command line. If you need a delay after calling 'upsdrvctl
|
||||||
|
shutdown', add a call to sleep in your shutdown script.
|
||||||
|
|
||||||
|
- The templates used by upsstats have changed considerably to reflect
|
||||||
|
the new variable names. If you use upsstats, you will need to
|
||||||
|
install new copies or edit your existing files to use the new names.
|
||||||
|
|
||||||
|
- Nobody needed UDP mode, so it has been removed. The only users
|
||||||
|
seemed to be a few people like me with ancient asapm-ups binaries.
|
||||||
|
If you really want to run asapm-ups again, bug me for the new patch
|
||||||
|
which makes it work with upsclient.
|
||||||
|
|
||||||
|
- 'make install-misc' is now 'make install-lib'. The misc directory
|
||||||
|
has been gone for a long time, and the target was ambiguous.
|
||||||
|
|
||||||
|
- The newapc driver has been renamed to apcsmart. If you previously
|
||||||
|
used newapc, make sure you delete the old binary and fix your
|
||||||
|
ups.conf. Otherwise, you may run the old driver from 1.4.
|
||||||
|
|
||||||
|
|
||||||
|
*** File trimmed here on changes from 1.2.2 to 1.4.0 ***
|
||||||
|
|
||||||
|
For information before this point, start with version 2.4.1 and work back.
|
1478
aclocal.m4
vendored
Normal file
1478
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
105
clients/Makefile.am
Normal file
105
clients/Makefile.am
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
# Network UPS Tools: clients
|
||||||
|
EXTRA_DIST =
|
||||||
|
|
||||||
|
# nutclient.cpp for some legacy reason (maybe initial detached development?)
|
||||||
|
# optionally includes "common.h" with the NUT build setup - and this option
|
||||||
|
# was never triggered in fact, not until pushed through command line like this:
|
||||||
|
AM_CXXFLAGS = -DHAVE_NUTCOMMON=1 -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
# Make sure out-of-dir dependencies exist (especially when dev-building parts):
|
||||||
|
$(top_builddir)/common/libcommon.la \
|
||||||
|
$(top_builddir)/common/libcommonclient.la \
|
||||||
|
$(top_builddir)/common/libparseconf.la: dummy
|
||||||
|
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
|
||||||
|
|
||||||
|
# by default, link programs in this directory with libcommon.a
|
||||||
|
LDADD = $(top_builddir)/common/libcommon.la libupsclient.la $(NETLIBS)
|
||||||
|
if WITH_SSL
|
||||||
|
LDADD += $(LIBSSL_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Avoid per-target CFLAGS, because this will prevent re-use of object
|
||||||
|
# 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
|
||||||
|
if WITH_SSL
|
||||||
|
AM_CFLAGS += $(LIBSSL_CFLAGS)
|
||||||
|
endif
|
||||||
|
if WITH_CGI
|
||||||
|
AM_CFLAGS += $(LIBGD_CFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
bin_PROGRAMS = upsc upslog upsrw upscmd
|
||||||
|
dist_bin_SCRIPTS = upssched-cmd
|
||||||
|
sbin_PROGRAMS = upsmon upssched
|
||||||
|
lib_LTLIBRARIES = libupsclient.la
|
||||||
|
if HAVE_CXX11
|
||||||
|
lib_LTLIBRARIES += libnutclient.la
|
||||||
|
lib_LTLIBRARIES += libnutclientstub.la
|
||||||
|
endif
|
||||||
|
if WITH_DEV
|
||||||
|
include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h nutclientmem.h
|
||||||
|
endif
|
||||||
|
if WITH_CGI
|
||||||
|
cgiexec_PROGRAMS = upsstats.cgi upsimage.cgi upsset.cgi
|
||||||
|
endif
|
||||||
|
|
||||||
|
upsc_SOURCES = upsc.c upsclient.h
|
||||||
|
upscmd_SOURCES = upscmd.c upsclient.h
|
||||||
|
upsrw_SOURCES = upsrw.c upsclient.h
|
||||||
|
upslog_SOURCES = upslog.c upsclient.h upslog.h
|
||||||
|
upsmon_SOURCES = upsmon.c upsmon.h upsclient.h
|
||||||
|
|
||||||
|
upssched_SOURCES = upssched.c upssched.h
|
||||||
|
upssched_LDADD = $(top_builddir)/common/libcommon.la $(top_builddir)/common/libparseconf.la $(NETLIBS)
|
||||||
|
|
||||||
|
upsimage_cgi_SOURCES = upsimage.c upsclient.h upsimagearg.h cgilib.c cgilib.h
|
||||||
|
upsimage_cgi_LDADD = $(LDADD) $(LIBGD_LDFLAGS)
|
||||||
|
|
||||||
|
upsset_cgi_SOURCES = upsset.c upsclient.h cgilib.c cgilib.h
|
||||||
|
upsstats_cgi_SOURCES = upsstats.c upsclient.h status.h upsstats.h \
|
||||||
|
upsimagearg.h cgilib.c cgilib.h
|
||||||
|
|
||||||
|
# not LDADD.
|
||||||
|
libupsclient_la_SOURCES = upsclient.c upsclient.h
|
||||||
|
libupsclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la
|
||||||
|
if WITH_SSL
|
||||||
|
libupsclient_la_LIBADD += $(LIBSSL_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Below we set API versions of public libraries
|
||||||
|
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||||
|
# Note that changes here may have to be reflected in packaging (the shared
|
||||||
|
# object .so names would differ)
|
||||||
|
|
||||||
|
# libupsclient version information
|
||||||
|
libupsclient_la_LDFLAGS = -version-info 6:0:0 -export-symbols-regex ^upscli_
|
||||||
|
|
||||||
|
if HAVE_CXX11
|
||||||
|
# libnutclient version information and build
|
||||||
|
libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||||
|
libnutclient_la_LDFLAGS = -version-info 2:0:0
|
||||||
|
# Needed in not-standalone builds with -DHAVE_NUTCOMMON=1
|
||||||
|
# which is defined for in-tree CXX builds above:
|
||||||
|
libnutclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la
|
||||||
|
else
|
||||||
|
EXTRA_DIST += nutclient.h nutclient.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
|
if HAVE_CXX11
|
||||||
|
# libnutclientstub version information and build
|
||||||
|
libnutclientstub_la_SOURCES = nutclientmem.h nutclientmem.cpp
|
||||||
|
libnutclientstub_la_LDFLAGS = -version-info 1:0:0
|
||||||
|
libnutclientstub_la_LIBADD = libnutclient.la
|
||||||
|
else
|
||||||
|
EXTRA_DIST += nutclientmem.h nutclientmem.cpp
|
||||||
|
endif
|
||||||
|
|
||||||
|
dummy:
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
|
||||||
|
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
|
||||||
|
# the root Makefile.am takes care of that!
|
||||||
|
#clean-local:
|
||||||
|
# rm -rf $(builddir)/.deps
|
1292
clients/Makefile.in
Normal file
1292
clients/Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
205
clients/cgilib.c
Normal file
205
clients/cgilib.c
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
/* cgilib - common routines for CGI programs
|
||||||
|
|
||||||
|
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "cgilib.h"
|
||||||
|
#include "parseconf.h"
|
||||||
|
|
||||||
|
static char *unescape(char *buf)
|
||||||
|
{
|
||||||
|
size_t i, buflen;
|
||||||
|
char ch, *newbuf, hex[8];
|
||||||
|
|
||||||
|
buflen = strlen(buf) + 2;
|
||||||
|
newbuf = xmalloc(buflen);
|
||||||
|
*newbuf = '\0';
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
for (i = 0; i < buflen - 1; i++) {
|
||||||
|
ch = buf[i];
|
||||||
|
|
||||||
|
if (ch == '+')
|
||||||
|
ch = ' ';
|
||||||
|
|
||||||
|
if (ch == '%') {
|
||||||
|
if (i + 2 > buflen)
|
||||||
|
fatalx(EXIT_FAILURE, "string too short for escaped char");
|
||||||
|
hex[0] = buf[++i];
|
||||||
|
hex[1] = buf[++i];
|
||||||
|
hex[2] = '\0';
|
||||||
|
if (!isxdigit((unsigned char) hex[0])
|
||||||
|
|| !isxdigit((unsigned char) hex[1]))
|
||||||
|
fatalx(EXIT_FAILURE, "bad escape char");
|
||||||
|
long l = strtol(hex, NULL, 16);
|
||||||
|
assert(l>=0);
|
||||||
|
assert(l<=255);
|
||||||
|
ch = (char)l; /* FIXME: Loophole about non-ASCII symbols in top 128 values, or negatives for signed char... */
|
||||||
|
|
||||||
|
if ((ch == 10) || (ch == 13))
|
||||||
|
ch = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintfcat(newbuf, buflen, "%c", ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void extractcgiargs(void)
|
||||||
|
{
|
||||||
|
char *query, *ptr, *eq, *varname, *value, *amp;
|
||||||
|
char *cleanval, *cleanvar;
|
||||||
|
|
||||||
|
query = getenv("QUERY_STRING");
|
||||||
|
if (query == NULL)
|
||||||
|
return; /* not run as a cgi script! */
|
||||||
|
if (strlen(query) == 0)
|
||||||
|
return; /* no query string to parse! */
|
||||||
|
|
||||||
|
/* varname=value&varname=value&varname=value ... */
|
||||||
|
|
||||||
|
ptr = query;
|
||||||
|
|
||||||
|
while (ptr) {
|
||||||
|
varname = ptr;
|
||||||
|
eq = strchr(varname, '=');
|
||||||
|
if (!eq) {
|
||||||
|
ptr = strchr(varname, '&');
|
||||||
|
if (ptr)
|
||||||
|
*ptr++ = '\0';
|
||||||
|
|
||||||
|
cleanvar = unescape(varname);
|
||||||
|
parsearg(cleanvar, "");
|
||||||
|
free(cleanvar);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*eq = '\0';
|
||||||
|
value = eq + 1;
|
||||||
|
amp = strchr(value, '&');
|
||||||
|
if (amp) {
|
||||||
|
ptr = amp + 1;
|
||||||
|
*amp = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ptr = NULL;
|
||||||
|
|
||||||
|
cleanvar = unescape(varname);
|
||||||
|
cleanval = unescape(value);
|
||||||
|
parsearg(cleanvar, cleanval);
|
||||||
|
free(cleanvar);
|
||||||
|
free(cleanval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void extractpostargs(void)
|
||||||
|
{
|
||||||
|
char buf[SMALLBUF], *ptr, *cleanval;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = fgetc(stdin);
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
while (ch != EOF) {
|
||||||
|
if (ch == '&') {
|
||||||
|
ptr = strchr(buf, '=');
|
||||||
|
if (!ptr)
|
||||||
|
parsearg(buf, "");
|
||||||
|
else {
|
||||||
|
*ptr++ = '\0';
|
||||||
|
cleanval = unescape(ptr);
|
||||||
|
parsearg(buf, cleanval);
|
||||||
|
free(cleanval);
|
||||||
|
}
|
||||||
|
buf[0] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
snprintfcat(buf, sizeof(buf), "%c", ch);
|
||||||
|
|
||||||
|
ch = fgetc(stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(buf) != 0) {
|
||||||
|
ptr = strchr(buf, '=');
|
||||||
|
if (!ptr)
|
||||||
|
parsearg(buf, "");
|
||||||
|
else {
|
||||||
|
*ptr++ = '\0';
|
||||||
|
cleanval = unescape(ptr);
|
||||||
|
parsearg(buf, cleanval);
|
||||||
|
free(cleanval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called for fatal errors in parseconf like malloc failures */
|
||||||
|
static void cgilib_err(const char *errmsg)
|
||||||
|
{
|
||||||
|
upslogx(LOG_ERR, "Fatal error in parseconf(ups.conf): %s", errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkhost(const char *host, char **desc)
|
||||||
|
{
|
||||||
|
char fn[SMALLBUF];
|
||||||
|
PCONF_CTX_t ctx;
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
return 0; /* deny null hostnames */
|
||||||
|
|
||||||
|
snprintf(fn, sizeof(fn), "%s/hosts.conf", confpath());
|
||||||
|
|
||||||
|
pconf_init(&ctx, cgilib_err);
|
||||||
|
|
||||||
|
if (!pconf_file_begin(&ctx, fn)) {
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
fprintf(stderr, "%s\n", ctx.errmsg);
|
||||||
|
|
||||||
|
return 0; /* failed: deny access */
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pconf_file_next(&ctx)) {
|
||||||
|
if (pconf_parse_error(&ctx)) {
|
||||||
|
fprintf(stderr, "Error: %s:%d: %s\n",
|
||||||
|
fn, ctx.linenum, ctx.errmsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MONITOR <host> <description> */
|
||||||
|
if (ctx.numargs < 3)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(ctx.arglist[0], "MONITOR") != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcmp(ctx.arglist[1], host)) {
|
||||||
|
if (desc)
|
||||||
|
*desc = xstrdup(ctx.arglist[2]);
|
||||||
|
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
return 1; /* found: allow access */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
|
||||||
|
return 0; /* not found: access denied */
|
||||||
|
}
|
47
clients/cgilib.h
Normal file
47
clients/cgilib.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/* cgilib.h - headers for cgilib.c
|
||||||
|
|
||||||
|
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUT_CGILIB_H_SEEN
|
||||||
|
#define NUT_CGILIB_H_SEEN 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* other programs that link to this should provide parsearg() ... */
|
||||||
|
void parsearg(char *var, char *value);
|
||||||
|
|
||||||
|
/* actually extract the values from QUERY_STRING */
|
||||||
|
void extractcgiargs(void);
|
||||||
|
|
||||||
|
/* like extractcgiargs, but this one is for POSTed values */
|
||||||
|
void extractpostargs(void);
|
||||||
|
|
||||||
|
/* see if a host is allowed per the hosts.conf */
|
||||||
|
int checkhost(const char *host, char **desc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_CGILIB_H_SEEN */
|
2055
clients/nutclient.cpp
Normal file
2055
clients/nutclient.cpp
Normal file
File diff suppressed because it is too large
Load diff
1072
clients/nutclient.h
Normal file
1072
clients/nutclient.h
Normal file
File diff suppressed because it is too large
Load diff
252
clients/nutclientmem.cpp
Normal file
252
clients/nutclientmem.cpp
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
/* nutclientmem.cpp - nutclientmem C++ library implementation
|
||||||
|
|
||||||
|
Copyright (C) 2021 Eric Clappier <ericclappier@eaton.com>
|
||||||
|
|
||||||
|
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 "nutclientmem.h"
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
|
namespace nut
|
||||||
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Memory Client stub implementation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
Device MemClientStub::getDevice(const std::string& name)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(name);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> MemClientStub::getDeviceNames()
|
||||||
|
{
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemClientStub::getDeviceDescription(const std::string& name)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(name);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> MemClientStub::getDeviceVariableNames(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> MemClientStub::getDeviceRWVariableNames(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemClientStub::getDeviceVariableDescription(const std::string& dev, const std::string& name)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
NUT_UNUSED_VARIABLE(name);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
ListValue MemClientStub::getDeviceVariableValue(const std::string& dev, const std::string& name)
|
||||||
|
{
|
||||||
|
ListValue res;
|
||||||
|
auto it_dev = _values.find(dev);
|
||||||
|
if (it_dev != _values.end())
|
||||||
|
{
|
||||||
|
auto map = it_dev->second;
|
||||||
|
auto it_map = map.find(name);
|
||||||
|
if (it_map != map.end())
|
||||||
|
{
|
||||||
|
res = it_map->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListObject MemClientStub::getDeviceVariableValues(const std::string& dev)
|
||||||
|
{
|
||||||
|
ListObject res;
|
||||||
|
auto it_dev = _values.find(dev);
|
||||||
|
if (it_dev != _values.end())
|
||||||
|
{
|
||||||
|
res = it_dev->second;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListDevice MemClientStub::getDevicesVariableValues(const std::set<std::string>& devs)
|
||||||
|
{
|
||||||
|
ListDevice res;
|
||||||
|
for (auto itr = devs.begin(); itr != devs.end(); itr++)
|
||||||
|
{
|
||||||
|
std::string dev = *itr;
|
||||||
|
auto it_dev = _values.find(dev);
|
||||||
|
if (it_dev != _values.end())
|
||||||
|
{
|
||||||
|
res.insert(std::pair<std::string, ListObject>(dev, it_dev->second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingID MemClientStub::setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)
|
||||||
|
{
|
||||||
|
auto it_dev = _values.find(dev);
|
||||||
|
if (it_dev == _values.end())
|
||||||
|
{
|
||||||
|
ListObject list;
|
||||||
|
_values.emplace(dev, list);
|
||||||
|
it_dev = _values.find(dev);
|
||||||
|
}
|
||||||
|
if (it_dev != _values.end())
|
||||||
|
{
|
||||||
|
auto map = &(it_dev->second);
|
||||||
|
auto it_map = map->find(name);
|
||||||
|
if (it_map != map->end())
|
||||||
|
{
|
||||||
|
it_map->second[0] = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ListValue list_value;
|
||||||
|
list_value.push_back(value);
|
||||||
|
map->emplace(name, list_value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingID MemClientStub::setDeviceVariable(const std::string& dev, const std::string& name, const ListValue& values)
|
||||||
|
{
|
||||||
|
auto it_dev = _values.find(dev);
|
||||||
|
if (it_dev != _values.end())
|
||||||
|
{
|
||||||
|
auto map = &(it_dev->second);
|
||||||
|
auto it_map = map->find(name);
|
||||||
|
if (it_map != map->end())
|
||||||
|
{
|
||||||
|
it_map->second = values;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map->emplace(name, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> MemClientStub::getDeviceCommandNames(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MemClientStub::getDeviceCommandDescription(const std::string& dev, const std::string& name)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
NUT_UNUSED_VARIABLE(name);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingID MemClientStub::executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
NUT_UNUSED_VARIABLE(name);
|
||||||
|
NUT_UNUSED_VARIABLE(param);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemClientStub::deviceLogin(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: "master" is deprecated, but supported
|
||||||
|
* for mixing old/new client/server combos: */
|
||||||
|
void MemClientStub::deviceMaster(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemClientStub::devicePrimary(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemClientStub::deviceForcedShutdown(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
int MemClientStub::deviceGetNumLogins(const std::string& dev)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(dev);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingResult MemClientStub::getTrackingResult(const TrackingID& id)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(id);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
//return TrackingResult::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MemClientStub::isFeatureEnabled(const Feature& feature)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(feature);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemClientStub::setFeature(const Feature& feature, bool status)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(feature);
|
||||||
|
NUT_UNUSED_VARIABLE(status);
|
||||||
|
throw NutException("Not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace nut */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* C nutclient API.
|
||||||
|
*/
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
NUTCLIENT_MEM_t nutclient_mem_create_client()
|
||||||
|
{
|
||||||
|
nut::MemClientStub* client = new nut::MemClientStub;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return static_cast<NUTCLIENT_MEM_t>(client);
|
||||||
|
}
|
||||||
|
catch(nut::NutException& ex)
|
||||||
|
{
|
||||||
|
// TODO really catch it
|
||||||
|
NUT_UNUSED_VARIABLE(ex);
|
||||||
|
delete client;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* extern "C" */
|
118
clients/nutclientmem.h
Normal file
118
clients/nutclientmem.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/* nutclientmem.h - definitions for nutclientmem C/C++ library
|
||||||
|
|
||||||
|
Copyright (C) 2021 Eric Clappier <ericclappier@eaton.com>
|
||||||
|
|
||||||
|
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 NUTCLIENTMEM_HPP_SEEN
|
||||||
|
#define NUTCLIENTMEM_HPP_SEEN
|
||||||
|
|
||||||
|
/* Begin of C++ nutclient library declaration */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "nutclient.h"
|
||||||
|
|
||||||
|
namespace nut
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef std::vector<std::string> ListValue;
|
||||||
|
typedef std::map<std::string, ListValue> ListObject;
|
||||||
|
typedef std::map<std::string, ListObject> ListDevice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory client stub.
|
||||||
|
* Class to stub TCPClient for test (data store in local memory).
|
||||||
|
*/
|
||||||
|
class MemClientStub : public Client
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a nut MemClientStub object.
|
||||||
|
*/
|
||||||
|
MemClientStub() {}
|
||||||
|
~MemClientStub() override {}
|
||||||
|
|
||||||
|
virtual void authenticate(const std::string& user, const std::string& passwd) override {
|
||||||
|
NUT_UNUSED_VARIABLE(user);
|
||||||
|
NUT_UNUSED_VARIABLE(passwd);
|
||||||
|
}
|
||||||
|
virtual void logout() override {}
|
||||||
|
|
||||||
|
virtual Device getDevice(const std::string& name) override;
|
||||||
|
virtual std::set<std::string> getDeviceNames() override;
|
||||||
|
virtual std::string getDeviceDescription(const std::string& name) override;
|
||||||
|
|
||||||
|
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev) override;
|
||||||
|
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev) override;
|
||||||
|
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name) override;
|
||||||
|
virtual ListValue getDeviceVariableValue(const std::string& dev, const std::string& name) override;
|
||||||
|
virtual ListObject getDeviceVariableValues(const std::string& dev) override;
|
||||||
|
virtual ListDevice getDevicesVariableValues(const std::set<std::string>& devs) override;
|
||||||
|
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value) override;
|
||||||
|
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const ListValue& values) override;
|
||||||
|
|
||||||
|
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev) override;
|
||||||
|
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name) override;
|
||||||
|
virtual TrackingID executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param="") override;
|
||||||
|
|
||||||
|
virtual void deviceLogin(const std::string& dev) override;
|
||||||
|
/* Note: "master" is deprecated, but supported
|
||||||
|
* for mixing old/new client/server combos: */
|
||||||
|
virtual void deviceMaster(const std::string& dev) override;
|
||||||
|
virtual void devicePrimary(const std::string& dev) override;
|
||||||
|
virtual void deviceForcedShutdown(const std::string& dev) override;
|
||||||
|
virtual int deviceGetNumLogins(const std::string& dev) override;
|
||||||
|
|
||||||
|
virtual TrackingResult getTrackingResult(const TrackingID& id) override;
|
||||||
|
|
||||||
|
virtual bool isFeatureEnabled(const Feature& feature) override;
|
||||||
|
virtual void setFeature(const Feature& feature, bool status) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListDevice _values;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace nut */
|
||||||
|
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
/* End of C++ nutclient library declaration */
|
||||||
|
|
||||||
|
/* Begin of C nutclient library declaration */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nut MEM client dedicated types and functions
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Hidden structure representing a MEM connection.
|
||||||
|
* NUTCLIENT_MEM_t is back compatible to NUTCLIENT_t.
|
||||||
|
*/
|
||||||
|
typedef NUTCLIENT_t NUTCLIENT_MEM_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a client to NUTD using memory.
|
||||||
|
* \return New client or nullptr if failed.
|
||||||
|
*/
|
||||||
|
NUTCLIENT_MEM_t nutclient_mem_create_client();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
/* End of C nutclient library declaration */
|
||||||
|
|
||||||
|
#endif /* NUTCLIENTMOCK_HPP_SEEN */
|
57
clients/status.h
Normal file
57
clients/status.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* status.h - translation of status abbreviations to descriptions
|
||||||
|
|
||||||
|
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUT_STATUS_H_SEEN
|
||||||
|
#define NUT_STATUS_H_SEEN 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is only used in upsstats.c, but might it also have external consumers?..
|
||||||
|
* To move or not to move?..
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
char *name;
|
||||||
|
char *desc;
|
||||||
|
int severity;
|
||||||
|
} stattab[] =
|
||||||
|
{
|
||||||
|
{ "OFF", "OFF", 1 },
|
||||||
|
{ "OL", "ONLINE", 0 },
|
||||||
|
{ "OB", "ON BATTERY", 2 },
|
||||||
|
{ "LB", "LOW BATTERY", 2 },
|
||||||
|
{ "RB", "REPLACE BATTERY", 2 },
|
||||||
|
{ "OVER", "OVERLOAD", 2 },
|
||||||
|
{ "TRIM", "VOLTAGE TRIM", 1 },
|
||||||
|
{ "BOOST", "VOLTAGE BOOST", 1 },
|
||||||
|
{ "CAL", "CALIBRATION", 1 },
|
||||||
|
{ "BYPASS", "BYPASS", 2 },
|
||||||
|
{ NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_STATUS_H_SEEN */
|
292
clients/upsc.c
Normal file
292
clients/upsc.c
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
/* upsc - simple "client" to test communications
|
||||||
|
|
||||||
|
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||||
|
Copyright (C) 2012 Arnaud Quette <arnaud.quette@free.fr>
|
||||||
|
|
||||||
|
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 "nut_platform.h"
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
#include "upsclient.h"
|
||||||
|
|
||||||
|
static char *upsname = NULL, *hostname = NULL;
|
||||||
|
static UPSCONN_t *ups = NULL;
|
||||||
|
|
||||||
|
static void usage(const char *prog)
|
||||||
|
{
|
||||||
|
printf("Network UPS Tools upsc %s\n\n", UPS_VERSION);
|
||||||
|
|
||||||
|
printf("usage: %s -l | -L [<hostname>[:port]]\n", prog);
|
||||||
|
printf(" %s <ups> [<variable>]\n", prog);
|
||||||
|
printf(" %s -c <ups>\n", prog);
|
||||||
|
|
||||||
|
printf("\nDemo program to display UPS variables.\n\n");
|
||||||
|
|
||||||
|
printf("First form (lists UPSes):\n");
|
||||||
|
printf(" -l - lists each UPS on <hostname>, one per line.\n");
|
||||||
|
printf(" -L - lists each UPS followed by its description (from ups.conf).\n");
|
||||||
|
printf(" Default hostname: localhost\n");
|
||||||
|
|
||||||
|
printf("\nSecond form (lists variables and values):\n");
|
||||||
|
printf(" <ups> - upsd server, <upsname>[@<hostname>[:<port>]] form\n");
|
||||||
|
printf(" <variable> - optional, display this variable only.\n");
|
||||||
|
printf(" Default: list all variables for <host>\n");
|
||||||
|
|
||||||
|
printf("\nThird form (lists clients connected to a device):\n");
|
||||||
|
printf(" -c - lists each client connected on <ups>, one per line.\n");
|
||||||
|
printf(" <ups> - upsd server, <upsname>[@<hostname>[:<port>]] form\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printvar(const char *var)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
/* old-style variable name? */
|
||||||
|
if (!strchr(var, '.')) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: old-style variable names are not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
query[0] = "VAR";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = var;
|
||||||
|
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
|
||||||
|
/* new var and old upsd? try to explain the situation */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: variable unknown (old upsd detected)");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numa < numq) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least %zu)", numa, numq);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", answer[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_vars(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "VAR";
|
||||||
|
query[1] = upsname;
|
||||||
|
numq = 2;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
|
||||||
|
/* check for an old upsd */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (upscli_list_next(ups, numq, query, &numa, &answer) == 1) {
|
||||||
|
|
||||||
|
/* VAR <upsname> <varname> <val> */
|
||||||
|
if (numa < 4) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s: %s\n", answer[2], answer[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_upses(int verbose)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "UPS";
|
||||||
|
numq = 1;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
/* check for an old upsd */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (upscli_list_next(ups, numq, query, &numa, &answer) == 1) {
|
||||||
|
|
||||||
|
/* UPS <upsname> <description> */
|
||||||
|
if (numa < 3) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbose) {
|
||||||
|
printf("%s: %s\n", answer[1], answer[2]);
|
||||||
|
} else {
|
||||||
|
printf("%s\n", answer[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_clients(const char *devname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "CLIENT";
|
||||||
|
query[1] = devname;
|
||||||
|
numq = 2;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
/* check for an old upsd */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((ret=upscli_list_next(ups, numq, query, &numa, &answer)) == 1) {
|
||||||
|
|
||||||
|
/* CLIENT <upsname> <address> */
|
||||||
|
if (numa < 3) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", answer[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clean_exit(void)
|
||||||
|
{
|
||||||
|
if (ups) {
|
||||||
|
upscli_disconnect(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(upsname);
|
||||||
|
free(hostname);
|
||||||
|
free(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t port;
|
||||||
|
int varlist = 0, clientlist = 0, verbose = 0;
|
||||||
|
const char *prog = xbasename(argv[0]);
|
||||||
|
|
||||||
|
while ((i = getopt(argc, argv, "+hlLcV")) != -1) {
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 'L':
|
||||||
|
verbose = 1;
|
||||||
|
goto fallthrough_case_l;
|
||||||
|
case 'l':
|
||||||
|
fallthrough_case_l:
|
||||||
|
varlist = 1;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
clientlist = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_SUCCESS); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
/* be a good little client that cleans up after itself */
|
||||||
|
atexit(clean_exit);
|
||||||
|
|
||||||
|
if (varlist) {
|
||||||
|
if (upscli_splitaddr(argv[0] ? argv[0] : "localhost", &hostname, &port) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: invalid hostname.\nRequired format: [hostname[:port]]");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: invalid UPS definition.\nRequired format: upsname[@hostname[:port]]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ups = xmalloc(sizeof(*ups));
|
||||||
|
|
||||||
|
if (upscli_connect(ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (varlist) {
|
||||||
|
list_upses(verbose);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientlist) {
|
||||||
|
list_clients(upsname);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
printvar(argv[1]);
|
||||||
|
} else {
|
||||||
|
list_vars();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||||
|
#if (defined NUT_PLATFORM_AIX)
|
||||||
|
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||||
|
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||||
|
}
|
||||||
|
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
1720
clients/upsclient.c
Normal file
1720
clients/upsclient.c
Normal file
File diff suppressed because it is too large
Load diff
190
clients/upsclient.h
Normal file
190
clients/upsclient.h
Normal file
|
@ -0,0 +1,190 @@
|
||||||
|
/* upsclient.h - definitions for upsclient functions
|
||||||
|
|
||||||
|
Copyright (C) 2002 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UPSCLIENT_H_SEEN
|
||||||
|
#define UPSCLIENT_H_SEEN
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||||
|
#include <nss.h>
|
||||||
|
#include <ssl.h>
|
||||||
|
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||||
|
|
||||||
|
/* Not including nut_stdint.h because this is part of end-user API */
|
||||||
|
#if defined HAVE_INTTYPES_H
|
||||||
|
#include <inttypes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UPSCLI_ERRBUF_LEN 256
|
||||||
|
#define UPSCLI_NETBUF_LEN 512 /* network i/o buffer */
|
||||||
|
|
||||||
|
#include "parseconf.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *host;
|
||||||
|
uint16_t port;
|
||||||
|
int fd;
|
||||||
|
int flags;
|
||||||
|
int upserror;
|
||||||
|
int syserrno;
|
||||||
|
int upsclient_magic;
|
||||||
|
|
||||||
|
PCONF_CTX_t pc_ctx;
|
||||||
|
|
||||||
|
char errbuf[UPSCLI_ERRBUF_LEN];
|
||||||
|
|
||||||
|
#ifdef WITH_OPENSSL
|
||||||
|
SSL *ssl;
|
||||||
|
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||||
|
PRFileDesc *ssl;
|
||||||
|
#else /* WITH_OPENSSL | WITH_NSS */
|
||||||
|
void *ssl;
|
||||||
|
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||||
|
|
||||||
|
char readbuf[64];
|
||||||
|
size_t readlen;
|
||||||
|
size_t readidx;
|
||||||
|
|
||||||
|
} UPSCONN_t;
|
||||||
|
|
||||||
|
const char *upscli_strerror(UPSCONN_t *ups);
|
||||||
|
|
||||||
|
int upscli_init(int certverify, const char *certpath, const char *certname, const char *certpasswd);
|
||||||
|
int upscli_cleanup(void);
|
||||||
|
|
||||||
|
int upscli_tryconnect(UPSCONN_t *ups, const char *host, uint16_t port, int flags, struct timeval *tv);
|
||||||
|
int upscli_connect(UPSCONN_t *ups, const char *host, uint16_t port, int flags);
|
||||||
|
|
||||||
|
void upscli_add_host_cert(const char* hostname, const char* certname, int certverify, int forcessl);
|
||||||
|
|
||||||
|
/* --- functions that only use the new names --- */
|
||||||
|
|
||||||
|
int upscli_get(UPSCONN_t *ups, size_t numq, const char **query,
|
||||||
|
size_t *numa, char ***answer);
|
||||||
|
|
||||||
|
int upscli_list_start(UPSCONN_t *ups, size_t numq, const char **query);
|
||||||
|
|
||||||
|
int upscli_list_next(UPSCONN_t *ups, size_t numq, const char **query,
|
||||||
|
size_t *numa, char ***answer);
|
||||||
|
|
||||||
|
ssize_t upscli_sendline_timeout(UPSCONN_t *ups, const char *buf, size_t buflen, const time_t timeout);
|
||||||
|
ssize_t upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen);
|
||||||
|
|
||||||
|
ssize_t upscli_readline_timeout(UPSCONN_t *ups, char *buf, size_t buflen, const time_t timeout);
|
||||||
|
ssize_t upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen);
|
||||||
|
|
||||||
|
int upscli_splitname(const char *buf, char **upsname, char **hostname,
|
||||||
|
uint16_t *port);
|
||||||
|
|
||||||
|
int upscli_splitaddr(const char *buf, char **hostname, uint16_t *port);
|
||||||
|
|
||||||
|
int upscli_disconnect(UPSCONN_t *ups);
|
||||||
|
|
||||||
|
/* these functions return elements from UPSCONN_t to avoid direct references */
|
||||||
|
|
||||||
|
int upscli_fd(UPSCONN_t *ups);
|
||||||
|
int upscli_upserror(UPSCONN_t *ups);
|
||||||
|
|
||||||
|
/* returns 1 if SSL mode is active for this connection */
|
||||||
|
int upscli_ssl(UPSCONN_t *ups);
|
||||||
|
|
||||||
|
/* upsclient error list */
|
||||||
|
|
||||||
|
#define UPSCLI_ERR_UNKNOWN 0 /* Unknown error */
|
||||||
|
#define UPSCLI_ERR_VARNOTSUPP 1 /* Variable not supported by UPS */
|
||||||
|
#define UPSCLI_ERR_NOSUCHHOST 2 /* No such host */
|
||||||
|
#define UPSCLI_ERR_INVRESP 3 /* Invalid response from server */
|
||||||
|
#define UPSCLI_ERR_UNKNOWNUPS 4 /* Unknown UPS */
|
||||||
|
#define UPSCLI_ERR_INVLISTTYPE 5 /* Invalid list type */
|
||||||
|
#define UPSCLI_ERR_ACCESSDENIED 6 /* Access denied */
|
||||||
|
#define UPSCLI_ERR_PWDREQUIRED 7 /* Password required */
|
||||||
|
#define UPSCLI_ERR_PWDINCORRECT 8 /* Password incorrect */
|
||||||
|
#define UPSCLI_ERR_MISSINGARG 9 /* Missing argument */
|
||||||
|
#define UPSCLI_ERR_DATASTALE 10 /* Data stale */
|
||||||
|
#define UPSCLI_ERR_VARUNKNOWN 11 /* Variable unknown */
|
||||||
|
#define UPSCLI_ERR_LOGINTWICE 12 /* Already logged in */
|
||||||
|
#define UPSCLI_ERR_PWDSETTWICE 13 /* Already set password */
|
||||||
|
#define UPSCLI_ERR_UNKNOWNTYPE 14 /* Unknown variable type */
|
||||||
|
#define UPSCLI_ERR_UNKNOWNVAR 15 /* Unknown variable */
|
||||||
|
#define UPSCLI_ERR_VARREADONLY 16 /* Read-only variable */
|
||||||
|
#define UPSCLI_ERR_TOOLONG 17 /* New value is too long */
|
||||||
|
#define UPSCLI_ERR_INVALIDVALUE 18 /* Invalid value for variable */
|
||||||
|
#define UPSCLI_ERR_SETFAILED 19 /* Set command failed */
|
||||||
|
#define UPSCLI_ERR_UNKINSTCMD 20 /* Unknown instant command */
|
||||||
|
#define UPSCLI_ERR_CMDFAILED 21 /* Instant command failed */
|
||||||
|
#define UPSCLI_ERR_CMDNOTSUPP 22 /* Instant command not supported */
|
||||||
|
#define UPSCLI_ERR_INVUSERNAME 23 /* Invalid username */
|
||||||
|
#define UPSCLI_ERR_USERSETTWICE 24 /* Already set username */
|
||||||
|
#define UPSCLI_ERR_UNKCOMMAND 25 /* Unknown command */
|
||||||
|
#define UPSCLI_ERR_INVALIDARG 26 /* Invalid argument */
|
||||||
|
#define UPSCLI_ERR_SENDFAILURE 27 /* Send failure: %s */
|
||||||
|
#define UPSCLI_ERR_RECVFAILURE 28 /* Receive failure: %s */
|
||||||
|
#define UPSCLI_ERR_SOCKFAILURE 29 /* socket failure: %s */
|
||||||
|
#define UPSCLI_ERR_BINDFAILURE 30 /* bind failure: %s */
|
||||||
|
#define UPSCLI_ERR_CONNFAILURE 31 /* Connection failure: %s */
|
||||||
|
#define UPSCLI_ERR_WRITE 32 /* Write error: %s */
|
||||||
|
#define UPSCLI_ERR_READ 33 /* Read error: %s */
|
||||||
|
#define UPSCLI_ERR_INVPASSWORD 34 /* Invalid password */
|
||||||
|
#define UPSCLI_ERR_USERREQUIRED 35 /* Username required */
|
||||||
|
#define UPSCLI_ERR_SSLFAIL 36 /* SSL is not available */
|
||||||
|
#define UPSCLI_ERR_SSLERR 37 /* SSL error: %s */
|
||||||
|
#define UPSCLI_ERR_SRVDISC 38 /* Server disconnected */
|
||||||
|
#define UPSCLI_ERR_DRVNOTCONN 39 /* Driver not connected */
|
||||||
|
#define UPSCLI_ERR_NOMEM 40 /* Memory allocation failure */
|
||||||
|
#define UPSCLI_ERR_PARSE 41 /* Parse error: %s */
|
||||||
|
#define UPSCLI_ERR_PROTOCOL 42 /* Protocol error */
|
||||||
|
|
||||||
|
#define UPSCLI_ERR_MAX 42 /* stop here */
|
||||||
|
|
||||||
|
/* list types for use with upscli_getlist */
|
||||||
|
|
||||||
|
#define UPSCLI_LIST_VARS 1 /* all variables */
|
||||||
|
#define UPSCLI_LIST_RW 2 /* just read/write variables */
|
||||||
|
#define UPSCLI_LIST_CMDS 3 /* instant commands */
|
||||||
|
|
||||||
|
/* flags for use with upscli_connect */
|
||||||
|
|
||||||
|
#define UPSCLI_CONN_TRYSSL 0x0001 /* try SSL, OK if not supported */
|
||||||
|
#define UPSCLI_CONN_REQSSL 0x0002 /* try SSL, fail if not supported */
|
||||||
|
#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */
|
||||||
|
#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */
|
||||||
|
#define UPSCLI_CONN_CERTVERIF 0x0010 /* Verify certificates for SSL */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
#endif /* UPSCLIENT_H_SEEN */
|
455
clients/upscmd.c
Normal file
455
clients/upscmd.c
Normal file
|
@ -0,0 +1,455 @@
|
||||||
|
/* upscmd - simple "client" to test instant commands via upsd
|
||||||
|
|
||||||
|
Copyright (C)
|
||||||
|
2000 Russell Kroll <rkroll@exploits.org>
|
||||||
|
2019 EATON (author: Arnaud Quette <ArnaudQuette@eaton.com>)
|
||||||
|
|
||||||
|
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 "nut_platform.h"
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
#include "upsclient.h"
|
||||||
|
|
||||||
|
static char *upsname = NULL, *hostname = NULL;
|
||||||
|
static UPSCONN_t *ups = NULL;
|
||||||
|
static int tracking_enabled = 0;
|
||||||
|
static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT;
|
||||||
|
|
||||||
|
struct list_t {
|
||||||
|
char *name;
|
||||||
|
struct list_t *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(const char *prog)
|
||||||
|
{
|
||||||
|
printf("Network UPS Tools upscmd %s\n\n", UPS_VERSION);
|
||||||
|
printf("usage: %s [-h]\n", prog);
|
||||||
|
printf(" %s [-l <ups>]\n", prog);
|
||||||
|
printf(" %s [-u <username>] [-p <password>] [-w] [-t <timeout>] <ups> <command> [<value>]\n\n", prog);
|
||||||
|
printf("Administration program to initiate instant commands on UPS hardware.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" -h display this help text\n");
|
||||||
|
printf(" -l <ups> show available commands on UPS <ups>\n");
|
||||||
|
printf(" -u <username> set username for command authentication\n");
|
||||||
|
printf(" -p <password> set password for command authentication\n");
|
||||||
|
printf(" -w wait for the completion of command by the driver\n");
|
||||||
|
printf(" and return its actual result from the device\n");
|
||||||
|
printf(" -t <timeout> set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT);
|
||||||
|
printf("\n");
|
||||||
|
printf(" <ups> UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
|
||||||
|
printf(" <command> Valid instant command - test.panel.start, etc.\n");
|
||||||
|
printf(" [<value>] Additional data for command - number of seconds, etc.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_cmd(char *cmdname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "CMDDESC";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = cmdname;
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if ((ret < 0) || (numa < numq)) {
|
||||||
|
printf("%s\n", cmdname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CMDDESC <upsname> <cmdname> <desc> */
|
||||||
|
printf("%s - %s\n", cmdname, answer[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void listcmds(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
struct list_t *lhead = NULL, *llast = NULL, *ltmp, *lnext;
|
||||||
|
|
||||||
|
query[0] = "CMD";
|
||||||
|
query[1] = upsname;
|
||||||
|
numq = 2;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
|
||||||
|
/* old upsd = no way to continue */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (upscli_list_next(ups, numq, query, &numa, &answer) == 1) {
|
||||||
|
|
||||||
|
/* CMD <upsname> <cmdname> */
|
||||||
|
if (numa < 3) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we must first read the entire list of commands,
|
||||||
|
before we can start reading the descriptions */
|
||||||
|
|
||||||
|
ltmp = xcalloc(1, sizeof(*ltmp));
|
||||||
|
ltmp->name = xstrdup(answer[2]);
|
||||||
|
|
||||||
|
if (llast) {
|
||||||
|
llast->next = ltmp;
|
||||||
|
} else {
|
||||||
|
lhead = ltmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
llast = ltmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* walk the list and try to get descriptions, freeing as we go */
|
||||||
|
printf("Instant commands supported on UPS [%s]:\n\n", upsname);
|
||||||
|
|
||||||
|
for (ltmp = lhead; ltmp; ltmp = lnext) {
|
||||||
|
lnext = ltmp->next;
|
||||||
|
|
||||||
|
print_cmd(ltmp->name);
|
||||||
|
|
||||||
|
free(ltmp->name);
|
||||||
|
free(ltmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC)
|
||||||
|
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||||
|
#endif
|
||||||
|
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC)
|
||||||
|
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||||
|
#endif
|
||||||
|
static void do_cmd(char **argv, const int argc)
|
||||||
|
{
|
||||||
|
int cmd_complete = 0;
|
||||||
|
char buf[SMALLBUF];
|
||||||
|
char tracking_id[UUID4_LEN];
|
||||||
|
time_t start, now;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
snprintf(buf, sizeof(buf), "INSTCMD %s %s %s\n", upsname, argv[0], argv[1]);
|
||||||
|
} else {
|
||||||
|
snprintf(buf, sizeof(buf), "INSTCMD %s %s\n", upsname, argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't send instant command: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Instant command failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify answer */
|
||||||
|
if (strncmp(buf, "OK", 2) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for status tracking id */
|
||||||
|
if (
|
||||||
|
!tracking_enabled ||
|
||||||
|
/* sanity check on the size: "OK TRACKING " + UUID4_LEN */
|
||||||
|
strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING "))
|
||||||
|
) {
|
||||||
|
/* reply as usual */
|
||||||
|
fprintf(stderr, "%s\n", buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||||
|
#endif
|
||||||
|
/* From the check above, we know that we have exactly UUID4_LEN chars
|
||||||
|
* (aka sizeof(tracking_id)) in the buf after "OK TRACKING " prefix,
|
||||||
|
* plus the null-byte.
|
||||||
|
*/
|
||||||
|
assert (UUID4_LEN == 1 + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")));
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
time(&start);
|
||||||
|
|
||||||
|
/* send status tracking request, looping if status is PENDING */
|
||||||
|
while (!cmd_complete) {
|
||||||
|
|
||||||
|
/* check for timeout */
|
||||||
|
time(&now);
|
||||||
|
if (difftime(now, start) >= timeout)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout");
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups));
|
||||||
|
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||||
|
/* Note for gating macros above: unsuffixed HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP
|
||||||
|
* means support of contexts both inside and outside function body, so the push
|
||||||
|
* above and pop below (outside this finction) are not used.
|
||||||
|
*/
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS
|
||||||
|
/* Note that the individual warning pragmas for use inside function bodies
|
||||||
|
* are named without a _INSIDEFUNC suffix, for simplicity and legacy reasons
|
||||||
|
*/
|
||||||
|
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE
|
||||||
|
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||||
|
#endif
|
||||||
|
/* and get status tracking reply */
|
||||||
|
assert(timeout < LONG_MAX);
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (upscli_readline_timeout(ups, buf, sizeof(buf), (long)timeout) < 0)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't receive status tracking information: %s", upscli_strerror(ups));
|
||||||
|
|
||||||
|
if (strncmp(buf, "PENDING", 7))
|
||||||
|
cmd_complete = 1;
|
||||||
|
else
|
||||||
|
/* wait a second before retrying */
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s\n", buf);
|
||||||
|
}
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void clean_exit(void)
|
||||||
|
{
|
||||||
|
if (ups) {
|
||||||
|
upscli_disconnect(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(upsname);
|
||||||
|
free(hostname);
|
||||||
|
free(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t port;
|
||||||
|
ssize_t ret;
|
||||||
|
int have_un = 0, have_pw = 0, cmdlist = 0;
|
||||||
|
char buf[SMALLBUF * 2], username[SMALLBUF], password[SMALLBUF];
|
||||||
|
const char *prog = xbasename(argv[0]);
|
||||||
|
|
||||||
|
while ((i = getopt(argc, argv, "+lhu:p:t:wV")) != -1) {
|
||||||
|
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
cmdlist = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
snprintf(username, sizeof(username), "%s", optarg);
|
||||||
|
have_un = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
snprintf(password, sizeof(password), "%s", optarg);
|
||||||
|
have_pw = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 't':
|
||||||
|
if (!str_to_uint(optarg, &timeout, 10))
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Could not convert the provided value for timeout ('-t' option) to unsigned int");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'w':
|
||||||
|
tracking_enabled = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_SUCCESS); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* be a good little client that cleans up after itself */
|
||||||
|
atexit(clean_exit);
|
||||||
|
|
||||||
|
if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
ups = xcalloc(1, sizeof(*ups));
|
||||||
|
|
||||||
|
if (upscli_connect(ups, hostname, port, 0) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmdlist) {
|
||||||
|
listcmds();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* also fallback for old command names */
|
||||||
|
if (!strchr(argv[1], '.')) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: old command names are not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_un) {
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
memset(username, '\0', sizeof(username));
|
||||||
|
pw = getpwuid(getuid());
|
||||||
|
|
||||||
|
if (pw) {
|
||||||
|
printf("Username (%s): ", pw->pw_name);
|
||||||
|
} else {
|
||||||
|
printf("Username: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fgets(username, sizeof(username), stdin)) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error reading from stdin!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deal with that pesky newline */
|
||||||
|
if (strlen(username) > 1) {
|
||||||
|
username[strlen(username) - 1] = '\0';
|
||||||
|
} else {
|
||||||
|
if (!pw) {
|
||||||
|
fatalx(EXIT_FAILURE, "No username available - even tried getpwuid");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(username, sizeof(username), "%s", pw->pw_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* getpass leaks slightly - use -p when testing in valgrind */
|
||||||
|
if (!have_pw) {
|
||||||
|
/* using getpass or getpass_r might not be a
|
||||||
|
good idea here (marked obsolete in POSIX) */
|
||||||
|
char *pwtmp = GETPASS("Password: ");
|
||||||
|
|
||||||
|
if (!pwtmp) {
|
||||||
|
fatalx(EXIT_FAILURE, "getpass failed: %s", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(password, sizeof(password), "%s", pwtmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "USERNAME %s\n", username);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't set username: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = upscli_readline(ups, buf, sizeof(buf));
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
if (upscli_upserror(ups) != UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Set username failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE,
|
||||||
|
"Set username failed due to an unknown command.\n"
|
||||||
|
"You probably need to upgrade upsd.");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "PASSWORD %s\n", password);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't set password: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Set password failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable status tracking ID */
|
||||||
|
if (tracking_enabled) {
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "SET TRACKING ON\n");
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't enable command status tracking: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Enabling command status tracking failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify the result */
|
||||||
|
if (strncmp(buf, "OK", 2) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Enabling command status tracking failed. upsd answered: %s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_cmd(&argv[1], argc - 1);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||||
|
#if (defined NUT_PLATFORM_AIX)
|
||||||
|
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||||
|
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||||
|
}
|
||||||
|
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
838
clients/upsimage.c
Normal file
838
clients/upsimage.c
Normal file
|
@ -0,0 +1,838 @@
|
||||||
|
/* upsimage - cgi program to create graphical ups information reports
|
||||||
|
|
||||||
|
Status:
|
||||||
|
20020814 - Simon Rozman
|
||||||
|
- redesigned the meters
|
||||||
|
20020823 - Simon Rozman
|
||||||
|
- added support for width, height and scale_height parameters
|
||||||
|
- added support for outvolt
|
||||||
|
- noimage now writes out a clue, why upsimage failed
|
||||||
|
20020902 - Simon Rozman
|
||||||
|
- background now transparent by default
|
||||||
|
- added support for colorization parameters
|
||||||
|
- removed linear antialiasing of the scale, until I come up with a better algorithm
|
||||||
|
20020913 - Simon Rozman
|
||||||
|
- added width, height and scale_height to imgarg table
|
||||||
|
20020928 - Simon Rozman
|
||||||
|
- added imgvar table to hold description, how to draw each UPS variable supported
|
||||||
|
- added support for ACFREQ, OUT_FREQ and UPSTEMP
|
||||||
|
|
||||||
|
Copyrights:
|
||||||
|
(C) 1998 Russell Kroll <rkroll@exploits.org>
|
||||||
|
(C) 2002 Simon Rozman <simon@rozman.net>
|
||||||
|
|
||||||
|
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 "nut_stdint.h"
|
||||||
|
#include "upsclient.h"
|
||||||
|
#include "cgilib.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <gd.h>
|
||||||
|
#include <gdfontmb.h>
|
||||||
|
|
||||||
|
#include "upsimagearg.h"
|
||||||
|
|
||||||
|
#define MAX_CGI_STRLEN 64
|
||||||
|
|
||||||
|
static char *monhost = NULL, *cmd = NULL;
|
||||||
|
|
||||||
|
static uint16_t port;
|
||||||
|
static char *upsname, *hostname;
|
||||||
|
static UPSCONN_t ups;
|
||||||
|
|
||||||
|
#define RED(x) ((x >> 16) & 0xff)
|
||||||
|
#define GREEN(x) ((x >> 8) & 0xff)
|
||||||
|
#define BLUE(x) (x & 0xff)
|
||||||
|
|
||||||
|
|
||||||
|
void parsearg(char *var, char *value)
|
||||||
|
{
|
||||||
|
long long i, v; /* Be big enough to fit all expected inputs; truncate later */
|
||||||
|
|
||||||
|
/* avoid bogus junk from evil people */
|
||||||
|
if ((strlen(var) > MAX_CGI_STRLEN) || (strlen(value) > MAX_CGI_STRLEN))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!strcmp(var, "host")) {
|
||||||
|
free(monhost);
|
||||||
|
monhost = xstrdup(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(var, "display")) {
|
||||||
|
free(cmd);
|
||||||
|
cmd = xstrdup(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if this is one of the shared (upsimagearg.h) variables */
|
||||||
|
for (i = 0; imgarg[i].name != NULL; i++) {
|
||||||
|
if (!strcmp(imgarg[i].name, var)) {
|
||||||
|
if (!strncmp(value, "0x", 2))
|
||||||
|
v = (long long)strtoul(value + 2, (char **)NULL, 16);
|
||||||
|
else
|
||||||
|
v = (long long)atoi(value);
|
||||||
|
|
||||||
|
/* avoid false numbers from bad people */
|
||||||
|
if (v < imgarg[i].min)
|
||||||
|
imgarg[i].val = imgarg[i].min;
|
||||||
|
else if (v > imgarg[i].max)
|
||||||
|
imgarg[i].val = imgarg[i].max;
|
||||||
|
else {
|
||||||
|
assert (v < INT_MAX);
|
||||||
|
assert (v > INT_MIN);
|
||||||
|
imgarg[i].val = (int)v;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return the value from the URL or the default if it wasn't set */
|
||||||
|
static int get_imgarg(const char *name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; imgarg[i].name != NULL; i++)
|
||||||
|
if (!strcmp(imgarg[i].name, name))
|
||||||
|
return imgarg[i].val;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write the HTML header then have gd dump the image */
|
||||||
|
static void drawimage(gdImagePtr im)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void drawimage(gdImagePtr im)
|
||||||
|
{
|
||||||
|
printf("Pragma: no-cache\n");
|
||||||
|
printf("Content-type: image/png\n\n");
|
||||||
|
|
||||||
|
gdImagePng(im, stdout);
|
||||||
|
gdImageDestroy(im);
|
||||||
|
|
||||||
|
upscli_disconnect(&ups);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* helper function to allocate color in the image */
|
||||||
|
static int color_alloc(gdImagePtr im, int rgb)
|
||||||
|
{
|
||||||
|
return gdImageColorAllocate(im, RED(rgb), GREEN(rgb), BLUE(rgb));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws the scale behind the bar indicator */
|
||||||
|
static void drawscale(
|
||||||
|
gdImagePtr im, /* image where we would like to draw scale */
|
||||||
|
int lvllo, int lvlhi, /* min and max numbers on the scale */
|
||||||
|
int step, int step5, int step10, /* steps for minor, submajor and major dashes */
|
||||||
|
int redlo1, int redhi1, /* first red zone start and end */
|
||||||
|
int redlo2, int redhi2, /* second red zone start and end */
|
||||||
|
int grnlo, int grnhi) /* green zone start and end */
|
||||||
|
{
|
||||||
|
int col1, col2, back_color, scale_num_color, ok_zone_maj_color,
|
||||||
|
ok_zone_min_color, neutral_zone_maj_color,
|
||||||
|
neutral_zone_min_color, warn_zone_maj_color,
|
||||||
|
warn_zone_min_color;
|
||||||
|
char lbltxt[SMALLBUF];
|
||||||
|
int y, level, range;
|
||||||
|
int width, height, scale_height;
|
||||||
|
|
||||||
|
back_color = color_alloc(im, get_imgarg("back_col"));
|
||||||
|
scale_num_color = color_alloc(im, get_imgarg("scale_num_col"));
|
||||||
|
ok_zone_maj_color = color_alloc(im, get_imgarg("ok_zone_maj_col"));
|
||||||
|
ok_zone_min_color = color_alloc(im, get_imgarg("ok_zone_min_col"));
|
||||||
|
neutral_zone_maj_color = color_alloc(im, get_imgarg("neutral_zone_maj_col"));
|
||||||
|
neutral_zone_min_color = color_alloc(im, get_imgarg("neutral_zone_min_col"));
|
||||||
|
warn_zone_maj_color = color_alloc(im, get_imgarg("warn_zone_maj_col"));
|
||||||
|
warn_zone_min_color = color_alloc(im, get_imgarg("warn_zone_min_col"));
|
||||||
|
|
||||||
|
width = get_imgarg("width");
|
||||||
|
height = get_imgarg("height");
|
||||||
|
scale_height = get_imgarg("scale_height");
|
||||||
|
|
||||||
|
/* start out with a background color and make it transparent */
|
||||||
|
gdImageFilledRectangle(im, 0, 0, width, height, back_color);
|
||||||
|
gdImageColorTransparent(im, back_color);
|
||||||
|
|
||||||
|
range = lvlhi - lvllo;
|
||||||
|
|
||||||
|
/* draw scale to correspond with the values */
|
||||||
|
for (level = lvlhi; level >= lvllo; level -= step) {
|
||||||
|
/* select dash RGB color according to the level */
|
||||||
|
if (((redlo1 <= level) && (level <=redhi1)) ||
|
||||||
|
((redlo2 <= level) && (level <=redhi2))) {
|
||||||
|
col1 = warn_zone_maj_color;
|
||||||
|
col2 = warn_zone_min_color;
|
||||||
|
} else if ((grnlo <= level) && (level <= grnhi)) {
|
||||||
|
col1 = ok_zone_maj_color;
|
||||||
|
col2 = ok_zone_min_color;
|
||||||
|
} else {
|
||||||
|
col1 = neutral_zone_maj_color;
|
||||||
|
col2 = neutral_zone_min_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate integer value for y */
|
||||||
|
y = scale_height * (lvlhi - level) / range;
|
||||||
|
|
||||||
|
/* draw major, semimajor or minor dash accordingly */
|
||||||
|
if (level % step10 == 0) {
|
||||||
|
gdImageLine(im, 0, y, width, y, col1);
|
||||||
|
} else {
|
||||||
|
if (level % step5 == 0)
|
||||||
|
gdImageLine(im, 5, y, width - 5, y, col2);
|
||||||
|
else
|
||||||
|
gdImageLine(im, 10, y, width - 10, y, col2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put the values on the scale */
|
||||||
|
for (level = lvlhi; level >= lvllo; level -= step) {
|
||||||
|
if (level % step10 == 0) {
|
||||||
|
y = scale_height * (lvlhi - level) / range;
|
||||||
|
snprintf(lbltxt, sizeof(lbltxt), "%d", level);
|
||||||
|
gdImageString(im, gdFontMediumBold,
|
||||||
|
width - (int)(strlen(lbltxt)) * gdFontMediumBold->w,
|
||||||
|
y, (unsigned char *) lbltxt, scale_num_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws the bar style indicator */
|
||||||
|
static void drawbar(
|
||||||
|
int lvllo, int lvlhi, /* min and max numbers on the scale */
|
||||||
|
int step, int step5, int step10, /* steps for minor, submajor and major dashes */
|
||||||
|
int redlo1, int redhi1, /* first red zone start and end */
|
||||||
|
int redlo2, int redhi2, /* second red zone start and end */
|
||||||
|
int grnlo, int grnhi, /* green zone start and end */
|
||||||
|
double value, /* UPS variable value to draw */
|
||||||
|
const char *format /* printf style format to be used when rendering summary text */
|
||||||
|
)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void drawbar(
|
||||||
|
int lvllo, int lvlhi, /* min and max numbers on the scale */
|
||||||
|
int step, int step5, int step10, /* steps for minor, submajor and major dashes */
|
||||||
|
int redlo1, int redhi1, /* first red zone start and end */
|
||||||
|
int redlo2, int redhi2, /* second red zone start and end */
|
||||||
|
int grnlo, int grnhi, /* green zone start and end */
|
||||||
|
double value, /* UPS variable value to draw */
|
||||||
|
const char *format /* printf style format to be used when rendering summary text */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
gdImagePtr im;
|
||||||
|
int bar_color, summary_color;
|
||||||
|
char text[SMALLBUF];
|
||||||
|
int bar_y;
|
||||||
|
int width, height, scale_height;
|
||||||
|
|
||||||
|
/* get the dimension parameters */
|
||||||
|
width = get_imgarg("width");
|
||||||
|
height = get_imgarg("height");
|
||||||
|
scale_height = get_imgarg("scale_height");
|
||||||
|
|
||||||
|
/* create the image */
|
||||||
|
im = gdImageCreate(width, height);
|
||||||
|
|
||||||
|
/* draw the scale */
|
||||||
|
drawscale(im, lvllo, lvlhi, step, step5, step10, redlo1, redhi1,
|
||||||
|
redlo2, redhi2, grnlo, grnhi);
|
||||||
|
|
||||||
|
/* allocate colors for the bar and summary text */
|
||||||
|
bar_color = color_alloc(im, get_imgarg("bar_col"));
|
||||||
|
summary_color = color_alloc(im, get_imgarg("summary_col"));
|
||||||
|
|
||||||
|
/* rescale UPS value to fit in the scale */
|
||||||
|
bar_y = (int)((1.0 - (value - lvllo) / (lvlhi - lvllo)) * scale_height);
|
||||||
|
|
||||||
|
/* sanity checks: */
|
||||||
|
|
||||||
|
/* 1: if value is above maximum, then bar_y goes negative */
|
||||||
|
if (bar_y < 0)
|
||||||
|
bar_y = 0;
|
||||||
|
|
||||||
|
/* 2: if value is below minimum, bar_y goes off the scale */
|
||||||
|
if (bar_y > scale_height)
|
||||||
|
bar_y = scale_height;
|
||||||
|
|
||||||
|
/* draw it */
|
||||||
|
gdImageFilledRectangle(im, 25, bar_y, width - 25, scale_height,
|
||||||
|
bar_color);
|
||||||
|
|
||||||
|
/* stick the text version of the value at the bottom center */
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||||
|
#endif
|
||||||
|
snprintf(text, sizeof(text), format, value);
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
gdImageString(im, gdFontMediumBold,
|
||||||
|
(width - (int)(strlen(text))*gdFontMediumBold->w)/2,
|
||||||
|
height - gdFontMediumBold->h,
|
||||||
|
(unsigned char *) text, summary_color);
|
||||||
|
|
||||||
|
drawimage(im);
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws the error image */
|
||||||
|
static void noimage(const char *fmt, ...)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void noimage(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
gdImagePtr im;
|
||||||
|
int back_color, summary_color;
|
||||||
|
int width, height;
|
||||||
|
char msg[SMALLBUF];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||||
|
#endif
|
||||||
|
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
width = get_imgarg("width");
|
||||||
|
height = get_imgarg("height");
|
||||||
|
|
||||||
|
im = gdImageCreate(width, height);
|
||||||
|
back_color = color_alloc(im, get_imgarg("back_col"));
|
||||||
|
summary_color = color_alloc(im, get_imgarg("summary_col"));
|
||||||
|
|
||||||
|
gdImageFilledRectangle(im, 0, 0, width, height, back_color);
|
||||||
|
gdImageColorTransparent(im, back_color);
|
||||||
|
|
||||||
|
if (width > height)
|
||||||
|
gdImageString(im, gdFontMediumBold,
|
||||||
|
(width - (int)(strlen(msg))*gdFontMediumBold->w)/2,
|
||||||
|
(height - gdFontMediumBold->h)/2,
|
||||||
|
(unsigned char *) msg, summary_color);
|
||||||
|
else
|
||||||
|
gdImageStringUp(im, gdFontMediumBold,
|
||||||
|
(width - gdFontMediumBold->h)/2,
|
||||||
|
(height + (int)(strlen(msg))*gdFontMediumBold->w)/2,
|
||||||
|
(unsigned char *) msg, summary_color);
|
||||||
|
|
||||||
|
drawimage(im);
|
||||||
|
|
||||||
|
/* NOTE: Earlier code called noimage() and then exit(EXIT_FAILURE);
|
||||||
|
* to signal an error via process exit code. Now that drawimage()
|
||||||
|
* always ends with exit(EXIT_SUCCESS) - which might make webserver
|
||||||
|
* feel good - the command-line use if any suffers no error returns.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws bar indicator when minimum, nominal or maximum values for the given
|
||||||
|
UPS variable can be determined.
|
||||||
|
deviation < 0 means that values below nom should be grey instead of
|
||||||
|
green */
|
||||||
|
static void drawgeneralbar(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void drawgeneralbar(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
int hi, lo, step1, step5, step10, graybelownom=0;
|
||||||
|
|
||||||
|
if(deviation < 0) {
|
||||||
|
deviation=-deviation;
|
||||||
|
graybelownom=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((nom == -1) && ((min == -1) || (max == -1)))
|
||||||
|
noimage("Can't determine range");
|
||||||
|
|
||||||
|
/* if min, max and nom are mixed up, arrange them appropriately */
|
||||||
|
if (nom != -1) {
|
||||||
|
if (min == -1)
|
||||||
|
min = nom - 3*deviation;
|
||||||
|
|
||||||
|
if (max == -1)
|
||||||
|
max = nom + 3*deviation;
|
||||||
|
} else {
|
||||||
|
/* if nominal value isn't available, assume, it's the
|
||||||
|
average between min and max */
|
||||||
|
nom = (min + max) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw scale in the background */
|
||||||
|
if ((max - min) <= 50) {
|
||||||
|
/* the scale is sparse enough to draw finer scale */
|
||||||
|
step1 = 1;
|
||||||
|
step5 = 5;
|
||||||
|
step10 = 10;
|
||||||
|
} else if((max - min) <= 100) {
|
||||||
|
step1 = 2;
|
||||||
|
step5 = 10;
|
||||||
|
step10 = 20;
|
||||||
|
} else {
|
||||||
|
step1 = 5;
|
||||||
|
step5 = 20;
|
||||||
|
step10 = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* round min and max points to get high and low numbers for graph */
|
||||||
|
lo = ((min - deviation) / step10) * step10;
|
||||||
|
hi = ((max + deviation + step10/2) / step10) * step10;
|
||||||
|
|
||||||
|
if(!graybelownom) {
|
||||||
|
drawbar(lo, hi, step1, step5, step10, max, hi, lo, min,
|
||||||
|
nom - deviation, nom + deviation, var, format);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
drawbar(lo, hi, step1, step5, step10, 0, min, max, hi,
|
||||||
|
nom, max, var, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws input and output voltage bar style indicators */
|
||||||
|
static void draw_utility(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_utility(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
/* hack: deal with hardware that doesn't have known transfer points */
|
||||||
|
if (min == -1) {
|
||||||
|
if(var < 200) {
|
||||||
|
min = 90;
|
||||||
|
}
|
||||||
|
else if(var < 300) {
|
||||||
|
min = 200;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
min = 340;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* somewhere between 220 and 230 V, to keep everybody satisfied */
|
||||||
|
if (nom == -1) {
|
||||||
|
if(var < 200) {
|
||||||
|
nom = 110;
|
||||||
|
}
|
||||||
|
else if(var < 300) {
|
||||||
|
nom = 225;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nom = 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* symmetrical around nom */
|
||||||
|
if (max == -1)
|
||||||
|
max = nom+(nom-min);
|
||||||
|
|
||||||
|
/* Acceptable range of voltage is 85%-110% of nominal voltage
|
||||||
|
* in EU at least. Be conservative and say +-10% */
|
||||||
|
deviation = (int)(nom * 0.1);
|
||||||
|
|
||||||
|
drawgeneralbar(var, min, nom, max, deviation, format);
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws battery.percent bar style indicator */
|
||||||
|
static void draw_battpct(double var, int min, int nom,
|
||||||
|
int max, int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_battpct(double var, int min, int nom,
|
||||||
|
int max, int deviation, const char *format)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(nom);
|
||||||
|
NUT_UNUSED_VARIABLE(max);
|
||||||
|
NUT_UNUSED_VARIABLE(deviation);
|
||||||
|
|
||||||
|
if (min < 0) {
|
||||||
|
min = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawbar(0, 100, 2, 10, 20, 0, min, -1, -1, 80, 100, var, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws battery.voltage bar style indicator */
|
||||||
|
static void draw_battvolt(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_battvolt(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
if(nom == -1) {
|
||||||
|
/* Use a fixed set of reasonable nominal voltages, seems to
|
||||||
|
* be the only way to get reasonable behaviour during
|
||||||
|
* discharge */
|
||||||
|
|
||||||
|
if(var < 9)
|
||||||
|
nom = 6;
|
||||||
|
else if(var < 18)
|
||||||
|
nom = 12;
|
||||||
|
else if(var < 30)
|
||||||
|
nom = 24;
|
||||||
|
else if(var < 60)
|
||||||
|
nom = 48;
|
||||||
|
else if(var < 120)
|
||||||
|
nom = 96;
|
||||||
|
else if(var < 230)
|
||||||
|
nom = 192;
|
||||||
|
else
|
||||||
|
nom = 384;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(min == -1) {
|
||||||
|
min = (int)(nom/2*1.6+1); /* Assume a 2V cell is dead at 1.6V */
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max == -1) {
|
||||||
|
max = (int)(nom/2*2.3+1); /* Assume 2.3V float charge voltage */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nom < min || nom > max)
|
||||||
|
nom = -1;
|
||||||
|
|
||||||
|
deviation = (int)(-nom*0.05); /* 5% deviation from nominal voltage */
|
||||||
|
if(deviation==0) {
|
||||||
|
deviation = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawgeneralbar(var, min, nom, max, deviation, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws ups.load bar style indicator */
|
||||||
|
static void draw_upsload(double var, int min,
|
||||||
|
int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_upsload(double var, int min,
|
||||||
|
int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(min);
|
||||||
|
NUT_UNUSED_VARIABLE(nom);
|
||||||
|
NUT_UNUSED_VARIABLE(max);
|
||||||
|
NUT_UNUSED_VARIABLE(deviation);
|
||||||
|
|
||||||
|
drawbar(0, 125, 5, 5, 25, 100, 125, -1, -1, 0, 50, var, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws temperature bar style indicator */
|
||||||
|
static void draw_temperature(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_temperature(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
int hi = get_imgarg("tempmax");
|
||||||
|
int lo = get_imgarg("tempmin");
|
||||||
|
NUT_UNUSED_VARIABLE(nom);
|
||||||
|
NUT_UNUSED_VARIABLE(deviation);
|
||||||
|
|
||||||
|
drawbar(lo, hi, 1, 5, 10, lo, min, max, hi, -1, -1, var, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draws humidity bar style indicator */
|
||||||
|
static void draw_humidity(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void draw_humidity(double var, int min, int nom, int max,
|
||||||
|
int deviation, const char *format)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(nom);
|
||||||
|
NUT_UNUSED_VARIABLE(deviation);
|
||||||
|
|
||||||
|
drawbar(0, 100, 2, 10, 20, 0, min, max, 100, -1, -1, var, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_var(const char *var, char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "VAR";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = var;
|
||||||
|
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(&ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (numa < numq)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
snprintf(buf, buflen, "%s", answer[3]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char str[SMALLBUF];
|
||||||
|
int i, min, nom, max;
|
||||||
|
double var = 0;
|
||||||
|
NUT_UNUSED_VARIABLE(argc);
|
||||||
|
NUT_UNUSED_VARIABLE(argv);
|
||||||
|
|
||||||
|
extractcgiargs();
|
||||||
|
|
||||||
|
/* no 'host=' or 'display=' given */
|
||||||
|
if ((!monhost) || (!cmd))
|
||||||
|
noimage("No host or display");
|
||||||
|
|
||||||
|
if (!checkhost(monhost, NULL))
|
||||||
|
noimage("Access denied");
|
||||||
|
|
||||||
|
upsname = hostname = NULL;
|
||||||
|
|
||||||
|
if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) {
|
||||||
|
noimage("Invalid UPS definition (upsname[@hostname[:port]])\n");
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_connect(&ups, hostname, port, 0) < 0) {
|
||||||
|
noimage("Can't connect to server:\n%s\n",
|
||||||
|
upscli_strerror(&ups));
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; imgvar[i].name; i++)
|
||||||
|
if (!strcmp(cmd, imgvar[i].name)) {
|
||||||
|
|
||||||
|
/* sanity check whether we have draw function
|
||||||
|
registered with this variable */
|
||||||
|
if (!imgvar[i].drawfunc) {
|
||||||
|
noimage("Draw function N/A");
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the variable value */
|
||||||
|
if (get_var(imgvar[i].name, str, sizeof(str)) == 1) {
|
||||||
|
var = strtod(str, NULL);
|
||||||
|
} else {
|
||||||
|
/* no value, no fun */
|
||||||
|
snprintf(str, sizeof(str), "%s N/A",
|
||||||
|
imgvar[i].name);
|
||||||
|
noimage(str);
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when getting minimum, nominal and maximum values,
|
||||||
|
we first look if the marginal value is supported
|
||||||
|
by the UPS driver, if not, we look it up in the
|
||||||
|
imgarg table under the SAME name */
|
||||||
|
|
||||||
|
/* get the minimum value */
|
||||||
|
if (imgvar[i].minimum) {
|
||||||
|
if (get_var(imgvar[i].minimum, str,
|
||||||
|
sizeof(str)) == 1) {
|
||||||
|
min = atoi(str);
|
||||||
|
} else {
|
||||||
|
min = get_imgarg(imgvar[i].minimum);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
min = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the nominal value */
|
||||||
|
if (imgvar[i].nominal) {
|
||||||
|
if (get_var(imgvar[i].nominal, str,
|
||||||
|
sizeof(str)) == 1) {
|
||||||
|
nom = atoi(str);
|
||||||
|
} else {
|
||||||
|
nom = get_imgarg(imgvar[i].nominal);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nom = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the maximum value */
|
||||||
|
if (imgvar[i].maximum) {
|
||||||
|
if (get_var(imgvar[i].maximum, str,
|
||||||
|
sizeof(str)) == 1) {
|
||||||
|
max = atoi(str);
|
||||||
|
} else {
|
||||||
|
max = get_imgarg(imgvar[i].maximum);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
max = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgvar[i].drawfunc(var, min, nom, max,
|
||||||
|
imgvar[i].deviation, imgvar[i].format);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
noimage("Unknown display");
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
imgvar_t imgvar[] = {
|
||||||
|
{ "input.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L1-N.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L2-N.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L3-N.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L1-L2.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L2-L3.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "input.L3-L1.voltage", "input.transfer.low", "input.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "battery.charge", "battery.charge.low", NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_battpct },
|
||||||
|
|
||||||
|
{ "battery.voltage", "battery.voltage.low", "battery.voltage.nominal",
|
||||||
|
"battery.voltage.high", 0,
|
||||||
|
"%.1f VDC", draw_battvolt },
|
||||||
|
|
||||||
|
/* We use 'high' ASCII for the degrees symbol, since the gdImageString()
|
||||||
|
* function doesn't understand UTF-8 or HTML escape sequences. :-( */
|
||||||
|
{ "ups.temperature", "ups.temperature.low", NULL,
|
||||||
|
"ups.temperature.high", 0,
|
||||||
|
"%.1f \260C", draw_temperature },
|
||||||
|
|
||||||
|
/* Same here. */
|
||||||
|
{ "ambient.temperature", "ambient.temperature.low", NULL,
|
||||||
|
"ambient.temperature.high", 0,
|
||||||
|
"%.1f \260C", draw_temperature },
|
||||||
|
|
||||||
|
{ "ambient.humidity", "ambient.humidity.low", NULL,
|
||||||
|
"ambient.humidity.high", 0,
|
||||||
|
"%.1f %%", draw_humidity },
|
||||||
|
|
||||||
|
{ "input.frequency", NULL, "input.frequency.nominal", NULL, 2,
|
||||||
|
"%.1f Hz", drawgeneralbar },
|
||||||
|
|
||||||
|
{ "ups.load", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L1.power.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L2.power.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L3.power.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L1.realpower.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L2.realpower.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.L3.realpower.percent", NULL, NULL, NULL, 0,
|
||||||
|
"%.1f %%", draw_upsload },
|
||||||
|
|
||||||
|
{ "output.voltage", "input.transfer.low", "output.voltage.nominal",
|
||||||
|
"input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L1-N.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L2-N.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L3-N.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L1-L2.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L2-L3.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.L3-L1.voltage", "input.transfer.low",
|
||||||
|
"output.voltage.nominal", "input.transfer.high", 0,
|
||||||
|
"%.1f VAC", draw_utility },
|
||||||
|
|
||||||
|
{ "output.frequency", NULL, "output.frequency.nominal", NULL, 2,
|
||||||
|
"%.1f Hz", drawgeneralbar },
|
||||||
|
|
||||||
|
{ NULL, NULL, NULL, NULL, 0,
|
||||||
|
NULL, NULL }
|
||||||
|
};
|
81
clients/upsimagearg.h
Normal file
81
clients/upsimagearg.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/* upsimagearg.h - arguments passed between upsstats and upsimage
|
||||||
|
|
||||||
|
Copyright (C) 2002 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUT_UPSIMAGEARG_H_SEEN
|
||||||
|
#define NUT_UPSIMAGEARG_H_SEEN 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This is used in upsstats.c and in upsimage.c, but compiler complains about
|
||||||
|
* non-extern definition if this is not "static". To move or not to move?..
|
||||||
|
* Do we have cases of building binaries refering to only one of those objects?
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
char *name;
|
||||||
|
int val; /* hex digits, ala HTML */
|
||||||
|
int min; /* minimum reasonable value */
|
||||||
|
int max; /* maximum reasonable value */
|
||||||
|
} imgarg[] =
|
||||||
|
{
|
||||||
|
{ "width", 100, 50, 200 },
|
||||||
|
{ "height", 350, 100, 500 },
|
||||||
|
{ "scale_height", 300, 100, 500 },
|
||||||
|
{ "back_col", 0x000000, 0x000000, 0xffffff },
|
||||||
|
{ "scale_num_col", 0xffff00, 0x000000, 0xffffff },
|
||||||
|
{ "summary_col", 0xffff00, 0x000000, 0xffffff },
|
||||||
|
{ "ok_zone_maj_col", 0x00ff00, 0x000000, 0xffffff },
|
||||||
|
{ "ok_zone_min_col", 0x007800, 0x000000, 0xffffff },
|
||||||
|
{ "neutral_zone_maj_col", 0xffffff, 0x000000, 0xffffff },
|
||||||
|
{ "neutral_zone_min_col", 0x646464, 0x000000, 0xffffff },
|
||||||
|
{ "warn_zone_maj_col", 0xff0000, 0x000000, 0xffffff },
|
||||||
|
{ "warn_zone_min_col", 0x960000, 0x000000, 0xffffff },
|
||||||
|
{ "bar_col", 0x00ff00, 0x000000, 0xffffff },
|
||||||
|
{ "tempmin", 0, -100, 150 },
|
||||||
|
{ "tempmax", 40, -100, 150 },
|
||||||
|
{ "nom_in_freq", 50, 0, 100 },
|
||||||
|
{ "nom_out_freq", 50, 0, 100 },
|
||||||
|
{ NULL, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name; /* name of the UPS variable */
|
||||||
|
char *minimum; /* name of minimum value UPS variable
|
||||||
|
or variable in imgarg table */
|
||||||
|
char *nominal; /* as above, only for nominal value */
|
||||||
|
char *maximum; /* as above, only for maximum value */
|
||||||
|
int deviation; /* variable deviation - width of green zone */
|
||||||
|
char *format; /* format string to generate summary text */
|
||||||
|
|
||||||
|
/* pointer to drawing function */
|
||||||
|
void (*drawfunc)(double, int, int, int, int, const char*);
|
||||||
|
} imgvar_t;
|
||||||
|
|
||||||
|
extern imgvar_t imgvar[];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_UPSIMAGEARG_H_SEEN */
|
584
clients/upslog.c
Normal file
584
clients/upslog.c
Normal file
|
@ -0,0 +1,584 @@
|
||||||
|
/* upslog - log ups values to a file for later collection and analysis
|
||||||
|
|
||||||
|
Copyright (C) 1998 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Basic theory of operation:
|
||||||
|
*
|
||||||
|
* First we go through and parse as much of the status format string as
|
||||||
|
* possible. We used to do this parsing run every time, but that's a
|
||||||
|
* waste of CPU since it can't change during the program's run.
|
||||||
|
*
|
||||||
|
* This version does the parsing pass once, and creates a linked list of
|
||||||
|
* pointers to the functions that do the work and the arg they get.
|
||||||
|
*
|
||||||
|
* That means the main loop just has to run the linked list and call
|
||||||
|
* anything it finds in there. Everything happens from there, and we
|
||||||
|
* don't have to pointlessly reparse the string every time around.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "nut_platform.h"
|
||||||
|
#include "upsclient.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "timehead.h"
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
#include "upslog.h"
|
||||||
|
|
||||||
|
static int reopen_flag = 0, exit_flag = 0;
|
||||||
|
static uint16_t port;
|
||||||
|
static char *upsname, *hostname;
|
||||||
|
static UPSCONN_t ups;
|
||||||
|
|
||||||
|
static FILE *logfile;
|
||||||
|
static const char *logfn, *monhost;
|
||||||
|
static sigset_t nut_upslog_sigmask;
|
||||||
|
static char logbuffer[LARGEBUF], *logformat;
|
||||||
|
|
||||||
|
static flist_t *fhead = NULL;
|
||||||
|
|
||||||
|
#define DEFAULT_LOGFORMAT "%TIME @Y@m@d @H@M@S% %VAR battery.charge% " \
|
||||||
|
"%VAR input.voltage% %VAR ups.load% [%VAR ups.status%] " \
|
||||||
|
"%VAR ups.temperature% %VAR input.frequency%"
|
||||||
|
|
||||||
|
static void reopen_log(void)
|
||||||
|
{
|
||||||
|
if (logfile == stdout) {
|
||||||
|
upslogx(LOG_INFO, "logging to stdout");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(logfile);
|
||||||
|
logfile = fopen(logfn, "a");
|
||||||
|
if (logfile == NULL)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "could not reopen logfile %s", logfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_reopen_flag(int sig)
|
||||||
|
{
|
||||||
|
reopen_flag = sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_exit_flag(int sig)
|
||||||
|
{
|
||||||
|
exit_flag = sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_print_now_flag(int sig)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(sig);
|
||||||
|
|
||||||
|
/* no need to do anything, the signal will cause sleep to be interrupted */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handlers: reload on HUP, exit on INT/QUIT/TERM */
|
||||||
|
static void setup_signals(void)
|
||||||
|
{
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
|
sigemptyset(&nut_upslog_sigmask);
|
||||||
|
sigaddset(&nut_upslog_sigmask, SIGHUP);
|
||||||
|
sa.sa_mask = nut_upslog_sigmask;
|
||||||
|
sa.sa_handler = set_reopen_flag;
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
if (sigaction(SIGHUP, &sa, NULL) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't install SIGHUP handler");
|
||||||
|
|
||||||
|
sa.sa_handler = set_exit_flag;
|
||||||
|
if (sigaction(SIGINT, &sa, NULL) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't install SIGINT handler");
|
||||||
|
if (sigaction(SIGQUIT, &sa, NULL) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't install SIGQUIT handler");
|
||||||
|
if (sigaction(SIGTERM, &sa, NULL) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't install SIGTERM handler");
|
||||||
|
|
||||||
|
sa.sa_handler = set_print_now_flag;
|
||||||
|
if (sigaction(SIGUSR1, &sa, NULL) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't install SIGUSR1 handler");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void help(const char *prog)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void help(const char *prog)
|
||||||
|
{
|
||||||
|
printf("UPS status logger.\n");
|
||||||
|
|
||||||
|
printf("\nusage: %s [OPTIONS]\n", prog);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf(" -f <format> - Log format. See below for details.\n");
|
||||||
|
printf(" - Use -f \"<format>\" so your shell doesn't break it up.\n");
|
||||||
|
printf(" -i <interval> - Time between updates, in seconds\n");
|
||||||
|
printf(" -l <logfile> - Log file name, or - for stdout (foreground by default)\n");
|
||||||
|
printf(" -F - stay foregrounded even if logging into a file\n");
|
||||||
|
printf(" -B - stay backgrounded even if logging to stdout\n");
|
||||||
|
printf(" -p <pidbase> - Base name for PID file (defaults to \"%s\")\n", prog);
|
||||||
|
printf(" -s <ups> - Monitor UPS <ups> - <upsname>@<host>[:<port>]\n");
|
||||||
|
printf(" - Example: -s myups@server\n");
|
||||||
|
printf(" -u <user> - Switch to <user> if started as root\n");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("Some valid format string escapes:\n");
|
||||||
|
printf("\t%%%% insert a single %%\n");
|
||||||
|
printf("\t%%TIME format%% insert the time with strftime formatting\n");
|
||||||
|
printf("\t%%HOST%% insert the local hostname\n");
|
||||||
|
printf("\t%%UPSHOST%% insert the host of the ups being monitored\n");
|
||||||
|
printf("\t%%PID%% insert the pid of upslog\n");
|
||||||
|
printf("\t%%VAR varname%% insert the value of ups variable varname\n\n");
|
||||||
|
printf("format string defaults to:\n");
|
||||||
|
printf("%s\n", DEFAULT_LOGFORMAT);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
printf("See the upslog(8) man page for more information.\n");
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print current host name */
|
||||||
|
static void do_host(const char *arg)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char hn[LARGEBUF];
|
||||||
|
NUT_UNUSED_VARIABLE(arg);
|
||||||
|
|
||||||
|
ret = gethostname(hn, sizeof(hn));
|
||||||
|
|
||||||
|
if (ret != 0) {
|
||||||
|
upslog_with_errno(LOG_ERR, "gethostname failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%s", hn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_upshost(const char *arg)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(arg);
|
||||||
|
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%s", monhost);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_pid(const char *arg)
|
||||||
|
{
|
||||||
|
NUT_UNUSED_VARIABLE(arg);
|
||||||
|
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (long)getpid());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_time(const char *arg)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
char timebuf[SMALLBUF], *format;
|
||||||
|
time_t tod;
|
||||||
|
struct tm tmbuf;
|
||||||
|
|
||||||
|
format = xstrdup(arg);
|
||||||
|
|
||||||
|
/* @s are used on the command line since % is taken */
|
||||||
|
for (i = 0; i < strlen(format); i++)
|
||||||
|
if (format[i] == '@')
|
||||||
|
format[i] = '%';
|
||||||
|
|
||||||
|
time(&tod);
|
||||||
|
strftime(timebuf, sizeof(timebuf), format, localtime_r(&tod, &tmbuf));
|
||||||
|
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%s", timebuf);
|
||||||
|
|
||||||
|
free(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void getvar(const char *var)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[4];
|
||||||
|
char **answer;
|
||||||
|
|
||||||
|
query[0] = "VAR";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = var;
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(&ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if ((ret < 0) || (numa < numq)) {
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "NA");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%s", answer[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_var(const char *arg)
|
||||||
|
{
|
||||||
|
if ((!arg) || (strlen(arg) < 1)) {
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "INVALID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* old variable names are no longer supported */
|
||||||
|
if (!strchr(arg, '.')) {
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "INVALID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a UPS name is now required */
|
||||||
|
if (!upsname) {
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "INVALID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getvar(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_etime(const char *arg)
|
||||||
|
{
|
||||||
|
time_t tod;
|
||||||
|
NUT_UNUSED_VARIABLE(arg);
|
||||||
|
|
||||||
|
time(&tod);
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (unsigned long) tod);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_literal(const char *arg)
|
||||||
|
{
|
||||||
|
snprintfcat(logbuffer, sizeof(logbuffer), "%s", arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* register another parsing function to be called later */
|
||||||
|
static void add_call(void (*fptr)(const char *arg), const char *arg)
|
||||||
|
{
|
||||||
|
flist_t *tmp, *last;
|
||||||
|
|
||||||
|
tmp = last = fhead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = xmalloc(sizeof(flist_t));
|
||||||
|
|
||||||
|
tmp->fptr = fptr;
|
||||||
|
|
||||||
|
if (arg)
|
||||||
|
tmp->arg = xstrdup(arg);
|
||||||
|
else
|
||||||
|
tmp->arg = NULL;
|
||||||
|
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
last->next = tmp;
|
||||||
|
else
|
||||||
|
fhead = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* turn the format string into a list of function calls with args */
|
||||||
|
static void compile_format(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int j, found;
|
||||||
|
size_t ofs;
|
||||||
|
char *cmd, *arg, *ptr;
|
||||||
|
|
||||||
|
for (i = 0; i < strlen(logformat); i++) {
|
||||||
|
|
||||||
|
/* if not a % sequence, append character and start over */
|
||||||
|
if (logformat[i] != '%') {
|
||||||
|
char buf[4];
|
||||||
|
|
||||||
|
/* we have to stuff it into a string first */
|
||||||
|
snprintf(buf, sizeof(buf), "%c", logformat[i]);
|
||||||
|
add_call(print_literal, buf);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if a %%, append % and start over */
|
||||||
|
if (logformat[i+1] == '%') {
|
||||||
|
add_call(print_literal, "%");
|
||||||
|
|
||||||
|
/* make sure we don't parse the second % next time */
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* it must start with a % now - %<cmd>[ <arg>]%*/
|
||||||
|
|
||||||
|
cmd = xstrdup(&logformat[i+1]);
|
||||||
|
ptr = strchr(cmd, '%');
|
||||||
|
|
||||||
|
/* no trailing % = broken */
|
||||||
|
if (!ptr) {
|
||||||
|
add_call(print_literal, "INVALID");
|
||||||
|
free(cmd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
|
/* remember length (plus first %) so we can skip over it */
|
||||||
|
ofs = strlen(cmd) + 1;
|
||||||
|
|
||||||
|
/* jump out to argument (if any) */
|
||||||
|
arg = strchr(cmd, ' ');
|
||||||
|
if (arg)
|
||||||
|
*arg++ = '\0';
|
||||||
|
|
||||||
|
found = 0;
|
||||||
|
|
||||||
|
/* see if we know how to handle this command */
|
||||||
|
|
||||||
|
for (j = 0; logcmds[j].name != NULL; j++) {
|
||||||
|
if (strncasecmp(cmd, logcmds[j].name,
|
||||||
|
strlen(logcmds[j].name)) == 0) {
|
||||||
|
|
||||||
|
add_call(logcmds[j].func, arg);
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(cmd);
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
add_call(print_literal, "INVALID");
|
||||||
|
|
||||||
|
/* now do the skip ahead saved from before */
|
||||||
|
i += ofs;
|
||||||
|
|
||||||
|
} /* for (i = 0; i < strlen(logformat); i++) */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* go through the list of functions and call them in order */
|
||||||
|
static void run_flist(void)
|
||||||
|
{
|
||||||
|
flist_t *tmp;
|
||||||
|
|
||||||
|
tmp = fhead;
|
||||||
|
|
||||||
|
memset(logbuffer, 0, sizeof(logbuffer));
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
tmp->fptr(tmp->arg);
|
||||||
|
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(logfile, "%s\n", logbuffer);
|
||||||
|
fflush(logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -s <monhost>
|
||||||
|
* -l <log file>
|
||||||
|
* -i <interval>
|
||||||
|
* -f <format>
|
||||||
|
* -u <username>
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int interval = 30, i, foreground = -1;
|
||||||
|
const char *prog = xbasename(argv[0]);
|
||||||
|
time_t now, nextpoll = 0;
|
||||||
|
const char *user = NULL;
|
||||||
|
struct passwd *new_uid = NULL;
|
||||||
|
const char *pidfilebase = prog;
|
||||||
|
|
||||||
|
logformat = DEFAULT_LOGFORMAT;
|
||||||
|
user = RUN_AS_USER;
|
||||||
|
|
||||||
|
printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);
|
||||||
|
|
||||||
|
while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) {
|
||||||
|
switch(i) {
|
||||||
|
case 'h':
|
||||||
|
help(prog);
|
||||||
|
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
monhost = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
logfn = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
interval = atoi(optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
logformat = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
user = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'V':
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
pidfilebase = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F':
|
||||||
|
foreground = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'B':
|
||||||
|
foreground = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
/* not enough args for the old way? */
|
||||||
|
if ((argc == 1) || (argc == 2))
|
||||||
|
help(prog);
|
||||||
|
|
||||||
|
/* see if it's being called in the old style - 3 or 4 args */
|
||||||
|
|
||||||
|
/* <system> <logfn> <interval> [<format>] */
|
||||||
|
|
||||||
|
if (argc >= 3) {
|
||||||
|
monhost = argv[0];
|
||||||
|
logfn = argv[1];
|
||||||
|
interval = atoi(argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc >= 4) {
|
||||||
|
/* read out the remaining argv entries to the format string */
|
||||||
|
|
||||||
|
logformat = xmalloc(LARGEBUF);
|
||||||
|
memset(logformat, '\0', LARGEBUF);
|
||||||
|
|
||||||
|
for (i = 3; i < argc; i++)
|
||||||
|
snprintfcat(logformat, LARGEBUF, "%s ", argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!monhost)
|
||||||
|
fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s <system>");
|
||||||
|
|
||||||
|
if (!logfn)
|
||||||
|
fatalx(EXIT_FAILURE, "No filename defined for logging - use -l <file>");
|
||||||
|
|
||||||
|
/* shouldn't happen */
|
||||||
|
if (!logformat)
|
||||||
|
fatalx(EXIT_FAILURE, "No format defined - but this should be impossible");
|
||||||
|
|
||||||
|
printf("logging status of %s to %s (%is intervals)\n",
|
||||||
|
monhost, logfn, interval);
|
||||||
|
|
||||||
|
if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0)
|
||||||
|
fprintf(stderr, "Warning: initial connect failed: %s\n",
|
||||||
|
upscli_strerror(&ups));
|
||||||
|
|
||||||
|
if (strcmp(logfn, "-") == 0)
|
||||||
|
logfile = stdout;
|
||||||
|
else
|
||||||
|
logfile = fopen(logfn, "a");
|
||||||
|
|
||||||
|
if (logfile == NULL)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn);
|
||||||
|
|
||||||
|
/* now drop root if we have it */
|
||||||
|
new_uid = get_user_pwent(user);
|
||||||
|
|
||||||
|
open_syslog(prog);
|
||||||
|
|
||||||
|
if (foreground < 0) {
|
||||||
|
if (logfile == stdout) {
|
||||||
|
foreground = 1;
|
||||||
|
} else {
|
||||||
|
foreground = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foreground) {
|
||||||
|
background();
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_signals();
|
||||||
|
|
||||||
|
writepid(pidfilebase);
|
||||||
|
|
||||||
|
become_user(new_uid);
|
||||||
|
|
||||||
|
compile_format();
|
||||||
|
|
||||||
|
while (exit_flag == 0) {
|
||||||
|
time(&now);
|
||||||
|
|
||||||
|
if (nextpoll > now) {
|
||||||
|
/* there is still time left, so sleep it off */
|
||||||
|
sleep((unsigned int)(difftime(nextpoll, now)));
|
||||||
|
nextpoll += interval;
|
||||||
|
} else {
|
||||||
|
/* we spent more time in polling than the interval allows */
|
||||||
|
nextpoll = now + interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reopen_flag) {
|
||||||
|
upslogx(LOG_INFO, "Signal %d: reopening log file",
|
||||||
|
reopen_flag);
|
||||||
|
reopen_log();
|
||||||
|
reopen_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reconnect if necessary */
|
||||||
|
if (upscli_fd(&ups) < 0) {
|
||||||
|
upscli_connect(&ups, hostname, port, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
run_flist();
|
||||||
|
|
||||||
|
/* don't keep connection open if we don't intend to use it shortly */
|
||||||
|
if (interval > 30) {
|
||||||
|
upscli_disconnect(&ups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
upslogx(LOG_INFO, "Signal %d: exiting", exit_flag);
|
||||||
|
|
||||||
|
if (logfile != stdout)
|
||||||
|
fclose(logfile);
|
||||||
|
|
||||||
|
upscli_disconnect(&ups);
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||||
|
#if (defined NUT_PLATFORM_AIX)
|
||||||
|
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||||
|
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||||
|
}
|
||||||
|
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
49
clients/upslog.h
Normal file
49
clients/upslog.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* upslog.h - table of functions for handling various logging functions */
|
||||||
|
|
||||||
|
#ifndef NUT_UPSLOG_H_SEEN
|
||||||
|
#define NUT_UPSLOG_H_SEEN 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* function list */
|
||||||
|
typedef struct flist_s {
|
||||||
|
void (*fptr)(const char *arg);
|
||||||
|
const char *arg;
|
||||||
|
struct flist_s *next;
|
||||||
|
} flist_t;
|
||||||
|
|
||||||
|
static void do_host(const char *arg);
|
||||||
|
static void do_upshost(const char *arg);
|
||||||
|
static void do_pid(const char *arg);
|
||||||
|
static void do_time(const char *arg);
|
||||||
|
static void do_var(const char *arg);
|
||||||
|
static void do_etime(const char *arg);
|
||||||
|
|
||||||
|
/* This is only used in upslog.c, but refers to routines declared here...
|
||||||
|
* To move or not to move?..
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
void (*func)(const char *arg);
|
||||||
|
} logcmds[] =
|
||||||
|
{
|
||||||
|
{ "HOST", do_host },
|
||||||
|
{ "UPSHOST", do_upshost },
|
||||||
|
{ "PID", do_pid },
|
||||||
|
{ "TIME", do_time },
|
||||||
|
{ "VAR", do_var },
|
||||||
|
{ "ETIME", do_etime },
|
||||||
|
{ NULL, (void(*)(const char*))(NULL) }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_UPSLOG_H_SEEN */
|
2319
clients/upsmon.c
Normal file
2319
clients/upsmon.c
Normal file
File diff suppressed because it is too large
Load diff
136
clients/upsmon.h
Normal file
136
clients/upsmon.h
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
/* upsmon.h - headers and other useful things for upsmon.h
|
||||||
|
|
||||||
|
Copyright (C) 2000 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUT_UPSMON_H_SEEN
|
||||||
|
#define NUT_UPSMON_H_SEEN 1
|
||||||
|
|
||||||
|
/* flags for ups->status */
|
||||||
|
|
||||||
|
#define ST_ONLINE (1 << 0) /* UPS is on line (OL) */
|
||||||
|
#define ST_ONBATT (1 << 1) /* UPS is on battery (OB) */
|
||||||
|
#define ST_LOWBATT (1 << 2) /* UPS has a low battery (LB) */
|
||||||
|
#define ST_FSD (1 << 3) /* primary has set forced shutdown flag */
|
||||||
|
#define ST_PRIMARY (1 << 4) /* we are the primary (manager) of this UPS */
|
||||||
|
#define ST_MASTER ST_PRIMARY /* legacy alias */
|
||||||
|
#define ST_LOGIN (1 << 5) /* we are logged into this UPS */
|
||||||
|
#define ST_CONNECTED (1 << 6) /* upscli_connect returned OK */
|
||||||
|
#define ST_CAL (1 << 7) /* UPS calibration in progress (CAL) */
|
||||||
|
|
||||||
|
/* required contents of flag file */
|
||||||
|
#define SDMAGIC "upsmon-shutdown-file"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* UPS tracking structure */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UPSCONN_t conn; /* upsclient state descriptor */
|
||||||
|
|
||||||
|
char *sys; /* raw system name from .conf */
|
||||||
|
char *upsname; /* just upsname */
|
||||||
|
char *hostname; /* just hostname */
|
||||||
|
uint16_t port; /* just the port */
|
||||||
|
|
||||||
|
unsigned int pv; /* power value from conf */
|
||||||
|
char *un; /* username (optional for now) */
|
||||||
|
char *pw; /* password from conf */
|
||||||
|
int status; /* status (see flags above) */
|
||||||
|
int retain; /* tracks deletions at reload */
|
||||||
|
|
||||||
|
/* handle suppression of COMMOK and ONLINE at startup */
|
||||||
|
int commstate; /* these start at -1, and only */
|
||||||
|
int linestate; /* fire on a 0->1 transition */
|
||||||
|
|
||||||
|
time_t lastpoll; /* time of last successful poll */
|
||||||
|
time_t lastnoncrit; /* time of last non-crit poll */
|
||||||
|
time_t lastrbwarn; /* time of last REPLBATT warning*/
|
||||||
|
time_t lastncwarn; /* time of last NOCOMM warning */
|
||||||
|
void *next;
|
||||||
|
} utype_t;
|
||||||
|
|
||||||
|
/* notify identifiers */
|
||||||
|
|
||||||
|
#define NOTIFY_ONLINE 0 /* UPS went on-line */
|
||||||
|
#define NOTIFY_ONBATT 1 /* UPS went on battery */
|
||||||
|
#define NOTIFY_LOWBATT 2 /* UPS went to low battery */
|
||||||
|
#define NOTIFY_FSD 3 /* Primary upsmon set FSD flag */
|
||||||
|
#define NOTIFY_COMMOK 4 /* Communication established */
|
||||||
|
#define NOTIFY_COMMBAD 5 /* Communication lost */
|
||||||
|
#define NOTIFY_SHUTDOWN 6 /* System shutdown in progress */
|
||||||
|
#define NOTIFY_REPLBATT 7 /* UPS battery needs to be replaced */
|
||||||
|
#define NOTIFY_NOCOMM 8 /* UPS hasn't been contacted in a while */
|
||||||
|
#define NOTIFY_NOPARENT 9 /* privileged parent process died */
|
||||||
|
#define NOTIFY_CAL 10 /* UPS is performing calibration */
|
||||||
|
|
||||||
|
/* notify flag values */
|
||||||
|
|
||||||
|
#define NOTIFY_IGNORE (1 << 0) /* don't do anything */
|
||||||
|
#define NOTIFY_SYSLOG (1 << 1) /* send the msg to the syslog */
|
||||||
|
#define NOTIFY_WALL (1 << 2) /* send the msg to all users */
|
||||||
|
#define NOTIFY_EXEC (1 << 3) /* send the msg to NOTIFYCMD script */
|
||||||
|
|
||||||
|
/* flags are set to NOTIFY_SYSLOG | NOTIFY_WALL at program init */
|
||||||
|
/* the user can override with NOTIFYFLAGS in the upsmon.conf */
|
||||||
|
|
||||||
|
/* This is only used in upsmon.c, but might it also have external consumers?..
|
||||||
|
* To move or not to move?..
|
||||||
|
*/
|
||||||
|
static struct {
|
||||||
|
int type;
|
||||||
|
const char *name;
|
||||||
|
char *msg; /* NULL until overridden */
|
||||||
|
const char *stockmsg;
|
||||||
|
int flags;
|
||||||
|
} notifylist[] =
|
||||||
|
{
|
||||||
|
{ NOTIFY_ONLINE, "ONLINE", NULL, "UPS %s on line power", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_ONBATT, "ONBATT", NULL, "UPS %s on battery", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_LOWBATT, "LOWBATT", NULL, "UPS %s battery is low", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_FSD, "FSD", NULL, "UPS %s: forced shutdown in progress", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_COMMOK, "COMMOK", NULL, "Communications with UPS %s established", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_COMMBAD, "COMMBAD", NULL, "Communications with UPS %s lost", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_SHUTDOWN, "SHUTDOWN", NULL, "Auto logout and shutdown proceeding", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_REPLBATT, "REPLBATT", NULL, "UPS %s battery needs to be replaced", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_NOCOMM, "NOCOMM", NULL, "UPS %s is unavailable", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_NOPARENT, "NOPARENT", NULL, "upsmon parent process died - shutdown impossible", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||||
|
{ NOTIFY_CAL, "CAL", NULL, "UPS %s: calibration in progress", NOTIFY_SYSLOG },
|
||||||
|
{ 0, NULL, NULL, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* values for signals passed between processes */
|
||||||
|
|
||||||
|
#define SIGCMD_FSD SIGUSR1
|
||||||
|
#define SIGCMD_STOP SIGTERM
|
||||||
|
#define SIGCMD_RELOAD SIGHUP
|
||||||
|
|
||||||
|
/* various constants */
|
||||||
|
|
||||||
|
#define NET_TIMEOUT 10 /* wait 10 seconds max for upsd to respond */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_UPSMON_H_SEEN */
|
711
clients/upsrw.c
Normal file
711
clients/upsrw.c
Normal file
|
@ -0,0 +1,711 @@
|
||||||
|
/* upsrw - simple client for read/write variable access (formerly upsct2)
|
||||||
|
|
||||||
|
Copyright (C)
|
||||||
|
1999 Russell Kroll <rkroll@exploits.org>
|
||||||
|
2019 EATON (author: Arnaud Quette <ArnaudQuette@eaton.com>)
|
||||||
|
|
||||||
|
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 "nut_platform.h"
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
#include "upsclient.h"
|
||||||
|
#include "extstate.h"
|
||||||
|
|
||||||
|
static char *upsname = NULL, *hostname = NULL;
|
||||||
|
static UPSCONN_t *ups = NULL;
|
||||||
|
static int tracking_enabled = 0;
|
||||||
|
static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT;
|
||||||
|
|
||||||
|
struct list_t {
|
||||||
|
char *name;
|
||||||
|
struct list_t *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(const char *prog)
|
||||||
|
{
|
||||||
|
printf("Network UPS Tools %s %s\n\n", prog, UPS_VERSION);
|
||||||
|
printf("usage: %s [-h]\n", prog);
|
||||||
|
printf(" %s [-s <variable>] [-u <username>] [-p <password>] [-w] [-t <timeout>] <ups>\n\n", prog);
|
||||||
|
printf("Demo program to set variables within UPS hardware.\n");
|
||||||
|
printf("\n");
|
||||||
|
printf(" -h display this help text\n");
|
||||||
|
printf(" -s <variable> specify variable to be changed\n");
|
||||||
|
printf(" use -s VAR=VALUE to avoid prompting for value\n");
|
||||||
|
printf(" -l show all possible read/write variables.\n");
|
||||||
|
printf(" -u <username> set username for command authentication\n");
|
||||||
|
printf(" -p <password> set password for command authentication\n");
|
||||||
|
printf(" -w wait for the completion of setting by the driver\n");
|
||||||
|
printf(" and return its actual result from the device\n");
|
||||||
|
printf(" -t <timeout> set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT);
|
||||||
|
printf("\n");
|
||||||
|
printf(" <ups> UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Call without -s to show all possible read/write variables (same as -l).\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clean_exit(void)
|
||||||
|
{
|
||||||
|
if (ups) {
|
||||||
|
upscli_disconnect(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(upsname);
|
||||||
|
free(hostname);
|
||||||
|
free(ups);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC)
|
||||||
|
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||||
|
#endif
|
||||||
|
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC)
|
||||||
|
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||||
|
#endif
|
||||||
|
static void do_set(const char *varname, const char *newval)
|
||||||
|
{
|
||||||
|
int cmd_complete = 0;
|
||||||
|
char buf[SMALLBUF], enc[SMALLBUF];
|
||||||
|
char tracking_id[UUID4_LEN];
|
||||||
|
time_t start, now;
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n", upsname, varname, pconf_encode(newval, enc, sizeof(enc)));
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't set variable: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Set variable failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify answer */
|
||||||
|
if (strncmp(buf, "OK", 2) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for status tracking id */
|
||||||
|
if (
|
||||||
|
!tracking_enabled ||
|
||||||
|
/* sanity check on the size: "OK TRACKING " + UUID4_LEN */
|
||||||
|
strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING "))
|
||||||
|
) {
|
||||||
|
/* reply as usual */
|
||||||
|
fprintf(stderr, "%s\n", buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||||
|
#endif
|
||||||
|
/* From the check above, we know that we have exactly UUID4_LEN chars
|
||||||
|
* (aka sizeof(tracking_id)) in the buf after "OK TRACKING " prefix,
|
||||||
|
* plus the null-byte.
|
||||||
|
*/
|
||||||
|
assert (UUID4_LEN == 1 + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")));
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
time(&start);
|
||||||
|
|
||||||
|
/* send status tracking request, looping if status is PENDING */
|
||||||
|
while (!cmd_complete) {
|
||||||
|
|
||||||
|
/* check for timeout */
|
||||||
|
time(&now);
|
||||||
|
if (difftime(now, start) >= timeout)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout");
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, buf, strlen(buf)) < 0)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups));
|
||||||
|
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||||
|
/* Note for gating macros above: unsuffixed HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP
|
||||||
|
* means support of contexts both inside and outside function body, so the push
|
||||||
|
* above and pop below (outside this finction) are not used.
|
||||||
|
*/
|
||||||
|
# pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS
|
||||||
|
/* Note that the individual warning pragmas for use inside function bodies
|
||||||
|
* are named without a _INSIDEFUNC suffix, for simplicity and legacy reasons
|
||||||
|
*/
|
||||||
|
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE
|
||||||
|
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||||
|
#endif
|
||||||
|
/* and get status tracking reply */
|
||||||
|
assert(timeout < LONG_MAX);
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (upscli_readline_timeout(ups, buf, sizeof(buf), (long)timeout) < 0)
|
||||||
|
fatalx(EXIT_FAILURE, "Can't receive status tracking information: %s", upscli_strerror(ups));
|
||||||
|
|
||||||
|
if (strncmp(buf, "PENDING", 7))
|
||||||
|
cmd_complete = 1;
|
||||||
|
else
|
||||||
|
/* wait a second before retrying */
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s\n", buf);
|
||||||
|
}
|
||||||
|
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||||
|
# pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void do_setvar(const char *varname, char *uin, const char *pass)
|
||||||
|
{
|
||||||
|
char newval[SMALLBUF], temp[SMALLBUF * 2], user[SMALLBUF], *ptr;
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
if (uin) {
|
||||||
|
snprintf(user, sizeof(user), "%s", uin);
|
||||||
|
} else {
|
||||||
|
memset(user, '\0', sizeof(user));
|
||||||
|
|
||||||
|
pw = getpwuid(getuid());
|
||||||
|
|
||||||
|
if (pw) {
|
||||||
|
printf("Username (%s): ", pw->pw_name);
|
||||||
|
} else {
|
||||||
|
printf("Username: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fgets(user, sizeof(user), stdin) == NULL) {
|
||||||
|
upsdebug_with_errno(LOG_INFO, "%s", __func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deal with that pesky newline */
|
||||||
|
if (strlen(user) > 1) {
|
||||||
|
user[strlen(user) - 1] = '\0';
|
||||||
|
} else {
|
||||||
|
if (!pw) {
|
||||||
|
fatalx(EXIT_FAILURE, "No username available - even tried getpwuid");
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(user, sizeof(user), "%s", pw->pw_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* leaks - use -p when running in valgrind */
|
||||||
|
if (!pass) {
|
||||||
|
pass = GETPASS("Password: " );
|
||||||
|
|
||||||
|
if (!pass) {
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "getpass failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if varname is in VAR=VALUE form */
|
||||||
|
if ((ptr = strchr(varname, '=')) != NULL) {
|
||||||
|
*ptr++ = 0;
|
||||||
|
snprintf(newval, sizeof(newval), "%s", ptr);
|
||||||
|
} else {
|
||||||
|
printf("Enter new value for %s: ", varname);
|
||||||
|
fflush(stdout);
|
||||||
|
if (fgets(newval, sizeof(newval), stdin) == NULL) {
|
||||||
|
upsdebug_with_errno(LOG_INFO, "%s", __func__);
|
||||||
|
}
|
||||||
|
newval[strlen(newval) - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(temp, sizeof(temp), "USERNAME %s\n", user);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't set username: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||||
|
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Set username failed due to an unknown command. You probably need to upgrade upsd.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Set username failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(temp, sizeof(temp), "PASSWORD %s\n", pass);
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't set password: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Set password failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no upsname means die */
|
||||||
|
if (!upsname) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* old variable names are no longer supported */
|
||||||
|
if (!strchr(varname, '.')) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: old variable names are not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable status tracking ID */
|
||||||
|
if (tracking_enabled) {
|
||||||
|
|
||||||
|
snprintf(temp, sizeof(temp), "SET TRACKING ON\n");
|
||||||
|
|
||||||
|
if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Can't enable set variable status tracking: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Enabling set variable status tracking failed: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify the result */
|
||||||
|
if (strncmp(temp, "OK", 2) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Enabling set variable status tracking failed. upsd answered: %s", temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_set(varname, newval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *get_data(const char *type, const char *varname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
char **answer;
|
||||||
|
const char *query[4];
|
||||||
|
|
||||||
|
query[0] = type;
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = varname;
|
||||||
|
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if ((ret < 0) || (numa < numq)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* <type> <upsname> <varname> <desc> */
|
||||||
|
return answer[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_string(const char *varname, const long len)
|
||||||
|
{
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
val = get_data("VAR", varname);
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
fatalx(EXIT_FAILURE, "do_string: can't get current value of %s", varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Type: STRING\n");
|
||||||
|
printf("Maximum length: %ld\n", len);
|
||||||
|
printf("Value: %s\n", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_number(const char *varname)
|
||||||
|
{
|
||||||
|
const char *val;
|
||||||
|
|
||||||
|
val = get_data("VAR", varname);
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
fatalx(EXIT_FAILURE, "do_number: can't get current value of %s", varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Type: NUMBER\n");
|
||||||
|
printf("Value: %s\n", val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display ENUM information
|
||||||
|
* @param varname the name of the NUT variable
|
||||||
|
* @param vartype the type of the NUT variable (ST_FLAG_STRING, ST_FLAG_NUMBER
|
||||||
|
* @param len the length of the NUT variable, if type == ST_FLAG_STRING
|
||||||
|
*/
|
||||||
|
static void do_enum(const char *varname, const int vartype, const long len)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
char **answer, buf[SMALLBUF];
|
||||||
|
const char *query[4], *val;
|
||||||
|
|
||||||
|
/* get current value */
|
||||||
|
val = get_data("VAR", varname);
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
fatalx(EXIT_FAILURE, "do_enum: can't get current value of %s", varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s", val);
|
||||||
|
|
||||||
|
query[0] = "ENUM";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = varname;
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
/* Fallback for older upsd versions */
|
||||||
|
if (vartype != ST_FLAG_NONE)
|
||||||
|
printf("Type: ENUM %s\n", (vartype == ST_FLAG_STRING)?"STRING":"NUMBER");
|
||||||
|
else
|
||||||
|
printf("Type: ENUM\n");
|
||||||
|
|
||||||
|
if (vartype == ST_FLAG_STRING)
|
||||||
|
printf("Maximum length: %ld\n", len);
|
||||||
|
|
||||||
|
while (ret == 1) {
|
||||||
|
|
||||||
|
/* ENUM <upsname> <varname> <value> */
|
||||||
|
|
||||||
|
if (numa < 4) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Option: \"%s\"", answer[3]);
|
||||||
|
|
||||||
|
if (!strcmp(answer[3], buf)) {
|
||||||
|
printf(" SELECTED");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_range(const char *varname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
char **answer;
|
||||||
|
const char *query[4], *val;
|
||||||
|
int ival, min, max;
|
||||||
|
|
||||||
|
/* get current value */
|
||||||
|
val = get_data("VAR", varname);
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
fatalx(EXIT_FAILURE, "do_range: can't get current value of %s", varname);
|
||||||
|
}
|
||||||
|
|
||||||
|
ival = atoi(val);
|
||||||
|
|
||||||
|
query[0] = "RANGE";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = varname;
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
/* Ranges implies a type "NUMBER" */
|
||||||
|
printf("Type: RANGE NUMBER\n");
|
||||||
|
|
||||||
|
while (ret == 1) {
|
||||||
|
|
||||||
|
/* RANGE <upsname> <varname> <min> <max> */
|
||||||
|
|
||||||
|
if (numa < 5) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
min = atoi(answer[3]);
|
||||||
|
max = atoi(answer[4]);
|
||||||
|
|
||||||
|
printf("Option: \"%i-%i\"", min, max);
|
||||||
|
|
||||||
|
if ((ival >= min) && (ival <= max)) {
|
||||||
|
printf(" SELECTED");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_type(const char *varname)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int is_enum = 0; /* 1 if ENUM; FIXME: add a boolean type in common.h */
|
||||||
|
size_t i, numq, numa;
|
||||||
|
char **answer;
|
||||||
|
const char *query[4];
|
||||||
|
|
||||||
|
query[0] = "TYPE";
|
||||||
|
query[1] = upsname;
|
||||||
|
query[2] = varname;
|
||||||
|
numq = 3;
|
||||||
|
|
||||||
|
ret = upscli_get(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
if ((ret < 0) || (numa < numq)) {
|
||||||
|
printf("Unknown type\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TYPE <upsname> <varname> <type>... */
|
||||||
|
for (i = 3; i < numa; i++) {
|
||||||
|
|
||||||
|
/* ENUM can be NUMBER or STRING
|
||||||
|
* just flag it for latter processing */
|
||||||
|
if (!strcasecmp(answer[i], "ENUM")) {
|
||||||
|
is_enum = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(answer[i], "RANGE")) {
|
||||||
|
do_range(varname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncasecmp(answer[i], "STRING:", 7)) {
|
||||||
|
|
||||||
|
char *len = answer[i] + 7;
|
||||||
|
long length = strtol(len, NULL, 10);
|
||||||
|
|
||||||
|
if (is_enum == 1)
|
||||||
|
do_enum(varname, ST_FLAG_STRING, length);
|
||||||
|
else
|
||||||
|
do_string(varname, length);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(answer[i], "NUMBER")) {
|
||||||
|
if (is_enum == 1)
|
||||||
|
do_enum(varname, ST_FLAG_NUMBER, 0);
|
||||||
|
else
|
||||||
|
do_number(varname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore this one */
|
||||||
|
if (!strcasecmp(answer[i], "RW")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Type: %s (unrecognized)\n", answer[i]);
|
||||||
|
}
|
||||||
|
/* Fallback for older upsd versions, where STRING|NUMBER is not
|
||||||
|
* appended to ENUM */
|
||||||
|
if (is_enum == 1)
|
||||||
|
do_enum(varname, ST_FLAG_NONE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_rw(const char *varname)
|
||||||
|
{
|
||||||
|
const char *tmp;
|
||||||
|
|
||||||
|
printf("[%s]\n", varname);
|
||||||
|
|
||||||
|
tmp = get_data("DESC", varname);
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
printf("%s\n", tmp);
|
||||||
|
} else {
|
||||||
|
printf("Description unavailable\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
do_type(varname);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_rwlist(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t numq, numa;
|
||||||
|
const char *query[2];
|
||||||
|
char **answer;
|
||||||
|
struct list_t *lhead, *llast, *ltmp, *lnext;
|
||||||
|
|
||||||
|
/* the upsname is now required */
|
||||||
|
if (!upsname) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: a UPS name must be specified (upsname[@hostname[:port]])");
|
||||||
|
}
|
||||||
|
|
||||||
|
llast = lhead = NULL;
|
||||||
|
|
||||||
|
query[0] = "RW";
|
||||||
|
query[1] = upsname;
|
||||||
|
numq = 2;
|
||||||
|
|
||||||
|
ret = upscli_list_start(ups, numq, query);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
|
||||||
|
/* old upsd --> fall back on old LISTRW technique */
|
||||||
|
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: upsd is too old to support this query");
|
||||||
|
}
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
|
||||||
|
while (ret == 1) {
|
||||||
|
|
||||||
|
/* RW <upsname> <varname> <value> */
|
||||||
|
if (numa < 4) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sock this entry away for later */
|
||||||
|
|
||||||
|
ltmp = xmalloc(sizeof(struct list_t));
|
||||||
|
ltmp->name = xstrdup(answer[2]);
|
||||||
|
ltmp->next = NULL;
|
||||||
|
|
||||||
|
if (llast) {
|
||||||
|
llast->next = ltmp;
|
||||||
|
} else {
|
||||||
|
lhead = ltmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
llast = ltmp;
|
||||||
|
|
||||||
|
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* use the list to get descriptions and types */
|
||||||
|
|
||||||
|
ltmp = lhead;
|
||||||
|
|
||||||
|
while (ltmp) {
|
||||||
|
lnext = ltmp->next;
|
||||||
|
|
||||||
|
print_rw(ltmp->name);
|
||||||
|
|
||||||
|
free(ltmp->name);
|
||||||
|
free(ltmp);
|
||||||
|
ltmp = lnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
uint16_t port;
|
||||||
|
const char *prog = xbasename(argv[0]);
|
||||||
|
char *password = NULL, *username = NULL, *setvar = NULL;
|
||||||
|
|
||||||
|
while ((i = getopt(argc, argv, "+hls:p:t:u:wV")) != -1) {
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
setvar = optarg;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
if (setvar) {
|
||||||
|
upslogx(LOG_WARNING, "Listing mode requested, overriding setvar specified earlier!");
|
||||||
|
setvar = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
password = optarg;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
if (!str_to_uint(optarg, &timeout, 10))
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Could not convert the provided value for timeout ('-t' option) to unsigned int");
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
username = optarg;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
tracking_enabled = 1;
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
usage(prog);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* be a good little client that cleans up after itself */
|
||||||
|
atexit(clean_exit);
|
||||||
|
|
||||||
|
if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
ups = xcalloc(1, sizeof(*ups));
|
||||||
|
|
||||||
|
if (upscli_connect(ups, hostname, port, 0) < 0) {
|
||||||
|
fatalx(EXIT_FAILURE, "Error: %s", upscli_strerror(ups));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setvar) {
|
||||||
|
/* setting a variable */
|
||||||
|
do_setvar(setvar, username, password);
|
||||||
|
} else {
|
||||||
|
/* if not, get the list of supported read/write variables */
|
||||||
|
print_rwlist();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||||
|
#if (defined NUT_PLATFORM_AIX)
|
||||||
|
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||||
|
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||||
|
}
|
||||||
|
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
32
clients/upssched-cmd
Executable file
32
clients/upssched-cmd
Executable file
|
@ -0,0 +1,32 @@
|
||||||
|
#! /bin/sh
|
||||||
|
#
|
||||||
|
# This script should be called by upssched via the CMDSCRIPT directive.
|
||||||
|
#
|
||||||
|
# Here is a quick example to show how to handle a bunch of possible
|
||||||
|
# timer names with the help of the case structure.
|
||||||
|
#
|
||||||
|
# This script may be replaced with another program without harm.
|
||||||
|
#
|
||||||
|
# The first argument passed to your CMDSCRIPT is the name of the timer
|
||||||
|
# from your AT lines.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
onbattwarn)
|
||||||
|
# Send a notification mail
|
||||||
|
echo "The UPS has been on battery for awhile" \
|
||||||
|
| mail -s"UPS monitor" bofh@pager.example.com
|
||||||
|
# Create a flag-file on the filesystem, for your own processing
|
||||||
|
/usr/bin/touch /some/path/ups-on-battery
|
||||||
|
;;
|
||||||
|
ups-back-on-power)
|
||||||
|
# Delete the flag-file on the filesystem
|
||||||
|
/bin/rm -f /some/path/ups-on-battery
|
||||||
|
;;
|
||||||
|
upsgone)
|
||||||
|
logger -t upssched-cmd "The communication with UPS has been gone for awhile"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
logger -t upssched-cmd "Unrecognized command: $1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
983
clients/upssched.c
Normal file
983
clients/upssched.c
Normal file
|
@ -0,0 +1,983 @@
|
||||||
|
/* upssched.c - upsmon's scheduling helper for offset timers
|
||||||
|
|
||||||
|
Copyright (C) 2000 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* design notes for the curious:
|
||||||
|
*
|
||||||
|
* 1. we get called with a upsname and notifytype from upsmon
|
||||||
|
* 2. the config file is searched for an AT condition that matches
|
||||||
|
* 3. the conditions on any matching lines are parsed
|
||||||
|
*
|
||||||
|
* starting a timer: the timer is added to the daemon's timer queue
|
||||||
|
* cancelling a timer: the timer is removed from that queue
|
||||||
|
* execute a command: the command is passed straight to the cmdscript
|
||||||
|
*
|
||||||
|
* if the daemon is not already running and is required (to start a timer)
|
||||||
|
* it will be started automatically
|
||||||
|
*
|
||||||
|
* when the time arrives, the command associated with a timer will be
|
||||||
|
* executed by the daemon (via the cmdscript)
|
||||||
|
*
|
||||||
|
* timers can be cancelled at any time before they trigger
|
||||||
|
*
|
||||||
|
* the daemon will shut down automatically when no more timers are active
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "upssched.h"
|
||||||
|
#include "timehead.h"
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
|
||||||
|
typedef struct ttype_s {
|
||||||
|
char *name;
|
||||||
|
time_t etime;
|
||||||
|
struct ttype_s *next;
|
||||||
|
} ttype_t;
|
||||||
|
|
||||||
|
static ttype_t *thead = NULL;
|
||||||
|
static conn_t *connhead = NULL;
|
||||||
|
static char *cmdscript = NULL, *pipefn = NULL, *lockfn = NULL;
|
||||||
|
static int verbose = 0; /* use for debugging */
|
||||||
|
|
||||||
|
/* ups name and notify type (string) as received from upsmon */
|
||||||
|
static const char *upsname, *notify_type;
|
||||||
|
|
||||||
|
#define PARENT_STARTED -2
|
||||||
|
#define PARENT_UNNECESSARY -3
|
||||||
|
#define MAX_TRIES 30
|
||||||
|
#define EMPTY_WAIT 15 /* min passes with no timers to exit */
|
||||||
|
#define US_LISTEN_BACKLOG 16
|
||||||
|
#define US_SOCK_BUF_LEN 256
|
||||||
|
#define US_MAX_READ 128
|
||||||
|
|
||||||
|
/* --- server functions --- */
|
||||||
|
|
||||||
|
static void exec_cmd(const char *cmd)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char buf[LARGEBUF];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%s %s", cmdscript, cmd);
|
||||||
|
|
||||||
|
err = system(buf);
|
||||||
|
if (WIFEXITED(err)) {
|
||||||
|
if (WEXITSTATUS(err)) {
|
||||||
|
upslogx(LOG_INFO, "exec_cmd(%s) returned %d", buf, WEXITSTATUS(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (WIFSIGNALED(err)) {
|
||||||
|
upslogx(LOG_WARNING, "exec_cmd(%s) terminated with signal %d", buf, WTERMSIG(err));
|
||||||
|
} else {
|
||||||
|
upslogx(LOG_ERR, "Execute command failure: %s", buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removetimer(ttype_t *tfind)
|
||||||
|
{
|
||||||
|
ttype_t *tmp, *last;
|
||||||
|
|
||||||
|
last = NULL;
|
||||||
|
tmp = thead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
if (tmp == tfind) { /* found it */
|
||||||
|
if (last == NULL) /* deleting first */
|
||||||
|
thead = tmp->next;
|
||||||
|
else
|
||||||
|
last->next = tmp->next;
|
||||||
|
|
||||||
|
free(tmp->name);
|
||||||
|
free(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this one should never happen */
|
||||||
|
|
||||||
|
upslogx(LOG_ERR, "removetimer: failed to locate target at %p", (void *)tfind);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checktimers(void)
|
||||||
|
{
|
||||||
|
ttype_t *tmp, *tmpnext;
|
||||||
|
time_t now;
|
||||||
|
static int emptyctr = 0;
|
||||||
|
|
||||||
|
/* if the queue is empty we might be ready to exit */
|
||||||
|
if (!thead) {
|
||||||
|
|
||||||
|
emptyctr++;
|
||||||
|
|
||||||
|
/* wait a little while in case someone wants us again */
|
||||||
|
if (emptyctr < EMPTY_WAIT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Timer queue empty, exiting");
|
||||||
|
|
||||||
|
#ifdef UPSSCHED_RACE_TEST
|
||||||
|
upslogx(LOG_INFO, "triggering race: sleeping 15 sec before exit");
|
||||||
|
sleep(15);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unlink(pipefn);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
emptyctr = 0;
|
||||||
|
|
||||||
|
/* flip through LL, look for activity */
|
||||||
|
tmp = thead;
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
while (tmp) {
|
||||||
|
tmpnext = tmp->next;
|
||||||
|
|
||||||
|
if (now >= tmp->etime) {
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Event: %s ", tmp->name);
|
||||||
|
|
||||||
|
exec_cmd(tmp->name);
|
||||||
|
|
||||||
|
/* delete from queue */
|
||||||
|
removetimer(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmpnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_timer(const char *name, const char *ofsstr)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
long ofs;
|
||||||
|
ttype_t *tmp, *last;
|
||||||
|
|
||||||
|
/* get the time */
|
||||||
|
time(&now);
|
||||||
|
|
||||||
|
/* add an event for <now> + <time> */
|
||||||
|
ofs = strtol(ofsstr, (char **) NULL, 10);
|
||||||
|
|
||||||
|
if (ofs < 0) {
|
||||||
|
upslogx(LOG_INFO, "bogus offset for timer, ignoring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "New timer: %s (%ld seconds)", name, ofs);
|
||||||
|
|
||||||
|
/* now add to the queue */
|
||||||
|
tmp = last = thead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = xmalloc(sizeof(ttype_t));
|
||||||
|
tmp->name = xstrdup(name);
|
||||||
|
tmp->etime = now + ofs;
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
last->next = tmp;
|
||||||
|
else
|
||||||
|
thead = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cancel_timer(const char *name, const char *cname)
|
||||||
|
{
|
||||||
|
ttype_t *tmp;
|
||||||
|
|
||||||
|
for (tmp = thead; tmp != NULL; tmp = tmp->next) {
|
||||||
|
if (!strcmp(tmp->name, name)) { /* match */
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Cancelling timer: %s", name);
|
||||||
|
removetimer(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this is not necessarily an error */
|
||||||
|
if (cname && cname[0]) {
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Cancel %s, event: %s", name, cname);
|
||||||
|
|
||||||
|
exec_cmd(cname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void us_serialize(int op)
|
||||||
|
{
|
||||||
|
static int pipefd[2];
|
||||||
|
ssize_t ret;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
switch(op) {
|
||||||
|
case SERIALIZE_INIT:
|
||||||
|
ret = pipe(pipefd);
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "serialize: pipe");
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERIALIZE_SET:
|
||||||
|
close(pipefd[0]);
|
||||||
|
close(pipefd[1]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERIALIZE_WAIT:
|
||||||
|
close(pipefd[1]);
|
||||||
|
ret = read(pipefd[0], &ch, 1);
|
||||||
|
close(pipefd[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_sock(void)
|
||||||
|
{
|
||||||
|
int ret, fd;
|
||||||
|
struct sockaddr_un ssaddr;
|
||||||
|
|
||||||
|
check_unix_socket_filename(pipefn);
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Can't create a unix domain socket");
|
||||||
|
|
||||||
|
ssaddr.sun_family = AF_UNIX;
|
||||||
|
snprintf(ssaddr.sun_path, sizeof(ssaddr.sun_path), "%s", pipefn);
|
||||||
|
|
||||||
|
unlink(pipefn);
|
||||||
|
|
||||||
|
umask(0007);
|
||||||
|
|
||||||
|
ret = bind(fd, (struct sockaddr *) &ssaddr, sizeof ssaddr);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "bind %s failed", pipefn);
|
||||||
|
|
||||||
|
ret = chmod(pipefn, 0660);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "chmod(%s, 0660) failed", pipefn);
|
||||||
|
|
||||||
|
ret = listen(fd, US_LISTEN_BACKLOG);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "listen(%d, %d) failed", fd, US_LISTEN_BACKLOG);
|
||||||
|
|
||||||
|
/* don't leak socket to CMDSCRIPT */
|
||||||
|
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void conn_del(conn_t *target)
|
||||||
|
{
|
||||||
|
conn_t *tmp, *last = NULL;
|
||||||
|
|
||||||
|
tmp = connhead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
if (tmp == target) {
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
last->next = tmp->next;
|
||||||
|
else
|
||||||
|
connhead = tmp->next;
|
||||||
|
|
||||||
|
pconf_finish(&tmp->ctx);
|
||||||
|
|
||||||
|
free(tmp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
upslogx(LOG_ERR, "Tried to delete a bogus state connection");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_to_one(conn_t *conn, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
ssize_t ret;
|
||||||
|
size_t buflen;
|
||||||
|
va_list ap;
|
||||||
|
char buf[US_SOCK_BUF_LEN];
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||||
|
#endif
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
buflen = strlen(buf);
|
||||||
|
if (buflen >= SSIZE_MAX) {
|
||||||
|
/* Can't compare buflen to ret */
|
||||||
|
upsdebugx(2, "send_to_one(): buffered message too large");
|
||||||
|
|
||||||
|
close(conn->fd);
|
||||||
|
conn_del(conn);
|
||||||
|
|
||||||
|
return 0; /* failed */
|
||||||
|
}
|
||||||
|
ret = write(conn->fd, buf, buflen);
|
||||||
|
|
||||||
|
if ((ret < 1) || (ret != (ssize_t) buflen)) {
|
||||||
|
upsdebugx(2, "write to fd %d failed", conn->fd);
|
||||||
|
|
||||||
|
close(conn->fd);
|
||||||
|
conn_del(conn);
|
||||||
|
|
||||||
|
return 0; /* failed */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /* OK */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void conn_add(int sockfd)
|
||||||
|
{
|
||||||
|
int acc, ret;
|
||||||
|
conn_t *tmp, *last;
|
||||||
|
struct sockaddr_un saddr;
|
||||||
|
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
|
||||||
|
int salen;
|
||||||
|
#else
|
||||||
|
socklen_t salen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
salen = sizeof(saddr);
|
||||||
|
acc = accept(sockfd, (struct sockaddr *) &saddr, &salen);
|
||||||
|
|
||||||
|
if (acc < 0) {
|
||||||
|
upslog_with_errno(LOG_ERR, "accept on unix fd failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* don't leak connection to CMDSCRIPT */
|
||||||
|
fcntl(acc, F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
/* enable nonblocking I/O */
|
||||||
|
|
||||||
|
ret = fcntl(acc, F_GETFL, 0);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
upslog_with_errno(LOG_ERR, "fcntl get on unix fd failed");
|
||||||
|
close(acc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = fcntl(acc, F_SETFL, ret | O_NDELAY);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
upslog_with_errno(LOG_ERR, "fcntl set O_NDELAY on unix fd failed");
|
||||||
|
close(acc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = last = connhead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = xmalloc(sizeof(conn_t));
|
||||||
|
tmp->fd = acc;
|
||||||
|
tmp->next = NULL;
|
||||||
|
|
||||||
|
if (last)
|
||||||
|
last->next = tmp;
|
||||||
|
else
|
||||||
|
connhead = tmp;
|
||||||
|
|
||||||
|
upsdebugx(3, "new connection on fd %d", acc);
|
||||||
|
|
||||||
|
pconf_init(&tmp->ctx, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sock_arg(conn_t *conn)
|
||||||
|
{
|
||||||
|
if (conn->ctx.numargs < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* CANCEL <name> [<cmd>] */
|
||||||
|
if (!strcmp(conn->ctx.arglist[0], "CANCEL")) {
|
||||||
|
|
||||||
|
if (conn->ctx.numargs < 3)
|
||||||
|
cancel_timer(conn->ctx.arglist[1], NULL);
|
||||||
|
else
|
||||||
|
cancel_timer(conn->ctx.arglist[1], conn->ctx.arglist[2]);
|
||||||
|
|
||||||
|
send_to_one(conn, "OK\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn->ctx.numargs < 3)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* START <name> <length> */
|
||||||
|
if (!strcmp(conn->ctx.arglist[0], "START")) {
|
||||||
|
start_timer(conn->ctx.arglist[1], conn->ctx.arglist[2]);
|
||||||
|
send_to_one(conn, "OK\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unknown */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_unknown(size_t numarg, char **arg)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
upslogx(LOG_INFO, "Unknown command on socket: ");
|
||||||
|
|
||||||
|
for (i = 0; i < numarg; i++)
|
||||||
|
upslogx(LOG_INFO, "arg %zu: %s", i, arg[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sock_read(conn_t *conn)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ssize_t ret;
|
||||||
|
char ch;
|
||||||
|
|
||||||
|
for (i = 0; i < US_MAX_READ; i++) {
|
||||||
|
|
||||||
|
ret = read(conn->fd, &ch, 1);
|
||||||
|
|
||||||
|
if (ret < 1) {
|
||||||
|
|
||||||
|
/* short read = no parsing, come back later */
|
||||||
|
if ((ret == -1) && (errno == EAGAIN))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* O_NDELAY with zero bytes means nothing to read but
|
||||||
|
* since read() follows a succesful select() with
|
||||||
|
* ready file descriptor, ret shouldn't be 0. */
|
||||||
|
if (ret == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* some other problem */
|
||||||
|
return -1; /* error */
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = pconf_char(&conn->ctx, ch);
|
||||||
|
|
||||||
|
if (ret == 0) /* nothing to parse yet */
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ret == -1) {
|
||||||
|
upslogx(LOG_NOTICE, "Parse error on sock: %s",
|
||||||
|
conn->ctx.errmsg);
|
||||||
|
|
||||||
|
return 0; /* nothing parsed */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try to use it, and complain about unknown commands */
|
||||||
|
if (!sock_arg(conn)) {
|
||||||
|
log_unknown(conn->ctx.numargs, conn->ctx.arglist);
|
||||||
|
send_to_one(conn, "ERR UNKNOWN\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1; /* we did some work */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* fell out without parsing anything */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start_daemon(int lockfd)
|
||||||
|
{
|
||||||
|
int maxfd, pid, pipefd, ret;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set rfds;
|
||||||
|
conn_t *tmp, *tmpnext;
|
||||||
|
|
||||||
|
us_serialize(SERIALIZE_INIT);
|
||||||
|
|
||||||
|
if ((pid = fork()) < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "Unable to enter background");
|
||||||
|
|
||||||
|
if (pid != 0) { /* parent */
|
||||||
|
|
||||||
|
/* wait for child to set up the listener */
|
||||||
|
us_serialize(SERIALIZE_WAIT);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* child */
|
||||||
|
|
||||||
|
close(0);
|
||||||
|
close(1);
|
||||||
|
close(2);
|
||||||
|
|
||||||
|
/* make fds 0-2 point somewhere defined */
|
||||||
|
if (open("/dev/null", O_RDWR) != 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "open /dev/null");
|
||||||
|
|
||||||
|
if (dup(0) == -1)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "dup");
|
||||||
|
|
||||||
|
if (dup(0) == -1)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "dup");
|
||||||
|
|
||||||
|
pipefd = open_sock();
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Timer daemon started");
|
||||||
|
|
||||||
|
/* release the parent */
|
||||||
|
us_serialize(SERIALIZE_SET);
|
||||||
|
|
||||||
|
/* drop the lock now that the background is running */
|
||||||
|
unlink(lockfn);
|
||||||
|
close(lockfd);
|
||||||
|
|
||||||
|
/* now watch for activity */
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
/* wait at most 1s so we can check our timers regularly */
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(pipefd, &rfds);
|
||||||
|
|
||||||
|
maxfd = pipefd;
|
||||||
|
|
||||||
|
for (tmp = connhead; tmp != NULL; tmp = tmp->next) {
|
||||||
|
FD_SET(tmp->fd, &rfds);
|
||||||
|
|
||||||
|
if (tmp->fd > maxfd)
|
||||||
|
maxfd = tmp->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = select(maxfd + 1, &rfds, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
|
||||||
|
if (FD_ISSET(pipefd, &rfds))
|
||||||
|
conn_add(pipefd);
|
||||||
|
|
||||||
|
tmp = connhead;
|
||||||
|
|
||||||
|
while (tmp) {
|
||||||
|
tmpnext = tmp->next;
|
||||||
|
|
||||||
|
if (FD_ISSET(tmp->fd, &rfds)) {
|
||||||
|
if (sock_read(tmp) < 0) {
|
||||||
|
close(tmp->fd);
|
||||||
|
conn_del(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = tmpnext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checktimers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- 'client' functions --- */
|
||||||
|
|
||||||
|
static int try_connect(void)
|
||||||
|
{
|
||||||
|
int pipefd, ret;
|
||||||
|
struct sockaddr_un saddr;
|
||||||
|
|
||||||
|
check_unix_socket_filename(pipefn);
|
||||||
|
|
||||||
|
memset(&saddr, '\0', sizeof(saddr));
|
||||||
|
saddr.sun_family = AF_UNIX;
|
||||||
|
snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s", pipefn);
|
||||||
|
|
||||||
|
pipefd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (pipefd < 0)
|
||||||
|
fatal_with_errno(EXIT_FAILURE, "socket");
|
||||||
|
|
||||||
|
ret = connect(pipefd, (const struct sockaddr *) &saddr, sizeof(saddr));
|
||||||
|
|
||||||
|
if (ret != -1)
|
||||||
|
return pipefd;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_lock(const char *fn)
|
||||||
|
{
|
||||||
|
return open(fn, O_RDONLY | O_CREAT | O_EXCL, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try to connect to bg process, and start one if necessary */
|
||||||
|
static int check_parent(const char *cmd, const char *arg2)
|
||||||
|
{
|
||||||
|
int pipefd, lockfd, tries = 0;
|
||||||
|
|
||||||
|
for (tries = 0; tries < MAX_TRIES; tries++) {
|
||||||
|
|
||||||
|
pipefd = try_connect();
|
||||||
|
|
||||||
|
if (pipefd != -1)
|
||||||
|
return pipefd;
|
||||||
|
|
||||||
|
/* timer daemon isn't running */
|
||||||
|
|
||||||
|
/* it's not running, so there's nothing to cancel */
|
||||||
|
if (!strcmp(cmd, "CANCEL") && (arg2 == NULL))
|
||||||
|
return PARENT_UNNECESSARY;
|
||||||
|
|
||||||
|
/* arg2 non-NULL means there is a cancel action available */
|
||||||
|
|
||||||
|
/* we need to start the daemon, so try to get the lock */
|
||||||
|
|
||||||
|
lockfd = get_lock(lockfn);
|
||||||
|
|
||||||
|
if (lockfd != -1) {
|
||||||
|
start_daemon(lockfd);
|
||||||
|
return PARENT_STARTED; /* started successfully */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we didn't get the lock - must be two upsscheds running */
|
||||||
|
|
||||||
|
/* blow this away in case we crashed before */
|
||||||
|
unlink(lockfn);
|
||||||
|
|
||||||
|
/* give the other one a chance to start it, then try again */
|
||||||
|
usleep(250000);
|
||||||
|
}
|
||||||
|
|
||||||
|
upslog_with_errno(LOG_ERR, "Failed to connect to parent and failed to create parent");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
||||||
|
{
|
||||||
|
int i, pipefd;
|
||||||
|
ssize_t ret;
|
||||||
|
size_t enclen, buflen;
|
||||||
|
char buf[SMALLBUF], enc[SMALLBUF + 8];
|
||||||
|
int ret_s;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set fdread;
|
||||||
|
|
||||||
|
/* insanity */
|
||||||
|
if (!arg1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* build the request */
|
||||||
|
snprintf(buf, sizeof(buf), "%s \"%s\"",
|
||||||
|
cmd, pconf_encode(arg1, enc, sizeof(enc)));
|
||||||
|
|
||||||
|
if (arg2)
|
||||||
|
snprintfcat(buf, sizeof(buf), " \"%s\"",
|
||||||
|
pconf_encode(arg2, enc, sizeof(enc)));
|
||||||
|
|
||||||
|
snprintf(enc, sizeof(enc), "%s\n", buf);
|
||||||
|
|
||||||
|
/* Sanity checks, for static analyzers to sleep well */
|
||||||
|
enclen = strlen(enc);
|
||||||
|
buflen = strlen(buf);
|
||||||
|
if (enclen >= SSIZE_MAX || buflen >= SSIZE_MAX) {
|
||||||
|
/* Can't compare enclen to ret below */
|
||||||
|
fatalx(EXIT_FAILURE, "Unable to connect to daemon: buffered message too large");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if the parent needs to be started (and maybe start it) */
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_TRIES; i++) {
|
||||||
|
|
||||||
|
pipefd = check_parent(cmd, arg2);
|
||||||
|
|
||||||
|
if (pipefd == PARENT_STARTED) {
|
||||||
|
/* loop back and try to connect now */
|
||||||
|
usleep(250000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* special case for CANCEL when no parent is running */
|
||||||
|
if (pipefd == PARENT_UNNECESSARY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* we're connected now */
|
||||||
|
|
||||||
|
ret = write(pipefd, enc, enclen);
|
||||||
|
|
||||||
|
/* if we can't send the whole thing, loop back and try again */
|
||||||
|
if ((ret < 1) || (ret != (ssize_t)enclen)) {
|
||||||
|
upslogx(LOG_ERR, "write failed, trying again");
|
||||||
|
close(pipefd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* select on child's pipe fd */
|
||||||
|
do {
|
||||||
|
/* set timeout every time before call select() */
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&fdread);
|
||||||
|
FD_SET(pipefd, &fdread);
|
||||||
|
|
||||||
|
ret_s = select(pipefd + 1, &fdread, NULL, NULL, &tv);
|
||||||
|
switch(ret_s) {
|
||||||
|
/* select error */
|
||||||
|
case -1:
|
||||||
|
upslogx(LOG_DEBUG, "parent select error: %s", strerror(errno));
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* nothing to read */
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* available data to read */
|
||||||
|
default:
|
||||||
|
ret = read(pipefd, buf, sizeof(buf));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (ret_s <= 0);
|
||||||
|
|
||||||
|
close(pipefd);
|
||||||
|
|
||||||
|
/* same idea: no OK = go try it all again */
|
||||||
|
if (ret < 2) {
|
||||||
|
upslogx(LOG_ERR, "read confirmation failed, trying again");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strncmp(buf, "OK", 2))
|
||||||
|
return; /* success */
|
||||||
|
|
||||||
|
upslogx(LOG_ERR, "read confirmation got [%s]", buf);
|
||||||
|
|
||||||
|
/* try again ... */
|
||||||
|
} /* loop until MAX_TRIES if no success above */
|
||||||
|
|
||||||
|
fatalx(EXIT_FAILURE, "Unable to connect to daemon and unable to start daemon");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_at(const char *ntype, const char *un, const char *cmd,
|
||||||
|
const char *ca1, const char *ca2)
|
||||||
|
{
|
||||||
|
/* complain both ways in case we don't have a tty */
|
||||||
|
|
||||||
|
if (!cmdscript) {
|
||||||
|
printf("CMDSCRIPT must be set before any ATs in the config file!\n");
|
||||||
|
fatalx(EXIT_FAILURE, "CMDSCRIPT must be set before any ATs in the config file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pipefn) {
|
||||||
|
printf("PIPEFN must be set before any ATs in the config file!\n");
|
||||||
|
fatalx(EXIT_FAILURE, "PIPEFN must be set before any ATs in the config file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lockfn) {
|
||||||
|
printf("LOCKFN must be set before any ATs in the config file!\n");
|
||||||
|
fatalx(EXIT_FAILURE, "LOCKFN must be set before any ATs in the config file!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check upsname: does this apply to us? */
|
||||||
|
if (strcmp(upsname, un) != 0)
|
||||||
|
if (strcmp(un, "*") != 0)
|
||||||
|
return; /* not for us, and not the wildcard */
|
||||||
|
|
||||||
|
/* see if the current notify type matches the one from the .conf */
|
||||||
|
if (strcasecmp(notify_type, ntype) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* if command is valid, send it to the daemon (which may start it) */
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "START-TIMER")) {
|
||||||
|
sendcmd("START", ca1, ca2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "CANCEL-TIMER")) {
|
||||||
|
sendcmd("CANCEL", ca1, ca2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(cmd, "EXECUTE")) {
|
||||||
|
if (ca1[0] == '\0') {
|
||||||
|
upslogx(LOG_ERR, "Empty EXECUTE command argument");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
upslogx(LOG_INFO, "Executing command: %s", ca1);
|
||||||
|
|
||||||
|
exec_cmd(ca1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
upslogx(LOG_ERR, "Invalid command: %s", cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int conf_arg(size_t numargs, char **arg)
|
||||||
|
{
|
||||||
|
if (numargs < 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* CMDSCRIPT <scriptname> */
|
||||||
|
if (!strcmp(arg[0], "CMDSCRIPT")) {
|
||||||
|
cmdscript = xstrdup(arg[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PIPEFN <pipename> */
|
||||||
|
if (!strcmp(arg[0], "PIPEFN")) {
|
||||||
|
pipefn = xstrdup(arg[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LOCKFN <filename> */
|
||||||
|
if (!strcmp(arg[0], "LOCKFN")) {
|
||||||
|
lockfn = xstrdup(arg[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numargs < 5)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* AT <notifytype> <upsname> <command> <cmdarg1> [<cmdarg2>] */
|
||||||
|
if (!strcmp(arg[0], "AT")) {
|
||||||
|
|
||||||
|
/* don't use arg[5] unless we have it... */
|
||||||
|
if (numargs > 5)
|
||||||
|
parse_at(arg[1], arg[2], arg[3], arg[4], arg[5]);
|
||||||
|
else
|
||||||
|
parse_at(arg[1], arg[2], arg[3], arg[4], NULL);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called for fatal errors in parseconf like malloc failures */
|
||||||
|
static void upssched_err(const char *errmsg)
|
||||||
|
{
|
||||||
|
upslogx(LOG_ERR, "Fatal error in parseconf(upssched.conf): %s", errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkconf(void)
|
||||||
|
{
|
||||||
|
char fn[SMALLBUF];
|
||||||
|
PCONF_CTX_t ctx;
|
||||||
|
|
||||||
|
snprintf(fn, sizeof(fn), "%s/upssched.conf", confpath());
|
||||||
|
|
||||||
|
pconf_init(&ctx, upssched_err);
|
||||||
|
|
||||||
|
if (!pconf_file_begin(&ctx, fn)) {
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
fatalx(EXIT_FAILURE, "%s", ctx.errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pconf_file_next(&ctx)) {
|
||||||
|
if (pconf_parse_error(&ctx)) {
|
||||||
|
upslogx(LOG_ERR, "Parse error: %s:%d: %s",
|
||||||
|
fn, ctx.linenum, ctx.errmsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.numargs < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!conf_arg(ctx.numargs, ctx.arglist)) {
|
||||||
|
unsigned int i;
|
||||||
|
char errmsg[SMALLBUF];
|
||||||
|
|
||||||
|
snprintf(errmsg, sizeof(errmsg),
|
||||||
|
"upssched.conf: invalid directive");
|
||||||
|
|
||||||
|
for (i = 0; i < ctx.numargs; i++)
|
||||||
|
snprintfcat(errmsg, sizeof(errmsg), " %s",
|
||||||
|
ctx.arglist[i]);
|
||||||
|
|
||||||
|
upslogx(LOG_WARNING, "%s", errmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
const char *prog = NULL;
|
||||||
|
/* More a use for argc to avoid warnings than a real need: */
|
||||||
|
if (argc > 0) {
|
||||||
|
xbasename(argv[0]);
|
||||||
|
} else {
|
||||||
|
xbasename("upssched");
|
||||||
|
}
|
||||||
|
|
||||||
|
verbose = 1; /* TODO: remove when done testing, or add -D */
|
||||||
|
|
||||||
|
/* normally we don't have stderr, so get this going to syslog early */
|
||||||
|
open_syslog(prog);
|
||||||
|
syslogbit_set();
|
||||||
|
|
||||||
|
upsname = getenv("UPSNAME");
|
||||||
|
notify_type = getenv("NOTIFYTYPE");
|
||||||
|
|
||||||
|
if ((!upsname) || (!notify_type)) {
|
||||||
|
printf("Error: UPSNAME and NOTIFYTYPE must be set.\n");
|
||||||
|
printf("This program should only be run from upsmon.\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* see if this matches anything in the config file */
|
||||||
|
checkconf();
|
||||||
|
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
31
clients/upssched.h
Normal file
31
clients/upssched.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* upssched.h - supporting structures */
|
||||||
|
|
||||||
|
#ifndef NUT_UPSSCHED_H_SEEN
|
||||||
|
#define NUT_UPSSCHED_H_SEEN 1
|
||||||
|
|
||||||
|
#include <parseconf.h>
|
||||||
|
|
||||||
|
#define SERIALIZE_INIT 1
|
||||||
|
#define SERIALIZE_SET 2
|
||||||
|
#define SERIALIZE_WAIT 3
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* track client connections */
|
||||||
|
typedef struct conn_s {
|
||||||
|
int fd;
|
||||||
|
PCONF_CTX_t ctx;
|
||||||
|
struct conn_s *next;
|
||||||
|
} conn_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_UPSSCHED_H_SEEN */
|
1119
clients/upsset.c
Normal file
1119
clients/upsset.c
Normal file
File diff suppressed because it is too large
Load diff
1074
clients/upsstats.c
Normal file
1074
clients/upsstats.c
Normal file
File diff suppressed because it is too large
Load diff
41
clients/upsstats.h
Normal file
41
clients/upsstats.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/* upsstats.h - structures for upsstats
|
||||||
|
|
||||||
|
Copyright (C) 2002 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUT_UPSSTATS_H_SEEN
|
||||||
|
#define NUT_UPSSTATS_H_SEEN 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
extern "C" {
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *sys;
|
||||||
|
char *desc;
|
||||||
|
void *next;
|
||||||
|
} ulist_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
}
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NUT_UPSSTATS_H_SEEN */
|
49
common/Makefile.am
Normal file
49
common/Makefile.am
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
# Network UPS Tools: common
|
||||||
|
|
||||||
|
AM_CFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = libparseconf.la libcommon.la libcommonclient.la
|
||||||
|
libparseconf_la_SOURCES = parseconf.c
|
||||||
|
|
||||||
|
# do not hard depend on '../include/nut_version.h', since it blocks
|
||||||
|
# 'dist', and is only required for actual build, in which case
|
||||||
|
# BUILT_SOURCES (in ../include) will ensure nut_version.h will
|
||||||
|
# be built before anything else... but do depend on its build area:
|
||||||
|
if BUILDING_IN_TREE
|
||||||
|
# No need for symlink hack
|
||||||
|
common.c: $(top_builddir)/include/nut_version.h
|
||||||
|
else
|
||||||
|
# Surprisingly, for some "make" implementations this dependency means
|
||||||
|
# that the "common.c" required for builds below will be seeked in the
|
||||||
|
# current directory. So for out-of-tree builds like distcheck, we have
|
||||||
|
# to symlink the "real" source to build area:
|
||||||
|
common.c: $(top_builddir)/include/nut_version.h $(srcdir)/common.c
|
||||||
|
test -s "$@" || ln -s -f "$(top_srcdir)/common/common.c" "$@"
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(top_builddir)/include/nut_version.h:
|
||||||
|
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
|
||||||
|
|
||||||
|
libcommon_la_SOURCES = state.c str.c upsconf.c
|
||||||
|
libcommonclient_la_SOURCES = state.c str.c
|
||||||
|
if BUILDING_IN_TREE
|
||||||
|
libcommon_la_SOURCES += common.c
|
||||||
|
libcommonclient_la_SOURCES += common.c
|
||||||
|
else
|
||||||
|
nodist_libcommon_la_SOURCES = common.c
|
||||||
|
nodist_libcommonclient_la_SOURCES = common.c
|
||||||
|
CLEANFILES = $(top_builddir)/common/common.c
|
||||||
|
BUILT_SOURCES = common.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ensure inclusion of local implementation of missing systems functions
|
||||||
|
# using LTLIBOBJS. Refer to configure.in/.ac -> AC_REPLACE_FUNCS
|
||||||
|
libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@
|
||||||
|
libcommonclient_la_LIBADD = libparseconf.la @LTLIBOBJS@
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
|
||||||
|
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
|
||||||
|
# the root Makefile.am takes care of that!
|
||||||
|
#clean-local:
|
||||||
|
# rm -rf $(builddir)/.deps
|
818
common/Makefile.in
Normal file
818
common/Makefile.in
Normal file
|
@ -0,0 +1,818 @@
|
||||||
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994-2020 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@
|
||||||
|
|
||||||
|
# Network UPS Tools: common
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
am__make_running_with_option = \
|
||||||
|
case $${target_option-} in \
|
||||||
|
?) ;; \
|
||||||
|
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||||
|
"target option '$${target_option-}' specified" >&2; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
has_opt=no; \
|
||||||
|
sane_makeflags=$$MAKEFLAGS; \
|
||||||
|
if $(am__is_gnu_make); then \
|
||||||
|
sane_makeflags=$$MFLAGS; \
|
||||||
|
else \
|
||||||
|
case $$MAKEFLAGS in \
|
||||||
|
*\\[\ \ ]*) \
|
||||||
|
bs=\\; \
|
||||||
|
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||||
|
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||||
|
esac; \
|
||||||
|
fi; \
|
||||||
|
skip_next=no; \
|
||||||
|
strip_trailopt () \
|
||||||
|
{ \
|
||||||
|
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||||
|
}; \
|
||||||
|
for flg in $$sane_makeflags; do \
|
||||||
|
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||||
|
case $$flg in \
|
||||||
|
*=*|--*) continue;; \
|
||||||
|
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||||
|
-*I?*) strip_trailopt 'I';; \
|
||||||
|
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||||
|
-*O?*) strip_trailopt 'O';; \
|
||||||
|
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||||
|
-*l?*) strip_trailopt 'l';; \
|
||||||
|
-[dEDm]) skip_next=yes;; \
|
||||||
|
-[JT]) skip_next=yes;; \
|
||||||
|
esac; \
|
||||||
|
case $$flg in \
|
||||||
|
*$$target_option*) has_opt=yes; break;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
test $$has_opt = yes
|
||||||
|
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||||
|
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||||
|
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@
|
||||||
|
@BUILDING_IN_TREE_TRUE@am__append_1 = common.c
|
||||||
|
@BUILDING_IN_TREE_TRUE@am__append_2 = common.c
|
||||||
|
subdir = common
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_c_pragmas.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_compare_version.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_run_or_link_ifelse.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_cppcheck.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_headers_windows.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_libltdl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libpowerman.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_check_pkgconfig.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_python.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_compiler_family.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_stash_warnings.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
LTLIBRARIES = $(noinst_LTLIBRARIES)
|
||||||
|
libcommon_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@
|
||||||
|
am__libcommon_la_SOURCES_DIST = state.c str.c upsconf.c common.c
|
||||||
|
@BUILDING_IN_TREE_TRUE@am__objects_1 = common.lo
|
||||||
|
am_libcommon_la_OBJECTS = state.lo str.lo upsconf.lo $(am__objects_1)
|
||||||
|
@BUILDING_IN_TREE_FALSE@nodist_libcommon_la_OBJECTS = common.lo
|
||||||
|
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) \
|
||||||
|
$(nodist_libcommon_la_OBJECTS)
|
||||||
|
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||||
|
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||||
|
am__v_lt_0 = --silent
|
||||||
|
am__v_lt_1 =
|
||||||
|
libcommonclient_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@
|
||||||
|
am__libcommonclient_la_SOURCES_DIST = state.c str.c common.c
|
||||||
|
am_libcommonclient_la_OBJECTS = state.lo str.lo $(am__objects_1)
|
||||||
|
@BUILDING_IN_TREE_FALSE@nodist_libcommonclient_la_OBJECTS = common.lo
|
||||||
|
libcommonclient_la_OBJECTS = $(am_libcommonclient_la_OBJECTS) \
|
||||||
|
$(nodist_libcommonclient_la_OBJECTS)
|
||||||
|
libparseconf_la_LIBADD =
|
||||||
|
am_libparseconf_la_OBJECTS = parseconf.lo
|
||||||
|
libparseconf_la_OBJECTS = $(am_libparseconf_la_OBJECTS)
|
||||||
|
AM_V_P = $(am__v_P_@AM_V@)
|
||||||
|
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||||
|
am__v_P_0 = false
|
||||||
|
am__v_P_1 = :
|
||||||
|
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||||
|
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_GEN_1 =
|
||||||
|
AM_V_at = $(am__v_at_@AM_V@)
|
||||||
|
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||||
|
am__v_at_0 = @
|
||||||
|
am__v_at_1 =
|
||||||
|
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||||
|
am__maybe_remake_depfiles = depfiles
|
||||||
|
am__depfiles_remade = $(DEPDIR)/atexit.Plo $(DEPDIR)/setenv.Plo \
|
||||||
|
$(DEPDIR)/snprintf.Plo $(DEPDIR)/strerror.Plo \
|
||||||
|
./$(DEPDIR)/common.Plo ./$(DEPDIR)/parseconf.Plo \
|
||||||
|
./$(DEPDIR)/state.Plo ./$(DEPDIR)/str.Plo \
|
||||||
|
./$(DEPDIR)/upsconf.Plo
|
||||||
|
am__mv = mv -f
|
||||||
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||||
|
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||||
|
$(AM_CFLAGS) $(CFLAGS)
|
||||||
|
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||||
|
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||||
|
am__v_CC_0 = @echo " CC " $@;
|
||||||
|
am__v_CC_1 =
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||||
|
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||||
|
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||||
|
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||||
|
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||||
|
am__v_CCLD_1 =
|
||||||
|
SOURCES = $(libcommon_la_SOURCES) $(nodist_libcommon_la_SOURCES) \
|
||||||
|
$(libcommonclient_la_SOURCES) \
|
||||||
|
$(nodist_libcommonclient_la_SOURCES) \
|
||||||
|
$(libparseconf_la_SOURCES)
|
||||||
|
DIST_SOURCES = $(am__libcommon_la_SOURCES_DIST) \
|
||||||
|
$(am__libcommonclient_la_SOURCES_DIST) \
|
||||||
|
$(libparseconf_la_SOURCES)
|
||||||
|
am__can_run_installinfo = \
|
||||||
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
|
n|no|NO) false;; \
|
||||||
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
|
esac
|
||||||
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
|
# Read a list of newline-separated strings from the standard input,
|
||||||
|
# and print each of them once, without duplicates. Input order is
|
||||||
|
# *not* preserved.
|
||||||
|
am__uniquify_input = $(AWK) '\
|
||||||
|
BEGIN { nonempty = 0; } \
|
||||||
|
{ items[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in items) print i; }; } \
|
||||||
|
'
|
||||||
|
# Make sure the list of sources is unique. This is necessary because,
|
||||||
|
# e.g., the same source file might be shared among _SOURCES variables
|
||||||
|
# for different programs/libraries.
|
||||||
|
am__define_uniq_tagged_files = \
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | $(am__uniquify_input)`
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp atexit.c \
|
||||||
|
setenv.c snprintf.c strerror.c
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
A2X = @A2X@
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
AR = @AR@
|
||||||
|
ASCIIDOC = @ASCIIDOC@
|
||||||
|
ASPELL = @ASPELL@
|
||||||
|
AUGPARSE = @AUGPARSE@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
BINDIR = @BINDIR@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CONFPATH = @CONFPATH@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPCHECK = @CPPCHECK@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
|
||||||
|
CPPUNIT_LIBS = @CPPUNIT_LIBS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DBLATEX = @DBLATEX@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
||||||
|
DOC_CHECK_LIST = @DOC_CHECK_LIST@
|
||||||
|
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||||
|
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||||
|
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||||
|
DRVPATH = @DRVPATH@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
GDLIB_CONFIG = @GDLIB_CONFIG@
|
||||||
|
GREP = @GREP@
|
||||||
|
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@
|
||||||
|
LIBDIR = @LIBDIR@
|
||||||
|
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||||
|
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||||
|
LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
|
||||||
|
LIBIPMI_LIBS = @LIBIPMI_LIBS@
|
||||||
|
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
|
||||||
|
LIBLTDL_LIBS = @LIBLTDL_LIBS@
|
||||||
|
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
|
||||||
|
LIBMODBUS_LIBS = @LIBMODBUS_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@
|
||||||
|
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||||
|
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||||
|
LIBUSB_CONFIG = @LIBUSB_CONFIG@
|
||||||
|
LIBUSB_LIBS = @LIBUSB_LIBS@
|
||||||
|
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||||
|
LIBWRAP_LIBS = @LIBWRAP_LIBS@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LN_S_R = @LN_S_R@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NETLIBS = @NETLIBS@
|
||||||
|
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
NUT_DATADIR = @NUT_DATADIR@
|
||||||
|
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
|
||||||
|
NUT_NETVERSION = @NUT_NETVERSION@
|
||||||
|
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@
|
||||||
|
PIDPATH = @PIDPATH@
|
||||||
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
PORT = @PORT@
|
||||||
|
PYTHON = @PYTHON@
|
||||||
|
PYTHON2 = @PYTHON2@
|
||||||
|
PYTHON3 = @PYTHON3@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||||
|
RUN_AS_USER = @RUN_AS_USER@
|
||||||
|
SBINDIR = @SBINDIR@
|
||||||
|
SED = @SED@
|
||||||
|
SERLIBS = @SERLIBS@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SOURCE_HIGHLIGHT = @SOURCE_HIGHLIGHT@
|
||||||
|
STATEPATH = @STATEPATH@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
SUN_LIBUSB = @SUN_LIBUSB@
|
||||||
|
TREE_VERSION = @TREE_VERSION@
|
||||||
|
VALGRIND = @VALGRIND@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||||
|
XMLLINT = @XMLLINT@
|
||||||
|
XSLTPROC = @XSLTPROC@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_AR = @ac_ct_AR@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
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@
|
||||||
|
auglensdir = @auglensdir@
|
||||||
|
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@
|
||||||
|
devddir = @devddir@
|
||||||
|
docdir = @docdir@
|
||||||
|
driverexecdir = @driverexecdir@
|
||||||
|
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
|
||||||
|
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
|
||||||
|
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
|
||||||
|
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@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
now = @now@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
runstatedir = @runstatedir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
systemdshutdowndir = @systemdshutdowndir@
|
||||||
|
systemdsystemunitdir = @systemdsystemunitdir@
|
||||||
|
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||||
|
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@
|
||||||
|
AM_CFLAGS = -I$(top_srcdir)/include
|
||||||
|
noinst_LTLIBRARIES = libparseconf.la libcommon.la libcommonclient.la
|
||||||
|
libparseconf_la_SOURCES = parseconf.c
|
||||||
|
libcommon_la_SOURCES = state.c str.c upsconf.c $(am__append_1)
|
||||||
|
libcommonclient_la_SOURCES = state.c str.c $(am__append_2)
|
||||||
|
@BUILDING_IN_TREE_FALSE@nodist_libcommon_la_SOURCES = common.c
|
||||||
|
@BUILDING_IN_TREE_FALSE@nodist_libcommonclient_la_SOURCES = common.c
|
||||||
|
@BUILDING_IN_TREE_FALSE@CLEANFILES = $(top_builddir)/common/common.c
|
||||||
|
@BUILDING_IN_TREE_FALSE@BUILT_SOURCES = common.c
|
||||||
|
|
||||||
|
# ensure inclusion of local implementation of missing systems functions
|
||||||
|
# using LTLIBOBJS. Refer to configure.in/.ac -> AC_REPLACE_FUNCS
|
||||||
|
libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@
|
||||||
|
libcommonclient_la_LIBADD = libparseconf.la @LTLIBOBJS@
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
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 common/Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnu common/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__maybe_remake_depfiles)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
|
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):
|
||||||
|
|
||||||
|
clean-noinstLTLIBRARIES:
|
||||||
|
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
|
||||||
|
@list='$(noinst_LTLIBRARIES)'; \
|
||||||
|
locs=`for p in $$list; do echo $$p; done | \
|
||||||
|
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||||
|
sort -u`; \
|
||||||
|
test -z "$$locs" || { \
|
||||||
|
echo rm -f $${locs}; \
|
||||||
|
rm -f $${locs}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) $(EXTRA_libcommon_la_DEPENDENCIES)
|
||||||
|
$(AM_V_CCLD)$(LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
libcommonclient.la: $(libcommonclient_la_OBJECTS) $(libcommonclient_la_DEPENDENCIES) $(EXTRA_libcommonclient_la_DEPENDENCIES)
|
||||||
|
$(AM_V_CCLD)$(LINK) $(libcommonclient_la_OBJECTS) $(libcommonclient_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
libparseconf.la: $(libparseconf_la_OBJECTS) $(libparseconf_la_DEPENDENCIES) $(EXTRA_libparseconf_la_DEPENDENCIES)
|
||||||
|
$(AM_V_CCLD)$(LINK) $(libparseconf_la_OBJECTS) $(libparseconf_la_LIBADD) $(LIBS)
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT)
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/atexit.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setenv.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parseconf.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@ # am--include-marker
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsconf.Plo@am__quote@ # am--include-marker
|
||||||
|
|
||||||
|
$(am__depfiles_remade):
|
||||||
|
@$(MKDIR_P) $(@D)
|
||||||
|
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
|
||||||
|
|
||||||
|
am--depfiles: $(am__depfiles_remade)
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||||
|
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||||
|
|
||||||
|
.c.lo:
|
||||||
|
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||||
|
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||||
|
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
ID: $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||||
|
tags: tags-am
|
||||||
|
TAGS: tags
|
||||||
|
|
||||||
|
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
set x; \
|
||||||
|
here=`pwd`; \
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
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-am
|
||||||
|
|
||||||
|
CTAGS: ctags
|
||||||
|
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
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"
|
||||||
|
cscopelist: cscopelist-am
|
||||||
|
|
||||||
|
cscopelist-am: $(am__tagged_files)
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
case "$(srcdir)" in \
|
||||||
|
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||||
|
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||||
|
esac; \
|
||||||
|
for i in $$list; do \
|
||||||
|
if test -f "$$i"; then \
|
||||||
|
echo "$(subdir)/$$i"; \
|
||||||
|
else \
|
||||||
|
echo "$$sdir/$$i"; \
|
||||||
|
fi; \
|
||||||
|
done >> $(top_builddir)/cscope.files
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
distdir: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
distdir-am: $(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)
|
||||||
|
installdirs:
|
||||||
|
install: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||||
|
install-exec: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) 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:
|
||||||
|
if test -z '$(STRIP)'; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
install; \
|
||||||
|
else \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||||
|
fi
|
||||||
|
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)
|
||||||
|
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||||
|
clean: clean-am
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||||
|
mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-am
|
||||||
|
-rm -f $(DEPDIR)/atexit.Plo
|
||||||
|
-rm -f $(DEPDIR)/setenv.Plo
|
||||||
|
-rm -f $(DEPDIR)/snprintf.Plo
|
||||||
|
-rm -f $(DEPDIR)/strerror.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/common.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/parseconf.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/state.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/str.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/upsconf.Plo
|
||||||
|
-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-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 $(DEPDIR)/atexit.Plo
|
||||||
|
-rm -f $(DEPDIR)/setenv.Plo
|
||||||
|
-rm -f $(DEPDIR)/snprintf.Plo
|
||||||
|
-rm -f $(DEPDIR)/strerror.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/common.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/parseconf.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/state.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/str.Plo
|
||||||
|
-rm -f ./$(DEPDIR)/upsconf.Plo
|
||||||
|
-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:
|
||||||
|
|
||||||
|
.MAKE: all check install install-am install-exec install-strip
|
||||||
|
|
||||||
|
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||||
|
clean-generic clean-libtool clean-noinstLTLIBRARIES \
|
||||||
|
cscopelist-am ctags ctags-am distclean distclean-compile \
|
||||||
|
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 maintainer-clean \
|
||||||
|
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||||
|
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||||
|
tags tags-am uninstall uninstall-am
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# do not hard depend on '../include/nut_version.h', since it blocks
|
||||||
|
# 'dist', and is only required for actual build, in which case
|
||||||
|
# BUILT_SOURCES (in ../include) will ensure nut_version.h will
|
||||||
|
# be built before anything else... but do depend on its build area:
|
||||||
|
# No need for symlink hack
|
||||||
|
@BUILDING_IN_TREE_TRUE@common.c: $(top_builddir)/include/nut_version.h
|
||||||
|
# Surprisingly, for some "make" implementations this dependency means
|
||||||
|
# that the "common.c" required for builds below will be seeked in the
|
||||||
|
# current directory. So for out-of-tree builds like distcheck, we have
|
||||||
|
# to symlink the "real" source to build area:
|
||||||
|
@BUILDING_IN_TREE_FALSE@common.c: $(top_builddir)/include/nut_version.h $(srcdir)/common.c
|
||||||
|
@BUILDING_IN_TREE_FALSE@ test -s "$@" || ln -s -f "$(top_srcdir)/common/common.c" "$@"
|
||||||
|
|
||||||
|
$(top_builddir)/include/nut_version.h:
|
||||||
|
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
|
||||||
|
|
||||||
|
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
|
||||||
|
# the root Makefile.am takes care of that!
|
||||||
|
#clean-local:
|
||||||
|
# rm -rf $(builddir)/.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:
|
22
common/atexit.c
Normal file
22
common/atexit.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* atexit() Mark Powell <medp@primagraphics.co.uk> */
|
||||||
|
/* Implemented in terms of on_exit() for old BSD-style systems, like SunOS4 */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_ATEXIT
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int atexit(fn)
|
||||||
|
void (*fn)();
|
||||||
|
{
|
||||||
|
#ifdef HAVE_ON_EXIT
|
||||||
|
return on_exit(fn, 0);
|
||||||
|
#else
|
||||||
|
/* Choose some errno thats likely to exist on lots of systems */
|
||||||
|
errno = EPERM;
|
||||||
|
return (-1);
|
||||||
|
#endif /* HAVE_ON_EXIT */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ATEXIT */
|
1079
common/common.c
Normal file
1079
common/common.c
Normal file
File diff suppressed because it is too large
Load diff
649
common/parseconf.c
Normal file
649
common/parseconf.c
Normal file
|
@ -0,0 +1,649 @@
|
||||||
|
/* parseconf.c - state machine-driven dynamic configuration file parser
|
||||||
|
|
||||||
|
Copyright (C) 2002 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* parseconf, version 4.
|
||||||
|
*
|
||||||
|
* This one abandons the "callback" system introduced last time. It
|
||||||
|
* didn't turn out as well as I had hoped - you got stuck "behind"
|
||||||
|
* parseconf too often.
|
||||||
|
*
|
||||||
|
* There is now a context buffer, and you call pconf_init to set it up.
|
||||||
|
* All subsequent calls must have it as the first argument. There are
|
||||||
|
* two entry points for parsing lines. You can have it read a file
|
||||||
|
* (pconf_file_begin and pconf_file_next), take lines directly from
|
||||||
|
* the caller (pconf_line), or go along a character at a time (pconf_char).
|
||||||
|
* The parsing is identical no matter how you feed it.
|
||||||
|
*
|
||||||
|
* Since there are no more callbacks, you take the successful return
|
||||||
|
* from the function and access ctx->arglist and ctx->numargs yourself.
|
||||||
|
* You must check for errors with pconf_parse_error before using them,
|
||||||
|
* since it might not be complete. This lets the caller handle all
|
||||||
|
* error reporting that's nonfatal.
|
||||||
|
*
|
||||||
|
* Fatal errors are those that involve memory allocation. If the user
|
||||||
|
* defines an error handler when calling pconf_init, that function will
|
||||||
|
* be called with the error message before parseconf exits. By default
|
||||||
|
* it will just write the message to stderr before exiting.
|
||||||
|
*
|
||||||
|
* Input vs. Output:
|
||||||
|
*
|
||||||
|
* What it reads --> What ends up in each argument
|
||||||
|
*
|
||||||
|
* this is a line --> "this" "is" "a" "line"
|
||||||
|
* this "is also" a line --> "this" "is also" "a" "line"
|
||||||
|
* embedded\ space --> "embedded space"
|
||||||
|
* embedded\\backslash --> "embedded\backslash"
|
||||||
|
*
|
||||||
|
* Arguments are split by whitespace (isspace()) unless that whitespace
|
||||||
|
* occurs inside a "quoted pair like this".
|
||||||
|
*
|
||||||
|
* You can also escape the double quote (") character. The backslash
|
||||||
|
* also allows you to join lines, allowing you to have logical lines
|
||||||
|
* that span physical lines, just like you can do in some shells.
|
||||||
|
*
|
||||||
|
* Lines normally end with a newline, but reaching EOF will also force
|
||||||
|
* parsing on what's been scanned so far.
|
||||||
|
*
|
||||||
|
* Design:
|
||||||
|
*
|
||||||
|
* Characters are read one at a time to drive the state machine.
|
||||||
|
* As words are completed (by hitting whitespace or ending a "" item),
|
||||||
|
* they are committed to the next buffer in the arglist. realloc is
|
||||||
|
* used, so the buffer can grow to handle bigger words.
|
||||||
|
*
|
||||||
|
* The arglist also grows as necessary with a similar approach. As a
|
||||||
|
* result, you can parse extremely long words and lines with an insane
|
||||||
|
* number of elements.
|
||||||
|
*
|
||||||
|
* Finally, there is argsize, which remembers how long each of the
|
||||||
|
* arglist elements are. This is how we know when to expand them.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "parseconf.h"
|
||||||
|
#include "attribute.h"
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
|
||||||
|
/* possible states */
|
||||||
|
|
||||||
|
#define STATE_FINDWORDSTART 1
|
||||||
|
#define STATE_FINDEOL 2
|
||||||
|
#define STATE_QUOTECOLLECT 3
|
||||||
|
#define STATE_QC_LITERAL 4
|
||||||
|
#define STATE_COLLECT 5
|
||||||
|
#define STATE_COLLECTLITERAL 6
|
||||||
|
#define STATE_ENDOFLINE 7
|
||||||
|
#define STATE_PARSEERR 8
|
||||||
|
|
||||||
|
static void pconf_fatal(PCONF_CTX_t *ctx, const char *errtxt)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
|
||||||
|
static void pconf_fatal(PCONF_CTX_t *ctx, const char *errtxt)
|
||||||
|
{
|
||||||
|
if (ctx->errhandler)
|
||||||
|
ctx->errhandler(errtxt);
|
||||||
|
else
|
||||||
|
fprintf(stderr, "parseconf: fatal error: %s\n", errtxt);
|
||||||
|
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_arg_word(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
size_t argpos;
|
||||||
|
size_t wbuflen;
|
||||||
|
|
||||||
|
/* this is where the new value goes */
|
||||||
|
argpos = ctx->numargs;
|
||||||
|
|
||||||
|
ctx->numargs++;
|
||||||
|
|
||||||
|
/* when facing more args than ever before, expand the list */
|
||||||
|
if (ctx->numargs > ctx->maxargs) {
|
||||||
|
ctx->maxargs = ctx->numargs;
|
||||||
|
|
||||||
|
/* resize the lists */
|
||||||
|
ctx->arglist = realloc(ctx->arglist,
|
||||||
|
sizeof(char *) * ctx->numargs);
|
||||||
|
|
||||||
|
if (!ctx->arglist)
|
||||||
|
pconf_fatal(ctx, "realloc arglist failed");
|
||||||
|
|
||||||
|
ctx->argsize = realloc(ctx->argsize,
|
||||||
|
sizeof(size_t) * ctx->numargs);
|
||||||
|
|
||||||
|
if (!ctx->argsize)
|
||||||
|
pconf_fatal(ctx, "realloc argsize failed");
|
||||||
|
|
||||||
|
/* ensure sane starting values */
|
||||||
|
ctx->arglist[argpos] = NULL;
|
||||||
|
ctx->argsize[argpos] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wbuflen = strlen(ctx->wordbuf);
|
||||||
|
|
||||||
|
/* now see if the string itself grew compared to last time */
|
||||||
|
if (wbuflen >= ctx->argsize[argpos]) {
|
||||||
|
size_t newlen;
|
||||||
|
|
||||||
|
/* allow for the trailing NULL */
|
||||||
|
newlen = wbuflen + 1;
|
||||||
|
|
||||||
|
/* expand the string storage */
|
||||||
|
ctx->arglist[argpos] = realloc(ctx->arglist[argpos], newlen);
|
||||||
|
|
||||||
|
if (!ctx->arglist[argpos])
|
||||||
|
pconf_fatal(ctx, "realloc arglist member failed");
|
||||||
|
|
||||||
|
/* remember the new size */
|
||||||
|
ctx->argsize[argpos] = newlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* strncpy doesn't give us a trailing NULL, so prep the space */
|
||||||
|
memset(ctx->arglist[argpos], '\0', ctx->argsize[argpos]);
|
||||||
|
|
||||||
|
/* finally copy the new value into the provided space */
|
||||||
|
strncpy(ctx->arglist[argpos], ctx->wordbuf, wbuflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addchar(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
size_t wbuflen;
|
||||||
|
|
||||||
|
wbuflen = strlen(ctx->wordbuf);
|
||||||
|
|
||||||
|
/* CVE-2012-2944: only allow the subset of ASCII charset from Space to ~ */
|
||||||
|
if ((ctx->ch < 0x20) || (ctx->ch > 0x7f)) {
|
||||||
|
fprintf(stderr, "addchar: discarding invalid character (0x%02x)!\n",
|
||||||
|
ctx->ch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->wordlen_limit != 0) {
|
||||||
|
if (wbuflen >= ctx->wordlen_limit) {
|
||||||
|
|
||||||
|
/* limit reached: don't append any more */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allow for the null */
|
||||||
|
if (wbuflen >= (ctx->wordbufsize - 1)) {
|
||||||
|
ctx->wordbufsize += 8;
|
||||||
|
|
||||||
|
ctx->wordbuf = realloc(ctx->wordbuf, ctx->wordbufsize);
|
||||||
|
|
||||||
|
if (!ctx->wordbuf)
|
||||||
|
pconf_fatal(ctx, "realloc wordbuf failed");
|
||||||
|
|
||||||
|
/* repoint as wordbuf may have moved */
|
||||||
|
ctx->wordptr = &ctx->wordbuf[wbuflen];
|
||||||
|
}
|
||||||
|
|
||||||
|
*ctx->wordptr++ = (char)ctx->ch;
|
||||||
|
*ctx->wordptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void endofword(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->arg_limit != 0) {
|
||||||
|
if (ctx->numargs >= ctx->arg_limit) {
|
||||||
|
|
||||||
|
/* don't accept this word - just drop it */
|
||||||
|
ctx->wordptr = ctx->wordbuf;
|
||||||
|
*ctx->wordptr = '\0';
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_arg_word(ctx);
|
||||||
|
|
||||||
|
ctx->wordptr = ctx->wordbuf;
|
||||||
|
*ctx->wordptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* look for the beginning of a word */
|
||||||
|
static int findwordstart(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* newline = the physical line is over, so the logical one is too */
|
||||||
|
if (ctx->ch == 10)
|
||||||
|
return STATE_ENDOFLINE;
|
||||||
|
|
||||||
|
/* the rest of the line is a comment */
|
||||||
|
if (ctx->ch == '#')
|
||||||
|
return STATE_FINDEOL;
|
||||||
|
|
||||||
|
/* space = not in a word yet, so loop back */
|
||||||
|
if (isspace((size_t)ctx->ch))
|
||||||
|
return STATE_FINDWORDSTART;
|
||||||
|
|
||||||
|
/* \ = literal = accept the next char blindly */
|
||||||
|
if (ctx->ch == '\\')
|
||||||
|
return STATE_COLLECTLITERAL;
|
||||||
|
|
||||||
|
/* " = begin word bounded by quotes */
|
||||||
|
if (ctx->ch == '"')
|
||||||
|
return STATE_QUOTECOLLECT;
|
||||||
|
|
||||||
|
/* at this point the word just started */
|
||||||
|
addchar(ctx);
|
||||||
|
|
||||||
|
/* if the first character is a '=' this is considered a whole word */
|
||||||
|
if (ctx->ch == '=') {
|
||||||
|
endofword(ctx);
|
||||||
|
return STATE_FINDWORDSTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATE_COLLECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eat characters until the end of the line is found */
|
||||||
|
static int findeol(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* newline = found it, so start a new line */
|
||||||
|
if (ctx->ch == 10)
|
||||||
|
return STATE_ENDOFLINE;
|
||||||
|
|
||||||
|
/* come back here */
|
||||||
|
return STATE_FINDEOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set up the error reporting details */
|
||||||
|
static void pconf_seterr(PCONF_CTX_t *ctx, const char *errmsg)
|
||||||
|
{
|
||||||
|
snprintf(ctx->errmsg, PCONF_ERR_LEN, "%s", errmsg);
|
||||||
|
|
||||||
|
ctx->error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* quote characters inside a word bounded by "quotes" */
|
||||||
|
static int quotecollect(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* user is trying to break us */
|
||||||
|
if (ctx->ch == '#') {
|
||||||
|
pconf_seterr(ctx, "Unbalanced word due to unescaped # in quotes");
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
/* this makes us drop all the way out of the caller */
|
||||||
|
return STATE_PARSEERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* another " means we're done with this word */
|
||||||
|
if (ctx->ch == '"') {
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
return STATE_FINDWORDSTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* literal - special case since it needs to return here */
|
||||||
|
if (ctx->ch == '\\')
|
||||||
|
return STATE_QC_LITERAL;
|
||||||
|
|
||||||
|
/* otherwise save it and loop back */
|
||||||
|
addchar(ctx);
|
||||||
|
|
||||||
|
return STATE_QUOTECOLLECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* take almost anything literally, but return to quotecollect */
|
||||||
|
static int qc_literal(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* continue onto the next line of the file */
|
||||||
|
if (ctx->ch == 10)
|
||||||
|
return STATE_QUOTECOLLECT;
|
||||||
|
|
||||||
|
addchar(ctx);
|
||||||
|
return STATE_QUOTECOLLECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collect characters inside a word */
|
||||||
|
static int collect(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* comment means the word is done, and skip to the end of the line */
|
||||||
|
if (ctx->ch == '#') {
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
return STATE_FINDEOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* newline means the word is done, and the line is done */
|
||||||
|
if (ctx->ch == 10) {
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
return STATE_ENDOFLINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* space means the word is done */
|
||||||
|
if (isspace((size_t)ctx->ch)) {
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
return STATE_FINDWORDSTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* '=' means the word is done and the = is a single char word*/
|
||||||
|
if (ctx->ch == '=') {
|
||||||
|
endofword(ctx);
|
||||||
|
findwordstart(ctx);
|
||||||
|
|
||||||
|
return STATE_FINDWORDSTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* \ = literal = accept the next char blindly */
|
||||||
|
if (ctx->ch == '\\')
|
||||||
|
return STATE_COLLECTLITERAL;
|
||||||
|
|
||||||
|
/* otherwise store it and come back for more */
|
||||||
|
addchar(ctx);
|
||||||
|
return STATE_COLLECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* take almost anything literally */
|
||||||
|
static int collectliteral(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
/* continue to the next line */
|
||||||
|
if (ctx->ch == 10)
|
||||||
|
return STATE_COLLECT;
|
||||||
|
|
||||||
|
addchar(ctx);
|
||||||
|
return STATE_COLLECT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up memory before going back to the user */
|
||||||
|
static void free_storage(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
free(ctx->wordbuf);
|
||||||
|
|
||||||
|
/* clear out the individual words first */
|
||||||
|
for (i = 0; i < ctx->maxargs; i++)
|
||||||
|
free(ctx->arglist[i]);
|
||||||
|
|
||||||
|
free(ctx->arglist);
|
||||||
|
free(ctx->argsize);
|
||||||
|
|
||||||
|
/* put things back to the initial state */
|
||||||
|
ctx->arglist = NULL;
|
||||||
|
ctx->argsize = NULL;
|
||||||
|
ctx->numargs = 0;
|
||||||
|
ctx->maxargs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pconf_init(PCONF_CTX_t *ctx, void errhandler(const char *))
|
||||||
|
{
|
||||||
|
/* set up the ctx elements */
|
||||||
|
|
||||||
|
ctx->f = NULL;
|
||||||
|
ctx->state = STATE_FINDWORDSTART;
|
||||||
|
ctx->numargs = 0;
|
||||||
|
ctx->maxargs = 0;
|
||||||
|
ctx->arg_limit = PCONF_DEFAULT_ARG_LIMIT;
|
||||||
|
ctx->wordlen_limit = PCONF_DEFAULT_WORDLEN_LIMIT;
|
||||||
|
ctx->linenum = 0;
|
||||||
|
ctx->error = 0;
|
||||||
|
ctx->arglist = NULL;
|
||||||
|
ctx->argsize = NULL;
|
||||||
|
|
||||||
|
ctx->wordbufsize = 16;
|
||||||
|
ctx->wordbuf = calloc(1, ctx->wordbufsize);
|
||||||
|
|
||||||
|
if (!ctx->wordbuf)
|
||||||
|
pconf_fatal(ctx, "malloc wordbuf failed");
|
||||||
|
ctx->wordptr = ctx->wordbuf;
|
||||||
|
|
||||||
|
ctx->errhandler = errhandler;
|
||||||
|
ctx->magic = PCONF_CTX_t_MAGIC;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_magic(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
if (!ctx)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ctx->magic != PCONF_CTX_t_MAGIC) {
|
||||||
|
snprintf(ctx->errmsg, PCONF_ERR_LEN, "Invalid ctx buffer");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pconf_file_begin(PCONF_CTX_t *ctx, const char *fn)
|
||||||
|
{
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctx->f = fopen(fn, "r");
|
||||||
|
|
||||||
|
if (!ctx->f) {
|
||||||
|
snprintf(ctx->errmsg, PCONF_ERR_LEN, "Can't open %s: %s",
|
||||||
|
fn, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prevent fd leaking to child processes */
|
||||||
|
fcntl(fileno(ctx->f), F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
|
return 1; /* OK */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_char(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
switch(ctx->state) {
|
||||||
|
case STATE_FINDWORDSTART:
|
||||||
|
ctx->state = findwordstart(ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_FINDEOL:
|
||||||
|
ctx->state = findeol(ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_QUOTECOLLECT:
|
||||||
|
ctx->state = quotecollect(ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_QC_LITERAL:
|
||||||
|
ctx->state = qc_literal(ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_COLLECT:
|
||||||
|
ctx->state = collect(ctx);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_COLLECTLITERAL:
|
||||||
|
ctx->state = collectliteral(ctx);
|
||||||
|
break;
|
||||||
|
} /* switch */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 1 if an error occurred, but only do it once */
|
||||||
|
int pconf_parse_error(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (ctx->error == 1) {
|
||||||
|
ctx->error = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up the ctx space */
|
||||||
|
void pconf_finish(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ctx->f)
|
||||||
|
fclose(ctx->f);
|
||||||
|
|
||||||
|
free_storage(ctx);
|
||||||
|
|
||||||
|
ctx->magic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read from a file until a whole line is ready for use */
|
||||||
|
int pconf_file_next(PCONF_CTX_t *ctx)
|
||||||
|
{
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctx->linenum++;
|
||||||
|
|
||||||
|
/* start over for the new line */
|
||||||
|
ctx->numargs = 0;
|
||||||
|
ctx->state = STATE_FINDWORDSTART;
|
||||||
|
|
||||||
|
while ((ctx->ch = fgetc(ctx->f)) != EOF) {
|
||||||
|
parse_char(ctx);
|
||||||
|
|
||||||
|
if (ctx->state == STATE_PARSEERR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (ctx->state == STATE_ENDOFLINE)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deal with files that don't end in a newline */
|
||||||
|
|
||||||
|
if (ctx->numargs != 0) {
|
||||||
|
|
||||||
|
/* still building a word? */
|
||||||
|
if (ctx->wordptr != ctx->wordbuf)
|
||||||
|
endofword(ctx);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finished with nothing left over */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse a provided line */
|
||||||
|
int pconf_line(PCONF_CTX_t *ctx, const char *line)
|
||||||
|
{
|
||||||
|
size_t i, linelen;
|
||||||
|
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctx->linenum++;
|
||||||
|
|
||||||
|
/* start over for the new line */
|
||||||
|
ctx->numargs = 0;
|
||||||
|
ctx->state = STATE_FINDWORDSTART;
|
||||||
|
|
||||||
|
linelen = strlen(line);
|
||||||
|
|
||||||
|
for (i = 0; i < linelen; i++) {
|
||||||
|
ctx->ch = line[i];
|
||||||
|
|
||||||
|
parse_char(ctx);
|
||||||
|
|
||||||
|
if (ctx->state == STATE_PARSEERR)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (ctx->state == STATE_ENDOFLINE)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deal with any lingering characters */
|
||||||
|
|
||||||
|
/* still building a word? */
|
||||||
|
if (ctx->wordptr != ctx->wordbuf)
|
||||||
|
endofword(ctx); /* tie it off */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PCONF_ESCAPE "#\\\""
|
||||||
|
|
||||||
|
char *pconf_encode(const char *src, char *dest, size_t destsize)
|
||||||
|
{
|
||||||
|
size_t i, srclen, destlen, maxlen;
|
||||||
|
|
||||||
|
if (destsize < 1)
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
memset(dest, '\0', destsize);
|
||||||
|
|
||||||
|
/* always leave room for a final NULL */
|
||||||
|
maxlen = destsize - 1;
|
||||||
|
srclen = strlen(src);
|
||||||
|
destlen = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < srclen; i++) {
|
||||||
|
if (strchr(PCONF_ESCAPE, src[i])) {
|
||||||
|
|
||||||
|
/* if they both won't fit, we're done */
|
||||||
|
if (destlen >= maxlen - 1)
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
dest[destlen++] = '\\';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bail out when dest is full */
|
||||||
|
if (destlen >= maxlen)
|
||||||
|
return dest;
|
||||||
|
|
||||||
|
dest[destlen++] = src[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse input a character at a time */
|
||||||
|
int pconf_char(PCONF_CTX_t *ctx, char ch)
|
||||||
|
{
|
||||||
|
if (!check_magic(ctx))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* if the last call finished a line, clean stuff up for another */
|
||||||
|
if ((ctx->state == STATE_ENDOFLINE) || (ctx->state == STATE_PARSEERR)) {
|
||||||
|
ctx->numargs = 0;
|
||||||
|
ctx->state = STATE_FINDWORDSTART;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->ch = ch;
|
||||||
|
parse_char(ctx);
|
||||||
|
|
||||||
|
if (ctx->state == STATE_ENDOFLINE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (ctx->state == STATE_PARSEERR)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
27
common/setenv.c
Normal file
27
common/setenv.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* setenv.c Ben Collver <collver@softhome.net> */
|
||||||
|
#ifndef HAVE_SETENV
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int nut_setenv(const char *name, const char *value, int overwrite)
|
||||||
|
{
|
||||||
|
char *val;
|
||||||
|
char *buffer;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (overwrite == 0) {
|
||||||
|
val = getenv(name);
|
||||||
|
if (val != NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = xmalloc(strlen(value) + strlen(name) + 2);
|
||||||
|
strcpy(buffer, name);
|
||||||
|
strcat(buffer, "=");
|
||||||
|
strcat(buffer, value);
|
||||||
|
rv = putenv(buffer); /* man putenv, do not free(buffer) */
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
#endif
|
965
common/snprintf.c
Normal file
965
common/snprintf.c
Normal file
|
@ -0,0 +1,965 @@
|
||||||
|
/*
|
||||||
|
* Copyright Patrick Powell 1995
|
||||||
|
* This code is based on code written by Patrick Powell (papowell@astart.com)
|
||||||
|
* It may be used for any purpose as long as this notice remains intact
|
||||||
|
* on all source code distributions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**************************************************************
|
||||||
|
* Original:
|
||||||
|
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
|
||||||
|
* A bombproof version of doprnt (dopr) included.
|
||||||
|
* Sigh. This sort of thing is always nasty do deal with. Note that
|
||||||
|
* the version here does not include floating point...
|
||||||
|
*
|
||||||
|
* snprintf() is used instead of sprintf() as it does limit checks
|
||||||
|
* for string length. This covers a nasty loophole.
|
||||||
|
*
|
||||||
|
* The other functions are there to prevent NULL pointers from
|
||||||
|
* causing nast effects.
|
||||||
|
*
|
||||||
|
* More Recently:
|
||||||
|
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
|
||||||
|
* This was ugly. It is still ugly. I opted out of floating point
|
||||||
|
* numbers, but the formatter understands just about everything
|
||||||
|
* from the normal C string format, at least as far as I can tell from
|
||||||
|
* the Solaris 2.5 printf(3S) man page.
|
||||||
|
*
|
||||||
|
* Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
|
||||||
|
* Ok, added some minimal floating point support, which means this
|
||||||
|
* probably requires libm on most operating systems. Don't yet
|
||||||
|
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
|
||||||
|
* was pretty badly broken, it just wasn't being exercised in ways
|
||||||
|
* which showed it, so that's been fixed. Also, formated the code
|
||||||
|
* to mutt conventions, and removed dead code left over from the
|
||||||
|
* original. Also, there is now a builtin-test, just compile with:
|
||||||
|
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
|
||||||
|
* and run snprintf for results.
|
||||||
|
*
|
||||||
|
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
|
||||||
|
* The PGP code was using unsigned hexadecimal formats.
|
||||||
|
* Unfortunately, unsigned formats simply didn't work.
|
||||||
|
*
|
||||||
|
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
|
||||||
|
* The original code assumed that both snprintf() and vsnprintf() were
|
||||||
|
* missing. Some systems only have snprintf() but not vsnprintf(), so
|
||||||
|
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
|
||||||
|
*
|
||||||
|
* Andrew Tridgell (tridge@samba.org) Oct 1998
|
||||||
|
* fixed handling of %.0f
|
||||||
|
* added test for HAVE_LONG_DOUBLE
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
|
||||||
|
|
||||||
|
/* Define this as a fall through, HAVE_STDARG_H is probably already set */
|
||||||
|
|
||||||
|
#ifndef HAVE_VARARGS_H
|
||||||
|
#define HAVE_VARARGS_H
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* varargs declarations: */
|
||||||
|
|
||||||
|
#if defined(HAVE_STDARG_H)
|
||||||
|
# include <stdarg.h>
|
||||||
|
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
|
||||||
|
# define VA_LOCAL_DECL va_list ap
|
||||||
|
# define VA_START(f) va_start(ap, f)
|
||||||
|
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
|
||||||
|
# define VA_END va_end(ap)
|
||||||
|
#else
|
||||||
|
# if defined(HAVE_VARARGS_H)
|
||||||
|
# include <varargs.h>
|
||||||
|
# undef HAVE_STDARGS
|
||||||
|
# define VA_LOCAL_DECL va_list ap
|
||||||
|
# define VA_START(f) va_start(ap) /* f is ignored! */
|
||||||
|
# define VA_SHIFT(v,t) v = va_arg(ap,t)
|
||||||
|
# define VA_END va_end(ap)
|
||||||
|
# else
|
||||||
|
/*XX ** NO VARARGS ** XX*/
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LONG_DOUBLE
|
||||||
|
#define LDOUBLE long double
|
||||||
|
#else
|
||||||
|
#define LDOUBLE double
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LONG_LONG_INT
|
||||||
|
#define LLONG long long
|
||||||
|
#else
|
||||||
|
#define LLONG long
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
|
||||||
|
/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
|
||||||
|
|
||||||
|
static void dopr (char *buffer, size_t maxlen, const char *format,
|
||||||
|
va_list args);
|
||||||
|
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
char *value, int flags, int min, int max);
|
||||||
|
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
long value, int base, int min, int max, int flags);
|
||||||
|
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
LDOUBLE fvalue, int min, int max, int flags);
|
||||||
|
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dopr(): poor man's version of doprintf
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* format read states */
|
||||||
|
#define DP_S_DEFAULT 0
|
||||||
|
#define DP_S_FLAGS 1
|
||||||
|
#define DP_S_MIN 2
|
||||||
|
#define DP_S_DOT 3
|
||||||
|
#define DP_S_MAX 4
|
||||||
|
#define DP_S_MOD 5
|
||||||
|
#define DP_S_CONV 6
|
||||||
|
#define DP_S_DONE 7
|
||||||
|
|
||||||
|
/* format flags - Bits */
|
||||||
|
#define DP_F_MINUS (1 << 0)
|
||||||
|
#define DP_F_PLUS (1 << 1)
|
||||||
|
#define DP_F_SPACE (1 << 2)
|
||||||
|
#define DP_F_NUM (1 << 3)
|
||||||
|
#define DP_F_ZERO (1 << 4)
|
||||||
|
#define DP_F_UP (1 << 5)
|
||||||
|
#define DP_F_UNSIGNED (1 << 6)
|
||||||
|
|
||||||
|
/* Conversion Flags */
|
||||||
|
#define DP_C_SHORT 1
|
||||||
|
/* Note: Originally DP_C_SHORT converted to "short int" types, but modernish
|
||||||
|
* (C99+ or even earlier) standards require that the minimal type passed
|
||||||
|
* through variadic args '...' is an int, and smaller types are padded up
|
||||||
|
* to it - so value shifts in memory and erroneous access crashes can occur
|
||||||
|
* if smaller data is accessed blindly. Code below has been fixed to not pass
|
||||||
|
* "short int" anymore - it just casts the int to desired smaller type (and
|
||||||
|
* so drops the padding bits). */
|
||||||
|
#define DP_C_LONG 2
|
||||||
|
#define DP_C_LDOUBLE 3
|
||||||
|
#define DP_C_LLONG 4
|
||||||
|
|
||||||
|
#ifdef C89PLUS
|
||||||
|
#undef C89PLUS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__STDC__) || defined(__STDC_VERSION__)
|
||||||
|
/* C89+ and C90+ code respectively */
|
||||||
|
#define C89PLUS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define char_to_int(p) ((p)- '0')
|
||||||
|
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
|
||||||
|
|
||||||
|
static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
LLONG value;
|
||||||
|
LDOUBLE fvalue;
|
||||||
|
char *strvalue;
|
||||||
|
int min;
|
||||||
|
int max;
|
||||||
|
int state;
|
||||||
|
int flags;
|
||||||
|
int cflags;
|
||||||
|
size_t currlen;
|
||||||
|
|
||||||
|
state = DP_S_DEFAULT;
|
||||||
|
currlen = flags = cflags = min = 0;
|
||||||
|
max = -1;
|
||||||
|
ch = *format++;
|
||||||
|
|
||||||
|
while (state != DP_S_DONE)
|
||||||
|
{
|
||||||
|
if ((ch == '\0') || (currlen >= maxlen))
|
||||||
|
state = DP_S_DONE;
|
||||||
|
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
case DP_S_DEFAULT:
|
||||||
|
if (ch == '%')
|
||||||
|
state = DP_S_FLAGS;
|
||||||
|
else
|
||||||
|
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case DP_S_FLAGS:
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case '-':
|
||||||
|
flags |= DP_F_MINUS;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
flags |= DP_F_PLUS;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
flags |= DP_F_SPACE;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case '#':
|
||||||
|
flags |= DP_F_NUM;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
flags |= DP_F_ZERO;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = DP_S_MIN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DP_S_MIN:
|
||||||
|
if (isdigit((unsigned char)ch))
|
||||||
|
{
|
||||||
|
min = 10*min + char_to_int (ch);
|
||||||
|
ch = *format++;
|
||||||
|
}
|
||||||
|
else if (ch == '*')
|
||||||
|
{
|
||||||
|
min = va_arg (args, int);
|
||||||
|
ch = *format++;
|
||||||
|
state = DP_S_DOT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = DP_S_DOT;
|
||||||
|
break;
|
||||||
|
case DP_S_DOT:
|
||||||
|
if (ch == '.')
|
||||||
|
{
|
||||||
|
state = DP_S_MAX;
|
||||||
|
ch = *format++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = DP_S_MOD;
|
||||||
|
break;
|
||||||
|
case DP_S_MAX:
|
||||||
|
if (isdigit((unsigned char)ch))
|
||||||
|
{
|
||||||
|
if (max < 0)
|
||||||
|
max = 0;
|
||||||
|
max = 10*max + char_to_int (ch);
|
||||||
|
ch = *format++;
|
||||||
|
}
|
||||||
|
else if (ch == '*')
|
||||||
|
{
|
||||||
|
max = va_arg (args, int);
|
||||||
|
ch = *format++;
|
||||||
|
state = DP_S_MOD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
state = DP_S_MOD;
|
||||||
|
break;
|
||||||
|
case DP_S_MOD:
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
cflags = DP_C_SHORT;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
cflags = DP_C_LONG;
|
||||||
|
ch = *format++;
|
||||||
|
if (ch == 'l') { /* It's a long long */
|
||||||
|
cflags = DP_C_LLONG;
|
||||||
|
ch = *format++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
cflags = DP_C_LDOUBLE;
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state = DP_S_CONV;
|
||||||
|
break;
|
||||||
|
case DP_S_CONV:
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
if (cflags == DP_C_SHORT)
|
||||||
|
#ifdef C89PLUS
|
||||||
|
value = (short int)va_arg (args, int);
|
||||||
|
#else
|
||||||
|
value = va_arg (args, short int);
|
||||||
|
#endif
|
||||||
|
else if (cflags == DP_C_LONG)
|
||||||
|
value = va_arg (args, long int);
|
||||||
|
else if (cflags == DP_C_LLONG)
|
||||||
|
value = va_arg (args, LLONG);
|
||||||
|
else
|
||||||
|
value = va_arg (args, int);
|
||||||
|
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
flags |= DP_F_UNSIGNED;
|
||||||
|
if (cflags == DP_C_SHORT)
|
||||||
|
#ifdef C89PLUS
|
||||||
|
value = (unsigned short int)va_arg (args, unsigned int);
|
||||||
|
#else
|
||||||
|
value = va_arg (args, unsigned short int);
|
||||||
|
#endif
|
||||||
|
else if (cflags == DP_C_LONG)
|
||||||
|
value = (long)va_arg (args, unsigned long int);
|
||||||
|
else if (cflags == DP_C_LLONG)
|
||||||
|
value = (long)va_arg (args, unsigned LLONG);
|
||||||
|
else
|
||||||
|
value = (long)va_arg (args, unsigned int);
|
||||||
|
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
flags |= DP_F_UNSIGNED;
|
||||||
|
if (cflags == DP_C_SHORT)
|
||||||
|
#ifdef C89PLUS
|
||||||
|
value = (unsigned short int)va_arg (args, unsigned int);
|
||||||
|
#else
|
||||||
|
value = va_arg (args, unsigned short int);
|
||||||
|
#endif
|
||||||
|
else if (cflags == DP_C_LONG)
|
||||||
|
value = (long)va_arg (args, unsigned long int);
|
||||||
|
else if (cflags == DP_C_LLONG)
|
||||||
|
value = (LLONG)va_arg (args, unsigned LLONG);
|
||||||
|
else
|
||||||
|
value = (long)va_arg (args, unsigned int);
|
||||||
|
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
flags |= DP_F_UP;
|
||||||
|
goto fallthrough_case_x;
|
||||||
|
case 'x':
|
||||||
|
fallthrough_case_x:
|
||||||
|
flags |= DP_F_UNSIGNED;
|
||||||
|
if (cflags == DP_C_SHORT)
|
||||||
|
#ifdef C89PLUS
|
||||||
|
value = (unsigned short int)va_arg (args, unsigned int);
|
||||||
|
#else
|
||||||
|
value = va_arg (args, unsigned short int);
|
||||||
|
#endif
|
||||||
|
else if (cflags == DP_C_LONG)
|
||||||
|
value = (long)va_arg (args, unsigned long int);
|
||||||
|
else if (cflags == DP_C_LLONG)
|
||||||
|
value = (LLONG)va_arg (args, unsigned LLONG);
|
||||||
|
else
|
||||||
|
value = (long)va_arg (args, unsigned int);
|
||||||
|
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (cflags == DP_C_LDOUBLE)
|
||||||
|
fvalue = va_arg (args, LDOUBLE);
|
||||||
|
else
|
||||||
|
fvalue = va_arg (args, double);
|
||||||
|
/* um, floating point? */
|
||||||
|
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'E':
|
||||||
|
flags |= DP_F_UP;
|
||||||
|
goto fallthrough_case_e;
|
||||||
|
case 'e':
|
||||||
|
fallthrough_case_e:
|
||||||
|
if (cflags == DP_C_LDOUBLE)
|
||||||
|
fvalue = va_arg (args, LDOUBLE);
|
||||||
|
else
|
||||||
|
fvalue = va_arg (args, double);
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
flags |= DP_F_UP;
|
||||||
|
goto fallthrough_case_g;
|
||||||
|
case 'g':
|
||||||
|
fallthrough_case_g:
|
||||||
|
if (cflags == DP_C_LDOUBLE)
|
||||||
|
fvalue = va_arg (args, LDOUBLE);
|
||||||
|
else
|
||||||
|
fvalue = va_arg (args, double);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
strvalue = va_arg (args, char *);
|
||||||
|
if (max < 0)
|
||||||
|
max = maxlen; /* ie, no max */
|
||||||
|
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
strvalue = va_arg (args, void *);
|
||||||
|
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (cflags == DP_C_SHORT)
|
||||||
|
{
|
||||||
|
short int *num;
|
||||||
|
num = va_arg (args, short int *);
|
||||||
|
*num = currlen;
|
||||||
|
}
|
||||||
|
else if (cflags == DP_C_LONG)
|
||||||
|
{
|
||||||
|
long int *num;
|
||||||
|
num = va_arg (args, long int *);
|
||||||
|
*num = (long int)currlen;
|
||||||
|
}
|
||||||
|
else if (cflags == DP_C_LLONG)
|
||||||
|
{
|
||||||
|
LLONG *num;
|
||||||
|
num = va_arg (args, LLONG *);
|
||||||
|
*num = (LLONG)currlen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int *num;
|
||||||
|
num = va_arg (args, int *);
|
||||||
|
*num = currlen;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
/* not supported yet, treat as next char */
|
||||||
|
ch = *format++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Unknown, skip */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ch = *format++;
|
||||||
|
state = DP_S_DEFAULT;
|
||||||
|
flags = cflags = min = 0;
|
||||||
|
max = -1;
|
||||||
|
break;
|
||||||
|
case DP_S_DONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* hmm? */
|
||||||
|
break; /* some picky compilers need this */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currlen < maxlen - 1)
|
||||||
|
buffer[currlen] = '\0';
|
||||||
|
else
|
||||||
|
buffer[maxlen - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
char *value, int flags, int min, int max)
|
||||||
|
{
|
||||||
|
int padlen, strln; /* amount to pad */
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
if (value == 0)
|
||||||
|
{
|
||||||
|
value = "<NULL>";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (strln = 0; value[strln]; ++strln); /* strlen */
|
||||||
|
padlen = min - strln;
|
||||||
|
if (padlen < 0)
|
||||||
|
padlen = 0;
|
||||||
|
if (flags & DP_F_MINUS)
|
||||||
|
padlen = -padlen; /* Left Justify */
|
||||||
|
|
||||||
|
while ((padlen > 0) && (cnt < max))
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
--padlen;
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
while (*value && (cnt < max))
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, *value++);
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
while ((padlen < 0) && (cnt < max))
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
++padlen;
|
||||||
|
++cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
|
||||||
|
|
||||||
|
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
long value, int base, int min, int max, int flags)
|
||||||
|
{
|
||||||
|
int signvalue = 0;
|
||||||
|
unsigned long uvalue;
|
||||||
|
char convert[20];
|
||||||
|
int place = 0;
|
||||||
|
int spadlen = 0; /* amount to space pad */
|
||||||
|
int zpadlen = 0; /* amount to zero pad */
|
||||||
|
int caps = 0;
|
||||||
|
|
||||||
|
if (max < 0)
|
||||||
|
max = 0;
|
||||||
|
|
||||||
|
uvalue = value;
|
||||||
|
|
||||||
|
if(!(flags & DP_F_UNSIGNED))
|
||||||
|
{
|
||||||
|
if( value < 0 ) {
|
||||||
|
signvalue = '-';
|
||||||
|
uvalue = -value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||||
|
signvalue = '+';
|
||||||
|
else
|
||||||
|
if (flags & DP_F_SPACE)
|
||||||
|
signvalue = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
|
||||||
|
|
||||||
|
do {
|
||||||
|
convert[place++] =
|
||||||
|
(caps? "0123456789ABCDEF":"0123456789abcdef")
|
||||||
|
[uvalue % (unsigned)base ];
|
||||||
|
uvalue = (uvalue / (unsigned)base );
|
||||||
|
} while(uvalue && (place < 20));
|
||||||
|
if (place == 20) place--;
|
||||||
|
convert[place] = 0;
|
||||||
|
|
||||||
|
zpadlen = max - place;
|
||||||
|
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
|
||||||
|
if (zpadlen < 0) zpadlen = 0;
|
||||||
|
if (spadlen < 0) spadlen = 0;
|
||||||
|
if (flags & DP_F_ZERO)
|
||||||
|
{
|
||||||
|
zpadlen = MAX(zpadlen, spadlen);
|
||||||
|
spadlen = 0;
|
||||||
|
}
|
||||||
|
if (flags & DP_F_MINUS)
|
||||||
|
spadlen = -spadlen; /* Left Justifty */
|
||||||
|
|
||||||
|
#ifdef DEBUG_SNPRINTF
|
||||||
|
printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
|
||||||
|
zpadlen, spadlen, min, max, place);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Spaces */
|
||||||
|
while (spadlen > 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
--spadlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sign */
|
||||||
|
if (signvalue)
|
||||||
|
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||||
|
|
||||||
|
/* Zeros */
|
||||||
|
if (zpadlen > 0)
|
||||||
|
{
|
||||||
|
while (zpadlen > 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, '0');
|
||||||
|
--zpadlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digits */
|
||||||
|
while (place > 0)
|
||||||
|
dopr_outch (buffer, currlen, maxlen, convert[--place]);
|
||||||
|
|
||||||
|
/* Left Justified spaces */
|
||||||
|
while (spadlen < 0) {
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
++spadlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef HAVE_ABS_VAL
|
||||||
|
static LDOUBLE abs_val (LDOUBLE value)
|
||||||
|
{
|
||||||
|
LDOUBLE result = value;
|
||||||
|
|
||||||
|
if (value < 0)
|
||||||
|
result = -value;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_FCVT
|
||||||
|
/* The two routines that may get defined below are only used if we also don't
|
||||||
|
* have a fcvt() in the system. Defining and not using the routines may be a
|
||||||
|
* warning (fatal with -Werror), so we hide them here. */
|
||||||
|
# ifndef HAVE_POW10
|
||||||
|
static LDOUBLE pow10 (int exp)
|
||||||
|
{
|
||||||
|
LDOUBLE result = 1;
|
||||||
|
|
||||||
|
while (exp)
|
||||||
|
{
|
||||||
|
result *= 10;
|
||||||
|
exp--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifndef HAVE_ROUND
|
||||||
|
static long round (LDOUBLE value)
|
||||||
|
{
|
||||||
|
long intpart;
|
||||||
|
|
||||||
|
intpart = (long)value;
|
||||||
|
value = value - intpart;
|
||||||
|
if (value >= 0.5)
|
||||||
|
intpart++;
|
||||||
|
|
||||||
|
return intpart;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif /* HAVE_FCVT */
|
||||||
|
|
||||||
|
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||||
|
LDOUBLE fvalue, int min, int max, int flags)
|
||||||
|
{
|
||||||
|
int signvalue = 0;
|
||||||
|
LDOUBLE ufvalue;
|
||||||
|
#ifndef HAVE_FCVT
|
||||||
|
char iconvert[20];
|
||||||
|
char fconvert[20];
|
||||||
|
#else
|
||||||
|
char iconvert[311];
|
||||||
|
char fconvert[311];
|
||||||
|
char *result;
|
||||||
|
int dec_pt, sig;
|
||||||
|
int r_length;
|
||||||
|
# ifdef HAVE_FCVTL
|
||||||
|
extern char *fcvtl(long double value, int ndigit, int *decpt, int *sign);
|
||||||
|
# else
|
||||||
|
extern char *fcvt(double value, int ndigit, int *decpt, int *sign);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
int iplace = 0;
|
||||||
|
int fplace = 0;
|
||||||
|
int padlen = 0; /* amount to pad */
|
||||||
|
int zpadlen = 0;
|
||||||
|
#ifndef HAVE_FCVT
|
||||||
|
int caps = 0;
|
||||||
|
long intpart;
|
||||||
|
long fracpart;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AIX manpage says the default is 0, but Solaris says the default
|
||||||
|
* is 6, and sprintf on AIX defaults to 6
|
||||||
|
*/
|
||||||
|
if (max < 0)
|
||||||
|
max = 6;
|
||||||
|
|
||||||
|
ufvalue = abs_val (fvalue);
|
||||||
|
|
||||||
|
if (fvalue < 0)
|
||||||
|
signvalue = '-';
|
||||||
|
else
|
||||||
|
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||||
|
signvalue = '+';
|
||||||
|
else
|
||||||
|
if (flags & DP_F_SPACE)
|
||||||
|
signvalue = ' ';
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_FCVT
|
||||||
|
intpart = (long)ufvalue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sorry, we only support 9 digits past the decimal because of our
|
||||||
|
* conversion method
|
||||||
|
*/
|
||||||
|
if (max > 9)
|
||||||
|
max = 9;
|
||||||
|
|
||||||
|
/* We "cheat" by converting the fractional part to integer by
|
||||||
|
* multiplying by a factor of 10
|
||||||
|
*/
|
||||||
|
fracpart = round ((pow10 (max)) * (ufvalue - intpart));
|
||||||
|
|
||||||
|
if (fracpart >= pow10 (max))
|
||||||
|
{
|
||||||
|
intpart++;
|
||||||
|
fracpart -= pow10 (max);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_SNPRINTF
|
||||||
|
printf("fmtfp: %g %d.%d min=%d max=%d\n",
|
||||||
|
(double)fvalue, intpart, fracpart, min, max);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Convert integer part */
|
||||||
|
do {
|
||||||
|
iconvert[iplace++] =
|
||||||
|
(caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
|
||||||
|
intpart = (intpart / 10);
|
||||||
|
} while(intpart && (iplace < 20));
|
||||||
|
if (iplace == 20) iplace--;
|
||||||
|
iconvert[iplace] = 0;
|
||||||
|
|
||||||
|
/* Convert fractional part */
|
||||||
|
do {
|
||||||
|
fconvert[fplace++] =
|
||||||
|
(caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
|
||||||
|
fracpart = (fracpart / 10);
|
||||||
|
} while(fracpart && (fplace < 20));
|
||||||
|
if (fplace == 20) fplace--;
|
||||||
|
fconvert[fplace] = 0;
|
||||||
|
#else /* use fcvt() */
|
||||||
|
if (max > 310)
|
||||||
|
max = 310;
|
||||||
|
# ifdef HAVE_FCVTL
|
||||||
|
result = fcvtl(ufvalue, max, &dec_pt, &sig);
|
||||||
|
# else
|
||||||
|
result = fcvt(ufvalue, max, &dec_pt, &sig);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
r_length = strlen(result);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix broken fcvt implementation returns..
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (r_length == 0)
|
||||||
|
{
|
||||||
|
result[0] = '0';
|
||||||
|
result[1] = '\0';
|
||||||
|
r_length = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( r_length < dec_pt )
|
||||||
|
dec_pt = r_length;
|
||||||
|
|
||||||
|
if (dec_pt <= 0) {
|
||||||
|
iplace = 1;
|
||||||
|
iconvert[0] = '0';
|
||||||
|
iconvert[1] = '\0';
|
||||||
|
|
||||||
|
fplace = 0;
|
||||||
|
|
||||||
|
while(r_length)
|
||||||
|
fconvert[fplace++] = result[--r_length];
|
||||||
|
|
||||||
|
while ((dec_pt < 0) && (fplace < max)) {
|
||||||
|
fconvert[fplace++] = '0';
|
||||||
|
dec_pt++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int c;
|
||||||
|
|
||||||
|
iplace=0;
|
||||||
|
for(c=dec_pt; c; iconvert[iplace++] = result[--c])
|
||||||
|
;
|
||||||
|
iconvert[iplace] = '\0';
|
||||||
|
|
||||||
|
result += dec_pt;
|
||||||
|
fplace = 0;
|
||||||
|
|
||||||
|
for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
#endif /* fcvt */
|
||||||
|
|
||||||
|
/* -1 for decimal point, another -1 if we are printing a sign */
|
||||||
|
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
||||||
|
zpadlen = max - fplace;
|
||||||
|
if (zpadlen < 0)
|
||||||
|
zpadlen = 0;
|
||||||
|
if (padlen < 0)
|
||||||
|
padlen = 0;
|
||||||
|
if (flags & DP_F_MINUS)
|
||||||
|
padlen = -padlen; /* Left Justifty */
|
||||||
|
|
||||||
|
if ((flags & DP_F_ZERO) && (padlen > 0))
|
||||||
|
{
|
||||||
|
if (signvalue)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||||
|
--padlen;
|
||||||
|
signvalue = 0;
|
||||||
|
}
|
||||||
|
while (padlen > 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, '0');
|
||||||
|
--padlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (padlen > 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
--padlen;
|
||||||
|
}
|
||||||
|
if (signvalue)
|
||||||
|
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||||
|
|
||||||
|
while (iplace > 0)
|
||||||
|
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DEBUG_SNPRINTF
|
||||||
|
printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decimal point. This should probably use locale to find the correct
|
||||||
|
* char to print out.
|
||||||
|
*/
|
||||||
|
if (max > 0) {
|
||||||
|
dopr_outch (buffer, currlen, maxlen, '.');
|
||||||
|
|
||||||
|
while (fplace > 0)
|
||||||
|
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (zpadlen > 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, '0');
|
||||||
|
--zpadlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (padlen < 0)
|
||||||
|
{
|
||||||
|
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||||
|
++padlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
|
||||||
|
{
|
||||||
|
if (*currlen < maxlen)
|
||||||
|
buffer[(*currlen)++] = c;
|
||||||
|
}
|
||||||
|
#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
|
||||||
|
|
||||||
|
#ifndef HAVE_VSNPRINTF
|
||||||
|
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
str[0] = 0;
|
||||||
|
dopr(str, count, fmt, args);
|
||||||
|
return(strlen(str));
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_VSNPRINTF */
|
||||||
|
|
||||||
|
#ifndef HAVE_SNPRINTF
|
||||||
|
/* VARARGS3 */
|
||||||
|
#ifdef HAVE_STDARGS
|
||||||
|
int snprintf (char *str,size_t count,const char *fmt,...)
|
||||||
|
#else
|
||||||
|
int snprintf (va_alist) va_dcl
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef HAVE_STDARGS
|
||||||
|
char *str;
|
||||||
|
size_t count;
|
||||||
|
char *fmt;
|
||||||
|
#endif
|
||||||
|
VA_LOCAL_DECL;
|
||||||
|
|
||||||
|
VA_START (fmt);
|
||||||
|
VA_SHIFT (str, char *);
|
||||||
|
VA_SHIFT (count, size_t );
|
||||||
|
VA_SHIFT (fmt, char *);
|
||||||
|
(void) vsnprintf(str, count, fmt, ap);
|
||||||
|
VA_END;
|
||||||
|
return(strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* keep compilers happy about empty files */
|
||||||
|
void dummy_snprintf(void) {}
|
||||||
|
#endif /* !HAVE_SNPRINTF */
|
||||||
|
|
||||||
|
#ifdef TEST_SNPRINTF
|
||||||
|
#ifndef LONG_STRING
|
||||||
|
#define LONG_STRING 1024
|
||||||
|
#endif
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
char buf1[LONG_STRING];
|
||||||
|
char buf2[LONG_STRING];
|
||||||
|
char *fp_fmt[] = {
|
||||||
|
"%-1.5f",
|
||||||
|
"%1.5f",
|
||||||
|
"%123.9f",
|
||||||
|
"%10.5f",
|
||||||
|
"% 10.5f",
|
||||||
|
"%+22.9f",
|
||||||
|
"%+4.9f",
|
||||||
|
"%01.3f",
|
||||||
|
"%4f",
|
||||||
|
"%3.1f",
|
||||||
|
"%3.2f",
|
||||||
|
"%.0f",
|
||||||
|
"%.1f",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
|
||||||
|
0.9996, 1.996, 4.136, 6442452944.1234, 0};
|
||||||
|
char *int_fmt[] = {
|
||||||
|
"%-1.5d",
|
||||||
|
"%1.5d",
|
||||||
|
"%123.9d",
|
||||||
|
"%5.5d",
|
||||||
|
"%10.5d",
|
||||||
|
"% 10.5d",
|
||||||
|
"%+22.33d",
|
||||||
|
"%01.3d",
|
||||||
|
"%4d",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
|
||||||
|
int x, y;
|
||||||
|
int fail = 0;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
printf ("Testing snprintf format codes against system sprintf...\n");
|
||||||
|
|
||||||
|
for (x = 0; fp_fmt[x] != NULL ; x++)
|
||||||
|
for (y = 0; fp_nums[y] != 0 ; y++)
|
||||||
|
{
|
||||||
|
snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
|
||||||
|
sprintf (buf2, fp_fmt[x], fp_nums[y]);
|
||||||
|
if (strcmp (buf1, buf2))
|
||||||
|
{
|
||||||
|
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||||
|
fp_fmt[x], buf1, buf2);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (x = 0; int_fmt[x] != NULL ; x++)
|
||||||
|
for (y = 0; int_nums[y] != 0 ; y++)
|
||||||
|
{
|
||||||
|
snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
|
||||||
|
sprintf (buf2, int_fmt[x], int_nums[y]);
|
||||||
|
if (strcmp (buf1, buf2))
|
||||||
|
{
|
||||||
|
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||||
|
int_fmt[x], buf1, buf2);
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
printf ("%d tests failed out of %d.\n", fail, num);
|
||||||
|
}
|
||||||
|
#endif /* SNPRINTF_TEST */
|
||||||
|
|
621
common/state.c
Normal file
621
common/state.c
Normal file
|
@ -0,0 +1,621 @@
|
||||||
|
/* state.c - Network UPS Tools common state management functions
|
||||||
|
|
||||||
|
Copyright (C)
|
||||||
|
2003 Russell Kroll <rkroll@exploits.org>
|
||||||
|
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||||
|
2012 Arnaud Quette <arnaud.quette@free.fr>
|
||||||
|
|
||||||
|
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 "config.h" /* must be first */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "state.h"
|
||||||
|
#include "parseconf.h"
|
||||||
|
|
||||||
|
static void val_escape(st_tree_t *node)
|
||||||
|
{
|
||||||
|
char etmp[ST_MAX_VALUE_LEN];
|
||||||
|
|
||||||
|
/* escape any tricky stuff like \ and " */
|
||||||
|
pconf_encode(node->raw, etmp, sizeof(etmp));
|
||||||
|
|
||||||
|
/* if nothing was escaped, we don't need to do anything else */
|
||||||
|
if (!strcmp(node->raw, etmp)) {
|
||||||
|
node->val = node->raw;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the escaped value grew, deal with it */
|
||||||
|
if (node->safesize < (strlen(etmp) + 1)) {
|
||||||
|
node->safesize = strlen(etmp) + 1;
|
||||||
|
node->safe = xrealloc(node->safe, node->safesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(node->safe, node->safesize, "%s", etmp);
|
||||||
|
node->val = node->safe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_tree_enum_free(enum_t *list)
|
||||||
|
{
|
||||||
|
if (!list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_tree_enum_free(list->next);
|
||||||
|
|
||||||
|
free(list->val);
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_tree_range_free(range_t *list)
|
||||||
|
{
|
||||||
|
if (!list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_tree_range_free(list->next);
|
||||||
|
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free all memory associated with a node */
|
||||||
|
static void st_tree_node_free(st_tree_t *node)
|
||||||
|
{
|
||||||
|
free(node->var);
|
||||||
|
free(node->raw);
|
||||||
|
free(node->safe);
|
||||||
|
|
||||||
|
/* never free node->val, since it's just a pointer to raw or safe */
|
||||||
|
|
||||||
|
/* blow away the list of enums */
|
||||||
|
st_tree_enum_free(node->enum_list);
|
||||||
|
|
||||||
|
/* and the list of ranges */
|
||||||
|
st_tree_range_free(node->range_list);
|
||||||
|
|
||||||
|
/* now finally kill the node itself */
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add a subtree to another subtree */
|
||||||
|
static void st_tree_node_add(st_tree_t **nptr, st_tree_t *sptr)
|
||||||
|
{
|
||||||
|
if (!sptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*nptr) {
|
||||||
|
|
||||||
|
st_tree_t *node = *nptr;
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, sptr->var) > 0) {
|
||||||
|
nptr = &node->left;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, sptr->var) < 0) {
|
||||||
|
nptr = &node->right;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
upsdebugx(1, "%s: duplicate value (shouldn't happen)", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nptr = sptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove a variable from a tree
|
||||||
|
* except for variables with ST_FLAG_IMMUTABLE
|
||||||
|
* (for override.* to survive) per issue #737
|
||||||
|
*/
|
||||||
|
int state_delinfo(st_tree_t **nptr, const char *var)
|
||||||
|
{
|
||||||
|
while (*nptr) {
|
||||||
|
|
||||||
|
st_tree_t *node = *nptr;
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) > 0) {
|
||||||
|
nptr = &node->left;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) < 0) {
|
||||||
|
nptr = &node->right;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->flags & ST_FLAG_IMMUTABLE) {
|
||||||
|
upsdebugx(6, "%s: not deleting immutable variable [%s]", __func__, var);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* whatever is on the left, hang it off current right */
|
||||||
|
st_tree_node_add(&node->right, node->left);
|
||||||
|
|
||||||
|
/* now point the parent at the old right child */
|
||||||
|
*nptr = node->right;
|
||||||
|
|
||||||
|
st_tree_node_free(node);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* interface */
|
||||||
|
|
||||||
|
int state_setinfo(st_tree_t **nptr, const char *var, const char *val)
|
||||||
|
{
|
||||||
|
while (*nptr) {
|
||||||
|
|
||||||
|
st_tree_t *node = *nptr;
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) > 0) {
|
||||||
|
nptr = &node->left;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) < 0) {
|
||||||
|
nptr = &node->right;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* updating an existing entry */
|
||||||
|
if (!strcasecmp(node->raw, val)) {
|
||||||
|
return 0; /* no change */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* changes should be ignored */
|
||||||
|
if (node->flags & ST_FLAG_IMMUTABLE) {
|
||||||
|
return 0; /* no change */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expand the buffer if the value grows */
|
||||||
|
if (node->rawsize < (strlen(val) + 1)) {
|
||||||
|
node->rawsize = strlen(val) + 1;
|
||||||
|
node->raw = xrealloc(node->raw, node->rawsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store the literal value for later comparisons */
|
||||||
|
snprintf(node->raw, node->rawsize, "%s", val);
|
||||||
|
|
||||||
|
val_escape(node);
|
||||||
|
|
||||||
|
return 1; /* changed */
|
||||||
|
}
|
||||||
|
|
||||||
|
*nptr = xcalloc(1, sizeof(**nptr));
|
||||||
|
|
||||||
|
(*nptr)->var = xstrdup(var);
|
||||||
|
(*nptr)->raw = xstrdup(val);
|
||||||
|
(*nptr)->rawsize = strlen(val) + 1;
|
||||||
|
|
||||||
|
val_escape(*nptr);
|
||||||
|
|
||||||
|
return 1; /* added */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int st_tree_enum_add(enum_t **list, const char *enc)
|
||||||
|
{
|
||||||
|
enum_t *item;
|
||||||
|
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
if (strcmp((*list)->val, enc)) {
|
||||||
|
list = &(*list)->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* duplicate */
|
||||||
|
}
|
||||||
|
|
||||||
|
item = xcalloc(1, sizeof(*item));
|
||||||
|
item->val = xstrdup(enc);
|
||||||
|
item->next = *list;
|
||||||
|
|
||||||
|
/* now we're done creating it, add it to the list */
|
||||||
|
*list = item;
|
||||||
|
|
||||||
|
return 1; /* added */
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_addenum(st_tree_t *root, const char *var, const char *val)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
char enc[ST_MAX_VALUE_LEN];
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
upslogx(LOG_ERR, "state_addenum: base variable (%s) "
|
||||||
|
"does not exist", var);
|
||||||
|
return 0; /* failed */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* smooth over any oddities in the enum value */
|
||||||
|
pconf_encode(val, enc, sizeof(enc));
|
||||||
|
|
||||||
|
return st_tree_enum_add(&sttmp->enum_list, enc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int st_tree_range_add(range_t **list, const int min, const int max)
|
||||||
|
{
|
||||||
|
range_t *item;
|
||||||
|
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
if (((*list)->min != min) && ((*list)->max != max)) {
|
||||||
|
list = &(*list)->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* duplicate */
|
||||||
|
}
|
||||||
|
|
||||||
|
item = xcalloc(1, sizeof(*item));
|
||||||
|
item->min = min;
|
||||||
|
item->max = max;
|
||||||
|
item->next = *list;
|
||||||
|
|
||||||
|
/* now we're done creating it, add it to the list */
|
||||||
|
*list = item;
|
||||||
|
|
||||||
|
return 1; /* added */
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_addrange(st_tree_t *root, const char *var, const int min, const int max)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
if (min > max) {
|
||||||
|
upslogx(LOG_ERR, "state_addrange: min is superior to max! (%i, %i)",
|
||||||
|
min, max);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
upslogx(LOG_ERR, "state_addrange: base variable (%s) "
|
||||||
|
"does not exist", var);
|
||||||
|
return 0; /* failed */
|
||||||
|
}
|
||||||
|
|
||||||
|
return st_tree_range_add(&sttmp->range_list, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_setaux(st_tree_t *root, const char *var, const char *auxs)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
long aux;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
upslogx(LOG_ERR, "state_addenum: base variable (%s) "
|
||||||
|
"does not exist", var);
|
||||||
|
return -1; /* failed */
|
||||||
|
}
|
||||||
|
|
||||||
|
aux = strtol(auxs, (char **) NULL, 10);
|
||||||
|
|
||||||
|
/* silently ignore matches */
|
||||||
|
if (sttmp->aux == aux) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sttmp->aux = aux;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *state_getinfo(st_tree_t *root, const char *var)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sttmp->val;
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_getflags(st_tree_t *root, const char *var)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sttmp->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
long state_getaux(st_tree_t *root, const char *var)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sttmp->aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
const enum_t *state_getenumlist(st_tree_t *root, const char *var)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sttmp->enum_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
const range_t *state_getrangelist(st_tree_t *root, const char *var)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sttmp->range_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_setflags(st_tree_t *root, const char *var, size_t numflags, char **flag)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
upslogx(LOG_ERR, "state_setflags: base variable (%s) "
|
||||||
|
"does not exist", var);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sttmp->flags = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < numflags; i++) {
|
||||||
|
|
||||||
|
if (!strcasecmp(flag[i], "RW")) {
|
||||||
|
sttmp->flags |= ST_FLAG_RW;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(flag[i], "STRING")) {
|
||||||
|
sttmp->flags |= ST_FLAG_STRING;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcasecmp(flag[i], "NUMBER")) {
|
||||||
|
sttmp->flags |= ST_FLAG_NUMBER;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
upsdebugx(2, "Unrecognized flag [%s]", flag[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_addcmd(cmdlist_t **list, const char *cmd)
|
||||||
|
{
|
||||||
|
cmdlist_t *item;
|
||||||
|
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
if (strcasecmp((*list)->name, cmd) > 0) {
|
||||||
|
/* insertion point reached */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp((*list)->name, cmd) < 0) {
|
||||||
|
list = &(*list)->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* duplicate */
|
||||||
|
}
|
||||||
|
|
||||||
|
item = xcalloc(1, sizeof(*item));
|
||||||
|
item->name = xstrdup(cmd);
|
||||||
|
item->next = *list;
|
||||||
|
|
||||||
|
/* now we're done creating it, insert it in the list */
|
||||||
|
*list = item;
|
||||||
|
|
||||||
|
return 1; /* added */
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_infofree(st_tree_t *node)
|
||||||
|
{
|
||||||
|
if (!node) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_infofree(node->left);
|
||||||
|
state_infofree(node->right);
|
||||||
|
|
||||||
|
st_tree_node_free(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void state_cmdfree(cmdlist_t *list)
|
||||||
|
{
|
||||||
|
if (!list) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_cmdfree(list->next);
|
||||||
|
|
||||||
|
free(list->name);
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_delcmd(cmdlist_t **list, const char *cmd)
|
||||||
|
{
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
cmdlist_t *item = *list;
|
||||||
|
|
||||||
|
if (strcasecmp(item->name, cmd) > 0) {
|
||||||
|
/* not found */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(item->name, cmd) < 0) {
|
||||||
|
list = &item->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found it! */
|
||||||
|
|
||||||
|
*list = item->next;
|
||||||
|
|
||||||
|
free(item->name);
|
||||||
|
free(item);
|
||||||
|
|
||||||
|
return 1; /* deleted */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int st_tree_del_enum(enum_t **list, const char *val)
|
||||||
|
{
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
enum_t *item = *list;
|
||||||
|
|
||||||
|
/* if this is not the right value, go on to the next */
|
||||||
|
if (strcasecmp(item->val, val)) {
|
||||||
|
list = &item->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found it! */
|
||||||
|
*list = item->next;
|
||||||
|
|
||||||
|
free(item->val);
|
||||||
|
free(item);
|
||||||
|
|
||||||
|
return 1; /* deleted */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_delenum(st_tree_t *root, const char *var, const char *val)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st_tree_del_enum(&sttmp->enum_list, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int st_tree_del_range(range_t **list, const int min, const int max)
|
||||||
|
{
|
||||||
|
while (*list) {
|
||||||
|
|
||||||
|
range_t *item = *list;
|
||||||
|
|
||||||
|
/* if this is not the right value, go on to the next */
|
||||||
|
if (((*list)->min != min) && ((*list)->max != max)) {
|
||||||
|
list = &item->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we found it! */
|
||||||
|
*list = item->next;
|
||||||
|
|
||||||
|
free(item);
|
||||||
|
|
||||||
|
return 1; /* deleted */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* not found */
|
||||||
|
}
|
||||||
|
|
||||||
|
int state_delrange(st_tree_t *root, const char *var, const int min, const int max)
|
||||||
|
{
|
||||||
|
st_tree_t *sttmp;
|
||||||
|
|
||||||
|
/* find the tree node for var */
|
||||||
|
sttmp = state_tree_find(root, var);
|
||||||
|
|
||||||
|
if (!sttmp) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return st_tree_del_range(&sttmp->range_list, min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
st_tree_t *state_tree_find(st_tree_t *node, const char *var)
|
||||||
|
{
|
||||||
|
while (node) {
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) > 0) {
|
||||||
|
node = node->left;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcasecmp(node->var, var) < 0) {
|
||||||
|
node = node->right;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break; /* found */
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
629
common/str.c
Normal file
629
common/str.c
Normal file
|
@ -0,0 +1,629 @@
|
||||||
|
/* str.c - Common string-related functions
|
||||||
|
*
|
||||||
|
* Copyright (C)
|
||||||
|
* 2000 Russell Kroll <rkroll@exploits.org>
|
||||||
|
* 2015 Daniele Pezzini <hyouko@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 "config.h" /* must be first */
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h> /* for strdup() and many others */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRINGS_H
|
||||||
|
#include <strings.h> /* for strncasecmp() and strcasecmp() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "nut_stdint.h"
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
|
char *str_trim(char *string, const char character)
|
||||||
|
{
|
||||||
|
return str_rtrim(str_ltrim(string, character), character);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_trim_m(char *string, const char *characters)
|
||||||
|
{
|
||||||
|
return str_rtrim_m(str_ltrim_m(string, characters), characters);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_ltrim(char *string, const char character)
|
||||||
|
{
|
||||||
|
char characters[2] = { character, '\0' };
|
||||||
|
|
||||||
|
return str_ltrim_m(string, characters);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_ltrim_m(char *string, const char *characters)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0' ||
|
||||||
|
characters == NULL ||
|
||||||
|
*characters == '\0'
|
||||||
|
)
|
||||||
|
return string;
|
||||||
|
|
||||||
|
while (
|
||||||
|
*string != '\0' &&
|
||||||
|
strchr(characters, *string) != NULL
|
||||||
|
)
|
||||||
|
memmove(string, string + 1, strlen(string));
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_rtrim(char *string, const char character)
|
||||||
|
{
|
||||||
|
char characters[2] = { character, '\0' };
|
||||||
|
|
||||||
|
return str_rtrim_m(string, characters);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_rtrim_m(char *string, const char *characters)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0' ||
|
||||||
|
characters == NULL ||
|
||||||
|
*characters == '\0'
|
||||||
|
)
|
||||||
|
return string;
|
||||||
|
|
||||||
|
ptr = &string[strlen(string) - 1];
|
||||||
|
|
||||||
|
while (
|
||||||
|
ptr >= string &&
|
||||||
|
strchr(characters, *ptr) != NULL
|
||||||
|
)
|
||||||
|
*ptr-- = '\0';
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_trim_space(char *string)
|
||||||
|
{
|
||||||
|
return str_rtrim_space(str_ltrim_space(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_ltrim_space(char *string)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0'
|
||||||
|
)
|
||||||
|
return string;
|
||||||
|
|
||||||
|
while (
|
||||||
|
*string != '\0' &&
|
||||||
|
isspace((size_t)*string)
|
||||||
|
)
|
||||||
|
memmove(string, string + 1, strlen(string));
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *str_rtrim_space(char *string)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0'
|
||||||
|
)
|
||||||
|
return string;
|
||||||
|
|
||||||
|
ptr = &string[strlen(string) - 1];
|
||||||
|
|
||||||
|
while (
|
||||||
|
ptr >= string &&
|
||||||
|
isspace((size_t)*ptr)
|
||||||
|
)
|
||||||
|
*ptr-- = '\0';
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_short(const char *string, const int base)
|
||||||
|
{
|
||||||
|
short number;
|
||||||
|
|
||||||
|
return str_to_short(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_short_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
short number;
|
||||||
|
|
||||||
|
return str_to_short_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_ushort(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned short number;
|
||||||
|
|
||||||
|
return str_to_ushort(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_ushort_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned short number;
|
||||||
|
|
||||||
|
return str_to_ushort_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_int(const char *string, const int base)
|
||||||
|
{
|
||||||
|
int number;
|
||||||
|
|
||||||
|
return str_to_int(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_int_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
int number;
|
||||||
|
|
||||||
|
return str_to_int_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_uint(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned int number;
|
||||||
|
|
||||||
|
return str_to_uint(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_uint_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned int number;
|
||||||
|
|
||||||
|
return str_to_uint_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_long(const char *string, const int base)
|
||||||
|
{
|
||||||
|
long number;
|
||||||
|
|
||||||
|
return str_to_long(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_long_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
long number;
|
||||||
|
|
||||||
|
return str_to_long_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_ulong(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned long number;
|
||||||
|
|
||||||
|
return str_to_ulong(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_ulong_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
unsigned long number;
|
||||||
|
|
||||||
|
return str_to_ulong_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_double(const char *string, const int base)
|
||||||
|
{
|
||||||
|
double number;
|
||||||
|
|
||||||
|
return str_to_double(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_is_double_strict(const char *string, const int base)
|
||||||
|
{
|
||||||
|
double number;
|
||||||
|
|
||||||
|
return str_to_double_strict(string, &number, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_short(const char *string, short *number, const int base)
|
||||||
|
{
|
||||||
|
long num;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_long(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
num < SHRT_MIN ||
|
||||||
|
num > SHRT_MAX
|
||||||
|
) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (short)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_short_strict(const char *string, short *number, const int base)
|
||||||
|
{
|
||||||
|
long num;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_long_strict(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
num < SHRT_MIN ||
|
||||||
|
num > SHRT_MAX
|
||||||
|
) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (short)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_ushort(const char *string, unsigned short *number, const int base)
|
||||||
|
{
|
||||||
|
unsigned long num;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_ulong(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (num > USHRT_MAX) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (unsigned short)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_ushort_strict(const char *string, unsigned short *number, const int base)
|
||||||
|
{
|
||||||
|
unsigned long num;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_ulong_strict(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (num > USHRT_MAX) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (unsigned short)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_int(const char *string, int *number, const int base)
|
||||||
|
{
|
||||||
|
long num; /* long >= int, make sure we fit well */
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_long(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
num < INT_MIN ||
|
||||||
|
num > INT_MAX
|
||||||
|
) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (int)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_int_strict(const char *string, int *number, const int base)
|
||||||
|
{
|
||||||
|
long num; /* long >= int, make sure we fit well */
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_long_strict(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
num < INT_MIN ||
|
||||||
|
num > INT_MAX
|
||||||
|
) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (int)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_uint(const char *string, unsigned int *number, const int base)
|
||||||
|
{
|
||||||
|
unsigned long num; /* long >= int, make sure we fit well */
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_ulong(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (num > UINT_MAX) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (unsigned int)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_uint_strict(const char *string, unsigned int *number, const int base)
|
||||||
|
{
|
||||||
|
unsigned long num; /* long >= int, make sure we fit well */
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (!str_to_ulong_strict(string, &num, base))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (num > UINT_MAX) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*number = (unsigned int)num;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_long(const char *string, long *number, const int base)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0'
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = strdup(string);
|
||||||
|
if (str == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
str_trim_space(str);
|
||||||
|
|
||||||
|
if (!str_to_long_strict(str, number, base)) {
|
||||||
|
free(str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_long_strict(const char *string, long *number, const int base)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0' ||
|
||||||
|
isspace((size_t)*string)
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
*number = strtol(string, &ptr, base);
|
||||||
|
|
||||||
|
if (
|
||||||
|
errno == EINVAL ||
|
||||||
|
*ptr != '\0'
|
||||||
|
) {
|
||||||
|
*number = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
*number = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_ulong(const char *string, unsigned long *number, const int base)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0'
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = strdup(string);
|
||||||
|
if (str == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
str_trim_space(str);
|
||||||
|
|
||||||
|
if (!str_to_ulong_strict(str, number, base)) {
|
||||||
|
free(str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_ulong_strict(const char *string, unsigned long *number, const int base)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0' ||
|
||||||
|
*string == '+' ||
|
||||||
|
*string == '-' ||
|
||||||
|
isspace((size_t)*string)
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
*number = strtoul(string, &ptr, base);
|
||||||
|
|
||||||
|
if (
|
||||||
|
errno == EINVAL ||
|
||||||
|
*ptr != '\0'
|
||||||
|
) {
|
||||||
|
*number = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
*number = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_double(const char *string, double *number, const int base)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0'
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = strdup(string);
|
||||||
|
if (str == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
str_trim_space(str);
|
||||||
|
|
||||||
|
if (!str_to_double_strict(str, number, base)) {
|
||||||
|
free(str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_to_double_strict(const char *string, double *number, const int base)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
|
||||||
|
*number = 0;
|
||||||
|
|
||||||
|
if (
|
||||||
|
string == NULL ||
|
||||||
|
*string == '\0' ||
|
||||||
|
isspace((size_t)*string)
|
||||||
|
) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (base)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
if (strlen(string) != strspn(string, "-+.0123456789Ee")) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
if (strlen(string) != strspn(string, "-+.0123456789ABCDEFabcdefXxPp")) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
*number = strtod(string, &ptr);
|
||||||
|
|
||||||
|
if (
|
||||||
|
errno == EINVAL ||
|
||||||
|
*ptr != '\0'
|
||||||
|
) {
|
||||||
|
*number = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno == ERANGE) {
|
||||||
|
*number = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int str_ends_with(const char *s, const char *suff) {
|
||||||
|
size_t slen;
|
||||||
|
size_t sufflen;
|
||||||
|
|
||||||
|
if (!s) return 0; /* null string does not end with anything */
|
||||||
|
if (!suff) return 1; /* null suffix tails anything */
|
||||||
|
|
||||||
|
slen = strlen(s);
|
||||||
|
sufflen = strlen(suff);
|
||||||
|
|
||||||
|
return (slen >= sufflen) && (!memcmp(s + slen - sufflen, suff, sufflen));
|
||||||
|
}
|
518
common/strerror.c
Normal file
518
common/strerror.c
Normal file
|
@ -0,0 +1,518 @@
|
||||||
|
/* strerror() Mark Powell <medp@primagraphics.co.uk> */
|
||||||
|
/* Simple implementation derived from libiberty */
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_STRERROR
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
char *strerror(int errnum)
|
||||||
|
{
|
||||||
|
static char buf[32];
|
||||||
|
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_BREAK
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code-break"
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
|
||||||
|
#pragma GCC diagnostic ignored "-Wunreachable-code"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (errnum) {
|
||||||
|
#if defined (EPERM)
|
||||||
|
case EPERM:
|
||||||
|
return "Not owner";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOENT)
|
||||||
|
case ENOENT:
|
||||||
|
return "No such file or directory";
|
||||||
|
#endif
|
||||||
|
#if defined (ESRCH)
|
||||||
|
case ESRCH:
|
||||||
|
return "No such process";
|
||||||
|
#endif
|
||||||
|
#if defined (EINTR)
|
||||||
|
case EINTR:
|
||||||
|
return "Interrupted system call";
|
||||||
|
#endif
|
||||||
|
#if defined (EIO)
|
||||||
|
case EIO:
|
||||||
|
return "I/O error";
|
||||||
|
#endif
|
||||||
|
#if defined (ENXIO)
|
||||||
|
case ENXIO:
|
||||||
|
return "No such device or address";
|
||||||
|
#endif
|
||||||
|
#if defined (E2BIG)
|
||||||
|
return "Arg list too long";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOEXEC)
|
||||||
|
case ENOEXEC:
|
||||||
|
return "Exec format error";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADF)
|
||||||
|
case EBADF:
|
||||||
|
return "Bad file number";
|
||||||
|
#endif
|
||||||
|
#if defined (ECHILD)
|
||||||
|
case ECHILD:
|
||||||
|
return "No child processes";
|
||||||
|
#endif
|
||||||
|
#if defined (EWOULDBLOCK) /* Put before EAGAIN, sometimes aliased */
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
return "Operation would block";
|
||||||
|
#endif
|
||||||
|
#if defined (EAGAIN)
|
||||||
|
#if defined (EWOULDBLOCK) && EAGAIN != EWOULDBLOCK
|
||||||
|
case EAGAIN:
|
||||||
|
return "No more processes";
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined (ENOMEM)
|
||||||
|
case ENOMEM:
|
||||||
|
return "Not enough space";
|
||||||
|
#endif
|
||||||
|
#if defined (EACCES)
|
||||||
|
case EACCES:
|
||||||
|
return "Permission denied";
|
||||||
|
#endif
|
||||||
|
#if defined (EFAULT)
|
||||||
|
case EFAULT:
|
||||||
|
return "Bad address";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTBLK)
|
||||||
|
case ENOTBLK:
|
||||||
|
return "Block device required";
|
||||||
|
#endif
|
||||||
|
#if defined (EBUSY)
|
||||||
|
case EBUSY:
|
||||||
|
return "Device busy";
|
||||||
|
#endif
|
||||||
|
#if defined (EEXIST)
|
||||||
|
case EEXIST:
|
||||||
|
return "File exists";
|
||||||
|
#endif
|
||||||
|
#if defined (EXDEV)
|
||||||
|
case EXDEV:
|
||||||
|
return "Cross-device link";
|
||||||
|
#endif
|
||||||
|
#if defined (ENODEV)
|
||||||
|
case ENODEV:
|
||||||
|
return "No such device";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTDIR)
|
||||||
|
case ENOTDIR:
|
||||||
|
return "Not a directory";
|
||||||
|
#endif
|
||||||
|
#if defined (EISDIR)
|
||||||
|
case EISDIR:
|
||||||
|
return "Is a directory";
|
||||||
|
#endif
|
||||||
|
#if defined (EINVAL)
|
||||||
|
case EINVAL:
|
||||||
|
return "Invalid argument";
|
||||||
|
#endif
|
||||||
|
#if defined (ENFILE)
|
||||||
|
case ENFILE:
|
||||||
|
return "File table overflow";
|
||||||
|
#endif
|
||||||
|
#if defined (EMFILE)
|
||||||
|
case EMFILE:
|
||||||
|
return "Too many open files";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTTY)
|
||||||
|
case ENOTTY:
|
||||||
|
return "Not a typewriter";
|
||||||
|
#endif
|
||||||
|
#if defined (ETXTBSY)
|
||||||
|
case ETXTBSY:
|
||||||
|
return "Text file busy";
|
||||||
|
#endif
|
||||||
|
#if defined (EFBIG)
|
||||||
|
case EFBIG:
|
||||||
|
return "File too large";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOSPC)
|
||||||
|
case ENOSPC:
|
||||||
|
return "No space left on device";
|
||||||
|
#endif
|
||||||
|
#if defined (ESPIPE)
|
||||||
|
case ESPIPE:
|
||||||
|
return "Illegal seek";
|
||||||
|
#endif
|
||||||
|
#if defined (EROFS)
|
||||||
|
case EROFS:
|
||||||
|
return "Read-only file system";
|
||||||
|
#endif
|
||||||
|
#if defined (EMLINK)
|
||||||
|
case EMLINK:
|
||||||
|
return "Too many links";
|
||||||
|
#endif
|
||||||
|
#if defined (EPIPE)
|
||||||
|
case EPIPE:
|
||||||
|
return "Broken pipe";
|
||||||
|
#endif
|
||||||
|
#if defined (EDOM)
|
||||||
|
case EDOM:
|
||||||
|
return "Math argument out of domain of func";
|
||||||
|
#endif
|
||||||
|
#if defined (ERANGE)
|
||||||
|
case ERANGE:
|
||||||
|
return "Math result not representable";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOMSG)
|
||||||
|
case ENOMSG:
|
||||||
|
return "No message of desired type";
|
||||||
|
#endif
|
||||||
|
#if defined (EIDRM)
|
||||||
|
case EIDRM:
|
||||||
|
return "Identifier removed";
|
||||||
|
#endif
|
||||||
|
#if defined (ECHRNG)
|
||||||
|
case ECHRNG:
|
||||||
|
return "Channel number out of range";
|
||||||
|
#endif
|
||||||
|
#if defined (EL2NSYNC)
|
||||||
|
return "Level 2 not synchronized";
|
||||||
|
#endif
|
||||||
|
#if defined (EL3HLT)
|
||||||
|
return "Level 3 halted";
|
||||||
|
#endif
|
||||||
|
#if defined (EL3RST)
|
||||||
|
return "Level 3 reset";
|
||||||
|
#endif
|
||||||
|
#if defined (ELNRNG)
|
||||||
|
case ELNRNG:
|
||||||
|
return "Link number out of range";
|
||||||
|
#endif
|
||||||
|
#if defined (EUNATCH)
|
||||||
|
case EUNATCH:
|
||||||
|
return "Protocol driver not attached";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOCSI)
|
||||||
|
case ENOCSI:
|
||||||
|
return "No CSI structure available";
|
||||||
|
#endif
|
||||||
|
#if defined (EL2HLT)
|
||||||
|
return "Level 2 halted";
|
||||||
|
#endif
|
||||||
|
#if defined (EDEADLK)
|
||||||
|
case EDEADLK:
|
||||||
|
return "Deadlock condition";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOLCK)
|
||||||
|
case ENOLCK:
|
||||||
|
return "No record locks available";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADE)
|
||||||
|
case EBADE:
|
||||||
|
return "Invalid exchange";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADR)
|
||||||
|
case EBADR:
|
||||||
|
return "Invalid request descriptor";
|
||||||
|
#endif
|
||||||
|
#if defined (EXFULL)
|
||||||
|
case EXFULL:
|
||||||
|
return "Exchange full";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOANO)
|
||||||
|
case ENOANO:
|
||||||
|
return "No anode";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADRQC)
|
||||||
|
case EBADRQC:
|
||||||
|
return "Invalid request code";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADSLT)
|
||||||
|
case EBADSLT:
|
||||||
|
return "Invalid slot";
|
||||||
|
#endif
|
||||||
|
#if defined (EDEADLOCK)
|
||||||
|
case EDEADLOCK:
|
||||||
|
return "File locking deadlock error";
|
||||||
|
#endif
|
||||||
|
#if defined (EBFONT)
|
||||||
|
case EBFONT:
|
||||||
|
return "Bad font file format";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOSTR)
|
||||||
|
case ENOSTR:
|
||||||
|
return "Device not a stream";
|
||||||
|
#endif
|
||||||
|
#if defined (ENODATA)
|
||||||
|
case ENODATA:
|
||||||
|
return "No data available";
|
||||||
|
#endif
|
||||||
|
#if defined (ETIME)
|
||||||
|
case ETIME:
|
||||||
|
return "Timer expired";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOSR)
|
||||||
|
case ENOSR:
|
||||||
|
return "Out of streams resources";
|
||||||
|
#endif
|
||||||
|
#if defined (ENONET)
|
||||||
|
case ENONET:
|
||||||
|
return "Machine is not on the network";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOPKG)
|
||||||
|
case ENOPKG:
|
||||||
|
return "Package not installed";
|
||||||
|
#endif
|
||||||
|
#if defined (EREMOTE)
|
||||||
|
case EREMOTE:
|
||||||
|
return "Object is remote";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOLINK)
|
||||||
|
case ENOLINK:
|
||||||
|
return "Link has been severed";
|
||||||
|
#endif
|
||||||
|
#if defined (EADV)
|
||||||
|
case EADV:
|
||||||
|
return "Advertise error";
|
||||||
|
#endif
|
||||||
|
#if defined (ESRMNT)
|
||||||
|
case ESRMNT:
|
||||||
|
return "Srmount error";
|
||||||
|
#endif
|
||||||
|
#if defined (ECOMM)
|
||||||
|
case ECOMM:
|
||||||
|
return "Communication error on send";
|
||||||
|
#endif
|
||||||
|
#if defined (EPROTO)
|
||||||
|
case EPROTO:
|
||||||
|
return "Protocol error";
|
||||||
|
#endif
|
||||||
|
#if defined (EMULTIHOP)
|
||||||
|
case EMULTIHOP:
|
||||||
|
return "Multihop attempted";
|
||||||
|
#endif
|
||||||
|
#if defined (EDOTDOT)
|
||||||
|
case EDOTDOT:
|
||||||
|
return "RFS specific error";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADMSG)
|
||||||
|
case EBADMSG:
|
||||||
|
return "Not a data message";
|
||||||
|
#endif
|
||||||
|
#if defined (ENAMETOOLONG)
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
return "File name too long";
|
||||||
|
#endif
|
||||||
|
#if defined (EOVERFLOW)
|
||||||
|
case EOVERFLOW:
|
||||||
|
return "Value too large for defined data type";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTUNIQ)
|
||||||
|
case ENOTUNIQ:
|
||||||
|
return "Name not unique on network";
|
||||||
|
#endif
|
||||||
|
#if defined (EBADFD)
|
||||||
|
case EBADFD:
|
||||||
|
return "File descriptor in bad state";
|
||||||
|
#endif
|
||||||
|
#if defined (EREMCHG)
|
||||||
|
case EREMCHG:
|
||||||
|
return "Remote address changed";
|
||||||
|
#endif
|
||||||
|
#if defined (ELIBACC)
|
||||||
|
case ELIBACC:
|
||||||
|
return "Can not access a needed shared library";
|
||||||
|
#endif
|
||||||
|
#if defined (ELIBBAD)
|
||||||
|
case ELIBBAD:
|
||||||
|
return "Accessing a corrupted shared library";
|
||||||
|
#endif
|
||||||
|
#if defined (ELIBSCN)
|
||||||
|
case ELIBSCN:
|
||||||
|
return ".lib section in a.out corrupted";
|
||||||
|
#endif
|
||||||
|
#if defined (ELIBMAX)
|
||||||
|
case ELIBMAX:
|
||||||
|
return "Attempting to link in too many shared libraries";
|
||||||
|
#endif
|
||||||
|
#if defined (ELIBEXEC)
|
||||||
|
case ELIBEXEC:
|
||||||
|
return "Cannot exec a shared library directly";
|
||||||
|
#endif
|
||||||
|
#if defined (EILSEQ)
|
||||||
|
case EILSEQ:
|
||||||
|
return "Illegal byte sequence";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOSYS)
|
||||||
|
case ENOSYS:
|
||||||
|
return "Operation not applicable";
|
||||||
|
#endif
|
||||||
|
#if defined (ELOOP)
|
||||||
|
case ELOOP:
|
||||||
|
return "Too many symbolic links encountered";
|
||||||
|
#endif
|
||||||
|
#if defined (ERESTART)
|
||||||
|
case ERESTART:
|
||||||
|
return "Interrupted system call should be restarted";
|
||||||
|
#endif
|
||||||
|
#if defined (ESTRPIPE)
|
||||||
|
case ESTRPIPE:
|
||||||
|
return "Streams pipe error";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTEMPTY)
|
||||||
|
case ENOTEMPTY:
|
||||||
|
return "Directory not empty";
|
||||||
|
#endif
|
||||||
|
#if defined (EUSERS)
|
||||||
|
case EUSERS:
|
||||||
|
return "Too many users";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTSOCK)
|
||||||
|
case ENOTSOCK:
|
||||||
|
return "Socket operation on non-socket";
|
||||||
|
#endif
|
||||||
|
#if defined (EDESTADDRREQ)
|
||||||
|
case EDESTADDRREQ:
|
||||||
|
return "Destination address required";
|
||||||
|
#endif
|
||||||
|
#if defined (EMSGSIZE)
|
||||||
|
case EMSGSIZE:
|
||||||
|
return "Message too long";
|
||||||
|
#endif
|
||||||
|
#if defined (EPROTOTYPE)
|
||||||
|
case EPROTOTYPE:
|
||||||
|
return "Protocol wrong type for socket";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOPROTOOPT)
|
||||||
|
case ENOPROTOOPT:
|
||||||
|
return "Protocol not available";
|
||||||
|
#endif
|
||||||
|
#if defined (EPROTONOSUPPORT)
|
||||||
|
case EPROTONOSUPPORT:
|
||||||
|
return "Protocol not supported";
|
||||||
|
#endif
|
||||||
|
#if defined (ESOCKTNOSUPPORT)
|
||||||
|
case ESOCKTNOSUPPORT:
|
||||||
|
return "Socket type not supported";
|
||||||
|
#endif
|
||||||
|
#if defined (EOPNOTSUPP)
|
||||||
|
case EOPNOTSUPP:
|
||||||
|
return "Operation not supported on transport endpoint";
|
||||||
|
#endif
|
||||||
|
#if defined (EPFNOSUPPORT)
|
||||||
|
case EPFNOSUPPORT:
|
||||||
|
return "Protocol family not supported";
|
||||||
|
#endif
|
||||||
|
#if defined (EAFNOSUPPORT)
|
||||||
|
case EAFNOSUPPORT:
|
||||||
|
return "Address family not supported by protocol";
|
||||||
|
#endif
|
||||||
|
#if defined (EADDRINUSE)
|
||||||
|
case EADDRINUSE:
|
||||||
|
return "Address already in use";
|
||||||
|
#endif
|
||||||
|
#if defined (EADDRNOTAVAIL)
|
||||||
|
case EADDRNOTAVAIL:
|
||||||
|
return "Cannot assign requested address";
|
||||||
|
#endif
|
||||||
|
#if defined (ENETDOWN)
|
||||||
|
case ENETDOWN:
|
||||||
|
return "Network is down";
|
||||||
|
#endif
|
||||||
|
#if defined (ENETUNREACH)
|
||||||
|
case ENETUNREACH:
|
||||||
|
return "Network is unreachable";
|
||||||
|
#endif
|
||||||
|
#if defined (ENETRESET)
|
||||||
|
case ENETRESET:
|
||||||
|
return "Network dropped connection because of reset";
|
||||||
|
#endif
|
||||||
|
#if defined (ECONNABORTED)
|
||||||
|
case ECONNABORTED:
|
||||||
|
return "Software caused connection abort";
|
||||||
|
#endif
|
||||||
|
#if defined (ECONNRESET)
|
||||||
|
case ECONNRESET:
|
||||||
|
return "Connection reset by peer";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOBUFS)
|
||||||
|
case ENOBUFS:
|
||||||
|
return "No buffer space available";
|
||||||
|
#endif
|
||||||
|
#if defined (EISCONN)
|
||||||
|
case EISCONN:
|
||||||
|
return "Transport endpoint is already connected";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTCONN)
|
||||||
|
case ENOTCONN:
|
||||||
|
return "Transport endpoint is not connected";
|
||||||
|
#endif
|
||||||
|
#if defined (ESHUTDOWN)
|
||||||
|
case ESHUTDOWN:
|
||||||
|
return "Cannot send after transport endpoint shutdown";
|
||||||
|
#endif
|
||||||
|
#if defined (ETOOMANYREFS)
|
||||||
|
case ETOOMANYREFS:
|
||||||
|
return "Too many references: cannot splice";
|
||||||
|
#endif
|
||||||
|
#if defined (ETIMEDOUT)
|
||||||
|
case ETIMEDOUT:
|
||||||
|
return "Connection timed out";
|
||||||
|
#endif
|
||||||
|
#if defined (ECONNREFUSED)
|
||||||
|
case ECONNREFUSED:
|
||||||
|
return "Connection refused";
|
||||||
|
#endif
|
||||||
|
#if defined (EHOSTDOWN)
|
||||||
|
case EHOSTDOWN:
|
||||||
|
return "Host is down";
|
||||||
|
#endif
|
||||||
|
#if defined (EHOSTUNREACH)
|
||||||
|
case EHOSTUNREACH:
|
||||||
|
return "No route to host";
|
||||||
|
#endif
|
||||||
|
#if defined (EALREADY)
|
||||||
|
case EALREADY:
|
||||||
|
return "Operation already in progress";
|
||||||
|
#endif
|
||||||
|
#if defined (EINPROGRESS)
|
||||||
|
case EINPROGRESS:
|
||||||
|
return "Operation now in progress";
|
||||||
|
#endif
|
||||||
|
#if defined (ESTALE)
|
||||||
|
case ESTALE:
|
||||||
|
return "Stale NFS file handle";
|
||||||
|
#endif
|
||||||
|
#if defined (EUCLEAN)
|
||||||
|
case EUCLEAN:
|
||||||
|
return "Structure needs cleaning";
|
||||||
|
#endif
|
||||||
|
#if defined (ENOTNAM)
|
||||||
|
case ENOTNAM:
|
||||||
|
return "Not a XENIX named type file";
|
||||||
|
#endif
|
||||||
|
#if defined (ENAVAIL)
|
||||||
|
case ENAVAIL:
|
||||||
|
return "No XENIX semaphores available";
|
||||||
|
#endif
|
||||||
|
#if defined (EISNAM)
|
||||||
|
case EISNAM:
|
||||||
|
return "Is a named type file";
|
||||||
|
#endif
|
||||||
|
#if defined (EREMOTEIO)
|
||||||
|
case EREMOTEIO:
|
||||||
|
return "Remote I/O error";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fallback: just print the error number */
|
||||||
|
snprintf(buf, sizeof(buf), "Error %d", errnum);
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_STRERROR */
|
98
common/upsconf.c
Normal file
98
common/upsconf.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/* upsconf.c - code for handling ups.conf ini-style parsing
|
||||||
|
|
||||||
|
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h" /* must be the first header */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "upsconf.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "parseconf.h"
|
||||||
|
|
||||||
|
static char *ups_section;
|
||||||
|
|
||||||
|
/* handle arguments separated by parseconf */
|
||||||
|
static void conf_args(size_t numargs, char **arg)
|
||||||
|
{
|
||||||
|
if (numargs < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* look for section headers - [upsname] */
|
||||||
|
if ((arg[0][0] == '[') && (arg[0][strlen(arg[0])-1] == ']')) {
|
||||||
|
|
||||||
|
free(ups_section);
|
||||||
|
|
||||||
|
arg[0][strlen(arg[0])-1] = '\0';
|
||||||
|
ups_section = xstrdup(&arg[0][1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle 'foo' (flag) */
|
||||||
|
if (numargs == 1) {
|
||||||
|
do_upsconf_args(ups_section, arg[0], NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numargs < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* handle 'foo = bar', 'foo=bar', 'foo =bar' or 'foo= bar' forms */
|
||||||
|
if (!strcmp(arg[1], "=")) {
|
||||||
|
do_upsconf_args(ups_section, arg[0], arg[2]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called for fatal errors in parseconf like malloc failures */
|
||||||
|
static void upsconf_err(const char *errmsg)
|
||||||
|
{
|
||||||
|
upslogx(LOG_ERR, "Fatal error in parseconf(ups.conf): %s", errmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open the ups.conf, parse it, and call back do_upsconf_args() */
|
||||||
|
void read_upsconf(void)
|
||||||
|
{
|
||||||
|
char fn[SMALLBUF];
|
||||||
|
PCONF_CTX_t ctx;
|
||||||
|
|
||||||
|
ups_section = NULL;
|
||||||
|
snprintf(fn, sizeof(fn), "%s/ups.conf", confpath());
|
||||||
|
|
||||||
|
pconf_init(&ctx, upsconf_err);
|
||||||
|
|
||||||
|
if (!pconf_file_begin(&ctx, fn))
|
||||||
|
fatalx(EXIT_FAILURE, "Can't open %s: %s", fn, ctx.errmsg);
|
||||||
|
|
||||||
|
while (pconf_file_next(&ctx)) {
|
||||||
|
if (pconf_parse_error(&ctx)) {
|
||||||
|
upslogx(LOG_ERR, "Parse error: %s:%d: %s",
|
||||||
|
fn, ctx.linenum, ctx.errmsg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf_args(ctx.numargs, ctx.arglist);
|
||||||
|
}
|
||||||
|
|
||||||
|
pconf_finish(&ctx);
|
||||||
|
|
||||||
|
free(ups_section);
|
||||||
|
}
|
143
compile
Executable file
143
compile
Executable file
|
@ -0,0 +1,143 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
|
||||||
|
scriptversion=2009-10-06.20; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
|
||||||
|
# Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# 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, 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
# This file is maintained in Automake, please report
|
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to
|
||||||
|
# <automake-patches@gnu.org>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||||
|
arguments, and rename the output as expected.
|
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the
|
||||||
|
right script to run: please start by reading the file `INSTALL'.
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "compile $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
eat=
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||||
|
# So we strip `-o arg' only if arg is an object.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.obj)
|
||||||
|
ofile=$2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" -o "$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile=$1
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then
|
||||||
|
# If no `-o' option was seen then we might have been invoked from a
|
||||||
|
# pattern rule where we don't need one. That is ok -- this is a
|
||||||
|
# normal compilation that the losing compiler can handle. If no
|
||||||
|
# `.c' file was seen then we are probably linking. That is also
|
||||||
|
# ok.
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
# Note: use `[/\\:.-]' here to ensure that we don't use the same name
|
||||||
|
# that we are using for the .o file. Also, base the name on the expected
|
||||||
|
# object file name, since that is what matters with a parallel build.
|
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||||
|
while true; do
|
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$@"
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||||
|
elif test -f "${cofile}bj"; then
|
||||||
|
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir "$lockdir"
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
41
conf/Makefile.am
Normal file
41
conf/Makefile.am
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Network UPS Tools: conf
|
||||||
|
|
||||||
|
INSTALL_0600 = $(INSTALL) -m 0600
|
||||||
|
|
||||||
|
SECFILES = upsd.conf.sample upsd.users.sample
|
||||||
|
PUBFILES = nut.conf.sample ups.conf.sample
|
||||||
|
CGIPUB = hosts.conf.sample upsset.conf.sample upsstats.html.sample \
|
||||||
|
upsstats-single.html.sample
|
||||||
|
|
||||||
|
if WITH_CGI
|
||||||
|
CGI_INSTALL = $(CGIPUB)
|
||||||
|
else
|
||||||
|
CGI_INSTALL =
|
||||||
|
endif
|
||||||
|
|
||||||
|
dist_sysconf_DATA = $(SECFILES) $(PUBFILES) $(CGI_INSTALL)
|
||||||
|
nodist_sysconf_DATA = upssched.conf.sample upsmon.conf.sample
|
||||||
|
|
||||||
|
SPELLCHECK_SRC = $(dist_sysconf_DATA) \
|
||||||
|
upssched.conf.sample.in upsmon.conf.sample.in
|
||||||
|
|
||||||
|
# NOTE: Due to portability, we do not use a GNU percent-wildcard extension:
|
||||||
|
#%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
# $(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
# NOTE: Portable suffix rules do not allow prerequisites, so we shim them here
|
||||||
|
# by a wildcard target in case the make implementation can put the two together.
|
||||||
|
*-spellchecked: Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
|
||||||
|
.sample.sample-spellchecked:
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
.in.in-spellchecked:
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
spellcheck spellcheck-interactive spellcheck-sortdict:
|
||||||
|
$(MAKE) -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC="$(SPELLCHECK_SRC)" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
CLEANFILES = *.pdf *.html *-spellchecked
|
688
conf/Makefile.in
Normal file
688
conf/Makefile.in
Normal file
|
@ -0,0 +1,688 @@
|
||||||
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994-2020 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@
|
||||||
|
|
||||||
|
# Network UPS Tools: conf
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
am__make_running_with_option = \
|
||||||
|
case $${target_option-} in \
|
||||||
|
?) ;; \
|
||||||
|
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||||
|
"target option '$${target_option-}' specified" >&2; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
has_opt=no; \
|
||||||
|
sane_makeflags=$$MAKEFLAGS; \
|
||||||
|
if $(am__is_gnu_make); then \
|
||||||
|
sane_makeflags=$$MFLAGS; \
|
||||||
|
else \
|
||||||
|
case $$MAKEFLAGS in \
|
||||||
|
*\\[\ \ ]*) \
|
||||||
|
bs=\\; \
|
||||||
|
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||||
|
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||||
|
esac; \
|
||||||
|
fi; \
|
||||||
|
skip_next=no; \
|
||||||
|
strip_trailopt () \
|
||||||
|
{ \
|
||||||
|
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||||
|
}; \
|
||||||
|
for flg in $$sane_makeflags; do \
|
||||||
|
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||||
|
case $$flg in \
|
||||||
|
*=*|--*) continue;; \
|
||||||
|
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||||
|
-*I?*) strip_trailopt 'I';; \
|
||||||
|
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||||
|
-*O?*) strip_trailopt 'O';; \
|
||||||
|
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||||
|
-*l?*) strip_trailopt 'l';; \
|
||||||
|
-[dEDm]) skip_next=yes;; \
|
||||||
|
-[JT]) skip_next=yes;; \
|
||||||
|
esac; \
|
||||||
|
case $$flg in \
|
||||||
|
*$$target_option*) has_opt=yes; break;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
test $$has_opt = yes
|
||||||
|
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||||
|
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||||
|
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 = conf
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_c_pragmas.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_compare_version.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_run_or_link_ifelse.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_cppcheck.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_headers_windows.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_libltdl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libpowerman.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_check_pkgconfig.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_python.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_compiler_family.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_stash_warnings.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_sysconf_DATA_DIST) \
|
||||||
|
$(am__DIST_COMMON)
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||||
|
CONFIG_CLEAN_FILES = upsmon.conf.sample upssched.conf.sample
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
AM_V_P = $(am__v_P_@AM_V@)
|
||||||
|
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||||
|
am__v_P_0 = false
|
||||||
|
am__v_P_1 = :
|
||||||
|
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||||
|
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_GEN_1 =
|
||||||
|
AM_V_at = $(am__v_at_@AM_V@)
|
||||||
|
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||||
|
am__v_at_0 = @
|
||||||
|
am__v_at_1 =
|
||||||
|
SOURCES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
am__can_run_installinfo = \
|
||||||
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
|
n|no|NO) false;; \
|
||||||
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
|
esac
|
||||||
|
am__dist_sysconf_DATA_DIST = upsd.conf.sample upsd.users.sample \
|
||||||
|
nut.conf.sample ups.conf.sample hosts.conf.sample \
|
||||||
|
upsset.conf.sample upsstats.html.sample \
|
||||||
|
upsstats-single.html.sample
|
||||||
|
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__uninstall_files_from_dir = { \
|
||||||
|
test -z "$$files" \
|
||||||
|
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||||
|
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||||
|
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||||
|
}
|
||||||
|
am__installdirs = "$(DESTDIR)$(sysconfdir)" "$(DESTDIR)$(sysconfdir)"
|
||||||
|
DATA = $(dist_sysconf_DATA) $(nodist_sysconf_DATA)
|
||||||
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in \
|
||||||
|
$(srcdir)/upsmon.conf.sample.in \
|
||||||
|
$(srcdir)/upssched.conf.sample.in
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
A2X = @A2X@
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
AR = @AR@
|
||||||
|
ASCIIDOC = @ASCIIDOC@
|
||||||
|
ASPELL = @ASPELL@
|
||||||
|
AUGPARSE = @AUGPARSE@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
BINDIR = @BINDIR@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CONFPATH = @CONFPATH@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPCHECK = @CPPCHECK@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
|
||||||
|
CPPUNIT_LIBS = @CPPUNIT_LIBS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DBLATEX = @DBLATEX@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
||||||
|
DOC_CHECK_LIST = @DOC_CHECK_LIST@
|
||||||
|
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||||
|
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||||
|
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||||
|
DRVPATH = @DRVPATH@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
GDLIB_CONFIG = @GDLIB_CONFIG@
|
||||||
|
GREP = @GREP@
|
||||||
|
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@
|
||||||
|
LIBDIR = @LIBDIR@
|
||||||
|
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||||
|
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||||
|
LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
|
||||||
|
LIBIPMI_LIBS = @LIBIPMI_LIBS@
|
||||||
|
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
|
||||||
|
LIBLTDL_LIBS = @LIBLTDL_LIBS@
|
||||||
|
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
|
||||||
|
LIBMODBUS_LIBS = @LIBMODBUS_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@
|
||||||
|
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||||
|
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||||
|
LIBUSB_CONFIG = @LIBUSB_CONFIG@
|
||||||
|
LIBUSB_LIBS = @LIBUSB_LIBS@
|
||||||
|
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||||
|
LIBWRAP_LIBS = @LIBWRAP_LIBS@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LN_S_R = @LN_S_R@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NETLIBS = @NETLIBS@
|
||||||
|
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
NUT_DATADIR = @NUT_DATADIR@
|
||||||
|
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
|
||||||
|
NUT_NETVERSION = @NUT_NETVERSION@
|
||||||
|
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@
|
||||||
|
PIDPATH = @PIDPATH@
|
||||||
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
PORT = @PORT@
|
||||||
|
PYTHON = @PYTHON@
|
||||||
|
PYTHON2 = @PYTHON2@
|
||||||
|
PYTHON3 = @PYTHON3@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||||
|
RUN_AS_USER = @RUN_AS_USER@
|
||||||
|
SBINDIR = @SBINDIR@
|
||||||
|
SED = @SED@
|
||||||
|
SERLIBS = @SERLIBS@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SOURCE_HIGHLIGHT = @SOURCE_HIGHLIGHT@
|
||||||
|
STATEPATH = @STATEPATH@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
SUN_LIBUSB = @SUN_LIBUSB@
|
||||||
|
TREE_VERSION = @TREE_VERSION@
|
||||||
|
VALGRIND = @VALGRIND@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||||
|
XMLLINT = @XMLLINT@
|
||||||
|
XSLTPROC = @XSLTPROC@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_AR = @ac_ct_AR@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
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@
|
||||||
|
auglensdir = @auglensdir@
|
||||||
|
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@
|
||||||
|
devddir = @devddir@
|
||||||
|
docdir = @docdir@
|
||||||
|
driverexecdir = @driverexecdir@
|
||||||
|
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
|
||||||
|
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
|
||||||
|
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
|
||||||
|
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@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
now = @now@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
runstatedir = @runstatedir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
systemdshutdowndir = @systemdshutdowndir@
|
||||||
|
systemdsystemunitdir = @systemdsystemunitdir@
|
||||||
|
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||||
|
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@
|
||||||
|
INSTALL_0600 = $(INSTALL) -m 0600
|
||||||
|
SECFILES = upsd.conf.sample upsd.users.sample
|
||||||
|
PUBFILES = nut.conf.sample ups.conf.sample
|
||||||
|
CGIPUB = hosts.conf.sample upsset.conf.sample upsstats.html.sample \
|
||||||
|
upsstats-single.html.sample
|
||||||
|
|
||||||
|
@WITH_CGI_FALSE@CGI_INSTALL =
|
||||||
|
@WITH_CGI_TRUE@CGI_INSTALL = $(CGIPUB)
|
||||||
|
dist_sysconf_DATA = $(SECFILES) $(PUBFILES) $(CGI_INSTALL)
|
||||||
|
nodist_sysconf_DATA = upssched.conf.sample upsmon.conf.sample
|
||||||
|
SPELLCHECK_SRC = $(dist_sysconf_DATA) \
|
||||||
|
upssched.conf.sample.in upsmon.conf.sample.in
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
CLEANFILES = *.pdf *.html *-spellchecked
|
||||||
|
all: all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .in .in-spellchecked .sample .sample-spellchecked
|
||||||
|
$(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 conf/Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnu conf/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__maybe_remake_depfiles)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
|
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):
|
||||||
|
upsmon.conf.sample: $(top_builddir)/config.status $(srcdir)/upsmon.conf.sample.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
upssched.conf.sample: $(top_builddir)/config.status $(srcdir)/upssched.conf.sample.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
install-dist_sysconfDATA: $(dist_sysconf_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(sysconfdir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-dist_sysconfDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
|
||||||
|
install-nodist_sysconfDATA: $(nodist_sysconf_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(nodist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(sysconfdir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-nodist_sysconfDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(nodist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
|
||||||
|
tags TAGS:
|
||||||
|
|
||||||
|
ctags CTAGS:
|
||||||
|
|
||||||
|
cscope cscopelist:
|
||||||
|
|
||||||
|
|
||||||
|
distdir: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
distdir-am: $(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 $(DATA)
|
||||||
|
installdirs:
|
||||||
|
for dir in "$(DESTDIR)$(sysconfdir)" "$(DESTDIR)$(sysconfdir)"; 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:
|
||||||
|
if test -z '$(STRIP)'; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
install; \
|
||||||
|
else \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||||
|
fi
|
||||||
|
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 "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||||
|
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-dist_sysconfDATA install-nodist_sysconfDATA
|
||||||
|
|
||||||
|
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-dist_sysconfDATA uninstall-nodist_sysconfDATA
|
||||||
|
|
||||||
|
.MAKE: install-am install-strip
|
||||||
|
|
||||||
|
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||||
|
cscopelist-am ctags-am distclean distclean-generic \
|
||||||
|
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
||||||
|
install install-am install-data install-data-am \
|
||||||
|
install-dist_sysconfDATA install-dvi install-dvi-am \
|
||||||
|
install-exec install-exec-am install-html install-html-am \
|
||||||
|
install-info install-info-am install-man \
|
||||||
|
install-nodist_sysconfDATA 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 tags-am uninstall \
|
||||||
|
uninstall-am uninstall-dist_sysconfDATA \
|
||||||
|
uninstall-nodist_sysconfDATA
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: Due to portability, we do not use a GNU percent-wildcard extension:
|
||||||
|
#%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
# $(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
# NOTE: Portable suffix rules do not allow prerequisites, so we shim them here
|
||||||
|
# by a wildcard target in case the make implementation can put the two together.
|
||||||
|
*-spellchecked: Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
|
||||||
|
.sample.sample-spellchecked:
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
.in.in-spellchecked:
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
spellcheck spellcheck-interactive spellcheck-sortdict:
|
||||||
|
$(MAKE) -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC="$(SPELLCHECK_SRC)" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
# 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:
|
29
conf/hosts.conf.sample
Normal file
29
conf/hosts.conf.sample
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Network UPS Tools: example hosts.conf
|
||||||
|
#
|
||||||
|
# This file is used to control the CGI programs. If you have not
|
||||||
|
# installed them, you may safely ignore or delete this file.
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# upsstats will use the list of MONITOR entries when displaying the
|
||||||
|
# default template (upsstats.html). The "FOREACHUPS" directive in the
|
||||||
|
# template will use this file to find systems running upsd.
|
||||||
|
#
|
||||||
|
# upsstats and upsimage also use this file to determine if a host may be
|
||||||
|
# monitored. This keeps evil people from using your system to annoy
|
||||||
|
# others with unintended queries.
|
||||||
|
#
|
||||||
|
# upsset presents a list of systems that may be viewed and controlled
|
||||||
|
# using this file.
|
||||||
|
#
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Usage: list systems running upsd that you want to monitor
|
||||||
|
#
|
||||||
|
# MONITOR <system> "<host description>"
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# MONITOR myups@localhost "Local UPS"
|
||||||
|
# MONITOR su2200@10.64.1.1 "Finance department"
|
||||||
|
# MONITOR matrix@shs-server.example.edu "Sierra High School data room #1"
|
39
conf/nut.conf.sample
Normal file
39
conf/nut.conf.sample
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Network UPS Tools: example nut.conf
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
# General section
|
||||||
|
##############################################################################
|
||||||
|
# The MODE determines which part of the NUT is to be started, and which
|
||||||
|
# configuration files must be modified.
|
||||||
|
#
|
||||||
|
# This file try to standardize the various files being found in the field, like
|
||||||
|
# /etc/default/nut on Debian based systems, /etc/sysconfig/ups on RedHat based
|
||||||
|
# systems, ... Distribution's init script should source this file to see which
|
||||||
|
# component(s) has to be started.
|
||||||
|
#
|
||||||
|
# The values of MODE can be:
|
||||||
|
# - none: NUT is not configured, or use the Integrated Power Management, or use
|
||||||
|
# some external system to startup NUT components. So nothing is to be started.
|
||||||
|
# - standalone: This mode address a local only configuration, with 1 UPS
|
||||||
|
# protecting the local system. This implies to start the 3 NUT layers (driver,
|
||||||
|
# upsd and upsmon) and the matching configuration files. This mode can also
|
||||||
|
# address UPS redundancy.
|
||||||
|
# - netserver: same as for the standalone configuration, but also need
|
||||||
|
# some more network access controls (firewall, tcp-wrappers) and possibly a
|
||||||
|
# specific LISTEN directive in upsd.conf.
|
||||||
|
# Since this MODE is opened to the network, a special care should be applied
|
||||||
|
# to security concerns.
|
||||||
|
# - netclient: this mode only requires upsmon.
|
||||||
|
#
|
||||||
|
# IMPORTANT NOTE:
|
||||||
|
# This file is intended to be sourced by standard POSIX shell scripts (so
|
||||||
|
# there is no guaranteed `export VAR=VAL` syntax) and by systemd on Linux.
|
||||||
|
# You MUST NOT use spaces around the equal sign!
|
||||||
|
|
||||||
|
MODE=none
|
||||||
|
|
||||||
|
# Uncomment this to allow starting the service even if ups.conf has no device
|
||||||
|
# sections at the moment. This environment variable overrides the built-in
|
||||||
|
# "false" and an optional same-named default flag that can be set in upsd.conf:
|
||||||
|
#ALLOW_NO_DEVICE=true
|
||||||
|
#export ALLOW_NO_DEVICE
|
202
conf/ups.conf.sample
Normal file
202
conf/ups.conf.sample
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
# Network UPS Tools: example ups.conf
|
||||||
|
#
|
||||||
|
# --- SECURITY NOTE ---
|
||||||
|
#
|
||||||
|
# If you use snmp-ups and set a community string in here, you
|
||||||
|
# will have to secure this file to keep other users from obtaining
|
||||||
|
# that string. It needs to be readable by upsdrvctl and any drivers,
|
||||||
|
# and by upsd.
|
||||||
|
#
|
||||||
|
# ---
|
||||||
|
#
|
||||||
|
# This is where you configure all the UPSes that this system will be
|
||||||
|
# monitoring directly. These are usually attached to serial ports, but
|
||||||
|
# USB devices and SNMP devices are also supported.
|
||||||
|
#
|
||||||
|
# This file is used by upsdrvctl to start and stop your driver(s), and
|
||||||
|
# is also used by upsd to determine which drivers to monitor. The
|
||||||
|
# drivers themselves also read this file for configuration directives.
|
||||||
|
#
|
||||||
|
# The general form is:
|
||||||
|
#
|
||||||
|
# [upsname]
|
||||||
|
# driver = <drivername>
|
||||||
|
# port = <portname>
|
||||||
|
# < any other directives here >
|
||||||
|
#
|
||||||
|
# The section header ([upsname]) can be just about anything as long as
|
||||||
|
# it is a single word inside brackets. upsd uses this to uniquely
|
||||||
|
# identify a UPS on this system.
|
||||||
|
#
|
||||||
|
# If you have a UPS called snoopy, your section header would be "[snoopy]".
|
||||||
|
# On a system called "doghouse", the line in your upsmon.conf to monitor
|
||||||
|
# and manage it would look something like this:
|
||||||
|
#
|
||||||
|
# MONITOR snoopy@doghouse 1 upsmonuser mypassword primary
|
||||||
|
#
|
||||||
|
# It might look like this if monitoring in "secondary" mode (without any
|
||||||
|
# ability to directly manage the UPS) from a different system:
|
||||||
|
#
|
||||||
|
# MONITOR snoopy@doghouse 1 upsmonuser mypassword secondary
|
||||||
|
#
|
||||||
|
# Configuration directives
|
||||||
|
# ------------------------
|
||||||
|
#
|
||||||
|
# These directives are used by upsdrvctl only and should be specified outside
|
||||||
|
# of a driver definition:
|
||||||
|
#
|
||||||
|
# maxretry: OPTIONAL. Specify the number of attempts to start the driver(s),
|
||||||
|
# in case of failure, before giving up. A delay of 'retrydelay' is
|
||||||
|
# inserted between each attempt. Caution should be taken when using
|
||||||
|
# this option, since it can impact the time taken by your system to
|
||||||
|
# start.
|
||||||
|
#
|
||||||
|
# The built-in default is 1 attempt.
|
||||||
|
#
|
||||||
|
# retrydelay: OPTIONAL. Specify the delay between each restart attempt of the
|
||||||
|
# driver(s), as specified by 'maxretry'. Caution should be taken
|
||||||
|
# when using this option, since it can impact the time taken by your
|
||||||
|
# system to start.
|
||||||
|
#
|
||||||
|
# The default is 5 seconds.
|
||||||
|
#
|
||||||
|
# chroot: OPTIONAL. Used for securing. See man page for details.
|
||||||
|
#
|
||||||
|
# driverpath: OPTIONAL. Used for custom setups. See man page for details.
|
||||||
|
#
|
||||||
|
# nowait: OPTIONAL. Tell upsdrvctl to not wait at all for the driver(s)
|
||||||
|
# to execute the requested command. Fire and forget.
|
||||||
|
#
|
||||||
|
# pollinterval: OPTIONAL. The status of the UPS will be refreshed after a
|
||||||
|
# maximum delay which is controlled by this setting (default
|
||||||
|
# 2 seconds). This may be useful if the driver is creating too
|
||||||
|
# much of a load on your system or network.
|
||||||
|
# Note that some drivers also have an option called *pollfreq*
|
||||||
|
# which controls how frequently some of the less critical
|
||||||
|
# parameters are polled. See respective driver man pages.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Set maxretry to 3 by default, this should mitigate race with slow devices:
|
||||||
|
maxretry = 3
|
||||||
|
|
||||||
|
# These directives can be set outside and inside a driver definition, with
|
||||||
|
# slightly different meanings per context:
|
||||||
|
#
|
||||||
|
# maxstartdelay: OPTIONAL. This can be set as a global variable
|
||||||
|
# above your first UPS definition and it can also be
|
||||||
|
# set in a UPS section. This value controls how long
|
||||||
|
# upsdrvctl will wait for the driver to finish starting.
|
||||||
|
# This keeps your system from getting stuck due to a
|
||||||
|
# broken driver or UPS.
|
||||||
|
# The default is 45 seconds.
|
||||||
|
#
|
||||||
|
# debug_min: OPTIONAL. Specify a minimum debug level for all driver daemons
|
||||||
|
# (when specified at global level), or for this driver daemon
|
||||||
|
# (when specified in a driver section), e.g. for troubleshooting
|
||||||
|
# a deployment. This does not directly impact the foreground or
|
||||||
|
# background running mode. If both the global and driver level
|
||||||
|
# `debug_min` are set, the driver-level setting takes precedence.
|
||||||
|
# Command-line option `-D` can only increase this verbosity level.
|
||||||
|
#
|
||||||
|
# user, group: OPTIONAL. Overrides the compiled-in (also global-section,
|
||||||
|
# when used in driver section) default unprivileged user/group
|
||||||
|
# name for NUT device driver. Impacts access rights used for
|
||||||
|
# the socket file access (group) and communication ports (user).
|
||||||
|
#
|
||||||
|
# synchronous: OPTIONAL. The driver work by default in asynchronous
|
||||||
|
# mode (like *no*) with fallback to synchronous if sending
|
||||||
|
# fails (i.e *synchronous=auto*). This means that all data
|
||||||
|
# are pushed by the driver on the communication socket to
|
||||||
|
# upsd (Unix socket on Unix, Named pipe on Windows) without
|
||||||
|
# waiting for these data to be actually consumed. With
|
||||||
|
# some HW, such as ePDUs, that can produce a lot of data,
|
||||||
|
# asynchronous mode may cause some congestion, resulting in
|
||||||
|
# the socket to be full, and the driver to appear as not
|
||||||
|
# connected. By enabling the 'synchronous' flag
|
||||||
|
# (value = 'yes'), the driver will wait for data to be
|
||||||
|
# consumed by upsd, prior to publishing more. This can be
|
||||||
|
# enabled either globally or per driver.
|
||||||
|
#
|
||||||
|
# The default is 'no' (i.e. asynchronous mode) for backward
|
||||||
|
# compatibility of the driver behavior.
|
||||||
|
#
|
||||||
|
|
||||||
|
# These directives are common to all drivers that support ups.conf:
|
||||||
|
#
|
||||||
|
# driver: REQUIRED. Specify the program to run to talk to this UPS.
|
||||||
|
# apcsmart, bestups, and sec are some examples.
|
||||||
|
#
|
||||||
|
# port: REQUIRED. The serial port where your UPS is connected.
|
||||||
|
# /dev/ttyS0 is usually the first port on Linux boxes, for example.
|
||||||
|
#
|
||||||
|
# sdorder: OPTIONAL. When you have multiple UPSes on your system, you
|
||||||
|
# usually need to turn them off in a certain order. upsdrvctl
|
||||||
|
# shuts down all the 0s, then the 1s, 2s, and so on. To exclude
|
||||||
|
# a UPS from the shutdown sequence, set this to -1.
|
||||||
|
#
|
||||||
|
# The default value for this parameter is 0.
|
||||||
|
#
|
||||||
|
# desc: optional, to keep a note of the UPS purpose, location, etc.
|
||||||
|
#
|
||||||
|
# nolock: optional, and not recommended for use in this file.
|
||||||
|
#
|
||||||
|
# If you put nolock in here, the driver will not lock the
|
||||||
|
# serial port every time it starts. This may allow other
|
||||||
|
# processes to seize the port if you start more than one by
|
||||||
|
# mistake.
|
||||||
|
#
|
||||||
|
# This is only intended to be used on systems where locking
|
||||||
|
# absolutely must be disabled for the software to work.
|
||||||
|
#
|
||||||
|
# ignorelb: OPTIONAL. Ignore low battery condition reported by device,
|
||||||
|
# and evaluate remaining battery charge or runtime instead.
|
||||||
|
# See man page for details.
|
||||||
|
#
|
||||||
|
# usb_set_altinterface(=num): OPTIONAL. Require that NUT calls this method
|
||||||
|
# to set the interface, even if 0 (default). Some devices require
|
||||||
|
# the call to initialize; others however can get stuck due to it -
|
||||||
|
# so it is not called by default. Yet others can be composite
|
||||||
|
# devices which use a non-zero interface to represent the UPS.
|
||||||
|
#
|
||||||
|
# default.<variable>: OPTIONAL. Set a default value for <variable> which is
|
||||||
|
# used in case the UPS doesn't provide a value, but which will be
|
||||||
|
# overwritten if a value is available from the UPS, e.g.:
|
||||||
|
# default.input.voltage.nominal = 230
|
||||||
|
# will report the nominal input voltage to be 230, unless the UPS
|
||||||
|
# eventually tells us differently.
|
||||||
|
#
|
||||||
|
# override.<variable>: OPTIONAL. Set a value for <value> that overrides
|
||||||
|
# (for NUT) any value that may be read from the UPS.
|
||||||
|
# Used for overriding values from the UPS that are clearly wrong
|
||||||
|
# (e.g. some devices report wrong values for battery voltage):
|
||||||
|
# override.battery.voltage.nominal = 12
|
||||||
|
# Use with caution! This will only change the appearance of the
|
||||||
|
# variable to the outside world (and NUT calculations), internally
|
||||||
|
# in the UPS the original value is used.
|
||||||
|
#
|
||||||
|
# Anything else is passed through to the hardware-specific part of
|
||||||
|
# the driver.
|
||||||
|
#
|
||||||
|
# Examples
|
||||||
|
# --------
|
||||||
|
#
|
||||||
|
# A simple example for a UPS called "powerpal" that uses the blazer_ser
|
||||||
|
# driver on /dev/ttyS0 is:
|
||||||
|
#
|
||||||
|
# [powerpal]
|
||||||
|
# driver = blazer_ser
|
||||||
|
# port = /dev/ttyS0
|
||||||
|
# desc = "Web server"
|
||||||
|
#
|
||||||
|
# If your UPS driver requires additional settings, you can specify them
|
||||||
|
# here. For example, if it supports a setting of "1234" for the
|
||||||
|
# variable "cable", it would look like this:
|
||||||
|
#
|
||||||
|
# [myups]
|
||||||
|
# driver = mydriver
|
||||||
|
# port = /dev/ttyS1
|
||||||
|
# cable = 1234
|
||||||
|
# desc = "Something descriptive"
|
||||||
|
#
|
||||||
|
# To find out if your driver supports any extra settings, start it with
|
||||||
|
# the -h option and/or read the driver's documentation.
|
168
conf/upsd.conf.sample
Normal file
168
conf/upsd.conf.sample
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
# Network UPS Tools: example upsd configuration file
|
||||||
|
#
|
||||||
|
# This file contains access control data, you should keep it secure.
|
||||||
|
#
|
||||||
|
# It should only be readable by the user that upsd becomes. See the FAQ.
|
||||||
|
#
|
||||||
|
# Each entry below provides usage and default value.
|
||||||
|
#
|
||||||
|
# For more information, refer to upsd.conf manual page.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# MAXAGE <seconds>
|
||||||
|
# MAXAGE 15
|
||||||
|
#
|
||||||
|
# This defaults to 15 seconds. After a UPS driver has stopped updating
|
||||||
|
# the data for this many seconds, upsd marks it stale and stops making
|
||||||
|
# that information available to clients. After all, the only thing worse
|
||||||
|
# than no data is bad data.
|
||||||
|
#
|
||||||
|
# You should only use this if your driver has difficulties keeping
|
||||||
|
# the data fresh within the normal 15 second interval. Watch the syslog
|
||||||
|
# for notifications from upsd about staleness.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# TRACKINGDELAY <seconds>
|
||||||
|
# TRACKINGDELAY 3600
|
||||||
|
#
|
||||||
|
# This defaults to 1 hour. When instant commands and variables setting status
|
||||||
|
# tracking is enabled, status execution information are kept during this
|
||||||
|
# amount of time, and then cleaned up.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# ALLOW_NO_DEVICE <Boolean>
|
||||||
|
# ALLOW_NO_DEVICE true
|
||||||
|
#
|
||||||
|
# Normally upsd requires that at least one device section is defined in ups.conf
|
||||||
|
# when the daemon starts, to serve its data. For automatically managed services
|
||||||
|
# it may be preferred to have upsd always running, and reload the configuration
|
||||||
|
# when power devices become defined.
|
||||||
|
#
|
||||||
|
# Boolean values 'true', 'yes', 'on' and '1' mean that the server would not
|
||||||
|
# refuse to start with zero device sections found in ups.conf.
|
||||||
|
#
|
||||||
|
# Boolean values 'false', 'no', 'off' and '0' mean that the server should refuse
|
||||||
|
# to start if zero device sections were found in ups.conf. This is the default.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# STATEPATH <path>
|
||||||
|
# STATEPATH /var/run/nut
|
||||||
|
#
|
||||||
|
# Tell upsd to look for the driver state sockets in 'path' rather
|
||||||
|
# than the default that was compiled into the program.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# LISTEN <IP address or name> [<port>]
|
||||||
|
# LISTEN 127.0.0.1 3493
|
||||||
|
# LISTEN ::1 3493
|
||||||
|
# LISTEN myhostname 83493
|
||||||
|
# LISTEN myhostname.mydomain
|
||||||
|
#
|
||||||
|
# This defaults to the localhost listening addresses and port 3493.
|
||||||
|
# In case of IP v4 or v6 disabled kernel, only the available one will be used.
|
||||||
|
#
|
||||||
|
# You may specify each interface IP address or name that you want upsd to
|
||||||
|
# listen on for connections, optionally with a port number.
|
||||||
|
#
|
||||||
|
# You may need this if you have multiple interfaces on your machine and
|
||||||
|
# you don't want upsd to listen to all interfaces (for instance on a
|
||||||
|
# firewall, you may not want to listen to the external interface).
|
||||||
|
#
|
||||||
|
# This will only be read at startup of upsd. If you make changes here,
|
||||||
|
# you'll need to restart upsd, reload will have no effect.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# MAXCONN <connections>
|
||||||
|
# MAXCONN 1024
|
||||||
|
#
|
||||||
|
# This defaults to maximum number allowed on your system. Each UPS, each
|
||||||
|
# LISTEN address and each client count as one connection. If the server
|
||||||
|
# runs out of connections, it will no longer accept new incoming client
|
||||||
|
# connections. Only set this if you know exactly what you're doing.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# CERTFILE <certificate file>
|
||||||
|
# CERTFILE /usr/local/ups/etc/upsd.pem
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with OpenSSL backend,
|
||||||
|
# you can enter the certificate file here.
|
||||||
|
# The certificates must be in PEM format and must be sorted starting with
|
||||||
|
# the subject's certificate (server certificate), followed by intermediate
|
||||||
|
# CA certificates (if applicable_ and the highest level (root) CA. It should
|
||||||
|
# end with the server key. See 'docs/security.txt' or the Security chapter of
|
||||||
|
# NUT user manual for more information on the SSL support in NUT.
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# CERTPATH <certificate file or directory>
|
||||||
|
# CERTPATH /usr/local/ups/etc/cert/upsd
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with NSS backend,
|
||||||
|
# you can enter the certificate path here.
|
||||||
|
# Certificates are stored in a dedicated database (split into 3 files).
|
||||||
|
# Specify the path of the database directory.
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# CERTIDENT <certificate name> <database password>
|
||||||
|
# CERTIDENT "my nut server" "MyPasSw0rD"
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with NSS backend,
|
||||||
|
# you can specify the certificate name to retrieve from database to
|
||||||
|
# authenticate itself and the password
|
||||||
|
# required to access certificate related private key.
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# CERTREQUEST <certificate request level>
|
||||||
|
# CERTREQUEST REQUIRE
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with NSS backend and client certificate
|
||||||
|
# validation (disabled by default, see 'docs/security.txt'),
|
||||||
|
# you can specify if upsd requests or requires client's' certificates.
|
||||||
|
# Possible values are :
|
||||||
|
# - 0 to not request to clients to provide any certificate
|
||||||
|
# - 1 to require to all clients a certificate
|
||||||
|
# - 2 to require to all clients a valid certificate
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# DISABLE_WEAK_SSL <Boolean>
|
||||||
|
# DISABLE_WEAK_SSL true
|
||||||
|
#
|
||||||
|
# Tell upsd to disable older/weak SSL/TLS protocols and ciphers.
|
||||||
|
#
|
||||||
|
# With relatively recent versions of OpenSSL or NSS it will be restricted
|
||||||
|
# to TLSv1.2 or better.
|
||||||
|
#
|
||||||
|
# Unless you have really ancient clients, you probably want to enable this.
|
||||||
|
# Currently disabled by default to ensure compatibility with existing setups.
|
||||||
|
|
||||||
|
# =======================================================================
|
||||||
|
# DEBUG_MIN <Integer>
|
||||||
|
# DEBUG_MIN 2
|
||||||
|
#
|
||||||
|
# Optionally specify a minimum debug level for `upsd` data daemon, e.g. for
|
||||||
|
# troubleshooting a deployment, without impacting foreground or background
|
||||||
|
# running mode directly, and without need to edit init-scripts or service
|
||||||
|
# unit definitions. Note that command-line option `-D` can only increase
|
||||||
|
# this verbosity level.
|
||||||
|
#
|
||||||
|
# NOTE: if the running daemon receives a `reload` command, presence of the
|
||||||
|
# `DEBUG_MIN NUMBER` value in the configuration file can be used to tune
|
||||||
|
# debugging verbosity in the running service daemon (it is recommended to
|
||||||
|
# comment it away or set the minimum to explicit zero when done, to avoid
|
||||||
|
# huge journals and I/O system abuse). Keep in mind that for this run-time
|
||||||
|
# tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files
|
||||||
|
# is applied instantly and overrides any previously set value, from file
|
||||||
|
# or CLI options, regardless of older logging level being higher or lower
|
||||||
|
# than the newly found number; a missing (or commented away) value however
|
||||||
|
# does not change the previously active logging verbosity.
|
75
conf/upsd.users.sample
Normal file
75
conf/upsd.users.sample
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# Network UPS Tools: Example upsd.users
|
||||||
|
#
|
||||||
|
# This file sets the permissions for upsd - the UPS network daemon.
|
||||||
|
# Users are defined here, are given passwords, and their privileges are
|
||||||
|
# controlled here too. Since this file will contain passwords, keep it
|
||||||
|
# secure, with only enough permissions for upsd to read it.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Each user gets a section. To start a section, put the username in
|
||||||
|
# brackets on a line by itself. To set something for that user, specify
|
||||||
|
# it under that section heading. The username is case-sensitive, so
|
||||||
|
# admin and AdMiN are two different users.
|
||||||
|
#
|
||||||
|
# Possible settings:
|
||||||
|
#
|
||||||
|
# password: The user's password. This is case-sensitive.
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# actions: Let the user do certain things with upsd.
|
||||||
|
#
|
||||||
|
# Valid actions are:
|
||||||
|
#
|
||||||
|
# SET - change the value of certain variables in the UPS
|
||||||
|
# FSD - set the "forced shutdown" flag in the UPS
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# instcmds: Let the user initiate specific instant commands. Use "ALL"
|
||||||
|
# to grant all commands automatically. There are many possible
|
||||||
|
# commands, so use 'upscmd -l' to see what your hardware supports. Here
|
||||||
|
# are a few examples:
|
||||||
|
#
|
||||||
|
# test.panel.start - Start a front panel test
|
||||||
|
# test.battery.start - Start battery test
|
||||||
|
# test.battery.stop - Stop battery test
|
||||||
|
# calibrate.start - Start calibration
|
||||||
|
# calibrate.stop - Stop calibration
|
||||||
|
#
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# [admin]
|
||||||
|
# password = mypass
|
||||||
|
# actions = SET
|
||||||
|
# instcmds = ALL
|
||||||
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# --- Configuring for a user who can execute tests only
|
||||||
|
#
|
||||||
|
# [testuser]
|
||||||
|
# password = pass
|
||||||
|
# instcmds = test.battery.start
|
||||||
|
# instcmds = test.battery.stop
|
||||||
|
|
||||||
|
#
|
||||||
|
# --- Configuring for upsmon
|
||||||
|
#
|
||||||
|
# To add a user for your upsmon, use this example:
|
||||||
|
#
|
||||||
|
# [upsmon]
|
||||||
|
# password = pass
|
||||||
|
# upsmon primary
|
||||||
|
# or
|
||||||
|
# upsmon secondary
|
||||||
|
#
|
||||||
|
# The matching MONITOR line in your upsmon.conf would look like this:
|
||||||
|
#
|
||||||
|
# MONITOR myups@localhost 1 upsmon pass primary (or secondary)
|
||||||
|
#
|
||||||
|
# See comments in the upsmon.conf(.sample) file for details about this
|
||||||
|
# keyword and the difference of NUT secondary and primary systems.
|
453
conf/upsmon.conf.sample.in
Normal file
453
conf/upsmon.conf.sample.in
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
# Network UPS Tools: example upsmon configuration
|
||||||
|
#
|
||||||
|
# This file contains passwords, so keep it secure.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# RUN_AS_USER <userid>
|
||||||
|
#
|
||||||
|
# By default, upsmon splits into two processes. One stays as root and
|
||||||
|
# waits to run the SHUTDOWNCMD. The other one switches to another userid
|
||||||
|
# and does everything else.
|
||||||
|
#
|
||||||
|
# The default unprivileged user is set at compile-time with the option
|
||||||
|
# 'configure --with-user=...'
|
||||||
|
#
|
||||||
|
# You can override it with '-u <user>' when starting upsmon, or just
|
||||||
|
# define it here for convenience.
|
||||||
|
#
|
||||||
|
# Note: if you plan to use the reload feature, this file (upsmon.conf)
|
||||||
|
# must be readable by this user! Since it contains passwords, DO NOT
|
||||||
|
# make it world-readable. Also, do not make it writable by the upsmon
|
||||||
|
# user, since it creates an opportunity for an attack by changing the
|
||||||
|
# SHUTDOWNCMD to something malicious.
|
||||||
|
#
|
||||||
|
# For best results, you should create a new normal user like "nutmon",
|
||||||
|
# and make it a member of a "nut" group or similar. Then specify it
|
||||||
|
# here and grant read access to the upsmon.conf for that group.
|
||||||
|
#
|
||||||
|
# This user should not have write access to upsmon.conf.
|
||||||
|
#
|
||||||
|
# RUN_AS_USER @RUN_AS_USER@
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# MONITOR <system> <powervalue> <username> <password> ("primary"|"secondary")
|
||||||
|
#
|
||||||
|
# List systems you want to monitor. Not all of these may supply power
|
||||||
|
# to the system running upsmon, but if you want to watch it, it has to
|
||||||
|
# be in this section.
|
||||||
|
#
|
||||||
|
# You must have at least one of these declared.
|
||||||
|
#
|
||||||
|
# <system> is a UPS identifier in the form <upsname>@<hostname>[:<port>]
|
||||||
|
# like ups@localhost, su700@mybox, etc.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# - "su700@mybox" means a UPS called "su700" on a system called "mybox"
|
||||||
|
#
|
||||||
|
# - "fenton@bigbox:5678" is a UPS called "fenton" on a system called
|
||||||
|
# "bigbox" which runs upsd on port "5678".
|
||||||
|
#
|
||||||
|
# The UPS names like "su700" and "fenton" are set in your ups.conf
|
||||||
|
# in [brackets] which identify a section for a particular driver.
|
||||||
|
#
|
||||||
|
# If the ups.conf on host "doghouse" has a section called "snoopy", the
|
||||||
|
# identifier for it would be "snoopy@doghouse".
|
||||||
|
#
|
||||||
|
# <powervalue> is an integer - the number of power supplies that this UPS
|
||||||
|
# feeds on this system. Most personal computers only have one power supply,
|
||||||
|
# so this value is normally set to 1, while most modern servers have at least
|
||||||
|
# two. You need a pretty big or special box to have any other value here.
|
||||||
|
#
|
||||||
|
# You can also set this to 0 for a system that doesn't take any power
|
||||||
|
# from the MONITORed supply, which you still want to monitor (e.g. for an
|
||||||
|
# administrative workstation fed from a different circuit than the datacenter
|
||||||
|
# servers it monitors). Use <powervalue> if 0 when you want to hear about
|
||||||
|
# changes for a given UPS without shutting down when it goes critical.
|
||||||
|
#
|
||||||
|
# <username> and <password> must match an entry in that system's
|
||||||
|
# upsd.users. If your username is "upsmon" and your password is
|
||||||
|
# "blah", the upsd.users would look like this:
|
||||||
|
#
|
||||||
|
# [upsmon]
|
||||||
|
# password = blah
|
||||||
|
# upsmon primary # (or secondary)
|
||||||
|
#
|
||||||
|
# "primary" means this system will shutdown last, allowing the secondary
|
||||||
|
# systems time to shutdown first.
|
||||||
|
#
|
||||||
|
# "secondary" means this system shuts down immediately when power goes
|
||||||
|
# critical and less than MINSUPPLIES power sources have reliable input feeds.
|
||||||
|
#
|
||||||
|
# The general assumption is that the "primary" system is the one with direct
|
||||||
|
# connection to an UPS (such as serial or USB cable), so the primary system
|
||||||
|
# runs the NUT driver and 'upsd' server locally and can manage the device,
|
||||||
|
# and it would often tell the UPS to completely power itself off as a step
|
||||||
|
# in power-race avoidance (see POWERDOWNFLAG for details).
|
||||||
|
#
|
||||||
|
# Also, since the primary system stays up the longest, it suffers higher risks
|
||||||
|
# of ungraceful shutdown if the estimation of remaining runtime (or of the
|
||||||
|
# time it takes to shut down this system) was guessed wrong. By consequence,
|
||||||
|
# the "secondary" systems typically monitor the power environment state
|
||||||
|
# through the 'upsd' processes running on the remote (often "primary") systems
|
||||||
|
# and do not directly interact with an UPS (no local NUT drivers are running
|
||||||
|
# on the secondary systems). As such, secondaries typically shut down as
|
||||||
|
# soon as there is a sufficiently long power outage, or a low-battery alert
|
||||||
|
# from the UPS, or a loss of connection to the primary while the power was
|
||||||
|
# last known to be missing.
|
||||||
|
#
|
||||||
|
# This assumption and configuration can also make sense for networked UPSes,
|
||||||
|
# where a rack full of servers might overload the communications capacity
|
||||||
|
# of the networked management card on the UPS - in this case you might either
|
||||||
|
# reduce the 'snmp-ups' or 'netxml-ups' driver polling rate, or dedicate a
|
||||||
|
# "primary" server and set up the rest as "secondary" systems.
|
||||||
|
#
|
||||||
|
# In case of such large setups as mentioned above, beware also that shutdown
|
||||||
|
# times of the rack done all at once can substantially differ from smaller
|
||||||
|
# scale experiments with single-server shutdowns, since systems can compete
|
||||||
|
# for shared storage and other limited resources as they go down (and also
|
||||||
|
# not everyone may safely shut down simultaneously - e.g. a NAS or DB server
|
||||||
|
# would better go down after all its clients). You would be well served by
|
||||||
|
# higher-end UPSes with manageable thresholds to declare a critical state.
|
||||||
|
#
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# MONITOR myups@bigserver 1 upswired blah primary
|
||||||
|
# MONITOR su700@server.example.com 1 upsmon secretpass secondary
|
||||||
|
# MONITOR myups@localhost 1 upsmon pass primary # (or secondary)
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# MINSUPPLIES <num>
|
||||||
|
#
|
||||||
|
# Give the number of power supplies that must be receiving power to keep
|
||||||
|
# this system running. Most systems have one power supply, so you would
|
||||||
|
# put "1" in this field.
|
||||||
|
#
|
||||||
|
# Large/expensive server type systems usually have more, and can run with
|
||||||
|
# a few missing. Some of these can run with 2 out of 4, for example,
|
||||||
|
# so you'd set that to 2. The idea is to keep the box running as long
|
||||||
|
# as possible, right?
|
||||||
|
#
|
||||||
|
# Obviously you have to put the redundant supplies on different UPS circuits
|
||||||
|
# for this to make sense! See big-servers.txt in the docs subdirectory
|
||||||
|
# for more information and ideas on how to use this feature.
|
||||||
|
|
||||||
|
MINSUPPLIES 1
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# SHUTDOWNCMD "<command>"
|
||||||
|
#
|
||||||
|
# upsmon runs this command when the system needs to be brought down.
|
||||||
|
#
|
||||||
|
# This should work just about everywhere ... if it doesn't, well, change it,
|
||||||
|
# perhaps to a more complicated custom script.
|
||||||
|
#
|
||||||
|
# Note that while you experiment with the initial setup and want to test how
|
||||||
|
# your configuration reacts to power state changes and ultimately when power
|
||||||
|
# is reported to go critical, but do not want your system to actually turn
|
||||||
|
# off, consider setting the SHUTDOWNCMD temporarily to do something benign -
|
||||||
|
# such as posting a message with 'logger' or 'wall' or 'mailx'. Do be careful
|
||||||
|
# to plug the UPS back into the wall in a timely fashion.
|
||||||
|
|
||||||
|
SHUTDOWNCMD "/sbin/shutdown -h +0"
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# NOTIFYCMD <command>
|
||||||
|
#
|
||||||
|
# upsmon calls this to send messages when things happen
|
||||||
|
#
|
||||||
|
# This command is called with the full text of the message (from NOTIFYMSG)
|
||||||
|
# as one argument.
|
||||||
|
#
|
||||||
|
# The environment string NOTIFYTYPE will contain the type string of
|
||||||
|
# whatever caused this event to happen.
|
||||||
|
#
|
||||||
|
# The environment string UPSNAME will contain the name of the system/device
|
||||||
|
# that generated the change.
|
||||||
|
#
|
||||||
|
# Note that this is only called for NOTIFY events that have EXEC set with
|
||||||
|
# NOTIFYFLAG. See NOTIFYFLAG below for more details.
|
||||||
|
#
|
||||||
|
# Making this some sort of shell script might not be a bad idea.
|
||||||
|
# Alternately you can use the upssched program as your NOTIFYCMD for some
|
||||||
|
# more complex setups (e.g. to ease handling of notification storms).
|
||||||
|
# For more information and ideas, see docs/scheduling.txt
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# NOTIFYCMD @BINDIR@/notifyme
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# POLLFREQ <n>
|
||||||
|
#
|
||||||
|
# Polling frequency for normal activities, measured in seconds.
|
||||||
|
#
|
||||||
|
# Adjust this to keep upsmon from flooding your network, but don't make
|
||||||
|
# it too high or it may miss certain short-lived power events.
|
||||||
|
|
||||||
|
POLLFREQ 5
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# POLLFREQALERT <n>
|
||||||
|
#
|
||||||
|
# Polling frequency in seconds while UPS on battery.
|
||||||
|
#
|
||||||
|
# You can make this number lower than POLLFREQ, which will make updates
|
||||||
|
# faster when any UPS is running on battery. This is a good way to tune
|
||||||
|
# network load if you have a lot of these things running.
|
||||||
|
#
|
||||||
|
# The default is 5 seconds for both this and POLLFREQ.
|
||||||
|
|
||||||
|
POLLFREQALERT 5
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# HOSTSYNC - How long upsmon will wait before giving up on another upsmon
|
||||||
|
#
|
||||||
|
# The primary upsmon process uses this number when waiting for secondary
|
||||||
|
# systems to disconnect once it has set the forced shutdown (FSD) flag.
|
||||||
|
# If they don't disconnect after this many seconds, it goes on without them.
|
||||||
|
#
|
||||||
|
# Similarly, upsmon secondary processes wait up to this interval for the
|
||||||
|
# primary upsmon to set FSD when an UPS they are monitoring goes critical -
|
||||||
|
# that is, on battery and low battery. If the primary doesn't do its job,
|
||||||
|
# the secondaries will shut down anyway to avoid damage to the file systems.
|
||||||
|
#
|
||||||
|
# This "wait for FSD" is done to avoid races where the status changes
|
||||||
|
# to critical and back between polls by the primary.
|
||||||
|
|
||||||
|
HOSTSYNC 15
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# DEADTIME - Interval to wait before declaring a stale ups "dead"
|
||||||
|
#
|
||||||
|
# upsmon requires a UPS to provide status information every few seconds
|
||||||
|
# (see POLLFREQ and POLLFREQALERT) to keep things updated. If the status
|
||||||
|
# fetch fails, the UPS is marked stale. If it stays stale for more than
|
||||||
|
# DEADTIME seconds, the UPS is marked dead.
|
||||||
|
#
|
||||||
|
# A dead UPS that was last known to be on battery is assumed to have gone
|
||||||
|
# to a low battery condition. This may force a shutdown if it is providing
|
||||||
|
# a critical amount of power to your system.
|
||||||
|
#
|
||||||
|
# Note: DEADTIME should be a multiple of POLLFREQ and POLLFREQALERT.
|
||||||
|
# Otherwise you'll have "dead" UPSes simply because upsmon isn't polling
|
||||||
|
# them quickly enough. Rule of thumb: take the larger of the two
|
||||||
|
# POLLFREQ values, and multiply by 3.
|
||||||
|
|
||||||
|
DEADTIME 15
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# POWERDOWNFLAG - Flag file for forcing UPS shutdown on the primary system
|
||||||
|
#
|
||||||
|
# upsmon will create a file with this name in primary mode when it's time
|
||||||
|
# to shut down the load. You should check for this file's existence in
|
||||||
|
# your shutdown scripts and run 'upsdrvctl shutdown' if it exists, to tell
|
||||||
|
# the UPS(es) to power off.
|
||||||
|
#
|
||||||
|
# See the config-notes.txt file in the docs subdirectory for more information.
|
||||||
|
# Refer to the section:
|
||||||
|
# [[UPS_shutdown]] "Configuring automatic shutdowns for low battery events"
|
||||||
|
# or refer to the online version.
|
||||||
|
|
||||||
|
POWERDOWNFLAG /etc/killpower
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# NOTIFYMSG - change messages sent by upsmon when certain events occur
|
||||||
|
#
|
||||||
|
# You can change the default messages to something else if you like.
|
||||||
|
#
|
||||||
|
# NOTIFYMSG <notify type> "message"
|
||||||
|
#
|
||||||
|
# NOTIFYMSG ONLINE "UPS %s on line power"
|
||||||
|
# NOTIFYMSG ONBATT "UPS %s on battery"
|
||||||
|
# NOTIFYMSG LOWBATT "UPS %s battery is low"
|
||||||
|
# NOTIFYMSG FSD "UPS %s: forced shutdown in progress"
|
||||||
|
# NOTIFYMSG COMMOK "Communications with UPS %s established"
|
||||||
|
# NOTIFYMSG COMMBAD "Communications with UPS %s lost"
|
||||||
|
# NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding"
|
||||||
|
# NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced"
|
||||||
|
# NOTIFYMSG NOCOMM "UPS %s is unavailable"
|
||||||
|
# NOTIFYMSG NOPARENT "upsmon parent process died - shutdown impossible"
|
||||||
|
#
|
||||||
|
# Note that %s is replaced with the identifier of the UPS in question.
|
||||||
|
#
|
||||||
|
# Possible values for <notify type>:
|
||||||
|
#
|
||||||
|
# ONLINE : UPS is back online
|
||||||
|
# ONBATT : UPS is on battery
|
||||||
|
# LOWBATT : UPS has a low battery (if also on battery, it's "critical")
|
||||||
|
# FSD : UPS is being shutdown by the primary (FSD = "Forced Shutdown")
|
||||||
|
# COMMOK : Communications established with the UPS
|
||||||
|
# COMMBAD : Communications lost to the UPS
|
||||||
|
# SHUTDOWN : The system is being shutdown
|
||||||
|
# REPLBATT : The UPS battery is bad and needs to be replaced
|
||||||
|
# NOCOMM : A UPS is unavailable (can't be contacted for monitoring)
|
||||||
|
# NOPARENT : The process that shuts down the system has died (shutdown impossible)
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# NOTIFYFLAG - change behavior of upsmon when NOTIFY events occur
|
||||||
|
#
|
||||||
|
# By default, upsmon sends walls (global messages to all logged in users)
|
||||||
|
# and writes to the syslog when things happen. You can change this.
|
||||||
|
#
|
||||||
|
# NOTIFYFLAG <notify type> <flag>[+<flag>][+<flag>] ...
|
||||||
|
#
|
||||||
|
# NOTIFYFLAG ONLINE SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG ONBATT SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG LOWBATT SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG FSD SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG COMMOK SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG COMMBAD SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG SHUTDOWN SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG REPLBATT SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG NOCOMM SYSLOG+WALL
|
||||||
|
# NOTIFYFLAG NOPARENT SYSLOG+WALL
|
||||||
|
#
|
||||||
|
# Possible values for the flags:
|
||||||
|
#
|
||||||
|
# SYSLOG - Write the message in the syslog
|
||||||
|
# WALL - Write the message to all users on the system
|
||||||
|
# EXEC - Execute NOTIFYCMD (see above) with the message
|
||||||
|
# IGNORE - Don't do anything
|
||||||
|
#
|
||||||
|
# If you use IGNORE, don't use any other flags on the same line.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# RBWARNTIME - replace battery warning time in seconds
|
||||||
|
#
|
||||||
|
# upsmon will normally warn you about a battery that needs to be replaced
|
||||||
|
# every 43200 seconds, which is 12 hours. It does this by triggering a
|
||||||
|
# NOTIFY_REPLBATT which is then handled by the usual notify structure
|
||||||
|
# you've defined above.
|
||||||
|
#
|
||||||
|
# If this number is not to your liking, override it here.
|
||||||
|
|
||||||
|
RBWARNTIME 43200
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# NOCOMMWARNTIME - no communications warning time in seconds
|
||||||
|
#
|
||||||
|
# upsmon will let you know through the usual notify system if it can't
|
||||||
|
# talk to any of the UPS entries that are defined in this file. It will
|
||||||
|
# trigger a NOTIFY_NOCOMM by default every 300 seconds unless you
|
||||||
|
# change the interval with this directive.
|
||||||
|
|
||||||
|
NOCOMMWARNTIME 300
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# FINALDELAY - last sleep interval before shutting down the system
|
||||||
|
#
|
||||||
|
# On a primary, upsmon will wait this long after sending the NOTIFY_SHUTDOWN
|
||||||
|
# before executing your SHUTDOWNCMD. If you need to do something in between
|
||||||
|
# those events, increase this number. Remember, at this point your UPS is
|
||||||
|
# almost depleted, so don't make this too high. If needed, on high-end UPS
|
||||||
|
# devices you can usually configure when the low-battery state is announced
|
||||||
|
# based on estimated remaining run-time or on charge level of the batteries.
|
||||||
|
#
|
||||||
|
# Alternatively, you can set this very low so you don't wait around when
|
||||||
|
# it's time to shut down. Some UPSes don't give much warning for low
|
||||||
|
# battery and will require a value of 0 here for a safe shutdown.
|
||||||
|
#
|
||||||
|
# Note: If FINALDELAY on the secondary is greater than HOSTSYNC on the
|
||||||
|
# primary, the primary will give up waiting for that secondary system
|
||||||
|
# to disconnect.
|
||||||
|
|
||||||
|
FINALDELAY 5
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# CERTPATH - path to certificates (database directory or directory with CA's)
|
||||||
|
#
|
||||||
|
# When compiled with SSL support, you can enter the certificate path here.
|
||||||
|
#
|
||||||
|
# With NSS:
|
||||||
|
# Certificates are stored in a dedicated database (split into 3 files).
|
||||||
|
# Specify the path of the database directory.
|
||||||
|
#
|
||||||
|
# CERTPATH @CONFPATH@/cert/upsmon
|
||||||
|
#
|
||||||
|
# With OpenSSL:
|
||||||
|
# Directory containing CA certificates in PEM format, used to verify
|
||||||
|
# the server certificate presented by the upsd server. The files each
|
||||||
|
# contain one CA certificate. The files are looked up by the CA subject
|
||||||
|
# name hash value, which must hence be available.
|
||||||
|
#
|
||||||
|
# CERTPATH /usr/ssl/certs
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# CERTIDENT - self certificate name and database password
|
||||||
|
# CERTIDENT <certificate name> <database password>
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with NSS, you can specify the certificate
|
||||||
|
# name to retrieve from database to authenticate itself and the password
|
||||||
|
# required to access certificate related private key.
|
||||||
|
#
|
||||||
|
# CERTIDENT "my nut monitor" "MyPasSw0rD"
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# CERTHOST - security properties for an host
|
||||||
|
# CERTHOST <hostname> <certificate name> <certverify> <forcessl>
|
||||||
|
#
|
||||||
|
# When compiled with SSL support with NSS, you can specify security directive
|
||||||
|
# for each server you can contact.
|
||||||
|
# Each entry maps server name with the expected certificate name and flags
|
||||||
|
# indicating if the server certificate is verified and if the connection
|
||||||
|
# must be secure.
|
||||||
|
#
|
||||||
|
# CERTHOST localhost "My nut server" 1 1
|
||||||
|
#
|
||||||
|
# See 'docs/security.txt' or the Security chapter of NUT user manual
|
||||||
|
# for more information on the SSL support in NUT.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# CERTVERIFY - make upsmon verify all connections with certificates
|
||||||
|
# CERTVERIFY 1
|
||||||
|
#
|
||||||
|
# When compiled with SSL support, make upsmon verify all connections with
|
||||||
|
# certificates.
|
||||||
|
# Without this, there is no guarantee that the upsd is the right host.
|
||||||
|
# Enabling this greatly reduces the risk of man in the middle attacks.
|
||||||
|
# This effectively forces the use of SSL, so don't use this unless
|
||||||
|
# all of your upsd hosts are ready for SSL and have their certificates
|
||||||
|
# in order.
|
||||||
|
# When compiled with NSS support of SSL, can be overridden for host
|
||||||
|
# specified with a CERTHOST directive.
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# FORCESSL - force upsmon to use SSL
|
||||||
|
# FORCESSL 1
|
||||||
|
#
|
||||||
|
# When compiled with SSL, specify that a secured connection must be used
|
||||||
|
# to communicate with upsd.
|
||||||
|
# If you don't use 'CERTVERIFY 1', then this will at least make sure
|
||||||
|
# that nobody can sniff your sessions without a large effort. Setting
|
||||||
|
# this will make upsmon drop connections if the remote upsd doesn't
|
||||||
|
# support SSL, so don't use it unless all of them have it running.
|
||||||
|
# When compiled with NSS support of SSL, can be overridden for host
|
||||||
|
# specified with a CERTHOST directive.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# DEBUG_MIN - specify minimal debugging level for upsmon daemon
|
||||||
|
# e.g. DEBUG_MIN 6
|
||||||
|
#
|
||||||
|
# Optionally specify a minimum debug level for `upsmon` daemon, e.g. for
|
||||||
|
# troubleshooting a deployment, without impacting foreground or background
|
||||||
|
# running mode directly, and without need to edit init-scripts or service
|
||||||
|
# unit definitions. Note that command-line option `-D` can only increase
|
||||||
|
# this verbosity level.
|
||||||
|
#
|
||||||
|
# NOTE: if the running daemon receives a `reload` command, presence of the
|
||||||
|
# `DEBUG_MIN NUMBER` value in the configuration file can be used to tune
|
||||||
|
# debugging verbosity in the running service daemon (it is recommended to
|
||||||
|
# comment it away or set the minimum to explicit zero when done, to avoid
|
||||||
|
# huge journals and I/O system abuse). Keep in mind that for this run-time
|
||||||
|
# tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files
|
||||||
|
# is applied instantly and overrides any previously set value, from file
|
||||||
|
# or CLI options, regardless of older logging level being higher or lower
|
||||||
|
# than the newly found number; a missing (or commented away) value however
|
||||||
|
# does not change the previously active logging verbosity.
|
124
conf/upssched.conf.sample.in
Normal file
124
conf/upssched.conf.sample.in
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
# Network UPS Tools - upssched.conf sample file
|
||||||
|
#
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# CMDSCRIPT <scriptname>
|
||||||
|
#
|
||||||
|
# This script gets called to invoke commands for timers that trigger.
|
||||||
|
# It is given a single argument - the <timername> in your
|
||||||
|
# AT ... START-TIMER defines.
|
||||||
|
#
|
||||||
|
# *** This must be defined *before* the first AT line. Otherwise the
|
||||||
|
# program will complain and exit without doing anything.
|
||||||
|
#
|
||||||
|
# A shell script with a big case..esac construct should work nicely for this.
|
||||||
|
# An example has been provided to help you get started.
|
||||||
|
|
||||||
|
CMDSCRIPT @BINDIR@/upssched-cmd
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# PIPEFN <filename>
|
||||||
|
#
|
||||||
|
# This sets the file name of the FIFO that will pass communications between
|
||||||
|
# processes to start and stop timers. This should be set to some path where
|
||||||
|
# normal users can't create the file, due to the possibility of symlinking
|
||||||
|
# and other evil.
|
||||||
|
#
|
||||||
|
# Note: if you are running Solaris or similar, the permissions that
|
||||||
|
# upssched sets on this file *are not enough* to keep you safe. If
|
||||||
|
# your OS ignores the permissions on a FIFO, then you MUST put this in
|
||||||
|
# a protected directory!
|
||||||
|
#
|
||||||
|
# Note 2: by default, upsmon will run upssched as whatever user you have
|
||||||
|
# defined with RUN_AS_USER in upsmon.conf. Make sure that user can
|
||||||
|
# create files and write to files in the path you use for PIPEFN and
|
||||||
|
# LOCKFN.
|
||||||
|
#
|
||||||
|
# My recommendation: create a special directory for upssched, make it
|
||||||
|
# owned by your upsmon user, then use it for both.
|
||||||
|
#
|
||||||
|
# This is commented out by default to make you visit this file and think
|
||||||
|
# about how your system works before potentially opening a hole.
|
||||||
|
#
|
||||||
|
# PIPEFN @STATEPATH@/upssched/upssched.pipe
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# LOCKFN <filename>
|
||||||
|
#
|
||||||
|
# REQUIRED. This was added after version 1.2.1.
|
||||||
|
#
|
||||||
|
# upssched needs to be able to create this filename in order to avoid
|
||||||
|
# a race condition when two events are dispatched from upsmon at nearly
|
||||||
|
# the same time. This file will only exist briefly. It must not be
|
||||||
|
# created by any other process.
|
||||||
|
#
|
||||||
|
# You should put this in the same directory as PIPEFN.
|
||||||
|
#
|
||||||
|
# LOCKFN @STATEPATH@/upssched/upssched.lock
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# AT <notifytype> <upsname> <command>
|
||||||
|
#
|
||||||
|
# Define a handler for a specific event <notifytype> on UPS <upsname>.
|
||||||
|
#
|
||||||
|
# <upsname> can be the special value * to apply this handler to every
|
||||||
|
# possible value of <upsname>.
|
||||||
|
#
|
||||||
|
# Run the command <command> via your CMDSCRIPT when it happens.
|
||||||
|
#
|
||||||
|
# Note that any AT that matches both the <notifytype> and the <upsname>
|
||||||
|
# for the current event will be used.
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
#
|
||||||
|
# Possible AT commands
|
||||||
|
#
|
||||||
|
# - START-TIMER <timername> <interval>
|
||||||
|
#
|
||||||
|
# Start a timer called <timername> that will trigger after <interval>
|
||||||
|
# seconds, calling your CMDSCRIPT with <timername> as the first
|
||||||
|
# argument.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# 1) Start a timer that will execute when communication with any UPS (*) has
|
||||||
|
# been gone for 10 seconds
|
||||||
|
#
|
||||||
|
# AT COMMBAD * START-TIMER upsgone 10
|
||||||
|
#
|
||||||
|
# 2) Start a timer that will execute when any UPS (*) has been running
|
||||||
|
# on battery for 30 seconds
|
||||||
|
#
|
||||||
|
# AT ONBATT * START-TIMER onbattwarn 30
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# - CANCEL-TIMER <timername> [cmd]
|
||||||
|
#
|
||||||
|
# Cancel a running timer called <timername>, if possible. If the timer
|
||||||
|
# has passed then pass the optional argument <cmd> to CMDSCRIPT.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# 1) If a specific UPS (myups@localhost) communication is restored, then stop
|
||||||
|
# the timer before it triggers
|
||||||
|
#
|
||||||
|
# AT COMMOK myups@localhost CANCEL-TIMER upsgone
|
||||||
|
#
|
||||||
|
# 2) If any UPS (*) reverts to utility power, then stop the timer before it
|
||||||
|
# triggers
|
||||||
|
#
|
||||||
|
# AT ONLINE * CANCEL-TIMER onbattwarn
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# - EXECUTE <command>
|
||||||
|
#
|
||||||
|
# Immediately pass <command> as an argument to CMDSCRIPT.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# If any UPS (*) reverts to utility power, then execute
|
||||||
|
# 'ups-back-on-line' via CMDSCRIPT.
|
||||||
|
#
|
||||||
|
# AT ONLINE * EXECUTE ups-back-on-line
|
36
conf/upsset.conf.sample
Normal file
36
conf/upsset.conf.sample
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Network UPS Tools - upsset.conf sample file
|
||||||
|
#
|
||||||
|
# This file is provided to ensure that you do not expose your upsd server
|
||||||
|
# to the world upon installing the CGI programs. Specifically, it keeps
|
||||||
|
# the upsset.cgi program from running until you have assured it that you
|
||||||
|
# have secured your web server's CGI directory.
|
||||||
|
#
|
||||||
|
# By default, your web server will probably let anyone access upsset.cgi
|
||||||
|
# once it is installed. This means that anyone could attempt to crack
|
||||||
|
# upsd logins since they would appear to be coming from your web server,
|
||||||
|
# rather than the outside world, slipping through any ACL/ACCESS definitions.
|
||||||
|
#
|
||||||
|
# For this reason, you *MUST* first secure your CGI programs before
|
||||||
|
# enabling upsset in this configuration file. If you can't do this in
|
||||||
|
# your web server, then you should *not* run this program.
|
||||||
|
#
|
||||||
|
# For Apache, the .htaccess file can be used in the directory with the
|
||||||
|
# programs. You'll need something like this:
|
||||||
|
#
|
||||||
|
# <Files upsset.cgi>
|
||||||
|
# deny from all
|
||||||
|
# allow from your.network.addresses
|
||||||
|
# </Files>
|
||||||
|
#
|
||||||
|
# You will probably have to set "AllowOverride Limit" for this directory in
|
||||||
|
# your server-level configuration file as well.
|
||||||
|
#
|
||||||
|
# If this doesn't make sense, then stop reading and leave this program alone.
|
||||||
|
#
|
||||||
|
# Assuming you have all this done (and it works), then you may uncomment
|
||||||
|
# the line below and start using upsset.cgi through your web browser.
|
||||||
|
#
|
||||||
|
|
||||||
|
###
|
||||||
|
### I_HAVE_SECURED_MY_CGI_DIRECTORY
|
||||||
|
###
|
303
conf/upsstats-single.html.sample
Normal file
303
conf/upsstats-single.html.sample
Normal file
|
@ -0,0 +1,303 @@
|
||||||
|
<!-- upsstats template file -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This is upsstats-single.html, a template for monitoring a single
|
||||||
|
host. This mode is selected by adding "host=<host>" to the
|
||||||
|
upsstats.cgi URL.
|
||||||
|
|
||||||
|
Such URLs are generated automatically when using the HOSTLINK
|
||||||
|
command.
|
||||||
|
|
||||||
|
See upsstats.html(5) for more information on template files.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- change this to TEMPF if you don't like Celsius. -->
|
||||||
|
|
||||||
|
@TEMPC@
|
||||||
|
@UPSSTATSPATH upsstats.cgi@
|
||||||
|
@UPSIMAGEPATH upsimage.cgi@
|
||||||
|
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||||
|
"http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
@REFRESH@
|
||||||
|
<title>@HOSTDESC@ : @VAR ups.model@ on @HOST@</title>
|
||||||
|
<!-- LINK REL="stylesheet" TYPE="text/css" HREF="http://localhost/nut/nut.css" / -->
|
||||||
|
<style type="text/css">
|
||||||
|
body{color:#00fc00; background:#808080; font-family:"Times New Roman", Times, serif;}
|
||||||
|
a:link{color:#00e;}
|
||||||
|
a:visited{color:#551a8b;}
|
||||||
|
table{background:#000;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<table style="margin:auto" BORDER="1" CELLSPACING="0" CELLPADDING="10">
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th COLSPAN="20">Network UPS Tools upsstats @VERSION@ - @HOSTDESC@ - @VAR ups.model@ on @HOST@</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th>@DATE %a %b %d %X %Z %Y@</th>
|
||||||
|
@IFSUPP ambient.temperature@
|
||||||
|
<th>Ambient</th>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP ambient.humidity@
|
||||||
|
<th>Ambient</th>
|
||||||
|
@ENDIF@
|
||||||
|
<th>Battery</th>
|
||||||
|
<th>Input</th>
|
||||||
|
<th>Output</th>
|
||||||
|
<th>Load</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
|
||||||
|
<td VALIGN="TOP">
|
||||||
|
|
||||||
|
<table BORDER="0"> <!-- table 2 -->
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th ALIGN="RIGHT">UPS Model:</th>
|
||||||
|
<td>@VAR ups.model@</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th ALIGN="RIGHT">Status:</th>
|
||||||
|
<td>@STATUS@</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@IFSUPP battery.runtime@
|
||||||
|
<tr>
|
||||||
|
<th ALIGN="RIGHT">Runtime:</th>
|
||||||
|
<td>@RUNTIME@</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP ups.temperature@
|
||||||
|
<tr>
|
||||||
|
<th ALIGN="RIGHT">UPS temp:</th>
|
||||||
|
<td>@UPSTEMP@ @DEGREES@</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP battery.voltage@
|
||||||
|
<tr>
|
||||||
|
<th ALIGN="RIGHT">Battery: </th>
|
||||||
|
<td>@VAR battery.voltage@ V@IFSUPP battery.current@, @VAR battery.current@ A</td>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th VALIGN="TOP" ALIGN="RIGHT">Input: </th>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
|
||||||
|
@IFSUPP input.L2-L3.voltage@
|
||||||
|
@VAR input.L1-L2.voltage@ V<br>
|
||||||
|
@VAR input.L2-L3.voltage@ V<br>
|
||||||
|
@VAR input.L3-L1.voltage@ V<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.L2-N.voltage@
|
||||||
|
@VAR input.L1-N.voltage@ V<br>
|
||||||
|
@VAR input.L2-N.voltage@ V<br>
|
||||||
|
@VAR input.L3-N.voltage@ V<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.voltage@
|
||||||
|
@VAR input.voltage@ V<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP input.L2.current@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR input.L1.current@ A<br>
|
||||||
|
@VAR input.L2.current@ A<br>
|
||||||
|
@VAR input.L3.current@ A<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.current@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR input.current@ A
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP input.frequency@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR input.frequency@ Hz
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<th VALIGN="TOP" ALIGN="RIGHT">Output: </th>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
@IFSUPP output.L2-L3.voltage@
|
||||||
|
@VAR output.L1-L2.voltage@ V<br>
|
||||||
|
@VAR output.L2-L3.voltage@ V<br>
|
||||||
|
@VAR output.L3-L1.voltage@ V<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.L2-N.voltage@
|
||||||
|
@VAR output.L1-N.voltage@ V<br>
|
||||||
|
@VAR output.L2-N.voltage@ V<br>
|
||||||
|
@VAR output.L3-N.voltage@ V<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.voltage@
|
||||||
|
@VAR output.voltage@ V
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP output.L2.current@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR output.L1.current@ A<br>
|
||||||
|
@VAR output.L2.current@ A<br>
|
||||||
|
@VAR output.L3.current@ A<br>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.current@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR output.current@ A
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP output.frequency@
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<td>
|
||||||
|
@VAR output.frequency@ Hz
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
</table> <!-- table 2 -->
|
||||||
|
</td>
|
||||||
|
|
||||||
|
@IFSUPP ambient.temperature@
|
||||||
|
@IFSUPP ambient.humidity@
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
<td ALIGN="CENTER">Temperature<br>@IMG ambient.temperature tempmin=0 tempmax=50 width=90@</td>
|
||||||
|
<td ALIGN="CENTER">Humidity<br>@IMG ambient.humidity width=90@</td>
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP ambient.temperature@
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
<td ALIGN="CENTER">Temperature<br>@IMG ambient.temperature tempmin=0 tempmax=50@</td>
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP ambient.humidity@
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
<td ALIGN="CENTER">Humidity<br>@IMG ambient.humidity@</td>
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
@IFSUPP battery.charge@
|
||||||
|
@IFSUPP battery.voltage@
|
||||||
|
<td ALIGN="CENTER">Charge<br>@IMG battery.charge width=90@</td>
|
||||||
|
<td ALIGN="CENTER">Voltage<br>@IMG battery.voltage width=90@</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP battery.charge@
|
||||||
|
<td ALIGN="CENTER">Charge<br>@IMG battery.charge@</td>
|
||||||
|
@ELSE@
|
||||||
|
<td ALIGN="CENTER">Voltage<br>@IMG battery.voltage@</td>
|
||||||
|
@ENDIF@
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
@IFSUPP input.L2-L3.voltage@
|
||||||
|
<td ALIGN="CENTER">L1-L2<br>@IMG input.L1-L2.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2-L3<br>@IMG input.L2-L3.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3-L1<br>@IMG input.L3-L1.voltage width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.L2-N.voltage@
|
||||||
|
<td ALIGN="CENTER">L1-N<br>@IMG input.L1-N.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2-N<br>@IMG input.L2-N.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3-N<br>@IMG input.L3-N.voltage width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
<td ALIGN="CENTER"><br>@IMG input.voltage@</td>
|
||||||
|
@ENDIF@
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
@IFSUPP output.L2-L3.voltage@
|
||||||
|
<td ALIGN="CENTER">L1-L2<br>@IMG output.L1-L2.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2-L3<br>@IMG output.L2-L3.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3-L1<br>@IMG output.L3-L1.voltage width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.L2-N.voltage@
|
||||||
|
<td ALIGN="CENTER">L1-N<br>@IMG output.L1-N.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2-N<br>@IMG output.L2-N.voltage width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3-N<br>@IMG output.L3-N.voltage width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
<td ALIGN="CENTER"><br>@IMG output.voltage@</td>
|
||||||
|
@ENDIF@
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td ALIGN="CENTER" VALIGN="TOP">
|
||||||
|
<table BORDER="0"><tr>
|
||||||
|
@IFSUPP output.L2.power.percent@
|
||||||
|
<td ALIGN="CENTER">L1<br>@IMG output.L1.power.percent width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2<br>@IMG output.L2.power.percent width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3<br>@IMG output.L3.power.percent width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.L2.realpower.percent@
|
||||||
|
<td ALIGN="CENTER">L1<br>@IMG output.L1.realpower.percent width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L2<br>@IMG output.L2.realpower.percent width=68@</td>
|
||||||
|
<td ALIGN="CENTER">L3<br>@IMG output.L3.realpower.percent width=68@</td>
|
||||||
|
@ELSE@
|
||||||
|
<td ALIGN="CENTER"><br>@IMG ups.load@</td>
|
||||||
|
@ENDIF@
|
||||||
|
</tr></table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<div><a href="https://jigsaw.w3.org/css-validator/check/referer"><img
|
||||||
|
style="float:right" src="https://jigsaw.w3.org/css-validator/images/vcss"
|
||||||
|
alt="Valid CSS" title="Valid CSS" height="31" width="88"></a>
|
||||||
|
<a href="https://validator.w3.org/check?uri=referer"><img
|
||||||
|
style="float:right" src="https://www.w3.org/Icons/valid-html401"
|
||||||
|
alt="Valid HTML 4.01 Strict" title="Valid HTML 4.01 Strict"
|
||||||
|
height="31" width="88"></a></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
196
conf/upsstats.html.sample
Normal file
196
conf/upsstats.html.sample
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
<!-- upsstats template file -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This (upsstats.html) is the default template file which is used
|
||||||
|
when upsstats.cgi is loaded with no arguments.
|
||||||
|
|
||||||
|
It usually contains a FOREACHUPS block to iterate through every
|
||||||
|
UPS in the hosts.conf.
|
||||||
|
|
||||||
|
See upsstats.html(5) for more information on template files.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- change this to TEMPF if you don't like Celsius. -->
|
||||||
|
|
||||||
|
@TEMPC@
|
||||||
|
@UPSSTATSPATH upsstats.cgi@
|
||||||
|
@UPSIMAGEPATH upsimage.cgi@
|
||||||
|
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||||
|
"http://www.w3.org/TR/html4/strict.dtd">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
@REFRESH@
|
||||||
|
<title>
|
||||||
|
Network UPS Tools upsstats
|
||||||
|
@VERSION@
|
||||||
|
: UPS Status
|
||||||
|
</title>
|
||||||
|
<style type="text/css">
|
||||||
|
body{font-family:"Times New Roman", Times, serif;}
|
||||||
|
a:link{color:#00e;}
|
||||||
|
a:visited{color:#551a8b;}
|
||||||
|
th, td{padding:0.5ex;}
|
||||||
|
.t1{background:#0ff;}
|
||||||
|
.t2{background:#0f0;}
|
||||||
|
</style>
|
||||||
|
<!-- link rel="stylesheet" type="text/css" href="nut.css" / -->
|
||||||
|
@REFRESH@
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<table style="margin:auto; background:#50A0A0; text-align:center;">
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th COLSPAN="10" style="background:#60B0B0;">
|
||||||
|
|
||||||
|
<span style="font-size:1.5em">Network UPS Tools upsstats
|
||||||
|
@VERSION@
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
@DATE %a %b %d %X %Z %Y@
|
||||||
|
</th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr style="background:#60B0B0;">
|
||||||
|
<th COLSPAN="1">System</th>
|
||||||
|
<th COLSPAN="1">Model</th>
|
||||||
|
<th COLSPAN="1">Status</th>
|
||||||
|
<th COLSPAN="1">Battery</th>
|
||||||
|
<th COLSPAN="1">Input (VAC)</th>
|
||||||
|
<th COLSPAN="1">Output (VAC)</th>
|
||||||
|
<th COLSPAN="1">Load (%)</th>
|
||||||
|
<th COLSPAN="1">UPS<br>Temp</th>
|
||||||
|
<th COLSPAN="1">Battery<br>Runtime</th>
|
||||||
|
<th COLSPAN="1">Data<br>Tree</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@FOREACHUPS@
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="t1">
|
||||||
|
@HOSTLINK@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t1">
|
||||||
|
@VAR ups.model@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td style="background:@STATUSCOLOR@">
|
||||||
|
@STATUS@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@IFSUPP battery.charge@
|
||||||
|
@VAR battery.charge@
|
||||||
|
%
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
@IFSUPP input.L2-L3.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L1-L2.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L2-L3.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L3-L1.voltage@
|
||||||
|
<td class="t2">
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.L2-N.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L1-N.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L2-N.voltage@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.L3-N.voltage@
|
||||||
|
<td class="t2">
|
||||||
|
@ELSE@
|
||||||
|
@IFBETWEEN input.transfer.low input.transfer.high input.voltage@
|
||||||
|
<td class="t2">
|
||||||
|
@ELSE@
|
||||||
|
<td style="background:red;">
|
||||||
|
@ENDIF@
|
||||||
|
|
||||||
|
@IFSUPP input.L2-L3.voltage@
|
||||||
|
@VAR input.L1-L2.voltage@
|
||||||
|
@VAR input.L2-L3.voltage@
|
||||||
|
@VAR input.L3-L1.voltage@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.L2-N.voltage@
|
||||||
|
@VAR input.L1-N.voltage@
|
||||||
|
@VAR input.L2-N.voltage@
|
||||||
|
@VAR input.L3-N.voltage@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP input.voltage@
|
||||||
|
@VAR input.voltage@
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@IFSUPP output.L2-L3.voltage@
|
||||||
|
@VAR output.L1-L2.voltage@
|
||||||
|
@VAR output.L2-L3.voltage@
|
||||||
|
@VAR output.L3-L1.voltage@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.L2-N.voltage@
|
||||||
|
@VAR output.L1-N.voltage@
|
||||||
|
@VAR output.L2-N.voltage@
|
||||||
|
@VAR output.L3-N.voltage@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.voltage@
|
||||||
|
@VAR output.voltage@
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@IFSUPP output.L2.power.percent@
|
||||||
|
@VAR output.L1.power.percent@
|
||||||
|
@VAR output.L2.power.percent@
|
||||||
|
@VAR output.L3.power.percent@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP output.L2.realpower.percent@
|
||||||
|
@VAR output.L1.realpower.percent@
|
||||||
|
@VAR output.L2.realpower.percent@
|
||||||
|
@VAR output.L3.realpower.percent@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP ups.load@
|
||||||
|
@VAR ups.load@
|
||||||
|
%
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@IFSUPP ups.temperature@
|
||||||
|
@UPSTEMP@
|
||||||
|
@DEGREES@
|
||||||
|
@ELSE@
|
||||||
|
@IFSUPP battery.temperature@
|
||||||
|
@BATTTEMP@
|
||||||
|
@DEGREES@
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@IFSUPP battery.runtime@
|
||||||
|
@RUNTIME@
|
||||||
|
@ENDIF@
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td class="t2">
|
||||||
|
@TREELINK@
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@ENDFOR@
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr><div><small>
|
||||||
|
<a href="https://jigsaw.w3.org/css-validator/check/referer"><img style="float:right" src="https://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88"></a>
|
||||||
|
<a href="https://validator.w3.org/check?uri=referer"><img style="float:right" src="https://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Strict" height="31" width="88"></a>
|
||||||
|
</small></div>
|
||||||
|
|
||||||
|
</body></html>
|
1480
config.guess
vendored
Executable file
1480
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
1801
config.sub
vendored
Executable file
1801
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
2969
configure.ac
Normal file
2969
configure.ac
Normal file
File diff suppressed because it is too large
Load diff
20
data/Makefile.am
Normal file
20
data/Makefile.am
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Network UPS Tools: data
|
||||||
|
|
||||||
|
SUBDIRS = html
|
||||||
|
|
||||||
|
dist_data_DATA = cmdvartab
|
||||||
|
nodist_data_DATA = driver.list
|
||||||
|
EXTRA_DIST = evolution500.seq epdu-managed.dev
|
||||||
|
|
||||||
|
# NOTE: Due to portability, we do not use a GNU percent-wildcard extension:
|
||||||
|
#%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
# $(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
cmdvartab-spellchecked: cmdvartab Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
spellcheck spellcheck-interactive spellcheck-sortdict:
|
||||||
|
$(MAKE) -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC="cmdvartab" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
CLEANFILES = *.pdf *.html *-spellchecked
|
842
data/Makefile.in
Normal file
842
data/Makefile.in
Normal file
|
@ -0,0 +1,842 @@
|
||||||
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994-2020 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@
|
||||||
|
|
||||||
|
# Network UPS Tools: data
|
||||||
|
|
||||||
|
VPATH = @srcdir@
|
||||||
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
am__make_running_with_option = \
|
||||||
|
case $${target_option-} in \
|
||||||
|
?) ;; \
|
||||||
|
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||||
|
"target option '$${target_option-}' specified" >&2; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
has_opt=no; \
|
||||||
|
sane_makeflags=$$MAKEFLAGS; \
|
||||||
|
if $(am__is_gnu_make); then \
|
||||||
|
sane_makeflags=$$MFLAGS; \
|
||||||
|
else \
|
||||||
|
case $$MAKEFLAGS in \
|
||||||
|
*\\[\ \ ]*) \
|
||||||
|
bs=\\; \
|
||||||
|
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||||
|
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||||
|
esac; \
|
||||||
|
fi; \
|
||||||
|
skip_next=no; \
|
||||||
|
strip_trailopt () \
|
||||||
|
{ \
|
||||||
|
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||||
|
}; \
|
||||||
|
for flg in $$sane_makeflags; do \
|
||||||
|
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||||
|
case $$flg in \
|
||||||
|
*=*|--*) continue;; \
|
||||||
|
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||||
|
-*I?*) strip_trailopt 'I';; \
|
||||||
|
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||||
|
-*O?*) strip_trailopt 'O';; \
|
||||||
|
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||||
|
-*l?*) strip_trailopt 'l';; \
|
||||||
|
-[dEDm]) skip_next=yes;; \
|
||||||
|
-[JT]) skip_next=yes;; \
|
||||||
|
esac; \
|
||||||
|
case $$flg in \
|
||||||
|
*$$target_option*) has_opt=yes; break;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
test $$has_opt = yes
|
||||||
|
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||||
|
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||||
|
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 = data
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_c_pragmas.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_compare_version.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_run_or_link_ifelse.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_cppcheck.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_headers_windows.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_libltdl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libpowerman.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_check_pkgconfig.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_python.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_compiler_family.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_stash_warnings.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(dist_data_DATA) \
|
||||||
|
$(am__DIST_COMMON)
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||||
|
CONFIG_CLEAN_FILES = driver.list
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
AM_V_P = $(am__v_P_@AM_V@)
|
||||||
|
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||||
|
am__v_P_0 = false
|
||||||
|
am__v_P_1 = :
|
||||||
|
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||||
|
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_GEN_1 =
|
||||||
|
AM_V_at = $(am__v_at_@AM_V@)
|
||||||
|
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||||
|
am__v_at_0 = @
|
||||||
|
am__v_at_1 =
|
||||||
|
SOURCES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||||
|
ctags-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 \
|
||||||
|
tags-recursive uninstall-recursive
|
||||||
|
am__can_run_installinfo = \
|
||||||
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
|
n|no|NO) false;; \
|
||||||
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
|
esac
|
||||||
|
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__uninstall_files_from_dir = { \
|
||||||
|
test -z "$$files" \
|
||||||
|
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||||
|
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||||
|
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||||
|
}
|
||||||
|
am__installdirs = "$(DESTDIR)$(datadir)" "$(DESTDIR)$(datadir)"
|
||||||
|
DATA = $(dist_data_DATA) $(nodist_data_DATA)
|
||||||
|
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||||
|
distclean-recursive maintainer-clean-recursive
|
||||||
|
am__recursive_targets = \
|
||||||
|
$(RECURSIVE_TARGETS) \
|
||||||
|
$(RECURSIVE_CLEAN_TARGETS) \
|
||||||
|
$(am__extra_recursive_targets)
|
||||||
|
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||||
|
distdir distdir-am
|
||||||
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
|
# Read a list of newline-separated strings from the standard input,
|
||||||
|
# and print each of them once, without duplicates. Input order is
|
||||||
|
# *not* preserved.
|
||||||
|
am__uniquify_input = $(AWK) '\
|
||||||
|
BEGIN { nonempty = 0; } \
|
||||||
|
{ items[$$0] = 1; nonempty = 1; } \
|
||||||
|
END { if (nonempty) { for (i in items) print i; }; } \
|
||||||
|
'
|
||||||
|
# Make sure the list of sources is unique. This is necessary because,
|
||||||
|
# e.g., the same source file might be shared among _SOURCES variables
|
||||||
|
# for different programs/libraries.
|
||||||
|
am__define_uniq_tagged_files = \
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | $(am__uniquify_input)`
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/driver.list.in
|
||||||
|
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@
|
||||||
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
AR = @AR@
|
||||||
|
ASCIIDOC = @ASCIIDOC@
|
||||||
|
ASPELL = @ASPELL@
|
||||||
|
AUGPARSE = @AUGPARSE@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
BINDIR = @BINDIR@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CONFPATH = @CONFPATH@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPCHECK = @CPPCHECK@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
|
||||||
|
CPPUNIT_LIBS = @CPPUNIT_LIBS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DBLATEX = @DBLATEX@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
||||||
|
DOC_CHECK_LIST = @DOC_CHECK_LIST@
|
||||||
|
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||||
|
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||||
|
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||||
|
DRVPATH = @DRVPATH@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
GDLIB_CONFIG = @GDLIB_CONFIG@
|
||||||
|
GREP = @GREP@
|
||||||
|
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@
|
||||||
|
LIBDIR = @LIBDIR@
|
||||||
|
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||||
|
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||||
|
LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
|
||||||
|
LIBIPMI_LIBS = @LIBIPMI_LIBS@
|
||||||
|
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
|
||||||
|
LIBLTDL_LIBS = @LIBLTDL_LIBS@
|
||||||
|
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
|
||||||
|
LIBMODBUS_LIBS = @LIBMODBUS_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@
|
||||||
|
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||||
|
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||||
|
LIBUSB_CONFIG = @LIBUSB_CONFIG@
|
||||||
|
LIBUSB_LIBS = @LIBUSB_LIBS@
|
||||||
|
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||||
|
LIBWRAP_LIBS = @LIBWRAP_LIBS@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LN_S_R = @LN_S_R@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NETLIBS = @NETLIBS@
|
||||||
|
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
NUT_DATADIR = @NUT_DATADIR@
|
||||||
|
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
|
||||||
|
NUT_NETVERSION = @NUT_NETVERSION@
|
||||||
|
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@
|
||||||
|
PIDPATH = @PIDPATH@
|
||||||
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
PORT = @PORT@
|
||||||
|
PYTHON = @PYTHON@
|
||||||
|
PYTHON2 = @PYTHON2@
|
||||||
|
PYTHON3 = @PYTHON3@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||||
|
RUN_AS_USER = @RUN_AS_USER@
|
||||||
|
SBINDIR = @SBINDIR@
|
||||||
|
SED = @SED@
|
||||||
|
SERLIBS = @SERLIBS@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SOURCE_HIGHLIGHT = @SOURCE_HIGHLIGHT@
|
||||||
|
STATEPATH = @STATEPATH@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
SUN_LIBUSB = @SUN_LIBUSB@
|
||||||
|
TREE_VERSION = @TREE_VERSION@
|
||||||
|
VALGRIND = @VALGRIND@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||||
|
XMLLINT = @XMLLINT@
|
||||||
|
XSLTPROC = @XSLTPROC@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_AR = @ac_ct_AR@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
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@
|
||||||
|
auglensdir = @auglensdir@
|
||||||
|
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@
|
||||||
|
devddir = @devddir@
|
||||||
|
docdir = @docdir@
|
||||||
|
driverexecdir = @driverexecdir@
|
||||||
|
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
|
||||||
|
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
|
||||||
|
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
|
||||||
|
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@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
now = @now@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
runstatedir = @runstatedir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
systemdshutdowndir = @systemdshutdowndir@
|
||||||
|
systemdsystemunitdir = @systemdsystemunitdir@
|
||||||
|
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||||
|
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@
|
||||||
|
SUBDIRS = html
|
||||||
|
dist_data_DATA = cmdvartab
|
||||||
|
nodist_data_DATA = driver.list
|
||||||
|
EXTRA_DIST = evolution500.seq epdu-managed.dev
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
CLEANFILES = *.pdf *.html *-spellchecked
|
||||||
|
all: all-recursive
|
||||||
|
|
||||||
|
.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 data/Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnu data/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__maybe_remake_depfiles)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
|
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):
|
||||||
|
driver.list: $(top_builddir)/config.status $(srcdir)/driver.list.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
install-dist_dataDATA: $(dist_data_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(datadir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-dist_dataDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(dist_data_DATA)'; test -n "$(datadir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir)
|
||||||
|
install-nodist_dataDATA: $(nodist_data_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(nodist_data_DATA)'; test -n "$(datadir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(datadir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(datadir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(datadir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-nodist_dataDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(nodist_data_DATA)'; test -n "$(datadir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(datadir)'; $(am__uninstall_files_from_dir)
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
$(am__recursive_targets):
|
||||||
|
@fail=; \
|
||||||
|
if $(am__make_keepgoing); then \
|
||||||
|
failcom='fail=yes'; \
|
||||||
|
else \
|
||||||
|
failcom='exit 1'; \
|
||||||
|
fi; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
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"
|
||||||
|
|
||||||
|
ID: $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||||
|
tags: tags-recursive
|
||||||
|
TAGS: tags
|
||||||
|
|
||||||
|
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
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; \
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
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-recursive
|
||||||
|
|
||||||
|
CTAGS: ctags
|
||||||
|
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||||
|
$(am__define_uniq_tagged_files); \
|
||||||
|
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"
|
||||||
|
cscopelist: cscopelist-recursive
|
||||||
|
|
||||||
|
cscopelist-am: $(am__tagged_files)
|
||||||
|
list='$(am__tagged_files)'; \
|
||||||
|
case "$(srcdir)" in \
|
||||||
|
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||||
|
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||||
|
esac; \
|
||||||
|
for i in $$list; do \
|
||||||
|
if test -f "$$i"; then \
|
||||||
|
echo "$(subdir)/$$i"; \
|
||||||
|
else \
|
||||||
|
echo "$$sdir/$$i"; \
|
||||||
|
fi; \
|
||||||
|
done >> $(top_builddir)/cscope.files
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
distdir: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
distdir-am: $(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
|
||||||
|
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
$(am__make_dryrun) \
|
||||||
|
|| test -d "$(distdir)/$$subdir" \
|
||||||
|
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||||
|
|| exit 1; \
|
||||||
|
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
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile $(DATA)
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
for dir in "$(DESTDIR)$(datadir)" "$(DESTDIR)$(datadir)"; do \
|
||||||
|
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||||
|
done
|
||||||
|
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-recursive
|
||||||
|
install-strip:
|
||||||
|
if test -z '$(STRIP)'; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
install; \
|
||||||
|
else \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||||
|
fi
|
||||||
|
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 "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-generic distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-recursive
|
||||||
|
|
||||||
|
html-am:
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am: install-dist_dataDATA install-nodist_dataDATA
|
||||||
|
|
||||||
|
install-dvi: install-dvi-recursive
|
||||||
|
|
||||||
|
install-dvi-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-html: install-html-recursive
|
||||||
|
|
||||||
|
install-html-am:
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-info-am:
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
install-pdf: install-pdf-recursive
|
||||||
|
|
||||||
|
install-pdf-am:
|
||||||
|
|
||||||
|
install-ps: install-ps-recursive
|
||||||
|
|
||||||
|
install-ps-am:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-recursive
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-recursive
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am: uninstall-dist_dataDATA uninstall-nodist_dataDATA
|
||||||
|
|
||||||
|
.MAKE: $(am__recursive_targets) install-am install-strip
|
||||||
|
|
||||||
|
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||||
|
check-am clean clean-generic clean-libtool cscopelist-am ctags \
|
||||||
|
ctags-am 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-dist_dataDATA install-dvi install-dvi-am install-exec \
|
||||||
|
install-exec-am install-html install-html-am install-info \
|
||||||
|
install-info-am install-man install-nodist_dataDATA \
|
||||||
|
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-am uninstall uninstall-am \
|
||||||
|
uninstall-dist_dataDATA uninstall-nodist_dataDATA
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: Due to portability, we do not use a GNU percent-wildcard extension:
|
||||||
|
#%-spellchecked: % Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
# $(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
cmdvartab-spellchecked: cmdvartab Makefile.am $(top_srcdir)/docs/Makefile.am $(abs_srcdir)/$(NUT_SPELL_DICT)
|
||||||
|
$(MAKE) -s -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC_ONE="$<" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
spellcheck spellcheck-interactive spellcheck-sortdict:
|
||||||
|
$(MAKE) -f $(top_builddir)/docs/Makefile SPELLCHECK_SRC="cmdvartab" SPELLCHECK_DIR="$(srcdir)" $@
|
||||||
|
|
||||||
|
# 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:
|
236
data/cmdvartab
Normal file
236
data/cmdvartab
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
# Network UPS Tools: variable and command descriptions
|
||||||
|
#
|
||||||
|
# This file is optional. You may delete it to save resources, but
|
||||||
|
# clients will receive "Unavailable" for any description requests.
|
||||||
|
#
|
||||||
|
# *** NOTE *** : When updating this file, also update docs/nut-names.txt
|
||||||
|
|
||||||
|
VARDESC ups.alarm "UPS alarms"
|
||||||
|
VARDESC ups.status "UPS status"
|
||||||
|
VARDESC ups.time "Internal UPS clock time"
|
||||||
|
VARDESC ups.date "Internal UPS clock date"
|
||||||
|
VARDESC ups.efficiency "Efficiency of the UPS"
|
||||||
|
VARDESC ups.model "UPS model"
|
||||||
|
VARDESC ups.mfr "UPS manufacturer"
|
||||||
|
VARDESC ups.mfr.date "UPS manufacturing date"
|
||||||
|
VARDESC ups.serial "UPS serial number"
|
||||||
|
VARDESC ups.vendorid "Vendor ID for USB devices"
|
||||||
|
VARDESC ups.productid "Product ID for USB devices"
|
||||||
|
VARDESC ups.firmware "UPS firmware"
|
||||||
|
VARDESC ups.firmware.aux "Auxiliary device firmware"
|
||||||
|
VARDESC ups.temperature "UPS temperature (degrees C)"
|
||||||
|
VARDESC ups.load "Load on UPS (percent of full)"
|
||||||
|
VARDESC ups.load.energysave "Load on UPS that triggers energysave (percent)"
|
||||||
|
VARDESC ups.load.high "Load when UPS switches to overload condition (percent)"
|
||||||
|
VARDESC ups.id "UPS system identifier"
|
||||||
|
VARDESC ups.delay.start "Interval to wait before (re)starting the load (seconds)"
|
||||||
|
VARDESC ups.delay.reboot "Interval to wait before rebooting the UPS (seconds)"
|
||||||
|
VARDESC ups.delay.shutdown "Interval to wait after shutdown with delay command (seconds)"
|
||||||
|
VARDESC ups.timer.start "Time before the load will be started (seconds)"
|
||||||
|
VARDESC ups.timer.reboot "Time before the load will be rebooted (seconds)"
|
||||||
|
VARDESC ups.timer.shutdown "Time before the load will be shutdown (seconds)"
|
||||||
|
VARDESC ups.test.interval "Interval between self tests (seconds)"
|
||||||
|
VARDESC ups.test.result "Results of last self test"
|
||||||
|
VARDESC ups.display.language "Language to use on front panel"
|
||||||
|
VARDESC ups.contacts "UPS external contact sensors"
|
||||||
|
VARDESC ups.power "Current value of apparent power (VA)"
|
||||||
|
VARDESC ups.power.nominal "UPS power rating (VA)"
|
||||||
|
VARDESC ups.realpower "Current value of real power (W)"
|
||||||
|
VARDESC ups.realpower.nominal "UPS real power rating (W)"
|
||||||
|
VARDESC ups.beeper.status "UPS beeper status"
|
||||||
|
VARDESC ups.type "UPS type"
|
||||||
|
VARDESC ups.start.auto "UPS starts when mains is (re)applied"
|
||||||
|
VARDESC ups.start.battery "Allow to start UPS from battery"
|
||||||
|
VARDESC ups.start.reboot "UPS reboots when power returns during shutdown delay"
|
||||||
|
|
||||||
|
VARDESC input.voltage "Input voltage (V)"
|
||||||
|
VARDESC input.voltage.extended "Extended input voltage range"
|
||||||
|
VARDESC input.voltage.maximum "Maximum incoming voltage seen (V)"
|
||||||
|
VARDESC input.voltage.minimum "Minimum incoming voltage seen (V)"
|
||||||
|
VARDESC input.voltage.status "Voltage status relative to the thresholds"
|
||||||
|
VARDESC input.voltage.low.warning "Input voltage low warning threshold (V)"
|
||||||
|
VARDESC input.voltage.low.critical "Input voltage low critical threshold (V)"
|
||||||
|
VARDESC input.voltage.high.warning "Input voltage high warning threshold (V)"
|
||||||
|
VARDESC input.voltage.high.critical "Input voltage high critical threshold (V)"
|
||||||
|
VARDESC input.voltage.nominal "Nominal input voltage (V)"
|
||||||
|
VARDESC input.transfer.reason "Reason for last transfer to battery"
|
||||||
|
VARDESC input.transfer.low "Low voltage transfer point (V)"
|
||||||
|
VARDESC input.transfer.high "High voltage transfer point (V)"
|
||||||
|
VARDESC input.transfer.low.min "smallest settable low voltage transfer point (V)"
|
||||||
|
VARDESC input.transfer.low.max "greatest settable low voltage transfer point (V)"
|
||||||
|
VARDESC input.transfer.high.min "smallest settable high voltage transfer point (V)"
|
||||||
|
VARDESC input.transfer.high.max "greatest settable high voltage transfer point (V)"
|
||||||
|
VARDESC input.sensitivity "Input power sensitivity"
|
||||||
|
VARDESC input.quality "Input power quality"
|
||||||
|
VARDESC input.current "Input current (A)"
|
||||||
|
VARDESC input.current.nominal "Nominal input current (A)"
|
||||||
|
VARDESC input.current.status "Current status relative to the thresholds"
|
||||||
|
VARDESC input.current.low.warning "Input current low warning threshold (A)"
|
||||||
|
VARDESC input.current.low.critical "Input current low critical threshold (A)"
|
||||||
|
VARDESC input.current.high.warning "Input current high warning threshold (A)"
|
||||||
|
VARDESC input.current.high.critical "Input current high critical threshold (A)"
|
||||||
|
VARDESC input.frequency "Input line frequency (Hz)"
|
||||||
|
VARDESC input.frequency.extended "Extended input frequency range"
|
||||||
|
VARDESC input.frequency.status "Frequency status"
|
||||||
|
VARDESC input.frequency.nominal "Nominal input line frequency (Hz)"
|
||||||
|
VARDESC input.frequency.low "Minimum input line frequency (Hz)"
|
||||||
|
VARDESC input.frequency.high "Maximum input line frequency (Hz)"
|
||||||
|
VARDESC input.transfer.boost.low "Low voltage boosting transfer point (V)"
|
||||||
|
VARDESC input.transfer.boost.high "High voltage boosting transfer point (V)"
|
||||||
|
VARDESC input.transfer.trim.low "Low voltage trimming transfer point (V)"
|
||||||
|
VARDESC input.transfer.trim.high "High voltage trimming transfer point (V)"
|
||||||
|
VARDESC input.transfer.delay "Delay before transfer to mains"
|
||||||
|
VARDESC input.load "Load on (ePDU) input (percent of full)"
|
||||||
|
VARDESC input.realpower "Current sum value of all (ePDU) phases real power (W)"
|
||||||
|
VARDESC input.power "Current sum value of all (ePDU) phases apparent power (VA)"
|
||||||
|
VARDESC input.source "The current input power source"
|
||||||
|
VARDESC input.source.preferred "The preferred input power source"
|
||||||
|
|
||||||
|
VARDESC output.voltage "Output voltage (V)"
|
||||||
|
VARDESC output.voltage.nominal "Nominal output voltage (V)"
|
||||||
|
VARDESC output.frequency "Output frequency (Hz)"
|
||||||
|
VARDESC output.frequency.nominal "Nominal output frequency (Hz)"
|
||||||
|
VARDESC output.current "Output current (A)"
|
||||||
|
VARDESC output.current.nominal "Nominal output current (A)"
|
||||||
|
|
||||||
|
VARDESC battery.charge "Battery charge (percent of full)"
|
||||||
|
VARDESC battery.charge.approx "Rough approximation of battery charge"
|
||||||
|
VARDESC battery.charge.low "Remaining battery level when UPS switches to LB (percent)"
|
||||||
|
VARDESC battery.charge.restart "Minimum battery level for restart after power off (percent)"
|
||||||
|
VARDESC battery.charge.warning "Battery level when UPS switches to Warning state (percent)"
|
||||||
|
VARDESC battery.voltage "Battery voltage (V)"
|
||||||
|
VARDESC battery.current "Battery current (A)"
|
||||||
|
VARDESC battery.capacity "Battery capacity (Ah)"
|
||||||
|
VARDESC battery.temperature "Battery temperature (degrees C)"
|
||||||
|
VARDESC battery.voltage.nominal "Nominal battery voltage (V)"
|
||||||
|
VARDESC battery.runtime "Battery runtime (seconds)"
|
||||||
|
VARDESC battery.runtime.low "Remaining battery runtime when UPS switches to LB (seconds)"
|
||||||
|
VARDESC battery.alarm.threshold "Battery alarm threshold"
|
||||||
|
VARDESC battery.date "Battery change date"
|
||||||
|
VARDESC battery.mfr.date "Battery manufacturing date"
|
||||||
|
VARDESC battery.packs "Number of battery packs"
|
||||||
|
VARDESC battery.packs.bad "Number of bad battery packs"
|
||||||
|
VARDESC battery.type "Battery chemistry"
|
||||||
|
VARDESC battery.protection "Prevent deep discharge of battery"
|
||||||
|
VARDESC battery.energysave "Switch off when running on battery and no/low load"
|
||||||
|
VARDESC battery.energysave.load "Switch off UPS if on battery and load level lower (percent)"
|
||||||
|
VARDESC battery.energysave.delay "Delay before switch off UPS if on battery and load level low (min)"
|
||||||
|
VARDESC battery.energysave.realpower "Switch off UPS if on battery and load level lower (Watts)"
|
||||||
|
VARDESC battery.charger.status "Battery charger status"
|
||||||
|
|
||||||
|
VARDESC ambient.temperature "Ambient temperature (degrees C)"
|
||||||
|
VARDESC ambient.temperature.alarm "Ambient temperature alarm is active"
|
||||||
|
VARDESC ambient.temperature.status "Ambient temperature status relative to the configured thresholds"
|
||||||
|
VARDESC ambient.temperature.alarm.maximum "Maximum allowed ambient temperature (degrees C)"
|
||||||
|
VARDESC ambient.temperature.alarm.minimum "Minimum allowed ambient temperature (degrees C)"
|
||||||
|
VARDESC ambient.temperature.alarm.enable "Enable ambient temperature alarm"
|
||||||
|
VARDESC ambient.temperature.low "Temperature threshold low (degrees C)"
|
||||||
|
VARDESC ambient.temperature.low.warning "Temperature threshold low warning (degrees C)"
|
||||||
|
VARDESC ambient.temperature.low.critical "Temperature threshold low critical (degrees C)"
|
||||||
|
VARDESC ambient.temperature.high "Temperature threshold high (degrees C)"
|
||||||
|
VARDESC ambient.temperature.high.warning "Temperature threshold high warning (degrees C)"
|
||||||
|
VARDESC ambient.temperature.high.critical "Temperature threshold high critical (degrees C)"
|
||||||
|
VARDESC ambient.humidity "Ambient humidity (percent)"
|
||||||
|
VARDESC ambient.humidity.alarm "Ambient humidity alarm is active"
|
||||||
|
VARDESC ambient.humidity.status "Ambient humidity status relative to the configured thresholds"
|
||||||
|
VARDESC ambient.humidity.alarm.maximum "Maximum allowed ambient humidity (percent)"
|
||||||
|
VARDESC ambient.humidity.alarm.minimum "Minimum allowed ambient humidity (percent)"
|
||||||
|
VARDESC ambient.humidity.alarm.enable "Enable ambient humidity alarm"
|
||||||
|
VARDESC ambient.humidity.low "Ambient humidity threshold low (percent)"
|
||||||
|
VARDESC ambient.humidity.low.warning "Ambient humidity threshold low warning (percent)"
|
||||||
|
VARDESC ambient.humidity.low.critical "Ambient humidity threshold low critical (percent)"
|
||||||
|
VARDESC ambient.humidity.high "Ambient humidity threshold high (percent)"
|
||||||
|
VARDESC ambient.humidity.high.warning "Ambient humidity threshold high warning (percent)"
|
||||||
|
VARDESC ambient.humidity.high.critical "Ambient humidity threshold high critical (percent)"
|
||||||
|
VARDESC ambient.present "Ambient sensor presence"
|
||||||
|
VARDESC ambient.contacts.1.status "State of the dry contact sensor 1"
|
||||||
|
VARDESC ambient.contacts.2.status "State of the dry contact sensor 2"
|
||||||
|
|
||||||
|
# FIXME: the outlet collection is indexed - solve with regexps?
|
||||||
|
#
|
||||||
|
# VARDESC outlet.[[:digit:]]+.id "Outlet system identifier (<index>)"
|
||||||
|
|
||||||
|
VARDESC outlet.id "Outlet system identifier"
|
||||||
|
VARDESC outlet.desc "Outlet description"
|
||||||
|
VARDESC outlet.switch "Outlet switch control"
|
||||||
|
VARDESC outlet.status "Outlet switch status"
|
||||||
|
VARDESC outlet.switchable "Outlet switch ability"
|
||||||
|
VARDESC outlet.autoswitch.charge.low "Remaining battery level to power off this outlet (percent)"
|
||||||
|
VARDESC outlet.delay.shutdown "Interval to wait before shutting down this outlet (seconds)"
|
||||||
|
VARDESC outlet.delay.start "Interval to wait before restarting this outlet (seconds)"
|
||||||
|
VARDESC outlet.1.id "Outlet system identifier"
|
||||||
|
VARDESC outlet.1.desc "Outlet description"
|
||||||
|
VARDESC outlet.1.switch "Outlet switch control"
|
||||||
|
VARDESC outlet.1.status "Outlet switch status"
|
||||||
|
VARDESC outlet.1.switchable "Outlet switch ability"
|
||||||
|
VARDESC outlet.1.autoswitch.charge.low "Remaining battery level to power off this outlet (percent)"
|
||||||
|
VARDESC outlet.1.delay.shutdown "Interval to wait before shutting down this outlet (seconds)"
|
||||||
|
VARDESC outlet.1.delay.start "Interval to wait before restarting this outlet (seconds)"
|
||||||
|
VARDESC outlet.2.id "Outlet system identifier"
|
||||||
|
VARDESC outlet.2.desc "Outlet description"
|
||||||
|
VARDESC outlet.2.switch "Outlet switch control"
|
||||||
|
VARDESC outlet.2.status "Outlet switch status"
|
||||||
|
VARDESC outlet.2.switchable "Outlet switch ability"
|
||||||
|
VARDESC outlet.2.autoswitch.charge.low "Remaining battery level to power off this outlet (percent)"
|
||||||
|
VARDESC outlet.2.delay.shutdown "Interval to wait before shutting down this outlet (seconds)"
|
||||||
|
VARDESC outlet.2.delay.start "Interval to wait before restarting this outlet (seconds)"
|
||||||
|
|
||||||
|
VARDESC driver.name "Driver name"
|
||||||
|
VARDESC driver.version "Driver version - NUT release"
|
||||||
|
VARDESC driver.version.internal "Internal driver version"
|
||||||
|
VARDESC driver.version.usb "USB library version"
|
||||||
|
|
||||||
|
VARDESC device.part "Device Part Number"
|
||||||
|
|
||||||
|
# FIXME: driver.parameter and driver.flag can have many possible members
|
||||||
|
#
|
||||||
|
# VARDESC driver.parameter.[[:alpha:]]+ "Driver parameter: <name>"
|
||||||
|
# VARDESC driver.flag.[[:alpha:]]+ "Driver flag: <name>"
|
||||||
|
|
||||||
|
VARDESC server.info "Server information"
|
||||||
|
VARDESC server.version "Server version"
|
||||||
|
|
||||||
|
CMDDESC load.off "Turn off the load immediately"
|
||||||
|
CMDDESC load.on "Turn on the load immediately"
|
||||||
|
CMDDESC shutdown.return "Turn off the load and return when power is back"
|
||||||
|
CMDDESC shutdown.stayoff "Turn off the load and remain off"
|
||||||
|
CMDDESC shutdown.stop "Stop a shutdown in progress"
|
||||||
|
CMDDESC shutdown.reboot "Shut down the load briefly while rebooting the UPS"
|
||||||
|
CMDDESC shutdown.reboot.graceful "Delay briefly then shut down the load while rebooting the UPS"
|
||||||
|
CMDDESC test.panel.start "Start testing the UPS panel"
|
||||||
|
CMDDESC test.panel.stop "Stop a UPS panel test"
|
||||||
|
CMDDESC test.failure.start "Start a simulated power failure"
|
||||||
|
CMDDESC test.failure.stop "Stop simulating a power failure"
|
||||||
|
CMDDESC test.battery.start "Start a battery test"
|
||||||
|
CMDDESC test.battery.start.quick "Start a quick battery test"
|
||||||
|
CMDDESC test.battery.start.deep "Start a deep battery test"
|
||||||
|
CMDDESC test.battery.stop "Stop the battery test"
|
||||||
|
CMDDESC test.system.start "Start a system test"
|
||||||
|
CMDDESC calibrate.start "Start run time calibration"
|
||||||
|
CMDDESC calibrate.stop "Stop run time calibration"
|
||||||
|
CMDDESC bypass.start "Put the UPS in bypass mode"
|
||||||
|
CMDDESC bypass.stop "Take the UPS out of bypass mode"
|
||||||
|
CMDDESC reset.input.minmax "Reset minimum and maximum input voltage status"
|
||||||
|
CMDDESC reset.watchdog "Reset watchdog timer"
|
||||||
|
CMDDESC beeper.on "Obsolete (use beeper.enable)"
|
||||||
|
CMDDESC beeper.off "Obsolete (use beeper.disable or beeper.mute)"
|
||||||
|
CMDDESC beeper.enable "Enable the UPS beeper"
|
||||||
|
CMDDESC beeper.disable "Disable the UPS beeper"
|
||||||
|
CMDDESC beeper.mute "Temporarily mute the UPS beeper"
|
||||||
|
CMDDESC beeper.toggle "Toggle the UPS beeper"
|
||||||
|
CMDDESC outlet.1.load.off "Turn off the load on outlet 1 immediately"
|
||||||
|
CMDDESC outlet.1.load.on "Turn on the load on outlet 1 immediately"
|
||||||
|
CMDDESC outlet.1.shutdown.return "Turn off the outlet 1 and return when power is back"
|
||||||
|
CMDDESC outlet.2.load.off "Turn off the load on outlet 2 immediately"
|
||||||
|
CMDDESC outlet.2.load.on "Turn on the load on outlet 2 immediately"
|
||||||
|
CMDDESC outlet.2.shutdown.return "Turn off the outlet 2 and return when power is back"
|
||||||
|
|
||||||
|
# The following two commands should *only* be defined when you need
|
||||||
|
# to compose a 'shutdown.return' command by sending both a switch-off
|
||||||
|
# with delay and a switch-on with delay command to the UPS. If this
|
||||||
|
# can be done with a single command, use 'shutdown.return' instead.
|
||||||
|
# Note that the switch-on with delay command *must not* turn on the
|
||||||
|
# load if the UPS is on battery.
|
||||||
|
#
|
||||||
|
CMDDESC load.off.delay "Turn off the load with a delay (seconds)"
|
||||||
|
CMDDESC load.on.delay "Turn on the load with a delay (seconds)"
|
1351
data/driver.list.in
Normal file
1351
data/driver.list.in
Normal file
File diff suppressed because it is too large
Load diff
70
data/epdu-managed.dev
Normal file
70
data/epdu-managed.dev
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
# dummy-ups example device definition file
|
||||||
|
#
|
||||||
|
# Generated using:
|
||||||
|
# $ upsc ups@host > epdu-managed.dev
|
||||||
|
|
||||||
|
device.mfr: EATON | Powerware
|
||||||
|
device.model: DBQ10634/5
|
||||||
|
device.serial: ADO6750531
|
||||||
|
device.type: pdu
|
||||||
|
driver.name: snmp-ups
|
||||||
|
driver.parameter.pollinterval: 2
|
||||||
|
driver.parameter.port: somewhere.org
|
||||||
|
driver.version: 2.3.0-1540MS
|
||||||
|
driver.version.internal: 0.44 (mib: aphel_revelation 0.2)
|
||||||
|
outlet.1.current: 0.00
|
||||||
|
outlet.1.current.maximum: 0.00
|
||||||
|
outlet.1.desc: Outlet 1
|
||||||
|
outlet.1.id: 1
|
||||||
|
outlet.1.power: 0.00
|
||||||
|
outlet.1.powerfactor: 0.05
|
||||||
|
outlet.1.realpower: 0.00
|
||||||
|
outlet.1.status: on
|
||||||
|
outlet.1.switchable: 0.00
|
||||||
|
outlet.1.voltage: 247.00
|
||||||
|
outlet.2.current: 0.00
|
||||||
|
outlet.2.current.maximum: 0.16
|
||||||
|
outlet.2.desc: Outlet 2
|
||||||
|
outlet.2.id: 2
|
||||||
|
outlet.2.power: 0.00
|
||||||
|
outlet.2.powerfactor: 0.01
|
||||||
|
outlet.2.realpower: 0.00
|
||||||
|
outlet.2.status: on
|
||||||
|
outlet.2.switchable: 1.00
|
||||||
|
outlet.2.voltage: 247.00
|
||||||
|
outlet.3.current: 0.00
|
||||||
|
outlet.3.current.maximum: 0.16
|
||||||
|
outlet.3.desc: Outlet 3
|
||||||
|
outlet.3.id: 3
|
||||||
|
outlet.3.power: 0.00
|
||||||
|
outlet.3.powerfactor: 0.13
|
||||||
|
outlet.3.realpower: 0.00
|
||||||
|
outlet.3.status: on
|
||||||
|
outlet.3.switchable: 2.00
|
||||||
|
outlet.3.voltage: 247.00
|
||||||
|
outlet.4.current: 0.19
|
||||||
|
outlet.4.current.maximum: 0.56
|
||||||
|
outlet.4.desc: Outlet 4
|
||||||
|
outlet.4.id: 2
|
||||||
|
outlet.4.power: 46.00
|
||||||
|
outlet.4.powerfactor: 0.60
|
||||||
|
outlet.4.realpower: 28.00
|
||||||
|
outlet.4.status: on
|
||||||
|
outlet.4.switchable: 3.00
|
||||||
|
outlet.4.voltage: 247.00
|
||||||
|
outlet.count: 4.00
|
||||||
|
outlet.current: 0.19
|
||||||
|
outlet.desc: All outlets
|
||||||
|
outlet.id: 0
|
||||||
|
outlet.power: 46.00
|
||||||
|
outlet.realpower: 28.00
|
||||||
|
outlet.voltage: 247.00
|
||||||
|
ups.firmware: 01.01.00
|
||||||
|
ups.id: my_device234
|
||||||
|
ups.macaddr:
|
||||||
|
ups.mfr: EATON | Powerware
|
||||||
|
ups.model: DBQ10634/5
|
||||||
|
ups.serial: ADO6750531
|
||||||
|
ups.status:
|
||||||
|
ups.temperature: 49.00
|
||||||
|
device.type: pdu
|
58
data/evolution500.seq
Normal file
58
data/evolution500.seq
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
# dummy-ups example power sequence file
|
||||||
|
#
|
||||||
|
# Base is the same as .dev files, generated using:
|
||||||
|
# $ upsc ups@host > evolution500.seq
|
||||||
|
#
|
||||||
|
# TIMER have then been added to generate power events.
|
||||||
|
|
||||||
|
battery.charge: 90
|
||||||
|
battery.charge.low: 30
|
||||||
|
battery.runtime: 3690
|
||||||
|
battery.voltage: 230.0
|
||||||
|
driver.name: usbhid-ups
|
||||||
|
driver.parameter.port: auto
|
||||||
|
driver.version: 2.2.0
|
||||||
|
driver.version.data: MGE HID 0.7
|
||||||
|
driver.version.internal: 0.23
|
||||||
|
input.frequency: 49.0
|
||||||
|
input.transfer.boost.low: 184.0
|
||||||
|
input.transfer.high: 294.0
|
||||||
|
input.transfer.low: 160.0
|
||||||
|
input.transfer.trim.high: 265.0
|
||||||
|
input.voltage: 230.0
|
||||||
|
outlet.desc: Main Outlet
|
||||||
|
outlet.id: 0
|
||||||
|
outlet.switchable: 0
|
||||||
|
outlet.1.autoswitch.charge.low: 0
|
||||||
|
outlet.1.delay.shutdown: -1
|
||||||
|
outlet.1.delay.start: -1
|
||||||
|
outlet.1.desc: PowerShare Outlet 1
|
||||||
|
outlet.1.id: 1
|
||||||
|
outlet.1.switch: 1
|
||||||
|
outlet.1.switchable: 1
|
||||||
|
outlet.2.autoswitch.charge.low: 0
|
||||||
|
outlet.2.delay.shutdown: -1
|
||||||
|
outlet.2.delay.start: -1
|
||||||
|
outlet.2.desc: PowerShare Outlet 2
|
||||||
|
outlet.2.id: 2
|
||||||
|
outlet.2.switch: 1
|
||||||
|
outlet.2.switchable: 1
|
||||||
|
output.current: 0.00
|
||||||
|
output.frequency: 49.0
|
||||||
|
output.voltage: 230.0
|
||||||
|
output.voltage.nominal: 230.0
|
||||||
|
ups.delay.shutdown: -1
|
||||||
|
ups.delay.start: -10
|
||||||
|
ups.load: 10
|
||||||
|
ups.mfr: MGE UPS SYSTEMS
|
||||||
|
ups.model: Pulsar Evolution 500
|
||||||
|
ups.power.nominal: 500
|
||||||
|
ups.serial: AV2G3300L
|
||||||
|
ups.status: OL CHRG
|
||||||
|
ups.test.interval: 604800
|
||||||
|
ups.test.result: Done and passed
|
||||||
|
TIMER 300
|
||||||
|
ups.status: OB DISCHRG
|
||||||
|
TIMER 300
|
||||||
|
ups.status: OB LB DISCHRG
|
||||||
|
TIMER 60
|
11
data/html/Makefile.am
Normal file
11
data/html/Makefile.am
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Network UPS Tools: data/html
|
||||||
|
# install these only if configured --with-cgi
|
||||||
|
if WITH_CGI
|
||||||
|
dist_html_DATA = index.html bottom.html nut-banner.png
|
||||||
|
nodist_html_DATA = header.html
|
||||||
|
endif
|
||||||
|
EXTRA_DIST = README
|
||||||
|
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
# Generated by configure script:
|
||||||
|
DISTCLEANFILES = header.html
|
655
data/html/Makefile.in
Normal file
655
data/html/Makefile.in
Normal file
|
@ -0,0 +1,655 @@
|
||||||
|
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994-2020 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@
|
||||||
|
am__is_gnu_make = { \
|
||||||
|
if test -z '$(MAKELEVEL)'; then \
|
||||||
|
false; \
|
||||||
|
elif test -n '$(MAKE_HOST)'; then \
|
||||||
|
true; \
|
||||||
|
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||||
|
true; \
|
||||||
|
else \
|
||||||
|
false; \
|
||||||
|
fi; \
|
||||||
|
}
|
||||||
|
am__make_running_with_option = \
|
||||||
|
case $${target_option-} in \
|
||||||
|
?) ;; \
|
||||||
|
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||||
|
"target option '$${target_option-}' specified" >&2; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
has_opt=no; \
|
||||||
|
sane_makeflags=$$MAKEFLAGS; \
|
||||||
|
if $(am__is_gnu_make); then \
|
||||||
|
sane_makeflags=$$MFLAGS; \
|
||||||
|
else \
|
||||||
|
case $$MAKEFLAGS in \
|
||||||
|
*\\[\ \ ]*) \
|
||||||
|
bs=\\; \
|
||||||
|
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||||
|
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||||
|
esac; \
|
||||||
|
fi; \
|
||||||
|
skip_next=no; \
|
||||||
|
strip_trailopt () \
|
||||||
|
{ \
|
||||||
|
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||||
|
}; \
|
||||||
|
for flg in $$sane_makeflags; do \
|
||||||
|
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||||
|
case $$flg in \
|
||||||
|
*=*|--*) continue;; \
|
||||||
|
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||||
|
-*I?*) strip_trailopt 'I';; \
|
||||||
|
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||||
|
-*O?*) strip_trailopt 'O';; \
|
||||||
|
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||||
|
-*l?*) strip_trailopt 'l';; \
|
||||||
|
-[dEDm]) skip_next=yes;; \
|
||||||
|
-[JT]) skip_next=yes;; \
|
||||||
|
esac; \
|
||||||
|
case $$flg in \
|
||||||
|
*$$target_option*) has_opt=yes; break;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
test $$has_opt = yes
|
||||||
|
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||||
|
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||||
|
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 = data/html
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_c_pragmas.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_compare_version.m4 \
|
||||||
|
$(top_srcdir)/m4/ax_run_or_link_ifelse.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_cppcheck.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_headers_windows.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_libltdl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_libpowerman.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_check_pkgconfig.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_check_python.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_compiler_family.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_stash_warnings.m4 \
|
||||||
|
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_html_DATA_DIST) \
|
||||||
|
$(am__DIST_COMMON)
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||||
|
CONFIG_CLEAN_FILES = header.html
|
||||||
|
CONFIG_CLEAN_VPATH_FILES =
|
||||||
|
AM_V_P = $(am__v_P_@AM_V@)
|
||||||
|
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||||
|
am__v_P_0 = false
|
||||||
|
am__v_P_1 = :
|
||||||
|
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||||
|
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||||
|
am__v_GEN_0 = @echo " GEN " $@;
|
||||||
|
am__v_GEN_1 =
|
||||||
|
AM_V_at = $(am__v_at_@AM_V@)
|
||||||
|
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||||
|
am__v_at_0 = @
|
||||||
|
am__v_at_1 =
|
||||||
|
SOURCES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
am__can_run_installinfo = \
|
||||||
|
case $$AM_UPDATE_INFO_DIR in \
|
||||||
|
n|no|NO) false;; \
|
||||||
|
*) (install-info --version) >/dev/null 2>&1;; \
|
||||||
|
esac
|
||||||
|
am__dist_html_DATA_DIST = index.html bottom.html nut-banner.png
|
||||||
|
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__uninstall_files_from_dir = { \
|
||||||
|
test -z "$$files" \
|
||||||
|
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||||
|
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||||
|
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||||
|
}
|
||||||
|
am__installdirs = "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)"
|
||||||
|
DATA = $(dist_html_DATA) $(nodist_html_DATA)
|
||||||
|
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||||
|
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/header.html.in \
|
||||||
|
README
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
A2X = @A2X@
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||||
|
AR = @AR@
|
||||||
|
ASCIIDOC = @ASCIIDOC@
|
||||||
|
ASPELL = @ASPELL@
|
||||||
|
AUGPARSE = @AUGPARSE@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
BINDIR = @BINDIR@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CONFPATH = @CONFPATH@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPCHECK = @CPPCHECK@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
|
||||||
|
CPPUNIT_LIBS = @CPPUNIT_LIBS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DBLATEX = @DBLATEX@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
DLLTOOL = @DLLTOOL@
|
||||||
|
DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
||||||
|
DOC_CHECK_LIST = @DOC_CHECK_LIST@
|
||||||
|
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||||
|
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||||
|
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||||
|
DRVPATH = @DRVPATH@
|
||||||
|
DSYMUTIL = @DSYMUTIL@
|
||||||
|
DUMPBIN = @DUMPBIN@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
FGREP = @FGREP@
|
||||||
|
GDLIB_CONFIG = @GDLIB_CONFIG@
|
||||||
|
GREP = @GREP@
|
||||||
|
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@
|
||||||
|
LIBDIR = @LIBDIR@
|
||||||
|
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||||
|
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||||
|
LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
|
||||||
|
LIBIPMI_LIBS = @LIBIPMI_LIBS@
|
||||||
|
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
|
||||||
|
LIBLTDL_LIBS = @LIBLTDL_LIBS@
|
||||||
|
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
|
||||||
|
LIBMODBUS_LIBS = @LIBMODBUS_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@
|
||||||
|
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||||
|
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||||
|
LIBUSB_CONFIG = @LIBUSB_CONFIG@
|
||||||
|
LIBUSB_LIBS = @LIBUSB_LIBS@
|
||||||
|
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||||
|
LIBWRAP_LIBS = @LIBWRAP_LIBS@
|
||||||
|
LIPO = @LIPO@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LN_S_R = @LN_S_R@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||||
|
MAINT = @MAINT@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||||
|
MKDIR_P = @MKDIR_P@
|
||||||
|
NETLIBS = @NETLIBS@
|
||||||
|
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
|
||||||
|
NM = @NM@
|
||||||
|
NMEDIT = @NMEDIT@
|
||||||
|
NUT_DATADIR = @NUT_DATADIR@
|
||||||
|
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
|
||||||
|
NUT_NETVERSION = @NUT_NETVERSION@
|
||||||
|
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@
|
||||||
|
PIDPATH = @PIDPATH@
|
||||||
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
PORT = @PORT@
|
||||||
|
PYTHON = @PYTHON@
|
||||||
|
PYTHON2 = @PYTHON2@
|
||||||
|
PYTHON3 = @PYTHON3@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||||
|
RUN_AS_USER = @RUN_AS_USER@
|
||||||
|
SBINDIR = @SBINDIR@
|
||||||
|
SED = @SED@
|
||||||
|
SERLIBS = @SERLIBS@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
SOURCE_HIGHLIGHT = @SOURCE_HIGHLIGHT@
|
||||||
|
STATEPATH = @STATEPATH@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
SUN_LIBUSB = @SUN_LIBUSB@
|
||||||
|
TREE_VERSION = @TREE_VERSION@
|
||||||
|
VALGRIND = @VALGRIND@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||||
|
XMLLINT = @XMLLINT@
|
||||||
|
XSLTPROC = @XSLTPROC@
|
||||||
|
abs_builddir = @abs_builddir@
|
||||||
|
abs_srcdir = @abs_srcdir@
|
||||||
|
abs_top_builddir = @abs_top_builddir@
|
||||||
|
abs_top_srcdir = @abs_top_srcdir@
|
||||||
|
ac_ct_AR = @ac_ct_AR@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
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@
|
||||||
|
auglensdir = @auglensdir@
|
||||||
|
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@
|
||||||
|
devddir = @devddir@
|
||||||
|
docdir = @docdir@
|
||||||
|
driverexecdir = @driverexecdir@
|
||||||
|
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
|
||||||
|
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
|
||||||
|
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
|
||||||
|
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@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
now = @now@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
runstatedir = @runstatedir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
systemdshutdowndir = @systemdshutdowndir@
|
||||||
|
systemdsystemunitdir = @systemdsystemunitdir@
|
||||||
|
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||||
|
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@
|
||||||
|
|
||||||
|
# Network UPS Tools: data/html
|
||||||
|
# install these only if configured --with-cgi
|
||||||
|
@WITH_CGI_TRUE@dist_html_DATA = index.html bottom.html nut-banner.png
|
||||||
|
@WITH_CGI_TRUE@nodist_html_DATA = header.html
|
||||||
|
EXTRA_DIST = README
|
||||||
|
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||||
|
# Generated by configure script:
|
||||||
|
DISTCLEANFILES = header.html
|
||||||
|
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 data/html/Makefile'; \
|
||||||
|
$(am__cd) $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnu data/html/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__maybe_remake_depfiles)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||||
|
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):
|
||||||
|
header.html: $(top_builddir)/config.status $(srcdir)/header.html.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
install-dist_htmlDATA: $(dist_html_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(htmldir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-dist_htmlDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(dist_html_DATA)'; test -n "$(htmldir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir)
|
||||||
|
install-nodist_htmlDATA: $(nodist_html_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
@list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \
|
||||||
|
if test -n "$$list"; then \
|
||||||
|
echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
|
||||||
|
$(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
|
||||||
|
fi; \
|
||||||
|
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)$(htmldir)'"; \
|
||||||
|
$(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-nodist_htmlDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(nodist_html_DATA)'; test -n "$(htmldir)" || list=; \
|
||||||
|
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||||
|
dir='$(DESTDIR)$(htmldir)'; $(am__uninstall_files_from_dir)
|
||||||
|
tags TAGS:
|
||||||
|
|
||||||
|
ctags CTAGS:
|
||||||
|
|
||||||
|
cscope cscopelist:
|
||||||
|
|
||||||
|
|
||||||
|
distdir: $(BUILT_SOURCES)
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||||
|
|
||||||
|
distdir-am: $(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 $(DATA)
|
||||||
|
installdirs:
|
||||||
|
for dir in "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(htmldir)"; 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:
|
||||||
|
if test -z '$(STRIP)'; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
install; \
|
||||||
|
else \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||||
|
fi
|
||||||
|
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)
|
||||||
|
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
|
||||||
|
|
||||||
|
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 "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||||
|
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-dist_htmlDATA install-nodist_htmlDATA
|
||||||
|
|
||||||
|
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-dist_htmlDATA uninstall-nodist_htmlDATA
|
||||||
|
|
||||||
|
.MAKE: install-am install-strip
|
||||||
|
|
||||||
|
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||||
|
cscopelist-am ctags-am distclean distclean-generic \
|
||||||
|
distclean-libtool distdir dvi dvi-am html html-am info info-am \
|
||||||
|
install install-am install-data install-data-am \
|
||||||
|
install-dist_htmlDATA install-dvi install-dvi-am install-exec \
|
||||||
|
install-exec-am install-html install-html-am install-info \
|
||||||
|
install-info-am install-man install-nodist_htmlDATA \
|
||||||
|
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 \
|
||||||
|
tags-am uninstall uninstall-am uninstall-dist_htmlDATA \
|
||||||
|
uninstall-nodist_htmlDATA
|
||||||
|
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
|
||||||
|
|
||||||
|
# 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:
|
97
data/html/README
Normal file
97
data/html/README
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
Desc: NUT HTML complementary information
|
||||||
|
File: README
|
||||||
|
Date: 27 Jul 2005
|
||||||
|
Auth: Arnaud Quette <arnaud.quette@free.fr>
|
||||||
|
Dave Breiland <superdave@dynamicis.com>
|
||||||
|
|
||||||
|
This file provides some complementary information
|
||||||
|
about the use and integration of NUT HTML pages.
|
||||||
|
|
||||||
|
1) Introduction
|
||||||
|
---------------
|
||||||
|
|
||||||
|
NUT HTML pages have been created as a central point
|
||||||
|
that ease the access to the various CGI scripts
|
||||||
|
providing the NUT web interface.
|
||||||
|
|
||||||
|
It consists of three .html files:
|
||||||
|
- index.html: defines the two container frames,
|
||||||
|
topFrame and mainFrame
|
||||||
|
- header.html: contain the header including links
|
||||||
|
to NUT website, and upsstat.cgi/upsset.cgi
|
||||||
|
- bottom.html: empty frame that will be replaced
|
||||||
|
with the content of upsstat.cgi or upsset.cgi.
|
||||||
|
|
||||||
|
2) Integration
|
||||||
|
--------------
|
||||||
|
|
||||||
|
You first need to install NUT CGI (ie using ./configure --with-cgi).
|
||||||
|
Refer to the README file for more information
|
||||||
|
|
||||||
|
There are two ways to integrate NUT HTML with your
|
||||||
|
webserver, with the same results:
|
||||||
|
|
||||||
|
a) take advantage of the existing tree
|
||||||
|
======================================
|
||||||
|
|
||||||
|
- the cgi are for example installed in /usr/lib/cgi-bin,
|
||||||
|
which is already configured in your webserver as the
|
||||||
|
default CGI path
|
||||||
|
|
||||||
|
- in the same spirit, we will use the existing DocumentRoot
|
||||||
|
and create a "nut" subdirectory, and copy the three .html
|
||||||
|
files (index, header and bottom)
|
||||||
|
|
||||||
|
Note that the links to cgi scripts in header.html are
|
||||||
|
pre configured to work in this situation, which ease
|
||||||
|
the packagers work.
|
||||||
|
|
||||||
|
b) configure manually
|
||||||
|
=====================
|
||||||
|
|
||||||
|
- copy the data/html directory to somepath (ie /usr/local/nut
|
||||||
|
for a standard installation from source)
|
||||||
|
|
||||||
|
-Now edit your webserver configuration file, adding for
|
||||||
|
example (for Apache):
|
||||||
|
|
||||||
|
#Begin Section
|
||||||
|
ScriptAlias /nut/cgi-bin/ /usr/local/nut/cgi-bin/
|
||||||
|
<Directory "/usr/local/nut/cgi-bin/">
|
||||||
|
AllowOverride AuthConfig
|
||||||
|
Options ExecCGI
|
||||||
|
Order allow,deny
|
||||||
|
Allow from all
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
Alias /nut/ /usr/local/nut/html/
|
||||||
|
<Directory "/usr/local/nut/html/">
|
||||||
|
Options None
|
||||||
|
AllowOverride AuthConfig
|
||||||
|
Order allow,deny
|
||||||
|
Allow from all
|
||||||
|
</Directory>
|
||||||
|
#End Section
|
||||||
|
|
||||||
|
-Make sure to change the links path in header.html according to your
|
||||||
|
configuration and installation.
|
||||||
|
|
||||||
|
3) Conclusion
|
||||||
|
=============
|
||||||
|
|
||||||
|
- Make sure to restart your webserver.
|
||||||
|
|
||||||
|
-Configure the CGI scripts. Manpages can be found from:
|
||||||
|
--prompt> man -M /usr/local/nut/man/ upsstats.cgi
|
||||||
|
--prompt> man -M /usr/local/nut/man/ upsset.cgi
|
||||||
|
--prompt> man -M /usr/local/nut/man/ upsimage.cgi
|
||||||
|
--prompt> man -M /usr/local/nut/man/ hosts.conf
|
||||||
|
|
||||||
|
-It is recommended that you use .htaccess files in the cgi-bin folder and the
|
||||||
|
html folder. Please reference:
|
||||||
|
http://httpd.apache.org/docs/howto/htaccess.html
|
||||||
|
|
||||||
|
- You will then be able to access the NUT HTML page at:
|
||||||
|
http://localhost/nut
|
||||||
|
|
||||||
|
|
8
data/html/bottom.html
Normal file
8
data/html/bottom.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE>
|
||||||
|
</TITLE>
|
||||||
|
</HEAD>
|
||||||
|
<BODY>
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
39
data/html/header.html.in
Normal file
39
data/html/header.html.in
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>
|
||||||
|
Network UPS Tools
|
||||||
|
</title>
|
||||||
|
</head>
|
||||||
|
<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000EE" VLINK="#551A8B">
|
||||||
|
|
||||||
|
<table BGCOLOR="#50A0A0" ALIGN="CENTER">
|
||||||
|
<tr><td>
|
||||||
|
|
||||||
|
<table CELLPADDING="3">
|
||||||
|
<tr ALIGN=CENTER>
|
||||||
|
<th COLSPAN="2" BGCOLOR="#60B0B0">
|
||||||
|
|
||||||
|
<a href="http://www.networkupstools.org" target="new">
|
||||||
|
<IMG SRC="nut-banner.png"></a>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
</th>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr ALIGN=CENTER>
|
||||||
|
<td BGCOLOR="#00FFFF">
|
||||||
|
<a href=/cgi-bin/nut/upsstats.cgi target=mainFrame>Statistics</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td BGCOLOR="#00FFFF">
|
||||||
|
<a href=/cgi-bin/nut/upsset.cgi target=mainFrame>Settings</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td></tr>
|
||||||
|
</table></body></html>
|
14
data/html/index.html
Normal file
14
data/html/index.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||||
|
<title>Network UPS Tools -- http://www.networkupstools.org</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<frameset rows="110,*" frameborder="NO" border="0" framespacing="0">
|
||||||
|
<frame src="header.html" name="topFrame" scrolling="NO" noresize>
|
||||||
|
<frame src="bottom.html" name="mainFrame">
|
||||||
|
</frameset>
|
||||||
|
<noframes><body>
|
||||||
|
</body></noframes>
|
||||||
|
</html>
|
BIN
data/html/nut-banner.png
Normal file
BIN
data/html/nut-banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
19
debian/NEWS
vendored
Normal file
19
debian/NEWS
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
nut (2.7.2-2) unstable; urgency=medium
|
||||||
|
|
||||||
|
Since version 1.2 NUT-Monitor uses safer directory permissions when
|
||||||
|
creating ~/.nut-monitor.
|
||||||
|
|
||||||
|
NUT-Monitor will now detect a pre-1.2 settings directory on startup
|
||||||
|
and update its permissions.
|
||||||
|
|
||||||
|
Please note that passwords stored in NUT-Monitor prior to this change
|
||||||
|
may have been exposed, and it is recommended that they be reset.
|
||||||
|
|
||||||
|
-- Michael Fincham <michael.fincham@catalyst.net.nz> Fri, 13 Feb 2015 11:57:12 +1300
|
||||||
|
|
||||||
|
nut (2.6.5-1) experimental; urgency=low
|
||||||
|
|
||||||
|
mge-shut driver has been replaced by a new implementation (newmge-shut).
|
||||||
|
In case of issue with this new version, users can revert to oldmge-shut.
|
||||||
|
|
||||||
|
-- Laurent Bigonville <bigon@debian.org> Mon, 13 Aug 2012 00:32:18 +0200
|
1934
debian/changelog
vendored
Normal file
1934
debian/changelog
vendored
Normal file
File diff suppressed because it is too large
Load diff
1
debian/compat
vendored
Normal file
1
debian/compat
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
12
|
305
debian/control
vendored
Normal file
305
debian/control
vendored
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
Source: nut
|
||||||
|
Section: admin
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Laurent Bigonville <bigon@debian.org>
|
||||||
|
Build-Depends: debhelper (>= 12),
|
||||||
|
dh-python,
|
||||||
|
libfreeipmi-dev (>= 0.8.5) [!hurd-i386],
|
||||||
|
libgd-dev | libgd2-xpm-dev | libgd2-noxpm-dev,
|
||||||
|
libipmimonitoring-dev (>= 1.1.5-2) [!hurd-i386],
|
||||||
|
libltdl-dev,
|
||||||
|
libneon27-gnutls-dev | libneon27-dev,
|
||||||
|
libnss3-dev,
|
||||||
|
libpowerman0-dev (>= 2.3.3),
|
||||||
|
libsnmp-dev | libsnmp9-dev,
|
||||||
|
libusb-dev (>= 0.1.8),
|
||||||
|
libwrap0-dev (>= 7.6),
|
||||||
|
python3
|
||||||
|
Build-Depends-Indep: asciidoc (>= 8.6.3) <!nodoc>,
|
||||||
|
asciidoc-dblatex <!nodoc>,
|
||||||
|
dblatex (>= 0.2.5) <!nodoc>,
|
||||||
|
docbook-xsl <!nodoc>,
|
||||||
|
libxml2-utils <!nodoc>
|
||||||
|
Standards-Version: 4.6.0
|
||||||
|
Homepage: https://networkupstools.org/
|
||||||
|
Vcs-Browser: https://salsa.debian.org/debian/nut
|
||||||
|
Vcs-Git: https://salsa.debian.org/debian/nut.git
|
||||||
|
|
||||||
|
Package: nut
|
||||||
|
Architecture: all
|
||||||
|
Section: metapackages
|
||||||
|
Depends: nut-client, nut-server, ${misc:Depends}
|
||||||
|
Description: network UPS tools - metapackage
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package is a metapackage that installs both nut-server and nut-client,
|
||||||
|
in most cases it is sufficient for a basic UPS monitoring system.
|
||||||
|
|
||||||
|
Package: nut-server
|
||||||
|
Architecture: any
|
||||||
|
Depends: adduser,
|
||||||
|
lsb-base (>= 3.0-6),
|
||||||
|
nut-client (= ${binary:Version}),
|
||||||
|
udev [linux-any],
|
||||||
|
${misc:Depends},
|
||||||
|
${shlibs:Depends}
|
||||||
|
Suggests: nut-cgi, nut-ipmi, nut-snmp, nut-xml
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Description: network UPS tools - core system
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides NUT's core system, and the serial and USB UPS
|
||||||
|
drivers.
|
||||||
|
|
||||||
|
Package: nut-client
|
||||||
|
Architecture: any
|
||||||
|
Depends: adduser, lsb-base (>= 3.0-6), ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Provides: ups-monitor
|
||||||
|
Conflicts: ups-monitor
|
||||||
|
Recommends: bash-completion
|
||||||
|
Suggests: nut-monitor
|
||||||
|
Replaces: ups-monitor
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Description: network UPS tools - clients
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides NUT's clients that allows the user to control
|
||||||
|
and monitor the UPS.
|
||||||
|
|
||||||
|
Package: nut-cgi
|
||||||
|
Architecture: any
|
||||||
|
Depends: adduser, ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Recommends: apache2 | httpd-cgi
|
||||||
|
Suggests: nut
|
||||||
|
Description: network UPS tools - web interface
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides an HTTP interface for Network UPS Tools which makes
|
||||||
|
it possible to monitor the core NUT system with a web browser.
|
||||||
|
|
||||||
|
Package: nut-snmp
|
||||||
|
Architecture: any
|
||||||
|
Depends: nut (>= 1.4.1-pre1), ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: network UPS tools - SNMP driver
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides snmp-ups, the SNMP multi-MIB driver for UPS, which
|
||||||
|
supports various MIBs including IETF, MGE, and APC. It adds an SNMP
|
||||||
|
Manager interface to the core NUT system.
|
||||||
|
|
||||||
|
Package: nut-ipmi
|
||||||
|
Architecture: kfreebsd-any linux-any
|
||||||
|
Depends: nut (>= 1.4.1-pre1), ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: network UPS tools - IPMI driver
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package currently provides nut-ipmipsu, a driver which allows the user to
|
||||||
|
monitor IPMI power supply units (PSU) found in servers of popular brands, such
|
||||||
|
as Dell, HP, IBM. It adds an IPMI interface to the core NUT system.
|
||||||
|
|
||||||
|
Package: nut-xml
|
||||||
|
Architecture: any
|
||||||
|
Depends: nut (>= 2.2.2), ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Description: network UPS tools - XML/HTTP driver
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides netxml-ups, which supports UPS models from
|
||||||
|
Eaton or MGE that use an XML/HTTP-based Network Management Card or
|
||||||
|
Proxy.
|
||||||
|
|
||||||
|
Package: nut-powerman-pdu
|
||||||
|
Architecture: any
|
||||||
|
Depends: nut (>= 2.4.0),
|
||||||
|
powerman (>= 2.3.3),
|
||||||
|
${misc:Depends},
|
||||||
|
${shlibs:Depends}
|
||||||
|
Description: network UPS tools - PowerMan PDU driver
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides powerman-pdu, which allows NUT clients to communicate
|
||||||
|
with the PowerMan daemon to support PDUs.
|
||||||
|
|
||||||
|
Package: nut-doc
|
||||||
|
Architecture: all
|
||||||
|
Section: doc
|
||||||
|
Depends: ${misc:Depends}
|
||||||
|
Suggests: doc-base
|
||||||
|
Build-Profiles: <!nodoc>
|
||||||
|
Description: network UPS tools - documentation
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package contains FAQ, user, developer and packager documentation.
|
||||||
|
|
||||||
|
Package: libupsclient4
|
||||||
|
Section: libs
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - client library
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the shared client library.
|
||||||
|
|
||||||
|
Package: libupsclient-dev
|
||||||
|
Section: libdevel
|
||||||
|
Architecture: any
|
||||||
|
Depends: libnss3-dev,
|
||||||
|
libupsclient4 (= ${binary:Version}),
|
||||||
|
${misc:Depends},
|
||||||
|
${shlibs:Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - development files
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the development files.
|
||||||
|
|
||||||
|
Package: libnutclient0
|
||||||
|
Section: libs
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - new client library
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the new shared client library.
|
||||||
|
|
||||||
|
Package: libnutclient-dev
|
||||||
|
Section: libdevel
|
||||||
|
Architecture: any
|
||||||
|
Depends: libnutclient0 (= ${binary:Version}),
|
||||||
|
${misc:Depends},
|
||||||
|
${shlibs:Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - development files for the new client library
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the development files for the new client library.
|
||||||
|
|
||||||
|
Package: libnutscan1
|
||||||
|
Section: libs
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - scanner library
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the shared scanner library.
|
||||||
|
|
||||||
|
Package: libnutscan-dev
|
||||||
|
Section: libdevel
|
||||||
|
Architecture: any
|
||||||
|
Depends: libnutscan1 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
|
||||||
|
Breaks: libupsclient-dev (<< 2.7.4-9~)
|
||||||
|
Replaces: libupsclient-dev (<< 2.7.4-9~)
|
||||||
|
Multi-Arch: same
|
||||||
|
Description: network UPS tools - development files for the scanner library
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides the development files for the scanner library.
|
||||||
|
|
||||||
|
#Package: python3-nut
|
||||||
|
#Section: python
|
||||||
|
#Architecture: all
|
||||||
|
#Depends: ${misc:Depends}, ${python3:Depends}
|
||||||
|
#Description: network UPS tools - Python3 bindings for NUT server
|
||||||
|
# Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
# allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
# power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
# through the server, and are notified whenever the power status
|
||||||
|
# changes.
|
||||||
|
# .
|
||||||
|
# This package provides Python3 bindings to connect to NUT server.
|
||||||
|
|
||||||
|
#Package: nut-monitor
|
||||||
|
#Architecture: all
|
||||||
|
#Depends: python-glade2,
|
||||||
|
# python-gobject-2,
|
||||||
|
# python-gtk2,
|
||||||
|
# python-nut,
|
||||||
|
# ${misc:Depends},
|
||||||
|
# ${python:Depends}
|
||||||
|
#Recommends: python-notify
|
||||||
|
#Description: network UPS tools - GUI application to monitor UPS status
|
||||||
|
# Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
# allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
# power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
# through the server, and are notified whenever the power status
|
||||||
|
# changes.
|
||||||
|
# .
|
||||||
|
# This package provides nut-monitor, a GUI application to monitor UPS status.
|
||||||
|
|
||||||
|
Package: libups-nut-perl
|
||||||
|
Section: perl
|
||||||
|
Architecture: all
|
||||||
|
Depends: ${misc:Depends}, ${perl:Depends}
|
||||||
|
Description: network UPS tools - Perl bindings for NUT server
|
||||||
|
Network UPS Tools (NUT) is a client/server monitoring system that
|
||||||
|
allows computers to share uninterruptible power supply (UPS) and
|
||||||
|
power distribution unit (PDU) hardware. Clients access the hardware
|
||||||
|
through the server, and are notified whenever the power status
|
||||||
|
changes.
|
||||||
|
.
|
||||||
|
This package provides Perl bindings to connect to NUT server.
|
69
debian/copyright
vendored
Normal file
69
debian/copyright
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
This package was debianized by Luca Filipozzi <lfilipoz@debian.org> on
|
||||||
|
Wed Jun 28 19:48:05 PDT 2000
|
||||||
|
|
||||||
|
It was downloaded from http://www.networkupstools.org/
|
||||||
|
|
||||||
|
Upstream Authors:
|
||||||
|
|
||||||
|
Russell Kroll <rkroll@exploits.org>
|
||||||
|
Arnaud Quette <http://arnaud.quette.free.fr/contact.html>
|
||||||
|
Arjen de Korte <arjen@de-korte.org>
|
||||||
|
Charles Lepple <clepple@gmail.com>
|
||||||
|
Kjell Claesson <kjell.claesson@epost.tidanet.se>
|
||||||
|
David Goncalves <david@lestat.st>
|
||||||
|
and the NUT Team
|
||||||
|
|
||||||
|
Copyright:
|
||||||
|
|
||||||
|
Copyright (C) 2000-2008 Russell Kroll, Arnaud Quette and the NUT Team
|
||||||
|
|
||||||
|
Licenses:
|
||||||
|
|
||||||
|
Most files are licensed under the GNU General Public License (GPL) version 2,
|
||||||
|
or (at your option) any later version.
|
||||||
|
|
||||||
|
The files in the scripts/python/ directory are released under GNU General
|
||||||
|
Public License (GPL) version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
GPL-2
|
||||||
|
-----
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
On Debian systems, the full text of the GNU General Public License v2
|
||||||
|
may be found in /usr/share/common-licenses/GPL-2.
|
||||||
|
|
||||||
|
GPL-3
|
||||||
|
-----
|
||||||
|
|
||||||
|
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 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
On Debian systems, the full text of the GNU General Public License v3
|
||||||
|
may be found in /usr/share/common-licenses/GPL-3.
|
||||||
|
|
||||||
|
|
||||||
|
The Debian packaging is Copyright (C) 2008, Arnaud Quette <aquette@debian.org>
|
||||||
|
and is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
8
debian/gbp.conf
vendored
Normal file
8
debian/gbp.conf
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[DEFAULT]
|
||||||
|
debian-branch = debian
|
||||||
|
upstream-branch = upstream
|
||||||
|
pristine-tar = True
|
||||||
|
|
||||||
|
[git-buildpackage]
|
||||||
|
tarball-dir = ../tarballs/
|
||||||
|
export-dir = ../build-area/
|
4
debian/libnutclient-dev.install
vendored
Normal file
4
debian/libnutclient-dev.install
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
usr/include/nutclient.h
|
||||||
|
usr/lib/*/libnutclient.a
|
||||||
|
usr/lib/*/libnutclient.so
|
||||||
|
usr/lib/*/pkgconfig/libnutclient.pc
|
1
debian/libnutclient0.install
vendored
Normal file
1
debian/libnutclient0.install
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
lib/*/libnutclient.so.*
|
199
debian/libnutclient0.symbols
vendored
Normal file
199
debian/libnutclient0.symbols
vendored
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
# SymbolsHelper-Confirmed: 2.7.4-9~ amd64 arm64 armel armhf hppa i386 ia64 m68k mips mips64el mipsel powerpc ppc64 ppc64el riscv64 s390x sh4 sparc64 x32
|
||||||
|
libnutclient.so.0 libnutclient0 #MINVER#
|
||||||
|
* Build-Depends-Package: libnutclient-dev
|
||||||
|
(c++)"nut::Client::Client()@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::getDevice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::getDeviceVariableValues(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::getDevices()@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::hasDevice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::hasDeviceCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::hasDeviceVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Client::~Client()@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::Command(nut::Command const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::Command(nut::Device*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::execute()@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::getDescription[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::getDevice() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::getDevice()@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::getName[abi:cxx11]() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::isOk() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::operator bool() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::operator!() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::operator<(nut::Command const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::operator==(nut::Command const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Command::~Command()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::Device(nut::Client*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::Device(nut::Device const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::executeCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::forcedShutdown()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getClient() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getClient()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getCommandNames[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getCommands()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getDescription[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getName[abi:cxx11]() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getNumLogins()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getRWVariableNames[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getRWVariables()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getVariableNames[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getVariableValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getVariableValues[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::getVariables()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::isOk() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::login()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::master()@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::operator bool() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::operator!() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::operator<(nut::Device const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::operator==(nut::Device const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::setVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::setVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Device::~Device()@Base" 2.7.3
|
||||||
|
(c++)"nut::IOException::~IOException()@Base" 2.7.3
|
||||||
|
(c++)"nut::NotConnectedException::NotConnectedException()@Base" 2.7.3
|
||||||
|
(c++)"nut::NotConnectedException::~NotConnectedException()@Base" 2.7.3
|
||||||
|
(c++)"nut::NutException::NutException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::NutException::str[abi:cxx11]() const@Base" 2.7.3
|
||||||
|
(c++)"nut::NutException::what() const@Base" 2.7.3
|
||||||
|
(c++)"nut::NutException::~NutException()@Base" 2.7.3
|
||||||
|
(c++)"nut::SystemException::SystemException()@Base" 2.7.3
|
||||||
|
(c++)"nut::SystemException::err[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::SystemException::~SystemException()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::TcpClient()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::TcpClient(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::authenticate(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::connect()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::connect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::detectError(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::deviceForcedShutdown(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::deviceGetNumLogins(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::deviceLogin(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::deviceMaster(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::disconnect()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::escape(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::executeDeviceCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++|arch-bits=32)"nut::TcpClient::explode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)@Base" 2.7.4
|
||||||
|
(c++|arch-bits=64)"nut::TcpClient::explode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long)@Base" 2.7.4
|
||||||
|
(c++)"nut::TcpClient::get(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDevice(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceCommandDescription(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceCommandNames(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceDescription(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceNames[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceRWVariableNames(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceVariableDescription(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceVariableNames(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceVariableValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getDeviceVariableValues(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getHost[abi:cxx11]() const@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getPort() const@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::getTimeout() const@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::isConnected() const@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::list(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::logout()@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::sendQuery(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::setDeviceVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::setDeviceVariable(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::setTimeout(long)@Base" 2.7.3
|
||||||
|
(c++)"nut::TcpClient::~TcpClient()@Base" 2.7.3
|
||||||
|
(c++)"nut::TimeoutException::TimeoutException()@Base" 2.7.3
|
||||||
|
(c++)"nut::TimeoutException::~TimeoutException()@Base" 2.7.3
|
||||||
|
(c++)"nut::UnknownHostException::UnknownHostException()@Base" 2.7.3
|
||||||
|
(c++)"nut::UnknownHostException::~UnknownHostException()@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::Variable(nut::Device*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::Variable(nut::Variable const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::getDescription[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::getDevice() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::getDevice()@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::getName[abi:cxx11]() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::getValue[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::isOk() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::operator bool() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::operator!() const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::operator<(nut::Variable const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::operator==(nut::Variable const&) const@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::setValue(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::setValues(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
|
||||||
|
(c++)"nut::Variable::~Variable()@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::Socket()@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::connect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::disconnect()@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::isConnected() const@Base" 2.7.3
|
||||||
|
(c++|arch-bits=32)"nut::internal::Socket::read(void*, unsigned int)@Base" 2.7.4
|
||||||
|
(c++|arch-bits=64)"nut::internal::Socket::read(void*, unsigned long)@Base" 2.7.4
|
||||||
|
(c++)"nut::internal::Socket::read[abi:cxx11]()@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::setTimeout(long)@Base" 2.7.3
|
||||||
|
(c++)"nut::internal::Socket::write(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++|arch-bits=32)"nut::internal::Socket::write(void const*, unsigned int)@Base" 2.7.4
|
||||||
|
(c++|arch-bits=64)"nut::internal::Socket::write(void const*, unsigned long)@Base" 2.7.4
|
||||||
|
nutclient_authenticate@Base 2.7.3
|
||||||
|
nutclient_destroy@Base 2.7.3
|
||||||
|
nutclient_device_forced_shutdown@Base 2.7.3
|
||||||
|
nutclient_device_login@Base 2.7.3
|
||||||
|
nutclient_device_master@Base 2.7.3
|
||||||
|
nutclient_execute_device_command@Base 2.7.3
|
||||||
|
nutclient_get_device_command_description@Base 2.7.3
|
||||||
|
nutclient_get_device_commands@Base 2.7.3
|
||||||
|
nutclient_get_device_description@Base 2.7.3
|
||||||
|
nutclient_get_device_num_logins@Base 2.7.3
|
||||||
|
nutclient_get_device_rw_variables@Base 2.7.3
|
||||||
|
nutclient_get_device_variable_description@Base 2.7.3
|
||||||
|
nutclient_get_device_variable_values@Base 2.7.3
|
||||||
|
nutclient_get_device_variables@Base 2.7.3
|
||||||
|
nutclient_get_devices@Base 2.7.3
|
||||||
|
nutclient_has_device@Base 2.7.3
|
||||||
|
nutclient_has_device_command@Base 2.7.3
|
||||||
|
nutclient_has_device_variable@Base 2.7.3
|
||||||
|
nutclient_logout@Base 2.7.3
|
||||||
|
nutclient_set_device_variable_value@Base 2.7.3
|
||||||
|
nutclient_set_device_variable_values@Base 2.7.3
|
||||||
|
nutclient_tcp_create_client@Base 2.7.3
|
||||||
|
nutclient_tcp_disconnect@Base 2.7.3
|
||||||
|
nutclient_tcp_get_timeout@Base 2.7.3
|
||||||
|
nutclient_tcp_is_connected@Base 2.7.3
|
||||||
|
nutclient_tcp_reconnect@Base 2.7.3
|
||||||
|
nutclient_tcp_set_timeout@Base 2.7.3
|
||||||
|
(c++)"std::_Rb_tree<nut::Device, nut::Device, std::_Identity<nut::Device>, std::less<nut::Device>, std::allocator<nut::Device> >::_M_erase(std::_Rb_tree_node<nut::Device>*)@Base" 2.7.3
|
||||||
|
(c++)"std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_erase(std::_Rb_tree_node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)@Base" 2.7.3
|
||||||
|
(c++)"std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >*)@Base" 2.7.3
|
||||||
|
(c++|optional=templinst)"std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.4
|
||||||
|
(c++)"std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >::_M_get_insert_unique_pos(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.3
|
||||||
|
(c++)"std::pair<std::_Rb_tree_iterator<nut::Variable>, bool> std::_Rb_tree<nut::Variable, nut::Variable, std::_Identity<nut::Variable>, std::less<nut::Variable>, std::allocator<nut::Variable> >::_M_insert_unique<nut::Variable>(nut::Variable&&)@Base" 2.7.3
|
||||||
|
(c++)"std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::operator=(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)@Base" 2.7.3
|
||||||
|
(c++)"std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::~vector()@Base" 2.7.3
|
||||||
|
(c++)"std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::~vector()@Base" 2.7.3
|
||||||
|
strarr_alloc@Base 2.7.3
|
||||||
|
strarr_free@Base 2.7.3
|
||||||
|
(c++)"typeinfo for nut::Client@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::IOException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::NotConnectedException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::NutException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::SystemException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::TcpClient@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::TimeoutException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo for nut::UnknownHostException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::Client@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::IOException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::NotConnectedException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::NutException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::SystemException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::TcpClient@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::TimeoutException@Base" 2.7.3
|
||||||
|
(c++)"typeinfo name for nut::UnknownHostException@Base" 2.7.3
|
||||||
|
(c++|optional=templinst)"void std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.4
|
||||||
|
(c++|optional=templinst)"void std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::_M_realloc_insert<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >(__gnu_cxx::__normal_iterator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)@Base" 2.7.4
|
||||||
|
(c++)"vtable for nut::Client@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::IOException@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::NotConnectedException@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::NutException@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::SystemException@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::TcpClient@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::TimeoutException@Base" 2.7.3
|
||||||
|
(c++)"vtable for nut::UnknownHostException@Base" 2.7.3
|
||||||
|
(c++|optional=templinst)"void std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)@Base" 2.7.4
|
||||||
|
(c++|optional=templinst|arch=s390x mipsel armhf)"std::pair<std::_Rb_tree_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, bool> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_insert_unique<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.4
|
||||||
|
(c++|optional=templinst|arch=!s390x !mipsel !armhf)"std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::insert(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)@Base" 2.7.4
|
6
debian/libnutscan-dev.install
vendored
Normal file
6
debian/libnutscan-dev.install
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
usr/include/nut-scan.h
|
||||||
|
usr/include/nutscan-device.h
|
||||||
|
usr/include/nutscan-init.h
|
||||||
|
usr/include/nutscan-ip.h
|
||||||
|
usr/lib/*/libnutscan.so
|
||||||
|
usr/lib/*/pkgconfig/libnutscan.pc
|
1
debian/libnutscan1.install
vendored
Normal file
1
debian/libnutscan1.install
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
lib/*/libnutscan.so.*
|
157
debian/libnutscan1.symbols
vendored
Normal file
157
debian/libnutscan1.symbols
vendored
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
libnutscan.so.1 libnutscan1 #MINVER#
|
||||||
|
* Build-Depends-Package: libnutscan-dev
|
||||||
|
AUT@Base 2.7.4-9~
|
||||||
|
UPS_VERSION@Base 2.7.4-9~
|
||||||
|
altpidpath@Base 2.7.4-9~
|
||||||
|
background@Base 2.7.4-9~
|
||||||
|
become_user@Base 2.7.4-9~
|
||||||
|
calc_checksum@Base 2.7.4-9~
|
||||||
|
checksum_test@Base 2.7.4-9~
|
||||||
|
chroot_start@Base 2.7.4-9~
|
||||||
|
comm_upsdrv_info@Base 2.7.4-9~
|
||||||
|
command_read_sequence@Base 2.7.4-9~
|
||||||
|
command_write_sequence@Base 2.7.4-9~
|
||||||
|
confpath@Base 2.7.4-9~
|
||||||
|
device_path@Base 2.7.4-9~
|
||||||
|
device_portname@Base 2.7.4-9~
|
||||||
|
dflt_statepath@Base 2.7.4-9~
|
||||||
|
do_lock_port@Base 2.7.4-9~
|
||||||
|
exit_flag@Base 2.7.4-9~
|
||||||
|
fatal_with_errno@Base 2.7.4-9~
|
||||||
|
fatalx@Base 2.7.4-9~
|
||||||
|
g_usec_timeout@Base 2.7.4-9~
|
||||||
|
get_answer@Base 2.7.4-9~
|
||||||
|
get_libname@Base 2.7.4-9~
|
||||||
|
get_user_pwent@Base 2.7.4-9~
|
||||||
|
getval@Base 2.7.4-9~
|
||||||
|
(arch=!hurd-i386)is_ipmi_device_supported@Base 2.7.4-9~
|
||||||
|
nut_debug_level@Base 2.7.4-9~
|
||||||
|
nut_log_level@Base 2.7.4-9~
|
||||||
|
nut_snmp_add_null_var@Base 2.7.4-9~
|
||||||
|
nutscan_add_device_to_device@Base 2.7.4-9~
|
||||||
|
nutscan_add_option_to_device@Base 2.7.4-9~
|
||||||
|
nutscan_avail_avahi@Base 2.7.4-9~
|
||||||
|
nutscan_avail_ipmi@Base 2.7.4-9~
|
||||||
|
nutscan_avail_nut@Base 2.7.4-9~
|
||||||
|
nutscan_avail_snmp@Base 2.7.4-9~
|
||||||
|
nutscan_avail_usb@Base 2.7.4-9~
|
||||||
|
nutscan_avail_xml_http@Base 2.7.4-9~
|
||||||
|
nutscan_cidr_to_ip@Base 2.7.4-9~
|
||||||
|
nutscan_device_type_string@Base 2.7.4-9~
|
||||||
|
nutscan_device_type_strings@Base 2.7.4-9~
|
||||||
|
nutscan_display_parsable@Base 2.7.4-9~
|
||||||
|
nutscan_display_ups_conf@Base 2.7.4-9~
|
||||||
|
nutscan_free@Base 2.7.4-9~
|
||||||
|
nutscan_free_device@Base 2.7.4-9~
|
||||||
|
nutscan_get_serial_ports_list@Base 2.7.4-9~
|
||||||
|
nutscan_init@Base 2.7.4-9~
|
||||||
|
nutscan_ip_iter_inc@Base 2.7.4-9~
|
||||||
|
nutscan_ip_iter_init@Base 2.7.4-9~
|
||||||
|
(arch=!hurd-i386)nutscan_load_ipmi_library@Base 2.7.4-9~
|
||||||
|
nutscan_load_neon_library@Base 2.7.4-9~
|
||||||
|
nutscan_load_snmp_library@Base 2.7.4-9~
|
||||||
|
nutscan_load_upsclient_library@Base 2.7.4-9~
|
||||||
|
nutscan_load_usb_library@Base 2.7.4-9~
|
||||||
|
nutscan_new_device@Base 2.7.4-9~
|
||||||
|
nutscan_rewind_device@Base 2.7.4-9~
|
||||||
|
nutscan_scan_avahi@Base 2.7.4-9~
|
||||||
|
nutscan_scan_eaton_serial@Base 2.7.4-9~
|
||||||
|
nutscan_scan_eaton_serial_q1@Base 2.7.4-9~
|
||||||
|
nutscan_scan_eaton_serial_shut@Base 2.7.4-9~
|
||||||
|
nutscan_scan_eaton_serial_xcp@Base 2.7.4-9~
|
||||||
|
nutscan_scan_ipmi@Base 2.7.4-9~
|
||||||
|
nutscan_scan_nut@Base 2.7.4-9~
|
||||||
|
nutscan_scan_snmp@Base 2.7.4-9~
|
||||||
|
nutscan_scan_usb@Base 2.7.4-9~
|
||||||
|
nutscan_scan_xml_http@Base 2.7.4-9~
|
||||||
|
open_syslog@Base 2.7.4-9~
|
||||||
|
pw_baud_rates@Base 2.7.4-9~
|
||||||
|
pw_comm_setup@Base 2.7.4-9~
|
||||||
|
search_paths@Base 2.7.4-9~
|
||||||
|
select_read@Base 2.7.4-9~
|
||||||
|
select_write@Base 2.7.4-9~
|
||||||
|
send_read_command@Base 2.7.4-9~
|
||||||
|
send_write_command@Base 2.7.4-9~
|
||||||
|
sendsignal@Base 2.7.4-9~
|
||||||
|
sendsignalfn@Base 2.7.4-9~
|
||||||
|
ser_close@Base 2.7.4-9~
|
||||||
|
ser_comm_fail@Base 2.7.4-9~
|
||||||
|
ser_comm_good@Base 2.7.4-9~
|
||||||
|
ser_flush_in@Base 2.7.4-9~
|
||||||
|
ser_flush_io@Base 2.7.4-9~
|
||||||
|
ser_get_buf@Base 2.7.4-9~
|
||||||
|
ser_get_buf_len@Base 2.7.4-9~
|
||||||
|
ser_get_char@Base 2.7.4-9~
|
||||||
|
ser_get_cts@Base 2.7.4-9~
|
||||||
|
ser_get_dcd@Base 2.7.4-9~
|
||||||
|
ser_get_dsr@Base 2.7.4-9~
|
||||||
|
ser_get_line@Base 2.7.4-9~
|
||||||
|
ser_get_line_alert@Base 2.7.4-9~
|
||||||
|
ser_open@Base 2.7.4-9~
|
||||||
|
ser_open_nf@Base 2.7.4-9~
|
||||||
|
ser_send@Base 2.7.4-9~
|
||||||
|
ser_send_buf@Base 2.7.4-9~
|
||||||
|
ser_send_buf_pace@Base 2.7.4-9~
|
||||||
|
ser_send_char@Base 2.7.4-9~
|
||||||
|
ser_send_pace@Base 2.7.4-9~
|
||||||
|
ser_set_dtr@Base 2.7.4-9~
|
||||||
|
ser_set_rts@Base 2.7.4-9~
|
||||||
|
ser_set_speed@Base 2.7.4-9~
|
||||||
|
ser_set_speed_nf@Base 2.7.4-9~
|
||||||
|
shut_synchronise@Base 2.7.4-9~
|
||||||
|
snprintfcat@Base 2.7.4-9~
|
||||||
|
str_is_double@Base 2.7.4-9~
|
||||||
|
str_is_double_strict@Base 2.7.4-9~
|
||||||
|
str_is_int@Base 2.7.4-9~
|
||||||
|
str_is_int_strict@Base 2.7.4-9~
|
||||||
|
str_is_long@Base 2.7.4-9~
|
||||||
|
str_is_long_strict@Base 2.7.4-9~
|
||||||
|
str_is_short@Base 2.7.4-9~
|
||||||
|
str_is_short_strict@Base 2.7.4-9~
|
||||||
|
str_is_uint@Base 2.7.4-9~
|
||||||
|
str_is_uint_strict@Base 2.7.4-9~
|
||||||
|
str_is_ulong@Base 2.7.4-9~
|
||||||
|
str_is_ulong_strict@Base 2.7.4-9~
|
||||||
|
str_is_ushort@Base 2.7.4-9~
|
||||||
|
str_is_ushort_strict@Base 2.7.4-9~
|
||||||
|
str_ltrim@Base 2.7.4-9~
|
||||||
|
str_ltrim_m@Base 2.7.4-9~
|
||||||
|
str_ltrim_space@Base 2.7.4-9~
|
||||||
|
str_rtrim@Base 2.7.4-9~
|
||||||
|
str_rtrim_m@Base 2.7.4-9~
|
||||||
|
str_rtrim_space@Base 2.7.4-9~
|
||||||
|
str_to_double@Base 2.7.4-9~
|
||||||
|
str_to_double_strict@Base 2.7.4-9~
|
||||||
|
str_to_int@Base 2.7.4-9~
|
||||||
|
str_to_int_strict@Base 2.7.4-9~
|
||||||
|
str_to_long@Base 2.7.4-9~
|
||||||
|
str_to_long_strict@Base 2.7.4-9~
|
||||||
|
str_to_short@Base 2.7.4-9~
|
||||||
|
str_to_short_strict@Base 2.7.4-9~
|
||||||
|
str_to_uint@Base 2.7.4-9~
|
||||||
|
str_to_uint_strict@Base 2.7.4-9~
|
||||||
|
str_to_ulong@Base 2.7.4-9~
|
||||||
|
str_to_ulong_strict@Base 2.7.4-9~
|
||||||
|
str_to_ushort@Base 2.7.4-9~
|
||||||
|
str_to_ushort_strict@Base 2.7.4-9~
|
||||||
|
str_trim@Base 2.7.4-9~
|
||||||
|
str_trim_m@Base 2.7.4-9~
|
||||||
|
str_trim_space@Base 2.7.4-9~
|
||||||
|
syslogbit_set@Base 2.7.4-9~
|
||||||
|
upsdebug_ascii@Base 2.7.4-9~
|
||||||
|
upsdebug_hex@Base 2.7.4-9~
|
||||||
|
upsdebug_with_errno@Base 2.7.4-9~
|
||||||
|
upsdebugx@Base 2.7.4-9~
|
||||||
|
upsdrv_cleanup@Base 2.7.4-9~
|
||||||
|
upsdrv_comm_good@Base 2.7.4-9~
|
||||||
|
upsdrv_initups@Base 2.7.4-9~
|
||||||
|
upsdrv_reconnect@Base 2.7.4-9~
|
||||||
|
upsfd@Base 2.7.4-9~
|
||||||
|
upslog_with_errno@Base 2.7.4-9~
|
||||||
|
upslogx@Base 2.7.4-9~
|
||||||
|
writepid@Base 2.7.4-9~
|
||||||
|
xbasename@Base 2.7.4-9~
|
||||||
|
xcalloc@Base 2.7.4-9~
|
||||||
|
xmalloc@Base 2.7.4-9~
|
||||||
|
xrealloc@Base 2.7.4-9~
|
||||||
|
xstrdup@Base 2.7.4-9~
|
1
debian/libups-nut-perl.install
vendored
Normal file
1
debian/libups-nut-perl.install
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
scripts/perl/Nut.pm /usr/share/perl5/UPS/
|
5
debian/libupsclient-dev.install
vendored
Normal file
5
debian/libupsclient-dev.install
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
usr/include/parseconf.h
|
||||||
|
usr/include/upsclient.h
|
||||||
|
usr/lib/*/libupsclient.a
|
||||||
|
usr/lib/*/libupsclient.so
|
||||||
|
usr/lib/*/pkgconfig/libupsclient.pc
|
1
debian/libupsclient4.install
vendored
Normal file
1
debian/libupsclient4.install
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
lib/*/libupsclient.so.*
|
114
debian/libupsclient4.symbols
vendored
Normal file
114
debian/libupsclient4.symbols
vendored
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
libupsclient.so.4 libupsclient4 #MINVER#
|
||||||
|
* Build-Depends-Package: libupsclient-dev
|
||||||
|
UPS_VERSION@Base 2.7.2
|
||||||
|
altpidpath@Base 2.7.2
|
||||||
|
background@Base 2.7.2
|
||||||
|
become_user@Base 2.7.2
|
||||||
|
chroot_start@Base 2.7.2
|
||||||
|
confpath@Base 2.7.2
|
||||||
|
dflt_statepath@Base 2.7.2
|
||||||
|
fatal_with_errno@Base 2.7.2
|
||||||
|
fatalx@Base 2.7.2
|
||||||
|
get_user_pwent@Base 2.7.2
|
||||||
|
nut_debug_level@Base 2.7.2
|
||||||
|
nut_log_level@Base 2.7.2
|
||||||
|
open_syslog@Base 2.7.2
|
||||||
|
pconf_char@Base 2.7.2
|
||||||
|
pconf_encode@Base 2.7.2
|
||||||
|
pconf_file_begin@Base 2.7.2
|
||||||
|
pconf_file_next@Base 2.7.2
|
||||||
|
pconf_finish@Base 2.7.2
|
||||||
|
pconf_init@Base 2.7.2
|
||||||
|
pconf_line@Base 2.7.2
|
||||||
|
pconf_parse_error@Base 2.7.2
|
||||||
|
select_read@Base 2.7.2
|
||||||
|
select_write@Base 2.7.2
|
||||||
|
sendsignal@Base 2.7.2
|
||||||
|
sendsignalfn@Base 2.7.2
|
||||||
|
snprintfcat@Base 2.7.2
|
||||||
|
state_addcmd@Base 2.7.2
|
||||||
|
state_addenum@Base 2.7.2
|
||||||
|
state_addrange@Base 2.7.2
|
||||||
|
state_cmdfree@Base 2.7.2
|
||||||
|
state_delcmd@Base 2.7.2
|
||||||
|
state_delenum@Base 2.7.2
|
||||||
|
state_delinfo@Base 2.7.2
|
||||||
|
state_delrange@Base 2.7.2
|
||||||
|
state_getaux@Base 2.7.2
|
||||||
|
state_getenumlist@Base 2.7.2
|
||||||
|
state_getflags@Base 2.7.2
|
||||||
|
state_getinfo@Base 2.7.2
|
||||||
|
state_getrangelist@Base 2.7.2
|
||||||
|
state_infofree@Base 2.7.2
|
||||||
|
state_setaux@Base 2.7.2
|
||||||
|
state_setflags@Base 2.7.2
|
||||||
|
state_setinfo@Base 2.7.2
|
||||||
|
state_tree_find@Base 2.7.2
|
||||||
|
str_is_double@Base 2.7.4
|
||||||
|
str_is_double_strict@Base 2.7.4
|
||||||
|
str_is_int@Base 2.7.4
|
||||||
|
str_is_int_strict@Base 2.7.4
|
||||||
|
str_is_long@Base 2.7.4
|
||||||
|
str_is_long_strict@Base 2.7.4
|
||||||
|
str_is_short@Base 2.7.4
|
||||||
|
str_is_short_strict@Base 2.7.4
|
||||||
|
str_is_uint@Base 2.7.4
|
||||||
|
str_is_uint_strict@Base 2.7.4
|
||||||
|
str_is_ulong@Base 2.7.4
|
||||||
|
str_is_ulong_strict@Base 2.7.4
|
||||||
|
str_is_ushort@Base 2.7.4
|
||||||
|
str_is_ushort_strict@Base 2.7.4
|
||||||
|
str_ltrim@Base 2.7.4
|
||||||
|
str_ltrim_m@Base 2.7.4
|
||||||
|
str_ltrim_space@Base 2.7.4
|
||||||
|
str_rtrim@Base 2.7.4
|
||||||
|
str_rtrim_m@Base 2.7.4
|
||||||
|
str_rtrim_space@Base 2.7.4
|
||||||
|
str_to_double@Base 2.7.4
|
||||||
|
str_to_double_strict@Base 2.7.4
|
||||||
|
str_to_int@Base 2.7.4
|
||||||
|
str_to_int_strict@Base 2.7.4
|
||||||
|
str_to_long@Base 2.7.4
|
||||||
|
str_to_long_strict@Base 2.7.4
|
||||||
|
str_to_short@Base 2.7.4
|
||||||
|
str_to_short_strict@Base 2.7.4
|
||||||
|
str_to_uint@Base 2.7.4
|
||||||
|
str_to_uint_strict@Base 2.7.4
|
||||||
|
str_to_ulong@Base 2.7.4
|
||||||
|
str_to_ulong_strict@Base 2.7.4
|
||||||
|
str_to_ushort@Base 2.7.4
|
||||||
|
str_to_ushort_strict@Base 2.7.4
|
||||||
|
str_trim@Base 2.7.4
|
||||||
|
str_trim_m@Base 2.7.4
|
||||||
|
str_trim_space@Base 2.7.4
|
||||||
|
syslogbit_set@Base 2.7.2
|
||||||
|
upscli_add_host_cert@Base 2.7.2
|
||||||
|
upscli_cleanup@Base 2.7.2
|
||||||
|
upscli_connect@Base 2.7.2
|
||||||
|
upscli_disconnect@Base 2.7.2
|
||||||
|
upscli_errlist@Base 2.7.2
|
||||||
|
upscli_fd@Base 2.7.2
|
||||||
|
upscli_get@Base 2.7.2
|
||||||
|
upscli_init@Base 2.7.2
|
||||||
|
upscli_list_next@Base 2.7.2
|
||||||
|
upscli_list_start@Base 2.7.2
|
||||||
|
upscli_readline@Base 2.7.2
|
||||||
|
upscli_sendline@Base 2.7.2
|
||||||
|
upscli_splitaddr@Base 2.7.2
|
||||||
|
upscli_splitname@Base 2.7.2
|
||||||
|
upscli_ssl@Base 2.7.2
|
||||||
|
upscli_strerror@Base 2.7.2
|
||||||
|
upscli_tryconnect@Base 2.7.2
|
||||||
|
upscli_upserror@Base 2.7.2
|
||||||
|
upsdebug_ascii@Base 2.7.2
|
||||||
|
upsdebug_hex@Base 2.7.2
|
||||||
|
upsdebug_with_errno@Base 2.7.2
|
||||||
|
upsdebugx@Base 2.7.2
|
||||||
|
upslog_with_errno@Base 2.7.2
|
||||||
|
upslogx@Base 2.7.2
|
||||||
|
writepid@Base 2.7.2
|
||||||
|
xbasename@Base 2.7.2
|
||||||
|
xcalloc@Base 2.7.2
|
||||||
|
xmalloc@Base 2.7.2
|
||||||
|
xrealloc@Base 2.7.2
|
||||||
|
xstrdup@Base 2.7.2
|
BIN
debian/local/nut-monitor.png
vendored
Normal file
BIN
debian/local/nut-monitor.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue