Imported Upstream version 2.7.1
This commit is contained in:
parent
a1fa151fc7
commit
0121794af9
451 changed files with 41339 additions and 10887 deletions
|
@ -20,9 +20,9 @@ endif
|
|||
bin_PROGRAMS = upsc upslog upsrw upscmd
|
||||
dist_bin_SCRIPTS = upssched-cmd
|
||||
sbin_PROGRAMS = upsmon upssched
|
||||
lib_LTLIBRARIES = libupsclient.la
|
||||
lib_LTLIBRARIES = libupsclient.la libnutclient.la
|
||||
if WITH_DEV
|
||||
include_HEADERS = upsclient.h ../include/parseconf.h
|
||||
include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h
|
||||
endif
|
||||
if WITH_CGI
|
||||
cgiexec_PROGRAMS = upsstats.cgi upsimage.cgi upsset.cgi
|
||||
|
@ -50,4 +50,10 @@ libupsclient_la_LIBADD = ../common/libparseconf.la
|
|||
if WITH_SSL
|
||||
libupsclient_la_LIBADD += $(LIBSSL_LIBS)
|
||||
endif
|
||||
libupsclient_la_LDFLAGS = -version-info 2:0:1
|
||||
|
||||
# libupsclient version information
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
libupsclient_la_LDFLAGS = -version-info 3:1:0
|
||||
|
||||
libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
@ -21,6 +21,23 @@
|
|||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
|
@ -66,8 +83,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
|
|||
$(top_srcdir)/m4/nut_check_libltdl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnss.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libpowerman.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libssl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libusb.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libwrap.m4 \
|
||||
$(top_srcdir)/m4/nut_check_os.m4 \
|
||||
|
@ -102,10 +120,19 @@ am__nobase_list = $(am__nobase_strip_setup); \
|
|||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(cgiexecdir)" "$(DESTDIR)$(sbindir)" \
|
||||
"$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libnutclient_la_LIBADD =
|
||||
am_libnutclient_la_OBJECTS = nutclient.lo
|
||||
libnutclient_la_OBJECTS = $(am_libnutclient_la_OBJECTS)
|
||||
am__DEPENDENCIES_1 =
|
||||
@WITH_SSL_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
libupsclient_la_DEPENDENCIES = ../common/libparseconf.la \
|
||||
|
@ -175,15 +202,32 @@ CCLD = $(CC)
|
|||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libupsclient_la_SOURCES) $(upsc_SOURCES) $(upscmd_SOURCES) \
|
||||
$(upsimage_cgi_SOURCES) $(upslog_SOURCES) $(upsmon_SOURCES) \
|
||||
$(upsrw_SOURCES) $(upssched_SOURCES) $(upsset_cgi_SOURCES) \
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
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) \
|
||||
$(upsstats_cgi_SOURCES)
|
||||
DIST_SOURCES = $(libupsclient_la_SOURCES) $(upsc_SOURCES) \
|
||||
$(upscmd_SOURCES) $(upsimage_cgi_SOURCES) $(upslog_SOURCES) \
|
||||
$(upsmon_SOURCES) $(upsrw_SOURCES) $(upssched_SOURCES) \
|
||||
$(upsset_cgi_SOURCES) $(upsstats_cgi_SOURCES)
|
||||
am__include_HEADERS_DIST = upsclient.h ../include/parseconf.h
|
||||
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) \
|
||||
$(upsstats_cgi_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
am__include_HEADERS_DIST = upsclient.h ../include/parseconf.h \
|
||||
nutclient.h
|
||||
HEADERS = $(include_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
|
@ -193,6 +237,7 @@ ACLOCAL = @ACLOCAL@
|
|||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
ASCIIDOC = @ASCIIDOC@
|
||||
ASPELL = @ASPELL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
|
@ -219,6 +264,7 @@ DOC_BUILD_LIST = @DOC_BUILD_LIST@
|
|||
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||
DRVPATH = @DRVPATH@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
|
@ -381,8 +427,8 @@ 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
|
||||
@WITH_DEV_TRUE@include_HEADERS = upsclient.h ../include/parseconf.h
|
||||
lib_LTLIBRARIES = libupsclient.la libnutclient.la
|
||||
@WITH_DEV_TRUE@include_HEADERS = upsclient.h ../include/parseconf.h nutclient.h
|
||||
upsc_SOURCES = upsc.c upsclient.h
|
||||
upscmd_SOURCES = upscmd.c upsclient.h
|
||||
upsrw_SOURCES = upsrw.c upsclient.h
|
||||
|
@ -400,11 +446,15 @@ upsstats_cgi_SOURCES = upsstats.c upsclient.h status.h upsstats.h \
|
|||
# not LDADD.
|
||||
libupsclient_la_SOURCES = upsclient.c upsclient.h
|
||||
libupsclient_la_LIBADD = ../common/libparseconf.la $(am__append_4)
|
||||
libupsclient_la_LDFLAGS = -version-info 2:0:1
|
||||
|
||||
# libupsclient version information
|
||||
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
|
||||
libupsclient_la_LDFLAGS = -version-info 3:1:0
|
||||
libnutclient_la_SOURCES = nutclient.h nutclient.cpp
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
.SUFFIXES: .c .cpp .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
|
@ -437,7 +487,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
|||
$(am__aclocal_m4_deps):
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
|
@ -445,6 +494,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
|||
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)"; \
|
||||
}
|
||||
|
@ -466,12 +517,17 @@ clean-libLTLIBRARIES:
|
|||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libupsclient.la: $(libupsclient_la_OBJECTS) $(libupsclient_la_DEPENDENCIES)
|
||||
libnutclient.la: $(libnutclient_la_OBJECTS) $(libnutclient_la_DEPENDENCIES) $(EXTRA_libnutclient_la_DEPENDENCIES)
|
||||
$(CXXLINK) -rpath $(libdir) $(libnutclient_la_OBJECTS) $(libnutclient_la_LIBADD) $(LIBS)
|
||||
libupsclient.la: $(libupsclient_la_OBJECTS) $(libupsclient_la_DEPENDENCIES) $(EXTRA_libupsclient_la_DEPENDENCIES)
|
||||
$(libupsclient_la_LINK) -rpath $(libdir) $(libupsclient_la_OBJECTS) $(libupsclient_la_LIBADD) $(LIBS)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
|
@ -513,8 +569,11 @@ clean-binPROGRAMS:
|
|||
rm -f $$list
|
||||
install-cgiexecPROGRAMS: $(cgiexec_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(cgiexecdir)" || $(MKDIR_P) "$(DESTDIR)$(cgiexecdir)"
|
||||
@list='$(cgiexec_PROGRAMS)'; test -n "$(cgiexecdir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(cgiexecdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(cgiexecdir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
|
@ -556,8 +615,11 @@ clean-cgiexecPROGRAMS:
|
|||
rm -f $$list
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
|
@ -597,37 +659,40 @@ clean-sbinPROGRAMS:
|
|||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
upsc$(EXEEXT): $(upsc_OBJECTS) $(upsc_DEPENDENCIES)
|
||||
upsc$(EXEEXT): $(upsc_OBJECTS) $(upsc_DEPENDENCIES) $(EXTRA_upsc_DEPENDENCIES)
|
||||
@rm -f upsc$(EXEEXT)
|
||||
$(LINK) $(upsc_OBJECTS) $(upsc_LDADD) $(LIBS)
|
||||
upscmd$(EXEEXT): $(upscmd_OBJECTS) $(upscmd_DEPENDENCIES)
|
||||
upscmd$(EXEEXT): $(upscmd_OBJECTS) $(upscmd_DEPENDENCIES) $(EXTRA_upscmd_DEPENDENCIES)
|
||||
@rm -f upscmd$(EXEEXT)
|
||||
$(LINK) $(upscmd_OBJECTS) $(upscmd_LDADD) $(LIBS)
|
||||
upsimage.cgi$(EXEEXT): $(upsimage_cgi_OBJECTS) $(upsimage_cgi_DEPENDENCIES)
|
||||
upsimage.cgi$(EXEEXT): $(upsimage_cgi_OBJECTS) $(upsimage_cgi_DEPENDENCIES) $(EXTRA_upsimage_cgi_DEPENDENCIES)
|
||||
@rm -f upsimage.cgi$(EXEEXT)
|
||||
$(LINK) $(upsimage_cgi_OBJECTS) $(upsimage_cgi_LDADD) $(LIBS)
|
||||
upslog$(EXEEXT): $(upslog_OBJECTS) $(upslog_DEPENDENCIES)
|
||||
upslog$(EXEEXT): $(upslog_OBJECTS) $(upslog_DEPENDENCIES) $(EXTRA_upslog_DEPENDENCIES)
|
||||
@rm -f upslog$(EXEEXT)
|
||||
$(LINK) $(upslog_OBJECTS) $(upslog_LDADD) $(LIBS)
|
||||
upsmon$(EXEEXT): $(upsmon_OBJECTS) $(upsmon_DEPENDENCIES)
|
||||
upsmon$(EXEEXT): $(upsmon_OBJECTS) $(upsmon_DEPENDENCIES) $(EXTRA_upsmon_DEPENDENCIES)
|
||||
@rm -f upsmon$(EXEEXT)
|
||||
$(LINK) $(upsmon_OBJECTS) $(upsmon_LDADD) $(LIBS)
|
||||
upsrw$(EXEEXT): $(upsrw_OBJECTS) $(upsrw_DEPENDENCIES)
|
||||
upsrw$(EXEEXT): $(upsrw_OBJECTS) $(upsrw_DEPENDENCIES) $(EXTRA_upsrw_DEPENDENCIES)
|
||||
@rm -f upsrw$(EXEEXT)
|
||||
$(LINK) $(upsrw_OBJECTS) $(upsrw_LDADD) $(LIBS)
|
||||
upssched$(EXEEXT): $(upssched_OBJECTS) $(upssched_DEPENDENCIES)
|
||||
upssched$(EXEEXT): $(upssched_OBJECTS) $(upssched_DEPENDENCIES) $(EXTRA_upssched_DEPENDENCIES)
|
||||
@rm -f upssched$(EXEEXT)
|
||||
$(LINK) $(upssched_OBJECTS) $(upssched_LDADD) $(LIBS)
|
||||
upsset.cgi$(EXEEXT): $(upsset_cgi_OBJECTS) $(upsset_cgi_DEPENDENCIES)
|
||||
upsset.cgi$(EXEEXT): $(upsset_cgi_OBJECTS) $(upsset_cgi_DEPENDENCIES) $(EXTRA_upsset_cgi_DEPENDENCIES)
|
||||
@rm -f upsset.cgi$(EXEEXT)
|
||||
$(LINK) $(upsset_cgi_OBJECTS) $(upsset_cgi_LDADD) $(LIBS)
|
||||
upsstats.cgi$(EXEEXT): $(upsstats_cgi_OBJECTS) $(upsstats_cgi_DEPENDENCIES)
|
||||
upsstats.cgi$(EXEEXT): $(upsstats_cgi_OBJECTS) $(upsstats_cgi_DEPENDENCIES) $(EXTRA_upsstats_cgi_DEPENDENCIES)
|
||||
@rm -f upsstats.cgi$(EXEEXT)
|
||||
$(LINK) $(upsstats_cgi_OBJECTS) $(upsstats_cgi_LDADD) $(LIBS)
|
||||
install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
|
||||
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
|
||||
|
@ -655,9 +720,7 @@ uninstall-dist_binSCRIPTS:
|
|||
@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 's,.*/,,;$(transform)'`; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(bindir)" && rm -f $$files
|
||||
dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
@ -666,6 +729,7 @@ 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@
|
||||
|
@ -698,6 +762,27 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.o:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
|
||||
|
||||
.cpp.obj:
|
||||
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.cpp.lo:
|
||||
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
|
@ -705,8 +790,11 @@ clean-libtool:
|
|||
-rm -rf .libs _libs
|
||||
install-includeHEADERS: $(include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
if test -n "$$list"; then \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
|
||||
fi; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
|
@ -720,9 +808,7 @@ uninstall-includeHEADERS:
|
|||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(includedir)" && rm -f $$files
|
||||
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
|
@ -825,10 +911,15 @@ install-am: all-am
|
|||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
/* other programs that link to this should provide parsearg() ... */
|
||||
void parsearg(char *var, char *value);
|
||||
|
||||
|
@ -29,3 +35,9 @@ void extractpostargs(void);
|
|||
/* see if a host is allowed per the hosts.conf */
|
||||
int checkhost(const char *host, char **desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
1726
clients/nutclient.cpp
Normal file
1726
clients/nutclient.cpp
Normal file
File diff suppressed because it is too large
Load diff
963
clients/nutclient.h
Normal file
963
clients/nutclient.h
Normal file
|
@ -0,0 +1,963 @@
|
|||
/* nutclient.h - definitions for nutclient C/C++ library
|
||||
|
||||
Copyright (C) 2012 Emilien Kia <emilien.kia@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef NUTCLIENT_HPP_SEEN
|
||||
#define NUTCLIENT_HPP_SEEN
|
||||
|
||||
/* Begin of C++ nutclient library declaration */
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <exception>
|
||||
|
||||
namespace nut
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
class Socket;
|
||||
} /* namespace internal */
|
||||
|
||||
|
||||
class Client;
|
||||
class TcpClient;
|
||||
class Device;
|
||||
class Variable;
|
||||
class Command;
|
||||
|
||||
/**
|
||||
* Basic nut exception.
|
||||
*/
|
||||
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;}
|
||||
private:
|
||||
std::string _msg;
|
||||
};
|
||||
|
||||
/**
|
||||
* System error.
|
||||
*/
|
||||
class SystemException : public NutException
|
||||
{
|
||||
public:
|
||||
SystemException();
|
||||
virtual ~SystemException() throw() {}
|
||||
private:
|
||||
static std::string err();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* IO oriented nut exception.
|
||||
*/
|
||||
class IOException : public NutException
|
||||
{
|
||||
public:
|
||||
IOException(const std::string& msg):NutException(msg){}
|
||||
virtual ~IOException() throw() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* IO oriented nut exception specialized for unknown host
|
||||
*/
|
||||
class UnknownHostException : public IOException
|
||||
{
|
||||
public:
|
||||
UnknownHostException():IOException("Unknown host"){}
|
||||
virtual ~UnknownHostException() throw() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* IO oriented nut exception when client is not connected
|
||||
*/
|
||||
class NotConnectedException : public IOException
|
||||
{
|
||||
public:
|
||||
NotConnectedException():IOException("Not connected"){}
|
||||
virtual ~NotConnectedException() throw() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* IO oriented nut exception when there is no response.
|
||||
*/
|
||||
class TimeoutException : public IOException
|
||||
{
|
||||
public:
|
||||
TimeoutException():IOException("Timeout"){}
|
||||
virtual ~TimeoutException() throw() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* A nut client is the starting point to dialog to NUTD.
|
||||
* It can connect to an NUTD then retrieve its device list.
|
||||
* Use a specific client class to connect to a NUTD.
|
||||
*/
|
||||
class Client
|
||||
{
|
||||
friend class Device;
|
||||
friend class Variable;
|
||||
friend class Command;
|
||||
public:
|
||||
~Client();
|
||||
|
||||
/**
|
||||
* Intend to authenticate to a NUTD server.
|
||||
* Set the username and password associated to the connection.
|
||||
* \param user User name.
|
||||
* \param passwd Password.
|
||||
* \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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Device manipulations.
|
||||
* \see nut::Device
|
||||
* \{
|
||||
*/
|
||||
/**
|
||||
* Retrieve a device from its name.
|
||||
* If the device does not exist, a bad (not ok) device is returned.
|
||||
* \param name Name of the device.
|
||||
* \return The device.
|
||||
*/
|
||||
virtual Device getDevice(const std::string& name)throw(NutException);
|
||||
/**
|
||||
* Retrieve the list of all devices supported by UPSD server.
|
||||
* \return The set of supported devices.
|
||||
*/
|
||||
virtual std::set<Device> getDevices()throw(NutException);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Retrieve the description of a device.
|
||||
* \param name Device name.
|
||||
* \return Device description.
|
||||
*/
|
||||
virtual std::string getDeviceDescription(const std::string& name)throw(NutException)=0;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
* Variable manipulations.
|
||||
* \see nut::Variable
|
||||
* \{
|
||||
*/
|
||||
/**
|
||||
* Retrieve names of all variables supported by a device.
|
||||
* \param dev Device name
|
||||
* \return Variable names
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceVariableNames(const std::string& dev)throw(NutException)=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;
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* 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;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
* Instant command manipulations.
|
||||
* \see nut::Command
|
||||
* \{
|
||||
*/
|
||||
/**
|
||||
* Retrieve names of all commands supported by a device.
|
||||
* \param dev Device name
|
||||
* \return Command names
|
||||
*/
|
||||
virtual std::set<std::string> getDeviceCommandNames(const std::string& dev)throw(NutException)=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);
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* Intend to execute a command.
|
||||
* \param dev Device name
|
||||
* \param name Command name
|
||||
*/
|
||||
virtual void executeDeviceCommand(const std::string& dev, const std::string& name)throw(NutException)=0;
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
* Device specific commands.
|
||||
* \{
|
||||
*/
|
||||
/**
|
||||
* Log the current user (if authenticated) for a device.
|
||||
* \param dev Device name.
|
||||
*/
|
||||
virtual void deviceLogin(const std::string& dev)throw(NutException)=0;
|
||||
/**
|
||||
* Retrieve the number of user longged in 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;
|
||||
|
||||
protected:
|
||||
Client();
|
||||
};
|
||||
|
||||
/**
|
||||
* TCP NUTD client.
|
||||
* It connect to NUTD with a TCP socket.
|
||||
*/
|
||||
class TcpClient : public Client
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a nut TcpClient object.
|
||||
* You must call one of TcpClient::connect() after.
|
||||
*/
|
||||
TcpClient();
|
||||
|
||||
/**
|
||||
* Construct a nut TcpClient object then connect it to the specified server.
|
||||
* \param host Server host name.
|
||||
* \param port Server port.
|
||||
*/
|
||||
TcpClient(const std::string& host, int port = 3493)throw(nut::IOException);
|
||||
~TcpClient();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Connect to the server.
|
||||
* Host name and ports must have already set (usefull for reconnection).
|
||||
*/
|
||||
void connect()throw(nut::IOException);
|
||||
|
||||
/**
|
||||
* Test if the connection is active.
|
||||
* \return tru if the connection is active.
|
||||
*/
|
||||
bool isConnected()const;
|
||||
/**
|
||||
* Force the deconnection.
|
||||
*/
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Set the timeout in seconds.
|
||||
* \param timeout Timeout n seconds, negative to block operations.
|
||||
*/
|
||||
void setTimeout(long timeout);
|
||||
|
||||
/**
|
||||
* Retrieve the timeout.
|
||||
* \returns Current timeout in seconds.
|
||||
*/
|
||||
long getTimeout()const;
|
||||
|
||||
/**
|
||||
* Retriueve the host name of the server the client is connected to.
|
||||
* \return Server host name
|
||||
*/
|
||||
std::string getHost()const;
|
||||
/**
|
||||
* Retriueve the port of host of the server the client is connected to.
|
||||
* \return Server port
|
||||
*/
|
||||
int 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 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 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 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);
|
||||
|
||||
protected:
|
||||
std::string sendQuery(const std::string& req)throw(nut::IOException);
|
||||
static void detectError(const std::string& req)throw(nut::NutException);
|
||||
|
||||
std::vector<std::string> get(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 = "")
|
||||
throw(nut::NutException);
|
||||
|
||||
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;
|
||||
internal::Socket* _socket;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Device attached to a client.
|
||||
* Device is a lightweight class which can be copied easily.
|
||||
*/
|
||||
class Device
|
||||
{
|
||||
friend class Client;
|
||||
friend class TcpClient;
|
||||
public:
|
||||
~Device();
|
||||
Device(const Device& dev);
|
||||
|
||||
/**
|
||||
* Retrieve the name of the device.
|
||||
* The name is the unique id under which NUTD known the device.
|
||||
*/
|
||||
std::string getName()const;
|
||||
/**
|
||||
* Retrieve the client to which the device is attached.
|
||||
*/
|
||||
const Client* getClient()const;
|
||||
/**
|
||||
* Retrieve the client to which the device is attached.
|
||||
*/
|
||||
Client* getClient();
|
||||
|
||||
/**
|
||||
* Test if the device is valid (has a name and is attached to a client).
|
||||
*/
|
||||
bool isOk()const;
|
||||
/**
|
||||
* Test if the device is valid (has a name and is attached to a client).
|
||||
* @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()
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Retrieve the description of the devce if specified.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
std::vector<std::string> getVariableValue(const std::string& name)throw(NutException);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* Retrieve all variables names supported by the device.
|
||||
* \return Set of available variable names.
|
||||
*/
|
||||
std::set<std::string> getVariableNames()throw(NutException);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* Intend to set values of a variable of the device.
|
||||
* \param name Variable name.
|
||||
* \param value New variable values.
|
||||
*/
|
||||
void setVariable(const std::string& name, const std::vector<std::string>& values)throw(NutException);
|
||||
|
||||
/**
|
||||
* Retrieve a Variable object representing the specified variable.
|
||||
* \param name Variable name.
|
||||
* \return Variable object.
|
||||
*/
|
||||
Variable getVariable(const std::string& name)throw(NutException);
|
||||
/**
|
||||
* Retrieve Variable objects representing all variables available for the device.
|
||||
* \return Set of Variable objects.
|
||||
*/
|
||||
std::set<Variable> getVariables()throw(NutException);
|
||||
/**
|
||||
* Retrieve Variable objects representing all Read/Write variables available for the device.
|
||||
* \return Set of Variable objects.
|
||||
*/
|
||||
std::set<Variable> getRWVariables()throw(NutException);
|
||||
|
||||
/**
|
||||
* Retrieve names of all commands supported by the device.
|
||||
* \return Set of available command names.
|
||||
*/
|
||||
std::set<std::string> getCommandNames()throw(NutException);
|
||||
/**
|
||||
* Retrieve objects for all commands supported by the device.
|
||||
* \return Set of available Command objects.
|
||||
*/
|
||||
std::set<Command> getCommands()throw(NutException);
|
||||
/**
|
||||
* Retrieve an object representing a command of the device.
|
||||
* \param name Command name.
|
||||
* \return Command object.
|
||||
*/
|
||||
Command getCommand(const std::string& name)throw(NutException);
|
||||
/**
|
||||
* Intend to execute a command on the device.
|
||||
* \param name Command name.
|
||||
*/
|
||||
void executeCommand(const std::string& name)throw(NutException);
|
||||
|
||||
/**
|
||||
* Login current client's user for the device.
|
||||
*/
|
||||
void login()throw(NutException);
|
||||
void master()throw(NutException);
|
||||
void forcedShutdown()throw(NutException);
|
||||
/**
|
||||
* Retrieve the number of logged user for the device.
|
||||
* \return Number of users.
|
||||
*/
|
||||
int getNumLogins()throw(NutException);
|
||||
|
||||
protected:
|
||||
Device(Client* client, const std::string& name);
|
||||
|
||||
private:
|
||||
Client* _client;
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Variable attached to a device.
|
||||
* Variable is a lightweight class which can be copied easily.
|
||||
*/
|
||||
class Variable
|
||||
{
|
||||
friend class Device;
|
||||
friend class TcpClient;
|
||||
public:
|
||||
~Variable();
|
||||
|
||||
Variable(const Variable& var);
|
||||
|
||||
/**
|
||||
* Retrieve variable name.
|
||||
*/
|
||||
std::string getName()const;
|
||||
/**
|
||||
* Retrieve the device to which the variable is attached to.
|
||||
*/
|
||||
const Device* getDevice()const;
|
||||
/**
|
||||
* Retrieve the device to which the variable is attached to.
|
||||
*/
|
||||
Device* getDevice();
|
||||
|
||||
/**
|
||||
* Test if the variable is valid (has a name and is attached to a device).
|
||||
*/
|
||||
bool isOk()const;
|
||||
/**
|
||||
* Test if the variable is valid (has a name and is attached to a device).
|
||||
* @see Variable::isOk()
|
||||
*/
|
||||
operator bool()const;
|
||||
/**
|
||||
* Test if the variable is not valid (has no name or is not attached to any device).
|
||||
* @see Variable::isOk()
|
||||
*/
|
||||
bool operator!()const;
|
||||
/**
|
||||
* Test if the two variables are sames (same name ad same device attached to).
|
||||
*/
|
||||
bool operator==(const Variable& var)const;
|
||||
/**
|
||||
* Less-than operator (based on variable name) to allow variable sorting.
|
||||
*/
|
||||
bool operator<(const Variable& var)const;
|
||||
|
||||
/**
|
||||
* Intend to retrieve variable value.
|
||||
* \return Value of the variable.
|
||||
*/
|
||||
std::vector<std::string> getValue()throw(NutException);
|
||||
/**
|
||||
* Intend to retireve variable description.
|
||||
* \return Variable description if provided.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
|
||||
/**
|
||||
* Intend to set a value to the variable.
|
||||
* \param value New variable value.
|
||||
*/
|
||||
void setValue(const std::string& value)throw(NutException);
|
||||
/**
|
||||
* Intend to set (multiple) values to the variable.
|
||||
* \param value New variable values.
|
||||
*/
|
||||
void setValues(const std::vector<std::string>& values)throw(NutException);
|
||||
|
||||
protected:
|
||||
Variable(Device* dev, const std::string& name);
|
||||
|
||||
private:
|
||||
Device* _device;
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Command attached to a device.
|
||||
* Command is a lightweight class which can be copied easily.
|
||||
*/
|
||||
class Command
|
||||
{
|
||||
friend class Device;
|
||||
friend class TcpClient;
|
||||
public:
|
||||
~Command();
|
||||
|
||||
Command(const Command& cmd);
|
||||
|
||||
/**
|
||||
* Retrieve command name.
|
||||
*/
|
||||
std::string getName()const;
|
||||
/**
|
||||
* Retrieve the device to which the command is attached to.
|
||||
*/
|
||||
const Device* getDevice()const;
|
||||
/**
|
||||
* Retrieve the device to which the command is attached to.
|
||||
*/
|
||||
Device* getDevice();
|
||||
|
||||
/**
|
||||
* Test if the command is valid (has a name and is attached to a device).
|
||||
*/
|
||||
bool isOk()const;
|
||||
/**
|
||||
* Test if the command is valid (has a name and is attached to a device).
|
||||
* @see Command::isOk()
|
||||
*/
|
||||
operator bool()const;
|
||||
/**
|
||||
* Test if the command is not valid (has no name or is not attached to any device).
|
||||
* @see Command::isOk()
|
||||
*/
|
||||
bool operator!()const;
|
||||
/**
|
||||
* Test if the two commands are sames (same name ad same device attached to).
|
||||
*/
|
||||
bool operator==(const Command& var)const;
|
||||
|
||||
/**
|
||||
* Less-than operator (based on command name) to allow comand sorting.
|
||||
*/
|
||||
bool operator<(const Command& var)const;
|
||||
|
||||
/**
|
||||
* Intend to retireve command description.
|
||||
* \return Command description if provided.
|
||||
*/
|
||||
std::string getDescription()throw(NutException);
|
||||
|
||||
/**
|
||||
* Intend to retrieve command description.
|
||||
* \return Command description if provided.
|
||||
*/
|
||||
void execute()throw(NutException);
|
||||
|
||||
protected:
|
||||
Command(Device* dev, const std::string& name);
|
||||
|
||||
private:
|
||||
Device* _device;
|
||||
std::string _name;
|
||||
};
|
||||
|
||||
} /* namespace nut */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
/* End of C++ nutclient library declaration */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Begin of C nutclient library declaration */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/**
|
||||
* Array of string manipulation functions.
|
||||
* \{
|
||||
*/
|
||||
/** Array of string.*/
|
||||
typedef char** strarr;
|
||||
/**
|
||||
* Alloc an array of string.
|
||||
*/
|
||||
strarr strarr_alloc(unsigned short count);
|
||||
|
||||
/**
|
||||
* Free an array of string.
|
||||
*/
|
||||
void strarr_free(strarr arr);
|
||||
|
||||
|
||||
/**
|
||||
* Nut general client types and functions.
|
||||
* \{
|
||||
*/
|
||||
/** Hidden structure representing a connection to NUTD. */
|
||||
typedef void* NUTCLIENT_t;
|
||||
|
||||
/**
|
||||
* Destroy a client.
|
||||
* \param client Nut client handle.
|
||||
*/
|
||||
void nutclient_destroy(NUTCLIENT_t client);
|
||||
|
||||
/**
|
||||
* Authenticate into the server.
|
||||
* \param client Nut client handle.
|
||||
* \param login User name.
|
||||
* \param passwd Password.
|
||||
*/
|
||||
void nutclient_authenticate(NUTCLIENT_t client, const char* login, const char* passwd);
|
||||
|
||||
/**
|
||||
* Log out from server.
|
||||
* \param client Nut client handle.
|
||||
*/
|
||||
void nutclient_logout(NUTCLIENT_t client);
|
||||
|
||||
/**
|
||||
* Register current user on the device.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
*/
|
||||
void nutclient_device_login(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Retrieve the number of users registered on a device.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
*/
|
||||
int nutclient_get_device_num_logins(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Set current user as master user of the device.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
*/
|
||||
void nutclient_device_master(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Set the FSD flag for the device.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
*/
|
||||
void nutclient_device_forced_shutdown(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Retrieve the list of devices of a client.
|
||||
* \param client Nut client handle.
|
||||
* \return Array of string containing device names. Must be freed with strarr_free(strarr).
|
||||
*/
|
||||
strarr nutclient_get_devices(NUTCLIENT_t client);
|
||||
|
||||
/**
|
||||
* Test if a device is supported by the client.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
* \return 1 if supported, 0 otherwise.
|
||||
*/
|
||||
int nutclient_has_device(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device description.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name to test.
|
||||
* \return Description of device. Must be freed after use.
|
||||
*/
|
||||
char* nutclient_get_device_description(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device variable names.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \return Array of string containing variable names. Must be freed with strarr_free(strarr).
|
||||
*/
|
||||
strarr nutclient_get_device_variables(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device read/write variable names.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \return Array of string containing read/write variable names. Must be freed with strarr_free(strarr).
|
||||
*/
|
||||
strarr nutclient_get_device_rw_variables(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Test if a variable is supported by the device and the client.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param var Variable name.
|
||||
* \return 1 if supported, 0 otherwise.
|
||||
*/
|
||||
int nutclient_has_device_variable(NUTCLIENT_t client, const char* dev, const char* var);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device variable description.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param var Variable name.
|
||||
* \return Description of device variable. Must be freed after use.
|
||||
*/
|
||||
char* nutclient_get_device_variable_description(NUTCLIENT_t client, const char* dev, const char* var);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device variable values.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param var Variable name.
|
||||
* \return Array of string containing variable values. Must be freed with strarr_free(strarr).
|
||||
*/
|
||||
strarr nutclient_get_device_variable_values(NUTCLIENT_t client, const char* dev, const char* var);
|
||||
|
||||
/**
|
||||
* Intend to set device variable value.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param var Variable name.
|
||||
* \param value Value to set.
|
||||
*/
|
||||
void nutclient_set_device_variable_value(NUTCLIENT_t client, const char* dev, const char* var, const char* value);
|
||||
|
||||
/**
|
||||
* Intend to set device variable multiple values.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param var Variable name.
|
||||
* \param values Values to set. The cller is responsible to free it after call.
|
||||
*/
|
||||
void nutclient_set_device_variable_values(NUTCLIENT_t client, const char* dev, const char* var, const strarr values);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device command names.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \return Array of string containing command names. Must be freed with strarr_free(strarr).
|
||||
*/
|
||||
strarr nutclient_get_device_commands(NUTCLIENT_t client, const char* dev);
|
||||
|
||||
/**
|
||||
* Test if a command is supported by the device and the client.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param cmd Command name.
|
||||
* \return 1 if supported, 0 otherwise.
|
||||
*/
|
||||
int nutclient_has_device_command(NUTCLIENT_t client, const char* dev, const char* cmd);
|
||||
|
||||
/**
|
||||
* Intend to retrieve device command description.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param cmd Command name.
|
||||
* \return Description of device command. Must be freed after use.
|
||||
*/
|
||||
char* nutclient_get_device_command_description(NUTCLIENT_t client, const char* dev, const char* cmd);
|
||||
|
||||
/**
|
||||
* Intend to execute device command.
|
||||
* \param client Nut client handle.
|
||||
* \param dev Device name.
|
||||
* \param cmd Command name.
|
||||
*/
|
||||
void nutclient_execute_device_command(NUTCLIENT_t client, const char* dev, const char* cmd);
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
/**
|
||||
* Nut TCP client dedicated types and functions
|
||||
* \{
|
||||
*/
|
||||
/**
|
||||
* Hidden structure representing a TCP connection to NUTD.
|
||||
* NUTCLIENT_TCP_t is back compatible to NUTCLIENT_t.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
NUTCLIENT_TCP_t nutclient_tcp_create_client(const char* host, unsigned short port);
|
||||
/**
|
||||
* Test if a nut TCP client is connected.
|
||||
* \param client Nut TCP client handle.
|
||||
* \return 1 if connected, 0 otherwise.
|
||||
*/
|
||||
int nutclient_tcp_is_connected(NUTCLIENT_TCP_t client);
|
||||
/**
|
||||
* Disconnect a nut TCP client.
|
||||
* \param client Nut TCP client handle.
|
||||
*/
|
||||
void nutclient_tcp_disconnect(NUTCLIENT_TCP_t client);
|
||||
/**
|
||||
* Intend to reconnect a nut TCP client.
|
||||
* \param client Nut TCP client handle.
|
||||
* \return 0 if correctly connected.
|
||||
* \todo Implement different error codes.
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* Retrieve the timeout value for the TCP connection.
|
||||
* \return Timeout value in seconds.
|
||||
*/
|
||||
long nutclient_tcp_get_timeout(NUTCLIENT_TCP_t client);
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
/* End of C nutclient library declaration */
|
||||
|
||||
|
||||
#endif /* NUTCLIENT_HPP_SEEN */
|
|
@ -17,6 +17,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
char *desc;
|
||||
|
@ -35,3 +41,10 @@ struct {
|
|||
{ "BYPASS", "BYPASS", 2 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_platform.h"
|
||||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
@ -274,3 +275,11 @@ int main(int argc, char **argv)
|
|||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||
#if (defined NUT_PLATFORM_AIX)
|
||||
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||
}
|
||||
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
|
||||
#include "config.h" /* safe because it doesn't contain prototypes */
|
||||
|
||||
#ifdef HAVE_PTHREAD
|
||||
/* this include is needed on AIX to have errno stored in thread local storage */
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
|
@ -33,8 +38,18 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
#include "upsclient.h"
|
||||
#include "common.h"
|
||||
#include "timehead.h"
|
||||
|
||||
#ifdef WITH_NSS
|
||||
#include <prerror.h>
|
||||
#include <prinit.h>
|
||||
#include <pk11func.h>
|
||||
#include <prtypes.h>
|
||||
#include <ssl.h>
|
||||
#include <private/pprio.h>
|
||||
#endif /* WITH_NSS */
|
||||
|
||||
#define UPSCLIENT_MAGIC 0x19980308
|
||||
|
||||
#define SMALLBUF 512
|
||||
|
@ -95,9 +110,354 @@ struct {
|
|||
{ 0, "Protocol error", }, /* 42: UPSCLI_ERR_PROTOCOL */
|
||||
};
|
||||
|
||||
|
||||
typedef struct HOST_CERT_s {
|
||||
const char *host;
|
||||
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);
|
||||
|
||||
|
||||
static int upscli_initialized = 0;
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
static SSL_CTX *ssl_ctx;
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSLL */
|
||||
static int verify_certificate = 1;
|
||||
static HOST_CERT_t *first_host_cert = NULL;
|
||||
static char* nsscertname = NULL;
|
||||
static char* nsscertpasswd = NULL;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
static void ssl_debug(void)
|
||||
{
|
||||
int e;
|
||||
char errmsg[SMALLBUF];
|
||||
|
||||
while ((e = ERR_get_error()) != 0) {
|
||||
ERR_error_string_n(e, errmsg, sizeof(errmsg));
|
||||
upsdebugx(2, "ssl_debug: %s", errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
static int ssl_error(SSL *ssl, int ret)
|
||||
{
|
||||
int e;
|
||||
|
||||
e = SSL_get_error(ssl, ret);
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR_WANT_READ", ret);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d 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);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
upslogx(LOG_ERR, "ssl_error() ret=%d SSL_ERROR %d", ret, e);
|
||||
ssl_debug();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
|
||||
static char *nss_password_callback(PK11SlotInfo *slot, PRBool retry,
|
||||
void *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;
|
||||
}
|
||||
|
||||
static void nss_error(const char* funcname)
|
||||
{
|
||||
char buffer[SMALLBUF];
|
||||
PRInt32 length = PR_GetErrorText(buffer);
|
||||
if (length > 0 && length < SMALLBUF) {
|
||||
upsdebugx(1, "nss_error %ld in %s : %s", (long)PR_GetError(), funcname, buffer);
|
||||
}else{
|
||||
upsdebugx(1, "nss_error %ld in %s", (long)PR_GetError(), funcname);
|
||||
}
|
||||
}
|
||||
|
||||
static SECStatus AuthCertificate(CERTCertDBHandle *arg, PRFileDesc *fd,
|
||||
PRBool checksig, PRBool isServer)
|
||||
{
|
||||
UPSCONN_t *ups = (UPSCONN_t *)SSL_RevealPinArg(fd);
|
||||
SECStatus status = SSL_AuthCertificate(arg, fd, checksig, isServer);
|
||||
upslogx(LOG_INFO, "Intend to authenticate server %s : %s",
|
||||
ups?ups->host:"<unnamed>",
|
||||
status==SECSuccess?"SUCCESS":"FAILED");
|
||||
if (status != SECSuccess) {
|
||||
nss_error("SSL_AuthCertificate");
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static SECStatus AuthCertificateDontVerify(CERTCertDBHandle *arg, PRFileDesc *fd,
|
||||
PRBool checksig, PRBool isServer)
|
||||
{
|
||||
UPSCONN_t *ups = (UPSCONN_t *)SSL_RevealPinArg(fd);
|
||||
upslogx(LOG_INFO, "Do not intend to authenticate server %s",
|
||||
ups?ups->host:"<unnamed>");
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus BadCertHandler(UPSCONN_t *arg, PRFileDesc *fd)
|
||||
{
|
||||
HOST_CERT_t* cert;
|
||||
upslogx(LOG_WARNING, "Certificate validation failed for %s",
|
||||
(arg&&arg->host)?arg->host:"<unnamed>");
|
||||
/* BadCertHandler is called when the NSS certificate validation is failed.
|
||||
* If the certificate verification (user conf) is mandatory, reject authentication
|
||||
* else accept it.
|
||||
*/
|
||||
cert = upscli_find_host_cert(arg->host);
|
||||
if (cert != NULL) {
|
||||
return cert->certverify==0 ? SECSuccess : SECFailure;
|
||||
} else {
|
||||
return verify_certificate==0 ? SECSuccess : SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
static SECStatus GetClientAuthData(UPSCONN_t *arg, PRFileDesc *fd,
|
||||
CERTDistNames *caNames, CERTCertificate **pRetCert, SECKEYPrivateKey **pRetKey)
|
||||
{
|
||||
CERTCertificate *cert;
|
||||
SECKEYPrivateKey *privKey;
|
||||
SECStatus status = NSS_GetClientAuthData(arg, fd, caNames, pRetCert, pRetKey);
|
||||
if (status == SECFailure) {
|
||||
if (nsscertname != NULL) {
|
||||
cert = PK11_FindCertFromNickname(nsscertname, NULL);
|
||||
if(cert==NULL) {
|
||||
upslogx(LOG_ERR, "Can not find self-certificate");
|
||||
nss_error("GetClientAuthData / PK11_FindCertFromNickname");
|
||||
}else{
|
||||
privKey = PK11_FindKeyByAnyCert(cert, NULL);
|
||||
if(privKey==NULL){
|
||||
upslogx(LOG_ERR, "Can not find private key related to self-certificate");
|
||||
nss_error("GetClientAuthData / PK11_FindKeyByAnyCert");
|
||||
}else{
|
||||
*pRetCert = cert;
|
||||
*pRetKey = privKey;
|
||||
status = SECSuccess;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
upslogx(LOG_ERR, "Self-certificate name not configured");
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void HandshakeCallback(PRFileDesc *fd, UPSCONN_t *client_data)
|
||||
{
|
||||
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,
|
||||
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
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
SECStatus status;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
|
||||
if (upscli_initialized == 1) {
|
||||
upslogx(LOG_WARNING, "upscli already initialized");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
ssl_method = TLSv1_client_method();
|
||||
|
||||
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 (!certpath) {
|
||||
if (certverify == 1) {
|
||||
upslogx(LOG_ERR, "Can not verify certificate if any is specified");
|
||||
return -1; /* Failed : cert is mandatory but no certfile */
|
||||
}
|
||||
} else {
|
||||
switch(certverify) {
|
||||
|
||||
case 0:
|
||||
ssl_mode = SSL_VERIFY_NONE;
|
||||
break;
|
||||
default:
|
||||
ssl_mode = SSL_VERIFY_PEER;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = SSL_CTX_load_verify_locations(ssl_ctx, NULL, certpath);
|
||||
if (ret != 1) {
|
||||
upslogx(LOG_ERR, "Failed to load certificate from pemfile %s", certpath);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
upslogx(LOG_NOTICE, "Init SSL without certificate database");
|
||||
status = NSS_NoDB_Init(NULL);
|
||||
}
|
||||
if (status != SECSuccess) {
|
||||
upslogx(LOG_ERR, "Can not initialize SSL context");
|
||||
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");
|
||||
nss_error("upscli_init / SSL_OptionSetDefault(SSL_ENABLE_SSL3)");
|
||||
return -1;
|
||||
}
|
||||
status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
|
||||
if (status != SECSuccess) {
|
||||
upslogx(LOG_ERR, "Can not enable TLSv1");
|
||||
nss_error("upscli_init / SSL_OptionSetDefault(SSL_ENABLE_TLS)");
|
||||
return -1;
|
||||
}
|
||||
status = SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, PR_FALSE);
|
||||
if (status != SECSuccess) {
|
||||
upslogx(LOG_ERR, "Can not disable SSLv2 hello compatibility");
|
||||
nss_error("upscli_init / SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO)");
|
||||
return -1;
|
||||
}
|
||||
if (certname) {
|
||||
nsscertname = xstrdup(certname);
|
||||
}
|
||||
if (certpasswd) {
|
||||
nsscertpasswd = xstrdup(certpasswd);
|
||||
}
|
||||
verify_certificate = certverify;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
upscli_initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void upscli_add_host_cert(const char* hostname, const char* certname, int certverify, int forcessl)
|
||||
{
|
||||
#ifdef WITH_NSS
|
||||
HOST_CERT_t* cert = xmalloc(sizeof(HOST_CERT_t));
|
||||
cert->next = first_host_cert;
|
||||
cert->host = xstrdup(hostname);
|
||||
cert->certname = xstrdup(certname);
|
||||
cert->certverify = certverify;
|
||||
cert->forcessl = forcessl;
|
||||
first_host_cert = cert;
|
||||
#endif /* WITH_NSS */
|
||||
}
|
||||
|
||||
static HOST_CERT_t* upscli_find_host_cert(const char* hostname)
|
||||
{
|
||||
#ifdef WITH_NSS
|
||||
HOST_CERT_t* cert = first_host_cert;
|
||||
if (hostname != NULL) {
|
||||
while (cert != NULL) {
|
||||
if (cert->host != NULL && strcmp(cert->host, hostname)==0 ) {
|
||||
return cert;
|
||||
}
|
||||
cert = cert->next;
|
||||
}
|
||||
}
|
||||
#endif /* WITH_NSS */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int upscli_cleanup()
|
||||
{
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ssl_ctx) {
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
ssl_ctx = NULL;
|
||||
}
|
||||
|
||||
#endif /* WITH_OPENSSL */
|
||||
|
||||
#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
|
||||
*/
|
||||
SSL_ClearSessionCache();
|
||||
NSS_Shutdown();
|
||||
PR_Cleanup();
|
||||
/* Called to release memory arena used by NSS/NSPR.
|
||||
* Prevent to show all PL_ArenaAllocate mem alloc as leaks.
|
||||
* https://developer.mozilla.org/en/NSS_Memory_allocation
|
||||
*/
|
||||
PL_ArenaFinish();
|
||||
#endif /* WITH_NSS */
|
||||
|
||||
upscli_initialized = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *upscli_strerror(UPSCONN_t *ups)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WITH_OPENSSL
|
||||
unsigned long err;
|
||||
char sslbuf[UPSCLI_ERRBUF_LEN];
|
||||
#endif
|
||||
|
@ -126,7 +486,7 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
return ups->errbuf;
|
||||
|
||||
case 2: /* SSL error */
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WITH_OPENSSL
|
||||
err = ERR_get_error();
|
||||
if (err) {
|
||||
ERR_error_string(err, sslbuf);
|
||||
|
@ -138,10 +498,18 @@ const char *upscli_strerror(UPSCONN_t *ups)
|
|||
upscli_errlist[ups->upserror].str,
|
||||
"peer disconnected");
|
||||
}
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
if (PR_GetErrorTextLength() < UPSCLI_ERRBUF_LEN) {
|
||||
PR_GetErrorText(ups->errbuf);
|
||||
} else {
|
||||
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,
|
||||
"SSL error, but SSL wasn't enabled at compile-time");
|
||||
#endif /* HAVE_SSL */
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
return ups->errbuf;
|
||||
|
||||
case 3: /* parsing (parseconf) error */
|
||||
|
@ -162,7 +530,7 @@ 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 select_read(const int fd, void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
static int upscli_select_read(const int fd, void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
{
|
||||
int ret;
|
||||
fd_set fds;
|
||||
|
@ -188,9 +556,13 @@ static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WITH_SSL
|
||||
if (ups->ssl) {
|
||||
#ifdef WITH_OPENSSL
|
||||
ret = SSL_read(ups->ssl, buf, buflen);
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
ret = PR_Read(ups->ssl, buf, buflen);
|
||||
#endif /* WITH_OPENSSL | WITH_NSS*/
|
||||
|
||||
if (ret < 1) {
|
||||
ups->upserror = UPSCLI_ERR_SSLERR;
|
||||
|
@ -200,7 +572,7 @@ static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = select_read(ups->fd, buf, buflen, 5, 0);
|
||||
ret = upscli_select_read(ups->fd, buf, buflen, 5, 0);
|
||||
|
||||
/* error reading data, server disconnected? */
|
||||
if (ret < 0) {
|
||||
|
@ -219,7 +591,7 @@ static int net_read(UPSCONN_t *ups, char *buf, size_t buflen)
|
|||
/* 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 select_write(const int fd, const void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
static int upscli_select_write(const int fd, const void *buf, const size_t buflen, const long d_sec, const long d_usec)
|
||||
{
|
||||
int ret;
|
||||
fd_set fds;
|
||||
|
@ -245,9 +617,13 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
{
|
||||
int ret;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WITH_SSL
|
||||
if (ups->ssl) {
|
||||
#ifdef WITH_OPENSSL
|
||||
ret = SSL_write(ups->ssl, buf, buflen);
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
ret = PR_Write(ups->ssl, buf, buflen);
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
if (ret < 1) {
|
||||
ups->upserror = UPSCLI_ERR_SSLERR;
|
||||
|
@ -257,7 +633,7 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
}
|
||||
#endif
|
||||
|
||||
ret = select_write(ups->fd, buf, buflen, 0, 0);
|
||||
ret = upscli_select_write(ups->fd, buf, buflen, 0, 0);
|
||||
|
||||
/* error writing data, server disconnected? */
|
||||
if (ret < 0) {
|
||||
|
@ -273,39 +649,34 @@ static int net_write(UPSCONN_t *ups, const char *buf, size_t buflen)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* stub first */
|
||||
#ifndef HAVE_SSL
|
||||
static int upscli_sslinit(UPSCONN_t *ups)
|
||||
|
||||
#ifdef WITH_SSL
|
||||
|
||||
/*
|
||||
* 1 : OK
|
||||
* -1 : ERROR
|
||||
* 0 : SSL NOT SUPPORTED
|
||||
*/
|
||||
static int upscli_sslinit(UPSCONN_t *ups, int verifycert)
|
||||
{
|
||||
return 0; /* not supported */
|
||||
}
|
||||
|
||||
int upscli_sslcert(UPSCONN_t *ups, const char *dir, const char *file, int verify)
|
||||
{
|
||||
if (!ups) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if forcing the verification, this fails since we have no SSL */
|
||||
if (verify == 1) {
|
||||
ups->upserror = UPSCLI_ERR_SSLFAIL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* not supported */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int upscli_sslinit(UPSCONN_t *ups)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
const SSL_METHOD *ssl_method;
|
||||
#else
|
||||
SSL_METHOD *ssl_method;
|
||||
#endif
|
||||
#ifdef WITH_OPENSSL
|
||||
int res;
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
SECStatus status;
|
||||
PRFileDesc *socket;
|
||||
HOST_CERT_t *cert;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
char buf[UPSCLI_NETBUF_LEN];
|
||||
|
||||
/* Intend to initialize upscli with no ssl db if not already done.
|
||||
* Compatibility stuff for old clients which do not initialize them.
|
||||
*/
|
||||
if (upscli_initialized==0) {
|
||||
upsdebugx(3, "upscli not initialized, "
|
||||
"force initialisation without SSL configuration");
|
||||
upscli_init(0, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* see if upsd even talks SSL/TLS */
|
||||
snprintf(buf, sizeof(buf), "STARTTLS\n");
|
||||
|
||||
|
@ -322,84 +693,150 @@ static int upscli_sslinit(UPSCONN_t *ups)
|
|||
}
|
||||
|
||||
/* upsd is happy, so let's crank up the client */
|
||||
|
||||
#ifdef WITH_OPENSSL
|
||||
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
ssl_method = TLSv1_client_method();
|
||||
|
||||
if (!ssl_method) {
|
||||
if (!ssl_ctx) {
|
||||
upsdebugx(3, "SSL context is not available");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ups->ssl_ctx = SSL_CTX_new(ssl_method);
|
||||
|
||||
if (!ups->ssl_ctx) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ups->ssl = SSL_new(ups->ssl_ctx);
|
||||
|
||||
ups->ssl = SSL_new(ssl_ctx);
|
||||
if (!ups->ssl) {
|
||||
upsdebugx(3, "Can not create SSL socket");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (SSL_set_fd(ups->ssl, ups->fd) != 1) {
|
||||
upsdebugx(3, "Can not bind file descriptor to SSL socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_set_connect_state(ups->ssl);
|
||||
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* set the paths for the certs to verify the server */
|
||||
int upscli_sslcert(UPSCONN_t *ups, const char *file, const char *path, int verify)
|
||||
{
|
||||
int ret, ssl_mode = SSL_VERIFY_NONE;
|
||||
|
||||
if (!ups) {
|
||||
return -1;
|
||||
if (verifycert != 0) {
|
||||
SSL_set_verify(ups->ssl, SSL_VERIFY_PEER, NULL);
|
||||
} else {
|
||||
SSL_set_verify(ups->ssl, SSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
|
||||
if (!ups->ssl_ctx) {
|
||||
ups->upserror = UPSCLI_ERR_INVALIDARG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(verify) {
|
||||
|
||||
case 0:
|
||||
ssl_mode = SSL_VERIFY_NONE;
|
||||
break;
|
||||
res = SSL_connect(ups->ssl);
|
||||
switch(res)
|
||||
{
|
||||
case 1:
|
||||
ssl_mode = SSL_VERIFY_PEER;
|
||||
upsdebugx(3, "SSL connected");
|
||||
break;
|
||||
case 0:
|
||||
upslog_with_errno(1, "SSL_connect do not accept handshake.");
|
||||
ssl_error(ups->ssl, res);
|
||||
return -1;
|
||||
default:
|
||||
ups->upserror = UPSCLI_ERR_INVALIDARG;
|
||||
upslog_with_errno(1, "Unknown return value from SSL_connect %d", res);
|
||||
ssl_error(ups->ssl, res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SSL_CTX_load_verify_locations(ups->ssl_ctx, file, path);
|
||||
|
||||
if (ret != 1) {
|
||||
ups->upserror = UPSCLI_ERR_SSLERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSL_set_verify(ups->ssl, ssl_mode, NULL);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
|
||||
socket = PR_ImportTCPSocket(ups->fd);
|
||||
if (socket == NULL){
|
||||
nss_error("upscli_sslinit / PR_ImportTCPSocket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ups->ssl = SSL_ImportFD(NULL, socket);
|
||||
if (ups->ssl == NULL){
|
||||
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());
|
||||
} else {
|
||||
status = SSL_AuthCertificateHook(ups->ssl,
|
||||
(SSLAuthCertificate)AuthCertificateDontVerify, CERT_GetDefaultCertDB());
|
||||
}
|
||||
if (status != SECSuccess) {
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cert = upscli_find_host_cert(ups->host);
|
||||
if (cert != NULL && cert->certname != NULL) {
|
||||
upslogx(LOG_INFO, "Connecting in SSL to '%s' and look at certificate called '%s'",
|
||||
ups->host, cert->certname);
|
||||
status = SSL_SetURL(ups->ssl, cert->certname);
|
||||
} else {
|
||||
upslogx(LOG_NOTICE, "Connecting in SSL to '%s' (no certificate name specified)", ups->host);
|
||||
status = SSL_SetURL(ups->ssl, ups->host);
|
||||
}
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_SetURL");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = SSL_ResetHandshake(ups->ssl, PR_FALSE);
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_ResetHandshake");
|
||||
ups->ssl = NULL;
|
||||
/* EKI wtf unimport or free the socket ? */
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = SSL_ForceHandshake(ups->ssl);
|
||||
if (status != SECSuccess) {
|
||||
nss_error("upscli_sslinit / SSL_ForceHandshake");
|
||||
ups->ssl = NULL;
|
||||
/* EKI wtf unimport or free the socket ? */
|
||||
/* TODO : Close the connection. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSL */
|
||||
#else /* WITH_SSL */
|
||||
|
||||
static int upscli_sslinit(UPSCONN_t *ups, int 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 sock_fd;
|
||||
int sock_fd;
|
||||
struct addrinfo hints, *res, *ai;
|
||||
char sport[NI_MAXSERV];
|
||||
int v;
|
||||
int v, certverify, tryssl, forcessl, ret;
|
||||
HOST_CERT_t* hostcert;
|
||||
fd_set wfds;
|
||||
int error;
|
||||
socklen_t error_size;
|
||||
|
@ -552,22 +989,46 @@ int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,stru
|
|||
|
||||
ups->port = port;
|
||||
|
||||
if (flags & UPSCLI_CONN_TRYSSL) {
|
||||
upscli_sslinit(ups);
|
||||
|
||||
/* see if something made us die inside sslinit */
|
||||
if (ups->upserror != 0) {
|
||||
hostcert = upscli_find_host_cert(host);
|
||||
|
||||
if (hostcert != NULL) {
|
||||
/* An host security rule is specified. */
|
||||
certverify = hostcert->certverify;
|
||||
forcessl = hostcert->forcessl;
|
||||
} else {
|
||||
certverify = (flags & UPSCLI_CONN_CERTVERIF) != 0 ? 1 : 0;
|
||||
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);
|
||||
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);
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
} else if (tryssl && ret == 0) {
|
||||
if (certverify != 0) {
|
||||
upslogx(LOG_NOTICE, "Can not connect to %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);
|
||||
} else {
|
||||
upslogx(LOG_INFO, "Connected to %s in SSL", host);
|
||||
if (certverify == 0) {
|
||||
/* you REALLY should set CERTVERIFY to 1 if using SSL... */
|
||||
upslogx(LOG_WARNING, "Certificate verification is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & UPSCLI_CONN_REQSSL) && (upscli_sslinit(ups) != 1)) {
|
||||
ups->upserror = UPSCLI_ERR_SSLFAIL;
|
||||
upscli_disconnect(ups);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1044,18 +1505,19 @@ int upscli_disconnect(UPSCONN_t *ups)
|
|||
|
||||
net_write(ups, "LOGOUT\n", 7);
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef WITH_OPENSSL
|
||||
if (ups->ssl) {
|
||||
SSL_shutdown(ups->ssl);
|
||||
SSL_free(ups->ssl);
|
||||
ups->ssl = NULL;
|
||||
}
|
||||
|
||||
if (ups->ssl_ctx) {
|
||||
SSL_CTX_free(ups->ssl_ctx);
|
||||
ups->ssl_ctx = NULL;
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
if (ups->ssl) {
|
||||
PR_Shutdown(ups->ssl, PR_SHUTDOWN_BOTH);
|
||||
PR_Close(ups->ssl);
|
||||
ups->ssl = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
shutdown(ups->fd, shutdown_how);
|
||||
|
||||
|
@ -1101,9 +1563,11 @@ int upscli_ssl(UPSCONN_t *ups)
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WITH_SSL
|
||||
if (ups->ssl) {
|
||||
return 1;
|
||||
}
|
||||
#endif /* WITH_SSL */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,13 @@
|
|||
#ifndef UPSCLIENT_H_SEEN
|
||||
#define UPSCLIENT_H_SEEN
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
#ifdef WITH_OPENSSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
#include <nss.h>
|
||||
#include <ssl.h>
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
|
@ -49,13 +52,13 @@ typedef struct {
|
|||
|
||||
char errbuf[UPSCLI_ERRBUF_LEN];
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
SSL_CTX *ssl_ctx;
|
||||
#ifdef WITH_OPENSSL
|
||||
SSL *ssl;
|
||||
#else
|
||||
void *ssl_ctx;
|
||||
void *ssl;
|
||||
#endif
|
||||
#elif defined(WITH_NSS) /* WITH_OPENSSL */
|
||||
PRFileDesc *ssl;
|
||||
#else /* WITH_OPENSSL | WITH_NSS */
|
||||
void *ssl;
|
||||
#endif /* WITH_OPENSSL | WITH_NSS */
|
||||
|
||||
char readbuf[64];
|
||||
size_t readlen;
|
||||
|
@ -65,10 +68,14 @@ typedef struct {
|
|||
|
||||
const char *upscli_strerror(UPSCONN_t *ups);
|
||||
|
||||
int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags, struct timeval *tv);
|
||||
int upscli_init(int certverify, const char *certpath, const char *certname, const char *certpasswd);
|
||||
int upscli_cleanup();
|
||||
|
||||
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);
|
||||
|
||||
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,
|
||||
|
@ -88,8 +95,6 @@ int upscli_splitname(const char *buf, char **upsname, char **hostname,
|
|||
|
||||
int upscli_splitaddr(const char *buf, char **hostname, int *port);
|
||||
|
||||
int upscli_sslcert(UPSCONN_t *ups, const char *file, const char *path, int verify);
|
||||
|
||||
int upscli_disconnect(UPSCONN_t *ups);
|
||||
|
||||
/* these functions return elements from UPSCONN_t to avoid direct references */
|
||||
|
@ -156,10 +161,11 @@ int upscli_ssl(UPSCONN_t *ups);
|
|||
|
||||
/* flags for use with upscli_connect */
|
||||
|
||||
#define UPSCLI_CONN_TRYSSL 0x0001 /* try SSL, OK if not supported */
|
||||
#define UPSCLI_CONN_REQSSL 0x0002 /* try SSL, fail if not supported */
|
||||
#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */
|
||||
#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */
|
||||
#define UPSCLI_CONN_TRYSSL 0x0001 /* try SSL, OK if not supported */
|
||||
#define UPSCLI_CONN_REQSSL 0x0002 /* try SSL, fail if not supported */
|
||||
#define UPSCLI_CONN_INET 0x0004 /* IPv4 only */
|
||||
#define UPSCLI_CONN_INET6 0x0008 /* IPv6 only */
|
||||
#define UPSCLI_CONN_CERTVERIF 0x0010 /* Verify certificates for SSL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_platform.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
|
@ -316,3 +317,11 @@ int main(int argc, char **argv)
|
|||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||
#if (defined NUT_PLATFORM_AIX)
|
||||
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||
}
|
||||
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
struct {
|
||||
char *name;
|
||||
int val; /* hex digits, ala HTML */
|
||||
|
@ -58,3 +64,10 @@ typedef struct {
|
|||
} imgvar_t;
|
||||
|
||||
extern imgvar_t imgvar[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_platform.h"
|
||||
#include "upsclient.h"
|
||||
|
||||
#include "config.h"
|
||||
|
@ -528,3 +529,11 @@ int main(int argc, char **argv)
|
|||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||
#if (defined NUT_PLATFORM_AIX)
|
||||
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||
}
|
||||
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/* upslog.h - table of functions for handling various logging functions */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
/* function list */
|
||||
typedef struct flist_s {
|
||||
void (*fptr)(const char *arg);
|
||||
|
@ -27,3 +33,10 @@ struct {
|
|||
{ "ETIME", do_etime },
|
||||
{ NULL, (void(*)())(NULL) }
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ static char *run_as_user = NULL;
|
|||
|
||||
/* SSL details - where to find certs, whether to use them */
|
||||
static char *certpath = NULL;
|
||||
static char *certname = NULL;
|
||||
static char *certpasswd = NULL;
|
||||
static int certverify = 0; /* don't verify by default */
|
||||
static int forcessl = 0; /* don't require ssl by default */
|
||||
|
||||
|
@ -1178,10 +1180,25 @@ static int parse_conf_arg(int numargs, char **arg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* CERTIDENT <name> <passwd> */
|
||||
if (!strcmp(arg[0], "CERTIDENT")) {
|
||||
free(certname);
|
||||
certname = xstrdup(arg[1]);
|
||||
free(certpasswd);
|
||||
certpasswd = xstrdup(arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* using up to arg[4] below */
|
||||
if (numargs < 5)
|
||||
return 0;
|
||||
|
||||
/* CERTHOST <hostname> <certname> (0|1) (0|1) */
|
||||
if (!strcmp(arg[0], "CERTHOST")) {
|
||||
upscli_add_host_cert(arg[1], arg[2], atoi(arg[3]), atoi(arg[4]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(arg[0], "MONITOR")) {
|
||||
|
||||
/* original style: no username (only 5 args) */
|
||||
|
@ -1300,6 +1317,8 @@ static void upsmon_cleanup(void)
|
|||
for (i = 0; notifylist[i].name != NULL; i++) {
|
||||
free(notifylist[i].msg);
|
||||
}
|
||||
|
||||
upscli_cleanup();
|
||||
}
|
||||
|
||||
static void user_fsd(int sig)
|
||||
|
@ -1362,51 +1381,6 @@ static void update_crittimer(utype_t *ups)
|
|||
/* fallthrough: let the timer age */
|
||||
}
|
||||
|
||||
static int try_ssl(utype_t *ups)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* if not doing SSL, we're done */
|
||||
if (!upscli_ssl(&ups->conn))
|
||||
return 1;
|
||||
|
||||
if (!certpath) {
|
||||
if (certverify == 1) {
|
||||
upslogx(LOG_ERR, "Configuration error: "
|
||||
"CERTVERIFY is set, but CERTPATH isn't");
|
||||
upslogx(LOG_ERR, "UPS [%s]: Connection impossible, "
|
||||
"dropping link", ups->sys);
|
||||
|
||||
ups_is_gone(ups);
|
||||
drop_connection(ups);
|
||||
|
||||
return 0; /* failed */
|
||||
}
|
||||
|
||||
/* certverify is 0, so just warn them and return */
|
||||
upslogx(LOG_WARNING, "Certificate verification is disabled");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* you REALLY should set CERTVERIFY to 1 if using SSL... */
|
||||
if (certverify == 0)
|
||||
upslogx(LOG_WARNING, "Certificate verification is disabled");
|
||||
|
||||
ret = upscli_sslcert(&ups->conn, NULL, certpath, certverify);
|
||||
|
||||
if (ret < 0) {
|
||||
upslogx(LOG_ERR, "UPS [%s]: SSL certificate set failed: %s",
|
||||
ups->sys, upscli_strerror(&ups->conn));
|
||||
|
||||
ups_is_gone(ups);
|
||||
drop_connection(ups);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* handle connecting to upsd, plus get SSL going too if possible */
|
||||
static int try_connect(utype_t *ups)
|
||||
{
|
||||
|
@ -1428,21 +1402,33 @@ static int try_connect(utype_t *ups)
|
|||
if (opt_af == AF_INET6)
|
||||
flags |= UPSCLI_CONN_INET6;
|
||||
|
||||
if (!certpath) {
|
||||
if (certverify == 1) {
|
||||
upslogx(LOG_ERR, "Configuration error: "
|
||||
"CERTVERIFY is set, but CERTPATH isn't");
|
||||
upslogx(LOG_ERR, "UPS [%s]: Connection impossible, "
|
||||
"dropping link", ups->sys);
|
||||
|
||||
ups_is_gone(ups);
|
||||
drop_connection(ups);
|
||||
|
||||
return 0; /* failed */
|
||||
}
|
||||
}
|
||||
|
||||
if (certverify == 1) {
|
||||
flags |= UPSCLI_CONN_CERTVERIF;
|
||||
}
|
||||
|
||||
ret = upscli_connect(&ups->conn, ups->hostname, ups->port, flags);
|
||||
|
||||
if (ret < 0) {
|
||||
upslogx(LOG_ERR, "UPS [%s]: connect failed: %s",
|
||||
ups->sys, upscli_strerror(&ups->conn));
|
||||
|
||||
ups_is_gone(ups);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = try_ssl(ups);
|
||||
|
||||
if (ret == 0)
|
||||
return 0; /* something broke while trying SSL */
|
||||
|
||||
/* we're definitely connected now */
|
||||
setflag(&ups->status, ST_CONNECTED);
|
||||
|
||||
|
@ -1998,7 +1984,11 @@ int main(int argc, char *argv[])
|
|||
|
||||
writepid(prog);
|
||||
}
|
||||
|
||||
|
||||
if (upscli_init(certverify, certpath, certname, certpasswd) < 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* prep our signal handlers */
|
||||
setup_signals();
|
||||
|
||||
|
|
|
@ -30,6 +30,12 @@
|
|||
/* required contents of flag file */
|
||||
#define SDMAGIC "upsmon-shutdown-file"
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
/* UPS tracking structure */
|
||||
|
||||
typedef struct {
|
||||
|
@ -110,3 +116,9 @@ struct {
|
|||
/* various constants */
|
||||
|
||||
#define NET_TIMEOUT 10 /* wait 10 seconds max for upsd to respond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "nut_platform.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include <netdb.h>
|
||||
|
@ -202,7 +203,7 @@ static const char *get_data(const char *type, const char *varname)
|
|||
return answer[3];
|
||||
}
|
||||
|
||||
static void do_string(const char *varname)
|
||||
static void do_string(const char *varname, const int len)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
|
@ -213,6 +214,7 @@ static void do_string(const char *varname)
|
|||
}
|
||||
|
||||
printf("Type: STRING\n");
|
||||
printf("Maximum length: %d\n", len);
|
||||
printf("Value: %s\n", val);
|
||||
}
|
||||
|
||||
|
@ -355,8 +357,13 @@ static void do_type(const char *varname)
|
|||
}
|
||||
|
||||
if (!strncasecmp(answer[i], "STRING:", 7)) {
|
||||
do_string(varname);
|
||||
|
||||
char *len = answer[i] + 7;
|
||||
int length = strtol(len, NULL, 10);
|
||||
|
||||
do_string(varname, length);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/* ignore this one */
|
||||
|
@ -518,3 +525,11 @@ int main(int argc, char **argv)
|
|||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/* Formal do_upsconf_args implementation to satisfy linker on AIX */
|
||||
#if (defined NUT_PLATFORM_AIX)
|
||||
void do_upsconf_args(char *upsname, char *var, char *val) {
|
||||
fatalx(EXIT_FAILURE, "INTERNAL ERROR: formal do_upsconf_args called");
|
||||
}
|
||||
#endif /* end of #if (defined NUT_PLATFORM_AIX) */
|
||||
|
|
|
@ -6,9 +6,22 @@
|
|||
#define SERIALIZE_SET 2
|
||||
#define SERIALIZE_WAIT 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
/* track client connections */
|
||||
typedef struct conn_s {
|
||||
int fd;
|
||||
PCONF_CTX_t ctx;
|
||||
struct conn_s *next;
|
||||
} conn_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,8 +17,21 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
extern "C" {
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char *sys;
|
||||
char *desc;
|
||||
void *next;
|
||||
} ulist_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* *INDENT-OFF* */
|
||||
}
|
||||
/* *INDENT-ON* */
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue