new upstream 2.8.0
This commit is contained in:
parent
fc7f4b43c1
commit
b2b0c9995a
836 changed files with 137090 additions and 30018 deletions
|
@ -1,7 +1,19 @@
|
|||
# Network UPS Tools: clients
|
||||
EXTRA_DIST =
|
||||
|
||||
# nutclient.cpp for some legacy reason (maybe initial detached development?)
|
||||
# optionally includes "common.h" with the NUT build setup - and this option
|
||||
# was never triggered in fact, not until pushed through command line like this:
|
||||
AM_CXXFLAGS = -DHAVE_NUTCOMMON=1 -I$(top_srcdir)/include
|
||||
|
||||
# Make sure out-of-dir dependencies exist (especially when dev-building parts):
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
$(top_builddir)/common/libcommonclient.la \
|
||||
$(top_builddir)/common/libparseconf.la: dummy
|
||||
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
|
||||
|
||||
# by default, link programs in this directory with libcommon.a
|
||||
LDADD = ../common/libcommon.la libupsclient.la $(NETLIBS)
|
||||
LDADD = $(top_builddir)/common/libcommon.la libupsclient.la $(NETLIBS)
|
||||
if WITH_SSL
|
||||
LDADD += $(LIBSSL_LIBS)
|
||||
endif
|
||||
|
@ -20,9 +32,13 @@ endif
|
|||
bin_PROGRAMS = upsc upslog upsrw upscmd
|
||||
dist_bin_SCRIPTS = upssched-cmd
|
||||
sbin_PROGRAMS = upsmon upssched
|
||||
lib_LTLIBRARIES = libupsclient.la libnutclient.la
|
||||
lib_LTLIBRARIES = libupsclient.la
|
||||
if HAVE_CXX11
|
||||
lib_LTLIBRARIES += libnutclient.la
|
||||
lib_LTLIBRARIES += libnutclientstub.la
|
||||
endif
|
||||
if WITH_DEV
|
||||
include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h
|
||||
include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h nutclientmem.h
|
||||
endif
|
||||
if WITH_CGI
|
||||
cgiexec_PROGRAMS = upsstats.cgi upsimage.cgi upsset.cgi
|
||||
|
@ -35,7 +51,7 @@ 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.la ../common/libparseconf.la $(NETLIBS)
|
||||
upssched_LDADD = $(top_builddir)/common/libcommon.la $(top_builddir)/common/libparseconf.la $(NETLIBS)
|
||||
|
||||
upsimage_cgi_SOURCES = upsimage.c upsclient.h upsimagearg.h cgilib.c cgilib.h
|
||||
upsimage_cgi_LDADD = $(LDADD) $(LIBGD_LDFLAGS)
|
||||
|
@ -46,15 +62,44 @@ upsstats_cgi_SOURCES = upsstats.c upsclient.h status.h upsstats.h \
|
|||
|
||||
# not LDADD.
|
||||
libupsclient_la_SOURCES = upsclient.c upsclient.h
|
||||
libupsclient_la_LIBADD = ../common/libcommonclient.la
|
||||
libupsclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la
|
||||
if WITH_SSL
|
||||
libupsclient_la_LIBADD += $(LIBSSL_LIBS)
|
||||
endif
|
||||
|
||||
# libupsclient version information
|
||||
# Below we set API versions of public libraries
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
libupsclient_la_LDFLAGS = -version-info 4:0:0
|
||||
# Note that changes here may have to be reflected in packaging (the shared
|
||||
# object .so names would differ)
|
||||
|
||||
# libupsclient version information
|
||||
libupsclient_la_LDFLAGS = -version-info 6:0:0 -export-symbols-regex ^upscli_
|
||||
|
||||
if HAVE_CXX11
|
||||
# libnutclient version information and build
|
||||
libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||
libnutclient_la_LDFLAGS = -version-info 0:0:0
|
||||
libnutclient_la_LDFLAGS = -version-info 2:0:0
|
||||
# Needed in not-standalone builds with -DHAVE_NUTCOMMON=1
|
||||
# which is defined for in-tree CXX builds above:
|
||||
libnutclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la
|
||||
else
|
||||
EXTRA_DIST += nutclient.h nutclient.cpp
|
||||
endif
|
||||
|
||||
if HAVE_CXX11
|
||||
# libnutclientstub version information and build
|
||||
libnutclientstub_la_SOURCES = nutclientmem.h nutclientmem.cpp
|
||||
libnutclientstub_la_LDFLAGS = -version-info 1:0:0
|
||||
libnutclientstub_la_LIBADD = libnutclient.la
|
||||
else
|
||||
EXTRA_DIST += nutclientmem.h nutclientmem.cpp
|
||||
endif
|
||||
|
||||
dummy:
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||
|
||||
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
|
||||
# the root Makefile.am takes care of that!
|
||||
#clean-local:
|
||||
# rm -rf $(builddir)/.deps
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Makefile.in generated by automake 1.14.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -14,13 +14,21 @@
|
|||
|
||||
@SET_MAKE@
|
||||
|
||||
# Network UPS Tools: clients
|
||||
|
||||
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
|
@ -90,24 +98,31 @@ target_triplet = @target@
|
|||
bin_PROGRAMS = upsc$(EXEEXT) upslog$(EXEEXT) upsrw$(EXEEXT) \
|
||||
upscmd$(EXEEXT)
|
||||
sbin_PROGRAMS = upsmon$(EXEEXT) upssched$(EXEEXT)
|
||||
@HAVE_CXX11_TRUE@am__append_4 = libnutclient.la libnutclientstub.la
|
||||
@WITH_CGI_TRUE@cgiexec_PROGRAMS = upsstats.cgi$(EXEEXT) \
|
||||
@WITH_CGI_TRUE@ upsimage.cgi$(EXEEXT) upsset.cgi$(EXEEXT)
|
||||
@WITH_SSL_TRUE@am__append_4 = $(LIBSSL_LIBS)
|
||||
@WITH_SSL_TRUE@am__append_5 = $(LIBSSL_LIBS)
|
||||
@HAVE_CXX11_FALSE@am__append_6 = nutclient.h nutclient.cpp \
|
||||
@HAVE_CXX11_FALSE@ nutclientmem.h nutclientmem.cpp
|
||||
subdir = clients
|
||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(dist_bin_SCRIPTS) $(top_srcdir)/depcomp \
|
||||
$(am__include_HEADERS_DIST)
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
|
||||
$(top_srcdir)/m4/ax_c_pragmas.m4 \
|
||||
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
|
||||
$(top_srcdir)/m4/ax_compare_version.m4 \
|
||||
$(top_srcdir)/m4/ax_run_or_link_ifelse.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/m4/nut_arg_with.m4 \
|
||||
$(top_srcdir)/m4/nut_check_asciidoc.m4 \
|
||||
$(top_srcdir)/m4/nut_check_cppcheck.m4 \
|
||||
$(top_srcdir)/m4/nut_check_headers_windows.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libavahi.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libfreeipmi.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libgd.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libltdl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||
|
@ -116,15 +131,26 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
|
|||
$(top_srcdir)/m4/nut_check_libusb.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libwrap.m4 \
|
||||
$(top_srcdir)/m4/nut_check_os.m4 \
|
||||
$(top_srcdir)/m4/nut_check_pkgconfig.m4 \
|
||||
$(top_srcdir)/m4/nut_check_python.m4 \
|
||||
$(top_srcdir)/m4/nut_compiler_family.m4 \
|
||||
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
|
||||
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||
$(top_srcdir)/m4/nut_stash_warnings.m4 \
|
||||
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(dist_bin_SCRIPTS) \
|
||||
$(am__include_HEADERS_DIST) $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cgiexecdir)" \
|
||||
"$(DESTDIR)$(sbindir)" "$(DESTDIR)$(libdir)" \
|
||||
"$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
|
||||
PROGRAMS = $(bin_PROGRAMS) $(cgiexec_PROGRAMS) $(sbin_PROGRAMS)
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
|
@ -152,12 +178,11 @@ am__uninstall_files_from_dir = { \
|
|||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" \
|
||||
"$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libnutclient_la_LIBADD =
|
||||
am_libnutclient_la_OBJECTS = nutclient.lo
|
||||
@HAVE_CXX11_TRUE@libnutclient_la_DEPENDENCIES = \
|
||||
@HAVE_CXX11_TRUE@ $(top_builddir)/common/libcommonclient.la
|
||||
am__libnutclient_la_SOURCES_DIST = nutclient.h nutclient.cpp
|
||||
@HAVE_CXX11_TRUE@am_libnutclient_la_OBJECTS = nutclient.lo
|
||||
libnutclient_la_OBJECTS = $(am_libnutclient_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
|
@ -167,9 +192,20 @@ libnutclient_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
|||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS) $(libnutclient_la_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
@HAVE_CXX11_TRUE@am_libnutclient_la_rpath = -rpath $(libdir)
|
||||
@HAVE_CXX11_TRUE@libnutclientstub_la_DEPENDENCIES = libnutclient.la
|
||||
am__libnutclientstub_la_SOURCES_DIST = nutclientmem.h nutclientmem.cpp
|
||||
@HAVE_CXX11_TRUE@am_libnutclientstub_la_OBJECTS = nutclientmem.lo
|
||||
libnutclientstub_la_OBJECTS = $(am_libnutclientstub_la_OBJECTS)
|
||||
libnutclientstub_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
|
||||
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS) $(libnutclientstub_la_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
@HAVE_CXX11_TRUE@am_libnutclientstub_la_rpath = -rpath $(libdir)
|
||||
am__DEPENDENCIES_1 =
|
||||
@WITH_SSL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libupsclient_la_DEPENDENCIES = ../common/libcommonclient.la \
|
||||
libupsclient_la_DEPENDENCIES = \
|
||||
$(top_builddir)/common/libcommonclient.la \
|
||||
$(am__DEPENDENCIES_2)
|
||||
am_libupsclient_la_OBJECTS = upsclient.lo
|
||||
libupsclient_la_OBJECTS = $(am_libupsclient_la_OBJECTS)
|
||||
|
@ -177,52 +213,51 @@ libupsclient_la_LINK = $(LIBTOOL) $(AM_V_lt) --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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsc_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upscmd_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am__DEPENDENCIES_3 = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upslog_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsmon_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsrw_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
libupsclient.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
am_upssched_OBJECTS = upssched.$(OBJEXT)
|
||||
upssched_OBJECTS = $(am_upssched_OBJECTS)
|
||||
upssched_DEPENDENCIES = ../common/libcommon.la \
|
||||
../common/libparseconf.la $(am__DEPENDENCIES_1)
|
||||
upssched_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
$(top_builddir)/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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsset_cgi_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
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.la libupsclient.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
upsstats_cgi_DEPENDENCIES = $(top_builddir)/common/libcommon.la \
|
||||
libupsclient.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2)
|
||||
SCRIPTS = $(dist_bin_SCRIPTS)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
|
||||
|
@ -238,7 +273,14 @@ am__v_at_0 = @
|
|||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/cgilib.Po ./$(DEPDIR)/nutclient.Plo \
|
||||
./$(DEPDIR)/nutclientmem.Plo ./$(DEPDIR)/upsc.Po \
|
||||
./$(DEPDIR)/upsclient.Plo ./$(DEPDIR)/upscmd.Po \
|
||||
./$(DEPDIR)/upsimage.Po ./$(DEPDIR)/upslog.Po \
|
||||
./$(DEPDIR)/upsmon.Po ./$(DEPDIR)/upsrw.Po \
|
||||
./$(DEPDIR)/upssched.Po ./$(DEPDIR)/upsset.Po \
|
||||
./$(DEPDIR)/upsstats.Po
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
|
@ -276,15 +318,16 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
|
|||
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
|
||||
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||
am__v_CXXLD_1 =
|
||||
SOURCES = $(libnutclient_la_SOURCES) $(libupsclient_la_SOURCES) \
|
||||
$(upsc_SOURCES) $(upscmd_SOURCES) $(upsimage_cgi_SOURCES) \
|
||||
$(upslog_SOURCES) $(upsmon_SOURCES) $(upsrw_SOURCES) \
|
||||
$(upssched_SOURCES) $(upsset_cgi_SOURCES) \
|
||||
SOURCES = $(libnutclient_la_SOURCES) $(libnutclientstub_la_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 = $(libnutclient_la_SOURCES) $(libupsclient_la_SOURCES) \
|
||||
$(upsc_SOURCES) $(upscmd_SOURCES) $(upsimage_cgi_SOURCES) \
|
||||
$(upslog_SOURCES) $(upsmon_SOURCES) $(upsrw_SOURCES) \
|
||||
$(upssched_SOURCES) $(upsset_cgi_SOURCES) \
|
||||
DIST_SOURCES = $(am__libnutclient_la_SOURCES_DIST) \
|
||||
$(am__libnutclientstub_la_SOURCES_DIST) \
|
||||
$(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__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
|
@ -292,7 +335,7 @@ am__can_run_installinfo = \
|
|||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__include_HEADERS_DIST = upsclient.h ../include/parseconf.h \
|
||||
nutclient.h
|
||||
nutclient.h nutclientmem.h
|
||||
HEADERS = $(include_HEADERS)
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
|
@ -313,6 +356,7 @@ am__define_uniq_tagged_files = \
|
|||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
A2X = @A2X@
|
||||
ACLOCAL = @ACLOCAL@
|
||||
|
@ -321,6 +365,7 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
|||
AR = @AR@
|
||||
ASCIIDOC = @ASCIIDOC@
|
||||
ASPELL = @ASPELL@
|
||||
AUGPARSE = @AUGPARSE@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
|
@ -331,6 +376,7 @@ CCDEPMODE = @CCDEPMODE@
|
|||
CFLAGS = @CFLAGS@
|
||||
CONFPATH = @CONFPATH@
|
||||
CPP = @CPP@
|
||||
CPPCHECK = @CPPCHECK@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
|
||||
CPPUNIT_LIBS = @CPPUNIT_LIBS@
|
||||
|
@ -344,6 +390,7 @@ DEFS = @DEFS@
|
|||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
||||
DOC_CHECK_LIST = @DOC_CHECK_LIST@
|
||||
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||
|
@ -356,6 +403,7 @@ ECHO_T = @ECHO_T@
|
|||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GDLIB_CONFIG = @GDLIB_CONFIG@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
@ -373,6 +421,8 @@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
|
|||
LIBIPMI_LIBS = @LIBIPMI_LIBS@
|
||||
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
|
||||
LIBLTDL_LIBS = @LIBLTDL_LIBS@
|
||||
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
|
||||
LIBMODBUS_LIBS = @LIBMODBUS_LIBS@
|
||||
LIBNEON_CFLAGS = @LIBNEON_CFLAGS@
|
||||
LIBNEON_LIBS = @LIBNEON_LIBS@
|
||||
LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@
|
||||
|
@ -383,21 +433,29 @@ LIBPOWERMAN_LIBS = @LIBPOWERMAN_LIBS@
|
|||
LIBS = @LIBS@
|
||||
LIBSSL_CFLAGS = @LIBSSL_CFLAGS@
|
||||
LIBSSL_LIBS = @LIBSSL_LIBS@
|
||||
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBTOOL_DEPS = @LIBTOOL_DEPS@
|
||||
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||
LIBUSB_CONFIG = @LIBUSB_CONFIG@
|
||||
LIBUSB_LIBS = @LIBUSB_LIBS@
|
||||
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||
LIBWRAP_LIBS = @LIBWRAP_LIBS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LN_S_R = @LN_S_R@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NETLIBS = @NETLIBS@
|
||||
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NUT_DATADIR = @NUT_DATADIR@
|
||||
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
|
||||
NUT_NETVERSION = @NUT_NETVERSION@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
|
@ -417,6 +475,9 @@ PKG_CONFIG = @PKG_CONFIG@
|
|||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||
PORT = @PORT@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON2 = @PYTHON2@
|
||||
PYTHON3 = @PYTHON3@
|
||||
RANLIB = @RANLIB@
|
||||
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||
RUN_AS_USER = @RUN_AS_USER@
|
||||
|
@ -430,6 +491,7 @@ STATEPATH = @STATEPATH@
|
|||
STRIP = @STRIP@
|
||||
SUN_LIBUSB = @SUN_LIBUSB@
|
||||
TREE_VERSION = @TREE_VERSION@
|
||||
VALGRIND = @VALGRIND@
|
||||
VERSION = @VERSION@
|
||||
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||
XMLLINT = @XMLLINT@
|
||||
|
@ -447,6 +509,7 @@ am__leading_dot = @am__leading_dot@
|
|||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
auglensdir = @auglensdir@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
|
@ -460,6 +523,9 @@ datarootdir = @datarootdir@
|
|||
devddir = @devddir@
|
||||
docdir = @docdir@
|
||||
driverexecdir = @driverexecdir@
|
||||
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
|
||||
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
|
||||
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
|
@ -485,12 +551,14 @@ pkgconfigdir = @pkgconfigdir@
|
|||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
systemdsystemshutdowndir = @systemdsystemshutdowndir@
|
||||
systemdshutdowndir = @systemdshutdowndir@
|
||||
systemdsystemunitdir = @systemdsystemunitdir@
|
||||
systemdtmpfilesdir = @systemdtmpfilesdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
|
@ -501,8 +569,16 @@ top_builddir = @top_builddir@
|
|||
top_srcdir = @top_srcdir@
|
||||
udevdir = @udevdir@
|
||||
|
||||
# Network UPS Tools: clients
|
||||
EXTRA_DIST = $(am__append_6)
|
||||
|
||||
# nutclient.cpp for some legacy reason (maybe initial detached development?)
|
||||
# optionally includes "common.h" with the NUT build setup - and this option
|
||||
# was never triggered in fact, not until pushed through command line like this:
|
||||
AM_CXXFLAGS = -DHAVE_NUTCOMMON=1 -I$(top_srcdir)/include
|
||||
|
||||
# by default, link programs in this directory with libcommon.a
|
||||
LDADD = ../common/libcommon.la libupsclient.la $(NETLIBS) \
|
||||
LDADD = $(top_builddir)/common/libcommon.la libupsclient.la $(NETLIBS) \
|
||||
$(am__append_1)
|
||||
|
||||
# Avoid per-target CFLAGS, because this will prevent re-use of object
|
||||
|
@ -510,15 +586,15 @@ LDADD = ../common/libcommon.la libupsclient.la $(NETLIBS) \
|
|||
# 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 libnutclient.la
|
||||
@WITH_DEV_TRUE@include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h
|
||||
lib_LTLIBRARIES = libupsclient.la $(am__append_4)
|
||||
@WITH_DEV_TRUE@include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h nutclientmem.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.la ../common/libparseconf.la $(NETLIBS)
|
||||
upssched_LDADD = $(top_builddir)/common/libcommon.la $(top_builddir)/common/libparseconf.la $(NETLIBS)
|
||||
upsimage_cgi_SOURCES = upsimage.c upsclient.h upsimagearg.h cgilib.c cgilib.h
|
||||
upsimage_cgi_LDADD = $(LDADD) $(LIBGD_LDFLAGS)
|
||||
upsset_cgi_SOURCES = upsset.c upsclient.h cgilib.c cgilib.h
|
||||
|
@ -528,13 +604,29 @@ upsstats_cgi_SOURCES = upsstats.c upsclient.h status.h upsstats.h \
|
|||
|
||||
# not LDADD.
|
||||
libupsclient_la_SOURCES = upsclient.c upsclient.h
|
||||
libupsclient_la_LIBADD = ../common/libcommonclient.la $(am__append_4)
|
||||
libupsclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la \
|
||||
$(am__append_5)
|
||||
|
||||
# Below we set API versions of public libraries
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
# Note that changes here may have to be reflected in packaging (the shared
|
||||
# object .so names would differ)
|
||||
|
||||
# libupsclient version information
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
libupsclient_la_LDFLAGS = -version-info 4:0:0
|
||||
libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||
libnutclient_la_LDFLAGS = -version-info 0:0:0
|
||||
libupsclient_la_LDFLAGS = -version-info 6:0:0 -export-symbols-regex ^upscli_
|
||||
|
||||
# libnutclient version information and build
|
||||
@HAVE_CXX11_TRUE@libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||
@HAVE_CXX11_TRUE@libnutclient_la_LDFLAGS = -version-info 2:0:0
|
||||
# Needed in not-standalone builds with -DHAVE_NUTCOMMON=1
|
||||
# which is defined for in-tree CXX builds above:
|
||||
@HAVE_CXX11_TRUE@libnutclient_la_LIBADD = $(top_builddir)/common/libcommonclient.la
|
||||
|
||||
# libnutclientstub version information and build
|
||||
@HAVE_CXX11_TRUE@libnutclientstub_la_SOURCES = nutclientmem.h nutclientmem.cpp
|
||||
@HAVE_CXX11_TRUE@libnutclientstub_la_LDFLAGS = -version-info 1:0:0
|
||||
@HAVE_CXX11_TRUE@libnutclientstub_la_LIBADD = libnutclient.la
|
||||
MAINTAINERCLEANFILES = Makefile.in .dirstamp
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
|
@ -551,14 +643,13 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
|
|||
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);; \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
|
@ -569,47 +660,6 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
|||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
@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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
|
||||
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)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
|
||||
libnutclient.la: $(libnutclient_la_OBJECTS) $(libnutclient_la_DEPENDENCIES) $(EXTRA_libnutclient_la_DEPENDENCIES)
|
||||
$(AM_V_CXXLD)$(libnutclient_la_LINK) -rpath $(libdir) $(libnutclient_la_OBJECTS) $(libnutclient_la_LIBADD) $(LIBS)
|
||||
|
||||
libupsclient.la: $(libupsclient_la_OBJECTS) $(libupsclient_la_DEPENDENCIES) $(EXTRA_libupsclient_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libupsclient_la_LINK) -rpath $(libdir) $(libupsclient_la_OBJECTS) $(libupsclient_la_LIBADD) $(LIBS)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
|
||||
|
@ -758,6 +808,50 @@ clean-sbinPROGRAMS:
|
|||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
@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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
|
||||
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)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
|
||||
libnutclient.la: $(libnutclient_la_OBJECTS) $(libnutclient_la_DEPENDENCIES) $(EXTRA_libnutclient_la_DEPENDENCIES)
|
||||
$(AM_V_CXXLD)$(libnutclient_la_LINK) $(am_libnutclient_la_rpath) $(libnutclient_la_OBJECTS) $(libnutclient_la_LIBADD) $(LIBS)
|
||||
|
||||
libnutclientstub.la: $(libnutclientstub_la_OBJECTS) $(libnutclientstub_la_DEPENDENCIES) $(EXTRA_libnutclientstub_la_DEPENDENCIES)
|
||||
$(AM_V_CXXLD)$(libnutclientstub_la_LINK) $(am_libnutclientstub_la_rpath) $(libnutclientstub_la_OBJECTS) $(libnutclientstub_la_LIBADD) $(LIBS)
|
||||
|
||||
libupsclient.la: $(libupsclient_la_OBJECTS) $(libupsclient_la_DEPENDENCIES) $(EXTRA_libupsclient_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libupsclient_la_LINK) -rpath $(libdir) $(libupsclient_la_OBJECTS) $(libupsclient_la_LIBADD) $(LIBS)
|
||||
|
||||
upsc$(EXEEXT): $(upsc_OBJECTS) $(upsc_DEPENDENCIES) $(EXTRA_upsc_DEPENDENCIES)
|
||||
@rm -f upsc$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(upsc_OBJECTS) $(upsc_LDADD) $(LIBS)
|
||||
|
@ -835,18 +929,25 @@ mostlyclean-compile:
|
|||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgilib.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nutclient.Plo@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@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cgilib.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nutclient.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nutclientmem.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsc.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsclient.Plo@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upscmd.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsimage.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upslog.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsmon.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsrw.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upssched.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsset.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsstats.Po@am__quote@ # am--include-marker
|
||||
|
||||
$(am__depfiles_remade):
|
||||
@$(MKDIR_P) $(@D)
|
||||
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
|
||||
|
||||
am--depfiles: $(am__depfiles_remade)
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
|
@ -975,7 +1076,10 @@ cscopelist-am: $(am__tagged_files)
|
|||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
distdir: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) distdir-am
|
||||
|
||||
distdir-am: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
|
@ -1007,11 +1111,11 @@ distdir: $(DISTFILES)
|
|||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(HEADERS)
|
||||
all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(HEADERS)
|
||||
install-binPROGRAMS: install-libLTLIBRARIES
|
||||
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \
|
||||
for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
|
@ -1044,6 +1148,7 @@ distclean-generic:
|
|||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-cgiexecPROGRAMS clean-generic \
|
||||
|
@ -1051,7 +1156,19 @@ clean-am: clean-binPROGRAMS clean-cgiexecPROGRAMS clean-generic \
|
|||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f ./$(DEPDIR)/cgilib.Po
|
||||
-rm -f ./$(DEPDIR)/nutclient.Plo
|
||||
-rm -f ./$(DEPDIR)/nutclientmem.Plo
|
||||
-rm -f ./$(DEPDIR)/upsc.Po
|
||||
-rm -f ./$(DEPDIR)/upsclient.Plo
|
||||
-rm -f ./$(DEPDIR)/upscmd.Po
|
||||
-rm -f ./$(DEPDIR)/upsimage.Po
|
||||
-rm -f ./$(DEPDIR)/upslog.Po
|
||||
-rm -f ./$(DEPDIR)/upsmon.Po
|
||||
-rm -f ./$(DEPDIR)/upsrw.Po
|
||||
-rm -f ./$(DEPDIR)/upssched.Po
|
||||
-rm -f ./$(DEPDIR)/upsset.Po
|
||||
-rm -f ./$(DEPDIR)/upsstats.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
@ -1099,7 +1216,19 @@ install-ps-am:
|
|||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f ./$(DEPDIR)/cgilib.Po
|
||||
-rm -f ./$(DEPDIR)/nutclient.Plo
|
||||
-rm -f ./$(DEPDIR)/nutclientmem.Plo
|
||||
-rm -f ./$(DEPDIR)/upsc.Po
|
||||
-rm -f ./$(DEPDIR)/upsclient.Plo
|
||||
-rm -f ./$(DEPDIR)/upscmd.Po
|
||||
-rm -f ./$(DEPDIR)/upsimage.Po
|
||||
-rm -f ./$(DEPDIR)/upslog.Po
|
||||
-rm -f ./$(DEPDIR)/upsmon.Po
|
||||
-rm -f ./$(DEPDIR)/upsrw.Po
|
||||
-rm -f ./$(DEPDIR)/upssched.Po
|
||||
-rm -f ./$(DEPDIR)/upsset.Po
|
||||
-rm -f ./$(DEPDIR)/upsstats.Po
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
|
@ -1122,7 +1251,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-cgiexecPROGRAMS \
|
|||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
|
||||
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
|
||||
clean-binPROGRAMS clean-cgiexecPROGRAMS clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool clean-sbinPROGRAMS \
|
||||
cscopelist-am ctags ctags-am distclean distclean-compile \
|
||||
|
@ -1142,6 +1271,21 @@ uninstall-am: uninstall-binPROGRAMS uninstall-cgiexecPROGRAMS \
|
|||
uninstall-dist_binSCRIPTS uninstall-includeHEADERS \
|
||||
uninstall-libLTLIBRARIES uninstall-sbinPROGRAMS
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Make sure out-of-dir dependencies exist (especially when dev-building parts):
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
$(top_builddir)/common/libcommonclient.la \
|
||||
$(top_builddir)/common/libparseconf.la: dummy
|
||||
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
|
||||
|
||||
dummy:
|
||||
|
||||
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
|
||||
# the root Makefile.am takes care of that!
|
||||
#clean-local:
|
||||
# rm -rf $(builddir)/.deps
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
|
|
|
@ -46,9 +46,12 @@ static char *unescape(char *buf)
|
|||
hex[1] = buf[++i];
|
||||
hex[2] = '\0';
|
||||
if (!isxdigit((unsigned char) hex[0])
|
||||
|| !isxdigit((unsigned char) hex[0]))
|
||||
|| !isxdigit((unsigned char) hex[1]))
|
||||
fatalx(EXIT_FAILURE, "bad escape char");
|
||||
ch = strtol(hex, NULL, 16);
|
||||
long l = strtol(hex, NULL, 16);
|
||||
assert(l>=0);
|
||||
assert(l<=255);
|
||||
ch = (char)l; /* FIXME: Loophole about non-ASCII symbols in top 128 values, or negatives for signed char... */
|
||||
|
||||
if ((ch == 10) || (ch == 13))
|
||||
ch = ' ';
|
||||
|
@ -89,7 +92,7 @@ void extractcgiargs(void)
|
|||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
*eq = '\0';
|
||||
value = eq + 1;
|
||||
amp = strchr(value, '&');
|
||||
|
@ -101,7 +104,7 @@ void extractcgiargs(void)
|
|||
ptr = NULL;
|
||||
|
||||
cleanvar = unescape(varname);
|
||||
cleanval = unescape(value);
|
||||
cleanval = unescape(value);
|
||||
parsearg(cleanvar, cleanval);
|
||||
free(cleanvar);
|
||||
free(cleanval);
|
||||
|
@ -199,4 +202,4 @@ int checkhost(const char *host, char **desc)
|
|||
pconf_finish(&ctx);
|
||||
|
||||
return 0; /* not found: access denied */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUT_CGILIB_H_SEEN
|
||||
#define NUT_CGILIB_H_SEEN 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
|
@ -41,3 +44,4 @@ int checkhost(const char *host, char **desc);
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_CGILIB_H_SEEN */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -28,6 +28,13 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <exception>
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
|
||||
/* See include/common.h for details behind this */
|
||||
#ifndef NUT_UNUSED_VARIABLE
|
||||
#define NUT_UNUSED_VARIABLE(x) (void)(x)
|
||||
#endif
|
||||
|
||||
namespace nut
|
||||
{
|
||||
|
@ -51,9 +58,11 @@ class NutException : public std::exception
|
|||
{
|
||||
public:
|
||||
NutException(const std::string& msg):_msg(msg){}
|
||||
virtual ~NutException() throw() {}
|
||||
virtual const char * what() const throw() {return this->_msg.c_str();}
|
||||
virtual std::string str() const throw() {return this->_msg;}
|
||||
NutException(const NutException&) = default;
|
||||
NutException& operator=(NutException& rhs) = default;
|
||||
virtual ~NutException() override;
|
||||
virtual const char * what() const noexcept override {return this->_msg.c_str();}
|
||||
virtual std::string str() const noexcept {return this->_msg;}
|
||||
private:
|
||||
std::string _msg;
|
||||
};
|
||||
|
@ -65,7 +74,9 @@ class SystemException : public NutException
|
|||
{
|
||||
public:
|
||||
SystemException();
|
||||
virtual ~SystemException() throw() {}
|
||||
SystemException(const SystemException&) = default;
|
||||
SystemException& operator=(SystemException& rhs) = default;
|
||||
virtual ~SystemException() override;
|
||||
private:
|
||||
static std::string err();
|
||||
};
|
||||
|
@ -78,7 +89,9 @@ class IOException : public NutException
|
|||
{
|
||||
public:
|
||||
IOException(const std::string& msg):NutException(msg){}
|
||||
virtual ~IOException() throw() {}
|
||||
IOException(const IOException&) = default;
|
||||
IOException& operator=(IOException& rhs) = default;
|
||||
virtual ~IOException() override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,7 +101,9 @@ class UnknownHostException : public IOException
|
|||
{
|
||||
public:
|
||||
UnknownHostException():IOException("Unknown host"){}
|
||||
virtual ~UnknownHostException() throw() {}
|
||||
UnknownHostException(const UnknownHostException&) = default;
|
||||
UnknownHostException& operator=(UnknownHostException& rhs) = default;
|
||||
virtual ~UnknownHostException() override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -98,7 +113,9 @@ class NotConnectedException : public IOException
|
|||
{
|
||||
public:
|
||||
NotConnectedException():IOException("Not connected"){}
|
||||
virtual ~NotConnectedException() throw() {}
|
||||
NotConnectedException(const NotConnectedException&) = default;
|
||||
NotConnectedException& operator=(NotConnectedException& rhs) = default;
|
||||
virtual ~NotConnectedException() override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -108,9 +125,30 @@ class TimeoutException : public IOException
|
|||
{
|
||||
public:
|
||||
TimeoutException():IOException("Timeout"){}
|
||||
virtual ~TimeoutException() throw() {}
|
||||
TimeoutException(const TimeoutException&) = default;
|
||||
TimeoutException& operator=(TimeoutException& rhs) = default;
|
||||
virtual ~TimeoutException() override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cookie given when performing async action, used to redeem result at a later date.
|
||||
*/
|
||||
typedef std::string TrackingID;
|
||||
|
||||
/**
|
||||
* Result of an async action.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
UNKNOWN,
|
||||
PENDING,
|
||||
SUCCESS,
|
||||
INVALID_ARGUMENT,
|
||||
FAILURE,
|
||||
} TrackingResult;
|
||||
|
||||
typedef std::string Feature;
|
||||
|
||||
/**
|
||||
* A nut client is the starting point to dialog to NUTD.
|
||||
* It can connect to an NUTD then retrieve its device list.
|
||||
|
@ -122,7 +160,7 @@ class Client
|
|||
friend class Variable;
|
||||
friend class Command;
|
||||
public:
|
||||
~Client();
|
||||
virtual ~Client();
|
||||
|
||||
/**
|
||||
* Intend to authenticate to a NUTD server.
|
||||
|
@ -132,13 +170,13 @@ public:
|
|||
* \todo Is his method is global to all connection protocol or is it specific to TCP ?
|
||||
* \note Actually, authentication fails only if already set, not if bad values are sent.
|
||||
*/
|
||||
virtual void authenticate(const std::string& user, const std::string& passwd)throw(NutException)=0;
|
||||
virtual void authenticate(const std::string& user, const std::string& passwd) = 0;
|
||||
|
||||
/**
|
||||
* Disconnect from the NUTD server.
|
||||
* \todo Is his method is global to all connection protocol or is it specific to TCP ?
|
||||
*/
|
||||
virtual void logout()throw(NutException)=0;
|
||||
virtual void logout() = 0;
|
||||
|
||||
/**
|
||||
* Device manipulations.
|
||||
|
@ -151,29 +189,29 @@ public:
|
|||
* \param name Name of the device.
|
||||
* \return The device.
|
||||
*/
|
||||
virtual Device getDevice(const std::string& name)throw(NutException);
|
||||
virtual Device getDevice(const std::string& name);
|
||||
/**
|
||||
* Retrieve the list of all devices supported by UPSD server.
|
||||
* \return The set of supported devices.
|
||||
*/
|
||||
virtual std::set<Device> getDevices()throw(NutException);
|
||||
virtual std::set<Device> getDevices();
|
||||
/**
|
||||
* Test if a device is supported by the NUTD server.
|
||||
* \param dev Device name.
|
||||
* \return true if supported, false otherwise.
|
||||
*/
|
||||
virtual bool hasDevice(const std::string& dev)throw(NutException);
|
||||
virtual bool hasDevice(const std::string& dev);
|
||||
/**
|
||||
* Retrieve names of devices supported by NUTD server.
|
||||
* \return The set of names of supported devices.
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceNames()throw(NutException)=0;
|
||||
virtual std::set<std::string> getDeviceNames() = 0;
|
||||
/**
|
||||
* Retrieve the description of a device.
|
||||
* \param name Device name.
|
||||
* \return Device description.
|
||||
*/
|
||||
virtual std::string getDeviceDescription(const std::string& name)throw(NutException)=0;
|
||||
virtual std::string getDeviceDescription(const std::string& name) = 0;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
|
@ -186,54 +224,60 @@ public:
|
|||
* \param dev Device name
|
||||
* \return Variable names
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)throw(NutException)=0;
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev) = 0;
|
||||
/**
|
||||
* Retrieve names of read/write variables supported by a device.
|
||||
* \param dev Device name
|
||||
* \return RW variable names
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev)throw(NutException)=0;
|
||||
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev) = 0;
|
||||
/**
|
||||
* Test if a variable is supported by a device.
|
||||
* \param dev Device name
|
||||
* \param name Variable name
|
||||
* \return true if the variable is supported.
|
||||
*/
|
||||
virtual bool hasDeviceVariable(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual bool hasDeviceVariable(const std::string& dev, const std::string& name);
|
||||
/**
|
||||
* Retrieve the description of a variable.
|
||||
* \param dev Device name
|
||||
* \param name Variable name
|
||||
* \return Variable description if provided.
|
||||
*/
|
||||
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name)throw(NutException)=0;
|
||||
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name) = 0;
|
||||
/**
|
||||
* Retrieve values of a variable.
|
||||
* \param dev Device name
|
||||
* \param name Variable name
|
||||
* \return Variable values (usually one) if available.
|
||||
*/
|
||||
virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name)throw(NutException)=0;
|
||||
virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name) = 0;
|
||||
/**
|
||||
* Retrieve values of all variables of a device.
|
||||
* \param dev Device name
|
||||
* \return Variable values indexed by variable names.
|
||||
*/
|
||||
virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev)throw(NutException);
|
||||
virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev);
|
||||
/**
|
||||
* Retrieve values of all variables of a set of devices.
|
||||
* \param devs Device names
|
||||
* \return Variable values indexed by variable names, indexed by device names.
|
||||
*/
|
||||
virtual std::map<std::string,std::map<std::string,std::vector<std::string> > > getDevicesVariableValues(const std::set<std::string>& devs);
|
||||
/**
|
||||
* Intend to set the value of a variable.
|
||||
* \param dev Device name
|
||||
* \param name Variable name
|
||||
* \param value Variable value
|
||||
*/
|
||||
virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)throw(NutException)=0;
|
||||
*/
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value) = 0;
|
||||
/**
|
||||
* Intend to set the value of a variable.
|
||||
* \param dev Device name
|
||||
* \param name Variable name
|
||||
* \param value Variable value
|
||||
*/
|
||||
virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)throw(NutException)=0;
|
||||
* \param values Vector of variable values
|
||||
*/
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values) = 0;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
|
@ -246,27 +290,28 @@ public:
|
|||
* \param dev Device name
|
||||
* \return Command names
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)throw(NutException)=0;
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev) = 0;
|
||||
/**
|
||||
* Test if a command is supported by a device.
|
||||
* \param dev Device name
|
||||
* \param name Command name
|
||||
* \return true if the command is supported.
|
||||
*/
|
||||
virtual bool hasDeviceCommand(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual bool hasDeviceCommand(const std::string& dev, const std::string& name);
|
||||
/**
|
||||
* Retrieve the description of a command.
|
||||
* \param dev Device name
|
||||
* \param name Command name
|
||||
* \return Command description if provided.
|
||||
*/
|
||||
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name)throw(NutException)=0;
|
||||
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name) = 0;
|
||||
/**
|
||||
* Intend to execute a command.
|
||||
* \param dev Device name
|
||||
* \param name Command name
|
||||
* \param param Additional command parameter
|
||||
*/
|
||||
virtual void executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException)=0;
|
||||
virtual TrackingID executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param="") = 0;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
|
@ -277,15 +322,33 @@ public:
|
|||
* Log the current user (if authenticated) for a device.
|
||||
* \param dev Device name.
|
||||
*/
|
||||
virtual void deviceLogin(const std::string& dev)throw(NutException)=0;
|
||||
virtual void deviceLogin(const std::string& dev) = 0;
|
||||
/**
|
||||
* Retrieve the number of user longged in the specified device.
|
||||
* Retrieve the number of user logged-in for the specified device.
|
||||
* \param dev Device name.
|
||||
* \return Number of logged-in users.
|
||||
*/
|
||||
virtual int deviceGetNumLogins(const std::string& dev)throw(NutException)=0;
|
||||
virtual void deviceMaster(const std::string& dev)throw(NutException)=0;
|
||||
virtual void deviceForcedShutdown(const std::string& dev)throw(NutException)=0;
|
||||
virtual int deviceGetNumLogins(const std::string& dev) = 0;
|
||||
/* NOTE: "master" is deprecated since NUT v2.8.0 in favor of "primary".
|
||||
* For the sake of old/new server/client interoperability,
|
||||
* practical implementations should try to use one and fall
|
||||
* back to the other, and only fail if both return "ERR".
|
||||
*/
|
||||
virtual void deviceMaster(const std::string& dev) = 0;
|
||||
virtual void devicePrimary(const std::string& dev) = 0;
|
||||
virtual void deviceForcedShutdown(const std::string& dev) = 0;
|
||||
|
||||
/**
|
||||
* Retrieve the result of a tracking ID.
|
||||
* \param id Tracking ID.
|
||||
*/
|
||||
virtual TrackingResult getTrackingResult(const TrackingID& id) = 0;
|
||||
|
||||
virtual bool hasFeature(const Feature& feature);
|
||||
virtual bool isFeatureEnabled(const Feature& feature) = 0;
|
||||
virtual void setFeature(const Feature& feature, bool status) = 0;
|
||||
|
||||
static const Feature TRACKING;
|
||||
|
||||
protected:
|
||||
Client();
|
||||
|
@ -297,6 +360,11 @@ protected:
|
|||
*/
|
||||
class TcpClient : public Client
|
||||
{
|
||||
/* We have a number of direct-call methods we do not expose
|
||||
* generally, but still want covered with integration tests
|
||||
*/
|
||||
friend class NutActiveClientTest;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a nut TcpClient object.
|
||||
|
@ -309,21 +377,21 @@ public:
|
|||
* \param host Server host name.
|
||||
* \param port Server port.
|
||||
*/
|
||||
TcpClient(const std::string& host, int port = 3493)throw(nut::IOException);
|
||||
~TcpClient();
|
||||
TcpClient(const std::string& host, uint16_t port = 3493);
|
||||
~TcpClient() override;
|
||||
|
||||
/**
|
||||
* Connect it to the specified server.
|
||||
* \param host Server host name.
|
||||
* \param port Server port.
|
||||
*/
|
||||
void connect(const std::string& host, int port = 3493)throw(nut::IOException);
|
||||
void connect(const std::string& host, uint16_t port = 3493);
|
||||
|
||||
/**
|
||||
* Connect to the server.
|
||||
* Host name and ports must have already set (usefull for reconnection).
|
||||
*/
|
||||
void connect()throw(nut::IOException);
|
||||
void connect();
|
||||
|
||||
/**
|
||||
* Test if the connection is active.
|
||||
|
@ -339,13 +407,13 @@ public:
|
|||
* Set the timeout in seconds.
|
||||
* \param timeout Timeout n seconds, negative to block operations.
|
||||
*/
|
||||
void setTimeout(long timeout);
|
||||
void setTimeout(time_t timeout);
|
||||
|
||||
/**
|
||||
* Retrieve the timeout.
|
||||
* \returns Current timeout in seconds.
|
||||
*/
|
||||
long getTimeout()const;
|
||||
time_t getTimeout()const;
|
||||
|
||||
/**
|
||||
* Retriueve the host name of the server the client is connected to.
|
||||
|
@ -356,53 +424,64 @@ public:
|
|||
* Retriueve the port of host of the server the client is connected to.
|
||||
* \return Server port
|
||||
*/
|
||||
int getPort()const;
|
||||
uint16_t getPort()const;
|
||||
|
||||
virtual void authenticate(const std::string& user, const std::string& passwd)throw(NutException);
|
||||
virtual void logout()throw(NutException);
|
||||
|
||||
virtual Device getDevice(const std::string& name)throw(NutException);
|
||||
virtual std::set<std::string> getDeviceNames()throw(NutException);
|
||||
virtual std::string getDeviceDescription(const std::string& name)throw(NutException);
|
||||
virtual void authenticate(const std::string& user, const std::string& passwd) override;
|
||||
virtual void logout() override;
|
||||
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)throw(NutException);
|
||||
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev)throw(NutException);
|
||||
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev)throw(NutException);
|
||||
virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)throw(NutException);
|
||||
virtual void setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values)throw(NutException);
|
||||
virtual Device getDevice(const std::string& name) override;
|
||||
virtual std::set<std::string> getDeviceNames() override;
|
||||
virtual std::string getDeviceDescription(const std::string& name) override;
|
||||
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)throw(NutException);
|
||||
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual void executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException);
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev) override;
|
||||
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev) override;
|
||||
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name) override;
|
||||
virtual std::vector<std::string> getDeviceVariableValue(const std::string& dev, const std::string& name) override;
|
||||
virtual std::map<std::string,std::vector<std::string> > getDeviceVariableValues(const std::string& dev) override;
|
||||
virtual std::map<std::string,std::map<std::string,std::vector<std::string> > > getDevicesVariableValues(const std::set<std::string>& devs) override;
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value) override;
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::vector<std::string>& values) override;
|
||||
|
||||
virtual void deviceLogin(const std::string& dev)throw(NutException);
|
||||
virtual void deviceMaster(const std::string& dev)throw(NutException);
|
||||
virtual void deviceForcedShutdown(const std::string& dev)throw(NutException);
|
||||
virtual int deviceGetNumLogins(const std::string& dev)throw(NutException);
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev) override;
|
||||
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name) override;
|
||||
virtual TrackingID executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param="") override;
|
||||
|
||||
virtual void deviceLogin(const std::string& dev) override;
|
||||
/* FIXME: Protocol update needed to handle master/primary alias
|
||||
* and probably an API bump also, to rename/alias the routine.
|
||||
*/
|
||||
virtual void deviceMaster(const std::string& dev) override;
|
||||
virtual void devicePrimary(const std::string& dev) override;
|
||||
virtual void deviceForcedShutdown(const std::string& dev) override;
|
||||
virtual int deviceGetNumLogins(const std::string& dev) override;
|
||||
|
||||
virtual TrackingResult getTrackingResult(const TrackingID& id) override;
|
||||
|
||||
virtual bool isFeatureEnabled(const Feature& feature) override;
|
||||
virtual void setFeature(const Feature& feature, bool status) override;
|
||||
|
||||
protected:
|
||||
std::string sendQuery(const std::string& req)throw(nut::IOException);
|
||||
static void detectError(const std::string& req)throw(nut::NutException);
|
||||
std::string sendQuery(const std::string& req);
|
||||
void sendAsyncQueries(const std::vector<std::string>& req);
|
||||
static void detectError(const std::string& req);
|
||||
TrackingID sendTrackingQuery(const std::string& req);
|
||||
|
||||
std::vector<std::string> get(const std::string& subcmd, const std::string& params = "")
|
||||
throw(nut::NutException);
|
||||
std::vector<std::string> get(const std::string& subcmd, const std::string& params = "");
|
||||
|
||||
std::vector<std::vector<std::string> > list(const std::string& subcmd, const std::string& params = "")
|
||||
throw(nut::NutException);
|
||||
std::vector<std::vector<std::string> > list(const std::string& subcmd, const std::string& params = "");
|
||||
|
||||
std::vector<std::vector<std::string> > parseList(const std::string& req);
|
||||
|
||||
static std::vector<std::string> explode(const std::string& str, size_t begin=0);
|
||||
static std::string escape(const std::string& str);
|
||||
|
||||
private:
|
||||
std::string _host;
|
||||
int _port;
|
||||
long _timeout;
|
||||
uint16_t _port;
|
||||
time_t _timeout;
|
||||
internal::Socket* _socket;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Device attached to a client.
|
||||
* Device is a lightweight class which can be copied easily.
|
||||
|
@ -411,9 +490,14 @@ class Device
|
|||
{
|
||||
friend class Client;
|
||||
friend class TcpClient;
|
||||
friend class TcpClientMock;
|
||||
#ifdef _NUTCLIENTTEST_BUILD
|
||||
friend class NutClientTest;
|
||||
#endif
|
||||
public:
|
||||
~Device();
|
||||
Device(const Device& dev);
|
||||
Device& operator=(const Device& dev);
|
||||
|
||||
/**
|
||||
* Retrieve the name of the device.
|
||||
|
@ -435,112 +519,117 @@ public:
|
|||
bool isOk()const;
|
||||
/**
|
||||
* Test if the device is valid (has a name and is attached to a client).
|
||||
* @see Device::isOk()
|
||||
* @see Device::isOk()
|
||||
*/
|
||||
operator bool()const;
|
||||
/**
|
||||
* Test if the device is not valid (has no name or is not attached to any client).
|
||||
* @see Device::isOk()
|
||||
* @see Device::isOk()
|
||||
*/
|
||||
bool operator!()const;
|
||||
/**
|
||||
* Test if the two devices are sames (same name ad same client attached to).
|
||||
*/
|
||||
bool operator==(const Device& dev)const;
|
||||
/**
|
||||
* Comparison operator.
|
||||
*/
|
||||
bool operator<(const Device& dev)const;
|
||||
/**
|
||||
* Comparison operator.
|
||||
*/
|
||||
bool operator<(const Device& dev)const;
|
||||
|
||||
/**
|
||||
* Retrieve the description of the devce if specified.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
std::string getDescription();
|
||||
|
||||
/**
|
||||
* Intend to retrieve the value of a variable of the device.
|
||||
* \param name Name of the variable to get.
|
||||
* \return Value of the variable, if available.
|
||||
* \return Value of the variable, if available.
|
||||
*/
|
||||
std::vector<std::string> getVariableValue(const std::string& name)throw(NutException);
|
||||
std::vector<std::string> getVariableValue(const std::string& name);
|
||||
/**
|
||||
* Intend to retrieve values of all variables of the devices.
|
||||
* \return Map of all variables values indexed by their names.
|
||||
*/
|
||||
std::map<std::string,std::vector<std::string> > getVariableValues()throw(NutException);
|
||||
std::map<std::string,std::vector<std::string> > getVariableValues();
|
||||
/**
|
||||
* Retrieve all variables names supported by the device.
|
||||
* \return Set of available variable names.
|
||||
*/
|
||||
std::set<std::string> getVariableNames()throw(NutException);
|
||||
std::set<std::string> getVariableNames();
|
||||
/**
|
||||
* Retrieve all Read/Write variables names supported by the device.
|
||||
* \return Set of available Read/Write variable names.
|
||||
*/
|
||||
std::set<std::string> getRWVariableNames()throw(NutException);
|
||||
std::set<std::string> getRWVariableNames();
|
||||
/**
|
||||
* Intend to set the value of a variable of the device.
|
||||
* \param name Variable name.
|
||||
* \param value New variable value.
|
||||
*/
|
||||
void setVariable(const std::string& name, const std::string& value)throw(NutException);
|
||||
void setVariable(const std::string& name, const std::string& value);
|
||||
/**
|
||||
* Intend to set values of a variable of the device.
|
||||
* \param name Variable name.
|
||||
* \param value New variable values.
|
||||
* \param values Vector of new variable values.
|
||||
*/
|
||||
void setVariable(const std::string& name, const std::vector<std::string>& values)throw(NutException);
|
||||
void setVariable(const std::string& name, const std::vector<std::string>& values);
|
||||
|
||||
/**
|
||||
* Retrieve a Variable object representing the specified variable.
|
||||
* \param name Variable name.
|
||||
* \param name Variable name.
|
||||
* \return Variable object.
|
||||
*/
|
||||
Variable getVariable(const std::string& name)throw(NutException);
|
||||
Variable getVariable(const std::string& name);
|
||||
/**
|
||||
* Retrieve Variable objects representing all variables available for the device.
|
||||
* \return Set of Variable objects.
|
||||
*/
|
||||
std::set<Variable> getVariables()throw(NutException);
|
||||
std::set<Variable> getVariables();
|
||||
/**
|
||||
* Retrieve Variable objects representing all Read/Write variables available for the device.
|
||||
* \return Set of Variable objects.
|
||||
*/
|
||||
std::set<Variable> getRWVariables()throw(NutException);
|
||||
std::set<Variable> getRWVariables();
|
||||
|
||||
/**
|
||||
* Retrieve names of all commands supported by the device.
|
||||
* \return Set of available command names.
|
||||
*/
|
||||
std::set<std::string> getCommandNames()throw(NutException);
|
||||
std::set<std::string> getCommandNames();
|
||||
/**
|
||||
* Retrieve objects for all commands supported by the device.
|
||||
* \return Set of available Command objects.
|
||||
*/
|
||||
std::set<Command> getCommands()throw(NutException);
|
||||
std::set<Command> getCommands();
|
||||
/**
|
||||
* Retrieve an object representing a command of the device.
|
||||
* \param name Command name.
|
||||
* \return Command object.
|
||||
*/
|
||||
Command getCommand(const std::string& name)throw(NutException);
|
||||
Command getCommand(const std::string& name);
|
||||
/**
|
||||
* Intend to execute a command on the device.
|
||||
* \param name Command name.
|
||||
* \param param Additional command parameter
|
||||
*/
|
||||
void executeCommand(const std::string& name)throw(NutException);
|
||||
TrackingID executeCommand(const std::string& name, const std::string& param="");
|
||||
|
||||
/**
|
||||
* Login current client's user for the device.
|
||||
*/
|
||||
void login()throw(NutException);
|
||||
void master()throw(NutException);
|
||||
void forcedShutdown()throw(NutException);
|
||||
void login();
|
||||
/* FIXME: Protocol update needed to handle master/primary alias
|
||||
* and probably an API bump also, to rename/alias the routine.
|
||||
*/
|
||||
void master();
|
||||
void primary();
|
||||
void forcedShutdown();
|
||||
/**
|
||||
* Retrieve the number of logged user for the device.
|
||||
* \return Number of users.
|
||||
*/
|
||||
int getNumLogins()throw(NutException);
|
||||
int getNumLogins();
|
||||
|
||||
protected:
|
||||
Device(Client* client, const std::string& name);
|
||||
|
@ -558,10 +647,15 @@ class Variable
|
|||
{
|
||||
friend class Device;
|
||||
friend class TcpClient;
|
||||
friend class TcpClientMock;
|
||||
#ifdef _NUTCLIENTTEST_BUILD
|
||||
friend class NutClientTest;
|
||||
#endif
|
||||
public:
|
||||
~Variable();
|
||||
|
||||
Variable(const Variable& var);
|
||||
Variable& operator=(const Variable& var);
|
||||
|
||||
/**
|
||||
* Retrieve variable name.
|
||||
|
@ -603,23 +697,23 @@ public:
|
|||
* Intend to retrieve variable value.
|
||||
* \return Value of the variable.
|
||||
*/
|
||||
std::vector<std::string> getValue()throw(NutException);
|
||||
std::vector<std::string> getValue();
|
||||
/**
|
||||
* Intend to retireve variable description.
|
||||
* \return Variable description if provided.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
std::string getDescription();
|
||||
|
||||
/**
|
||||
* Intend to set a value to the variable.
|
||||
* \param value New variable value.
|
||||
*/
|
||||
void setValue(const std::string& value)throw(NutException);
|
||||
void setValue(const std::string& value);
|
||||
/**
|
||||
* Intend to set (multiple) values to the variable.
|
||||
* \param value New variable values.
|
||||
* \param values Vector of new variable values.
|
||||
*/
|
||||
void setValues(const std::vector<std::string>& values)throw(NutException);
|
||||
void setValues(const std::vector<std::string>& values);
|
||||
|
||||
protected:
|
||||
Variable(Device* dev, const std::string& name);
|
||||
|
@ -637,10 +731,15 @@ class Command
|
|||
{
|
||||
friend class Device;
|
||||
friend class TcpClient;
|
||||
friend class TcpClientMock;
|
||||
#ifdef _NUTCLIENTTEST_BUILD
|
||||
friend class NutClientTest;
|
||||
#endif
|
||||
public:
|
||||
~Command();
|
||||
|
||||
Command(const Command& cmd);
|
||||
Command& operator=(const Command& cmd);
|
||||
|
||||
/**
|
||||
* Retrieve command name.
|
||||
|
@ -683,13 +782,13 @@ public:
|
|||
* Intend to retireve command description.
|
||||
* \return Command description if provided.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
std::string getDescription();
|
||||
|
||||
/**
|
||||
* Intend to retrieve command description.
|
||||
* \return Command description if provided.
|
||||
* Intend to execute the instant command on device.
|
||||
* \param param Optional additional command parameter
|
||||
*/
|
||||
void execute()throw(NutException);
|
||||
void execute(const std::string& param="");
|
||||
|
||||
protected:
|
||||
Command(Device* dev, const std::string& name);
|
||||
|
@ -722,13 +821,19 @@ typedef char** strarr;
|
|||
/**
|
||||
* Alloc an array of string.
|
||||
*/
|
||||
strarr strarr_alloc(unsigned short count);
|
||||
strarr strarr_alloc(size_t count);
|
||||
|
||||
/**
|
||||
* Free an array of string.
|
||||
*/
|
||||
void strarr_free(strarr arr);
|
||||
|
||||
/**
|
||||
* Convert C++ types into an array of string.
|
||||
*/
|
||||
strarr stringvector_to_strarr(const std::vector<std::string>& strset);
|
||||
strarr stringset_to_strarr(const std::set<std::string>& strset);
|
||||
|
||||
|
||||
/**
|
||||
* Nut general client types and functions.
|
||||
|
@ -738,7 +843,7 @@ void strarr_free(strarr arr);
|
|||
typedef void* NUTCLIENT_t;
|
||||
|
||||
/**
|
||||
* Destroy a client.
|
||||
* Destroy a client.
|
||||
* \param client Nut client handle.
|
||||
*/
|
||||
void nutclient_destroy(NUTCLIENT_t client);
|
||||
|
@ -776,7 +881,11 @@ int nutclient_get_device_num_logins(NUTCLIENT_t client, const char* dev);
|
|||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
*/
|
||||
/* FIXME: Protocol update needed to handle master/primary alias
|
||||
* and probably an API bump also, to rename/alias the routine.
|
||||
*/
|
||||
void nutclient_device_master(NUTCLIENT_t client, const char* dev);
|
||||
void nutclient_device_primary(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Set the FSD flag for the device.
|
||||
|
@ -901,7 +1010,7 @@ char* nutclient_get_device_command_description(NUTCLIENT_t client, const char* d
|
|||
* \param dev Device name.
|
||||
* \param cmd Command name.
|
||||
*/
|
||||
void nutclient_execute_device_command(NUTCLIENT_t client, const char* dev, const char* cmd);
|
||||
void nutclient_execute_device_command(NUTCLIENT_t client, const char* dev, const char* cmd, const char* param="");
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -911,7 +1020,7 @@ void nutclient_execute_device_command(NUTCLIENT_t client, const char* dev, const
|
|||
* \{
|
||||
*/
|
||||
/**
|
||||
* Hidden structure representing a TCP connection to NUTD.
|
||||
* Hidden structure representing a TCP connection to NUTD.
|
||||
* NUTCLIENT_TCP_t is back compatible to NUTCLIENT_t.
|
||||
*/
|
||||
typedef NUTCLIENT_t NUTCLIENT_TCP_t;
|
||||
|
@ -920,9 +1029,9 @@ typedef NUTCLIENT_t NUTCLIENT_TCP_t;
|
|||
* Create a client to NUTD using a TCP connection.
|
||||
* \param host Host name to connect to.
|
||||
* \param port Host port.
|
||||
* \return New client or NULL if failed.
|
||||
* \return New client or nullptr if failed.
|
||||
*/
|
||||
NUTCLIENT_TCP_t nutclient_tcp_create_client(const char* host, unsigned short port);
|
||||
NUTCLIENT_TCP_t nutclient_tcp_create_client(const char* host, uint16_t port);
|
||||
/**
|
||||
* Test if a nut TCP client is connected.
|
||||
* \param client Nut TCP client handle.
|
||||
|
@ -945,12 +1054,12 @@ int nutclient_tcp_reconnect(NUTCLIENT_TCP_t client);
|
|||
* Set the timeout value for the TCP connection.
|
||||
* \param timeout Timeout in seconds, negative for blocking.
|
||||
*/
|
||||
void nutclient_tcp_set_timeout(NUTCLIENT_TCP_t client, long timeout);
|
||||
void nutclient_tcp_set_timeout(NUTCLIENT_TCP_t client, time_t timeout);
|
||||
/**
|
||||
* Retrieve the timeout value for the TCP connection.
|
||||
* \return Timeout value in seconds.
|
||||
*/
|
||||
long nutclient_tcp_get_timeout(NUTCLIENT_TCP_t client);
|
||||
time_t nutclient_tcp_get_timeout(NUTCLIENT_TCP_t client);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
|
252
clients/nutclientmem.cpp
Normal file
252
clients/nutclientmem.cpp
Normal file
|
@ -0,0 +1,252 @@
|
|||
/* nutclientmem.cpp - nutclientmem C++ library implementation
|
||||
|
||||
Copyright (C) 2021 Eric Clappier <ericclappier@eaton.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "nutclientmem.h"
|
||||
#include <common.h>
|
||||
|
||||
namespace nut
|
||||
{
|
||||
|
||||
/*
|
||||
*
|
||||
* Memory Client stub implementation
|
||||
*
|
||||
*/
|
||||
|
||||
Device MemClientStub::getDevice(const std::string& name)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(name);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::set<std::string> MemClientStub::getDeviceNames()
|
||||
{
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::string MemClientStub::getDeviceDescription(const std::string& name)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(name);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::set<std::string> MemClientStub::getDeviceVariableNames(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::set<std::string> MemClientStub::getDeviceRWVariableNames(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::string MemClientStub::getDeviceVariableDescription(const std::string& dev, const std::string& name)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
NUT_UNUSED_VARIABLE(name);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
ListValue MemClientStub::getDeviceVariableValue(const std::string& dev, const std::string& name)
|
||||
{
|
||||
ListValue res;
|
||||
auto it_dev = _values.find(dev);
|
||||
if (it_dev != _values.end())
|
||||
{
|
||||
auto map = it_dev->second;
|
||||
auto it_map = map.find(name);
|
||||
if (it_map != map.end())
|
||||
{
|
||||
res = it_map->second;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ListObject MemClientStub::getDeviceVariableValues(const std::string& dev)
|
||||
{
|
||||
ListObject res;
|
||||
auto it_dev = _values.find(dev);
|
||||
if (it_dev != _values.end())
|
||||
{
|
||||
res = it_dev->second;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
ListDevice MemClientStub::getDevicesVariableValues(const std::set<std::string>& devs)
|
||||
{
|
||||
ListDevice res;
|
||||
for (auto itr = devs.begin(); itr != devs.end(); itr++)
|
||||
{
|
||||
std::string dev = *itr;
|
||||
auto it_dev = _values.find(dev);
|
||||
if (it_dev != _values.end())
|
||||
{
|
||||
res.insert(std::pair<std::string, ListObject>(dev, it_dev->second));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TrackingID MemClientStub::setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value)
|
||||
{
|
||||
auto it_dev = _values.find(dev);
|
||||
if (it_dev == _values.end())
|
||||
{
|
||||
ListObject list;
|
||||
_values.emplace(dev, list);
|
||||
it_dev = _values.find(dev);
|
||||
}
|
||||
if (it_dev != _values.end())
|
||||
{
|
||||
auto map = &(it_dev->second);
|
||||
auto it_map = map->find(name);
|
||||
if (it_map != map->end())
|
||||
{
|
||||
it_map->second[0] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ListValue list_value;
|
||||
list_value.push_back(value);
|
||||
map->emplace(name, list_value);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
TrackingID MemClientStub::setDeviceVariable(const std::string& dev, const std::string& name, const ListValue& values)
|
||||
{
|
||||
auto it_dev = _values.find(dev);
|
||||
if (it_dev != _values.end())
|
||||
{
|
||||
auto map = &(it_dev->second);
|
||||
auto it_map = map->find(name);
|
||||
if (it_map != map->end())
|
||||
{
|
||||
it_map->second = values;
|
||||
}
|
||||
else
|
||||
{
|
||||
map->emplace(name, values);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::set<std::string> MemClientStub::getDeviceCommandNames(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
std::string MemClientStub::getDeviceCommandDescription(const std::string& dev, const std::string& name)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
NUT_UNUSED_VARIABLE(name);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
TrackingID MemClientStub::executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
NUT_UNUSED_VARIABLE(name);
|
||||
NUT_UNUSED_VARIABLE(param);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
void MemClientStub::deviceLogin(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
/* Note: "master" is deprecated, but supported
|
||||
* for mixing old/new client/server combos: */
|
||||
void MemClientStub::deviceMaster(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
void MemClientStub::devicePrimary(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
void MemClientStub::deviceForcedShutdown(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
int MemClientStub::deviceGetNumLogins(const std::string& dev)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(dev);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
TrackingResult MemClientStub::getTrackingResult(const TrackingID& id)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(id);
|
||||
throw NutException("Not implemented");
|
||||
//return TrackingResult::SUCCESS;
|
||||
}
|
||||
|
||||
bool MemClientStub::isFeatureEnabled(const Feature& feature)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(feature);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
void MemClientStub::setFeature(const Feature& feature, bool status)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(feature);
|
||||
NUT_UNUSED_VARIABLE(status);
|
||||
throw NutException("Not implemented");
|
||||
}
|
||||
|
||||
} /* namespace nut */
|
||||
|
||||
/**
|
||||
* C nutclient API.
|
||||
*/
|
||||
extern "C" {
|
||||
|
||||
NUTCLIENT_MEM_t nutclient_mem_create_client()
|
||||
{
|
||||
nut::MemClientStub* client = new nut::MemClientStub;
|
||||
try
|
||||
{
|
||||
return static_cast<NUTCLIENT_MEM_t>(client);
|
||||
}
|
||||
catch(nut::NutException& ex)
|
||||
{
|
||||
// TODO really catch it
|
||||
NUT_UNUSED_VARIABLE(ex);
|
||||
delete client;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
118
clients/nutclientmem.h
Normal file
118
clients/nutclientmem.h
Normal file
|
@ -0,0 +1,118 @@
|
|||
/* nutclientmem.h - definitions for nutclientmem C/C++ library
|
||||
|
||||
Copyright (C) 2021 Eric Clappier <ericclappier@eaton.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUTCLIENTMEM_HPP_SEEN
|
||||
#define NUTCLIENTMEM_HPP_SEEN
|
||||
|
||||
/* Begin of C++ nutclient library declaration */
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "nutclient.h"
|
||||
|
||||
namespace nut
|
||||
{
|
||||
|
||||
typedef std::vector<std::string> ListValue;
|
||||
typedef std::map<std::string, ListValue> ListObject;
|
||||
typedef std::map<std::string, ListObject> ListDevice;
|
||||
|
||||
/**
|
||||
* Memory client stub.
|
||||
* Class to stub TCPClient for test (data store in local memory).
|
||||
*/
|
||||
class MemClientStub : public Client
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a nut MemClientStub object.
|
||||
*/
|
||||
MemClientStub() {}
|
||||
~MemClientStub() override {}
|
||||
|
||||
virtual void authenticate(const std::string& user, const std::string& passwd) override {
|
||||
NUT_UNUSED_VARIABLE(user);
|
||||
NUT_UNUSED_VARIABLE(passwd);
|
||||
}
|
||||
virtual void logout() override {}
|
||||
|
||||
virtual Device getDevice(const std::string& name) override;
|
||||
virtual std::set<std::string> getDeviceNames() override;
|
||||
virtual std::string getDeviceDescription(const std::string& name) override;
|
||||
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev) override;
|
||||
virtual std::set<std::string> getDeviceRWVariableNames(const std::string& dev) override;
|
||||
virtual std::string getDeviceVariableDescription(const std::string& dev, const std::string& name) override;
|
||||
virtual ListValue getDeviceVariableValue(const std::string& dev, const std::string& name) override;
|
||||
virtual ListObject getDeviceVariableValues(const std::string& dev) override;
|
||||
virtual ListDevice getDevicesVariableValues(const std::set<std::string>& devs) override;
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const std::string& value) override;
|
||||
virtual TrackingID setDeviceVariable(const std::string& dev, const std::string& name, const ListValue& values) override;
|
||||
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev) override;
|
||||
virtual std::string getDeviceCommandDescription(const std::string& dev, const std::string& name) override;
|
||||
virtual TrackingID executeDeviceCommand(const std::string& dev, const std::string& name, const std::string& param="") override;
|
||||
|
||||
virtual void deviceLogin(const std::string& dev) override;
|
||||
/* Note: "master" is deprecated, but supported
|
||||
* for mixing old/new client/server combos: */
|
||||
virtual void deviceMaster(const std::string& dev) override;
|
||||
virtual void devicePrimary(const std::string& dev) override;
|
||||
virtual void deviceForcedShutdown(const std::string& dev) override;
|
||||
virtual int deviceGetNumLogins(const std::string& dev) override;
|
||||
|
||||
virtual TrackingResult getTrackingResult(const TrackingID& id) override;
|
||||
|
||||
virtual bool isFeatureEnabled(const Feature& feature) override;
|
||||
virtual void setFeature(const Feature& feature, bool status) override;
|
||||
|
||||
private:
|
||||
ListDevice _values;
|
||||
};
|
||||
|
||||
} /* namespace nut */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
/* End of C++ nutclient library declaration */
|
||||
|
||||
/* Begin of C nutclient library declaration */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* Nut MEM client dedicated types and functions
|
||||
*/
|
||||
/**
|
||||
* Hidden structure representing a MEM connection.
|
||||
* NUTCLIENT_MEM_t is back compatible to NUTCLIENT_t.
|
||||
*/
|
||||
typedef NUTCLIENT_t NUTCLIENT_MEM_t;
|
||||
|
||||
/**
|
||||
* Create a client to NUTD using memory.
|
||||
* \return New client or nullptr if failed.
|
||||
*/
|
||||
NUTCLIENT_MEM_t nutclient_mem_create_client();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
/* End of C nutclient library declaration */
|
||||
|
||||
#endif /* NUTCLIENTMOCK_HPP_SEEN */
|
|
@ -17,13 +17,19 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUT_STATUS_H_SEEN
|
||||
#define NUT_STATUS_H_SEEN 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
/* This is only used in upsstats.c, but might it also have external consumers?..
|
||||
* To move or not to move?..
|
||||
*/
|
||||
static struct {
|
||||
char *name;
|
||||
char *desc;
|
||||
int severity;
|
||||
|
@ -48,3 +54,4 @@ struct {
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_STATUS_H_SEEN */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* upsc - simple "client" to test communications
|
||||
/* upsc - simple "client" to test communications
|
||||
|
||||
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||
Copyright (C) 2012 Arnaud Quette <arnaud.quette@free.fr>
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "nut_stdint.h"
|
||||
#include "upsclient.h"
|
||||
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
|
@ -58,7 +59,7 @@ static void usage(const char *prog)
|
|||
static void printvar(const char *var)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -86,7 +87,7 @@ static void printvar(const char *var)
|
|||
}
|
||||
|
||||
if (numa < numq) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least %d)", numa, numq);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least %zu)", numa, numq);
|
||||
}
|
||||
|
||||
printf("%s\n", answer[3]);
|
||||
|
@ -95,7 +96,7 @@ static void printvar(const char *var)
|
|||
static void list_vars(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -119,7 +120,7 @@ static void list_vars(void)
|
|||
|
||||
/* VAR <upsname> <varname> <val> */
|
||||
if (numa < 4) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||
}
|
||||
|
||||
printf("%s: %s\n", answer[2], answer[3]);
|
||||
|
@ -129,7 +130,7 @@ static void list_vars(void)
|
|||
static void list_upses(int verbose)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -137,7 +138,7 @@ static void list_upses(int verbose)
|
|||
numq = 1;
|
||||
|
||||
ret = upscli_list_start(ups, numq, query);
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
/* check for an old upsd */
|
||||
if (upscli_upserror(ups) == UPSCLI_ERR_UNKCOMMAND) {
|
||||
|
@ -151,7 +152,7 @@ static void list_upses(int verbose)
|
|||
|
||||
/* UPS <upsname> <description> */
|
||||
if (numa < 3) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 3)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||
}
|
||||
|
||||
if(verbose) {
|
||||
|
@ -165,7 +166,7 @@ static void list_upses(int verbose)
|
|||
static void list_clients(const char *devname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -188,7 +189,7 @@ static void list_clients(const char *devname)
|
|||
|
||||
/* CLIENT <upsname> <address> */
|
||||
if (numa < 3) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 3)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||
}
|
||||
|
||||
printf("%s\n", answer[2]);
|
||||
|
@ -208,7 +209,8 @@ static void clean_exit(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, port;
|
||||
int i;
|
||||
uint16_t port;
|
||||
int varlist = 0, clientlist = 0, verbose = 0;
|
||||
const char *prog = xbasename(argv[0]);
|
||||
|
||||
|
@ -218,7 +220,9 @@ int main(int argc, char **argv)
|
|||
{
|
||||
case 'L':
|
||||
verbose = 1;
|
||||
goto fallthrough_case_l;
|
||||
case 'l':
|
||||
fallthrough_case_l:
|
||||
varlist = 1;
|
||||
break;
|
||||
case 'c':
|
||||
|
@ -227,6 +231,9 @@ int main(int argc, char **argv)
|
|||
|
||||
case 'V':
|
||||
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_SUCCESS); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifdef HAVE_PTHREAD
|
||||
/* this include is needed on AIX to have errno stored in thread local storage */
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
@ -38,13 +38,14 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "upsclient.h"
|
||||
#include "common.h"
|
||||
#include "nut_stdint.h"
|
||||
#include "timehead.h"
|
||||
#include "upsclient.h"
|
||||
|
||||
/* WA for Solaris/i386 bug: non-blocking connect sets errno to ENOENT */
|
||||
#if (defined NUT_PLATFORM_SOLARIS && CPU_TYPE == i386)
|
||||
#define SOLARIS_i386_NBCONNECT_ENOENT(status) (ENOENT == (status))
|
||||
#if (defined NUT_PLATFORM_SOLARIS)
|
||||
#define SOLARIS_i386_NBCONNECT_ENOENT(status) ( (!strcmp("i386", CPU_TYPE)) ? (ENOENT == (status)) : 0 )
|
||||
#else
|
||||
#define SOLARIS_i386_NBCONNECT_ENOENT(status) (0)
|
||||
#endif /* end of Solaris/i386 WA for non-blocking connect */
|
||||
|
@ -75,7 +76,7 @@
|
|||
#define shutdown_how 2
|
||||
#endif
|
||||
|
||||
struct {
|
||||
static struct {
|
||||
int flags;
|
||||
const char *str;
|
||||
} upscli_errlist[] =
|
||||
|
@ -131,7 +132,7 @@ typedef struct HOST_CERT_s {
|
|||
const char *certname;
|
||||
int certverify;
|
||||
int forcessl;
|
||||
|
||||
|
||||
struct HOST_CERT_s *next;
|
||||
} HOST_CERT_t;
|
||||
static HOST_CERT_t* upscli_find_host_cert(const char* hostname);
|
||||
|
@ -153,7 +154,7 @@ static char* nsscertpasswd = NULL;
|
|||
|
||||
static void ssl_debug(void)
|
||||
{
|
||||
int e;
|
||||
unsigned long e;
|
||||
char errmsg[SMALLBUF];
|
||||
|
||||
while ((e = ERR_get_error()) != 0) {
|
||||
|
@ -162,32 +163,36 @@ static void ssl_debug(void)
|
|||
}
|
||||
}
|
||||
|
||||
static int ssl_error(SSL *ssl, int ret)
|
||||
static int ssl_error(SSL *ssl, ssize_t ret)
|
||||
{
|
||||
int e;
|
||||
|
||||
e = SSL_get_error(ssl, ret);
|
||||
if (ret >= INT_MAX) {
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%zd would not fit in an int", ret);
|
||||
return -1;
|
||||
}
|
||||
e = SSL_get_error(ssl, (int)ret);
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR_WANT_READ", ret);
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%zd SSL_ERROR_WANT_READ", ret);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR_WANT_WRITE", ret);
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%zd SSL_ERROR_WANT_WRITE", ret);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (ret == 0 && ERR_peek_error() == 0) {
|
||||
upslogx(LOG_ERR, "ssl_error() EOF from client");
|
||||
} else {
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR_SYSCALL", ret);
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%zd SSL_ERROR_SYSCALL", ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR %d", ret, e);
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%zd SSL_ERROR %d", ret, e);
|
||||
ssl_debug();
|
||||
}
|
||||
|
||||
|
@ -196,9 +201,12 @@ static int ssl_error(SSL *ssl, int ret)
|
|||
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
|
||||
static char *nss_password_callback(PK11SlotInfo *slot, PRBool retry,
|
||||
static char *nss_password_callback(PK11SlotInfo *slot, PRBool retry,
|
||||
void *arg)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(retry);
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
|
||||
upslogx(LOG_INFO, "Intend to retrieve password for %s / %s: password %sconfigured",
|
||||
PK11_GetSlotName(slot), PK11_GetTokenName(slot), nsscertpasswd?"":"not ");
|
||||
return nsscertpasswd ? PL_strdup(nsscertpasswd) : NULL;
|
||||
|
@ -233,6 +241,10 @@ static SECStatus AuthCertificateDontVerify(CERTCertDBHandle *arg, PRFileDesc *fd
|
|||
PRBool checksig, PRBool isServer)
|
||||
{
|
||||
UPSCONN_t *ups = (UPSCONN_t *)SSL_RevealPinArg(fd);
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
NUT_UNUSED_VARIABLE(checksig);
|
||||
NUT_UNUSED_VARIABLE(isServer);
|
||||
|
||||
upslogx(LOG_INFO, "Do not intend to authenticate server %s",
|
||||
ups?ups->host:"<unnamed>");
|
||||
return SECSuccess;
|
||||
|
@ -241,6 +253,8 @@ static SECStatus AuthCertificateDontVerify(CERTCertDBHandle *arg, PRFileDesc *fd
|
|||
static SECStatus BadCertHandler(UPSCONN_t *arg, PRFileDesc *fd)
|
||||
{
|
||||
HOST_CERT_t* cert;
|
||||
NUT_UNUSED_VARIABLE(fd);
|
||||
|
||||
upslogx(LOG_WARNING, "Certificate validation failed for %s",
|
||||
(arg&&arg->host)?arg->host:"<unnamed>");
|
||||
/* BadCertHandler is called when the NSS certificate validation is failed.
|
||||
|
@ -288,49 +302,63 @@ static SECStatus GetClientAuthData(UPSCONN_t *arg, PRFileDesc *fd,
|
|||
|
||||
static void HandshakeCallback(PRFileDesc *fd, UPSCONN_t *client_data)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(fd);
|
||||
|
||||
upslogx(LOG_INFO, "SSL handshake done successfully with server %s",
|
||||
client_data->host);
|
||||
}
|
||||
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
int upscli_init(int certverify, const char *certpath,
|
||||
int upscli_init(int certverify, const char *certpath,
|
||||
const char *certname, const char *certpasswd)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
int ret, ssl_mode = SSL_VERIFY_NONE;
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
const SSL_METHOD *ssl_method;
|
||||
#else
|
||||
SSL_METHOD *ssl_method;
|
||||
#endif
|
||||
long ret;
|
||||
int ssl_mode = SSL_VERIFY_NONE;
|
||||
NUT_UNUSED_VARIABLE(certname);
|
||||
NUT_UNUSED_VARIABLE(certpasswd);
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
SECStatus status;
|
||||
#else
|
||||
NUT_UNUSED_VARIABLE(certverify);
|
||||
NUT_UNUSED_VARIABLE(certpath);
|
||||
NUT_UNUSED_VARIABLE(certname);
|
||||
NUT_UNUSED_VARIABLE(certpasswd);
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
|
||||
if (upscli_initialized == 1) {
|
||||
upslogx(LOG_WARNING, "upscli already initialized");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
SSL_library_init();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
ssl_method = TLSv1_client_method();
|
||||
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
#else
|
||||
ssl_ctx = SSL_CTX_new(TLS_client_method());
|
||||
#endif
|
||||
|
||||
if (!ssl_method) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssl_ctx = SSL_CTX_new(ssl_method);
|
||||
if (!ssl_ctx) {
|
||||
upslogx(LOG_ERR, "Can not initialize SSL context");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
/* set minimum protocol TLSv1 */
|
||||
SSL_CTX_set_options(ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
||||
#else
|
||||
ret = SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_VERSION);
|
||||
if (ret != 1) {
|
||||
upslogx(LOG_ERR, "Can not set minimum protocol to TLSv1");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!certpath) {
|
||||
if (certverify == 1) {
|
||||
upslogx(LOG_ERR, "Can not verify certificate if any is specified");
|
||||
|
@ -353,13 +381,13 @@ int upscli_init(int certverify, const char *certpath,
|
|||
return -1;
|
||||
}
|
||||
|
||||
SSL_CTX_set_verify(ssl_ctx, ssl_mode, NULL);
|
||||
SSL_CTX_set_verify(ssl_ctx, ssl_mode, NULL);
|
||||
}
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
|
||||
|
||||
|
||||
PK11_SetPasswordFunc(nss_password_callback);
|
||||
|
||||
|
||||
if (certpath) {
|
||||
upslogx(LOG_INFO, "Init SSL with cerificate database located at %s", certpath);
|
||||
status = NSS_Init(certpath);
|
||||
|
@ -372,16 +400,16 @@ int upscli_init(int certverify, const char *certpath,
|
|||
nss_error("upscli_init / NSS_[NoDB]_Init");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
status = NSS_SetDomesticPolicy();
|
||||
if (status != SECSuccess) {
|
||||
upslogx(LOG_ERR, "Can not initialize SSL policy");
|
||||
nss_error("upscli_init / NSS_SetDomesticPolicy");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
SSL_ClearSessionCache();
|
||||
|
||||
|
||||
status = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
|
||||
if (status != SECSuccess) {
|
||||
upslogx(LOG_ERR, "Can not enable SSLv3");
|
||||
|
@ -407,8 +435,13 @@ int upscli_init(int certverify, const char *certpath,
|
|||
nsscertpasswd = xstrdup(certpasswd);
|
||||
}
|
||||
verify_certificate = certverify;
|
||||
#else
|
||||
/* Note: historically we do not return with error here,
|
||||
* just fall through to below and treat as initialized.
|
||||
*/
|
||||
upslogx(LOG_ERR, "upscli_init called but SSL wasn't compiled in");
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
|
||||
upscli_initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -423,6 +456,11 @@ void upscli_add_host_cert(const char* hostname, const char* certname, int certve
|
|||
cert->certverify = certverify;
|
||||
cert->forcessl = forcessl;
|
||||
first_host_cert = cert;
|
||||
#else
|
||||
NUT_UNUSED_VARIABLE(hostname);
|
||||
NUT_UNUSED_VARIABLE(certname);
|
||||
NUT_UNUSED_VARIABLE(certverify);
|
||||
NUT_UNUSED_VARIABLE(forcessl);
|
||||
#endif /* WITH_NSS */
|
||||
}
|
||||
|
||||
|
@ -438,11 +476,13 @@ static HOST_CERT_t* upscli_find_host_cert(const char* hostname)
|
|||
cert = cert->next;
|
||||
}
|
||||
}
|
||||
#else
|
||||
NUT_UNUSED_VARIABLE(hostname);
|
||||
#endif /* WITH_NSS */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int upscli_cleanup()
|
||||
int upscli_cleanup(void)
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ssl_ctx) {
|
||||
|
@ -452,7 +492,7 @@ int upscli_cleanup()
|
|||
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
||||
#ifdef WITH_NSS
|
||||
#ifdef WITH_NSS
|
||||
/* Called to force cache clearing to prevent NSS shutdown failures.
|
||||
* http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslfnc.html#1138601
|
||||
*/
|
||||
|
@ -465,7 +505,7 @@ int upscli_cleanup()
|
|||
*/
|
||||
PL_ArenaFinish();
|
||||
#endif /* WITH_NSS */
|
||||
|
||||
|
||||
upscli_initialized = 0;
|
||||
return 1;
|
||||
}
|
||||
|
@ -477,6 +517,16 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
char sslbuf[UPSCLI_ERRBUF_LEN];
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
|
||||
if (!ups) {
|
||||
return upscli_errlist[UPSCLI_ERR_INVALIDARG].str;
|
||||
}
|
||||
|
@ -517,12 +567,12 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
if (PR_GetErrorTextLength() < UPSCLI_ERRBUF_LEN) {
|
||||
PR_GetErrorText(ups->errbuf);
|
||||
} else {
|
||||
snprintf(ups->errbuf, UPSCLI_ERRBUF_LEN,
|
||||
snprintf(ups->errbuf, UPSCLI_ERRBUF_LEN,
|
||||
"SSL error #%ld, message too long to be displayed",
|
||||
(long)PR_GetError());
|
||||
}
|
||||
#else
|
||||
snprintf(ups->errbuf, UPSCLI_ERRBUF_LEN,
|
||||
snprintf(ups->errbuf, UPSCLI_ERRBUF_LEN,
|
||||
"SSL error, but SSL wasn't enabled at compile-time");
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
return ups->errbuf;
|
||||
|
@ -534,6 +584,10 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
return ups->errbuf;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
snprintf(ups->errbuf, UPSCLI_ERRBUF_LEN, "Unknown error flag %d",
|
||||
|
@ -545,9 +599,9 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
/* Read up to buflen bytes from fd and return the number of bytes
|
||||
read. If no data is available within d_sec + d_usec, return 0.
|
||||
On error, a value < 0 is returned (errno indicates error). */
|
||||
static int upscli_select_read(const int fd, void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
static ssize_t upscli_select_read(const int fd, void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
|
@ -566,17 +620,37 @@ static int upscli_select_read(const int fd, void *buf, const size_t buflen, cons
|
|||
return read(fd, buf, buflen);
|
||||
}
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
/* internal: abstract the SSL calls for the other functions */
|
||||
static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
||||
static ssize_t net_read(UPSCONN_t *ups, char *buf, size_t buflen, const time_t timeout)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret = -1;
|
||||
|
||||
#ifdef WITH_SSL
|
||||
if (ups->ssl) {
|
||||
#ifdef WITH_OPENSSL
|
||||
ret = SSL_read(ups->ssl, buf, buflen);
|
||||
/* SSL_* routines deal with int type for return and buflen
|
||||
* We might need to window our I/O if we exceed 2GB (in
|
||||
* 32-bit builds)... Not likely to exceed in 64-bit builds,
|
||||
* but smaller systems with 16-bits might be endangered :)
|
||||
*/
|
||||
assert(buflen <= INT_MAX);
|
||||
int iret = SSL_read(ups->ssl, buf, (int)buflen);
|
||||
assert(iret <= SSIZE_MAX);
|
||||
ret = (ssize_t)iret;
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
ret = PR_Read(ups->ssl, buf, buflen);
|
||||
/* PR_* routines deal in PRInt32 type
|
||||
* We might need to window our I/O if we exceed 2GB :) */
|
||||
assert(buflen <= PR_INT32_MAX);
|
||||
ret = PR_Read(ups->ssl, buf, (PRInt32)buflen);
|
||||
#endif /* WITH_OPENSSL | WITH_NSS*/
|
||||
|
||||
if (ret < 1) {
|
||||
|
@ -587,7 +661,7 @@ static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = upscli_select_read(ups->fd, buf, buflen, 5, 0);
|
||||
ret = upscli_select_read(ups->fd, buf, buflen, timeout, 0);
|
||||
|
||||
/* error reading data, server disconnected? */
|
||||
if (ret < 0) {
|
||||
|
@ -602,13 +676,16 @@ static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/* Write up to buflen bytes to fd and return the number of bytes
|
||||
written. If no data is available within d_sec + d_usec, return 0.
|
||||
On error, a value < 0 is returned (errno indicates error). */
|
||||
static int upscli_select_write(const int fd, const void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
static ssize_t upscli_select_write(const int fd, const void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
|
@ -627,17 +704,37 @@ static int upscli_select_write(const int fd, const void *buf, const size_t bufle
|
|||
return write(fd, buf, buflen);
|
||||
}
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
/* internal: abstract the SSL calls for the other functions */
|
||||
static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
||||
static ssize_t net_write(UPSCONN_t *ups, const char *buf, size_t buflen, const time_t timeout)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret = -1;
|
||||
|
||||
#ifdef WITH_SSL
|
||||
if (ups->ssl) {
|
||||
#ifdef WITH_OPENSSL
|
||||
ret = SSL_write(ups->ssl, buf, buflen);
|
||||
/* SSL_* routines deal with int type for return and buflen
|
||||
* We might need to window our I/O if we exceed 2GB (in
|
||||
* 32-bit builds)... Not likely to exceed in 64-bit builds,
|
||||
* but smaller systems with 16-bits might be endangered :)
|
||||
*/
|
||||
assert(buflen <= INT_MAX);
|
||||
int iret = SSL_write(ups->ssl, buf, (int)buflen);
|
||||
assert(iret <= SSIZE_MAX);
|
||||
ret = (ssize_t)iret;
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
ret = PR_Write(ups->ssl, buf, buflen);
|
||||
/* PR_* routines deal in PRInt32 type
|
||||
* We might need to window our I/O if we exceed 2GB :) */
|
||||
assert(buflen <= PR_INT32_MAX);
|
||||
ret = PR_Write(ups->ssl, buf, (PRInt32)buflen);
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
if (ret < 1) {
|
||||
|
@ -648,7 +745,7 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = upscli_select_write(ups->fd, buf, buflen, 0, 0);
|
||||
ret = upscli_select_write(ups->fd, buf, buflen, timeout, 0);
|
||||
|
||||
/* error writing data, server disconnected? */
|
||||
if (ret < 0) {
|
||||
|
@ -663,6 +760,9 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WITH_SSL
|
||||
|
@ -670,7 +770,7 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
/*
|
||||
* 1 : OK
|
||||
* -1 : ERROR
|
||||
* 0 : SSL NOT SUPPORTED
|
||||
* 0 : SSL NOT SUPPORTED
|
||||
*/
|
||||
static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
||||
{
|
||||
|
@ -679,7 +779,7 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
SECStatus status;
|
||||
PRFileDesc *socket;
|
||||
HOST_CERT_t *cert;
|
||||
HOST_CERT_t *cert;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
char buf[UPSCLI_NETBUF_LEN];
|
||||
|
||||
|
@ -691,7 +791,7 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
"force initialisation without SSL configuration");
|
||||
upscli_init(0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* see if upsd even talks SSL/TLS */
|
||||
snprintf(buf, sizeof(buf), "STARTTLS\n");
|
||||
|
||||
|
@ -708,7 +808,7 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
}
|
||||
|
||||
/* upsd is happy, so let's crank up the client */
|
||||
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
if (!ssl_ctx) {
|
||||
|
@ -737,7 +837,7 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
switch(res)
|
||||
{
|
||||
case 1:
|
||||
upsdebugx(3, "SSL connected");
|
||||
upsdebugx(3, "SSL connected (%s)", SSL_get_version(ups->ssl));
|
||||
break;
|
||||
case 0:
|
||||
upslog_with_errno(1, "SSL_connect do not accept handshake.");
|
||||
|
@ -747,7 +847,7 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
upslog_with_errno(1, "Unknown return value from SSL_connect %d", res);
|
||||
ssl_error(ups->ssl, res);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
|
@ -764,12 +864,12 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
nss_error("upscli_sslinit / SSL_ImportFD");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (SSL_SetPKCS11PinArg(ups->ssl, ups) == -1){
|
||||
nss_error("upscli_sslinit / SSL_SetPKCS11PinArg");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (verifycert) {
|
||||
status = SSL_AuthCertificateHook(ups->ssl,
|
||||
(SSLAuthCertificate)AuthCertificate, CERT_GetDefaultCertDB());
|
||||
|
@ -781,19 +881,19 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
nss_error("upscli_sslinit / SSL_AuthCertificateHook");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
status = SSL_BadCertHook(ups->ssl, (SSLBadCertHandler)BadCertHandler, ups);
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_BadCertHook");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
status = SSL_GetClientAuthDataHook(ups->ssl, (SSLGetClientAuthData)GetClientAuthData, ups);
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_GetClientAuthDataHook");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
status = SSL_HandshakeCallback(ups->ssl, (SSLHandshakeCallback)HandshakeCallback, ups);
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_HandshakeCallback");
|
||||
|
@ -830,9 +930,9 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
/* TODO : Close the connection. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
}
|
||||
|
||||
|
@ -840,12 +940,15 @@ static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
|||
|
||||
static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(ups);
|
||||
NUT_UNUSED_VARIABLE(verifycert);
|
||||
|
||||
return 0; /* not supported */
|
||||
}
|
||||
|
||||
#endif /* WITH_SSL */
|
||||
|
||||
int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,struct timeval * timeout)
|
||||
int upscli_tryconnect(UPSCONN_t *ups, const char *host, uint16_t port, int flags, struct timeval * timeout)
|
||||
{
|
||||
int sock_fd;
|
||||
struct addrinfo hints, *res, *ai;
|
||||
|
@ -871,7 +974,7 @@ int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,stru
|
|||
return -1;
|
||||
}
|
||||
|
||||
snprintf(sport, sizeof(sport), "%hu", (unsigned short int)port);
|
||||
snprintf(sport, sizeof(sport), "%ju", (uintmax_t)port);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
|
@ -1005,7 +1108,7 @@ int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,stru
|
|||
ups->port = port;
|
||||
|
||||
hostcert = upscli_find_host_cert(host);
|
||||
|
||||
|
||||
if (hostcert != NULL) {
|
||||
/* An host security rule is specified. */
|
||||
certverify = hostcert->certverify;
|
||||
|
@ -1015,39 +1118,39 @@ int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,stru
|
|||
forcessl = (flags & UPSCLI_CONN_REQSSL) != 0 ? 1 : 0;
|
||||
}
|
||||
tryssl = (flags & UPSCLI_CONN_TRYSSL) != 0 ? 1 : 0;
|
||||
|
||||
|
||||
if (tryssl || forcessl) {
|
||||
ret = upscli_sslinit(ups, certverify);
|
||||
if (forcessl && ret != 1) {
|
||||
upslogx(LOG_ERR, "Can not connect to %s in SSL, disconnect", host);
|
||||
upslogx(LOG_ERR, "Can not connect to NUT server %s in SSL, disconnect", host);
|
||||
ups->upserror = UPSCLI_ERR_SSLFAIL;
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
} else if (tryssl && ret == -1) {
|
||||
upslogx(LOG_NOTICE, "Error while connecting to %s, disconnect", host);
|
||||
upslogx(LOG_NOTICE, "Error while connecting to NUT server %s, disconnect", host);
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
} else if (tryssl && ret == 0) {
|
||||
if (certverify != 0) {
|
||||
upslogx(LOG_NOTICE, "Can not connect to %s in SSL and "
|
||||
upslogx(LOG_NOTICE, "Can not connect to NUT server %s in SSL and "
|
||||
"certificate is needed, disconnect", host);
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
}
|
||||
upsdebugx(3, "Can not connect to %s in SSL, continue uncrypted", host);
|
||||
upsdebugx(3, "Can not connect to NUT server %s in SSL, continue unencrypted", host);
|
||||
} else {
|
||||
upslogx(LOG_INFO, "Connected to %s in SSL", host);
|
||||
upslogx(LOG_INFO, "Connected to NUT server %s in SSL", host);
|
||||
if (certverify == 0) {
|
||||
/* you REALLY should set CERTVERIFY to 1 if using SSL... */
|
||||
upslogx(LOG_WARNING, "Certificate verification is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags)
|
||||
int upscli_connect(UPSCONN_t *ups, const char *host, uint16_t port, int flags)
|
||||
{
|
||||
return upscli_tryconnect(ups,host,port,flags,NULL);
|
||||
}
|
||||
|
@ -1058,7 +1161,7 @@ static struct {
|
|||
const char *text;
|
||||
} upsd_errlist[] =
|
||||
{
|
||||
{ UPSCLI_ERR_VARNOTSUPP, "VAR-NOT-SUPPORTED" },
|
||||
{ UPSCLI_ERR_VARNOTSUPP, "VAR-NOT-SUPPORTED" },
|
||||
{ UPSCLI_ERR_UNKNOWNUPS, "UNKNOWN-UPS" },
|
||||
{ UPSCLI_ERR_ACCESSDENIED, "ACCESS-DENIED" },
|
||||
{ UPSCLI_ERR_PWDREQUIRED, "PASSWORD-REQUIRED" },
|
||||
|
@ -1083,7 +1186,7 @@ static struct {
|
|||
{ UPSCLI_ERR_INVPASSWORD, "INVALID-PASSWORD" },
|
||||
{ UPSCLI_ERR_USERREQUIRED, "USERNAME-REQUIRED" },
|
||||
{ UPSCLI_ERR_DRVNOTCONN, "DRIVER-NOT-CONNECTED" },
|
||||
|
||||
|
||||
{ 0, NULL, }
|
||||
};
|
||||
|
||||
|
@ -1120,9 +1223,9 @@ static int upscli_errcheck(UPSCONN_t *ups, char *buf)
|
|||
}
|
||||
|
||||
static void build_cmd(char *buf, size_t bufsize, const char *cmdname,
|
||||
int numarg, const char **arg)
|
||||
size_t numarg, const char **arg)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
size_t len;
|
||||
char enc[UPSCLI_NETBUF_LEN];
|
||||
const char *format;
|
||||
|
@ -1142,8 +1245,20 @@ static void build_cmd(char *buf, size_t bufsize, const char *cmdname,
|
|||
/* snprintfcat would tie us to common */
|
||||
|
||||
len = strlen(buf);
|
||||
snprintf(buf + len, bufsize - len, format,
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
snprintf(buf + len, bufsize - len, format,
|
||||
pconf_encode(arg[i], enc, sizeof(enc)));
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
len = strlen(buf);
|
||||
|
@ -1151,9 +1266,9 @@ static void build_cmd(char *buf, size_t bufsize, const char *cmdname,
|
|||
}
|
||||
|
||||
/* make sure upsd is giving us what we asked for */
|
||||
static int verify_resp(int num, const char **q, char **a)
|
||||
static int verify_resp(size_t num, const char **q, char **a)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (strcasecmp(q[i], a[i]) != 0) {
|
||||
|
@ -1166,11 +1281,11 @@ static int verify_resp(int num, const char **q, char **a)
|
|||
return 1; /* OK */
|
||||
}
|
||||
|
||||
int upscli_get(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer)
|
||||
int upscli_get(UPSCONN_t *ups, size_t numq, const char **query,
|
||||
size_t *numa, char ***answer)
|
||||
{
|
||||
char cmd[UPSCLI_NETBUF_LEN], tmp[UPSCLI_NETBUF_LEN];
|
||||
|
||||
|
||||
if (!ups) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1219,7 +1334,7 @@ int upscli_get(UPSCONN_t *ups, unsigned int numq, const char **query,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int upscli_list_start(UPSCONN_t *ups, unsigned int numq, const char **query)
|
||||
int upscli_list_start(UPSCONN_t *ups, size_t numq, const char **query)
|
||||
{
|
||||
char cmd[UPSCLI_NETBUF_LEN], tmp[UPSCLI_NETBUF_LEN];
|
||||
|
||||
|
@ -1277,8 +1392,8 @@ int upscli_list_start(UPSCONN_t *ups, unsigned int numq, const char **query)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int upscli_list_next(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer)
|
||||
int upscli_list_next(UPSCONN_t *ups, size_t numq, const char **query,
|
||||
size_t *numa, char ***answer)
|
||||
{
|
||||
char tmp[UPSCLI_NETBUF_LEN];
|
||||
|
||||
|
@ -1326,9 +1441,9 @@ int upscli_list_next(UPSCONN_t *ups, unsigned int numq, const char **query,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen)
|
||||
ssize_t upscli_sendline_timeout(UPSCONN_t *ups, const char *buf, size_t buflen, const time_t timeout)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
|
||||
if (!ups) {
|
||||
return -1;
|
||||
|
@ -1349,7 +1464,7 @@ int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
return -1;
|
||||
}
|
||||
|
||||
ret = net_write(ups, buf, buflen);
|
||||
ret = net_write(ups, buf, buflen, timeout);
|
||||
|
||||
if (ret < 1) {
|
||||
upscli_disconnect(ups);
|
||||
|
@ -1359,9 +1474,14 @@ int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen)
|
||||
ssize_t upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen)
|
||||
{
|
||||
int ret;
|
||||
return upscli_sendline_timeout(ups, buf, buflen, 0);
|
||||
}
|
||||
|
||||
ssize_t upscli_readline_timeout(UPSCONN_t *ups, char *buf, size_t buflen, const time_t timeout)
|
||||
{
|
||||
ssize_t ret;
|
||||
size_t recv;
|
||||
|
||||
if (!ups) {
|
||||
|
@ -1387,14 +1507,17 @@ int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
|
||||
if (ups->readidx == ups->readlen) {
|
||||
|
||||
ret = net_read(ups, ups->readbuf, sizeof(ups->readbuf));
|
||||
ret = net_read(ups, ups->readbuf, sizeof(ups->readbuf), timeout);
|
||||
|
||||
if (ret < 1) {
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ups->readlen = ret;
|
||||
/* Here ret is safe to cast since it is >=1 and certainly
|
||||
* fits under SIZE_MAX being it signed sibling
|
||||
*/
|
||||
ups->readlen = (size_t)ret;
|
||||
ups->readidx = 0;
|
||||
}
|
||||
|
||||
|
@ -1409,8 +1532,13 @@ int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
ssize_t upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen)
|
||||
{
|
||||
return upscli_readline_timeout(ups, buf, buflen, DEFAULT_NETWORK_TIMEOUT);
|
||||
}
|
||||
|
||||
/* split upsname[@hostname[:port]] into separate components */
|
||||
int upscli_splitname(const char *buf, char **upsname, char **hostname, int *port)
|
||||
int upscli_splitname(const char *buf, char **upsname, char **hostname, uint16_t *port)
|
||||
{
|
||||
char *s, tmp[SMALLBUF], *last = NULL;
|
||||
|
||||
|
@ -1446,9 +1574,10 @@ int upscli_splitname(const char *buf, char **upsname, char **hostname, int *port
|
|||
}
|
||||
|
||||
/* split hostname[:port] into separate components */
|
||||
int upscli_splitaddr(const char *buf, char **hostname, int *port)
|
||||
int upscli_splitaddr(const char *buf, char **hostname, uint16_t *port)
|
||||
{
|
||||
char *s, tmp[SMALLBUF], *last = NULL;
|
||||
long l;
|
||||
|
||||
/* paranoia */
|
||||
if ((!buf) || (!hostname) || (!port)) {
|
||||
|
@ -1491,10 +1620,13 @@ int upscli_splitaddr(const char *buf, char **hostname, int *port)
|
|||
}
|
||||
}
|
||||
|
||||
if ((*(++s) == '\0') || ((*port = strtol(s, NULL, 10)) < 1 )) {
|
||||
/* Check that "long" port fits in an "uint16_t" so is in IP range
|
||||
* (under 65536) */
|
||||
if ((*(++s) == '\0') || ((l = strtol(s, NULL, 10)) < 1 ) || (l > 65535)) {
|
||||
fprintf(stderr, "upscli_splitaddr: no port specified after ':' separator\n");
|
||||
return -1;
|
||||
}
|
||||
*port = (uint16_t)l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1518,7 +1650,7 @@ int upscli_disconnect(UPSCONN_t *ups)
|
|||
return 0;
|
||||
}
|
||||
|
||||
net_write(ups, "LOGOUT\n", 7);
|
||||
net_write(ups, "LOGOUT\n", 7, 0);
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ups->ssl) {
|
||||
|
|
|
@ -21,13 +21,26 @@
|
|||
#define UPSCLIENT_H_SEEN
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
#include <nss.h>
|
||||
#include <ssl.h>
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
/* Not including nut_stdint.h because this is part of end-user API */
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if defined HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
|
@ -41,7 +54,7 @@ extern "C" {
|
|||
|
||||
typedef struct {
|
||||
char *host;
|
||||
int port;
|
||||
uint16_t port;
|
||||
int fd;
|
||||
int flags;
|
||||
int upserror;
|
||||
|
@ -69,31 +82,33 @@ typedef struct {
|
|||
const char *upscli_strerror(UPSCONN_t *ups);
|
||||
|
||||
int upscli_init(int certverify, const char *certpath, const char *certname, const char *certpasswd);
|
||||
int upscli_cleanup();
|
||||
int upscli_cleanup(void);
|
||||
|
||||
int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags, struct timeval *tv);
|
||||
int upscli_connect(UPSCONN_t *ups, const char *host, int port, int flags);
|
||||
int upscli_tryconnect(UPSCONN_t *ups, const char *host, uint16_t port, int flags, struct timeval *tv);
|
||||
int upscli_connect(UPSCONN_t *ups, const char *host, uint16_t port, int flags);
|
||||
|
||||
void upscli_add_host_cert(const char* hostname, const char* certname, int certverify, int forcessl);
|
||||
|
||||
/* --- functions that only use the new names --- */
|
||||
|
||||
int upscli_get(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer);
|
||||
int upscli_get(UPSCONN_t *ups, size_t numq, const char **query,
|
||||
size_t *numa, char ***answer);
|
||||
|
||||
int upscli_list_start(UPSCONN_t *ups, unsigned int numq, const char **query);
|
||||
int upscli_list_start(UPSCONN_t *ups, size_t numq, const char **query);
|
||||
|
||||
int upscli_list_next(UPSCONN_t *ups, unsigned int numq, const char **query,
|
||||
unsigned int *numa, char ***answer);
|
||||
int upscli_list_next(UPSCONN_t *ups, size_t numq, const char **query,
|
||||
size_t *numa, char ***answer);
|
||||
|
||||
int upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen);
|
||||
ssize_t upscli_sendline_timeout(UPSCONN_t *ups, const char *buf, size_t buflen, const time_t timeout);
|
||||
ssize_t upscli_sendline(UPSCONN_t *ups, const char *buf, size_t buflen);
|
||||
|
||||
int upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen);
|
||||
ssize_t upscli_readline_timeout(UPSCONN_t *ups, char *buf, size_t buflen, const time_t timeout);
|
||||
ssize_t upscli_readline(UPSCONN_t *ups, char *buf, size_t buflen);
|
||||
|
||||
int upscli_splitname(const char *buf, char **upsname, char **hostname,
|
||||
int *port);
|
||||
uint16_t *port);
|
||||
|
||||
int upscli_splitaddr(const char *buf, char **hostname, int *port);
|
||||
int upscli_splitaddr(const char *buf, char **hostname, uint16_t *port);
|
||||
|
||||
int upscli_disconnect(UPSCONN_t *ups);
|
||||
|
||||
|
@ -103,7 +118,7 @@ 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);
|
||||
int upscli_ssl(UPSCONN_t *ups);
|
||||
|
||||
/* upsclient error list */
|
||||
|
||||
|
|
148
clients/upscmd.c
148
clients/upscmd.c
|
@ -1,6 +1,8 @@
|
|||
/* upscmd - simple "client" to test instant commands via upsd
|
||||
|
||||
Copyright (C) 2000 Russell Kroll <rkroll@exploits.org>
|
||||
Copyright (C)
|
||||
2000 Russell Kroll <rkroll@exploits.org>
|
||||
2019 EATON (author: Arnaud Quette <ArnaudQuette@eaton.com>)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -26,10 +28,13 @@
|
|||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "nut_stdint.h"
|
||||
#include "upsclient.h"
|
||||
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
static UPSCONN_t *ups = NULL;
|
||||
static int tracking_enabled = 0;
|
||||
static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT;
|
||||
|
||||
struct list_t {
|
||||
char *name;
|
||||
|
@ -41,13 +46,16 @@ 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(" %s [-u <username>] [-p <password>] [-w] [-t <timeout>] <ups> <command> [<value>]\n\n", prog);
|
||||
printf("Administration program to initiate instant commands on UPS hardware.\n");
|
||||
printf("\n");
|
||||
printf(" -h display this help text\n");
|
||||
printf(" -l <ups> show available commands on UPS <ups>\n");
|
||||
printf(" -u <username> set username for command authentication\n");
|
||||
printf(" -p <password> set password for command authentication\n");
|
||||
printf(" -w wait for the completion of command by the driver\n");
|
||||
printf(" and return its actual result from the device\n");
|
||||
printf(" -t <timeout> set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT);
|
||||
printf("\n");
|
||||
printf(" <ups> UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
|
||||
printf(" <command> Valid instant command - test.panel.start, etc.\n");
|
||||
|
@ -57,7 +65,7 @@ static void usage(const char *prog)
|
|||
static void print_cmd(char *cmdname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -80,7 +88,7 @@ static void print_cmd(char *cmdname)
|
|||
static void listcmds(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
struct list_t *lhead = NULL, *llast = NULL, *ltmp, *lnext;
|
||||
|
@ -105,7 +113,7 @@ static void listcmds(void)
|
|||
|
||||
/* CMD <upsname> <cmdname> */
|
||||
if (numa < 3) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 3)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 3)", numa);
|
||||
}
|
||||
|
||||
/* we must first read the entire list of commands,
|
||||
|
@ -136,9 +144,21 @@ static void listcmds(void)
|
|||
}
|
||||
}
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC)
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC)
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
static void do_cmd(char **argv, const int argc)
|
||||
{
|
||||
int cmd_complete = 0;
|
||||
char buf[SMALLBUF];
|
||||
char tracking_id[UUID4_LEN];
|
||||
time_t start, now;
|
||||
|
||||
if (argc > 1) {
|
||||
snprintf(buf, sizeof(buf), "INSTCMD %s %s %s\n", upsname, argv[0], argv[1]);
|
||||
|
@ -154,13 +174,88 @@ static void do_cmd(char **argv, const int argc)
|
|||
fatalx(EXIT_FAILURE, "Instant command failed: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
/* FUTURE: status cookies will tie in here */
|
||||
/* verify answer */
|
||||
if (strncmp(buf, "OK", 2) != 0) {
|
||||
fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf);
|
||||
}
|
||||
|
||||
/* check for status tracking id */
|
||||
if (
|
||||
!tracking_enabled ||
|
||||
/* sanity check on the size: "OK TRACKING " + UUID4_LEN */
|
||||
strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING "))
|
||||
) {
|
||||
/* reply as usual */
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||
#endif
|
||||
/* From the check above, we know that we have exactly UUID4_LEN chars
|
||||
* (aka sizeof(tracking_id)) in the buf after "OK TRACKING " prefix,
|
||||
* plus the null-byte.
|
||||
*/
|
||||
assert (UUID4_LEN == 1 + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")));
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
time(&start);
|
||||
|
||||
/* send status tracking request, looping if status is PENDING */
|
||||
while (!cmd_complete) {
|
||||
|
||||
/* check for timeout */
|
||||
time(&now);
|
||||
if (difftime(now, start) >= timeout)
|
||||
fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout");
|
||||
|
||||
snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id);
|
||||
|
||||
if (upscli_sendline(ups, buf, strlen(buf)) < 0)
|
||||
fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups));
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||
/* Note for gating macros above: unsuffixed HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP
|
||||
* means support of contexts both inside and outside function body, so the push
|
||||
* above and pop below (outside this finction) are not used.
|
||||
*/
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS
|
||||
/* Note that the individual warning pragmas for use inside function bodies
|
||||
* are named without a _INSIDEFUNC suffix, for simplicity and legacy reasons
|
||||
*/
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
/* and get status tracking reply */
|
||||
assert(timeout < LONG_MAX);
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
if (upscli_readline_timeout(ups, buf, sizeof(buf), (long)timeout) < 0)
|
||||
fatalx(EXIT_FAILURE, "Can't receive status tracking information: %s", upscli_strerror(ups));
|
||||
|
||||
if (strncmp(buf, "PENDING", 7))
|
||||
cmd_complete = 1;
|
||||
else
|
||||
/* wait a second before retrying */
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static void clean_exit(void)
|
||||
{
|
||||
|
@ -175,12 +270,14 @@ static void clean_exit(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, ret, port;
|
||||
int i;
|
||||
uint16_t port;
|
||||
ssize_t ret;
|
||||
int have_un = 0, have_pw = 0, cmdlist = 0;
|
||||
char buf[SMALLBUF], username[SMALLBUF], password[SMALLBUF];
|
||||
char buf[SMALLBUF * 2], username[SMALLBUF], password[SMALLBUF];
|
||||
const char *prog = xbasename(argv[0]);
|
||||
|
||||
while ((i = getopt(argc, argv, "+lhu:p:V")) != -1) {
|
||||
while ((i = getopt(argc, argv, "+lhu:p:t:wV")) != -1) {
|
||||
|
||||
switch (i)
|
||||
{
|
||||
|
@ -198,8 +295,20 @@ int main(int argc, char **argv)
|
|||
have_pw = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (!str_to_uint(optarg, &timeout, 10))
|
||||
fatal_with_errno(EXIT_FAILURE, "Could not convert the provided value for timeout ('-t' option) to unsigned int");
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
tracking_enabled = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
fatalx(EXIT_SUCCESS, "Network UPS Tools upscmd %s", UPS_VERSION);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_SUCCESS); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
|
@ -313,6 +422,25 @@ int main(int argc, char **argv)
|
|||
fatalx(EXIT_FAILURE, "Set password failed: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
/* enable status tracking ID */
|
||||
if (tracking_enabled) {
|
||||
|
||||
snprintf(buf, sizeof(buf), "SET TRACKING ON\n");
|
||||
|
||||
if (upscli_sendline(ups, buf, strlen(buf)) < 0) {
|
||||
fatalx(EXIT_FAILURE, "Can't enable command status tracking: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
if (upscli_readline(ups, buf, sizeof(buf)) < 0) {
|
||||
fatalx(EXIT_FAILURE, "Enabling command status tracking failed: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
/* Verify the result */
|
||||
if (strncmp(buf, "OK", 2) != 0) {
|
||||
fatalx(EXIT_FAILURE, "Enabling command status tracking failed. upsd answered: %s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
do_cmd(&argv[1], argc - 1);
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_stdint.h"
|
||||
#include "upsclient.h"
|
||||
#include "cgilib.h"
|
||||
#include <stdlib.h>
|
||||
|
@ -49,7 +50,7 @@
|
|||
|
||||
static char *monhost = NULL, *cmd = NULL;
|
||||
|
||||
static int port;
|
||||
static uint16_t port;
|
||||
static char *upsname, *hostname;
|
||||
static UPSCONN_t ups;
|
||||
|
||||
|
@ -60,7 +61,7 @@ static UPSCONN_t ups;
|
|||
|
||||
void parsearg(char *var, char *value)
|
||||
{
|
||||
int i, v;
|
||||
long long i, v; /* Be big enough to fit all expected inputs; truncate later */
|
||||
|
||||
/* avoid bogus junk from evil people */
|
||||
if ((strlen(var) > MAX_CGI_STRLEN) || (strlen(value) > MAX_CGI_STRLEN))
|
||||
|
@ -82,17 +83,20 @@ void parsearg(char *var, char *value)
|
|||
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);
|
||||
v = (long long)strtoul(value + 2, (char **)NULL, 16);
|
||||
else
|
||||
v = atoi(value);
|
||||
v = (long long)atoi(value);
|
||||
|
||||
/* avoid false numbers from bad people */
|
||||
if (v < imgarg[i].min)
|
||||
imgarg[i].val = imgarg[i].min;
|
||||
else if (v > imgarg[i].max)
|
||||
imgarg[i].val = imgarg[i].max;
|
||||
else
|
||||
imgarg[i].val = v;
|
||||
else {
|
||||
assert (v < INT_MAX);
|
||||
assert (v > INT_MIN);
|
||||
imgarg[i].val = (int)v;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +115,9 @@ static int get_imgarg(const char *name)
|
|||
}
|
||||
|
||||
/* write the HTML header then have gd dump the image */
|
||||
static void drawimage(gdImagePtr im)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void drawimage(gdImagePtr im)
|
||||
{
|
||||
printf("Pragma: no-cache\n");
|
||||
|
@ -191,7 +198,7 @@ static void drawscale(
|
|||
if (level % step5 == 0)
|
||||
gdImageLine(im, 5, y, width - 5, y, col2);
|
||||
else
|
||||
gdImageLine(im, 10, y, width - 10, y, col2);
|
||||
gdImageLine(im, 10, y, width - 10, y, col2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,13 +207,25 @@ static void drawscale(
|
|||
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);
|
||||
gdImageString(im, gdFontMediumBold,
|
||||
width - (int)(strlen(lbltxt)) * gdFontMediumBold->w,
|
||||
y, (unsigned char *) lbltxt, scale_num_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draws the bar style indicator */
|
||||
static void drawbar(
|
||||
int lvllo, int lvlhi, /* min and max numbers on the scale */
|
||||
int step, int step5, int step10, /* steps for minor, submajor and major dashes */
|
||||
int redlo1, int redhi1, /* first red zone start and end */
|
||||
int redlo2, int redhi2, /* second red zone start and end */
|
||||
int grnlo, int grnhi, /* green zone start and end */
|
||||
double value, /* UPS variable value to draw */
|
||||
const char *format /* printf style format to be used when rendering summary text */
|
||||
)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void drawbar(
|
||||
int lvllo, int lvlhi, /* min and max numbers on the scale */
|
||||
int step, int step5, int step10, /* steps for minor, submajor and major dashes */
|
||||
|
@ -240,7 +259,7 @@ static void drawbar(
|
|||
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;
|
||||
bar_y = (int)((1.0 - (value - lvllo) / (lvlhi - lvllo)) * scale_height);
|
||||
|
||||
/* sanity checks: */
|
||||
|
||||
|
@ -257,9 +276,21 @@ static void drawbar(
|
|||
bar_color);
|
||||
|
||||
/* stick the text version of the value at the bottom center */
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
snprintf(text, sizeof(text), format, value);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
gdImageString(im, gdFontMediumBold,
|
||||
(width - strlen(text)*gdFontMediumBold->w)/2,
|
||||
(width - (int)(strlen(text))*gdFontMediumBold->w)/2,
|
||||
height - gdFontMediumBold->h,
|
||||
(unsigned char *) text, summary_color);
|
||||
|
||||
|
@ -269,6 +300,9 @@ static void drawbar(
|
|||
}
|
||||
|
||||
/* draws the error image */
|
||||
static void noimage(const char *fmt, ...)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void noimage(const char *fmt, ...)
|
||||
{
|
||||
gdImagePtr im;
|
||||
|
@ -278,7 +312,19 @@ static void noimage(const char *fmt, ...)
|
|||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
width = get_imgarg("width");
|
||||
|
@ -293,17 +339,23 @@ static void noimage(const char *fmt, ...)
|
|||
|
||||
if (width > height)
|
||||
gdImageString(im, gdFontMediumBold,
|
||||
(width - strlen(msg)*gdFontMediumBold->w)/2,
|
||||
(width - (int)(strlen(msg))*gdFontMediumBold->w)/2,
|
||||
(height - gdFontMediumBold->h)/2,
|
||||
(unsigned char *) msg, summary_color);
|
||||
else
|
||||
gdImageStringUp(im, gdFontMediumBold,
|
||||
(width - gdFontMediumBold->h)/2,
|
||||
(height + strlen(msg)*gdFontMediumBold->w)/2,
|
||||
(height + (int)(strlen(msg))*gdFontMediumBold->w)/2,
|
||||
(unsigned char *) msg, summary_color);
|
||||
|
||||
drawimage(im);
|
||||
|
||||
/* NOTE: Earlier code called noimage() and then exit(EXIT_FAILURE);
|
||||
* to signal an error via process exit code. Now that drawimage()
|
||||
* always ends with exit(EXIT_SUCCESS) - which might make webserver
|
||||
* feel good - the command-line use if any suffers no error returns.
|
||||
*/
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
@ -311,6 +363,10 @@ static void noimage(const char *fmt, ...)
|
|||
UPS variable can be determined.
|
||||
deviation < 0 means that values below nom should be grey instead of
|
||||
green */
|
||||
static void drawgeneralbar(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void drawgeneralbar(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
|
@ -370,6 +426,10 @@ static void drawgeneralbar(double var, int min, int nom, int max,
|
|||
}
|
||||
|
||||
/* draws input and output voltage bar style indicators */
|
||||
static void draw_utility(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_utility(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
|
@ -405,7 +465,7 @@ static void draw_utility(double var, int min, int nom, int max,
|
|||
|
||||
/* Acceptable range of voltage is 85%-110% of nominal voltage
|
||||
* in EU at least. Be conservative and say +-10% */
|
||||
deviation = nom*0.1;
|
||||
deviation = (int)(nom * 0.1);
|
||||
|
||||
drawgeneralbar(var, min, nom, max, deviation, format);
|
||||
|
||||
|
@ -413,9 +473,17 @@ static void draw_utility(double var, int min, int nom, int max,
|
|||
}
|
||||
|
||||
/* draws battery.percent bar style indicator */
|
||||
static void draw_battpct(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
static void draw_battpct(double var, int min, int nom,
|
||||
int max, int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_battpct(double var, int min, int nom,
|
||||
int max, int deviation, const char *format)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(nom);
|
||||
NUT_UNUSED_VARIABLE(max);
|
||||
NUT_UNUSED_VARIABLE(deviation);
|
||||
|
||||
if (min < 0) {
|
||||
min = 50;
|
||||
}
|
||||
|
@ -424,6 +492,10 @@ static void draw_battpct(double var, int min, int nom, int max,
|
|||
}
|
||||
|
||||
/* draws battery.voltage bar style indicator */
|
||||
static void draw_battvolt(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_battvolt(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
|
@ -450,18 +522,17 @@ static void draw_battvolt(double var, int min, int nom, int max,
|
|||
}
|
||||
|
||||
if(min == -1) {
|
||||
min = nom/2*1.6+1; /* Assume a 2V cell is dead at 1.6V */
|
||||
min = (int)(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 */
|
||||
max = (int)(nom/2*2.3+1); /* Assume 2.3V float charge voltage */
|
||||
}
|
||||
|
||||
if (nom < min || nom > max)
|
||||
nom = -1;
|
||||
nom = -1;
|
||||
|
||||
|
||||
deviation = -(nom*0.05); /* 5% deviation from nominal voltage */
|
||||
deviation = (int)(-nom*0.05); /* 5% deviation from nominal voltage */
|
||||
if(deviation==0) {
|
||||
deviation = -1;
|
||||
}
|
||||
|
@ -470,33 +541,57 @@ static void draw_battvolt(double var, int min, int nom, int max,
|
|||
}
|
||||
|
||||
/* draws ups.load bar style indicator */
|
||||
static void draw_upsload(double var, int min, int nom, int max,
|
||||
static void draw_upsload(double var, int min,
|
||||
int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_upsload(double var, int min,
|
||||
int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(min);
|
||||
NUT_UNUSED_VARIABLE(nom);
|
||||
NUT_UNUSED_VARIABLE(max);
|
||||
NUT_UNUSED_VARIABLE(deviation);
|
||||
|
||||
drawbar(0, 125, 5, 5, 25, 100, 125, -1, -1, 0, 50, var, format);
|
||||
}
|
||||
|
||||
/* draws temperature bar style indicator */
|
||||
static void draw_temperature(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_temperature(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
int hi = get_imgarg("tempmax");
|
||||
int lo = get_imgarg("tempmin");
|
||||
NUT_UNUSED_VARIABLE(nom);
|
||||
NUT_UNUSED_VARIABLE(deviation);
|
||||
|
||||
drawbar(lo, hi, 1, 5, 10, lo, min, max, hi, -1, -1, var, format);
|
||||
}
|
||||
|
||||
/* draws humidity bar style indicator */
|
||||
static void draw_humidity(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void draw_humidity(double var, int min, int nom, int max,
|
||||
int deviation, const char *format)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(nom);
|
||||
NUT_UNUSED_VARIABLE(deviation);
|
||||
|
||||
drawbar(0, 100, 2, 10, 20, 0, min, max, 100, -1, -1, var, format);
|
||||
}
|
||||
|
||||
static int get_var(const char *var, char *buf, size_t buflen)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -523,6 +618,8 @@ int main(int argc, char **argv)
|
|||
char str[SMALLBUF];
|
||||
int i, min, nom, max;
|
||||
double var = 0;
|
||||
NUT_UNUSED_VARIABLE(argc);
|
||||
NUT_UNUSED_VARIABLE(argv);
|
||||
|
||||
extractcgiargs();
|
||||
|
||||
|
@ -537,13 +634,17 @@ int main(int argc, char **argv)
|
|||
|
||||
if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) {
|
||||
noimage("Invalid UPS definition (upsname[@hostname[:port]])\n");
|
||||
exit(EXIT_FAILURE);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
}
|
||||
|
||||
if (upscli_connect(&ups, hostname, port, 0) < 0) {
|
||||
noimage("Can't connect to server:\n%s\n",
|
||||
upscli_strerror(&ups));
|
||||
exit(EXIT_FAILURE);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
}
|
||||
|
||||
for (i = 0; imgvar[i].name; i++)
|
||||
|
@ -553,7 +654,9 @@ int main(int argc, char **argv)
|
|||
registered with this variable */
|
||||
if (!imgvar[i].drawfunc) {
|
||||
noimage("Draw function N/A");
|
||||
exit(EXIT_FAILURE);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* get the variable value */
|
||||
|
@ -564,7 +667,9 @@ int main(int argc, char **argv)
|
|||
snprintf(str, sizeof(str), "%s N/A",
|
||||
imgvar[i].name);
|
||||
noimage(str);
|
||||
exit(EXIT_FAILURE);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_FAILURE); /* Should not get here in practice, but compiler is afraid we can fall through */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* when getting minimum, nominal and maximum values,
|
||||
|
@ -617,7 +722,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
noimage("Unknown display");
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
exit(EXIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
imgvar_t imgvar[] = {
|
||||
|
|
|
@ -17,25 +17,32 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUT_UPSIMAGEARG_H_SEEN
|
||||
#define NUT_UPSIMAGEARG_H_SEEN 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
/* This is used in upsstats.c and in upsimage.c, but compiler complains about
|
||||
* non-extern definition if this is not "static". To move or not to move?..
|
||||
* Do we have cases of building binaries refering to only one of those objects?
|
||||
*/
|
||||
static struct {
|
||||
char *name;
|
||||
int val; /* hex digits, ala HTML */
|
||||
int min; /* minimum reasonable value */
|
||||
int max; /* maximum reasonable value */
|
||||
} imgarg[] =
|
||||
} 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 },
|
||||
{ "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 },
|
||||
|
@ -47,20 +54,20 @@ struct {
|
|||
{ "tempmax", 40, -100, 150 },
|
||||
{ "nom_in_freq", 50, 0, 100 },
|
||||
{ "nom_out_freq", 50, 0, 100 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *name; /* name of the UPS variable */
|
||||
char *minimum; /* name of minimum value UPS variable
|
||||
or variable in imgarg table */
|
||||
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*);
|
||||
void (*drawfunc)(double, int, int, int, int, const char*);
|
||||
} imgvar_t;
|
||||
|
||||
extern imgvar_t imgvar[];
|
||||
|
@ -71,3 +78,4 @@ extern imgvar_t imgvar[];
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_UPSIMAGEARG_H_SEEN */
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
/* 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
|
||||
* 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.
|
||||
|
@ -37,9 +37,11 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "timehead.h"
|
||||
#include "nut_stdint.h"
|
||||
#include "upslog.h"
|
||||
|
||||
static int port, reopen_flag = 0, exit_flag = 0;
|
||||
static int reopen_flag = 0, exit_flag = 0;
|
||||
static uint16_t port;
|
||||
static char *upsname, *hostname;
|
||||
static UPSCONN_t ups;
|
||||
|
||||
|
@ -79,6 +81,8 @@ static void set_exit_flag(int sig)
|
|||
|
||||
static void set_print_now_flag(int sig)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(sig);
|
||||
|
||||
/* no need to do anything, the signal will cause sleep to be interrupted */
|
||||
}
|
||||
|
||||
|
@ -108,6 +112,9 @@ static void setup_signals(void)
|
|||
fatal_with_errno(EXIT_FAILURE, "Can't install SIGUSR1 handler");
|
||||
}
|
||||
|
||||
static void help(const char *prog)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void help(const char *prog)
|
||||
{
|
||||
printf("UPS status logger.\n");
|
||||
|
@ -118,7 +125,9 @@ static void help(const char *prog)
|
|||
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(" -l <logfile> - Log file name, or - for stdout (foreground by default)\n");
|
||||
printf(" -F - stay foregrounded even if logging into a file\n");
|
||||
printf(" -B - stay backgrounded even if logging to stdout\n");
|
||||
printf(" -p <pidbase> - Base name for PID file (defaults to \"%s\")\n", prog);
|
||||
printf(" -s <ups> - Monitor UPS <ups> - <upsname>@<host>[:<port>]\n");
|
||||
printf(" - Example: -s myups@server\n");
|
||||
|
@ -146,6 +155,7 @@ static void do_host(const char *arg)
|
|||
{
|
||||
int ret;
|
||||
char hn[LARGEBUF];
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
|
||||
ret = gethostname(hn, sizeof(hn));
|
||||
|
||||
|
@ -159,11 +169,15 @@ static void do_host(const char *arg)
|
|||
|
||||
static void do_upshost(const char *arg)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%s", monhost);
|
||||
}
|
||||
|
||||
static void do_pid(const char *arg)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (long)getpid());
|
||||
}
|
||||
|
||||
|
@ -172,6 +186,7 @@ static void do_time(const char *arg)
|
|||
unsigned int i;
|
||||
char timebuf[SMALLBUF], *format;
|
||||
time_t tod;
|
||||
struct tm tmbuf;
|
||||
|
||||
format = xstrdup(arg);
|
||||
|
||||
|
@ -181,7 +196,7 @@ static void do_time(const char *arg)
|
|||
format[i] = '%';
|
||||
|
||||
time(&tod);
|
||||
strftime(timebuf, sizeof(timebuf), format, localtime(&tod));
|
||||
strftime(timebuf, sizeof(timebuf), format, localtime_r(&tod, &tmbuf));
|
||||
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%s", timebuf);
|
||||
|
||||
|
@ -191,7 +206,7 @@ static void do_time(const char *arg)
|
|||
static void getvar(const char *var)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -235,6 +250,7 @@ static void do_var(const char *arg)
|
|||
static void do_etime(const char *arg)
|
||||
{
|
||||
time_t tod;
|
||||
NUT_UNUSED_VARIABLE(arg);
|
||||
|
||||
time(&tod);
|
||||
snprintfcat(logbuffer, sizeof(logbuffer), "%ld", (unsigned long) tod);
|
||||
|
@ -269,7 +285,7 @@ static void add_call(void (*fptr)(const char *arg), const char *arg)
|
|||
tmp->next = NULL;
|
||||
|
||||
if (last)
|
||||
last->next = tmp;
|
||||
last->next = tmp;
|
||||
else
|
||||
fhead = tmp;
|
||||
}
|
||||
|
@ -277,8 +293,9 @@ static void add_call(void (*fptr)(const char *arg), const char *arg)
|
|||
/* turn the format string into a list of function calls with args */
|
||||
static void compile_format(void)
|
||||
{
|
||||
unsigned int i;
|
||||
int j, found, ofs;
|
||||
size_t i;
|
||||
int j, found;
|
||||
size_t ofs;
|
||||
char *cmd, *arg, *ptr;
|
||||
|
||||
for (i = 0; i < strlen(logformat); i++) {
|
||||
|
@ -330,7 +347,7 @@ static void compile_format(void)
|
|||
/* see if we know how to handle this command */
|
||||
|
||||
for (j = 0; logcmds[j].name != NULL; j++) {
|
||||
if (strncasecmp(cmd, logcmds[j].name,
|
||||
if (strncasecmp(cmd, logcmds[j].name,
|
||||
strlen(logcmds[j].name)) == 0) {
|
||||
|
||||
add_call(logcmds[j].func, arg);
|
||||
|
@ -378,7 +395,7 @@ static void run_flist(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int interval = 30, i;
|
||||
int interval = 30, i, foreground = -1;
|
||||
const char *prog = xbasename(argv[0]);
|
||||
time_t now, nextpoll = 0;
|
||||
const char *user = NULL;
|
||||
|
@ -390,11 +407,13 @@ int main(int argc, char **argv)
|
|||
|
||||
printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);
|
||||
|
||||
while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:")) != -1) {
|
||||
while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) {
|
||||
switch(i) {
|
||||
case 'h':
|
||||
help(prog);
|
||||
#ifndef HAVE___ATTRIBUTE__NORETURN
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 's':
|
||||
monhost = optarg;
|
||||
|
@ -422,6 +441,14 @@ int main(int argc, char **argv)
|
|||
case 'p':
|
||||
pidfilebase = optarg;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
foreground = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
foreground = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,7 +489,7 @@ int main(int argc, char **argv)
|
|||
if (!logformat)
|
||||
fatalx(EXIT_FAILURE, "No format defined - but this should be impossible");
|
||||
|
||||
printf("logging status of %s to %s (%is intervals)\n",
|
||||
printf("logging status of %s to %s (%is intervals)\n",
|
||||
monhost, logfn, interval);
|
||||
|
||||
if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) {
|
||||
|
@ -470,7 +497,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0)
|
||||
fprintf(stderr, "Warning: initial connect failed: %s\n",
|
||||
fprintf(stderr, "Warning: initial connect failed: %s\n",
|
||||
upscli_strerror(&ups));
|
||||
|
||||
if (strcmp(logfn, "-") == 0)
|
||||
|
@ -484,10 +511,19 @@ int main(int argc, char **argv)
|
|||
/* now drop root if we have it */
|
||||
new_uid = get_user_pwent(user);
|
||||
|
||||
open_syslog(prog);
|
||||
open_syslog(prog);
|
||||
|
||||
if (logfile != stdout)
|
||||
if (foreground < 0) {
|
||||
if (logfile == stdout) {
|
||||
foreground = 1;
|
||||
} else {
|
||||
foreground = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foreground) {
|
||||
background();
|
||||
}
|
||||
|
||||
setup_signals();
|
||||
|
||||
|
@ -502,7 +538,7 @@ int main(int argc, char **argv)
|
|||
|
||||
if (nextpoll > now) {
|
||||
/* there is still time left, so sleep it off */
|
||||
sleep(difftime(nextpoll, now));
|
||||
sleep((unsigned int)(difftime(nextpoll, now)));
|
||||
nextpoll += interval;
|
||||
} else {
|
||||
/* we spent more time in polling than the interval allows */
|
||||
|
@ -510,7 +546,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (reopen_flag) {
|
||||
upslogx(LOG_INFO, "Signal %d: reopening log file",
|
||||
upslogx(LOG_INFO, "Signal %d: reopening log file",
|
||||
reopen_flag);
|
||||
reopen_log();
|
||||
reopen_flag = 0;
|
||||
|
@ -535,7 +571,7 @@ int main(int argc, char **argv)
|
|||
fclose(logfile);
|
||||
|
||||
upscli_disconnect(&ups);
|
||||
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/* upslog.h - table of functions for handling various logging functions */
|
||||
|
||||
#ifndef NUT_UPSLOG_H_SEEN
|
||||
#define NUT_UPSLOG_H_SEEN 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
|
@ -20,7 +23,10 @@ static void do_time(const char *arg);
|
|||
static void do_var(const char *arg);
|
||||
static void do_etime(const char *arg);
|
||||
|
||||
struct {
|
||||
/* This is only used in upslog.c, but refers to routines declared here...
|
||||
* To move or not to move?..
|
||||
*/
|
||||
static struct {
|
||||
const char *name;
|
||||
void (*func)(const char *arg);
|
||||
} logcmds[] =
|
||||
|
@ -31,7 +37,7 @@ struct {
|
|||
{ "TIME", do_time },
|
||||
{ "VAR", do_var },
|
||||
{ "ETIME", do_etime },
|
||||
{ NULL, (void(*)())(NULL) }
|
||||
{ NULL, (void(*)(const char*))(NULL) }
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -40,3 +46,4 @@ struct {
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_UPSLOG_H_SEEN */
|
||||
|
|
583
clients/upsmon.c
583
clients/upsmon.c
File diff suppressed because it is too large
Load diff
|
@ -17,18 +17,23 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUT_UPSMON_H_SEEN
|
||||
#define NUT_UPSMON_H_SEEN 1
|
||||
|
||||
/* flags for ups->status */
|
||||
|
||||
#define ST_ONLINE (1 << 0) /* UPS is on line (OL) */
|
||||
#define ST_ONBATT (1 << 1) /* UPS is on battery (OB) */
|
||||
#define ST_LOWBATT (1 << 2) /* UPS has a low battery (LB) */
|
||||
#define ST_FSD (1 << 3) /* master has set forced shutdown flag */
|
||||
#define ST_MASTER (1 << 4) /* we are the master on this UPS */
|
||||
#define ST_LOGIN (1 << 5) /* we are logged into this UPS */
|
||||
#define ST_CONNECTED (1 << 6) /* upscli_connect returned OK */
|
||||
#define ST_ONLINE (1 << 0) /* UPS is on line (OL) */
|
||||
#define ST_ONBATT (1 << 1) /* UPS is on battery (OB) */
|
||||
#define ST_LOWBATT (1 << 2) /* UPS has a low battery (LB) */
|
||||
#define ST_FSD (1 << 3) /* primary has set forced shutdown flag */
|
||||
#define ST_PRIMARY (1 << 4) /* we are the primary (manager) of this UPS */
|
||||
#define ST_MASTER ST_PRIMARY /* legacy alias */
|
||||
#define ST_LOGIN (1 << 5) /* we are logged into this UPS */
|
||||
#define ST_CONNECTED (1 << 6) /* upscli_connect returned OK */
|
||||
#define ST_CAL (1 << 7) /* UPS calibration in progress (CAL) */
|
||||
|
||||
/* required contents of flag file */
|
||||
#define SDMAGIC "upsmon-shutdown-file"
|
||||
#define SDMAGIC "upsmon-shutdown-file"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
|
@ -44,9 +49,9 @@ typedef struct {
|
|||
char *sys; /* raw system name from .conf */
|
||||
char *upsname; /* just upsname */
|
||||
char *hostname; /* just hostname */
|
||||
int port; /* just the port */
|
||||
uint16_t port; /* just the port */
|
||||
|
||||
int pv; /* power value from conf */
|
||||
unsigned int pv; /* power value from conf */
|
||||
char *un; /* username (optional for now) */
|
||||
char *pw; /* password from conf */
|
||||
int status; /* status (see flags above) */
|
||||
|
@ -65,16 +70,17 @@ typedef struct {
|
|||
|
||||
/* 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 */
|
||||
#define NOTIFY_ONLINE 0 /* UPS went on-line */
|
||||
#define NOTIFY_ONBATT 1 /* UPS went on battery */
|
||||
#define NOTIFY_LOWBATT 2 /* UPS went to low battery */
|
||||
#define NOTIFY_FSD 3 /* Primary upsmon set FSD flag */
|
||||
#define NOTIFY_COMMOK 4 /* Communication established */
|
||||
#define NOTIFY_COMMBAD 5 /* Communication lost */
|
||||
#define NOTIFY_SHUTDOWN 6 /* System shutdown in progress */
|
||||
#define NOTIFY_REPLBATT 7 /* UPS battery needs to be replaced */
|
||||
#define NOTIFY_NOCOMM 8 /* UPS hasn't been contacted in a while */
|
||||
#define NOTIFY_NOPARENT 9 /* privileged parent process died */
|
||||
#define NOTIFY_CAL 10 /* UPS is performing calibration */
|
||||
|
||||
/* notify flag values */
|
||||
|
||||
|
@ -86,7 +92,10 @@ typedef struct {
|
|||
/* flags are set to NOTIFY_SYSLOG | NOTIFY_WALL at program init */
|
||||
/* the user can override with NOTIFYFLAGS in the upsmon.conf */
|
||||
|
||||
struct {
|
||||
/* This is only used in upsmon.c, but might it also have external consumers?..
|
||||
* To move or not to move?..
|
||||
*/
|
||||
static struct {
|
||||
int type;
|
||||
const char *name;
|
||||
char *msg; /* NULL until overridden */
|
||||
|
@ -104,6 +113,7 @@ struct {
|
|||
{ NOTIFY_REPLBATT, "REPLBATT", NULL, "UPS %s battery needs to be replaced", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||
{ NOTIFY_NOCOMM, "NOCOMM", NULL, "UPS %s is unavailable", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||
{ NOTIFY_NOPARENT, "NOPARENT", NULL, "upsmon parent process died - shutdown impossible", NOTIFY_SYSLOG | NOTIFY_WALL },
|
||||
{ NOTIFY_CAL, "CAL", NULL, "UPS %s: calibration in progress", NOTIFY_SYSLOG },
|
||||
{ 0, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
@ -122,3 +132,5 @@ struct {
|
|||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_UPSMON_H_SEEN */
|
||||
|
|
225
clients/upsrw.c
225
clients/upsrw.c
|
@ -1,6 +1,8 @@
|
|||
/* upsrw - simple client for read/write variable access (formerly upsct2)
|
||||
|
||||
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||
Copyright (C)
|
||||
1999 Russell Kroll <rkroll@exploits.org>
|
||||
2019 EATON (author: Arnaud Quette <ArnaudQuette@eaton.com>)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -25,10 +27,14 @@
|
|||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "nut_stdint.h"
|
||||
#include "upsclient.h"
|
||||
#include "extstate.h"
|
||||
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
static char *upsname = NULL, *hostname = NULL;
|
||||
static UPSCONN_t *ups = NULL;
|
||||
static int tracking_enabled = 0;
|
||||
static unsigned int timeout = DEFAULT_TRACKING_TIMEOUT;
|
||||
|
||||
struct list_t {
|
||||
char *name;
|
||||
|
@ -39,18 +45,22 @@ static void usage(const char *prog)
|
|||
{
|
||||
printf("Network UPS Tools %s %s\n\n", prog, UPS_VERSION);
|
||||
printf("usage: %s [-h]\n", prog);
|
||||
printf(" %s [-s <variable>] [-u <username>] [-p <password>] <ups>\n\n", prog);
|
||||
printf(" %s [-s <variable>] [-u <username>] [-p <password>] [-w] [-t <timeout>] <ups>\n\n", prog);
|
||||
printf("Demo program to set variables within UPS hardware.\n");
|
||||
printf("\n");
|
||||
printf(" -h display this help text\n");
|
||||
printf(" -s <variable> specify variable to be changed\n");
|
||||
printf(" use -s VAR=VALUE to avoid prompting for value\n");
|
||||
printf(" -l show all possible read/write variables.\n");
|
||||
printf(" -u <username> set username for command authentication\n");
|
||||
printf(" -p <password> set password for command authentication\n");
|
||||
printf(" -w wait for the completion of setting by the driver\n");
|
||||
printf(" and return its actual result from the device\n");
|
||||
printf(" -t <timeout> set a timeout when using -w (in seconds, default: %u)\n", DEFAULT_TRACKING_TIMEOUT);
|
||||
printf("\n");
|
||||
printf(" <ups> UPS identifier - <upsname>[@<hostname>[:<port>]]\n");
|
||||
printf("\n");
|
||||
printf("Call without -s to show all possible read/write variables.\n");
|
||||
printf("Call without -s to show all possible read/write variables (same as -l).\n");
|
||||
}
|
||||
|
||||
static void clean_exit(void)
|
||||
|
@ -64,9 +74,21 @@ static void clean_exit(void)
|
|||
free(ups);
|
||||
}
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC)
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#if (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC)
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
static void do_set(const char *varname, const char *newval)
|
||||
{
|
||||
int cmd_complete = 0;
|
||||
char buf[SMALLBUF], enc[SMALLBUF];
|
||||
char tracking_id[UUID4_LEN];
|
||||
time_t start, now;
|
||||
|
||||
snprintf(buf, sizeof(buf), "SET VAR %s %s \"%s\"\n", upsname, varname, pconf_encode(newval, enc, sizeof(enc)));
|
||||
|
||||
|
@ -78,17 +100,92 @@ static void do_set(const char *varname, const char *newval)
|
|||
fatalx(EXIT_FAILURE, "Set variable failed: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
/* FUTURE: status cookies will tie in here */
|
||||
/* verify answer */
|
||||
if (strncmp(buf, "OK", 2) != 0) {
|
||||
fatalx(EXIT_FAILURE, "Unexpected response from upsd: %s", buf);
|
||||
}
|
||||
|
||||
/* check for status tracking id */
|
||||
if (
|
||||
!tracking_enabled ||
|
||||
/* sanity check on the size: "OK TRACKING " + UUID4_LEN */
|
||||
strlen(buf) != (UUID4_LEN - 1 + strlen("OK TRACKING "))
|
||||
) {
|
||||
/* reply as usual */
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||
#endif
|
||||
/* From the check above, we know that we have exactly UUID4_LEN chars
|
||||
* (aka sizeof(tracking_id)) in the buf after "OK TRACKING " prefix,
|
||||
* plus the null-byte.
|
||||
*/
|
||||
assert (UUID4_LEN == 1 + snprintf(tracking_id, sizeof(tracking_id), "%s", buf + strlen("OK TRACKING ")));
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_TRUNCATION
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
time(&start);
|
||||
|
||||
/* send status tracking request, looping if status is PENDING */
|
||||
while (!cmd_complete) {
|
||||
|
||||
/* check for timeout */
|
||||
time(&now);
|
||||
if (difftime(now, start) >= timeout)
|
||||
fatalx(EXIT_FAILURE, "Can't receive status tracking information: timeout");
|
||||
|
||||
snprintf(buf, sizeof(buf), "GET TRACKING %s\n", tracking_id);
|
||||
|
||||
if (upscli_sendline(ups, buf, strlen(buf)) < 0)
|
||||
fatalx(EXIT_FAILURE, "Can't send status tracking request: %s", upscli_strerror(ups));
|
||||
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||
/* Note for gating macros above: unsuffixed HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP
|
||||
* means support of contexts both inside and outside function body, so the push
|
||||
* above and pop below (outside this finction) are not used.
|
||||
*/
|
||||
# pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS
|
||||
/* Note that the individual warning pragmas for use inside function bodies
|
||||
* are named without a _INSIDEFUNC suffix, for simplicity and legacy reasons
|
||||
*/
|
||||
# pragma GCC diagnostic ignored "-Wtype-limits"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
||||
#endif
|
||||
/* and get status tracking reply */
|
||||
assert(timeout < LONG_MAX);
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
if (upscli_readline_timeout(ups, buf, sizeof(buf), (long)timeout) < 0)
|
||||
fatalx(EXIT_FAILURE, "Can't receive status tracking information: %s", upscli_strerror(ups));
|
||||
|
||||
if (strncmp(buf, "PENDING", 7))
|
||||
cmd_complete = 1;
|
||||
else
|
||||
/* wait a second before retrying */
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s\n", buf);
|
||||
}
|
||||
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_BESIDEFUNC) && (!defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP_INSIDEFUNC) && ( (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TYPE_LIMITS_BESIDEFUNC) || (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_TAUTOLOGICAL_CONSTANT_OUT_OF_RANGE_COMPARE_BESIDEFUNC) )
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static void do_setvar(const char *varname, char *uin, const char *pass)
|
||||
{
|
||||
char newval[SMALLBUF], temp[SMALLBUF], user[SMALLBUF], *ptr;
|
||||
char newval[SMALLBUF], temp[SMALLBUF * 2], user[SMALLBUF], *ptr;
|
||||
struct passwd *pw;
|
||||
|
||||
if (uin) {
|
||||
|
@ -177,13 +274,32 @@ static void do_setvar(const char *varname, char *uin, const char *pass)
|
|||
fatalx(EXIT_FAILURE, "Error: old variable names are not supported");
|
||||
}
|
||||
|
||||
/* enable status tracking ID */
|
||||
if (tracking_enabled) {
|
||||
|
||||
snprintf(temp, sizeof(temp), "SET TRACKING ON\n");
|
||||
|
||||
if (upscli_sendline(ups, temp, strlen(temp)) < 0) {
|
||||
fatalx(EXIT_FAILURE, "Can't enable set variable status tracking: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
if (upscli_readline(ups, temp, sizeof(temp)) < 0) {
|
||||
fatalx(EXIT_FAILURE, "Enabling set variable status tracking failed: %s", upscli_strerror(ups));
|
||||
}
|
||||
|
||||
/* Verify the result */
|
||||
if (strncmp(temp, "OK", 2) != 0) {
|
||||
fatalx(EXIT_FAILURE, "Enabling set variable status tracking failed. upsd answered: %s", temp);
|
||||
}
|
||||
}
|
||||
|
||||
do_set(varname, newval);
|
||||
}
|
||||
|
||||
static const char *get_data(const char *type, const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer;
|
||||
const char *query[4];
|
||||
|
||||
|
@ -203,7 +319,7 @@ static const char *get_data(const char *type, const char *varname)
|
|||
return answer[3];
|
||||
}
|
||||
|
||||
static void do_string(const char *varname, const int len)
|
||||
static void do_string(const char *varname, const long len)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
|
@ -214,14 +330,34 @@ static void do_string(const char *varname, const int len)
|
|||
}
|
||||
|
||||
printf("Type: STRING\n");
|
||||
printf("Maximum length: %d\n", len);
|
||||
printf("Maximum length: %ld\n", len);
|
||||
printf("Value: %s\n", val);
|
||||
}
|
||||
|
||||
static void do_enum(const char *varname)
|
||||
static void do_number(const char *varname)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = get_data("VAR", varname);
|
||||
|
||||
if (!val) {
|
||||
fatalx(EXIT_FAILURE, "do_number: can't get current value of %s", varname);
|
||||
}
|
||||
|
||||
printf("Type: NUMBER\n");
|
||||
printf("Value: %s\n", val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display ENUM information
|
||||
* @param varname the name of the NUT variable
|
||||
* @param vartype the type of the NUT variable (ST_FLAG_STRING, ST_FLAG_NUMBER
|
||||
* @param len the length of the NUT variable, if type == ST_FLAG_STRING
|
||||
*/
|
||||
static void do_enum(const char *varname, const int vartype, const long len)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer, buf[SMALLBUF];
|
||||
const char *query[4], *val;
|
||||
|
||||
|
@ -247,14 +383,21 @@ static void do_enum(const char *varname)
|
|||
|
||||
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||
|
||||
printf("Type: ENUM\n");
|
||||
/* Fallback for older upsd versions */
|
||||
if (vartype != ST_FLAG_NONE)
|
||||
printf("Type: ENUM %s\n", (vartype == ST_FLAG_STRING)?"STRING":"NUMBER");
|
||||
else
|
||||
printf("Type: ENUM\n");
|
||||
|
||||
if (vartype == ST_FLAG_STRING)
|
||||
printf("Maximum length: %ld\n", len);
|
||||
|
||||
while (ret == 1) {
|
||||
|
||||
/* ENUM <upsname> <varname> <value> */
|
||||
|
||||
if (numa < 4) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||
}
|
||||
|
||||
printf("Option: \"%s\"", answer[3]);
|
||||
|
@ -272,7 +415,7 @@ static void do_enum(const char *varname)
|
|||
static void do_range(const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer;
|
||||
const char *query[4], *val;
|
||||
int ival, min, max;
|
||||
|
@ -299,14 +442,15 @@ static void do_range(const char *varname)
|
|||
|
||||
ret = upscli_list_next(ups, numq, query, &numa, &answer);
|
||||
|
||||
printf("Type: RANGE\n");
|
||||
/* Ranges implies a type "NUMBER" */
|
||||
printf("Type: RANGE NUMBER\n");
|
||||
|
||||
while (ret == 1) {
|
||||
|
||||
/* RANGE <upsname> <varname> <min> <max> */
|
||||
|
||||
if (numa < 5) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||
}
|
||||
|
||||
min = atoi(answer[3]);
|
||||
|
@ -327,7 +471,8 @@ static void do_range(const char *varname)
|
|||
static void do_type(const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i, numq, numa;
|
||||
int is_enum = 0; /* 1 if ENUM; FIXME: add a boolean type in common.h */
|
||||
size_t i, numq, numa;
|
||||
char **answer;
|
||||
const char *query[4];
|
||||
|
||||
|
@ -339,16 +484,18 @@ static void do_type(const char *varname)
|
|||
ret = upscli_get(ups, numq, query, &numa, &answer);
|
||||
|
||||
if ((ret < 0) || (numa < numq)) {
|
||||
printf("Unknown type\n");
|
||||
printf("Unknown type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TYPE <upsname> <varname> <type>... */
|
||||
for (i = 3; i < numa; i++) {
|
||||
|
||||
/* ENUM can be NUMBER or STRING
|
||||
* just flag it for latter processing */
|
||||
if (!strcasecmp(answer[i], "ENUM")) {
|
||||
do_enum(varname);
|
||||
return;
|
||||
is_enum = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp(answer[i], "RANGE")) {
|
||||
|
@ -359,15 +506,21 @@ static void do_type(const char *varname)
|
|||
if (!strncasecmp(answer[i], "STRING:", 7)) {
|
||||
|
||||
char *len = answer[i] + 7;
|
||||
int length = strtol(len, NULL, 10);
|
||||
long length = strtol(len, NULL, 10);
|
||||
|
||||
do_string(varname, length);
|
||||
if (is_enum == 1)
|
||||
do_enum(varname, ST_FLAG_STRING, length);
|
||||
else
|
||||
do_string(varname, length);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (!strcasecmp(answer[i], "NUMBER")) {
|
||||
printf("Type: NUMBER\n");
|
||||
if (is_enum == 1)
|
||||
do_enum(varname, ST_FLAG_NUMBER, 0);
|
||||
else
|
||||
do_number(varname);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -378,6 +531,10 @@ static void do_type(const char *varname)
|
|||
|
||||
printf("Type: %s (unrecognized)\n", answer[i]);
|
||||
}
|
||||
/* Fallback for older upsd versions, where STRING|NUMBER is not
|
||||
* appended to ENUM */
|
||||
if (is_enum == 1)
|
||||
do_enum(varname, ST_FLAG_NONE, 0);
|
||||
}
|
||||
|
||||
static void print_rw(const char *varname)
|
||||
|
@ -402,7 +559,7 @@ static void print_rw(const char *varname)
|
|||
static void print_rwlist(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[2];
|
||||
char **answer;
|
||||
struct list_t *lhead, *llast, *ltmp, *lnext;
|
||||
|
@ -436,7 +593,7 @@ static void print_rwlist(void)
|
|||
|
||||
/* RW <upsname> <varname> <value> */
|
||||
if (numa < 4) {
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %d args, need at least 4)", numa);
|
||||
fatalx(EXIT_FAILURE, "Error: insufficient data (got %zu args, need at least 4)", numa);
|
||||
}
|
||||
|
||||
/* sock this entry away for later */
|
||||
|
@ -473,22 +630,36 @@ static void print_rwlist(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, port;
|
||||
int i;
|
||||
uint16_t port;
|
||||
const char *prog = xbasename(argv[0]);
|
||||
char *password = NULL, *username = NULL, *setvar = NULL;
|
||||
|
||||
while ((i = getopt(argc, argv, "+hs:p:u:V")) != -1) {
|
||||
while ((i = getopt(argc, argv, "+hls:p:t:u:wV")) != -1) {
|
||||
switch (i)
|
||||
{
|
||||
case 's':
|
||||
setvar = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
if (setvar) {
|
||||
upslogx(LOG_WARNING, "Listing mode requested, overriding setvar specified earlier!");
|
||||
setvar = NULL;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
password = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if (!str_to_uint(optarg, &timeout, 10))
|
||||
fatal_with_errno(EXIT_FAILURE, "Could not convert the provided value for timeout ('-t' option) to unsigned int");
|
||||
break;
|
||||
case 'u':
|
||||
username = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
tracking_enabled = 1;
|
||||
break;
|
||||
case 'V':
|
||||
printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
@ -11,8 +11,19 @@
|
|||
# from your AT lines.
|
||||
|
||||
case $1 in
|
||||
onbattwarn)
|
||||
# Send a notification mail
|
||||
echo "The UPS has been on battery for awhile" \
|
||||
| mail -s"UPS monitor" bofh@pager.example.com
|
||||
# Create a flag-file on the filesystem, for your own processing
|
||||
/usr/bin/touch /some/path/ups-on-battery
|
||||
;;
|
||||
ups-back-on-power)
|
||||
# Delete the flag-file on the filesystem
|
||||
/bin/rm -f /some/path/ups-on-battery
|
||||
;;
|
||||
upsgone)
|
||||
logger -t upssched-cmd "The UPS has been gone for awhile"
|
||||
logger -t upssched-cmd "The communication with UPS has been gone for awhile"
|
||||
;;
|
||||
*)
|
||||
logger -t upssched-cmd "Unrecognized command: $1"
|
||||
|
|
|
@ -46,9 +46,12 @@
|
|||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "upssched.h"
|
||||
#include "timehead.h"
|
||||
#include "nut_stdint.h"
|
||||
|
||||
typedef struct ttype_s {
|
||||
char *name;
|
||||
|
@ -56,14 +59,13 @@ typedef struct ttype_s {
|
|||
struct ttype_s *next;
|
||||
} ttype_t;
|
||||
|
||||
ttype_t *thead = NULL;
|
||||
static conn_t *connhead = NULL;
|
||||
char *cmdscript = NULL, *pipefn = NULL, *lockfn = NULL;
|
||||
int verbose = 0; /* use for debugging */
|
||||
static ttype_t *thead = NULL;
|
||||
static conn_t *connhead = NULL;
|
||||
static char *cmdscript = NULL, *pipefn = NULL, *lockfn = NULL;
|
||||
static int verbose = 0; /* use for debugging */
|
||||
|
||||
|
||||
/* ups name and notify type (string) as received from upsmon */
|
||||
const char *upsname, *notify_type;
|
||||
/* ups name and notify type (string) as received from upsmon */
|
||||
static const char *upsname, *notify_type;
|
||||
|
||||
#define PARENT_STARTED -2
|
||||
#define PARENT_UNNECESSARY -3
|
||||
|
@ -179,7 +181,7 @@ static void checktimers(void)
|
|||
static void start_timer(const char *name, const char *ofsstr)
|
||||
{
|
||||
time_t now;
|
||||
int ofs;
|
||||
long ofs;
|
||||
ttype_t *tmp, *last;
|
||||
|
||||
/* get the time */
|
||||
|
@ -194,7 +196,7 @@ static void start_timer(const char *name, const char *ofsstr)
|
|||
}
|
||||
|
||||
if (verbose)
|
||||
upslogx(LOG_INFO, "New timer: %s (%d seconds)", name, ofs);
|
||||
upslogx(LOG_INFO, "New timer: %s (%ld seconds)", name, ofs);
|
||||
|
||||
/* now add to the queue */
|
||||
tmp = last = thead;
|
||||
|
@ -240,7 +242,7 @@ static void cancel_timer(const char *name, const char *cname)
|
|||
static void us_serialize(int op)
|
||||
{
|
||||
static int pipefd[2];
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
char ch;
|
||||
|
||||
switch(op) {
|
||||
|
@ -270,6 +272,7 @@ static int open_sock(void)
|
|||
int ret, fd;
|
||||
struct sockaddr_un ssaddr;
|
||||
|
||||
check_unix_socket_filename(pipefn);
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fd < 0)
|
||||
|
@ -297,6 +300,9 @@ static int open_sock(void)
|
|||
if (ret < 0)
|
||||
fatal_with_errno(EXIT_FAILURE, "listen(%d, %d) failed", fd, US_LISTEN_BACKLOG);
|
||||
|
||||
/* don't leak socket to CMDSCRIPT */
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -329,17 +335,40 @@ static void conn_del(conn_t *target)
|
|||
|
||||
static int send_to_one(conn_t *conn, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
ssize_t ret;
|
||||
size_t buflen;
|
||||
va_list ap;
|
||||
char buf[US_SOCK_BUF_LEN];
|
||||
|
||||
va_start(ap, fmt);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
ret = write(conn->fd, buf, strlen(buf));
|
||||
buflen = strlen(buf);
|
||||
if (buflen >= SSIZE_MAX) {
|
||||
/* Can't compare buflen to ret */
|
||||
upsdebugx(2, "send_to_one(): buffered message too large");
|
||||
|
||||
if ((ret < 1) || (ret != (int) strlen(buf))) {
|
||||
close(conn->fd);
|
||||
conn_del(conn);
|
||||
|
||||
return 0; /* failed */
|
||||
}
|
||||
ret = write(conn->fd, buf, buflen);
|
||||
|
||||
if ((ret < 1) || (ret != (ssize_t) buflen)) {
|
||||
upsdebugx(2, "write to fd %d failed", conn->fd);
|
||||
|
||||
close(conn->fd);
|
||||
|
@ -356,7 +385,7 @@ static void conn_add(int sockfd)
|
|||
int acc, ret;
|
||||
conn_t *tmp, *last;
|
||||
struct sockaddr_un saddr;
|
||||
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
|
||||
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED)
|
||||
int salen;
|
||||
#else
|
||||
socklen_t salen;
|
||||
|
@ -370,6 +399,9 @@ static void conn_add(int sockfd)
|
|||
return;
|
||||
}
|
||||
|
||||
/* don't leak connection to CMDSCRIPT */
|
||||
fcntl(acc, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* enable nonblocking I/O */
|
||||
|
||||
ret = fcntl(acc, F_GETFL, 0);
|
||||
|
@ -440,19 +472,20 @@ static int sock_arg(conn_t *conn)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void log_unknown(int numarg, char **arg)
|
||||
static void log_unknown(size_t numarg, char **arg)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
upslogx(LOG_INFO, "Unknown command on socket: ");
|
||||
|
||||
for (i = 0; i < numarg; i++)
|
||||
upslogx(LOG_INFO, "arg %d: %s", i, arg[i]);
|
||||
upslogx(LOG_INFO, "arg %zu: %s", i, arg[i]);
|
||||
}
|
||||
|
||||
static int sock_read(conn_t *conn)
|
||||
{
|
||||
int i, ret;
|
||||
int i;
|
||||
ssize_t ret;
|
||||
char ch;
|
||||
|
||||
for (i = 0; i < US_MAX_READ; i++) {
|
||||
|
@ -465,13 +498,19 @@ static int sock_read(conn_t *conn)
|
|||
if ((ret == -1) && (errno == EAGAIN))
|
||||
return 0;
|
||||
|
||||
/* O_NDELAY with zero bytes means nothing to read but
|
||||
* since read() follows a succesful select() with
|
||||
* ready file descriptor, ret shouldn't be 0. */
|
||||
if (ret == 0)
|
||||
continue;
|
||||
|
||||
/* some other problem */
|
||||
return -1; /* error */
|
||||
}
|
||||
|
||||
ret = pconf_char(&conn->ctx, ch);
|
||||
|
||||
if (ret == 0) /* nothing to parse yet */
|
||||
if (ret == 0) /* nothing to parse yet */
|
||||
continue;
|
||||
|
||||
if (ret == -1) {
|
||||
|
@ -594,6 +633,8 @@ static int try_connect(void)
|
|||
int pipefd, ret;
|
||||
struct sockaddr_un saddr;
|
||||
|
||||
check_unix_socket_filename(pipefn);
|
||||
|
||||
memset(&saddr, '\0', sizeof(saddr));
|
||||
saddr.sun_family = AF_UNIX;
|
||||
snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s", pipefn);
|
||||
|
@ -659,28 +700,15 @@ static int check_parent(const char *cmd, const char *arg2)
|
|||
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];
|
||||
int i, pipefd;
|
||||
ssize_t ret;
|
||||
size_t enclen, buflen;
|
||||
char buf[SMALLBUF], enc[SMALLBUF + 8];
|
||||
int ret_s;
|
||||
struct timeval tv;
|
||||
fd_set fdread;
|
||||
|
||||
/* insanity */
|
||||
if (!arg1)
|
||||
|
@ -696,6 +724,14 @@ static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
|||
|
||||
snprintf(enc, sizeof(enc), "%s\n", buf);
|
||||
|
||||
/* Sanity checks, for static analyzers to sleep well */
|
||||
enclen = strlen(enc);
|
||||
buflen = strlen(buf);
|
||||
if (enclen >= SSIZE_MAX || buflen >= SSIZE_MAX) {
|
||||
/* Can't compare enclen to ret below */
|
||||
fatalx(EXIT_FAILURE, "Unable to connect to daemon: buffered message too large");
|
||||
}
|
||||
|
||||
/* see if the parent needs to be started (and maybe start it) */
|
||||
|
||||
for (i = 0; i < MAX_TRIES; i++) {
|
||||
|
@ -703,7 +739,6 @@ static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
|||
pipefd = check_parent(cmd, arg2);
|
||||
|
||||
if (pipefd == PARENT_STARTED) {
|
||||
|
||||
/* loop back and try to connect now */
|
||||
usleep(250000);
|
||||
continue;
|
||||
|
@ -715,23 +750,41 @@ static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
|||
|
||||
/* we're connected now */
|
||||
|
||||
ret = write(pipefd, enc, strlen(enc));
|
||||
ret = write(pipefd, enc, enclen);
|
||||
|
||||
/* if we can't send the whole thing, loop back and try again */
|
||||
if ((ret < 1) || (ret != (int) strlen(enc))) {
|
||||
if ((ret < 1) || (ret != (ssize_t)enclen)) {
|
||||
upslogx(LOG_ERR, "write failed, trying again");
|
||||
close(pipefd);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ugh - probably should use select here... */
|
||||
setup_sigalrm();
|
||||
/* select on child's pipe fd */
|
||||
do {
|
||||
/* set timeout every time before call select() */
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
alarm(2);
|
||||
ret = read(pipefd, buf, sizeof(buf));
|
||||
alarm(0);
|
||||
FD_ZERO(&fdread);
|
||||
FD_SET(pipefd, &fdread);
|
||||
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
ret_s = select(pipefd + 1, &fdread, NULL, NULL, &tv);
|
||||
switch(ret_s) {
|
||||
/* select error */
|
||||
case -1:
|
||||
upslogx(LOG_DEBUG, "parent select error: %s", strerror(errno));
|
||||
break;
|
||||
|
||||
/* nothing to read */
|
||||
case 0:
|
||||
break;
|
||||
|
||||
/* available data to read */
|
||||
default:
|
||||
ret = read(pipefd, buf, sizeof(buf));
|
||||
break;
|
||||
}
|
||||
} while (ret_s <= 0);
|
||||
|
||||
close(pipefd);
|
||||
|
||||
|
@ -747,7 +800,7 @@ static void sendcmd(const char *cmd, const char *arg1, const char *arg2)
|
|||
upslogx(LOG_ERR, "read confirmation got [%s]", buf);
|
||||
|
||||
/* try again ... */
|
||||
}
|
||||
} /* loop until MAX_TRIES if no success above */
|
||||
|
||||
fatalx(EXIT_FAILURE, "Unable to connect to daemon and unable to start daemon");
|
||||
}
|
||||
|
@ -794,7 +847,7 @@ static void parse_at(const char *ntype, const char *un, const char *cmd,
|
|||
}
|
||||
|
||||
if (!strcmp(cmd, "EXECUTE")) {
|
||||
if (ca1 == '\0') {
|
||||
if (ca1[0] == '\0') {
|
||||
upslogx(LOG_ERR, "Empty EXECUTE command argument");
|
||||
return;
|
||||
}
|
||||
|
@ -809,7 +862,7 @@ static void parse_at(const char *ntype, const char *un, const char *cmd,
|
|||
upslogx(LOG_ERR, "Invalid command: %s", cmd);
|
||||
}
|
||||
|
||||
static int conf_arg(int numargs, char **arg)
|
||||
static int conf_arg(size_t numargs, char **arg)
|
||||
{
|
||||
if (numargs < 2)
|
||||
return 0;
|
||||
|
@ -900,9 +953,15 @@ static void checkconf(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *prog = xbasename(argv[0]);
|
||||
const char *prog = NULL;
|
||||
/* More a use for argc to avoid warnings than a real need: */
|
||||
if (argc > 0) {
|
||||
xbasename(argv[0]);
|
||||
} else {
|
||||
xbasename("upssched");
|
||||
}
|
||||
|
||||
verbose = 1; /* TODO: remove when done testing */
|
||||
verbose = 1; /* TODO: remove when done testing, or add -D */
|
||||
|
||||
/* normally we don't have stderr, so get this going to syslog early */
|
||||
open_syslog(prog);
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
/* upssched.h - supporting structures */
|
||||
|
||||
#ifndef NUT_UPSSCHED_H_SEEN
|
||||
#define NUT_UPSSCHED_H_SEEN 1
|
||||
|
||||
#include <parseconf.h>
|
||||
|
||||
#define SERIALIZE_INIT 1
|
||||
|
@ -25,3 +28,4 @@ typedef struct conn_s {
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_UPSSCHED_H_SEEN */
|
||||
|
|
118
clients/upsset.c
118
clients/upsset.c
|
@ -24,6 +24,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "nut_stdint.h"
|
||||
#include "upsclient.h"
|
||||
#include "cgilib.h"
|
||||
#include "parseconf.h"
|
||||
|
@ -39,12 +40,12 @@ struct list_t {
|
|||
#define HARD_UPSVAR_LIMIT_NUM 64
|
||||
#define HARD_UPSVAR_LIMIT_LEN 256
|
||||
|
||||
char *monups, *username, *password, *function, *upscommand;
|
||||
static char *monups, *username, *password, *function, *upscommand;
|
||||
|
||||
/* set once the MAGIC_ENABLE_STRING is found in the upsset.conf */
|
||||
int magic_string_set = 0;
|
||||
/* set once the MAGIC_ENABLE_STRING is found in the upsset.conf */
|
||||
static int magic_string_set = 0;
|
||||
|
||||
static int port;
|
||||
static uint16_t port;
|
||||
static char *upsname, *hostname;
|
||||
static UPSCONN_t ups;
|
||||
|
||||
|
@ -54,7 +55,7 @@ typedef struct {
|
|||
void *next;
|
||||
} uvtype_t;
|
||||
|
||||
uvtype_t *firstuv = NULL;
|
||||
static uvtype_t *firstuv = NULL;
|
||||
|
||||
void parsearg(char *var, char *value)
|
||||
{
|
||||
|
@ -134,7 +135,7 @@ static void do_header(const char *title)
|
|||
printf("<HTML>\n");
|
||||
printf("<HEAD><TITLE>upsset: %s</TITLE></HEAD>\n", title);
|
||||
|
||||
printf("<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000EE\" VLINK=\"#551A8B\">\n");
|
||||
printf("<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000EE\" VLINK=\"#551A8B\">\n");
|
||||
|
||||
printf("<TABLE BGCOLOR=\"#50A0A0\" ALIGN=\"CENTER\">\n");
|
||||
printf("<TR><TD>\n");
|
||||
|
@ -144,7 +145,7 @@ static void start_table(void)
|
|||
{
|
||||
printf("<TABLE CELLPADDING=\"5\" CELLSPACING=\"0\" ALIGN=\"CENTER\" WIDTH=\"100%%\">\n");
|
||||
printf("<TR><TH COLSPAN=2 BGCOLOR=\"#60B0B0\">\n");
|
||||
printf("<FONT SIZE=\"+2\">Network UPS Tools upsset %s</FONT>\n",
|
||||
printf("<FONT SIZE=\"+2\">Network UPS Tools upsset %s</FONT>\n",
|
||||
UPS_VERSION);
|
||||
printf("</TH></TR>\n");
|
||||
}
|
||||
|
@ -158,12 +159,12 @@ static void do_hidden(const char *next)
|
|||
password);
|
||||
|
||||
if (next)
|
||||
printf("<INPUT TYPE=\"HIDDEN\" NAME=\"function\" VALUE=\"%s\">\n",
|
||||
printf("<INPUT TYPE=\"HIDDEN\" NAME=\"function\" VALUE=\"%s\">\n",
|
||||
next);
|
||||
}
|
||||
|
||||
/* generate SELECT chooser from hosts.conf entries */
|
||||
static void upslist_arg(int numargs, char **arg)
|
||||
static void upslist_arg(size_t numargs, char **arg)
|
||||
{
|
||||
if (numargs < 3)
|
||||
return;
|
||||
|
@ -222,7 +223,7 @@ static void do_pickups(const char *currfunc)
|
|||
continue;
|
||||
}
|
||||
|
||||
upslist_arg(ctx.numargs, ctx.arglist);
|
||||
upslist_arg(ctx.numargs, ctx.arglist);
|
||||
}
|
||||
|
||||
pconf_finish(&ctx);
|
||||
|
@ -253,6 +254,10 @@ static void do_pickups(const char *currfunc)
|
|||
printf("</FORM>\n");
|
||||
}
|
||||
|
||||
static void error_page(const char *next, const char *title,
|
||||
const char *fmt, ...)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void error_page(const char *next, const char *title,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
|
@ -260,7 +265,19 @@ static void error_page(const char *next, const char *title,
|
|||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
|
||||
#pragma GCC diagnostic ignored "-Wformat-security"
|
||||
#endif
|
||||
vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
va_end(ap);
|
||||
|
||||
do_header(title);
|
||||
|
@ -282,6 +299,9 @@ static void error_page(const char *next, const char *title,
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void loginscreen(void)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void loginscreen(void)
|
||||
{
|
||||
do_header("Login");
|
||||
|
@ -331,7 +351,7 @@ static void upsd_connect(void)
|
|||
static void print_cmd(const char *cmd)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer;
|
||||
const char *query[4];
|
||||
|
||||
|
@ -354,7 +374,7 @@ static void print_cmd(const char *cmd)
|
|||
static void showcmds(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[2];
|
||||
char **answer;
|
||||
struct list_t *lhead, *llast, *ltmp, *lnext;
|
||||
|
@ -391,7 +411,7 @@ static void showcmds(void)
|
|||
/* CMD upsname cmdname */
|
||||
if (numa < 3) {
|
||||
fprintf(stderr, "Error: insufficient data "
|
||||
"(got %d args, need at least 3)\n", numa);
|
||||
"(got %zu args, need at least 3)\n", numa);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -466,7 +486,7 @@ static void showcmds(void)
|
|||
|
||||
upscli_disconnect(&ups);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
/* handle setting authentication data in the server */
|
||||
static void send_auth(const char *next)
|
||||
|
@ -491,7 +511,7 @@ static void send_auth(const char *next)
|
|||
"upsd version too old - USERNAME not supported");
|
||||
}
|
||||
|
||||
error_page(next, "Can't set user name",
|
||||
error_page(next, "Can't set user name",
|
||||
"Set user name failed: %s", upscli_strerror(&ups));
|
||||
}
|
||||
|
||||
|
@ -504,7 +524,10 @@ static void send_auth(const char *next)
|
|||
if (upscli_readline(&ups, buf, sizeof(buf)) < 0)
|
||||
error_page(next, "Can't set password",
|
||||
"Password set failed: %s", upscli_strerror(&ups));
|
||||
}
|
||||
}
|
||||
|
||||
static void docmd(void)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void docmd(void)
|
||||
{
|
||||
|
@ -515,13 +538,13 @@ static void docmd(void)
|
|||
"Access to that host is not authorized");
|
||||
|
||||
/* the user is messing with us */
|
||||
if (!upscommand)
|
||||
error_page("showcmds", "Form error",
|
||||
if (!upscommand)
|
||||
error_page("showcmds", "Form error",
|
||||
"No instant command selected");
|
||||
|
||||
/* (l)user took the default blank option */
|
||||
if (strlen(upscommand) == 0)
|
||||
error_page("showcmds", "Form error",
|
||||
error_page("showcmds", "Form error",
|
||||
"No instant command selected");
|
||||
|
||||
upsd_connect();
|
||||
|
@ -595,7 +618,7 @@ static void docmd(void)
|
|||
static const char *get_data(const char *type, const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer;
|
||||
const char *query[4];
|
||||
|
||||
|
@ -633,7 +656,7 @@ static void do_string(const char *varname, int maxlen)
|
|||
static void do_enum(const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
char **answer, *val;
|
||||
const char *query[4], *tmp;
|
||||
|
||||
|
@ -659,8 +682,9 @@ static void do_enum(const char *varname)
|
|||
|
||||
if (ret < 0) {
|
||||
printf("Unavailable\n");
|
||||
fprintf(stderr, "Error doing ENUM %s %s: %s\n",
|
||||
fprintf(stderr, "Error doing ENUM %s %s: %s\n",
|
||||
upsname, varname, upscli_strerror(&ups));
|
||||
free(val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -674,7 +698,7 @@ static void do_enum(const char *varname)
|
|||
|
||||
if (numa < 4) {
|
||||
fprintf(stderr, "Error: insufficient data "
|
||||
"(got %d args, need at least 4)\n", numa);
|
||||
"(got %zu args, need at least 4)\n", numa);
|
||||
|
||||
free(val);
|
||||
return;
|
||||
|
@ -697,7 +721,7 @@ static void do_enum(const char *varname)
|
|||
static void do_type(const char *varname)
|
||||
{
|
||||
int ret;
|
||||
unsigned int i, numq, numa;
|
||||
size_t i, numq, numa;
|
||||
char **answer;
|
||||
const char *query[4];
|
||||
|
||||
|
@ -709,7 +733,7 @@ static void do_type(const char *varname)
|
|||
ret = upscli_get(&ups, numq, query, &numa, &answer);
|
||||
|
||||
if ((ret < 0) || (numa < numq)) {
|
||||
printf("Unknown type\n");
|
||||
printf("Unknown type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -727,7 +751,9 @@ static void do_type(const char *varname)
|
|||
/* split out the :<len> data */
|
||||
ptr = strchr(answer[i], ':');
|
||||
*ptr++ = '\0';
|
||||
len = strtol(ptr, (char **) NULL, 10);
|
||||
long l = strtol(ptr, (char **) NULL, 10);
|
||||
assert(l <= 127); /* FIXME: Loophole about longer numbers? Why are we limited to char at all here? */
|
||||
len = (char)l;
|
||||
|
||||
do_string(varname, len);
|
||||
return;
|
||||
|
@ -741,10 +767,12 @@ static void do_type(const char *varname)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_rw(const char *upsname, const char *varname)
|
||||
static void print_rw(const char *arg_upsname, const char *varname)
|
||||
{
|
||||
const char *tmp;
|
||||
|
||||
printf("<!-- <TR><TD>Device</TD><TD>%s</TD></TR> -->\n", arg_upsname);
|
||||
|
||||
printf("<TR BGCOLOR=\"#60B0B0\" ALIGN=\"CENTER\">\n");
|
||||
|
||||
printf("<TD>");
|
||||
|
@ -765,10 +793,13 @@ static void print_rw(const char *upsname, const char *varname)
|
|||
printf("</TR>\n");
|
||||
}
|
||||
|
||||
static void showsettings(void)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void showsettings(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[2];
|
||||
char **answer, *desc = NULL;
|
||||
struct list_t *lhead, *llast, *ltmp, *lnext;
|
||||
|
@ -907,13 +938,16 @@ static int setvar(const char *var, const char *val)
|
|||
}
|
||||
|
||||
/* turn a form submission of settings into SET commands for upsd */
|
||||
static void savesettings(void)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void savesettings(void)
|
||||
{
|
||||
int changed = 0;
|
||||
char *desc;
|
||||
uvtype_t *upsvar;
|
||||
|
||||
if (!checkhost(monups, &desc))
|
||||
if (!checkhost(monups, &desc))
|
||||
error_page("showsettings", "Access denied",
|
||||
"Access to that host is not authorized");
|
||||
|
||||
|
@ -953,6 +987,9 @@ static void savesettings(void)
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void initial_pickups(void)
|
||||
__attribute__((noreturn));
|
||||
|
||||
static void initial_pickups(void)
|
||||
{
|
||||
do_header("Select a UPS");
|
||||
|
@ -1027,10 +1064,12 @@ static void check_conf(void)
|
|||
fprintf(stderr, "upsset.conf does not permit execution\n");
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(argc);
|
||||
NUT_UNUSED_VARIABLE(argv);
|
||||
username = password = function = monups = NULL;
|
||||
|
||||
printf("Content-type: text/html\n\n");
|
||||
|
@ -1040,15 +1079,16 @@ int main(int argc, char **argv)
|
|||
|
||||
/* see if there's anything waiting .. the server my not close STDIN properly */
|
||||
if (1) {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 250000; /* wait for up to 250ms for a POST response */
|
||||
if ((select(STDIN_FILENO+1, &fds, 0, 0, &tv)) > 0)
|
||||
extractpostargs();
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(STDIN_FILENO, &fds);
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 250000; /* wait for up to 250ms for a POST response */
|
||||
|
||||
if ((select(STDIN_FILENO+1, &fds, 0, 0, &tv)) > 0)
|
||||
extractpostargs();
|
||||
}
|
||||
if ((!username) || (!password) || (!function))
|
||||
loginscreen();
|
||||
|
@ -1074,6 +1114,6 @@ int main(int argc, char **argv)
|
|||
docmd();
|
||||
|
||||
printf("Error: Unhandled function name [%s]\n", function);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_stdint.h"
|
||||
#include "timehead.h"
|
||||
#include "upsclient.h"
|
||||
#include "status.h"
|
||||
#include "cgilib.h"
|
||||
#include "parseconf.h"
|
||||
#include "timehead.h"
|
||||
#include "upsstats.h"
|
||||
#include "upsimagearg.h"
|
||||
|
||||
|
@ -36,7 +37,7 @@ static int use_celsius = 1, refreshdelay = -1, treemode = 0;
|
|||
/* from cgilib's checkhost() */
|
||||
static char *monhostdesc = NULL;
|
||||
|
||||
static int port;
|
||||
static uint16_t port;
|
||||
static char *upsname, *hostname;
|
||||
static char *upsimgpath="upsimage.cgi", *upsstatpath="upsstats.cgi";
|
||||
static UPSCONN_t ups;
|
||||
|
@ -103,7 +104,7 @@ static int check_ups_fd(int do_report)
|
|||
static int get_var(const char *var, char *buf, size_t buflen, int verbose)
|
||||
{
|
||||
int ret;
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -134,7 +135,7 @@ static int get_var(const char *var, char *buf, size_t buflen, int verbose)
|
|||
if (numa < numq) {
|
||||
if (verbose)
|
||||
printf("[Invalid response]\n");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -195,9 +196,10 @@ static int do_date(const char *buf)
|
|||
{
|
||||
char datebuf[SMALLBUF];
|
||||
time_t tod;
|
||||
struct tm tmbuf;
|
||||
|
||||
time(&tod);
|
||||
if (strftime(datebuf, sizeof(datebuf), buf, localtime(&tod))) {
|
||||
if (strftime(datebuf, sizeof(datebuf), buf, localtime_r(&tod, &tmbuf))) {
|
||||
printf("%s", datebuf);
|
||||
return 1;
|
||||
}
|
||||
|
@ -291,12 +293,12 @@ static int do_img(char *buf)
|
|||
|
||||
/* only allow known types through */
|
||||
|
||||
if (!strcmp(type, "input.voltage")
|
||||
|| !strcmp(type, "input.L1-N.voltage")
|
||||
|| !strcmp(type, "input.L2-N.voltage")
|
||||
if (!strcmp(type, "input.voltage")
|
||||
|| !strcmp(type, "input.L1-N.voltage")
|
||||
|| !strcmp(type, "input.L2-N.voltage")
|
||||
|| !strcmp(type, "input.L3-N.voltage")
|
||||
|| !strcmp(type, "input.L1-L2.voltage")
|
||||
|| !strcmp(type, "input.L2-L3.voltage")
|
||||
|| !strcmp(type, "input.L1-L2.voltage")
|
||||
|| !strcmp(type, "input.L2-L3.voltage")
|
||||
|| !strcmp(type, "input.L3-L1.voltage")) {
|
||||
return get_img_val(type, "Input voltage", imgargs);
|
||||
}
|
||||
|
@ -308,11 +310,11 @@ static int do_img(char *buf)
|
|||
return get_img_val(type, "Battery charge", imgargs);
|
||||
|
||||
if (!strcmp(type, "output.voltage")
|
||||
|| !strcmp(type, "output.L1-N.voltage")
|
||||
|| !strcmp(type, "output.L2-N.voltage")
|
||||
|| !strcmp(type, "output.L1-N.voltage")
|
||||
|| !strcmp(type, "output.L2-N.voltage")
|
||||
|| !strcmp(type, "output.L3-N.voltage")
|
||||
|| !strcmp(type, "output.L1-L2.voltage")
|
||||
|| !strcmp(type, "output.L2-L3.voltage")
|
||||
|| !strcmp(type, "output.L1-L2.voltage")
|
||||
|| !strcmp(type, "output.L2-L3.voltage")
|
||||
|| !strcmp(type, "output.L3-L1.voltage")) {
|
||||
return get_img_val(type, "Output voltage", imgargs);
|
||||
}
|
||||
|
@ -349,7 +351,7 @@ static void ups_connect(void)
|
|||
{
|
||||
static ulist_t *lastups = NULL;
|
||||
char *newups, *newhost;
|
||||
int newport;
|
||||
uint16_t newport;
|
||||
|
||||
/* try to minimize reconnects */
|
||||
if (lastups) {
|
||||
|
@ -363,13 +365,13 @@ static void ups_connect(void)
|
|||
/* see if it's just on the same host */
|
||||
newups = newhost = NULL;
|
||||
|
||||
if (upscli_splitname(currups->sys, &newups, &newhost,
|
||||
if (upscli_splitname(currups->sys, &newups, &newhost,
|
||||
&newport) != 0) {
|
||||
printf("Unusable UPS definition [%s]\n", currups->sys);
|
||||
fprintf(stderr, "Unusable UPS definition [%s]\n",
|
||||
fprintf(stderr, "Unusable UPS definition [%s]\n",
|
||||
currups->sys);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!strcmp(newhost, hostname)) && (port == newport)) {
|
||||
free(upsname);
|
||||
|
@ -564,7 +566,7 @@ static void do_upsimgpath(const char *s) {
|
|||
static void do_temp(const char *var)
|
||||
{
|
||||
char tempc[SMALLBUF];
|
||||
float tempf;
|
||||
double tempf;
|
||||
|
||||
if (!get_var(var, tempc, sizeof(tempc), 1))
|
||||
return;
|
||||
|
@ -807,7 +809,8 @@ static int do_command(char *cmd)
|
|||
static void parse_line(const char *buf)
|
||||
{
|
||||
char cmd[SMALLBUF];
|
||||
int i, len, do_cmd = 0;
|
||||
size_t i, len;
|
||||
char do_cmd = 0;
|
||||
|
||||
for (i = 0; buf[i]; i += len) {
|
||||
|
||||
|
@ -824,9 +827,10 @@ static void parse_line(const char *buf)
|
|||
i++; /* skip over the '@' character */
|
||||
continue;
|
||||
}
|
||||
assert (len < INT_MAX);
|
||||
|
||||
if (do_cmd) {
|
||||
snprintf(cmd, sizeof(cmd), "%.*s", len, &buf[i]);
|
||||
snprintf(cmd, sizeof(cmd), "%.*s", (int)len, &buf[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -836,13 +840,13 @@ static void parse_line(const char *buf)
|
|||
}
|
||||
|
||||
/* pass it trough */
|
||||
printf("%.*s", len, &buf[i]);
|
||||
printf("%.*s", (int)len, &buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void display_template(const char *tfn)
|
||||
{
|
||||
char fn[SMALLBUF], buf[LARGEBUF];
|
||||
char fn[SMALLBUF], buf[LARGEBUF];
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/%s", confpath(), tfn);
|
||||
|
||||
|
@ -865,7 +869,7 @@ static void display_template(const char *tfn)
|
|||
|
||||
static void display_tree(int verbose)
|
||||
{
|
||||
unsigned int numq, numa;
|
||||
size_t numq, numa;
|
||||
const char *query[4];
|
||||
char **answer;
|
||||
|
||||
|
@ -890,7 +894,7 @@ static void display_tree(int verbose)
|
|||
printf("<HTML>\n");
|
||||
printf("<HEAD><TITLE>upsstat: data tree of %s</TITLE></HEAD>\n", currups->desc);
|
||||
|
||||
printf("<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000EE\" VLINK=\"#551A8B\">\n");
|
||||
printf("<BODY BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000EE\" VLINK=\"#551A8B\">\n");
|
||||
|
||||
printf("<TABLE BGCOLOR=\"#50A0A0\" ALIGN=\"CENTER\">\n");
|
||||
printf("<TR><TD>\n");
|
||||
|
@ -910,12 +914,12 @@ static void display_tree(int verbose)
|
|||
if (numa < 4) {
|
||||
if (verbose)
|
||||
printf("[Invalid response]\n");
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
printf("<TR BGCOLOR=\"#60B0B0\" ALIGN=\"LEFT\">\n");
|
||||
|
||||
|
||||
printf("<TD>%s</TD>\n", answer[2]);
|
||||
printf("<TD>:</TD>\n");
|
||||
printf("<TD>%s<br></TD>\n", answer[3]);
|
||||
|
@ -936,7 +940,7 @@ static void add_ups(char *sys, char *desc)
|
|||
|
||||
tmp = last = ulhead;
|
||||
|
||||
while (tmp) {
|
||||
while (tmp) {
|
||||
last = tmp;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
@ -1041,9 +1045,12 @@ static void display_single(void)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NUT_UNUSED_VARIABLE(argc);
|
||||
NUT_UNUSED_VARIABLE(argv);
|
||||
|
||||
extractcgiargs();
|
||||
|
||||
printf("Content-type: text/html\n");
|
||||
printf("Content-type: text/html\n");
|
||||
printf("Pragma: no-cache\n");
|
||||
printf("\n");
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUT_UPSSTATS_H_SEEN
|
||||
#define NUT_UPSSTATS_H_SEEN 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
|
@ -35,3 +38,4 @@ typedef struct {
|
|||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
#endif /* NUT_UPSSTATS_H_SEEN */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue