Imported Upstream version 2.4.3
This commit is contained in:
commit
26fb71b504
446 changed files with 148951 additions and 0 deletions
53
clients/Makefile.am
Normal file
53
clients/Makefile.am
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Network UPS Tools: clients
|
||||
|
||||
# by default, link programs in this directory with libcommon.a
|
||||
LDADD = ../common/libcommon.a libupsclient.la $(NETLIBS)
|
||||
if WITH_SSL
|
||||
LDADD += $(LIBSSL_LDFLAGS)
|
||||
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 WITH_DEV
|
||||
include_HEADERS = upsclient.h ../include/parseconf.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 = ../common/libcommon.a ../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 = ../common/libparseconf.la
|
||||
if WITH_SSL
|
||||
libupsclient_la_LIBADD += $(LIBSSL_LDFLAGS)
|
||||
endif
|
||||
libupsclient_la_LDFLAGS = -version-info 1:0:0
|
912
clients/Makefile.in
Normal file
912
clients/Makefile.in
Normal file
|
@ -0,0 +1,912 @@
|
|||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Network UPS Tools: clients
|
||||
|
||||
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
@WITH_SSL_TRUE@am__append_1 = $(LIBSSL_LDFLAGS)
|
||||
@WITH_SSL_TRUE@am__append_2 = $(LIBSSL_CFLAGS)
|
||||
@WITH_CGI_TRUE@am__append_3 = $(LIBGD_CFLAGS)
|
||||
bin_PROGRAMS = upsc$(EXEEXT) upslog$(EXEEXT) upsrw$(EXEEXT) \
|
||||
upscmd$(EXEEXT)
|
||||
sbin_PROGRAMS = upsmon$(EXEEXT) upssched$(EXEEXT)
|
||||
@WITH_CGI_TRUE@cgiexec_PROGRAMS = upsstats.cgi$(EXEEXT) \
|
||||
@WITH_CGI_TRUE@ upsimage.cgi$(EXEEXT) upsset.cgi$(EXEEXT)
|
||||
@WITH_SSL_TRUE@am__append_4 = $(LIBSSL_LDFLAGS)
|
||||
subdir = clients
|
||||
DIST_COMMON = $(am__include_HEADERS_DIST) $(dist_bin_SCRIPTS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_create_stdint_h.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_ipv6.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libgd.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libhal.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libpowerman.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libssl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libusb.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libwrap.m4 \
|
||||
$(top_srcdir)/m4/nut_check_os.m4 \
|
||||
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" \
|
||||
"$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
am__DEPENDENCIES_1 =
|
||||
@WITH_SSL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libupsclient_la_DEPENDENCIES = ../common/libparseconf.la \
|
||||
$(am__DEPENDENCIES_2)
|
||||
am_libupsclient_la_OBJECTS = upsclient.lo
|
||||
libupsclient_la_OBJECTS = $(am_libupsclient_la_OBJECTS)
|
||||
libupsclient_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libupsclient_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
PROGRAMS = $(bin_PROGRAMS) $(cgiexec_PROGRAMS) $(sbin_PROGRAMS)
|
||||
am_upsc_OBJECTS = upsc.$(OBJEXT)
|
||||
upsc_OBJECTS = $(am_upsc_OBJECTS)
|
||||
upsc_LDADD = $(LDADD)
|
||||
upsc_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upscmd_OBJECTS = upscmd.$(OBJEXT)
|
||||
upscmd_OBJECTS = $(am_upscmd_OBJECTS)
|
||||
upscmd_LDADD = $(LDADD)
|
||||
upscmd_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upsimage_cgi_OBJECTS = upsimage.$(OBJEXT) cgilib.$(OBJEXT)
|
||||
upsimage_cgi_OBJECTS = $(am_upsimage_cgi_OBJECTS)
|
||||
am__DEPENDENCIES_3 = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsimage_cgi_DEPENDENCIES = $(am__DEPENDENCIES_3) \
|
||||
$(am__DEPENDENCIES_1)
|
||||
am_upslog_OBJECTS = upslog.$(OBJEXT)
|
||||
upslog_OBJECTS = $(am_upslog_OBJECTS)
|
||||
upslog_LDADD = $(LDADD)
|
||||
upslog_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upsmon_OBJECTS = upsmon.$(OBJEXT)
|
||||
upsmon_OBJECTS = $(am_upsmon_OBJECTS)
|
||||
upsmon_LDADD = $(LDADD)
|
||||
upsmon_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upsrw_OBJECTS = upsrw.$(OBJEXT)
|
||||
upsrw_OBJECTS = $(am_upsrw_OBJECTS)
|
||||
upsrw_LDADD = $(LDADD)
|
||||
upsrw_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upssched_OBJECTS = upssched.$(OBJEXT)
|
||||
upssched_OBJECTS = $(am_upssched_OBJECTS)
|
||||
upssched_DEPENDENCIES = ../common/libcommon.a \
|
||||
../common/libparseconf.la $(am__DEPENDENCIES_1)
|
||||
am_upsset_cgi_OBJECTS = upsset.$(OBJEXT) cgilib.$(OBJEXT)
|
||||
upsset_cgi_OBJECTS = $(am_upsset_cgi_OBJECTS)
|
||||
upsset_cgi_LDADD = $(LDADD)
|
||||
upsset_cgi_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upsstats_cgi_OBJECTS = upsstats.$(OBJEXT) cgilib.$(OBJEXT)
|
||||
upsstats_cgi_OBJECTS = $(am_upsstats_cgi_OBJECTS)
|
||||
upsstats_cgi_LDADD = $(LDADD)
|
||||
upsstats_cgi_DEPENDENCIES = ../common/libcommon.a libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
SCRIPTS = $(dist_bin_SCRIPTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libupsclient_la_SOURCES) $(upsc_SOURCES) $(upscmd_SOURCES) \
|
||||
$(upsimage_cgi_SOURCES) $(upslog_SOURCES) $(upsmon_SOURCES) \
|
||||
$(upsrw_SOURCES) $(upssched_SOURCES) $(upsset_cgi_SOURCES) \
|
||||
$(upsstats_cgi_SOURCES)
|
||||
DIST_SOURCES = $(libupsclient_la_SOURCES) $(upsc_SOURCES) \
|
||||
$(upscmd_SOURCES) $(upsimage_cgi_SOURCES) $(upslog_SOURCES) \
|
||||
$(upsmon_SOURCES) $(upsrw_SOURCES) $(upssched_SOURCES) \
|
||||
$(upsset_cgi_SOURCES) $(upsstats_cgi_SOURCES)
|
||||
am__include_HEADERS_DIST = upsclient.h ../include/parseconf.h
|
||||
HEADERS = $(include_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BINDIR = @BINDIR@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CONFPATH = @CONFPATH@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@
|
||||
HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@
|
||||
HAL_FDI_PATH = @HAL_FDI_PATH@
|
||||
HAL_USER = @HAL_USER@
|
||||
HAVE_GLIB_2_14 = @HAVE_GLIB_2_14@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||
LIBHAL_CFLAGS = @LIBHAL_CFLAGS@
|
||||
LIBHAL_LDFLAGS = @LIBHAL_LDFLAGS@
|
||||
LIBNEON_CFLAGS = @LIBNEON_CFLAGS@
|
||||
LIBNEON_LDFLAGS = @LIBNEON_LDFLAGS@
|
||||
LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@
|
||||
LIBNETSNMP_LDFLAGS = @LIBNETSNMP_LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@
|
||||
LIBPOWERMAN_LDFLAGS = @LIBPOWERMAN_LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
LIBSSL_CFLAGS = @LIBSSL_CFLAGS@
|
||||
LIBSSL_LDFLAGS = @LIBSSL_LDFLAGS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||
LIBUSB_LDFLAGS = @LIBUSB_LDFLAGS@
|
||||
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||
LIBWRAP_LDFLAGS = @LIBWRAP_LDFLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NETLIBS = @NETLIBS@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS_NAME = @OS_NAME@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||
RUN_AS_USER = @RUN_AS_USER@
|
||||
SED = @SED@
|
||||
SERLIBS = @SERLIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STATEPATH = @STATEPATH@
|
||||
STRIP = @STRIP@
|
||||
SUN_LIBUSB = @SUN_LIBUSB@
|
||||
VERSION = @VERSION@
|
||||
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
cgiexecdir = @cgiexecdir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
driverexecdir = @driverexecdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
hotplugdir = @hotplugdir@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_ECHO = @lt_ECHO@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
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@
|
||||
|
||||
# by default, link programs in this directory with libcommon.a
|
||||
LDADD = ../common/libcommon.a libupsclient.la $(NETLIBS) \
|
||||
$(am__append_1)
|
||||
|
||||
# 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 $(am__append_2) $(am__append_3)
|
||||
dist_bin_SCRIPTS = upssched-cmd
|
||||
lib_LTLIBRARIES = libupsclient.la
|
||||
@WITH_DEV_TRUE@include_HEADERS = upsclient.h ../include/parseconf.h
|
||||
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 = ../common/libcommon.a ../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 = ../common/libparseconf.la $(am__append_4)
|
||||
libupsclient_la_LDFLAGS = -version-info 1:0:0
|
||||
all: 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 clients/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu clients/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libupsclient.la: $(libupsclient_la_OBJECTS) $(libupsclient_la_DEPENDENCIES)
|
||||
$(libupsclient_la_LINK) -rpath $(libdir) $(libupsclient_la_OBJECTS) $(libupsclient_la_LIBADD) $(LIBS)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
then echo "$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
|
||||
sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) files[d] = files[d] " " $$1; \
|
||||
else { print "f", $$3 "/" $$4, $$1; } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
|
||||
-e 's/$$/$(EXEEXT)/' `; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(bindir)" && rm -f $$files
|
||||
|
||||
clean-binPROGRAMS:
|
||||
@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
install-cgiexecPROGRAMS: $(cgiexec_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(cgiexecdir)" || $(MKDIR_P) "$(DESTDIR)$(cgiexecdir)"
|
||||
@list='$(cgiexec_PROGRAMS)'; test -n "$(cgiexecdir)" || list=; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
then echo "$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
|
||||
sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) files[d] = files[d] " " $$1; \
|
||||
else { print "f", $$3 "/" $$4, $$1; } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cgiexecdir)$$dir'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cgiexecdir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-cgiexecPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(cgiexec_PROGRAMS)'; test -n "$(cgiexecdir)" || list=; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
|
||||
-e 's/$$/$(EXEEXT)/' `; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(cgiexecdir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(cgiexecdir)" && rm -f $$files
|
||||
|
||||
clean-cgiexecPROGRAMS:
|
||||
@list='$(cgiexec_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
then echo "$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
|
||||
sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) files[d] = files[d] " " $$1; \
|
||||
else { print "f", $$3 "/" $$4, $$1; } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-sbinPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
|
||||
-e 's/$$/$(EXEEXT)/' `; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
|
||||
|
||||
clean-sbinPROGRAMS:
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
upsc$(EXEEXT): $(upsc_OBJECTS) $(upsc_DEPENDENCIES)
|
||||
@rm -f upsc$(EXEEXT)
|
||||
$(LINK) $(upsc_OBJECTS) $(upsc_LDADD) $(LIBS)
|
||||
upscmd$(EXEEXT): $(upscmd_OBJECTS) $(upscmd_DEPENDENCIES)
|
||||
@rm -f upscmd$(EXEEXT)
|
||||
$(LINK) $(upscmd_OBJECTS) $(upscmd_LDADD) $(LIBS)
|
||||
upsimage.cgi$(EXEEXT): $(upsimage_cgi_OBJECTS) $(upsimage_cgi_DEPENDENCIES)
|
||||
@rm -f upsimage.cgi$(EXEEXT)
|
||||
$(LINK) $(upsimage_cgi_OBJECTS) $(upsimage_cgi_LDADD) $(LIBS)
|
||||
upslog$(EXEEXT): $(upslog_OBJECTS) $(upslog_DEPENDENCIES)
|
||||
@rm -f upslog$(EXEEXT)
|
||||
$(LINK) $(upslog_OBJECTS) $(upslog_LDADD) $(LIBS)
|
||||
upsmon$(EXEEXT): $(upsmon_OBJECTS) $(upsmon_DEPENDENCIES)
|
||||
@rm -f upsmon$(EXEEXT)
|
||||
$(LINK) $(upsmon_OBJECTS) $(upsmon_LDADD) $(LIBS)
|
||||
upsrw$(EXEEXT): $(upsrw_OBJECTS) $(upsrw_DEPENDENCIES)
|
||||
@rm -f upsrw$(EXEEXT)
|
||||
$(LINK) $(upsrw_OBJECTS) $(upsrw_LDADD) $(LIBS)
|
||||
upssched$(EXEEXT): $(upssched_OBJECTS) $(upssched_DEPENDENCIES)
|
||||
@rm -f upssched$(EXEEXT)
|
||||
$(LINK) $(upssched_OBJECTS) $(upssched_LDADD) $(LIBS)
|
||||
upsset.cgi$(EXEEXT): $(upsset_cgi_OBJECTS) $(upsset_cgi_DEPENDENCIES)
|
||||
@rm -f upsset.cgi$(EXEEXT)
|
||||
$(LINK) $(upsset_cgi_OBJECTS) $(upsset_cgi_LDADD) $(LIBS)
|
||||
upsstats.cgi$(EXEEXT): $(upsstats_cgi_OBJECTS) $(upsstats_cgi_DEPENDENCIES)
|
||||
@rm -f upsstats.cgi$(EXEEXT)
|
||||
$(LINK) $(upsstats_cgi_OBJECTS) $(upsstats_cgi_LDADD) $(LIBS)
|
||||
install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n' \
|
||||
-e 'h;s|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) { files[d] = files[d] " " $$1; \
|
||||
if (++n[d] == $(am__install_max)) { \
|
||||
print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
|
||||
else { print "f", d "/" $$4, $$1 } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
|
||||
$(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-dist_binSCRIPTS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 's,.*/,,;$(transform)'`; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(bindir)" && rm -f $$files
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgilib.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsc.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsclient.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upscmd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsimage.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upslog.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsmon.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsrw.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upssched.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsset.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsstats.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-includeHEADERS: $(include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-includeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(includedir)" && rm -f $$files
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(HEADERS)
|
||||
install-binPROGRAMS: install-libLTLIBRARIES
|
||||
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-cgiexecPROGRAMS clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool clean-sbinPROGRAMS \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-includeHEADERS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-binPROGRAMS install-cgiexecPROGRAMS \
|
||||
install-dist_binSCRIPTS install-libLTLIBRARIES \
|
||||
install-sbinPROGRAMS
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-binPROGRAMS uninstall-cgiexecPROGRAMS \
|
||||
uninstall-dist_binSCRIPTS uninstall-includeHEADERS \
|
||||
uninstall-libLTLIBRARIES uninstall-sbinPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
|
||||
clean-cgiexecPROGRAMS clean-generic clean-libLTLIBRARIES \
|
||||
clean-libtool clean-sbinPROGRAMS ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-binPROGRAMS install-cgiexecPROGRAMS \
|
||||
install-data install-data-am install-dist_binSCRIPTS \
|
||||
install-dvi install-dvi-am install-exec install-exec-am \
|
||||
install-html install-html-am install-includeHEADERS \
|
||||
install-info install-info-am install-libLTLIBRARIES \
|
||||
install-man install-pdf install-pdf-am install-ps \
|
||||
install-ps-am install-sbinPROGRAMS install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-binPROGRAMS \
|
||||
uninstall-cgiexecPROGRAMS uninstall-dist_binSCRIPTS \
|
||||
uninstall-includeHEADERS uninstall-libLTLIBRARIES \
|
||||
uninstall-sbinPROGRAMS
|
||||
|
||||
|
||||
# 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:
|
202
clients/cgilib.c
Normal file
202
clients/cgilib.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
/* 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[0]))
|
||||
fatalx(EXIT_FAILURE, "bad escape char");
|
||||
ch = strtol(hex, NULL, 16);
|
||||
|
||||
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 */
|
||||
}
|
31
clients/cgilib.h
Normal file
31
clients/cgilib.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
/* 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);
|
||||
|
37
clients/status.h
Normal file
37
clients/status.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
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 }
|
||||
};
|
229
clients/upsc.c
Normal file
229
clients/upsc.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/* upsc - simple "client" to test communications
|
||||
|
||||
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 "common.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.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("\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");
|
||||
}
|
||||
|
||||
static void printvar(const char *var)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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 %d args, need at least %d)", numa, numq);
|
||||
}
|
||||
|
||||
printf("%s\n", answer[3]);
|
||||
}
|
||||
|
||||
static void list_vars(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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 %d args, need at least 4)", numa);
|
||||
}
|
||||
|
||||
printf("%s: %s\n", answer[2], answer[3]);
|
||||
}
|
||||
}
|
||||
|
||||
static void list_upses(int verbose)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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 %d args, need at least 3)", numa);
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
printf("%s: %s\n", answer[1], answer[2]);
|
||||
} else {
|
||||
printf("%s\n", answer[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void clean_exit(void)
|
||||
{
|
||||
if (ups) {
|
||||
upscli_disconnect(ups);
|
||||
}
|
||||
|
||||
free(upsname);
|
||||
free(hostname);
|
||||
free(ups);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, port;
|
||||
int varlist = 0, verbose = 0;
|
||||
const char *prog = xbasename(argv[0]);
|
||||
|
||||
while ((i = getopt(argc, argv, "+hlLV")) != -1) {
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 'L':
|
||||
verbose = 1;
|
||||
case 'l':
|
||||
varlist = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||
|
||||
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 (argc > 1) {
|
||||
printvar(argv[1]);
|
||||
} else {
|
||||
list_vars();
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
1108
clients/upsclient.c
Normal file
1108
clients/upsclient.c
Normal file
File diff suppressed because it is too large
Load diff
166
clients/upsclient.h
Normal file
166
clients/upsclient.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* 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 HAVE_SSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UPSCLI_ERRBUF_LEN 256
|
||||
#define UPSCLI_NETBUF_LEN 512 /* network i/o buffer */
|
||||
|
||||
#include "parseconf.h"
|
||||
|
||||
typedef struct {
|
||||
char *host;
|
||||
int port;
|
||||
int fd;
|
||||
int flags;
|
||||
int upserror;
|
||||
int syserrno;
|
||||
int upsclient_magic;
|
||||
|
||||
PCONF_CTX_t pc_ctx;
|
||||
|
||||
char errbuf[UPSCLI_ERRBUF_LEN];
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
SSL_CTX *ssl_ctx;
|
||||
SSL *ssl;
|
||||
#else
|
||||
void *ssl_ctx;
|
||||
void *ssl;
|
||||
#endif
|
||||
|
||||
char readbuf[64];
|
||||
size_t readlen;
|
||||
size_t readidx;
|
||||
|
||||
} UPSCONN_t;
|
||||
|
||||
const char *upscli_strerror(UPSCONN_t *ups);
|
||||
|
||||
int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags);
|
||||
|
||||
/* --- functions that only use the new names --- */
|
||||
|
||||
int upscli_get(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer);
|
||||
|
||||
int upscli_list_start(UPSCONN_t *ups, unsigned int numq, const char **query);
|
||||
|
||||
int upscli_list_next(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer);
|
||||
|
||||
int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen);
|
||||
|
||||
int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen);
|
||||
|
||||
int upscli_splitname(const char *buf, char **upsname, char **hostname,
|
||||
int *port);
|
||||
|
||||
int upscli_splitaddr(const char *buf, char **hostname, int *port);
|
||||
|
||||
int upscli_sslcert(UPSCONN_t *ups, const char *file, const char *path, int verify);
|
||||
|
||||
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 */
|
||||
#ifdef HAVE_IPV6
|
||||
#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */
|
||||
#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UPSCLIENT_H_SEEN */
|
311
clients/upscmd.c
Normal file
311
clients/upscmd.c
Normal file
|
@ -0,0 +1,311 @@
|
|||
/* upscmd - simple "client" to test instant commands via upsd
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "upsclient.h"
|
||||
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
static UPSCONN_t *ups = NULL;
|
||||
|
||||
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>] <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("\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;
|
||||
unsigned int 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;
|
||||
unsigned int 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 %d 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_cmd(char **argv, const int argc)
|
||||
{
|
||||
char buf[SMALLBUF];
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
static void clean_exit(void)
|
||||
{
|
||||
if (ups) {
|
||||
upscli_disconnect(ups);
|
||||
}
|
||||
|
||||
free(upsname);
|
||||
free(hostname);
|
||||
free(ups);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, ret, port;
|
||||
int have_un = 0, have_pw = 0, cmdlist = 0;
|
||||
char buf[SMALLBUF], username[SMALLBUF], password[SMALLBUF];
|
||||
const char *prog = xbasename(argv[0]);
|
||||
|
||||
while ((i = getopt(argc, argv, "+lhu:p:V")) != -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 'V':
|
||||
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
do_cmd(&argv[1], argc - 1);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
731
clients/upsimage.c
Normal file
731
clients/upsimage.c
Normal file
|
@ -0,0 +1,731 @@
|
|||
/* 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 "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 int 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)
|
||||
{
|
||||
int i, v;
|
||||
|
||||
/* 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 = strtoul(value + 2, (char **)NULL, 16);
|
||||
else
|
||||
v = 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
|
||||
imgarg[i].val = 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)
|
||||
{
|
||||
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 - 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 */
|
||||
)
|
||||
{
|
||||
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 = (1 - (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 */
|
||||
snprintf(text, sizeof(text), format, value);
|
||||
gdImageString(im, gdFontMediumBold,
|
||||
(width - 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, ...)
|
||||
{
|
||||
gdImagePtr im;
|
||||
int back_color, summary_color;
|
||||
int width, height;
|
||||
char msg[SMALLBUF];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
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 - strlen(msg)*gdFontMediumBold->w)/2,
|
||||
(height - gdFontMediumBold->h)/2,
|
||||
(unsigned char *) msg, summary_color);
|
||||
else
|
||||
gdImageStringUp(im, gdFontMediumBold,
|
||||
(width - gdFontMediumBold->h)/2,
|
||||
(height + strlen(msg)*gdFontMediumBold->w)/2,
|
||||
(unsigned char *) msg, summary_color);
|
||||
|
||||
drawimage(im);
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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 = 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 = nom/2*1.6+1; /* Assume a 2V cell is dead at 1.6V */
|
||||
}
|
||||
|
||||
if(max == -1) {
|
||||
max = nom/2*2.3+1; /* Assume 2.3V float charge voltage */
|
||||
}
|
||||
|
||||
if (nom < min || nom > max)
|
||||
nom = -1;
|
||||
|
||||
|
||||
deviation = -(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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int hi = get_imgarg("tempmax");
|
||||
int lo = get_imgarg("tempmin");
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
unsigned int 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;
|
||||
|
||||
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");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (upscli_connect(&ups, hostname, port, 0) < 0) {
|
||||
noimage("Can't connect to server:\n%s\n",
|
||||
upscli_strerror(&ups));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
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");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* 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");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct 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 }
|
||||
};
|
60
clients/upsimagearg.h
Normal file
60
clients/upsimagearg.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
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 }
|
||||
};
|
||||
|
||||
struct imgvar_t {
|
||||
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*);
|
||||
};
|
||||
|
||||
extern struct imgvar_t imgvar[];
|
532
clients/upslog.c
Normal file
532
clients/upslog.c
Normal file
|
@ -0,0 +1,532 @@
|
|||
/* 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 "upsclient.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "timehead.h"
|
||||
#include "upslog.h"
|
||||
|
||||
static int port, reopen_flag = 0, exit_flag = 0;
|
||||
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 struct 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;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
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\n");
|
||||
printf(" -p <pidbase> - Base name for PID file (defaults to \"upslog\")\n");
|
||||
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];
|
||||
|
||||
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)
|
||||
{
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%s", monhost);
|
||||
}
|
||||
|
||||
static void do_pid(const char *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;
|
||||
|
||||
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(&tod));
|
||||
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%s", timebuf);
|
||||
|
||||
free(format);
|
||||
}
|
||||
|
||||
static void getvar(const char *var)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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;
|
||||
|
||||
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)
|
||||
{
|
||||
struct flist_t *tmp, *last;
|
||||
|
||||
tmp = last = fhead;
|
||||
|
||||
while (tmp) {
|
||||
last = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = xmalloc(sizeof(struct 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)
|
||||
{
|
||||
unsigned int i;
|
||||
int j, found, 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)
|
||||
{
|
||||
struct 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;
|
||||
char *prog = NULL;
|
||||
time_t now, nextpoll = 0;
|
||||
const char *user = NULL;
|
||||
struct passwd *new_uid = NULL;
|
||||
const char *pidfilebase = "upslog";
|
||||
|
||||
logformat = DEFAULT_LOGFORMAT;
|
||||
user = RUN_AS_USER;
|
||||
|
||||
printf("Network UPS Tools upslog %s\n", UPS_VERSION);
|
||||
|
||||
prog = argv[0];
|
||||
|
||||
while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:")) != -1) {
|
||||
switch(i) {
|
||||
case 'h':
|
||||
help(prog);
|
||||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
openlog("upslog", LOG_PID, LOG_FACILITY);
|
||||
|
||||
if (logfile != stdout)
|
||||
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(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);
|
||||
}
|
29
clients/upslog.h
Normal file
29
clients/upslog.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* upslog.h - table of functions for handling various logging functions */
|
||||
|
||||
/* function list */
|
||||
struct flist_t {
|
||||
void (*fptr)(const char *arg);
|
||||
const char *arg;
|
||||
struct flist_t *next;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
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(*)())(NULL) }
|
||||
};
|
2046
clients/upsmon.c
Normal file
2046
clients/upsmon.c
Normal file
File diff suppressed because it is too large
Load diff
114
clients/upsmon.h
Normal file
114
clients/upsmon.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
/* flags for ups->status */
|
||||
|
||||
#define ST_ONLINE 0x001 /* UPS is on line (OL) */
|
||||
#define ST_ONBATT 0x002 /* UPS is on battery (OB) */
|
||||
#define ST_LOWBATT 0x004 /* UPS has a low battery (LB) */
|
||||
#define ST_FSD 0x008 /* master has set forced shutdown flag */
|
||||
#define ST_MASTER 0x010 /* we are the master on this UPS */
|
||||
/* was ST_ALIVE 0x020 */
|
||||
#define ST_LOGIN 0x040 /* we are logged into this UPS */
|
||||
/* was ST_FIRST 0x080 */
|
||||
#define ST_CONNECTED 0x100 /* upscli_connect returned OK */
|
||||
|
||||
/* required contents of flag file */
|
||||
#define SDMAGIC "upsmon-shutdown-file"
|
||||
|
||||
/* 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 */
|
||||
int port; /* just the port */
|
||||
|
||||
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 /* Master 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 awhile */
|
||||
#define NOTIFY_NOPARENT 9 /* privileged parent process died */
|
||||
|
||||
/* notify flag values */
|
||||
|
||||
#define NOTIFY_IGNORE 1 /* don't do anything */
|
||||
#define NOTIFY_SYSLOG 2 /* send the msg to the syslog */
|
||||
#define NOTIFY_WALL 4 /* send the msg to all users */
|
||||
#define NOTIFY_EXEC 8 /* 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 */
|
||||
|
||||
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 },
|
||||
{ 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 */
|
508
clients/upsrw.c
Normal file
508
clients/upsrw.c
Normal file
|
@ -0,0 +1,508 @@
|
|||
/* upsrw - simple client for read/write variable access (formerly upsct2)
|
||||
|
||||
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 "common.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "upsclient.h"
|
||||
|
||||
struct list_t {
|
||||
char *name;
|
||||
struct list_t *next;
|
||||
};
|
||||
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
printf("Network UPS Tools upsrw %s\n\n", UPS_VERSION);
|
||||
printf("usage: %s [-h]\n", prog);
|
||||
printf(" %s [-s <variable>] [-u <username>] [-p <password>] <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(" -u <username> set username for command authentication\n");
|
||||
printf(" -p <password> set password for command authentication\n");
|
||||
printf("\n");
|
||||
printf(" <ups> UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
|
||||
printf("\n");
|
||||
printf("Call without -s to show all possible read/write variables.\n");
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void clean_exit(UPSCONN_t *ups, char *upsname, char *hostname, int code)
|
||||
{
|
||||
free(upsname);
|
||||
free(hostname);
|
||||
|
||||
upscli_disconnect(ups);
|
||||
|
||||
exit(code);
|
||||
}
|
||||
|
||||
static int do_set(UPSCONN_t *ups, const char *upsname, const char *varname,
|
||||
const char *newval)
|
||||
{
|
||||
char buf[SMALLBUF], enc[SMALLBUF];
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "Can't set variable: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||
fprintf(stderr, "Set variable failed: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* FUTURE: status cookies will tie in here */
|
||||
if (strncmp(buf, "OK", 2) != 0) {
|
||||
printf("Unexpected response from upsd: %s\n", buf);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int do_setvar(UPSCONN_t *ups, const char *varname, char *uin,
|
||||
const char *pass, char *upsname, char *hostname)
|
||||
{
|
||||
char newval[SMALLBUF], temp[SMALLBUF], 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) {
|
||||
fprintf(stderr, "getpass failed: %s\n",
|
||||
strerror(errno));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
fprintf(stderr, "Can't set username: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||
|
||||
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||
fprintf(stderr, "Set username failed due to an "
|
||||
"unknown command.\n");
|
||||
|
||||
fprintf(stderr, "You probably need to upgrade upsd.\n");
|
||||
|
||||
clean_exit(ups, upsname, hostname, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Set username failed: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
snprintf(temp, sizeof(temp), "PASSWORD %s\n", pass);
|
||||
|
||||
if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
|
||||
fprintf(stderr, "Can't set password: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||
fprintf(stderr, "Set password failed: %s\n",
|
||||
upscli_strerror(ups));
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* no upsname means die */
|
||||
if (!upsname) {
|
||||
fprintf(stderr, "Error: a UPS name must be specified (upsname[@hostname[:port]])\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* old variable names are no longer supported */
|
||||
if (!strchr(varname, '.')) {
|
||||
fprintf(stderr, "Error: old variable names are not supported\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return do_set(ups, upsname, varname, newval);
|
||||
}
|
||||
|
||||
static const char *get_data(const char *type, UPSCONN_t *ups,
|
||||
const char *upsname, const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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(UPSCONN_t *ups, const char *upsname, const char *varname)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = get_data("VAR", ups, upsname, varname);
|
||||
|
||||
if (!val) {
|
||||
fprintf(stderr, "do_string: can't get current value of %s\n",
|
||||
varname);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Type: STRING\n");
|
||||
printf("Value: %s\n", val);
|
||||
}
|
||||
|
||||
static void do_enum(UPSCONN_t *ups, const char *upsname, const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
char **answer, *val;
|
||||
const char *query[4], *tmp;
|
||||
|
||||
/* get current value */
|
||||
tmp = get_data("VAR", ups, upsname, varname);
|
||||
|
||||
if (!tmp) {
|
||||
fprintf(stderr, "do_enum: can't get current value of %s\n",
|
||||
varname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* tmp is a pointer into answer - have to save it somewhere else */
|
||||
val = xstrdup(tmp);
|
||||
|
||||
query[0] = "ENUM";
|
||||
query[1] = upsname;
|
||||
query[2] = varname;
|
||||
numq = 3;
|
||||
|
||||
ret = upscli_list_start(ups, numq, query);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error: %s\n", upscli_strerror(ups));
|
||||
return;
|
||||
}
|
||||
|
||||
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||
|
||||
printf("Type: ENUM\n");
|
||||
|
||||
while (ret == 1) {
|
||||
|
||||
/* ENUM <upsname> <varname> <value> */
|
||||
|
||||
if (numa < 4) {
|
||||
fprintf(stderr, "Error: insufficient data "
|
||||
"(got %d args, need at least 4)\n", numa);
|
||||
|
||||
free(val);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Option: \"%s\"", answer[3]);
|
||||
|
||||
if (!strcmp(answer[3], val))
|
||||
printf(" SELECTED");
|
||||
|
||||
printf("\n");
|
||||
|
||||
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||
}
|
||||
|
||||
free(val);
|
||||
}
|
||||
|
||||
static void do_type(UPSCONN_t *ups, const char *upsname, const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int 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++) {
|
||||
|
||||
if (!strcasecmp(answer[i], "ENUM")) {
|
||||
do_enum(ups, upsname, varname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strncasecmp(answer[i], "STRING:", 7)) {
|
||||
do_string(ups, upsname, varname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ignore this one */
|
||||
if (!strcasecmp(answer[i], "RW"))
|
||||
continue;
|
||||
|
||||
printf("Type: %s (unrecognized)\n", answer[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void print_rw(UPSCONN_t *ups, const char *upsname, const char *varname)
|
||||
{
|
||||
const char *tmp;
|
||||
|
||||
printf("[%s]\n", varname);
|
||||
|
||||
tmp = get_data("DESC", ups, upsname, varname);
|
||||
|
||||
if (tmp)
|
||||
printf("%s\n", tmp);
|
||||
else
|
||||
printf("Description unavailable\n");
|
||||
|
||||
do_type(ups, upsname, varname);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static int print_rwlist(UPSCONN_t *ups, const char *upsname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
const char *query[2];
|
||||
char **answer;
|
||||
struct list_t *lhead, *llast, *ltmp, *lnext;
|
||||
|
||||
/* the upsname is now required */
|
||||
if (!upsname) {
|
||||
fprintf(stderr, "Error: a UPS name must be specified (upsname[@hostname[:port]])\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "Error: upsd is too old to support this query\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Error: %s\n", upscli_strerror(ups));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||
|
||||
while (ret == 1) {
|
||||
|
||||
/* RW <upsname> <varname> <value> */
|
||||
if (numa < 4) {
|
||||
fprintf(stderr, "Error: insufficient data "
|
||||
"(got %d args, need at least 4)\n", numa);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* 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(ups, upsname, ltmp->name);
|
||||
|
||||
free(ltmp->name);
|
||||
free(ltmp);
|
||||
ltmp = lnext;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, port, ret;
|
||||
char *upsname, *hostname, *setvar, *prog;
|
||||
char *password = NULL, *username = NULL;
|
||||
UPSCONN_t ups;
|
||||
|
||||
setvar = username = NULL;
|
||||
prog = argv[0];
|
||||
|
||||
while ((i = getopt(argc, argv, "+s:p:u:V")) != -1) {
|
||||
switch (i) {
|
||||
case 's':
|
||||
setvar = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
password = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
username = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
printf("Network UPS Tools upsrw %s\n", UPS_VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
usage(prog);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage(prog);
|
||||
|
||||
upsname = hostname = NULL;
|
||||
|
||||
if (upscli_splitname(argv[0], &upsname, &hostname, &port) != 0) {
|
||||
fprintf(stderr, "Error: invalid UPS definition. Required format: upsname[@hostname[:port]]\n");
|
||||
clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (upscli_connect(&ups, hostname, port, 0) < 0) {
|
||||
fprintf(stderr, "Can't connect: %s\n", upscli_strerror(&ups));
|
||||
clean_exit(&ups, upsname, hostname, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* setting a variable? */
|
||||
if (setvar) {
|
||||
ret = do_setvar(&ups, setvar, username, password, upsname,
|
||||
hostname);
|
||||
|
||||
clean_exit(&ups, upsname, hostname, ret);
|
||||
}
|
||||
|
||||
/* if not, get the list of supported read/write variables */
|
||||
ret = print_rwlist(&ups, upsname);
|
||||
|
||||
clean_exit(&ups, upsname, hostname, ret);
|
||||
|
||||
/* NOTREACHED */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
21
clients/upssched-cmd
Executable file
21
clients/upssched-cmd
Executable file
|
@ -0,0 +1,21 @@
|
|||
#! /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
|
||||
upsgone)
|
||||
logger -t upssched-cmd "The UPS has been gone for awhile"
|
||||
;;
|
||||
*)
|
||||
logger -t upssched-cmd "Unrecognized command: $1"
|
||||
;;
|
||||
esac
|
||||
|
921
clients/upssched.c
Normal file
921
clients/upssched.c
Normal file
|
@ -0,0 +1,921 @@
|
|||
/* 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 "upssched.h"
|
||||
#include "timehead.h"
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
time_t etime;
|
||||
void *next;
|
||||
} ttype_t;
|
||||
|
||||
ttype_t *thead = NULL;
|
||||
static struct conn_t *connhead = NULL;
|
||||
char *cmdscript = NULL, *pipefn = NULL, *lockfn = NULL;
|
||||
int verbose = 0; /* use for debugging */
|
||||
|
||||
|
||||
/* ups name and notify type (string) as received from upsmon */
|
||||
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;
|
||||
int 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 (%d 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];
|
||||
int 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;
|
||||
|
||||
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);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void conn_del(struct conn_t *target)
|
||||
{
|
||||
struct 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(struct conn_t *conn, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
char buf[US_SOCK_BUF_LEN];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
ret = write(conn->fd, buf, strlen(buf));
|
||||
|
||||
if ((ret < 1) || (ret != (int) strlen(buf))) {
|
||||
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;
|
||||
struct conn_t *tmp, *last;
|
||||
struct sockaddr_un saddr;
|
||||
socklen_t salen;
|
||||
|
||||
salen = sizeof(saddr);
|
||||
acc = accept(sockfd, (struct sockaddr *) &saddr, &salen);
|
||||
|
||||
if (acc < 0) {
|
||||
upslog_with_errno(LOG_ERR, "accept on unix fd failed");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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(struct 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(struct 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(int numarg, char **arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
upslogx(LOG_INFO, "Unknown command on socket: ");
|
||||
|
||||
for (i = 0; i < numarg; i++)
|
||||
upslogx(LOG_INFO, "arg %d: %s", i, arg[i]);
|
||||
}
|
||||
|
||||
static int sock_read(struct conn_t *conn)
|
||||
{
|
||||
int i, 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;
|
||||
|
||||
/* 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;
|
||||
struct conn_t *tmp, *tmpnext;
|
||||
socklen_t fromlen;
|
||||
|
||||
fromlen = sizeof(struct sockaddr);
|
||||
|
||||
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;
|
||||
|
||||
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 read_timeout(int sig)
|
||||
{
|
||||
/* ignore this */
|
||||
return;
|
||||
}
|
||||
|
||||
static void setup_sigalrm(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
sigset_t nut_upssched_sigmask;
|
||||
|
||||
sigemptyset(&nut_upssched_sigmask);
|
||||
sa.sa_mask = nut_upssched_sigmask;
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = read_timeout;
|
||||
sigaction(SIGALRM, &sa, NULL);
|
||||
}
|
||||
|
||||
static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
||||
{
|
||||
int i, pipefd, ret;
|
||||
char buf[SMALLBUF], enc[SMALLBUF];
|
||||
|
||||
/* 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)));
|
||||
|
||||
snprintfcat(buf, sizeof(buf), "\n");
|
||||
|
||||
/* 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, buf, strlen(buf));
|
||||
|
||||
/* if we can't send the whole thing, loop back and try again */
|
||||
if ((ret < 1) || (ret != (int) strlen(buf))) {
|
||||
upslogx(LOG_ERR, "write failed, trying again");
|
||||
close(pipefd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ugh - probably should use select here... */
|
||||
setup_sigalrm();
|
||||
|
||||
alarm(2);
|
||||
ret = read(pipefd, buf, sizeof(buf));
|
||||
alarm(0);
|
||||
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
|
||||
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 ... */
|
||||
}
|
||||
|
||||
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') {
|
||||
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(int 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)
|
||||
{
|
||||
verbose = 1; /* TODO: remove when done testing */
|
||||
|
||||
/* normally we don't have stderr, so get this going to syslog early */
|
||||
openlog("upssched", LOG_PID, LOG_DAEMON);
|
||||
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);
|
||||
}
|
14
clients/upssched.h
Normal file
14
clients/upssched.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* upssched.h - supporting structures */
|
||||
|
||||
#include <parseconf.h>
|
||||
|
||||
#define SERIALIZE_INIT 1
|
||||
#define SERIALIZE_SET 2
|
||||
#define SERIALIZE_WAIT 3
|
||||
|
||||
/* track client connections */
|
||||
struct conn_t {
|
||||
int fd;
|
||||
PCONF_CTX_t ctx;
|
||||
void *next;
|
||||
};
|
1079
clients/upsset.c
Normal file
1079
clients/upsset.c
Normal file
File diff suppressed because it is too large
Load diff
1067
clients/upsstats.c
Normal file
1067
clients/upsstats.c
Normal file
File diff suppressed because it is too large
Load diff
24
clients/upsstats.h
Normal file
24
clients/upsstats.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *sys;
|
||||
char *desc;
|
||||
void *next;
|
||||
} ulist_t;
|
Loading…
Add table
Add a link
Reference in a new issue