new upstream 2.8.0
This commit is contained in:
parent
fc7f4b43c1
commit
b2b0c9995a
836 changed files with 137090 additions and 30018 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
580
common/common.c
580
common/common.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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, "=");
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
60
common/str.c
60
common/str.c
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue