new upstream 2.8.0

This commit is contained in:
lagertonne 2022-06-29 12:37:36 +02:00
parent fc7f4b43c1
commit b2b0c9995a
836 changed files with 137090 additions and 30018 deletions

View file

@ -8,10 +8,42 @@ libparseconf_la_SOURCES = parseconf.c
# do not hard depend on '../include/nut_version.h', since it blocks
# 'dist', and is only required for actual build, in which case
# BUILT_SOURCES (in ../include) will ensure nut_version.h will
# be built before anything else
libcommon_la_SOURCES = common.c state.c str.c upsconf.c
libcommonclient_la_SOURCES = common.c state.c str.c
# be built before anything else... but do depend on its build area:
if BUILDING_IN_TREE
# No need for symlink hack
common.c: $(top_builddir)/include/nut_version.h
else
# Surprisingly, for some "make" implementations this dependency means
# that the "common.c" required for builds below will be seeked in the
# current directory. So for out-of-tree builds like distcheck, we have
# to symlink the "real" source to build area:
common.c: $(top_builddir)/include/nut_version.h $(srcdir)/common.c
test -s "$@" || ln -s -f "$(top_srcdir)/common/common.c" "$@"
endif
$(top_builddir)/include/nut_version.h:
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
libcommon_la_SOURCES = state.c str.c upsconf.c
libcommonclient_la_SOURCES = state.c str.c
if BUILDING_IN_TREE
libcommon_la_SOURCES += common.c
libcommonclient_la_SOURCES += common.c
else
nodist_libcommon_la_SOURCES = common.c
nodist_libcommonclient_la_SOURCES = common.c
CLEANFILES = $(top_builddir)/common/common.c
BUILT_SOURCES = common.c
endif
# ensure inclusion of local implementation of missing systems functions
# using LTLIBOBJS. Refer to configure.in -> AC_REPLACE_FUNCS
# using LTLIBOBJS. Refer to configure.in/.ac -> AC_REPLACE_FUNCS
libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@
libcommonclient_la_LIBADD = libparseconf.la @LTLIBOBJS@
MAINTAINERCLEANFILES = Makefile.in .dirstamp
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
# the root Makefile.am takes care of that!
#clean-local:
# rm -rf $(builddir)/.deps

View file

@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# Makefile.in generated by automake 1.16.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -17,7 +17,17 @@
# Network UPS Tools: common
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@ -81,20 +91,27 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
@BUILDING_IN_TREE_TRUE@am__append_1 = common.c
@BUILDING_IN_TREE_TRUE@am__append_2 = common.c
subdir = common
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am atexit.c \
snprintf.c setenv.c strerror.c $(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_c___attribute__.m4 \
$(top_srcdir)/m4/ax_c_pragmas.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_compare_version.m4 \
$(top_srcdir)/m4/ax_run_or_link_ifelse.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
$(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nut_arg_with.m4 \
$(top_srcdir)/m4/nut_check_asciidoc.m4 \
$(top_srcdir)/m4/nut_check_cppcheck.m4 \
$(top_srcdir)/m4/nut_check_headers_windows.m4 \
$(top_srcdir)/m4/nut_check_libavahi.m4 \
$(top_srcdir)/m4/nut_check_libfreeipmi.m4 \
$(top_srcdir)/m4/nut_check_libgd.m4 \
$(top_srcdir)/m4/nut_check_libltdl.m4 \
$(top_srcdir)/m4/nut_check_libmodbus.m4 \
$(top_srcdir)/m4/nut_check_libneon.m4 \
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
$(top_srcdir)/m4/nut_check_libnss.m4 \
@ -103,26 +120,39 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
$(top_srcdir)/m4/nut_check_libusb.m4 \
$(top_srcdir)/m4/nut_check_libwrap.m4 \
$(top_srcdir)/m4/nut_check_os.m4 \
$(top_srcdir)/m4/nut_check_pkgconfig.m4 \
$(top_srcdir)/m4/nut_check_python.m4 \
$(top_srcdir)/m4/nut_compiler_family.m4 \
$(top_srcdir)/m4/nut_func_getnameinfo_argtypes.m4 \
$(top_srcdir)/m4/nut_report_feature.m4 \
$(top_srcdir)/m4/nut_stash_warnings.m4 \
$(top_srcdir)/m4/nut_type_socklen_t.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libcommon_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@
am_libcommon_la_OBJECTS = common.lo state.lo str.lo upsconf.lo
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
am__libcommon_la_SOURCES_DIST = state.c str.c upsconf.c common.c
@BUILDING_IN_TREE_TRUE@am__objects_1 = common.lo
am_libcommon_la_OBJECTS = state.lo str.lo upsconf.lo $(am__objects_1)
@BUILDING_IN_TREE_FALSE@nodist_libcommon_la_OBJECTS = common.lo
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) \
$(nodist_libcommon_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libcommonclient_la_DEPENDENCIES = libparseconf.la @LTLIBOBJS@
am_libcommonclient_la_OBJECTS = common.lo state.lo str.lo
libcommonclient_la_OBJECTS = $(am_libcommonclient_la_OBJECTS)
am__libcommonclient_la_SOURCES_DIST = state.c str.c common.c
am_libcommonclient_la_OBJECTS = state.lo str.lo $(am__objects_1)
@BUILDING_IN_TREE_FALSE@nodist_libcommonclient_la_OBJECTS = common.lo
libcommonclient_la_OBJECTS = $(am_libcommonclient_la_OBJECTS) \
$(nodist_libcommonclient_la_OBJECTS)
libparseconf_la_LIBADD =
am_libparseconf_la_OBJECTS = parseconf.lo
libparseconf_la_OBJECTS = $(am_libparseconf_la_OBJECTS)
@ -140,7 +170,12 @@ am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__maybe_remake_depfiles = depfiles
am__depfiles_remade = $(DEPDIR)/atexit.Plo $(DEPDIR)/setenv.Plo \
$(DEPDIR)/snprintf.Plo $(DEPDIR)/strerror.Plo \
./$(DEPDIR)/common.Plo ./$(DEPDIR)/parseconf.Plo \
./$(DEPDIR)/state.Plo ./$(DEPDIR)/str.Plo \
./$(DEPDIR)/upsconf.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -160,9 +195,12 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libcommon_la_SOURCES) $(libcommonclient_la_SOURCES) \
SOURCES = $(libcommon_la_SOURCES) $(nodist_libcommon_la_SOURCES) \
$(libcommonclient_la_SOURCES) \
$(nodist_libcommonclient_la_SOURCES) \
$(libparseconf_la_SOURCES)
DIST_SOURCES = $(libcommon_la_SOURCES) $(libcommonclient_la_SOURCES) \
DIST_SOURCES = $(am__libcommon_la_SOURCES_DIST) \
$(am__libcommonclient_la_SOURCES_DIST) \
$(libparseconf_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
@ -188,6 +226,8 @@ am__define_uniq_tagged_files = \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp atexit.c \
setenv.c snprintf.c strerror.c
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
A2X = @A2X@
ACLOCAL = @ACLOCAL@
@ -196,6 +236,7 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
ASCIIDOC = @ASCIIDOC@
ASPELL = @ASPELL@
AUGPARSE = @AUGPARSE@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@ -206,6 +247,7 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONFPATH = @CONFPATH@
CPP = @CPP@
CPPCHECK = @CPPCHECK@
CPPFLAGS = @CPPFLAGS@
CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
CPPUNIT_LIBS = @CPPUNIT_LIBS@
@ -219,6 +261,7 @@ DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DOC_BUILD_LIST = @DOC_BUILD_LIST@
DOC_CHECK_LIST = @DOC_CHECK_LIST@
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
@ -231,6 +274,7 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GDLIB_CONFIG = @GDLIB_CONFIG@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -248,6 +292,8 @@ LIBIPMI_CFLAGS = @LIBIPMI_CFLAGS@
LIBIPMI_LIBS = @LIBIPMI_LIBS@
LIBLTDL_CFLAGS = @LIBLTDL_CFLAGS@
LIBLTDL_LIBS = @LIBLTDL_LIBS@
LIBMODBUS_CFLAGS = @LIBMODBUS_CFLAGS@
LIBMODBUS_LIBS = @LIBMODBUS_LIBS@
LIBNEON_CFLAGS = @LIBNEON_CFLAGS@
LIBNEON_LIBS = @LIBNEON_LIBS@
LIBNETSNMP_CFLAGS = @LIBNETSNMP_CFLAGS@
@ -258,21 +304,29 @@ LIBPOWERMAN_LIBS = @LIBPOWERMAN_LIBS@
LIBS = @LIBS@
LIBSSL_CFLAGS = @LIBSSL_CFLAGS@
LIBSSL_LIBS = @LIBSSL_LIBS@
LIBSSL_REQUIRES = @LIBSSL_REQUIRES@
LIBTOOL = @LIBTOOL@
LIBTOOL_DEPS = @LIBTOOL_DEPS@
LIBUSB_CFLAGS = @LIBUSB_CFLAGS@
LIBUSB_CONFIG = @LIBUSB_CONFIG@
LIBUSB_LIBS = @LIBUSB_LIBS@
LIBWRAP_CFLAGS = @LIBWRAP_CFLAGS@
LIBWRAP_LIBS = @LIBWRAP_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LN_S_R = @LN_S_R@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NETLIBS = @NETLIBS@
NET_SNMP_CONFIG = @NET_SNMP_CONFIG@
NM = @NM@
NMEDIT = @NMEDIT@
NUT_DATADIR = @NUT_DATADIR@
NUT_LIBEXECDIR = @NUT_LIBEXECDIR@
NUT_NETVERSION = @NUT_NETVERSION@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
@ -292,6 +346,9 @@ PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PORT = @PORT@
PYTHON = @PYTHON@
PYTHON2 = @PYTHON2@
PYTHON3 = @PYTHON3@
RANLIB = @RANLIB@
RUN_AS_GROUP = @RUN_AS_GROUP@
RUN_AS_USER = @RUN_AS_USER@
@ -305,6 +362,7 @@ STATEPATH = @STATEPATH@
STRIP = @STRIP@
SUN_LIBUSB = @SUN_LIBUSB@
TREE_VERSION = @TREE_VERSION@
VALGRIND = @VALGRIND@
VERSION = @VERSION@
WORDS_BIGENDIAN = @WORDS_BIGENDIAN@
XMLLINT = @XMLLINT@
@ -322,6 +380,7 @@ am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
auglensdir = @auglensdir@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@ -335,6 +394,9 @@ datarootdir = @datarootdir@
devddir = @devddir@
docdir = @docdir@
driverexecdir = @driverexecdir@
dummy_PKG_CONFIG = @dummy_PKG_CONFIG@
dummy_PKG_CONFIG_CFLAGS = @dummy_PKG_CONFIG_CFLAGS@
dummy_PKG_CONFIG_LIBS = @dummy_PKG_CONFIG_LIBS@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
@ -360,12 +422,14 @@ pkgconfigdir = @pkgconfigdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
systemdsystemshutdowndir = @systemdsystemshutdowndir@
systemdshutdowndir = @systemdshutdowndir@
systemdsystemunitdir = @systemdsystemunitdir@
systemdtmpfilesdir = @systemdtmpfilesdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
@ -378,18 +442,20 @@ udevdir = @udevdir@
AM_CFLAGS = -I$(top_srcdir)/include
noinst_LTLIBRARIES = libparseconf.la libcommon.la libcommonclient.la
libparseconf_la_SOURCES = parseconf.c
libcommon_la_SOURCES = state.c str.c upsconf.c $(am__append_1)
libcommonclient_la_SOURCES = state.c str.c $(am__append_2)
@BUILDING_IN_TREE_FALSE@nodist_libcommon_la_SOURCES = common.c
@BUILDING_IN_TREE_FALSE@nodist_libcommonclient_la_SOURCES = common.c
@BUILDING_IN_TREE_FALSE@CLEANFILES = $(top_builddir)/common/common.c
@BUILDING_IN_TREE_FALSE@BUILT_SOURCES = common.c
# do not hard depend on '../include/nut_version.h', since it blocks
# 'dist', and is only required for actual build, in which case
# BUILT_SOURCES (in ../include) will ensure nut_version.h will
# be built before anything else
libcommon_la_SOURCES = common.c state.c str.c upsconf.c
libcommonclient_la_SOURCES = common.c state.c str.c
# ensure inclusion of local implementation of missing systems functions
# using LTLIBOBJS. Refer to configure.in -> AC_REPLACE_FUNCS
# using LTLIBOBJS. Refer to configure.in/.ac -> AC_REPLACE_FUNCS
libcommon_la_LIBADD = libparseconf.la @LTLIBOBJS@
libcommonclient_la_LIBADD = libparseconf.la @LTLIBOBJS@
all: all-am
MAINTAINERCLEANFILES = Makefile.in .dirstamp
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
@ -405,14 +471,13 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu common/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu common/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
@ -450,15 +515,21 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/atexit.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setenv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parseconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/atexit.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/setenv.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/strerror.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parseconf.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upsconf.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
am--depfiles: $(am__depfiles_remade)
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -542,7 +613,10 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
@ -573,11 +647,14 @@ distdir: $(DISTFILES)
fi; \
done
check-am: all-am
check: check-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-exec-am
install-data: install-data-am
uninstall: uninstall-am
@ -598,6 +675,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@ -606,13 +684,23 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf $(DEPDIR) ./$(DEPDIR)
-rm -f $(DEPDIR)/atexit.Plo
-rm -f $(DEPDIR)/setenv.Plo
-rm -f $(DEPDIR)/snprintf.Plo
-rm -f $(DEPDIR)/strerror.Plo
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/parseconf.Plo
-rm -f ./$(DEPDIR)/state.Plo
-rm -f ./$(DEPDIR)/str.Plo
-rm -f ./$(DEPDIR)/upsconf.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@ -658,7 +746,15 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf $(DEPDIR) ./$(DEPDIR)
-rm -f $(DEPDIR)/atexit.Plo
-rm -f $(DEPDIR)/setenv.Plo
-rm -f $(DEPDIR)/snprintf.Plo
-rm -f $(DEPDIR)/strerror.Plo
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/parseconf.Plo
-rm -f ./$(DEPDIR)/state.Plo
-rm -f ./$(DEPDIR)/str.Plo
-rm -f ./$(DEPDIR)/upsconf.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
@ -677,22 +773,45 @@ ps-am:
uninstall-am:
.MAKE: install-am install-strip
.MAKE: all check install install-am install-exec install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# do not hard depend on '../include/nut_version.h', since it blocks
# 'dist', and is only required for actual build, in which case
# BUILT_SOURCES (in ../include) will ensure nut_version.h will
# be built before anything else... but do depend on its build area:
# No need for symlink hack
@BUILDING_IN_TREE_TRUE@common.c: $(top_builddir)/include/nut_version.h
# Surprisingly, for some "make" implementations this dependency means
# that the "common.c" required for builds below will be seeked in the
# current directory. So for out-of-tree builds like distcheck, we have
# to symlink the "real" source to build area:
@BUILDING_IN_TREE_FALSE@common.c: $(top_builddir)/include/nut_version.h $(srcdir)/common.c
@BUILDING_IN_TREE_FALSE@ test -s "$@" || ln -s -f "$(top_srcdir)/common/common.c" "$@"
$(top_builddir)/include/nut_version.h:
@cd $(@D) && $(MAKE) $(AM_MAKEFLAGS) $(@F)
# NOTE: Do not clean ".deps" in SUBDIRS of the main project,
# the root Makefile.am takes care of that!
#clean-local:
# rm -rf $(builddir)/.deps
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.

View file

@ -1,6 +1,7 @@
/* common.c - common useful functions
Copyright (C) 2000 Russell Kroll <rkroll@exploits.org>
Copyright (C) 2021-2022 Jim Klimov <jimklimov+nut@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,8 +22,11 @@
#include <ctype.h>
#include <syslog.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <sys/un.h>
/* the reason we define UPS_VERSION as a static string, rather than a
macro, is to make dependency tracking easier (only common.o depends
@ -32,6 +36,52 @@
#include "nut_version.h"
const char *UPS_VERSION = NUT_VERSION_MACRO;
#include <stdio.h>
/* Know which bitness we were built for,
* to adjust the search paths for get_libname() */
#include "nut_stdint.h"
#if UINTPTR_MAX == 0xffffffffffffffffULL
# define BUILD_64 1
#else
# ifdef BUILD_64
# undef BUILD_64
# endif
#endif
/* https://stackoverflow.com/a/12844426/4715872 */
#include <sys/types.h>
#include <limits.h>
#include <stdlib.h>
pid_t get_max_pid_t()
{
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic ignored "-Wunreachable-code"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
#endif
if (sizeof(pid_t) == sizeof(short)) return (pid_t)SHRT_MAX;
if (sizeof(pid_t) == sizeof(int)) return (pid_t)INT_MAX;
if (sizeof(pid_t) == sizeof(long)) return (pid_t)LONG_MAX;
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined _STDC_C99) || (defined __C99FEATURES__) /* C99+ build mode */
# if defined(LLONG_MAX) /* since C99 */
if (sizeof(pid_t) == sizeof(long long)) return (pid_t)LLONG_MAX;
# endif
#endif
abort();
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic pop
#endif
}
int nut_debug_level = 0;
int nut_log_level = 0;
static int upslog_flags = UPSLOG_STDERR;
@ -51,7 +101,7 @@ static int xbit_test(int val, int flag)
return ((val & flag) == flag);
}
/* enable writing upslog_with_errno() and upslogx() type messages to
/* enable writing upslog_with_errno() and upslogx() type messages to
the syslog */
void syslogbit_set(void)
{
@ -126,7 +176,7 @@ void background(void)
close(1);
close(2);
if (pid != 0)
if (pid != 0)
_exit(EXIT_SUCCESS); /* parent */
/* child */
@ -163,8 +213,32 @@ struct passwd *get_user_pwent(const char *name)
fatalx(EXIT_FAILURE, "user %s not found", name);
else
fatal_with_errno(EXIT_FAILURE, "getpwnam(%s)", name);
return NULL; /* to make the compiler happy */
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_RETURN) )
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic ignored "-Wunreachable-code"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_RETURN
#pragma GCC diagnostic ignored "-Wunreachable-code-return"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
# ifdef HAVE_PRAGMA_CLANG_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_RETURN
# pragma clang diagnostic ignored "-Wunreachable-code-return"
# endif
#endif
/* Oh joy, adding unreachable "return" to make one compiler happy,
* and pragmas around to make other compilers happy, all at once! */
return NULL;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#if (defined HAVE_PRAGMA_GCC_DIAGNOSTIC_PUSH_POP) && ( (defined HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE) || (defined HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_RETURN) )
#pragma GCC diagnostic pop
#endif
}
/* change to the user defined in the struct */
@ -208,7 +282,7 @@ void writepid(const char *name)
{
char fn[SMALLBUF];
FILE *pidf;
int mask;
mode_t mask;
/* use full path if present, else build filename in PIDPATH */
if (*name == '/')
@ -220,7 +294,9 @@ void writepid(const char *name)
pidf = fopen(fn, "w");
if (pidf) {
fprintf(pidf, "%d\n", (int) getpid());
intmax_t pid = (intmax_t)getpid();
upsdebugx(1, "Saving PID %jd into %s", pid, fn);
fprintf(pidf, "%jd\n", pid);
fclose(pidf);
} else {
upslog_with_errno(LOG_NOTICE, "writepid: fopen %s", fn);
@ -229,30 +305,17 @@ void writepid(const char *name)
umask(mask);
}
/* open pidfn, get the pid, then send it sig */
int sendsignalfn(const char *pidfn, int sig)
/* send sig to pid, returns -1 for error, or
* zero for a successfully sent signal
*/
int sendsignalpid(pid_t pid, int sig)
{
char buf[SMALLBUF];
FILE *pidf;
int pid, ret;
int ret;
pidf = fopen(pidfn, "r");
if (!pidf) {
upslog_with_errno(LOG_NOTICE, "fopen %s", pidfn);
return -1;
}
if (fgets(buf, sizeof(buf), pidf) == NULL) {
upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn);
fclose(pidf);
return -1;
}
pid = strtol(buf, (char **)NULL, 10);
if (pid < 2) {
upslogx(LOG_NOTICE, "Ignoring invalid pid number %d", pid);
fclose(pidf);
if (pid < 2 || pid > get_max_pid_t()) {
upslogx(LOG_NOTICE,
"Ignoring invalid pid number %" PRIdMAX,
(intmax_t) pid);
return -1;
}
@ -261,21 +324,78 @@ int sendsignalfn(const char *pidfn, int sig)
if (ret < 0) {
perror("kill");
fclose(pidf);
return -1;
}
/* now actually send it */
ret = kill(pid, sig);
if (sig != 0) {
/* now actually send it */
ret = kill(pid, sig);
if (ret < 0) {
perror("kill");
if (ret < 0) {
perror("kill");
return -1;
}
}
return 0;
}
/* parses string buffer into a pid_t if it passes
* a few sanity checks; returns -1 on error
*/
pid_t parsepid(const char *buf)
{
pid_t pid = -1;
/* assuming 10 digits for a long */
intmax_t _pid = strtol(buf, (char **)NULL, 10);
if (_pid <= get_max_pid_t()) {
pid = (pid_t)_pid;
} else {
upslogx(LOG_NOTICE, "Received a pid number too big for a pid_t: %" PRIdMAX, _pid);
}
return pid;
}
/* open pidfn, get the pid, then send it sig
* returns negative codes for errors, or
* zero for a successfully sent signal
*/
int sendsignalfn(const char *pidfn, int sig)
{
char buf[SMALLBUF];
FILE *pidf;
pid_t pid = -1;
int ret = -1;
pidf = fopen(pidfn, "r");
if (!pidf) {
upslog_with_errno(LOG_NOTICE, "fopen %s", pidfn);
return -3;
}
if (fgets(buf, sizeof(buf), pidf) == NULL) {
upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn);
fclose(pidf);
return -1;
return -2;
}
/* TOTHINK: Original code only closed pidf before
* exiting the method, on error or "normally".
* Why not here? Do we want an (exclusive?) hold
* on it while being active in the method?
*/
/* this method actively reports errors, if any */
pid = parsepid(buf);
if (pid >= 0) {
/* this method actively reports errors, if any */
ret = sendsignalpid(pid, sig);
}
fclose(pidf);
return 0;
return ret;
}
int snprintfcat(char *dst, size_t size, const char *fmt, ...)
@ -285,14 +405,46 @@ int snprintfcat(char *dst, size_t size, const char *fmt, ...)
int ret;
size--;
assert(len <= size);
if (len > size) {
/* Do not truncate existing string */
errno = ERANGE;
return -1;
}
va_start(ap, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
/* Note: this code intentionally uses a caller-provided format string */
ret = vsnprintf(dst + len, size - len, fmt, ap);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(ap);
dst[size] = '\0';
return len + ret;
/* Note: there is a standards loophole here: strlen() must return size_t
* and printf() family returns a signed int with negatives for errors.
* In theory it can overflow a 64-vs-32 bit range, or signed-vs-unsigned.
* In practice we hope to not have gigabytes-long config strings.
*/
if (ret < 0) {
return ret;
}
#ifdef INT_MAX
if ( ( (unsigned long long)len + (unsigned long long)ret ) >= (unsigned long long)INT_MAX ) {
errno = ERANGE;
return -1;
}
#endif
return (int)len + ret;
}
/* lazy way to send a signal if the program uses the PIDPATH */
@ -319,7 +471,27 @@ static void vupslog(int priority, const char *fmt, va_list va, int use_strerror)
int ret;
char buf[LARGEBUF];
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
#pragma clang diagnostic ignored "-Wformat-security"
#endif
ret = vsnprintf(buf, sizeof(buf), fmt, va);
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
if ((ret < 0) || (ret >= (int) sizeof(buf)))
syslog(LOG_WARNING, "vupslog: vsnprintf needed more than %d bytes",
@ -329,20 +501,20 @@ static void vupslog(int priority, const char *fmt, va_list va, int use_strerror)
snprintfcat(buf, sizeof(buf), ": %s", strerror(errno));
if (nut_debug_level > 0) {
static struct timeval start = { 0 };
static struct timeval start = { 0, 0 };
struct timeval now;
gettimeofday(&now, NULL);
if (start.tv_sec == 0) {
start = now;
}
if (start.tv_usec > now.tv_usec) {
now.tv_usec += 1000000;
now.tv_sec -= 1;
}
fprintf(stderr, "%4.0f.%06ld\t", difftime(now.tv_sec, start.tv_sec), (long)(now.tv_usec - start.tv_usec));
}
@ -353,7 +525,7 @@ static void vupslog(int priority, const char *fmt, va_list va, int use_strerror)
}
/* Return the default path for the directory containing configuration files */
const char * confpath(void)
const char * confpath(void)
{
const char * path;
@ -364,33 +536,82 @@ const char * confpath(void)
}
/* Return the default path for the directory containing state files */
const char * dflt_statepath(void)
const char * dflt_statepath(void)
{
const char * path;
if ((path = getenv("NUT_STATEPATH")) == NULL)
path = getenv("NUT_STATEPATH");
if ( (path == NULL) || (*path == '\0') )
path = STATEPATH;
return path;
}
/* Return the alternate path for pid files */
const char * altpidpath(void)
/* Return the alternate path for pid files, for processes running as non-root
* Per documentation and configure script, the fallback value is the
* state-file path as the daemon and drivers can write there too.
* Note that this differs from PIDPATH that higher-privileged daemons, such
* as upsmon, tend to use.
*/
const char * altpidpath(void)
{
const char * path;
path = getenv("NUT_ALTPIDPATH");
if ( (path == NULL) || (*path == '\0') )
path = getenv("NUT_STATEPATH");
if ( (path != NULL) && (*path != '\0') )
return path;
#ifdef ALTPIDPATH
return ALTPIDPATH;
#else
return dflt_statepath();
/* We assume, here and elsewhere, that at least STATEPATH is always defined */
return STATEPATH;
#endif
}
/* Die with a standard message if socket filename is too long */
void check_unix_socket_filename(const char *fn) {
struct sockaddr_un ssaddr;
if (strlen(fn) < sizeof(ssaddr.sun_path))
return;
/* Avoid useless truncated pathnames that
* other driver instances would conflict
* with, and upsd can not discover.
* Note this is quite short on many OSes
* varying 104-108 bytes (UNIX_PATH_MAX)
* as opposed to PATH_MAX or MAXPATHLEN
* typically of a kilobyte range.
*/
fatalx(EXIT_FAILURE,
"Can't create a unix domain socket: pathname '%s' "
"is too long (%zu) for 'struct sockaddr_un->sun_path' "
"on this system (%zu)",
fn, strlen(fn), sizeof(ssaddr.sun_path));
}
/* logs the formatted string to any configured logging devices + the output of strerror(errno) */
void upslog_with_errno(int priority, const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vupslog(priority, fmt, va, 1);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
}
@ -400,44 +621,115 @@ void upslogx(int priority, const char *fmt, ...)
va_list va;
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vupslog(priority, fmt, va, 0);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
}
void upsdebug_with_errno(int level, const char *fmt, ...)
void s_upsdebug_with_errno(int level, const char *fmt, ...)
{
va_list va;
char fmt2[LARGEBUF];
/* Note: Thanks to macro wrapping, we do not quite need this
* test now, but we still need the "level" value to report
* below - when it is not zero.
*/
if (nut_debug_level < level)
return;
/* For debugging output, we want to prepend the debug level so the user can
* e.g. lower the level (less -D's on command line) to retain just the amount
* of logging info he needs to see at the moment. Using '-DDDDD' all the time
* is too brutal and needed high-level overview can be lost. This [D#] prefix
* can help limit this debug stream quicker, than experimentally picking ;) */
if (level > 0) {
int ret;
ret = snprintf(fmt2, sizeof(fmt2), "[D%d] %s", level, fmt);
if ((ret < 0) || (ret >= (int) sizeof(fmt2))) {
syslog(LOG_WARNING, "upsdebug_with_errno: snprintf needed more than %d bytes",
LARGEBUF);
} else {
fmt = (const char *)fmt2;
}
}
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vupslog(LOG_DEBUG, fmt, va, 1);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
}
void upsdebugx(int level, const char *fmt, ...)
void s_upsdebugx(int level, const char *fmt, ...)
{
va_list va;
char fmt2[LARGEBUF];
if (nut_debug_level < level)
return;
/* See comments above in upsdebug_with_errno() - they apply here too. */
if (level > 0) {
int ret;
ret = snprintf(fmt2, sizeof(fmt2), "[D%d] %s", level, fmt);
if ((ret < 0) || (ret >= (int) sizeof(fmt2))) {
syslog(LOG_WARNING, "upsdebugx: snprintf needed more than %d bytes",
LARGEBUF);
} else {
fmt = (const char *)fmt2;
}
}
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vupslog(LOG_DEBUG, fmt, va, 0);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
}
/* dump message msg and len bytes from buf to upsdebugx(level) in
hexadecimal. (This function replaces Philippe Marzouk's original
dump_hex() function) */
void upsdebug_hex(int level, const char *msg, const void *buf, int len)
void s_upsdebug_hex(int level, const char *msg, const void *buf, size_t len)
{
char line[100];
int n; /* number of characters currently in line */
int i; /* number of bytes output from buffer */
size_t i; /* number of bytes output from buffer */
n = snprintf(line, sizeof(line), "%s: (%d bytes) =>", msg, len);
n = snprintf(line, sizeof(line), "%s: (%zu bytes) =>", msg, len);
if (n < 0) goto failed;
for (i = 0; i < len; i++) {
@ -447,9 +739,16 @@ void upsdebug_hex(int level, const char *msg, const void *buf, int len)
}
n = snprintfcat(line, sizeof(line), n ? " %02x" : "%02x",
((unsigned char *)buf)[i]);
((const unsigned char *)buf)[i]);
if (n < 0) goto failed;
}
upsdebugx(level, "%s", line);
s_upsdebugx(level, "%s", line);
return;
failed:
s_upsdebugx(level, "%s", "Failed to print a hex dump for debug");
}
/* taken from www.asciitable.com */
@ -489,29 +788,37 @@ static const char* ascii_symb[] = {
};
/* dump message msg and len bytes from buf to upsdebugx(level) in ascii. */
void upsdebug_ascii(int level, const char *msg, const void *buf, int len)
void s_upsdebug_ascii(int level, const char *msg, const void *buf, size_t len)
{
char line[256];
int i;
int n; /* number of characters currently in line */
size_t i; /* number of bytes output from buffer */
unsigned char ch;
if (nut_debug_level < level)
return; /* save cpu cycles */
snprintf(line, sizeof(line), "%s", msg);
n = snprintf(line, sizeof(line), "%s", msg);
if (n < 0) goto failed;
for (i=0; i<len; ++i) {
ch = ((unsigned char *)buf)[i];
ch = ((const unsigned char *)buf)[i];
if (ch < 0x20)
snprintfcat(line, sizeof(line), "%3s ", ascii_symb[ch]);
n = snprintfcat(line, sizeof(line), "%3s ", ascii_symb[ch]);
else if (ch >= 0x80)
snprintfcat(line, sizeof(line), "%02Xh ", ch);
n = snprintfcat(line, sizeof(line), "%02Xh ", ch);
else
snprintfcat(line, sizeof(line), "'%c' ", ch);
n = snprintfcat(line, sizeof(line), "'%c' ", ch);
if (n < 0) goto failed;
}
upsdebugx(level, "%s", line);
s_upsdebugx(level, "%s", line);
return;
failed:
s_upsdebugx(level, "%s", "Failed to print an ASCII data dump for debug");
}
static void vfatal(const char *fmt, va_list va, int use_strerror)
@ -521,7 +828,19 @@ static void vfatal(const char *fmt, va_list va, int use_strerror)
if (xbit_test(upslog_flags, UPSLOG_SYSLOG_ON_FATAL))
xbit_set(&upslog_flags, UPSLOG_SYSLOG);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vupslog(LOG_ERR, fmt, va, use_strerror);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
}
void fatal_with_errno(int status, const char *fmt, ...)
@ -529,7 +848,19 @@ void fatal_with_errno(int status, const char *fmt, ...)
va_list va;
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vfatal(fmt, va, (errno > 0) ? 1 : 0);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
exit(status);
@ -540,7 +871,19 @@ void fatalx(int status, const char *fmt, ...)
va_list va;
va_start(va, fmt);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_FORMAT_SECURITY
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
vfatal(fmt, va, 0);
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_FORMAT_NONLITERAL
#pragma GCC diagnostic pop
#endif
va_end(va);
exit(status);
@ -587,7 +930,7 @@ char *xstrdup(const char *string)
/* Read up to buflen bytes from fd and return the number of bytes
read. If no data is available within d_sec + d_usec, return 0.
On error, a value < 0 is returned (errno indicates error). */
int select_read(const int fd, void *buf, const size_t buflen, const long d_sec, const long d_usec)
ssize_t select_read(const int fd, void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec)
{
int ret;
fd_set fds;
@ -611,7 +954,7 @@ int select_read(const int fd, void *buf, const size_t buflen, const long d_sec,
/* Write up to buflen bytes to fd and return the number of bytes
written. If no data is available within d_sec + d_usec, return 0.
On error, a value < 0 is returned (errno indicates error). */
int select_write(const int fd, const void *buf, const size_t buflen, const long d_sec, const long d_usec)
ssize_t select_write(const int fd, const void *buf, const size_t buflen, const time_t d_sec, const suseconds_t d_usec)
{
int ret;
fd_set fds;
@ -631,3 +974,106 @@ int select_write(const int fd, const void *buf, const size_t buflen, const long
return write(fd, buf, buflen);
}
/* FIXME: would be good to get more from /etc/ld.so.conf[.d] and/or
* LD_LIBRARY_PATH and a smarter dependency on build bitness; also
* note that different OSes can have their pathnames set up differently
* with regard to default/preferred bitness (maybe a "32" in the name
* should also be searched explicitly - again, IFF our build is 32-bit).
*
* General premise for this solution is that some parts of NUT (e.g. the
* nut-scanner tool, or DMF feature code) must be pre-built and distributed
* in binary packages, but only at run-time it gets to know which third-party
* libraries it should use for particular operations. This differs from e.g.
* distribution packages which group NUT driver binaries explicitly dynamically
* linked against certain OS-provided libraries for accessing this or that
* communications media and/or vendor protocol.
*/
static const char * search_paths[] = {
/* Use the library path (and bitness) provided during ./configure first */
LIBDIR,
"/usr"LIBDIR,
"/usr/local"LIBDIR,
#ifdef BUILD_64
/* Fall back to explicit preference of 64-bit paths as named on some OSes */
"/usr/lib/64",
"/usr/lib64",
#endif
"/usr/lib",
#ifdef BUILD_64
"/lib/64",
"/lib64",
#endif
"/lib",
#ifdef BUILD_64
"/usr/local/lib/64",
"/usr/local/lib64",
#endif
"/usr/local/lib",
#ifdef AUTOTOOLS_TARGET_SHORT_ALIAS
"/usr/lib/" AUTOTOOLS_TARGET_SHORT_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_TARGET_SHORT_ALIAS,
#else
# ifdef AUTOTOOLS_HOST_SHORT_ALIAS
"/usr/lib/" AUTOTOOLS_HOST_SHORT_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_HOST_SHORT_ALIAS,
# else
# ifdef AUTOTOOLS_BUILD_SHORT_ALIAS
"/usr/lib/" AUTOTOOLS_BUILD_SHORT_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_BUILD_SHORT_ALIAS,
# endif
# endif
#endif
#ifdef AUTOTOOLS_TARGET_ALIAS
"/usr/lib/" AUTOTOOLS_TARGET_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_TARGET_ALIAS,
#else
# ifdef AUTOTOOLS_HOST_ALIAS
"/usr/lib/" AUTOTOOLS_HOST_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_HOST_ALIAS,
# else
# ifdef AUTOTOOLS_BUILD_ALIAS
"/usr/lib/" AUTOTOOLS_BUILD_ALIAS,
"/usr/lib/gcc/" AUTOTOOLS_BUILD_ALIAS,
# endif
# endif
#endif
NULL
};
char * get_libname(const char* base_libname)
{
DIR *dp;
struct dirent *dirp;
int index = 0;
char *libname_path = NULL;
char current_test_path[LARGEBUF];
size_t base_libname_length = strlen(base_libname);
for(index = 0 ; (search_paths[index] != NULL) && (libname_path == NULL) ; index++)
{
memset(current_test_path, 0, LARGEBUF);
if ((dp = opendir(search_paths[index])) == NULL)
continue;
upsdebugx(2,"Looking for lib %s in directory #%d : %s", base_libname, index, search_paths[index]);
while ((dirp = readdir(dp)) != NULL)
{
upsdebugx(5,"Comparing lib %s with dirpath %s", base_libname, dirp->d_name);
int compres = strncmp(dirp->d_name, base_libname, base_libname_length);
if(compres == 0) {
snprintf(current_test_path, LARGEBUF, "%s/%s", search_paths[index], dirp->d_name);
libname_path = realpath(current_test_path, NULL);
upsdebugx(2,"Candidate path for lib %s is %s (realpath %s)", base_libname, current_test_path, (libname_path!=NULL)?libname_path:"NULL");
if (libname_path != NULL)
break;
}
}
closedir(dp);
}
upsdebugx(1,"Looking for lib %s, found %s", base_libname, (libname_path!=NULL)?libname_path:"NULL");
return libname_path;
}

View file

@ -26,7 +26,7 @@
* There is now a context buffer, and you call pconf_init to set it up.
* All subsequent calls must have it as the first argument. There are
* two entry points for parsing lines. You can have it read a file
* (pconf_file_begin and pconf_file_next), take lines directly from
* (pconf_file_begin and pconf_file_next), take lines directly from
* the caller (pconf_line), or go along a character at a time (pconf_char).
* The parsing is identical no matter how you feed it.
*
@ -38,7 +38,7 @@
*
* Fatal errors are those that involve memory allocation. If the user
* defines an error handler when calling pconf_init, that function will
* be called with the error message before parseconf exits. By default
* be called with the error message before parseconf exits. By default
* it will just write the message to stderr before exiting.
*
* Input vs. Output:
@ -57,12 +57,12 @@
* also allows you to join lines, allowing you to have logical lines
* that span physical lines, just like you can do in some shells.
*
* Lines normally end with a newline, but reaching EOF will also force
* Lines normally end with a newline, but reaching EOF will also force
* parsing on what's been scanned so far.
*
*
* Design:
*
* Characters are read one at a time to drive the state machine.
* Characters are read one at a time to drive the state machine.
* As words are completed (by hitting whitespace or ending a "" item),
* they are committed to the next buffer in the arglist. realloc is
* used, so the buffer can grow to handle bigger words.
@ -76,15 +76,20 @@
*
*/
#include "common.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "parseconf.h"
#include "attribute.h"
#include "nut_stdint.h"
/* possible states */
@ -97,6 +102,9 @@
#define STATE_ENDOFLINE 7
#define STATE_PARSEERR 8
static void pconf_fatal(PCONF_CTX_t *ctx, const char *errtxt)
__attribute__((noreturn));
static void pconf_fatal(PCONF_CTX_t *ctx, const char *errtxt)
{
if (ctx->errhandler)
@ -109,7 +117,7 @@ static void pconf_fatal(PCONF_CTX_t *ctx, const char *errtxt)
static void add_arg_word(PCONF_CTX_t *ctx)
{
int argpos;
size_t argpos;
size_t wbuflen;
/* this is where the new value goes */
@ -122,13 +130,13 @@ static void add_arg_word(PCONF_CTX_t *ctx)
ctx->maxargs = ctx->numargs;
/* resize the lists */
ctx->arglist = realloc(ctx->arglist,
ctx->arglist = realloc(ctx->arglist,
sizeof(char *) * ctx->numargs);
if (!ctx->arglist)
pconf_fatal(ctx, "realloc arglist failed");
ctx->argsize = realloc(ctx->argsize,
ctx->argsize = realloc(ctx->argsize,
sizeof(size_t) * ctx->numargs);
if (!ctx->argsize)
@ -171,7 +179,7 @@ static void addchar(PCONF_CTX_t *ctx)
wbuflen = strlen(ctx->wordbuf);
/* CVE-2012-2944: only allow the subset Ascii charset from Space to ~ */
/* CVE-2012-2944: only allow the subset of ASCII charset from Space to ~ */
if ((ctx->ch < 0x20) || (ctx->ch > 0x7f)) {
fprintf(stderr, "addchar: discarding invalid character (0x%02x)!\n",
ctx->ch);
@ -199,7 +207,7 @@ static void addchar(PCONF_CTX_t *ctx)
ctx->wordptr = &ctx->wordbuf[wbuflen];
}
*ctx->wordptr++ = ctx->ch;
*ctx->wordptr++ = (char)ctx->ch;
*ctx->wordptr = '\0';
}
@ -234,8 +242,8 @@ static int findwordstart(PCONF_CTX_t *ctx)
return STATE_FINDEOL;
/* space = not in a word yet, so loop back */
if (isspace(ctx->ch))
return STATE_FINDWORDSTART;
if (isspace((size_t)ctx->ch))
return STATE_FINDWORDSTART;
/* \ = literal = accept the next char blindly */
if (ctx->ch == '\\')
@ -255,7 +263,7 @@ static int findwordstart(PCONF_CTX_t *ctx)
}
return STATE_COLLECT;
}
}
/* eat characters until the end of the line is found */
static int findeol(PCONF_CTX_t *ctx)
@ -274,7 +282,7 @@ static void pconf_seterr(PCONF_CTX_t *ctx, const char *errmsg)
snprintf(ctx->errmsg, PCONF_ERR_LEN, "%s", errmsg);
ctx->error = 1;
}
}
/* quote characters inside a word bounded by "quotes" */
static int quotecollect(PCONF_CTX_t *ctx)
@ -291,7 +299,7 @@ static int quotecollect(PCONF_CTX_t *ctx)
/* another " means we're done with this word */
if (ctx->ch == '"') {
endofword(ctx);
return STATE_FINDWORDSTART;
}
@ -334,7 +342,7 @@ static int collect(PCONF_CTX_t *ctx)
}
/* space means the word is done */
if (isspace(ctx->ch)) {
if (isspace((size_t)ctx->ch)) {
endofword(ctx);
return STATE_FINDWORDSTART;
@ -443,6 +451,9 @@ int pconf_file_begin(PCONF_CTX_t *ctx, const char *fn)
return 0;
}
/* prevent fd leaking to child processes */
fcntl(fileno(ctx->f), F_SETFD, FD_CLOEXEC);
return 1; /* OK */
}
@ -571,7 +582,7 @@ int pconf_line(PCONF_CTX_t *ctx, const char *line)
/* deal with any lingering characters */
/* still building a word? */
if (ctx->wordptr != ctx->wordbuf)
if (ctx->wordptr != ctx->wordbuf)
endofword(ctx); /* tie it off */
return 1;

View file

@ -9,13 +9,14 @@ int nut_setenv(const char *name, const char *value, int overwrite)
char *val;
char *buffer;
int rv;
if (overwrite == 0) {
val = getenv(name);
if (val != NULL) {
return 0;
}
}
buffer = xmalloc(strlen(value) + strlen(name) + 2);
strcpy(buffer, name);
strcat(buffer, "=");

View file

@ -35,9 +35,9 @@
* original. Also, there is now a builtin-test, just compile with:
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
* and run snprintf for results.
*
*
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
* The PGP code was using unsigned hexadecimal formats.
* The PGP code was using unsigned hexadecimal formats.
* Unfortunately, unsigned formats simply didn't work.
*
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
@ -54,7 +54,7 @@
#include "config.h"
#include <string.h>
# include <ctype.h>
#include <ctype.h>
#include <sys/types.h>
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
@ -102,14 +102,14 @@
/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
static void dopr (char *buffer, size_t maxlen, const char *format,
static void dopr (char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
char *value, int flags, int min, int max);
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
long value, int base, int min, int max, int flags);
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
/*
@ -137,10 +137,26 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
/* Conversion Flags */
#define DP_C_SHORT 1
/* Note: Originally DP_C_SHORT converted to "short int" types, but modernish
* (C99+ or even earlier) standards require that the minimal type passed
* through variadic args '...' is an int, and smaller types are padded up
* to it - so value shifts in memory and erroneous access crashes can occur
* if smaller data is accessed blindly. Code below has been fixed to not pass
* "short int" anymore - it just casts the int to desired smaller type (and
* so drops the padding bits). */
#define DP_C_LONG 2
#define DP_C_LDOUBLE 3
#define DP_C_LLONG 4
#ifdef C89PLUS
#undef C89PLUS
#endif
#if defined(__STDC__) || defined(__STDC_VERSION__)
/* C89+ and C90+ code respectively */
#define C89PLUS 1
#endif
#define char_to_int(p) ((p)- '0')
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
@ -156,7 +172,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
int flags;
int cflags;
size_t currlen;
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
max = -1;
@ -164,237 +180,259 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
while (state != DP_S_DONE)
{
if ((ch == '\0') || (currlen >= maxlen))
if ((ch == '\0') || (currlen >= maxlen))
state = DP_S_DONE;
switch(state)
switch(state)
{
case DP_S_DEFAULT:
if (ch == '%')
state = DP_S_FLAGS;
else
dopr_outch (buffer, &currlen, maxlen, ch);
if (ch == '%')
state = DP_S_FLAGS;
else
dopr_outch (buffer, &currlen, maxlen, ch);
ch = *format++;
break;
case DP_S_FLAGS:
switch (ch)
switch (ch)
{
case '-':
flags |= DP_F_MINUS;
flags |= DP_F_MINUS;
ch = *format++;
break;
break;
case '+':
flags |= DP_F_PLUS;
flags |= DP_F_PLUS;
ch = *format++;
break;
break;
case ' ':
flags |= DP_F_SPACE;
flags |= DP_F_SPACE;
ch = *format++;
break;
break;
case '#':
flags |= DP_F_NUM;
flags |= DP_F_NUM;
ch = *format++;
break;
break;
case '0':
flags |= DP_F_ZERO;
flags |= DP_F_ZERO;
ch = *format++;
break;
break;
default:
state = DP_S_MIN;
break;
state = DP_S_MIN;
break;
}
break;
case DP_S_MIN:
if (isdigit((unsigned char)ch))
if (isdigit((unsigned char)ch))
{
min = 10*min + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
min = 10*min + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
}
else
state = DP_S_DOT;
min = va_arg (args, int);
ch = *format++;
state = DP_S_DOT;
}
else
state = DP_S_DOT;
break;
case DP_S_DOT:
if (ch == '.')
if (ch == '.')
{
state = DP_S_MAX;
ch = *format++;
}
else
state = DP_S_MOD;
state = DP_S_MAX;
ch = *format++;
}
else
state = DP_S_MOD;
break;
case DP_S_MAX:
if (isdigit((unsigned char)ch))
if (isdigit((unsigned char)ch))
{
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
if (max < 0)
max = 0;
max = 10*max + char_to_int (ch);
ch = *format++;
}
else if (ch == '*')
{
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
}
else
state = DP_S_MOD;
max = va_arg (args, int);
ch = *format++;
state = DP_S_MOD;
}
else
state = DP_S_MOD;
break;
case DP_S_MOD:
switch (ch)
switch (ch)
{
case 'h':
cflags = DP_C_SHORT;
ch = *format++;
break;
cflags = DP_C_SHORT;
ch = *format++;
break;
case 'l':
cflags = DP_C_LONG;
ch = *format++;
if (ch == 'l') { /* It's a long long */
cflags = DP_C_LLONG;
ch = *format++;
}
break;
cflags = DP_C_LONG;
ch = *format++;
if (ch == 'l') { /* It's a long long */
cflags = DP_C_LLONG;
ch = *format++;
}
break;
case 'L':
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
cflags = DP_C_LDOUBLE;
ch = *format++;
break;
default:
break;
break;
}
state = DP_S_CONV;
break;
case DP_S_CONV:
switch (ch)
switch (ch)
{
case 'd':
case 'i':
if (cflags == DP_C_SHORT)
value = va_arg (args, short int);
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else if (cflags == DP_C_LLONG)
value = va_arg (args, LLONG);
else
value = va_arg (args, int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (short int)va_arg (args, int);
#else
value = va_arg (args, short int);
#endif
else if (cflags == DP_C_LONG)
value = va_arg (args, long int);
else if (cflags == DP_C_LLONG)
value = va_arg (args, LLONG);
else
value = va_arg (args, int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'o':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (long)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break;
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (long)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
break;
case 'u':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
break;
case 'X':
flags |= DP_F_UP;
flags |= DP_F_UP;
goto fallthrough_case_x;
case 'x':
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
value = va_arg (args, unsigned short int);
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break;
fallthrough_case_x:
flags |= DP_F_UNSIGNED;
if (cflags == DP_C_SHORT)
#ifdef C89PLUS
value = (unsigned short int)va_arg (args, unsigned int);
#else
value = va_arg (args, unsigned short int);
#endif
else if (cflags == DP_C_LONG)
value = (long)va_arg (args, unsigned long int);
else if (cflags == DP_C_LLONG)
value = (LLONG)va_arg (args, unsigned LLONG);
else
value = (long)va_arg (args, unsigned int);
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
break;
case 'f':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
/* um, floating point? */
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
/* um, floating point? */
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'E':
flags |= DP_F_UP;
flags |= DP_F_UP;
goto fallthrough_case_e;
case 'e':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
fallthrough_case_e:
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
case 'G':
flags |= DP_F_UP;
flags |= DP_F_UP;
goto fallthrough_case_g;
case 'g':
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
fallthrough_case_g:
if (cflags == DP_C_LDOUBLE)
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
break;
case 'c':
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
if (max < 0)
max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
strvalue = va_arg (args, char *);
if (max < 0)
max = maxlen; /* ie, no max */
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
break;
case 'p':
strvalue = va_arg (args, void *);
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
strvalue = va_arg (args, void *);
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
break;
case 'n':
if (cflags == DP_C_SHORT)
{
short int *num;
num = va_arg (args, short int *);
*num = currlen;
}
else if (cflags == DP_C_LONG)
{
long int *num;
num = va_arg (args, long int *);
*num = (long int)currlen;
}
else if (cflags == DP_C_LLONG)
{
LLONG *num;
num = va_arg (args, LLONG *);
*num = (LLONG)currlen;
}
else
{
int *num;
num = va_arg (args, int *);
*num = currlen;
if (cflags == DP_C_SHORT)
{
short int *num;
num = va_arg (args, short int *);
*num = currlen;
}
break;
else if (cflags == DP_C_LONG)
{
long int *num;
num = va_arg (args, long int *);
*num = (long int)currlen;
}
else if (cflags == DP_C_LLONG)
{
LLONG *num;
num = va_arg (args, LLONG *);
*num = (LLONG)currlen;
}
else
{
int *num;
num = va_arg (args, int *);
*num = currlen;
}
break;
case '%':
dopr_outch (buffer, &currlen, maxlen, ch);
break;
dopr_outch (buffer, &currlen, maxlen, ch);
break;
case 'w':
/* not supported yet, treat as next char */
ch = *format++;
break;
/* not supported yet, treat as next char */
ch = *format++;
break;
default:
/* Unknown, skip */
break;
/* Unknown, skip */
break;
}
ch = *format++;
state = DP_S_DEFAULT;
@ -408,18 +446,18 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
break; /* some picky compilers need this */
}
}
if (currlen < maxlen - 1)
if (currlen < maxlen - 1)
buffer[currlen] = '\0';
else
else
buffer[maxlen - 1] = '\0';
}
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max)
char *value, int flags, int min, int max)
{
int padlen, strln; /* amount to pad */
int cnt = 0;
if (value == 0)
{
value = "<NULL>";
@ -427,23 +465,23 @@ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
for (strln = 0; value[strln]; ++strln); /* strlen */
padlen = min - strln;
if (padlen < 0)
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justify */
while ((padlen > 0) && (cnt < max))
while ((padlen > 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
++cnt;
}
while (*value && (cnt < max))
while (*value && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, *value++);
++cnt;
}
while ((padlen < 0) && (cnt < max))
while ((padlen < 0) && (cnt < max))
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
@ -454,7 +492,7 @@ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags)
long value, int base, int min, int max, int flags)
{
int signvalue = 0;
unsigned long uvalue;
@ -463,7 +501,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
int spadlen = 0; /* amount to space pad */
int zpadlen = 0; /* amount to zero pad */
int caps = 0;
if (max < 0)
max = 0;
@ -477,12 +515,12 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
}
else
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
signvalue = '+';
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
signvalue = ' ';
}
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
do {
@ -503,27 +541,27 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
zpadlen = MAX(zpadlen, spadlen);
spadlen = 0;
}
if (flags & DP_F_MINUS)
if (flags & DP_F_MINUS)
spadlen = -spadlen; /* Left Justifty */
#ifdef DEBUG_SNPRINTF
printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
zpadlen, spadlen, min, max, place);
zpadlen, spadlen, min, max, place);
#endif
/* Spaces */
while (spadlen > 0)
while (spadlen > 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
--spadlen;
}
/* Sign */
if (signvalue)
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
/* Zeros */
if (zpadlen > 0)
if (zpadlen > 0)
{
while (zpadlen > 0)
{
@ -533,9 +571,9 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
}
/* Digits */
while (place > 0)
while (place > 0)
dopr_outch (buffer, currlen, maxlen, convert[--place]);
/* Left Justified spaces */
while (spadlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
@ -543,6 +581,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
}
}
#ifndef HAVE_ABS_VAL
static LDOUBLE abs_val (LDOUBLE value)
{
LDOUBLE result = value;
@ -552,7 +591,13 @@ static LDOUBLE abs_val (LDOUBLE value)
return result;
}
#endif
#ifndef HAVE_FCVT
/* The two routines that may get defined below are only used if we also don't
* have a fcvt() in the system. Defining and not using the routines may be a
* warning (fatal with -Werror), so we hide them here. */
# ifndef HAVE_POW10
static LDOUBLE pow10 (int exp)
{
LDOUBLE result = 1;
@ -562,10 +607,12 @@ static LDOUBLE pow10 (int exp)
result *= 10;
exp--;
}
return result;
}
# endif
# ifndef HAVE_ROUND
static long round (LDOUBLE value)
{
long intpart;
@ -577,9 +624,11 @@ static long round (LDOUBLE value)
return intpart;
}
# endif
#endif /* HAVE_FCVT */
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags)
LDOUBLE fvalue, int min, int max, int flags)
{
int signvalue = 0;
LDOUBLE ufvalue;
@ -601,12 +650,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int zpadlen = 0;
#ifndef HAVE_FCVT
int caps = 0;
long intpart;
long fracpart;
/*
#endif
/*
* AIX manpage says the default is 0, but Solaris says the default
* is 6, and sprintf on AIX defaults to 6
*/
@ -622,7 +673,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
signvalue = '+';
else
if (flags & DP_F_SPACE)
signvalue = ' ';
signvalue = ' ';
#if 0
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
@ -631,8 +682,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
#ifndef HAVE_FCVT
intpart = (long)ufvalue;
/*
* Sorry, we only support 9 digits past the decimal because of our
/*
* Sorry, we only support 9 digits past the decimal because of our
* conversion method
*/
if (max > 9)
@ -650,8 +701,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
}
#ifdef DEBUG_SNPRINTF
printf("fmtfp: %g %d.%d min=%d max=%d\n",
(double)fvalue, intpart, fracpart, min, max);
printf("fmtfp: %g %d.%d min=%d max=%d\n",
(double)fvalue, intpart, fracpart, min, max);
#endif
/* Convert integer part */
@ -707,38 +758,38 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
fconvert[fplace++] = result[--r_length];
while ((dec_pt < 0) && (fplace < max)) {
fconvert[fplace++] = '0';
dec_pt++;
}
fconvert[fplace++] = '0';
dec_pt++;
}
} else {
int c;
iplace=0;
for(c=dec_pt; c; iconvert[iplace++] = result[--c])
;
;
iconvert[iplace] = '\0';
result += dec_pt;
fplace = 0;
for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c])
;
;
}
#endif /* fcvt */
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
if (zpadlen < 0)
zpadlen = 0;
if (padlen < 0)
if (padlen < 0)
padlen = 0;
if (flags & DP_F_MINUS)
if (flags & DP_F_MINUS)
padlen = -padlen; /* Left Justifty */
if ((flags & DP_F_ZERO) && (padlen > 0))
if ((flags & DP_F_ZERO) && (padlen > 0))
{
if (signvalue)
if (signvalue)
{
dopr_outch (buffer, currlen, maxlen, signvalue);
--padlen;
@ -755,10 +806,10 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
dopr_outch (buffer, currlen, maxlen, ' ');
--padlen;
}
if (signvalue)
if (signvalue)
dopr_outch (buffer, currlen, maxlen, signvalue);
while (iplace > 0)
while (iplace > 0)
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
@ -771,10 +822,10 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
* char to print out.
*/
if (max > 0) {
dopr_outch (buffer, currlen, maxlen, '.');
dopr_outch (buffer, currlen, maxlen, '.');
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
while (zpadlen > 0)
@ -783,7 +834,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
--zpadlen;
}
while (padlen < 0)
while (padlen < 0)
{
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
@ -820,7 +871,7 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
char *fmt;
#endif
VA_LOCAL_DECL;
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
@ -860,7 +911,7 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
"%.1f",
NULL
};
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 6442452944.1234, 0};
char *int_fmt[] = {
"%-1.5d",
@ -888,9 +939,9 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
sprintf (buf2, fp_fmt[x], fp_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2);
fail++;
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
fp_fmt[x], buf1, buf2);
fail++;
}
num++;
}
@ -902,9 +953,9 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
sprintf (buf2, int_fmt[x], int_nums[y]);
if (strcmp (buf1, buf2))
{
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2);
fail++;
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
int_fmt[x], buf1, buf2);
fail++;
}
num++;
}

View file

@ -20,6 +20,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h" /* must be first */
#include <stdio.h>
#include <stdarg.h>
#include <sys/stat.h>
@ -124,7 +126,10 @@ static void st_tree_node_add(st_tree_t **nptr, st_tree_t *sptr)
*nptr = sptr;
}
/* remove a variable from a tree */
/* remove a variable from a tree
* except for variables with ST_FLAG_IMMUTABLE
* (for override.* to survive) per issue #737
*/
int state_delinfo(st_tree_t **nptr, const char *var)
{
while (*nptr) {
@ -141,6 +146,11 @@ int state_delinfo(st_tree_t **nptr, const char *var)
continue;
}
if (node->flags & ST_FLAG_IMMUTABLE) {
upsdebugx(6, "%s: not deleting immutable variable [%s]", __func__, var);
return 0;
}
/* whatever is on the left, hang it off current right */
st_tree_node_add(&node->right, node->left);
@ -153,7 +163,7 @@ int state_delinfo(st_tree_t **nptr, const char *var)
}
return 0; /* not found */
}
}
/* interface */
@ -218,7 +228,7 @@ static int st_tree_enum_add(enum_t **list, const char *enc)
list = &(*list)->next;
continue;
}
return 0; /* duplicate */
}
@ -303,7 +313,7 @@ int state_addrange(st_tree_t *root, const char *var, const int min, const int ma
int state_setaux(st_tree_t *root, const char *var, const char *auxs)
{
st_tree_t *sttmp;
int aux;
long aux;
/* find the tree node for var */
sttmp = state_tree_find(root, var);
@ -354,7 +364,7 @@ int state_getflags(st_tree_t *root, const char *var)
return sttmp->flags;
}
int state_getaux(st_tree_t *root, const char *var)
long state_getaux(st_tree_t *root, const char *var)
{
st_tree_t *sttmp;
@ -396,9 +406,9 @@ const range_t *state_getrangelist(st_tree_t *root, const char *var)
return sttmp->range_list;
}
void state_setflags(st_tree_t *root, const char *var, int numflags, char **flag)
{
int i;
void state_setflags(st_tree_t *root, const char *var, size_t numflags, char **flag)
{
size_t i;
st_tree_t *sttmp;
/* find the tree node for var */
@ -424,6 +434,11 @@ void state_setflags(st_tree_t *root, const char *var, int numflags, char **flag)
continue;
}
if (!strcasecmp(flag[i], "NUMBER")) {
sttmp->flags |= ST_FLAG_NUMBER;
continue;
}
upsdebugx(2, "Unrecognized flag [%s]", flag[i]);
}
}

View file

@ -20,12 +20,21 @@
*
*/
#include "config.h" /* must be first */
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STRING_H
#include <string.h> /* for strdup() and many others */
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h> /* for strncasecmp() and strcasecmp() */
#endif
#include "nut_stdint.h"
#include "str.h"
char *str_trim(char *string, const char character)
@ -109,7 +118,7 @@ char *str_ltrim_space(char *string)
while (
*string != '\0' &&
isspace(*string)
isspace((size_t)*string)
)
memmove(string, string + 1, strlen(string));
@ -130,7 +139,7 @@ char *str_rtrim_space(char *string)
while (
ptr >= string &&
isspace(*ptr)
isspace((size_t)*ptr)
)
*ptr-- = '\0';
@ -252,7 +261,7 @@ int str_to_short(const char *string, short *number, const int base)
return 0;
}
*number = num;
*number = (short)num;
return 1;
}
@ -273,7 +282,7 @@ int str_to_short_strict(const char *string, short *number, const int base)
return 0;
}
*number = num;
*number = (short)num;
return 1;
}
@ -291,7 +300,7 @@ int str_to_ushort(const char *string, unsigned short *number, const int base)
return 0;
}
*number = num;
*number = (unsigned short)num;
return 1;
}
@ -309,13 +318,13 @@ int str_to_ushort_strict(const char *string, unsigned short *number, const int b
return 0;
}
*number = num;
*number = (unsigned short)num;
return 1;
}
int str_to_int(const char *string, int *number, const int base)
{
long num;
long num; /* long >= int, make sure we fit well */
*number = 0;
@ -330,13 +339,13 @@ int str_to_int(const char *string, int *number, const int base)
return 0;
}
*number = num;
*number = (int)num;
return 1;
}
int str_to_int_strict(const char *string, int *number, const int base)
{
long num;
long num; /* long >= int, make sure we fit well */
*number = 0;
@ -351,13 +360,13 @@ int str_to_int_strict(const char *string, int *number, const int base)
return 0;
}
*number = num;
*number = (int)num;
return 1;
}
int str_to_uint(const char *string, unsigned int *number, const int base)
{
unsigned long num;
unsigned long num; /* long >= int, make sure we fit well */
*number = 0;
@ -369,13 +378,13 @@ int str_to_uint(const char *string, unsigned int *number, const int base)
return 0;
}
*number = num;
*number = (unsigned int)num;
return 1;
}
int str_to_uint_strict(const char *string, unsigned int *number, const int base)
{
unsigned long num;
unsigned long num; /* long >= int, make sure we fit well */
*number = 0;
@ -387,7 +396,7 @@ int str_to_uint_strict(const char *string, unsigned int *number, const int base)
return 0;
}
*number = num;
*number = (unsigned int)num;
return 1;
}
@ -429,7 +438,7 @@ int str_to_long_strict(const char *string, long *number, const int base)
if (
string == NULL ||
*string == '\0' ||
isspace(*string)
isspace((size_t)*string)
) {
errno = EINVAL;
return 0;
@ -495,7 +504,7 @@ int str_to_ulong_strict(const char *string, unsigned long *number, const int bas
*string == '\0' ||
*string == '+' ||
*string == '-' ||
isspace(*string)
isspace((size_t)*string)
) {
errno = EINVAL;
return 0;
@ -559,7 +568,7 @@ int str_to_double_strict(const char *string, double *number, const int base)
if (
string == NULL ||
*string == '\0' ||
isspace(*string)
isspace((size_t)*string)
) {
errno = EINVAL;
return 0;
@ -605,3 +614,16 @@ int str_to_double_strict(const char *string, double *number, const int base)
return 1;
}
int str_ends_with(const char *s, const char *suff) {
size_t slen;
size_t sufflen;
if (!s) return 0; /* null string does not end with anything */
if (!suff) return 1; /* null suffix tails anything */
slen = strlen(s);
sufflen = strlen(suff);
return (slen >= sufflen) && (!memcmp(s + slen - sufflen, suff, sufflen));
}

View file

@ -11,6 +11,16 @@ char *strerror(int errnum)
{
static char buf[32];
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic push
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE_BREAK
#pragma GCC diagnostic ignored "-Wunreachable-code-break"
#endif
#ifdef HAVE_PRAGMA_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic ignored "-Wunreachable-code"
#endif
switch (errnum) {
#if defined (EPERM)
case EPERM:
@ -498,6 +508,11 @@ char *strerror(int errnum)
/* Fallback: just print the error number */
snprintf(buf, sizeof(buf), "Error %d", errnum);
return buf;
#ifdef HAVE_PRAGMAS_FOR_GCC_DIAGNOSTIC_IGNORED_UNREACHABLE_CODE
#pragma GCC diagnostic pop
#endif
}
#endif /* HAVE_STRERROR */

View file

@ -17,6 +17,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h" /* must be the first header */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@ -29,14 +31,14 @@
static char *ups_section;
/* handle arguments separated by parseconf */
static void conf_args(int numargs, char **arg)
static void conf_args(size_t numargs, char **arg)
{
if (numargs < 1)
return;
/* look for section headers - [upsname] */
if ((arg[0][0] == '[') && (arg[0][strlen(arg[0])-1] == ']')) {
free(ups_section);
arg[0][strlen(arg[0])-1] = '\0';