Imported Upstream version 2.4.3
This commit is contained in:
commit
26fb71b504
446 changed files with 148951 additions and 0 deletions
30
server/Makefile.am
Normal file
30
server/Makefile.am
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Network UPS Tools: server
|
||||
|
||||
# Avoid per-target CFLAGS, because this will prevent re-use of object
|
||||
# files. In any case, CFLAGS are only -I options, so there is no harm,
|
||||
# but only add them if we really use the target.
|
||||
AM_CFLAGS = -I$(top_srcdir)/include
|
||||
if WITH_WRAP
|
||||
AM_CFLAGS += $(LIBWRAP_CFLAGS)
|
||||
endif
|
||||
if WITH_SSL
|
||||
AM_CFLAGS += $(LIBSSL_CFLAGS)
|
||||
endif
|
||||
LDADD = ../common/libcommon.a ../common/libparseconf.la $(NETLIBS)
|
||||
if WITH_WRAP
|
||||
LDADD += $(LIBWRAP_LDFLAGS)
|
||||
endif
|
||||
if WITH_SSL
|
||||
LDADD += $(LIBSSL_LDFLAGS)
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = upsd
|
||||
EXTRA_PROGRAMS = sockdebug
|
||||
|
||||
upsd_SOURCES = upsd.c user.c conf.c ssl.c sstate.c desc.c \
|
||||
netget.c netmisc.c netlist.c netuser.c netset.c netinstcmd.c \
|
||||
conf.h ctype.h desc.h netcmds.h neterr.h netget.h netinstcmd.h \
|
||||
netlist.h netmisc.h netset.h netuser.h ssl.h sstate.h stype.h upsd.h \
|
||||
upstype.h user-data.h user.h
|
||||
|
||||
sockdebug_SOURCES = sockdebug.c
|
||||
615
server/Makefile.in
Normal file
615
server/Makefile.in
Normal file
|
|
@ -0,0 +1,615 @@
|
|||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Network UPS Tools: server
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
@WITH_WRAP_TRUE@am__append_1 = $(LIBWRAP_CFLAGS)
|
||||
@WITH_SSL_TRUE@am__append_2 = $(LIBSSL_CFLAGS)
|
||||
@WITH_WRAP_TRUE@am__append_3 = $(LIBWRAP_LDFLAGS)
|
||||
@WITH_SSL_TRUE@am__append_4 = $(LIBSSL_LDFLAGS)
|
||||
sbin_PROGRAMS = upsd$(EXEEXT)
|
||||
EXTRA_PROGRAMS = sockdebug$(EXEEXT)
|
||||
subdir = server
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_create_stdint_h.m4 \
|
||||
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/m4/nut_arg_with.m4 \
|
||||
$(top_srcdir)/m4/nut_check_ipv6.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libgd.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libhal.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libneon.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libpowerman.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libssl.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libusb.m4 \
|
||||
$(top_srcdir)/m4/nut_check_libwrap.m4 \
|
||||
$(top_srcdir)/m4/nut_check_os.m4 \
|
||||
$(top_srcdir)/m4/nut_report_feature.m4 \
|
||||
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
|
||||
$(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = $(top_builddir)/include/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(sbindir)"
|
||||
PROGRAMS = $(sbin_PROGRAMS)
|
||||
am_sockdebug_OBJECTS = sockdebug.$(OBJEXT)
|
||||
sockdebug_OBJECTS = $(am_sockdebug_OBJECTS)
|
||||
sockdebug_LDADD = $(LDADD)
|
||||
am__DEPENDENCIES_1 =
|
||||
@WITH_WRAP_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
|
||||
@WITH_SSL_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1)
|
||||
sockdebug_DEPENDENCIES = ../common/libcommon.a \
|
||||
../common/libparseconf.la $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3)
|
||||
am_upsd_OBJECTS = upsd.$(OBJEXT) user.$(OBJEXT) conf.$(OBJEXT) \
|
||||
ssl.$(OBJEXT) sstate.$(OBJEXT) desc.$(OBJEXT) netget.$(OBJEXT) \
|
||||
netmisc.$(OBJEXT) netlist.$(OBJEXT) netuser.$(OBJEXT) \
|
||||
netset.$(OBJEXT) netinstcmd.$(OBJEXT)
|
||||
upsd_OBJECTS = $(am_upsd_OBJECTS)
|
||||
upsd_LDADD = $(LDADD)
|
||||
upsd_DEPENDENCIES = ../common/libcommon.a ../common/libparseconf.la \
|
||||
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
|
||||
$(am__DEPENDENCIES_3)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(sockdebug_SOURCES) $(upsd_SOURCES)
|
||||
DIST_SOURCES = $(sockdebug_SOURCES) $(upsd_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
BINDIR = @BINDIR@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CONFPATH = @CONFPATH@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
|
||||
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
|
||||
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
HAL_CALLOUTS_PATH = @HAL_CALLOUTS_PATH@
|
||||
HAL_DEVICE_MATCH_KEY = @HAL_DEVICE_MATCH_KEY@
|
||||
HAL_FDI_PATH = @HAL_FDI_PATH@
|
||||
HAL_USER = @HAL_USER@
|
||||
HAVE_GLIB_2_14 = @HAVE_GLIB_2_14@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBGD_CFLAGS = @LIBGD_CFLAGS@
|
||||
LIBGD_LDFLAGS = @LIBGD_LDFLAGS@
|
||||
LIBHAL_CFLAGS = @LIBHAL_CFLAGS@
|
||||
LIBHAL_LDFLAGS = @LIBHAL_LDFLAGS@
|
||||
LIBNEON_CFLAGS = @LIBNEON_CFLAGS@
|
||||
LIBNEON_LDFLAGS = @LIBNEON_LDFLAGS@
|
||||
LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@
|
||||
LIBNETSNMP_LDFLAGS = @LIBNETSNMP_LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBPOWERMAN_CFLAGS = @LIBPOWERMAN_CFLAGS@
|
||||
LIBPOWERMAN_LDFLAGS = @LIBPOWERMAN_LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
LIBSSL_CFLAGS = @LIBSSL_CFLAGS@
|
||||
LIBSSL_LDFLAGS = @LIBSSL_LDFLAGS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
|
||||
LIBUSB_LDFLAGS = @LIBUSB_LDFLAGS@
|
||||
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
|
||||
LIBWRAP_LDFLAGS = @LIBWRAP_LDFLAGS@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NETLIBS = @NETLIBS@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OS_NAME = @OS_NAME@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
RUN_AS_GROUP = @RUN_AS_GROUP@
|
||||
RUN_AS_USER = @RUN_AS_USER@
|
||||
SED = @SED@
|
||||
SERLIBS = @SERLIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STATEPATH = @STATEPATH@
|
||||
STRIP = @STRIP@
|
||||
SUN_LIBUSB = @SUN_LIBUSB@
|
||||
VERSION = @VERSION@
|
||||
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
cgiexecdir = @cgiexecdir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
driverexecdir = @driverexecdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
hotplugdir = @hotplugdir@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_ECHO = @lt_ECHO@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
udevdir = @udevdir@
|
||||
|
||||
# Avoid per-target CFLAGS, because this will prevent re-use of object
|
||||
# files. In any case, CFLAGS are only -I options, so there is no harm,
|
||||
# but only add them if we really use the target.
|
||||
AM_CFLAGS = -I$(top_srcdir)/include $(am__append_1) $(am__append_2)
|
||||
LDADD = ../common/libcommon.a ../common/libparseconf.la $(NETLIBS) \
|
||||
$(am__append_3) $(am__append_4)
|
||||
upsd_SOURCES = upsd.c user.c conf.c ssl.c sstate.c desc.c \
|
||||
netget.c netmisc.c netlist.c netuser.c netset.c netinstcmd.c \
|
||||
conf.h ctype.h desc.h netcmds.h neterr.h netget.h netinstcmd.h \
|
||||
netlist.h netmisc.h netset.h netuser.h ssl.h sstate.h stype.h upsd.h \
|
||||
upstype.h user-data.h user.h
|
||||
|
||||
sockdebug_SOURCES = sockdebug.c
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu server/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu server/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-sbinPROGRAMS: $(sbin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed 's/$(EXEEXT)$$//' | \
|
||||
while read p p1; do if test -f $$p || test -f $$p1; \
|
||||
then echo "$$p"; echo "$$p"; else :; fi; \
|
||||
done | \
|
||||
sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
|
||||
-e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
|
||||
sed 'N;N;N;s,\n, ,g' | \
|
||||
$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
|
||||
{ d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
|
||||
if ($$2 == $$4) files[d] = files[d] " " $$1; \
|
||||
else { print "f", $$3 "/" $$4, $$1; } } \
|
||||
END { for (d in files) print "f", d, files[d] }' | \
|
||||
while read type dir files; do \
|
||||
if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
|
||||
} \
|
||||
; done
|
||||
|
||||
uninstall-sbinPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
|
||||
files=`for p in $$list; do echo "$$p"; done | \
|
||||
sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
|
||||
-e 's/$$/$(EXEEXT)/' `; \
|
||||
test -n "$$list" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(sbindir)" && rm -f $$files
|
||||
|
||||
clean-sbinPROGRAMS:
|
||||
@list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
sockdebug$(EXEEXT): $(sockdebug_OBJECTS) $(sockdebug_DEPENDENCIES)
|
||||
@rm -f sockdebug$(EXEEXT)
|
||||
$(LINK) $(sockdebug_OBJECTS) $(sockdebug_LDADD) $(LIBS)
|
||||
upsd$(EXEEXT): $(upsd_OBJECTS) $(upsd_DEPENDENCIES)
|
||||
@rm -f upsd$(EXEEXT)
|
||||
$(LINK) $(upsd_OBJECTS) $(upsd_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/desc.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netget.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netinstcmd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netlist.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netmisc.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netset.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netuser.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockdebug.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sstate.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(sbindir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-sbinPROGRAMS
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-sbinPROGRAMS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-sbinPROGRAMS ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-sbinPROGRAMS install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-sbinPROGRAMS
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
489
server/conf.c
Normal file
489
server/conf.c
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
/* conf.c - configuration handlers for upsd
|
||||
|
||||
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "upsd.h"
|
||||
#include "conf.h"
|
||||
#include "upsconf.h"
|
||||
#include "sstate.h"
|
||||
#include "user.h"
|
||||
#include "ssl.h"
|
||||
|
||||
ups_t *upstable = NULL;
|
||||
int num_ups = 0;
|
||||
|
||||
/* add another UPS for monitoring from ups.conf */
|
||||
static void ups_create(const char *fn, const char *name, const char *desc)
|
||||
{
|
||||
upstype_t *temp, *last;
|
||||
|
||||
temp = last = firstups;
|
||||
|
||||
/* find end of linked list */
|
||||
while (temp != NULL) {
|
||||
last = temp;
|
||||
|
||||
if (!strcasecmp(temp->name, name)) {
|
||||
upslogx(LOG_ERR, "UPS name [%s] is already in use!",
|
||||
name);
|
||||
return;
|
||||
}
|
||||
|
||||
temp = temp->next;
|
||||
}
|
||||
|
||||
/* grab some memory and add the info */
|
||||
temp = xmalloc(sizeof(upstype_t));
|
||||
|
||||
temp->name = xstrdup(name);
|
||||
temp->fn = xstrdup(fn);
|
||||
|
||||
if (desc)
|
||||
temp->desc = xstrdup(desc);
|
||||
else
|
||||
temp->desc = NULL;
|
||||
|
||||
temp->stale = 1;
|
||||
|
||||
temp->numlogins = 0;
|
||||
temp->fsd = 0;
|
||||
temp->retain = 1;
|
||||
temp->next = NULL;
|
||||
|
||||
temp->dumpdone = 0;
|
||||
temp->data_ok = 0;
|
||||
|
||||
/* preload this to the current time to avoid false staleness */
|
||||
time(&temp->last_heard);
|
||||
|
||||
temp->last_ping = 0;
|
||||
temp->last_connfail = 0;
|
||||
temp->inforoot = NULL;
|
||||
temp->cmdlist = NULL;
|
||||
|
||||
if (last == NULL)
|
||||
firstups = temp;
|
||||
else
|
||||
last->next = temp;
|
||||
|
||||
temp->sock_fd = sstate_connect(temp);
|
||||
|
||||
num_ups++;
|
||||
}
|
||||
|
||||
/* change the configuration of an existing UPS (used during reloads) */
|
||||
static void ups_update(const char *fn, const char *name, const char *desc)
|
||||
{
|
||||
upstype_t *temp;
|
||||
|
||||
temp = get_ups_ptr(name);
|
||||
|
||||
if (!temp) {
|
||||
upslogx(LOG_ERR, "UPS %s disappeared during reload", name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* paranoia */
|
||||
if (!temp->fn) {
|
||||
upslogx(LOG_ERR, "UPS %s had a NULL filename!", name);
|
||||
|
||||
/* let's give it something quick to use later */
|
||||
temp->fn = xstrdup("");
|
||||
}
|
||||
|
||||
/* when the filename changes, force a reconnect */
|
||||
if (strcmp(temp->fn, fn) != 0) {
|
||||
|
||||
upslogx(LOG_NOTICE, "Redefined UPS [%s]", name);
|
||||
|
||||
/* release all data */
|
||||
sstate_infofree(temp);
|
||||
sstate_cmdfree(temp);
|
||||
pconf_finish(&temp->sock_ctx);
|
||||
|
||||
close(temp->sock_fd);
|
||||
temp->sock_fd = -1;
|
||||
temp->dumpdone = 0;
|
||||
|
||||
/* now redefine the filename and wrap up */
|
||||
free(temp->fn);
|
||||
temp->fn = xstrdup(fn);
|
||||
}
|
||||
|
||||
/* update the description */
|
||||
|
||||
free(temp->desc);
|
||||
|
||||
if (desc)
|
||||
temp->desc = xstrdup(desc);
|
||||
else
|
||||
temp->desc = NULL;
|
||||
|
||||
/* always set this on reload */
|
||||
temp->retain = 1;
|
||||
}
|
||||
|
||||
/* return 1 if usable, 0 if not */
|
||||
static int parse_upsd_conf_args(int numargs, char **arg)
|
||||
{
|
||||
/* everything below here uses up through arg[1] */
|
||||
if (numargs < 2)
|
||||
return 0;
|
||||
|
||||
/* MAXAGE <seconds> */
|
||||
if (!strcmp(arg[0], "MAXAGE")) {
|
||||
maxage = atoi(arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* MAXCONN <connections> */
|
||||
if (!strcmp(arg[0], "MAXCONN")) {
|
||||
maxconn = atoi(arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* STATEPATH <dir> */
|
||||
if (!strcmp(arg[0], "STATEPATH")) {
|
||||
free(statepath);
|
||||
statepath = xstrdup(arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* DATAPATH <dir> */
|
||||
if (!strcmp(arg[0], "DATAPATH")) {
|
||||
free(datapath);
|
||||
datapath = xstrdup(arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* CERTFILE <dir> */
|
||||
if (!strcmp(arg[0], "CERTFILE")) {
|
||||
free(certfile);
|
||||
certfile = xstrdup(arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ACCEPT <aclname> [<aclname>...] */
|
||||
if (!strcmp(arg[0], "ACCEPT")) {
|
||||
upslogx(LOG_WARNING, "ACCEPT in upsd.conf is no longer supported - switch to LISTEN");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* REJECT <aclname> [<aclname>...] */
|
||||
if (!strcmp(arg[0], "REJECT")) {
|
||||
upslogx(LOG_WARNING, "REJECT in upsd.conf is no longer supported - switch to LISTEN");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* LISTEN <address> [<port>] */
|
||||
if (!strcmp(arg[0], "LISTEN")) {
|
||||
if (numargs < 3)
|
||||
listen_add(arg[1], string_const(PORT));
|
||||
else
|
||||
listen_add(arg[1], arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* everything below here uses up through arg[2] */
|
||||
if (numargs < 3)
|
||||
return 0;
|
||||
|
||||
/* ACL <aclname> <ip block> */
|
||||
if (!strcmp(arg[0], "ACL")) {
|
||||
upslogx(LOG_WARNING, "ACL in upsd.conf is no longer supported - switch to LISTEN");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* not recognized */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called for fatal errors in parseconf like malloc failures */
|
||||
static void upsd_conf_err(const char *errmsg)
|
||||
{
|
||||
upslogx(LOG_ERR, "Fatal error in parseconf (upsd.conf): %s", errmsg);
|
||||
}
|
||||
|
||||
void load_upsdconf(int reloading)
|
||||
{
|
||||
char fn[SMALLBUF];
|
||||
PCONF_CTX_t ctx;
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/upsd.conf", confpath());
|
||||
|
||||
check_perms(fn);
|
||||
|
||||
pconf_init(&ctx, upsd_conf_err);
|
||||
|
||||
if (!pconf_file_begin(&ctx, fn)) {
|
||||
pconf_finish(&ctx);
|
||||
|
||||
if (!reloading)
|
||||
fatalx(EXIT_FAILURE, "%s", ctx.errmsg);
|
||||
|
||||
upslogx(LOG_ERR, "Reload failed: %s", ctx.errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
while (pconf_file_next(&ctx)) {
|
||||
if (pconf_parse_error(&ctx)) {
|
||||
upslogx(LOG_ERR, "Parse error: %s:%d: %s",
|
||||
fn, ctx.linenum, ctx.errmsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.numargs < 1)
|
||||
continue;
|
||||
|
||||
if (!parse_upsd_conf_args(ctx.numargs, ctx.arglist)) {
|
||||
unsigned int i;
|
||||
char errmsg[SMALLBUF];
|
||||
|
||||
snprintf(errmsg, sizeof(errmsg),
|
||||
"upsd.conf: invalid directive");
|
||||
|
||||
for (i = 0; i < ctx.numargs; i++)
|
||||
snprintfcat(errmsg, sizeof(errmsg), " %s",
|
||||
ctx.arglist[i]);
|
||||
|
||||
upslogx(LOG_WARNING, "%s", errmsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pconf_finish(&ctx);
|
||||
}
|
||||
|
||||
/* callback during parsing of ups.conf */
|
||||
void do_upsconf_args(char *upsname, char *var, char *val)
|
||||
{
|
||||
ups_t *tmp, *last;
|
||||
|
||||
/* no "global" stuff for us */
|
||||
if (!upsname)
|
||||
return;
|
||||
|
||||
last = tmp = upstable;
|
||||
|
||||
while (tmp) {
|
||||
last = tmp;
|
||||
|
||||
if (!strcmp(tmp->upsname, upsname)) {
|
||||
if (!strcmp(var, "driver"))
|
||||
tmp->driver = xstrdup(val);
|
||||
if (!strcmp(var, "port"))
|
||||
tmp->port = xstrdup(val);
|
||||
if (!strcmp(var, "desc"))
|
||||
tmp->desc = xstrdup(val);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = xmalloc(sizeof(ups_t));
|
||||
tmp->upsname = xstrdup(upsname);
|
||||
tmp->driver = NULL;
|
||||
tmp->port = NULL;
|
||||
tmp->desc = NULL;
|
||||
tmp->next = NULL;
|
||||
|
||||
if (!strcmp(var, "driver"))
|
||||
tmp->driver = xstrdup(val);
|
||||
if (!strcmp(var, "port"))
|
||||
tmp->port = xstrdup(val);
|
||||
if (!strcmp(var, "desc"))
|
||||
tmp->desc = xstrdup(val);
|
||||
|
||||
if (last)
|
||||
last->next = tmp;
|
||||
else
|
||||
upstable = tmp;
|
||||
}
|
||||
|
||||
/* add valid UPSes from ups.conf to the internal structures */
|
||||
void upsconf_add(int reloading)
|
||||
{
|
||||
ups_t *tmp = upstable, *next;
|
||||
char statefn[SMALLBUF];
|
||||
|
||||
if (!tmp) {
|
||||
upslogx(LOG_WARNING, "Warning: no UPS definitions in ups.conf");
|
||||
return;
|
||||
}
|
||||
|
||||
while (tmp) {
|
||||
|
||||
/* save for later, since we delete as we go along */
|
||||
next = tmp->next;
|
||||
|
||||
/* this should always be set, but better safe than sorry */
|
||||
if (!tmp->upsname) {
|
||||
tmp = tmp->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* don't accept an entry that's missing items */
|
||||
if ((!tmp->driver) || (!tmp->port)) {
|
||||
upslogx(LOG_WARNING, "Warning: ignoring incomplete configuration for UPS [%s]\n",
|
||||
tmp->upsname);
|
||||
} else {
|
||||
snprintf(statefn, sizeof(statefn), "%s-%s",
|
||||
tmp->driver, tmp->upsname);
|
||||
|
||||
/* if a UPS exists, update it, else add it as new */
|
||||
if ((reloading) && (get_ups_ptr(tmp->upsname) != NULL))
|
||||
ups_update(statefn, tmp->upsname, tmp->desc);
|
||||
else
|
||||
ups_create(statefn, tmp->upsname, tmp->desc);
|
||||
}
|
||||
|
||||
/* free tmp's resources */
|
||||
|
||||
free(tmp->driver);
|
||||
free(tmp->port);
|
||||
free(tmp->desc);
|
||||
free(tmp->upsname);
|
||||
free(tmp);
|
||||
|
||||
tmp = next;
|
||||
}
|
||||
|
||||
/* upstable should be completely gone by this point */
|
||||
upstable = NULL;
|
||||
}
|
||||
|
||||
/* remove a UPS from the linked list */
|
||||
static void delete_ups(upstype_t *target)
|
||||
{
|
||||
upstype_t *ptr, *last;
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
ptr = last = firstups;
|
||||
|
||||
while (ptr) {
|
||||
if (ptr == target) {
|
||||
upslogx(LOG_NOTICE, "Deleting UPS [%s]", target->name);
|
||||
|
||||
/* make sure nobody stays logged into this thing */
|
||||
kick_login_clients(target->name);
|
||||
|
||||
/* about to delete the first ups? */
|
||||
if (ptr == last)
|
||||
firstups = ptr->next;
|
||||
else
|
||||
last->next = ptr->next;
|
||||
|
||||
if (ptr->sock_fd != -1)
|
||||
close(ptr->sock_fd);
|
||||
|
||||
/* release memory */
|
||||
sstate_infofree(ptr);
|
||||
sstate_cmdfree(ptr);
|
||||
pconf_finish(&ptr->sock_ctx);
|
||||
|
||||
free(ptr->fn);
|
||||
free(ptr->name);
|
||||
free(ptr->desc);
|
||||
free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
last = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
/* shouldn't happen */
|
||||
upslogx(LOG_ERR, "delete_ups: UPS not found");
|
||||
}
|
||||
|
||||
/* see if we can open a file */
|
||||
static int check_file(const char *fn)
|
||||
{
|
||||
char chkfn[SMALLBUF];
|
||||
FILE *f;
|
||||
|
||||
snprintf(chkfn, sizeof(chkfn), "%s/%s", confpath(), fn);
|
||||
|
||||
f = fopen(chkfn, "r");
|
||||
|
||||
if (!f) {
|
||||
upslog_with_errno(LOG_ERR, "Reload failed: can't open %s", chkfn);
|
||||
return 0; /* failed */
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 1; /* OK */
|
||||
}
|
||||
|
||||
/* called after SIGHUP */
|
||||
void conf_reload(void)
|
||||
{
|
||||
upstype_t *upstmp, *upsnext;
|
||||
|
||||
upslogx(LOG_INFO, "SIGHUP: reloading configuration");
|
||||
|
||||
/* see if we can access upsd.conf before blowing away the config */
|
||||
if (!check_file("upsd.conf"))
|
||||
return;
|
||||
|
||||
/* reset retain flags on all known UPS entries */
|
||||
upstmp = firstups;
|
||||
while (upstmp) {
|
||||
upstmp->retain = 0;
|
||||
upstmp = upstmp->next;
|
||||
}
|
||||
|
||||
/* reload from ups.conf */
|
||||
read_upsconf();
|
||||
upsconf_add(1); /* 1 = reloading */
|
||||
|
||||
/* now reread upsd.conf */
|
||||
load_upsdconf(1); /* 1 = reloading */
|
||||
|
||||
/* now delete all UPS entries that didn't get reloaded */
|
||||
|
||||
upstmp = firstups;
|
||||
|
||||
while (upstmp) {
|
||||
/* upstmp may be deleted during this pass */
|
||||
upsnext = upstmp->next;
|
||||
|
||||
if (upstmp->retain == 0)
|
||||
delete_ups(upstmp);
|
||||
|
||||
upstmp = upsnext;
|
||||
}
|
||||
|
||||
/* did they actually delete the last UPS? */
|
||||
if (firstups == NULL)
|
||||
upslogx(LOG_WARNING, "Warning: no UPSes currently defined!");
|
||||
|
||||
/* and also make sure upsd.users can be read... */
|
||||
if (!check_file("upsd.users"))
|
||||
return;
|
||||
|
||||
/* delete all users */
|
||||
user_flush();
|
||||
|
||||
/* and finally reread from upsd.users */
|
||||
user_load();
|
||||
}
|
||||
43
server/conf.h
Normal file
43
server/conf.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* conf.h - supporting elements of conf parsing functions for upsd
|
||||
|
||||
Copyright (C)
|
||||
2001 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* read upsd.conf */
|
||||
void load_upsdconf(int reloading);
|
||||
|
||||
/* add valid UPSes from ups.conf to the internal structures */
|
||||
void upsconf_add(int reloading);
|
||||
|
||||
/* flush existing config, then reread everything */
|
||||
void conf_reload(void);
|
||||
|
||||
typedef struct ups_s {
|
||||
char *upsname;
|
||||
char *driver;
|
||||
char *port;
|
||||
char *desc;
|
||||
struct ups_s *next;
|
||||
} ups_t;
|
||||
|
||||
/* used for really clean shutdowns */
|
||||
void delete_acls(void);
|
||||
void delete_access(void);
|
||||
|
||||
extern int num_ups;
|
||||
55
server/ctype.h
Normal file
55
server/ctype.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* ctype.h - client data definitions for upsd
|
||||
|
||||
Copyright (C)
|
||||
2002 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef CTYPE_H_SEEN
|
||||
#define CTYPE_H_SEEN 1
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include "parseconf.h"
|
||||
|
||||
/* client structure */
|
||||
typedef struct ctype_s {
|
||||
char *addr;
|
||||
int sock_fd;
|
||||
time_t last_heard;
|
||||
char *loginups;
|
||||
char *password;
|
||||
char *username;
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
SSL *ssl;
|
||||
#else
|
||||
void *ssl;
|
||||
#endif
|
||||
int ssl_connected;
|
||||
|
||||
PCONF_CTX_t ctx;
|
||||
|
||||
/* doubly linked list */
|
||||
struct ctype_s *prev;
|
||||
struct ctype_s *next;
|
||||
} ctype_t;
|
||||
|
||||
#endif /* CTYPE_H_SEEN */
|
||||
165
server/desc.c
Normal file
165
server/desc.c
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/* desc.c - variable/command description handling for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "parseconf.h"
|
||||
|
||||
#include "desc.h"
|
||||
|
||||
extern const char *datapath;
|
||||
|
||||
struct dlist_t {
|
||||
char *name;
|
||||
char *desc;
|
||||
struct dlist_t *next;
|
||||
};
|
||||
|
||||
static struct dlist_t *cmd_list = NULL, *var_list = NULL;
|
||||
|
||||
static void list_free(struct dlist_t *ptr)
|
||||
{
|
||||
struct dlist_t *next;
|
||||
|
||||
while (ptr) {
|
||||
next = ptr->next;
|
||||
|
||||
free(ptr->name);
|
||||
free(ptr->desc);
|
||||
free(ptr);
|
||||
|
||||
ptr = next;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *list_get(const struct dlist_t *list, const char *name)
|
||||
{
|
||||
const struct dlist_t *tmp;
|
||||
|
||||
tmp = list;
|
||||
|
||||
while (tmp) {
|
||||
if (!strcasecmp(tmp->name, name))
|
||||
return tmp->desc;
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void desc_add(struct dlist_t **list, const char *name, const char *desc)
|
||||
{
|
||||
struct dlist_t *tmp, *last;
|
||||
|
||||
tmp = last = *list;
|
||||
|
||||
while (tmp) {
|
||||
last = tmp;
|
||||
|
||||
/* replace duplicates */
|
||||
if (!strcasecmp(tmp->name, name)) {
|
||||
free(tmp->desc);
|
||||
tmp->desc = xstrdup(desc);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = xmalloc(sizeof(struct dlist_t));
|
||||
|
||||
tmp->name = xstrdup(name);
|
||||
tmp->desc = xstrdup(desc);
|
||||
tmp->next = NULL;
|
||||
|
||||
if (last)
|
||||
last->next = tmp;
|
||||
else
|
||||
*list = tmp;
|
||||
}
|
||||
|
||||
static void desc_file_err(const char *errmsg)
|
||||
{
|
||||
upslogx(LOG_ERR, "Fatal error in parseconf (cmdvartab): %s", errmsg);
|
||||
}
|
||||
|
||||
/* interface */
|
||||
|
||||
void desc_load(void)
|
||||
{
|
||||
char fn[SMALLBUF];
|
||||
PCONF_CTX_t ctx;
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/cmdvartab", datapath);
|
||||
|
||||
pconf_init(&ctx, desc_file_err);
|
||||
|
||||
/* this file is not required */
|
||||
if (!pconf_file_begin(&ctx, fn)) {
|
||||
upslogx(LOG_INFO, "%s not found - disabling descriptions", fn);
|
||||
pconf_finish(&ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
while (pconf_file_next(&ctx)) {
|
||||
if (pconf_parse_error(&ctx)) {
|
||||
upslogx(LOG_ERR, "Parse error: %s:%d: %s",
|
||||
fn, ctx.linenum, ctx.errmsg);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ctx.numargs < 3)
|
||||
continue;
|
||||
|
||||
if (!strcmp(ctx.arglist[0], "CMDDESC")) {
|
||||
desc_add(&cmd_list, ctx.arglist[1], ctx.arglist[2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(ctx.arglist[0], "VARDESC")) {
|
||||
desc_add(&var_list, ctx.arglist[1], ctx.arglist[2]);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unknown */
|
||||
}
|
||||
|
||||
pconf_finish(&ctx);
|
||||
}
|
||||
|
||||
void desc_free(void)
|
||||
{
|
||||
list_free(cmd_list);
|
||||
list_free(var_list);
|
||||
|
||||
cmd_list = var_list = NULL;
|
||||
}
|
||||
|
||||
const char *desc_get_cmd(const char *name)
|
||||
{
|
||||
return list_get(cmd_list, name);
|
||||
}
|
||||
|
||||
const char *desc_get_var(const char *name)
|
||||
{
|
||||
return list_get(var_list, name);
|
||||
}
|
||||
4
server/desc.h
Normal file
4
server/desc.h
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
void desc_load(void);
|
||||
void desc_free(void);
|
||||
const char *desc_get_cmd(const char *name);
|
||||
const char *desc_get_var(const char *name);
|
||||
60
server/netcmds.h
Normal file
60
server/netcmds.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* netcmds.h - upsd support structure details
|
||||
|
||||
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ctype.h"
|
||||
|
||||
#include "ssl.h"
|
||||
#include "netget.h"
|
||||
#include "netset.h"
|
||||
#include "netlist.h"
|
||||
#include "netmisc.h"
|
||||
#include "netuser.h"
|
||||
#include "netinstcmd.h"
|
||||
|
||||
#define FLAG_USER 0x0001 /* username and password must be set */
|
||||
|
||||
struct netcmds_t {
|
||||
const char *name;
|
||||
void (*func)(ctype_t *client, int numargs, const char **arg);
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct netcmds_t netcmds[] =
|
||||
{
|
||||
{ "VER", net_ver, 0 },
|
||||
{ "HELP", net_help, 0 },
|
||||
{ "STARTTLS", net_starttls, 0 },
|
||||
|
||||
{ "GET", net_get, 0 },
|
||||
{ "LIST", net_list, 0 },
|
||||
|
||||
{ "USERNAME", net_username, 0 },
|
||||
{ "PASSWORD", net_password, 0 },
|
||||
|
||||
{ "LOGIN", net_login, FLAG_USER },
|
||||
{ "LOGOUT", net_logout, 0 },
|
||||
{ "MASTER", net_master, FLAG_USER },
|
||||
|
||||
{ "FSD", net_fsd, FLAG_USER },
|
||||
|
||||
{ "SET", net_set, FLAG_USER },
|
||||
{ "INSTCMD", net_instcmd, FLAG_USER },
|
||||
|
||||
{ NULL, (void(*)())(NULL), 0 }
|
||||
};
|
||||
35
server/neterr.h
Normal file
35
server/neterr.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* network error definitions for consistency */
|
||||
|
||||
#define NUT_ERR_ACCESS_DENIED "ACCESS-DENIED"
|
||||
#define NUT_ERR_UNKNOWN_UPS "UNKNOWN-UPS"
|
||||
#define NUT_ERR_VAR_NOT_SUPPORTED "VAR-NOT-SUPPORTED"
|
||||
#define NUT_ERR_CMD_NOT_SUPPORTED "CMD-NOT-SUPPORTED"
|
||||
#define NUT_ERR_INVALID_ARGUMENT "INVALID-ARGUMENT"
|
||||
#define NUT_ERR_INSTCMD_FAILED "INSTCMD-FAILED"
|
||||
#define NUT_ERR_SET_FAILED "SET-FAILED"
|
||||
#define NUT_ERR_READONLY "READONLY"
|
||||
#define NUT_ERR_TOO_LONG "TOO-LONG"
|
||||
#define NUT_ERR_FEATURE_NOT_SUPPORTED "FEATURE-NOT-SUPPORTED"
|
||||
#define NUT_ERR_FEATURE_NOT_CONFIGURED "FEATURE-NOT-CONFIGURED"
|
||||
#define NUT_ERR_ALREADY_SSL_MODE "ALREADY-SSL-MODE"
|
||||
|
||||
/* errors which are only used by top-level upsd functions */
|
||||
|
||||
#define NUT_ERR_DRIVER_NOT_CONNECTED "DRIVER-NOT-CONNECTED"
|
||||
#define NUT_ERR_DATA_STALE "DATA-STALE"
|
||||
#define NUT_ERR_ALREADY_LOGGED_IN "ALREADY-LOGGED-IN"
|
||||
#define NUT_ERR_INVALID_PASSWORD "INVALID-PASSWORD"
|
||||
#define NUT_ERR_ALREADY_SET_PASSWORD "ALREADY-SET-PASSWORD"
|
||||
#define NUT_ERR_INVALID_USERNAME "INVALID-USERNAME"
|
||||
#define NUT_ERR_ALREADY_SET_USERNAME "ALREADY-SET-USERNAME"
|
||||
#define NUT_ERR_USERNAME_REQUIRED "USERNAME-REQUIRED"
|
||||
#define NUT_ERR_PASSWORD_REQUIRED "PASSWORD-REQUIRED"
|
||||
#define NUT_ERR_UNKNOWN_COMMAND "UNKNOWN-COMMAND"
|
||||
|
||||
/* errors which are only used with the old functions */
|
||||
|
||||
#define NUT_ERR_VAR_UNKNOWN "VAR-UNKNOWN"
|
||||
#define NUT_ERR_UNKNOWN_TYPE "UNKNOWN-TYPE"
|
||||
#define NUT_ERR_UNKNOWN_INSTCMD "UNKNOWN-INSTCMD"
|
||||
#define NUT_ERR_MISSING_ARGUMENT "MISSING-ARGUMENT"
|
||||
#define NUT_ERR_INVALID_VALUE "INVALID-VALUE"
|
||||
266
server/netget.c
Normal file
266
server/netget.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/* netget.c - GET handlers for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
#include "desc.h"
|
||||
#include "neterr.h"
|
||||
|
||||
#include "netget.h"
|
||||
|
||||
static void get_numlogins(ctype_t *client, const char *upsname)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
sendback(client, "NUMLOGINS %s %d\n", upsname, ups->numlogins);
|
||||
}
|
||||
|
||||
static void get_upsdesc(ctype_t *client, const char *upsname)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
char esc[SMALLBUF];
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
if (ups->desc) {
|
||||
pconf_encode(ups->desc, esc, sizeof(esc));
|
||||
sendback(client, "UPSDESC %s \"%s\"\n", upsname, esc);
|
||||
|
||||
} else {
|
||||
|
||||
sendback(client, "UPSDESC %s \"Unavailable\"\n", upsname);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_desc(ctype_t *client, const char *upsname, const char *var)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
const char *desc;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
desc = desc_get_var(var);
|
||||
|
||||
if (desc)
|
||||
sendback(client, "DESC %s %s \"%s\"\n", upsname, var, desc);
|
||||
else
|
||||
sendback(client, "DESC %s %s \"Description unavailable\"\n", upsname, var);
|
||||
}
|
||||
|
||||
static void get_cmddesc(ctype_t *client, const char *upsname, const char *cmd)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
const char *desc;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
desc = desc_get_cmd(cmd);
|
||||
|
||||
if (desc)
|
||||
sendback(client, "CMDDESC %s %s \"%s\"\n", upsname, cmd, desc);
|
||||
else
|
||||
sendback(client, "CMDDESC %s %s \"Description unavailable\"\n",
|
||||
upsname, cmd);
|
||||
}
|
||||
|
||||
static void get_type(ctype_t *client, const char *upsname, const char *var)
|
||||
{
|
||||
char buf[SMALLBUF];
|
||||
const upstype_t *ups;
|
||||
const struct st_tree_t *node;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
node = sstate_getnode(ups, var);
|
||||
|
||||
if (!node) {
|
||||
send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "TYPE %s %s", upsname, var);
|
||||
|
||||
if (node->flags & ST_FLAG_RW)
|
||||
snprintfcat(buf, sizeof(buf), " RW");
|
||||
|
||||
if (node->enum_list) {
|
||||
sendback(client, "%s ENUM\n", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->flags & ST_FLAG_STRING) {
|
||||
sendback(client, "%s STRING:%d\n", buf, node->aux);
|
||||
return;
|
||||
}
|
||||
|
||||
/* hmm... */
|
||||
|
||||
sendback(client, "TYPE %s %s UNKNOWN\n", upsname, var);
|
||||
}
|
||||
|
||||
static void get_var_server(ctype_t *client, const char *upsname, const char *var)
|
||||
{
|
||||
if (!strcasecmp(var, "server.info")) {
|
||||
sendback(client, "VAR %s server.info "
|
||||
"\"Network UPS Tools upsd %s - "
|
||||
"http://www.networkupstools.org/\"\n",
|
||||
upsname, UPS_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "server.version")) {
|
||||
sendback(client, "VAR %s server.version \"%s\"\n",
|
||||
upsname, UPS_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
static void get_var(ctype_t *client, const char *upsname, const char *var)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
const char *val;
|
||||
|
||||
/* ignore upsname for server.* variables */
|
||||
if (!strncasecmp(var, "server.", 7)) {
|
||||
get_var_server(client, upsname, var);
|
||||
return;
|
||||
}
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
val = sstate_getinfo(ups, var);
|
||||
|
||||
if (!val) {
|
||||
send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle special case for status */
|
||||
if ((!strcasecmp(var, "ups.status")) && (ups->fsd))
|
||||
sendback(client, "VAR %s %s \"FSD %s\"\n", upsname, var, val);
|
||||
else
|
||||
sendback(client, "VAR %s %s \"%s\"\n", upsname, var, val);
|
||||
}
|
||||
|
||||
void net_get(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg < 2) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET NUMLOGINS UPS */
|
||||
if (!strcasecmp(arg[0], "NUMLOGINS")) {
|
||||
get_numlogins(client, arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET UPSDESC UPS */
|
||||
if (!strcasecmp(arg[0], "UPSDESC")) {
|
||||
get_upsdesc(client, arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numarg < 3) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET VAR UPS VARNAME */
|
||||
if (!strcasecmp(arg[0], "VAR")) {
|
||||
get_var(client, arg[1], arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET TYPE UPS VARNAME */
|
||||
if (!strcasecmp(arg[0], "TYPE")) {
|
||||
get_type(client, arg[1], arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET DESC UPS VARNAME */
|
||||
if (!strcasecmp(arg[0], "DESC")) {
|
||||
get_desc(client, arg[1], arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* GET CMDDESC UPS CMDNAME */
|
||||
if (!strcasecmp(arg[0], "CMDDESC")) {
|
||||
get_cmddesc(client, arg[1], arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
1
server/netget.h
Normal file
1
server/netget.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void net_get(ctype_t *client, int numarg, const char **arg);
|
||||
98
server/netinstcmd.c
Normal file
98
server/netinstcmd.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* netinstcmd.c - INSTCMD handler for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "user.h" /* for user_checkinstcmd */
|
||||
#include "neterr.h"
|
||||
|
||||
#include "netinstcmd.h"
|
||||
|
||||
static void send_instcmd(ctype_t *client, const char *upsname,
|
||||
const char *cmdname)
|
||||
{
|
||||
int found;
|
||||
upstype_t *ups;
|
||||
const struct cmdlist_t *ctmp;
|
||||
char sockcmd[SMALLBUF];
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
ctmp = sstate_getcmdlist(ups);
|
||||
|
||||
found = 0;
|
||||
|
||||
while (ctmp) {
|
||||
if (!strcasecmp(ctmp->name, cmdname)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ctmp = ctmp->next;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
send_err(client, NUT_ERR_CMD_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* see if this user is allowed to do this command */
|
||||
if (!user_checkinstcmd(client->username, client->password, cmdname)) {
|
||||
send_err(client, NUT_ERR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
upslogx(LOG_INFO, "Instant command: %s@%s did %s on %s",
|
||||
client->username, client->addr, cmdname,
|
||||
ups->name);
|
||||
|
||||
snprintf(sockcmd, sizeof(sockcmd), "INSTCMD %s\n", cmdname);
|
||||
|
||||
if (!sstate_sendline(ups, sockcmd)) {
|
||||
upslogx(LOG_INFO, "Set command send failed");
|
||||
send_err(client, NUT_ERR_INSTCMD_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "OK\n");
|
||||
}
|
||||
|
||||
void net_instcmd(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg < 2) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* INSTCMD <ups> <cmdname> */
|
||||
send_instcmd(client, arg[0], arg[1]);
|
||||
return;
|
||||
}
|
||||
1
server/netinstcmd.h
Normal file
1
server/netinstcmd.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void net_instcmd(ctype_t *client, int numarg, const char **arg);
|
||||
268
server/netlist.c
Normal file
268
server/netlist.c
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
/* netlist.c - LIST handlers for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
#include "neterr.h"
|
||||
|
||||
#include "netlist.h"
|
||||
|
||||
extern upstype_t *firstups; /* for list_ups */
|
||||
|
||||
static int tree_dump(struct st_tree_t *node, ctype_t *client, const char *ups,
|
||||
int rw, int fsd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!node)
|
||||
return 1; /* not an error */
|
||||
|
||||
if (node->left) {
|
||||
ret = tree_dump(node->left, client, ups, rw, fsd);
|
||||
|
||||
if (!ret)
|
||||
return 0; /* write failed in child */
|
||||
}
|
||||
|
||||
if (rw) {
|
||||
|
||||
/* only send this back if it's been flagged RW */
|
||||
if (node->flags & ST_FLAG_RW) {
|
||||
ret = sendback(client, "RW %s %s \"%s\"\n",
|
||||
ups, node->var, node->val);
|
||||
|
||||
} else {
|
||||
ret = 1; /* dummy */
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* normal variable list only */
|
||||
|
||||
/* status is always a special case */
|
||||
if ((fsd == 1) && (!strcasecmp(node->var, "ups.status"))) {
|
||||
ret = sendback(client, "VAR %s %s \"FSD %s\"\n",
|
||||
ups, node->var, node->val);
|
||||
|
||||
} else {
|
||||
ret = sendback(client, "VAR %s %s \"%s\"\n",
|
||||
ups, node->var, node->val);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 1)
|
||||
return 0;
|
||||
|
||||
if (node->right)
|
||||
return tree_dump(node->right, client, ups, rw, fsd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void list_rw(ctype_t *client, const char *upsname)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
if (!sendback(client, "BEGIN LIST RW %s\n", upsname))
|
||||
return;
|
||||
|
||||
if (!tree_dump(ups->inforoot, client, upsname, 1, ups->fsd))
|
||||
return;
|
||||
|
||||
sendback(client, "END LIST RW %s\n", upsname);
|
||||
}
|
||||
|
||||
static void list_var(ctype_t *client, const char *upsname)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
if (!sendback(client, "BEGIN LIST VAR %s\n", upsname))
|
||||
return;
|
||||
|
||||
if (!tree_dump(ups->inforoot, client, upsname, 0, ups->fsd))
|
||||
return;
|
||||
|
||||
sendback(client, "END LIST VAR %s\n", upsname);
|
||||
}
|
||||
|
||||
static void list_cmd(ctype_t *client, const char *upsname)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
struct cmdlist_t *ctmp;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
if (!sendback(client, "BEGIN LIST CMD %s\n", upsname))
|
||||
return;
|
||||
|
||||
for (ctmp = ups->cmdlist; ctmp != NULL; ctmp = ctmp->next) {
|
||||
if (!sendback(client, "CMD %s %s\n", upsname, ctmp->name))
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "END LIST CMD %s\n", upsname);
|
||||
}
|
||||
|
||||
static void list_enum(ctype_t *client, const char *upsname, const char *var)
|
||||
{
|
||||
const upstype_t *ups;
|
||||
const struct st_tree_t *node;
|
||||
const struct enum_t *etmp;
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
node = sstate_getnode(ups, var);
|
||||
|
||||
if (!node) {
|
||||
send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sendback(client, "BEGIN LIST ENUM %s %s\n", upsname, var))
|
||||
return;
|
||||
|
||||
for (etmp = node->enum_list; etmp != NULL; etmp = etmp->next) {
|
||||
if (!sendback(client, "ENUM %s %s \"%s\"\n",
|
||||
upsname, var, etmp->val))
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "END LIST ENUM %s %s\n", upsname, var);
|
||||
}
|
||||
|
||||
static void list_ups(ctype_t *client)
|
||||
{
|
||||
upstype_t *utmp;
|
||||
char esc[SMALLBUF];
|
||||
|
||||
if (!sendback(client, "BEGIN LIST UPS\n"))
|
||||
return;
|
||||
|
||||
utmp = firstups;
|
||||
|
||||
while (utmp) {
|
||||
int ret;
|
||||
|
||||
if (utmp->desc) {
|
||||
pconf_encode(utmp->desc, esc, sizeof(esc));
|
||||
ret = sendback(client, "UPS %s \"%s\"\n",
|
||||
utmp->name, esc);
|
||||
|
||||
} else {
|
||||
ret = sendback(client, "UPS %s \"Unavailable\"\n",
|
||||
utmp->name);
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
utmp = utmp->next;
|
||||
}
|
||||
|
||||
sendback(client, "END LIST UPS\n");
|
||||
}
|
||||
|
||||
void net_list(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg < 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* LIST UPS */
|
||||
if (!strcasecmp(arg[0], "UPS")) {
|
||||
list_ups(client);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numarg < 2) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* LIST VAR UPS */
|
||||
if (!strcasecmp(arg[0], "VAR")) {
|
||||
list_var(client, arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* LIST RW UPS */
|
||||
if (!strcasecmp(arg[0], "RW")) {
|
||||
list_rw(client, arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* LIST CMD UPS */
|
||||
if (!strcasecmp(arg[0], "CMD")) {
|
||||
list_cmd(client, arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (numarg < 3) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* LIST ENUM UPS VARNAME */
|
||||
if (!strcasecmp(arg[0], "ENUM")) {
|
||||
list_enum(client, arg[1], arg[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
}
|
||||
1
server/netlist.h
Normal file
1
server/netlist.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void net_list(ctype_t *client, int numarg, const char **arg);
|
||||
80
server/netmisc.c
Normal file
80
server/netmisc.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/* netmisc.c - miscellaneous network handlers for upsd (VER, HELP, FSD)
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
#include "user.h" /* for user_checkaction */
|
||||
#include "neterr.h"
|
||||
|
||||
#include "netmisc.h"
|
||||
|
||||
void net_ver(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg != 0) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "Network UPS Tools upsd %s - http://www.networkupstools.org/\n",
|
||||
UPS_VERSION);
|
||||
}
|
||||
|
||||
void net_help(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg != 0) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "Commands: HELP VER GET LIST SET INSTCMD LOGIN LOGOUT"
|
||||
" USERNAME PASSWORD STARTTLS\n");
|
||||
}
|
||||
|
||||
void net_fsd(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
upstype_t *ups;
|
||||
|
||||
if (numarg != 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
ups = get_ups_ptr(arg[0]);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure this user is allowed to do FSD */
|
||||
if (!user_checkaction(client->username, client->password, "FSD")) {
|
||||
send_err(client, NUT_ERR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
upslogx(LOG_INFO, "Client %s@%s set FSD on UPS [%s]",
|
||||
client->username, client->addr, ups->name);
|
||||
|
||||
ups->fsd = 1;
|
||||
sendback(client, "OK FSD-SET\n");
|
||||
}
|
||||
|
||||
3
server/netmisc.h
Normal file
3
server/netmisc.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
void net_ver(ctype_t *client, int numarg, const char **arg);
|
||||
void net_help(ctype_t *client, int numarg, const char **arg);
|
||||
void net_fsd(ctype_t *client, int numarg, const char **arg);
|
||||
143
server/netset.c
Normal file
143
server/netset.c
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* netset.c - SET handler for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
#include "user.h" /* for user_checkaction */
|
||||
#include "neterr.h"
|
||||
|
||||
#include "netset.h"
|
||||
|
||||
static void set_var(ctype_t *client, const char *upsname, const char *var,
|
||||
const char *newval)
|
||||
{
|
||||
upstype_t *ups;
|
||||
const char *val;
|
||||
const struct enum_t *etmp;
|
||||
char cmd[SMALLBUF], esc[SMALLBUF];
|
||||
|
||||
ups = get_ups_ptr(upsname);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ups_available(ups, client))
|
||||
return;
|
||||
|
||||
/* make sure this user is allowed to do SET */
|
||||
if (!user_checkaction(client->username, client->password, "SET")) {
|
||||
send_err(client, NUT_ERR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
val = sstate_getinfo(ups, var);
|
||||
|
||||
if (!val) {
|
||||
send_err(client, NUT_ERR_VAR_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure this variable is writable (RW) */
|
||||
if ((sstate_getflags(ups, var) & ST_FLAG_RW) == 0) {
|
||||
send_err(client, NUT_ERR_READONLY);
|
||||
return;
|
||||
}
|
||||
|
||||
/* see if the new value is allowed for this variable */
|
||||
|
||||
if (sstate_getflags(ups, var) & ST_FLAG_STRING) {
|
||||
int aux;
|
||||
|
||||
aux = sstate_getaux(ups, var);
|
||||
|
||||
/* check for insanity from the driver */
|
||||
if (aux < 1) {
|
||||
upslogx(LOG_WARNING, "UPS [%s]: auxdata for %s is invalid",
|
||||
ups->name, var);
|
||||
|
||||
send_err(client, NUT_ERR_SET_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aux < (int) strlen(newval)) {
|
||||
send_err(client, NUT_ERR_TOO_LONG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* see if it's enumerated */
|
||||
|
||||
etmp = sstate_getenumlist(ups, var);
|
||||
|
||||
if (etmp) {
|
||||
int found = 0;
|
||||
|
||||
while (etmp) {
|
||||
if (!strcmp(etmp->val, newval)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
etmp = etmp->next;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
send_err(client, NUT_ERR_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* must be OK now */
|
||||
|
||||
upslogx(LOG_INFO, "Set variable: %s@%s set %s on %s to %s",
|
||||
client->username, client->addr, var, ups->name, newval);
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "SET %s \"%s\"\n",
|
||||
var, pconf_encode(newval, esc, sizeof(esc)));
|
||||
|
||||
if (!sstate_sendline(ups, cmd)) {
|
||||
upslogx(LOG_INFO, "Set command send failed");
|
||||
send_err(client, NUT_ERR_SET_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
sendback(client, "OK\n");
|
||||
}
|
||||
|
||||
void net_set(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg < 4) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
/* SET VAR UPS VARNAME VALUE */
|
||||
if (!strcasecmp(arg[0], "VAR")) {
|
||||
set_var(client, arg[1], arg[2], arg[3]);
|
||||
return;
|
||||
}
|
||||
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
1
server/netset.h
Normal file
1
server/netset.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
void net_set(ctype_t *client, int numarg, const char **arg);
|
||||
154
server/netuser.c
Normal file
154
server/netuser.c
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/* netuser.c - LOGIN/LOGOUT/USERNAME/PASSWORD/MASTER handlers for upsd
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "upsd.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
#include "neterr.h"
|
||||
#include "user.h" /* for user_checkaction */
|
||||
|
||||
#include "netuser.h"
|
||||
|
||||
/* LOGIN <ups> */
|
||||
void net_login(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
upstype_t *ups;
|
||||
|
||||
if (numarg != 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->loginups != NULL) {
|
||||
upslogx(LOG_INFO, "Client %s@%s tried to login twice", client->username, client->addr);
|
||||
send_err(client, NUT_ERR_ALREADY_LOGGED_IN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure we got a valid UPS name */
|
||||
ups = get_ups_ptr(arg[0]);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure this is a valid user */
|
||||
if (!user_checkaction(client->username, client->password, "LOGIN")) {
|
||||
send_err(client, NUT_ERR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
ups->numlogins++;
|
||||
client->loginups = xstrdup(ups->name);
|
||||
|
||||
upslogx(LOG_INFO, "User %s@%s logged into UPS [%s]%s", client->username, client->addr,
|
||||
client->loginups, client->ssl ? " (SSL)" : "");
|
||||
sendback(client, "OK\n");
|
||||
}
|
||||
|
||||
void net_logout(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg != 0) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->loginups != NULL) {
|
||||
upslogx(LOG_INFO, "User %s@%s logged out from UPS [%s]%s", client->username, client->addr,
|
||||
client->loginups, client->ssl ? " (SSL)" : "");
|
||||
}
|
||||
|
||||
sendback(client, "OK Goodbye\n");
|
||||
|
||||
client->last_heard = 0;
|
||||
}
|
||||
|
||||
/* MASTER <upsname> */
|
||||
void net_master(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
upstype_t *ups;
|
||||
|
||||
if (numarg != 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
ups = get_ups_ptr(arg[0]);
|
||||
|
||||
if (!ups) {
|
||||
send_err(client, NUT_ERR_UNKNOWN_UPS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* make sure this user is allowed to do MASTER */
|
||||
if (!user_checkaction(client->username, client->password, "MASTER")) {
|
||||
send_err(client, NUT_ERR_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is just an access level check */
|
||||
sendback(client, "OK MASTER-GRANTED\n");
|
||||
}
|
||||
|
||||
/* USERNAME <username> */
|
||||
void net_username(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg != 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->username != NULL) {
|
||||
upslogx(LOG_INFO, "Client %s@%s tried to set a username twice",
|
||||
client->username, client->addr);
|
||||
|
||||
send_err(client, NUT_ERR_ALREADY_SET_USERNAME);
|
||||
return;
|
||||
}
|
||||
|
||||
client->username = xstrdup(arg[0]);
|
||||
sendback(client, "OK\n");
|
||||
}
|
||||
|
||||
/* PASSWORD <password> */
|
||||
void net_password(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (numarg != 1) {
|
||||
send_err(client, NUT_ERR_INVALID_ARGUMENT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->password != NULL) {
|
||||
if (client->username)
|
||||
upslogx(LOG_INFO, "Client %s@%s tried to set a password twice",
|
||||
client->username, client->addr);
|
||||
else
|
||||
upslogx(LOG_INFO, "Client on %s tried to set a password twice",
|
||||
client->addr);
|
||||
|
||||
send_err(client, NUT_ERR_ALREADY_SET_PASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
client->password = xstrdup(arg[0]);
|
||||
sendback(client, "OK\n");
|
||||
}
|
||||
5
server/netuser.h
Normal file
5
server/netuser.h
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
void net_login(ctype_t *client, int numarg, const char **arg);
|
||||
void net_logout(ctype_t *client, int numarg, const char **arg);
|
||||
void net_master(ctype_t *client, int numarg, const char **arg);
|
||||
void net_username(ctype_t *client, int numarg, const char **arg);
|
||||
void net_password(ctype_t *client, int numarg, const char **arg);
|
||||
171
server/sockdebug.c
Normal file
171
server/sockdebug.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/* sockdebug.c - Network UPS Tools driver-server socket debugger
|
||||
|
||||
Copyright (C) 2003 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "parseconf.h"
|
||||
|
||||
PCONF_CTX_t sock_ctx;
|
||||
|
||||
static void sock_arg(int numarg, char **arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("numarg=%d : ", numarg);
|
||||
|
||||
for (i = 0; i < numarg; i++)
|
||||
printf("[%s] ", arg[i]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static int socket_connect(const char *sockfn)
|
||||
{
|
||||
int ret, fd;
|
||||
struct sockaddr_un sa;
|
||||
|
||||
memset(&sa, '\0', sizeof(sa));
|
||||
sa.sun_family = AF_UNIX;
|
||||
snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", sockfn);
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
|
||||
|
||||
if (ret < 0) {
|
||||
perror("connect");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
ret = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
perror("fcntl(get)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = fcntl(fd, F_SETFL, ret | O_NDELAY);
|
||||
|
||||
if (ret < 0) {
|
||||
perror("fcntl(set)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void read_sock(int fd)
|
||||
{
|
||||
int i, ret;
|
||||
char buf[SMALLBUF];
|
||||
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
|
||||
if (ret == 0) {
|
||||
fprintf(stderr, "read on socket returned 0\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
perror("read sockfd");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (i = 0; i < ret; i++) {
|
||||
|
||||
switch (pconf_char(&sock_ctx, buf[i])) {
|
||||
case 1:
|
||||
sock_arg(sock_ctx.numargs, sock_ctx.arglist);
|
||||
break;
|
||||
|
||||
case -1:
|
||||
printf("Parse error: [%s]\n", sock_ctx.errmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret, sockfd;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s <socket name>\n", argv[0]);
|
||||
fprintf(stderr, " %s /var/state/ups/apcsmart-ttyS1.newsock\n",
|
||||
argv[0]);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
sockfd = socket_connect(argv[1]);
|
||||
|
||||
printf("connected: fd %d\n", sockfd);
|
||||
|
||||
pconf_init(&sock_ctx, NULL);
|
||||
|
||||
for (;;) {
|
||||
struct timeval tv;
|
||||
fd_set rfds;
|
||||
int maxfd;
|
||||
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fileno(stdin), &rfds);
|
||||
FD_SET(sockfd, &rfds);
|
||||
|
||||
/* paranoia */
|
||||
maxfd = (sockfd > fileno(stdin)) ? sockfd : fileno(stdin);
|
||||
|
||||
ret = select(maxfd + 1, &rfds, NULL, NULL, &tv);
|
||||
|
||||
if (FD_ISSET(sockfd, &rfds))
|
||||
read_sock(sockfd);
|
||||
|
||||
if (FD_ISSET(fileno(stdin), &rfds)) {
|
||||
char buf[SMALLBUF];
|
||||
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
|
||||
ret = write(sockfd, buf, strlen(buf));
|
||||
|
||||
if ((ret < 0) || (ret != (int) strlen(buf))) {
|
||||
perror("write to socket");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
248
server/ssl.c
Normal file
248
server/ssl.c
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
/* ssl.c - Interface to OpenSSL for upsd
|
||||
|
||||
Copyright (C)
|
||||
2002 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
based on the original implementation:
|
||||
|
||||
Copyright (C) 2002 Technorama Ltd. <oss-list-ups@technorama.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "upsd.h"
|
||||
#include "neterr.h"
|
||||
#include "ssl.h"
|
||||
|
||||
char *certfile = NULL;
|
||||
|
||||
static int ssl_initialized = 0;
|
||||
|
||||
#ifndef HAVE_SSL
|
||||
|
||||
/* stubs for non-ssl compiles */
|
||||
void net_starttls(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
send_err(client, NUT_ERR_FEATURE_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
int ssl_write(ctype_t *client, const char *buf, size_t buflen)
|
||||
{
|
||||
upslogx(LOG_ERR, "ssl_write called but SSL wasn't compiled in");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ssl_read(ctype_t *client, char *buf, size_t buflen)
|
||||
{
|
||||
upslogx(LOG_ERR, "ssl_read called but SSL wasn't compiled in");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ssl_init(void)
|
||||
{
|
||||
ssl_initialized = 0; /* keep gcc quiet */
|
||||
}
|
||||
|
||||
void ssl_finish(ctype_t *client)
|
||||
{
|
||||
if (client->ssl) {
|
||||
upslogx(LOG_ERR, "ssl_finish found active SSL connection but SSL wasn't compiled in");
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
|
||||
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(1, "ssl_debug: %s", errmsg);
|
||||
}
|
||||
}
|
||||
|
||||
void net_starttls(ctype_t *client, int numarg, const char **arg)
|
||||
{
|
||||
if (client->ssl) {
|
||||
send_err(client, NUT_ERR_ALREADY_SSL_MODE);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((!ssl_ctx) || (!certfile) || (!ssl_initialized)) {
|
||||
send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sendback(client, "OK STARTTLS\n")) {
|
||||
return;
|
||||
}
|
||||
|
||||
client->ssl = SSL_new(ssl_ctx);
|
||||
|
||||
if (!client->ssl) {
|
||||
upslog_with_errno(LOG_ERR, "SSL_new failed\n");
|
||||
ssl_debug();
|
||||
return;
|
||||
}
|
||||
|
||||
if (SSL_set_fd(client->ssl, client->sock_fd) != 1) {
|
||||
upslog_with_errno(LOG_ERR, "SSL_set_fd failed\n");
|
||||
ssl_debug();
|
||||
}
|
||||
}
|
||||
|
||||
void ssl_init(void)
|
||||
{
|
||||
if (!certfile) {
|
||||
return;
|
||||
}
|
||||
|
||||
check_perms(certfile);
|
||||
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
|
||||
if ((ssl_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL) {
|
||||
fatal_with_errno(EXIT_FAILURE, "SSL_CTX_new");
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_RSAPrivateKey_file(ssl_ctx, certfile, SSL_FILETYPE_PEM) != 1) {
|
||||
ssl_debug();
|
||||
upslogx(LOG_ERR, "SSL_CTX_use_RSAPrivateKey_file(%s) failed", certfile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate_chain_file(ssl_ctx, certfile) != 1) {
|
||||
upslogx(LOG_ERR, "SSL_CTX_use_certificate_chain_file(%s) failed", certfile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SSL_CTX_check_private_key(ssl_ctx) != 1) {
|
||||
upslogx(LOG_ERR, "SSL_CTX_check_private_key(%s) failed", certfile);
|
||||
return;
|
||||
}
|
||||
|
||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, "HIGH:@STRENGTH") != 1) {
|
||||
fatalx(EXIT_FAILURE, "SSL_CTX_set_cipher_list");
|
||||
}
|
||||
|
||||
ssl_initialized = 1;
|
||||
}
|
||||
|
||||
static int ssl_error(SSL *ssl, int ret)
|
||||
{
|
||||
int e;
|
||||
|
||||
e = SSL_get_error(ssl, ret);
|
||||
|
||||
switch (e)
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_READ", ret);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_WRITE", ret);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
if (ret == 0 && ERR_peek_error() == 0) {
|
||||
upsdebugx(1, "ssl_error() EOF from client");
|
||||
} else {
|
||||
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_SYSCALL", ret);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR %d", ret, e);
|
||||
ssl_debug();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ssl_accept(ctype_t *client)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SSL_accept(client->ssl);
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 1:
|
||||
client->ssl_connected = 1;
|
||||
upsdebugx(3, "SSL connected");
|
||||
return 0;
|
||||
|
||||
case 0:
|
||||
case -1:
|
||||
return ssl_error(client->ssl, ret);
|
||||
}
|
||||
|
||||
upslog_with_errno(LOG_ERR, "Unknown return value from SSL_accept");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ssl_read(ctype_t *client, char *buf, size_t buflen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!client->ssl_connected) {
|
||||
if (ssl_accept(client) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = SSL_read(client->ssl, buf, buflen);
|
||||
|
||||
if (ret < 1) {
|
||||
ssl_error(client->ssl, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ssl_write(ctype_t *client, const char *buf, size_t buflen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = SSL_write(client->ssl, buf, buflen);
|
||||
|
||||
upsdebugx(5, "ssl_write ret=%d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ssl_finish(ctype_t *client)
|
||||
{
|
||||
if (client->ssl) {
|
||||
SSL_free(client->ssl);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSL */
|
||||
40
server/ssl.h
Normal file
40
server/ssl.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* ssl.h - ssl support prototypes for upsd
|
||||
|
||||
Copyright (C) 2002 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SSL_H_SEEN
|
||||
#define SSL_H_SEEN 1
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include "ctype.h"
|
||||
|
||||
extern char *certfile;
|
||||
|
||||
void ssl_init(void);
|
||||
void ssl_finish(ctype_t *client);
|
||||
|
||||
int ssl_read(ctype_t *client, char *buf, size_t buflen);
|
||||
int ssl_write(ctype_t *client, const char *buf, size_t buflen);
|
||||
|
||||
void net_starttls(ctype_t *client, int numarg, const char **arg);
|
||||
|
||||
#endif /* SSL_H_SEEN */
|
||||
382
server/sstate.c
Normal file
382
server/sstate.c
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/* sstate.c - Network UPS Tools server-side state management
|
||||
|
||||
Copyright (C)
|
||||
2003 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "timehead.h"
|
||||
|
||||
#include "upstype.h"
|
||||
#include "sstate.h"
|
||||
#include "state.h"
|
||||
|
||||
static int parse_args(upstype_t *ups, int numargs, char **arg)
|
||||
{
|
||||
if (numargs < 1)
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(arg[0], "PONG")) {
|
||||
upsdebugx(3, "Got PONG from UPS [%s]", ups->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(arg[0], "DUMPDONE")) {
|
||||
upsdebugx(3, "UPS [%s]: dump is done", ups->name);
|
||||
ups->dumpdone = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(arg[0], "DATASTALE")) {
|
||||
ups->data_ok = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(arg[0], "DATAOK")) {
|
||||
ups->data_ok = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (numargs < 2)
|
||||
return 0;
|
||||
|
||||
/* ADDCMD <cmdname> */
|
||||
if (!strcasecmp(arg[0], "ADDCMD")) {
|
||||
state_addcmd(&ups->cmdlist, arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* DELCMD <cmdname> */
|
||||
if (!strcasecmp(arg[0], "DELCMD")) {
|
||||
state_delcmd(&ups->cmdlist, arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* DELINFO <var> */
|
||||
if (!strcasecmp(arg[0], "DELINFO")) {
|
||||
state_delinfo(&ups->inforoot, arg[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (numargs < 3)
|
||||
return 0;
|
||||
|
||||
/* SETFLAGS <varname> <flags>... */
|
||||
if (!strcasecmp(arg[0], "SETFLAGS")) {
|
||||
state_setflags(ups->inforoot, arg[1], numargs - 2, &arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SETINFO <varname> <value> */
|
||||
if (!strcasecmp(arg[0], "SETINFO")) {
|
||||
state_setinfo(&ups->inforoot, arg[1], arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ADDENUM <varname> <enumval> */
|
||||
if (!strcasecmp(arg[0], "ADDENUM")) {
|
||||
state_addenum(ups->inforoot, arg[1], arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* DELENUM <varname> <enumval> */
|
||||
if (!strcasecmp(arg[0], "DELENUM")) {
|
||||
state_delenum(ups->inforoot, arg[1], arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* SETAUX <varname> <auxval> */
|
||||
if (!strcasecmp(arg[0], "SETAUX")) {
|
||||
state_setaux(ups->inforoot, arg[1], arg[2]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* nothing fancy - just make the driver say something back to us */
|
||||
static void sendping(upstype_t *ups)
|
||||
{
|
||||
int ret;
|
||||
const char *cmd = "PING\n";
|
||||
|
||||
if ((!ups) || (ups->sock_fd < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
upsdebugx(3, "Pinging UPS [%s]", ups->name);
|
||||
|
||||
ret = write(ups->sock_fd, cmd, strlen(cmd));
|
||||
|
||||
if (ret != (int)strlen(cmd)) {
|
||||
upslog_with_errno(LOG_NOTICE, "Send ping to UPS [%s] failed", ups->name);
|
||||
sstate_disconnect(ups);
|
||||
return;
|
||||
}
|
||||
|
||||
time(&ups->last_ping);
|
||||
}
|
||||
|
||||
/* interface */
|
||||
|
||||
int sstate_connect(upstype_t *ups)
|
||||
{
|
||||
int ret, fd;
|
||||
const char *dumpcmd = "DUMPALL\n";
|
||||
struct sockaddr_un sa;
|
||||
|
||||
memset(&sa, '\0', sizeof(sa));
|
||||
sa.sun_family = AF_UNIX;
|
||||
snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", ups->fn);
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
upslog_with_errno(LOG_ERR, "Can't create socket for UPS [%s]", ups->name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = connect(fd, (struct sockaddr *) &sa, sizeof(sa));
|
||||
|
||||
if (ret < 0) {
|
||||
time_t now;
|
||||
|
||||
close(fd);
|
||||
|
||||
/* rate-limit complaints - don't spam the syslog */
|
||||
time(&now);
|
||||
if (difftime(now, ups->last_connfail) < SS_CONNFAIL_INT)
|
||||
return -1;
|
||||
|
||||
ups->last_connfail = now;
|
||||
upslog_with_errno(LOG_ERR, "Can't connect to UPS [%s] (%s)",
|
||||
ups->name, ups->fn);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fcntl(fd, F_GETFL, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
upslog_with_errno(LOG_ERR, "fcntl get on UPS [%s] failed", ups->name);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = fcntl(fd, F_SETFL, ret | O_NDELAY);
|
||||
|
||||
if (ret < 0) {
|
||||
upslog_with_errno(LOG_ERR, "fcntl set O_NDELAY on UPS [%s] failed", ups->name);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get a dump started so we have a fresh set of data */
|
||||
ret = write(fd, dumpcmd, strlen(dumpcmd));
|
||||
|
||||
if (ret != (int)strlen(dumpcmd)) {
|
||||
upslog_with_errno(LOG_ERR, "Initial write to UPS [%s] failed", ups->name);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pconf_init(&ups->sock_ctx, NULL);
|
||||
|
||||
ups->dumpdone = 0;
|
||||
ups->stale = 0;
|
||||
|
||||
/* now is the last time we heard something from the driver */
|
||||
time(&ups->last_heard);
|
||||
|
||||
/* set ups.status to "WAIT" while waiting for the driver response to dumpcmd */
|
||||
state_setinfo(&ups->inforoot, "ups.status", "WAIT");
|
||||
|
||||
upslogx(LOG_INFO, "Connected to UPS [%s]: %s", ups->name, ups->fn);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
void sstate_disconnect(upstype_t *ups)
|
||||
{
|
||||
if ((!ups) || (ups->sock_fd < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sstate_infofree(ups);
|
||||
sstate_cmdfree(ups);
|
||||
|
||||
pconf_finish(&ups->sock_ctx);
|
||||
|
||||
close(ups->sock_fd);
|
||||
ups->sock_fd = -1;
|
||||
}
|
||||
|
||||
void sstate_readline(upstype_t *ups)
|
||||
{
|
||||
int i, ret;
|
||||
char buf[SMALLBUF];
|
||||
|
||||
if ((!ups) || (ups->sock_fd < 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = read(ups->sock_fd, buf, sizeof(buf));
|
||||
|
||||
if (ret < 0) {
|
||||
switch(errno)
|
||||
{
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
return;
|
||||
|
||||
default:
|
||||
upslog_with_errno(LOG_WARNING, "Read from UPS [%s] failed", ups->name);
|
||||
sstate_disconnect(ups);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ret; i++) {
|
||||
|
||||
switch (pconf_char(&ups->sock_ctx, buf[i]))
|
||||
{
|
||||
case 1:
|
||||
/* set the 'last heard' time to now for later staleness checks */
|
||||
if (parse_args(ups, ups->sock_ctx.numargs, ups->sock_ctx.arglist)) {
|
||||
time(&ups->last_heard);
|
||||
}
|
||||
continue;
|
||||
|
||||
case 0:
|
||||
continue; /* haven't gotten a line yet */
|
||||
|
||||
default:
|
||||
/* parse error */
|
||||
upslogx(LOG_NOTICE, "Parse error on sock: %s", ups->sock_ctx.errmsg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *sstate_getinfo(const upstype_t *ups, const char *var)
|
||||
{
|
||||
return state_getinfo(ups->inforoot, var);
|
||||
}
|
||||
|
||||
int sstate_getflags(const upstype_t *ups, const char *var)
|
||||
{
|
||||
return state_getflags(ups->inforoot, var);
|
||||
}
|
||||
|
||||
int sstate_getaux(const upstype_t *ups, const char *var)
|
||||
{
|
||||
return state_getaux(ups->inforoot, var);
|
||||
}
|
||||
|
||||
const struct enum_t *sstate_getenumlist(const upstype_t *ups, const char *var)
|
||||
{
|
||||
return state_getenumlist(ups->inforoot, var);
|
||||
}
|
||||
|
||||
const struct cmdlist_t *sstate_getcmdlist(const upstype_t *ups)
|
||||
{
|
||||
return ups->cmdlist;
|
||||
}
|
||||
|
||||
int sstate_dead(upstype_t *ups, int maxage)
|
||||
{
|
||||
time_t now;
|
||||
double elapsed;
|
||||
|
||||
/* an unconnected ups is always dead */
|
||||
if (ups->sock_fd < 0) {
|
||||
upsdebugx(3, "sstate_dead: connection to driver socket for UPS [%s] lost", ups->name);
|
||||
return 1; /* dead */
|
||||
}
|
||||
|
||||
time(&now);
|
||||
|
||||
/* ignore DATAOK/DATASTALE unless the dump is done */
|
||||
if ((ups->dumpdone) && (!ups->data_ok)) {
|
||||
upsdebugx(3, "sstate_dead: driver for UPS [%s] says data is stale", ups->name);
|
||||
return 1; /* dead */
|
||||
}
|
||||
|
||||
elapsed = difftime(now, ups->last_heard);
|
||||
|
||||
/* somewhere beyond a third of the maximum time - prod it to make it talk */
|
||||
if ((elapsed > (maxage / 3)) && (difftime(now, ups->last_ping) > (maxage / 3)))
|
||||
sendping(ups);
|
||||
|
||||
if (elapsed > maxage) {
|
||||
upsdebugx(3, "sstate_dead: didn't hear from driver for UPS [%s] for %g seconds (max %d)",
|
||||
ups->name, elapsed, maxage);
|
||||
return 1; /* dead */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* release all info(tree) data used by <ups> */
|
||||
void sstate_infofree(upstype_t *ups)
|
||||
{
|
||||
state_infofree(ups->inforoot);
|
||||
|
||||
ups->inforoot = NULL;
|
||||
}
|
||||
|
||||
void sstate_cmdfree(upstype_t *ups)
|
||||
{
|
||||
state_cmdfree(ups->cmdlist);
|
||||
|
||||
ups->cmdlist = NULL;
|
||||
}
|
||||
|
||||
int sstate_sendline(upstype_t *ups, const char *buf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((!ups) ||(ups->sock_fd < 0)) {
|
||||
return 0; /* failed */
|
||||
}
|
||||
|
||||
ret = write(ups->sock_fd, buf, strlen(buf));
|
||||
|
||||
if (ret == (int)strlen(buf)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
upslog_with_errno(LOG_NOTICE, "Send to UPS [%s] failed", ups->name);
|
||||
sstate_disconnect(ups);
|
||||
|
||||
return 0; /* failed */
|
||||
}
|
||||
|
||||
const struct st_tree_t *sstate_getnode(const upstype_t *ups, const char *varname)
|
||||
{
|
||||
return state_tree_find(ups->inforoot, varname);
|
||||
}
|
||||
43
server/sstate.h
Normal file
43
server/sstate.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* sstate.h - Network UPS Tools server-side state management
|
||||
|
||||
Copyright (C)
|
||||
2003 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "upstype.h"
|
||||
|
||||
#define SS_CONNFAIL_INT 300 /* complain about a dead driver every 5 mins */
|
||||
#define SS_MAX_READ 256 /* don't let drivers tie us up in read() */
|
||||
|
||||
int sstate_connect(upstype_t *ups);
|
||||
void sstate_disconnect(upstype_t *ups);
|
||||
void sstate_readline(upstype_t *ups);
|
||||
const char *sstate_getinfo(const upstype_t *ups, const char *var);
|
||||
int sstate_getflags(const upstype_t *ups, const char *var);
|
||||
int sstate_getaux(const upstype_t *ups, const char *var);
|
||||
const struct enum_t *sstate_getenumlist(const upstype_t *ups, const char *var);
|
||||
const struct cmdlist_t *sstate_getcmdlist(const upstype_t *ups);
|
||||
void sstate_makeinfolist(const upstype_t *ups, char *buf, size_t bufsize);
|
||||
void sstate_makerwlist(const upstype_t *ups, char *buf, size_t bufsize);
|
||||
void sstate_makeinstcmdlist_t(const upstype_t *ups, char *buf, size_t bufsize);
|
||||
int sstate_dead(upstype_t *ups, int maxage);
|
||||
void sstate_infofree(upstype_t *ups);
|
||||
void sstate_cmdfree(upstype_t *ups);
|
||||
int sstate_sendline(upstype_t *ups, const char *buf);
|
||||
const struct st_tree_t *sstate_getnode(const upstype_t *ups, const char *varname);
|
||||
|
||||
41
server/stype.h
Normal file
41
server/stype.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* stype.h - server data definitions for upsd
|
||||
|
||||
Copyright (C)
|
||||
2007 Arjen de Korte <arjen@de-korte.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef STYPE_H_SEEN
|
||||
#define STYPE_H_SEEN 1
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
typedef struct stype_s {
|
||||
char *addr;
|
||||
char *port;
|
||||
int sock_fd;
|
||||
struct stype_s *next;
|
||||
} stype_t;
|
||||
|
||||
#endif /* STYPE_H_SEEN */
|
||||
1091
server/upsd.c
Normal file
1091
server/upsd.c
Normal file
File diff suppressed because it is too large
Load diff
87
server/upsd.h
Normal file
87
server/upsd.h
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/* upsd.h - support structures and other minor details
|
||||
|
||||
Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Much of the content from here was also useful to the
|
||||
* drivers, so has been moved into include/shared-tables.h
|
||||
* instead of being within the daemon specific include file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UPSD_H_SEEN
|
||||
#define UPSD_H_SEEN
|
||||
|
||||
#include "attribute.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "timehead.h"
|
||||
|
||||
#include <sys/file.h>
|
||||
|
||||
#include "parseconf.h"
|
||||
#include "ctype.h"
|
||||
#include "upstype.h"
|
||||
|
||||
#define NUT_NET_ANSWER_MAX SMALLBUF
|
||||
|
||||
/* prototypes from upsd.c */
|
||||
|
||||
upstype_t *get_ups_ptr(const char *upsname);
|
||||
int ups_available(const upstype_t *ups, ctype_t *client);
|
||||
|
||||
void listen_add(const char *addr, const char *port);
|
||||
|
||||
void kick_login_clients(const char *upsname);
|
||||
int sendback(ctype_t *client, const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||
int send_err(ctype_t *client, const char *errtype);
|
||||
|
||||
void server_load(void);
|
||||
void server_free(void);
|
||||
|
||||
void check_perms(const char *fn);
|
||||
|
||||
/* declarations from upsd.c */
|
||||
|
||||
extern int maxage, maxconn;
|
||||
extern char *statepath, *datapath;
|
||||
extern upstype_t *firstups;
|
||||
|
||||
/* map commands onto signals */
|
||||
|
||||
#define SIGCMD_STOP SIGTERM
|
||||
#define SIGCMD_RELOAD SIGHUP
|
||||
|
||||
/* awkward way to make a string out of a numeric constant */
|
||||
|
||||
#define string_const_aux(x) #x
|
||||
#define string_const(x) string_const_aux(x)
|
||||
|
||||
#ifdef SHUT_RDWR
|
||||
#define shutdown_how SHUT_RDWR
|
||||
#else
|
||||
#define shutdown_how 2
|
||||
#endif
|
||||
|
||||
#endif /* UPSD_H_SEEN */
|
||||
55
server/upstype.h
Normal file
55
server/upstype.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* upstype.h - internal UPS tracking structure details
|
||||
|
||||
Copyright (C)
|
||||
2003 Russell Kroll <rkroll@exploits.org>
|
||||
2008 Arjen de Korte <adkorte-guest@alioth.debian.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef UPSTYPE_H_SEEN
|
||||
#define UPSTYPE_H_SEEN 1
|
||||
|
||||
#include "parseconf.h"
|
||||
|
||||
/* structure for the linked list of each UPS that we track */
|
||||
typedef struct upstype_s {
|
||||
char *name;
|
||||
char *fn;
|
||||
char *desc;
|
||||
|
||||
int sock_fd;
|
||||
int stale;
|
||||
int dumpdone;
|
||||
int data_ok;
|
||||
time_t last_heard;
|
||||
time_t last_ping;
|
||||
time_t last_connfail;
|
||||
PCONF_CTX_t sock_ctx;
|
||||
struct st_tree_t *inforoot;
|
||||
struct cmdlist_t *cmdlist;
|
||||
|
||||
int numlogins;
|
||||
int fsd; /* forced shutdown in effect? */
|
||||
|
||||
int retain;
|
||||
|
||||
struct upstype_s *next;
|
||||
|
||||
} upstype_t;
|
||||
|
||||
extern upstype_t *firstups;
|
||||
|
||||
#endif /* UPSTYPE_H_SEEN */
|
||||
36
server/user-data.h
Normal file
36
server/user-data.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* user-data.h - structures for user.c
|
||||
|
||||
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *cmd;
|
||||
void *next;
|
||||
} instcmdlist_t;
|
||||
|
||||
typedef struct {
|
||||
char *action;
|
||||
void *next;
|
||||
} actionlist_t;
|
||||
|
||||
typedef struct {
|
||||
char *username;
|
||||
char *password;
|
||||
instcmdlist_t *firstcmd;
|
||||
actionlist_t *firstaction;
|
||||
void *next;
|
||||
} ulist_t;
|
||||
491
server/user.c
Normal file
491
server/user.c
Normal file
|
|
@ -0,0 +1,491 @@
|
|||
/* user.c - user handling functions for upsd
|
||||
|
||||
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "parseconf.h"
|
||||
|
||||
#include "user.h"
|
||||
#include "user-data.h"
|
||||
|
||||
ulist_t *users = NULL;
|
||||
|
||||
static ulist_t *curr_user;
|
||||
|
||||
/* create a new user entry */
|
||||
static void user_add(const char *un)
|
||||
{
|
||||
ulist_t *tmp, *last = NULL;
|
||||
|
||||
if (!un) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (tmp = users; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
last = tmp;
|
||||
|
||||
if (!strcmp(tmp->username, un)) {
|
||||
fprintf(stderr, "Ignoring duplicate user %s\n", un);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = xcalloc(1, sizeof(*tmp));
|
||||
tmp->username = xstrdup(un);
|
||||
|
||||
if (last) {
|
||||
last->next = tmp;
|
||||
} else {
|
||||
users = tmp;
|
||||
}
|
||||
|
||||
/* remember who we're working on */
|
||||
curr_user = tmp;
|
||||
}
|
||||
|
||||
/* set password */
|
||||
static void user_password(const char *pw)
|
||||
{
|
||||
if (!curr_user) {
|
||||
upslogx(LOG_WARNING, "Ignoring password definition outside "
|
||||
"user section");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pw) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (curr_user->password) {
|
||||
fprintf(stderr, "Ignoring duplicate password for %s\n",
|
||||
curr_user->username);
|
||||
return;
|
||||
}
|
||||
|
||||
curr_user->password = xstrdup(pw);
|
||||
}
|
||||
|
||||
/* attach allowed instcmds to user */
|
||||
static void user_add_instcmd(const char *cmd)
|
||||
{
|
||||
instcmdlist_t *tmp, *last = NULL;
|
||||
|
||||
if (!curr_user) {
|
||||
upslogx(LOG_WARNING, "Ignoring instcmd definition outside "
|
||||
"user section");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cmd) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (tmp = curr_user->firstcmd; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
last = tmp;
|
||||
|
||||
/* ignore duplicates */
|
||||
if (!strcasecmp(tmp->cmd, cmd)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tmp = xcalloc(1, sizeof(*tmp));
|
||||
|
||||
tmp->cmd = xstrdup(cmd);
|
||||
|
||||
if (last) {
|
||||
last->next = tmp;
|
||||
} else {
|
||||
curr_user->firstcmd = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static actionlist_t *addaction(actionlist_t *base, const char *action)
|
||||
{
|
||||
actionlist_t *tmp, *last = NULL;
|
||||
|
||||
if (!action) {
|
||||
return base;
|
||||
}
|
||||
|
||||
for (tmp = base; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
last = tmp;
|
||||
}
|
||||
|
||||
tmp = xcalloc(1, sizeof(*tmp));
|
||||
tmp->action = xstrdup(action);
|
||||
|
||||
if (last) {
|
||||
last->next = tmp;
|
||||
return base;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* attach allowed actions to user */
|
||||
static void user_add_action(const char *act)
|
||||
{
|
||||
if (!curr_user) {
|
||||
upslogx(LOG_WARNING, "Ignoring action definition outside "
|
||||
"user section");
|
||||
return;
|
||||
}
|
||||
|
||||
curr_user->firstaction = addaction(curr_user->firstaction, act);
|
||||
}
|
||||
|
||||
static void flushcmd(instcmdlist_t *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
flushcmd(ptr->next);
|
||||
|
||||
free(ptr->cmd);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void flushaction(actionlist_t *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
flushaction(ptr->next);
|
||||
|
||||
free(ptr->action);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static void flushuser(ulist_t *ptr)
|
||||
{
|
||||
if (!ptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
flushuser(ptr->next);
|
||||
flushcmd(ptr->firstcmd);
|
||||
flushaction(ptr->firstaction);
|
||||
|
||||
free(ptr->username);
|
||||
free(ptr->password);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
/* flush all user attributes - used during reload */
|
||||
void user_flush(void)
|
||||
{
|
||||
flushuser(users);
|
||||
users = NULL;
|
||||
}
|
||||
|
||||
static int user_matchinstcmd(ulist_t *user, const char * cmd)
|
||||
{
|
||||
instcmdlist_t *tmp;
|
||||
|
||||
for (tmp = user->firstcmd; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
if (!strcasecmp(tmp->cmd, cmd)) {
|
||||
return 1; /* good */
|
||||
}
|
||||
|
||||
if (!strcasecmp(tmp->cmd, "all")) {
|
||||
return 1; /* good */
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
int user_checkinstcmd(const char *un, const char *pw, const char *cmd)
|
||||
{
|
||||
ulist_t *tmp;
|
||||
|
||||
if ((!un) || (!pw) || (!cmd)) {
|
||||
return 0; /* failed */
|
||||
}
|
||||
|
||||
for (tmp = users; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
/* let's be paranoid before we call strcmp */
|
||||
|
||||
if ((!tmp->username) || (!tmp->password)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(tmp->username, un)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (strcmp(tmp->password, pw)) {
|
||||
/* password mismatch */
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
if (!user_matchinstcmd(tmp, cmd)) {
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
/* passed all checks */
|
||||
return 1; /* good */
|
||||
}
|
||||
|
||||
/* username not found */
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
static int user_matchaction(ulist_t *user, const char *action)
|
||||
{
|
||||
actionlist_t *tmp;
|
||||
|
||||
for (tmp = user->firstaction; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
if (!strcasecmp(tmp->action, action)) {
|
||||
return 1; /* good */
|
||||
}
|
||||
}
|
||||
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
int user_checkaction(const char *un, const char *pw, const char *action)
|
||||
{
|
||||
ulist_t *tmp;
|
||||
|
||||
if ((!un) || (!pw) || (!action))
|
||||
return 0; /* failed */
|
||||
|
||||
for (tmp = users; tmp != NULL; tmp = tmp->next) {
|
||||
|
||||
/* let's be paranoid before we call strcmp */
|
||||
|
||||
if ((!tmp->username) || (!tmp->password)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(tmp->username, un)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(tmp->password, pw)) {
|
||||
upsdebugx(2, "user_checkaction: password mismatch");
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
if (!user_matchaction(tmp, action)) {
|
||||
upsdebugx(2, "user_matchaction: failed");
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
/* passed all checks */
|
||||
return 1; /* good */
|
||||
}
|
||||
|
||||
/* username not found */
|
||||
return 0; /* fail */
|
||||
}
|
||||
|
||||
/* handle "upsmon master" and "upsmon slave" for nicer configurations */
|
||||
static void set_upsmon_type(char *type)
|
||||
{
|
||||
/* master: login, master, fsd */
|
||||
if (!strcasecmp(type, "master")) {
|
||||
user_add_action("login");
|
||||
user_add_action("master");
|
||||
user_add_action("fsd");
|
||||
return;
|
||||
}
|
||||
|
||||
/* slave: just login */
|
||||
if (!strcasecmp(type, "slave")) {
|
||||
user_add_action("login");
|
||||
return;
|
||||
}
|
||||
|
||||
upslogx(LOG_WARNING, "Unknown upsmon type %s", type);
|
||||
}
|
||||
|
||||
/* actually do something with the variable + value pairs */
|
||||
static void parse_var(char *var, char *val)
|
||||
{
|
||||
if (!strcasecmp(var, "password")) {
|
||||
user_password(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "instcmds")) {
|
||||
user_add_instcmd(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "actions")) {
|
||||
user_add_action(val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(var, "allowfrom")) {
|
||||
upslogx(LOG_WARNING, "allowfrom in upsd.users is no longer used");
|
||||
return;
|
||||
}
|
||||
|
||||
/* someone did 'upsmon = type' - allow it anyway */
|
||||
if (!strcasecmp(var, "upsmon")) {
|
||||
set_upsmon_type(val);
|
||||
return;
|
||||
}
|
||||
|
||||
upslogx(LOG_NOTICE, "Unrecognized user setting %s", var);
|
||||
}
|
||||
|
||||
/* parse first var+val pair, then flip through remaining vals */
|
||||
static void parse_rest(char *var, char *fval, char **arg, int next, int left)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* no globals supported yet, so there's no sense in continuing */
|
||||
if (!curr_user) {
|
||||
return;
|
||||
}
|
||||
|
||||
parse_var(var, fval);
|
||||
|
||||
if (left == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < left; i++) {
|
||||
parse_var(var, arg[next + i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void user_parse_arg(int numargs, char **arg)
|
||||
{
|
||||
char *ep;
|
||||
|
||||
if ((numargs == 0) || (!arg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ignore old file format */
|
||||
if (!strcasecmp(arg[0], "user")) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle 'foo=bar' (compressed form) */
|
||||
|
||||
ep = strchr(arg[0], '=');
|
||||
if (ep) {
|
||||
*ep = '\0';
|
||||
|
||||
/* parse first var/val, plus subsequent values (if any) */
|
||||
|
||||
/* 0 1 2 ... */
|
||||
/* foo=bar <rest1> <rest2> ... */
|
||||
|
||||
parse_rest(arg[0], ep+1, arg, 1, numargs - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* look for section headers - [username] */
|
||||
if ((arg[0][0] == '[') && (arg[0][strlen(arg[0])-1] == ']')) {
|
||||
|
||||
arg[0][strlen(arg[0])-1] = '\0';
|
||||
user_add(&arg[0][1]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (numargs < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcasecmp(arg[0], "upsmon")) {
|
||||
set_upsmon_type(arg[1]);
|
||||
}
|
||||
|
||||
/* everything after here needs arg[1] and arg[2] */
|
||||
if (numargs < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* handle 'foo = bar' (split form) */
|
||||
if (!strcmp(arg[1], "=")) {
|
||||
|
||||
/* 0 1 2 3 4 ... */
|
||||
/* foo = bar <rest1> <rest2> ... */
|
||||
|
||||
/* parse first var/val, plus subsequent values (if any) */
|
||||
|
||||
parse_rest(arg[0], arg[2], arg, 3, numargs - 3);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ... unhandled ... */
|
||||
}
|
||||
|
||||
/* called for fatal errors in parseconf like malloc failures */
|
||||
static void upsd_user_err(const char *errmsg)
|
||||
{
|
||||
upslogx(LOG_ERR, "Fatal error in parseconf(upsd.users): %s", errmsg);
|
||||
}
|
||||
|
||||
void user_load(void)
|
||||
{
|
||||
char fn[SMALLBUF];
|
||||
PCONF_CTX_t ctx;
|
||||
|
||||
curr_user = NULL;
|
||||
|
||||
snprintf(fn, sizeof(fn), "%s/upsd.users", confpath());
|
||||
|
||||
check_perms(fn);
|
||||
|
||||
pconf_init(&ctx, upsd_user_err);
|
||||
|
||||
if (!pconf_file_begin(&ctx, fn)) {
|
||||
|
||||
pconf_finish(&ctx);
|
||||
|
||||
upslogx(LOG_WARNING, "%s", ctx.errmsg);
|
||||
return;
|
||||
}
|
||||
|
||||
while (pconf_file_next(&ctx)) {
|
||||
|
||||
if (pconf_parse_error(&ctx)) {
|
||||
upslogx(LOG_ERR, "Parse error: %s:%d: %s",
|
||||
fn, ctx.linenum, ctx.errmsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
user_parse_arg(ctx.numargs, ctx.arglist);
|
||||
}
|
||||
|
||||
pconf_finish(&ctx);
|
||||
}
|
||||
28
server/user.h
Normal file
28
server/user.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* user.c - supporting elements of user handling functions for upsd
|
||||
|
||||
Copyright (C) 2001 Russell Kroll <rkroll@exploits.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
void user_load(void);
|
||||
|
||||
int user_checkinstcmd(const char *un, const char *pw, const char *cmd);
|
||||
int user_checkaction(const char *un, const char *pw, const char *action);
|
||||
|
||||
void user_flush(void);
|
||||
|
||||
/* cheat - we don't want the full upsd.h included here */
|
||||
void check_perms(const char *fn);
|
||||
Loading…
Add table
Add a link
Reference in a new issue