From 7f1524669755d7a6e6cd1c3fb80084df273f3dc1 Mon Sep 17 00:00:00 2001 From: Thomas Markwalder Date: Thu, 23 Jan 2020 16:21:52 -0500 Subject: [#76] Initial implemention to dhcpctl_timed_wait_for_completion common/conflex.c includes/dhctoken.h dhcpctl/omshell.c Added support for "disconnect" dhcpctl/cltest.2 - new file that exercizes timed waits and disconnect dhcpctl/Makefile.am.in Added cltest2.c dhcpctl/dhcpctl.* dhcpctl_timed_wait_for_completion() - new function dhcpctl_disconnect() - new function Added debug logging omapip/dispatch.c Added protocol logging omapi_wait_for_completion() Fixed dangling waiter reference omapi_one_dispatch() Added logic to skip emit writefds from select list omapip/support.c Changed annoying DEBUG logs to DEBUG_PROTOCOL --- dhcpctl/Makefile.am | 9 +- dhcpctl/Makefile.am.in | 9 +- dhcpctl/Makefile.in | 179 ++++++++++++++----------------- dhcpctl/cltest2.c | 285 +++++++++++++++++++++++++++++++++++++++++++++++++ dhcpctl/dhcpctl.c | 145 ++++++++++++++++++++++++- dhcpctl/dhcpctl.h | 8 ++ dhcpctl/omshell.c | 23 ++++ 7 files changed, 559 insertions(+), 99 deletions(-) create mode 100644 dhcpctl/cltest2.c (limited to 'dhcpctl') diff --git a/dhcpctl/Makefile.am b/dhcpctl/Makefile.am index 0d669715..9e623375 100644 --- a/dhcpctl/Makefile.am +++ b/dhcpctl/Makefile.am @@ -5,7 +5,7 @@ BINDLIBISCDIR=@BINDLIBISCDIR@ bin_PROGRAMS = omshell lib_LIBRARIES = libdhcpctl.a -noinst_PROGRAMS = cltest +noinst_PROGRAMS = cltest cltest2 man_MANS = omshell.1 dhcpctl.3 EXTRA_DIST = $(man_MANS) @@ -24,3 +24,10 @@ cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ $(BINDLIBDNSDIR)/libdns.a \ $(BINDLIBISCCFGDIR)/libisccfg.a \ $(BINDLIBISCDIR)/libisc.a + +cltest2_SOURCES = cltest2.c +cltest2_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ + $(BINDLIBIRSDIR)/libirs.a \ + $(BINDLIBDNSDIR)/libdns.a \ + $(BINDLIBISCCFGDIR)/libisccfg.a \ + $(BINDLIBISCDIR)/libisc.a diff --git a/dhcpctl/Makefile.am.in b/dhcpctl/Makefile.am.in index 0d77ffc6..28333cef 100644 --- a/dhcpctl/Makefile.am.in +++ b/dhcpctl/Makefile.am.in @@ -5,7 +5,7 @@ BINDLIBISCDIR=@Q@BINDLIBISCDIR@Q@ bin_PROGRAMS = omshell lib_@DHLIBS@ = libdhcpctl.@A@ -noinst_PROGRAMS = cltest +noinst_PROGRAMS = cltest cltest2 man_MANS = omshell.1 dhcpctl.3 EXTRA_DIST = $(man_MANS) @@ -24,3 +24,10 @@ cltest_LDADD = libdhcpctl.@A@ ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \ $(BINDLIBDNSDIR)/libdns.@A@ \ $(BINDLIBISCCFGDIR)/libisccfg.@A@ \ $(BINDLIBISCDIR)/libisc.@A@ + +cltest2_SOURCES = cltest2.c +cltest2_LDADD = libdhcpctl.@A@ ../common/libdhcp.@A@ ../omapip/libomapi.@A@ \ + $(BINDLIBIRSDIR)/libirs.@A@ \ + $(BINDLIBDNSDIR)/libdns.@A@ \ + $(BINDLIBISCCFGDIR)/libisccfg.@A@ \ + $(BINDLIBISCDIR)/libisc.@A@ diff --git a/dhcpctl/Makefile.in b/dhcpctl/Makefile.in index 3c8232d1..e1da56a5 100644 --- a/dhcpctl/Makefile.in +++ b/dhcpctl/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.13.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -16,17 +16,7 @@ VPATH = @srcdir@ -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__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ @@ -90,20 +80,18 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = omshell$(EXEEXT) -noinst_PROGRAMS = cltest$(EXEEXT) +noinst_PROGRAMS = cltest$(EXEEXT) cltest2$(EXEEXT) subdir = dhcpctl +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.am.in $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(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)/includes/config.h CONFIG_CLEAN_FILES = Makefile.am CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \ - "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" -PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -131,6 +119,8 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" LIBRARIES = $(lib_LIBRARIES) ARFLAGS = cru AM_V_AR = $(am__v_AR_@AM_V@) @@ -142,12 +132,19 @@ libdhcpctl_a_LIBADD = am_libdhcpctl_a_OBJECTS = dhcpctl.$(OBJEXT) callback.$(OBJEXT) \ remote.$(OBJEXT) libdhcpctl_a_OBJECTS = $(am_libdhcpctl_a_OBJECTS) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) am_cltest_OBJECTS = cltest.$(OBJEXT) cltest_OBJECTS = $(am_cltest_OBJECTS) cltest_DEPENDENCIES = libdhcpctl.a ../common/libdhcp.a \ ../omapip/libomapi.a $(BINDLIBIRSDIR)/libirs.a \ $(BINDLIBDNSDIR)/libdns.a $(BINDLIBISCCFGDIR)/libisccfg.a \ $(BINDLIBISCDIR)/libisc.a +am_cltest2_OBJECTS = cltest2.$(OBJEXT) +cltest2_OBJECTS = $(am_cltest2_OBJECTS) +cltest2_DEPENDENCIES = libdhcpctl.a ../common/libdhcp.a \ + ../omapip/libomapi.a $(BINDLIBIRSDIR)/libirs.a \ + $(BINDLIBDNSDIR)/libdns.a $(BINDLIBISCCFGDIR)/libisccfg.a \ + $(BINDLIBISCDIR)/libisc.a am_omshell_OBJECTS = omshell.$(OBJEXT) omshell_OBJECTS = $(am_omshell_OBJECTS) omshell_DEPENDENCIES = libdhcpctl.a ../common/libdhcp.a \ @@ -168,10 +165,7 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/includes depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/callback.Po ./$(DEPDIR)/cltest.Po \ - ./$(DEPDIR)/dhcpctl.Po ./$(DEPDIR)/omshell.Po \ - ./$(DEPDIR)/remote.Po +am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -185,9 +179,10 @@ 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 = $(libdhcpctl_a_SOURCES) $(cltest_SOURCES) $(omshell_SOURCES) -DIST_SOURCES = $(libdhcpctl_a_SOURCES) $(cltest_SOURCES) \ +SOURCES = $(libdhcpctl_a_SOURCES) $(cltest_SOURCES) $(cltest2_SOURCES) \ $(omshell_SOURCES) +DIST_SOURCES = $(libdhcpctl_a_SOURCES) $(cltest_SOURCES) \ + $(cltest2_SOURCES) $(omshell_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -216,8 +211,6 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -am__DIST_COMMON = $(srcdir)/Makefile.am.in $(srcdir)/Makefile.in \ - $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) A = @A@ ACLOCAL = @ACLOCAL@ @@ -360,6 +353,13 @@ cltest_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ $(BINDLIBISCCFGDIR)/libisccfg.a \ $(BINDLIBISCDIR)/libisc.a +cltest2_SOURCES = cltest2.c +cltest2_LDADD = libdhcpctl.a ../common/libdhcp.a ../omapip/libomapi.a \ + $(BINDLIBIRSDIR)/libirs.a \ + $(BINDLIBDNSDIR)/libdns.a \ + $(BINDLIBISCCFGDIR)/libisccfg.a \ + $(BINDLIBISCDIR)/libisc.a + all: all-am .SUFFIXES: @@ -376,13 +376,14 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign dhcpctl/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign dhcpctl/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__maybe_remake_depfiles)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -395,6 +396,42 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__aclocal_m4_deps): Makefile.am: $(top_builddir)/config.status $(srcdir)/Makefile.am.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) + +libdhcpctl.a: $(libdhcpctl_a_OBJECTS) $(libdhcpctl_a_DEPENDENCIES) $(EXTRA_libdhcpctl_a_DEPENDENCIES) + $(AM_V_at)-rm -f libdhcpctl.a + $(AM_V_AR)$(libdhcpctl_a_AR) libdhcpctl.a $(libdhcpctl_a_OBJECTS) $(libdhcpctl_a_LIBADD) + $(AM_V_at)$(RANLIB) libdhcpctl.a install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ @@ -440,47 +477,15 @@ clean-binPROGRAMS: clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) -install-libLIBRARIES: $(lib_LIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } - @$(POST_INSTALL) - @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - if test -f $$p; then \ - $(am__strip_dir) \ - echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ - ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ - else :; fi; \ - done - -uninstall-libLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) - -clean-libLIBRARIES: - -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) - -libdhcpctl.a: $(libdhcpctl_a_OBJECTS) $(libdhcpctl_a_DEPENDENCIES) $(EXTRA_libdhcpctl_a_DEPENDENCIES) - $(AM_V_at)-rm -f libdhcpctl.a - $(AM_V_AR)$(libdhcpctl_a_AR) libdhcpctl.a $(libdhcpctl_a_OBJECTS) $(libdhcpctl_a_LIBADD) - $(AM_V_at)$(RANLIB) libdhcpctl.a cltest$(EXEEXT): $(cltest_OBJECTS) $(cltest_DEPENDENCIES) $(EXTRA_cltest_DEPENDENCIES) @rm -f cltest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(cltest_OBJECTS) $(cltest_LDADD) $(LIBS) +cltest2$(EXEEXT): $(cltest2_OBJECTS) $(cltest2_DEPENDENCIES) $(EXTRA_cltest2_DEPENDENCIES) + @rm -f cltest2$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(cltest2_OBJECTS) $(cltest2_LDADD) $(LIBS) + omshell$(EXEEXT): $(omshell_OBJECTS) $(omshell_DEPENDENCIES) $(EXTRA_omshell_DEPENDENCIES) @rm -f omshell$(EXEEXT) $(AM_V_CCLD)$(LINK) $(omshell_OBJECTS) $(omshell_LDADD) $(LIBS) @@ -491,31 +496,26 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cltest.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpctl.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omshell.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote.Po@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cltest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cltest2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dhcpctl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/omshell.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ @@ -655,10 +655,7 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -distdir: $(BUILT_SOURCES) - $(MAKE) $(AM_MAKEFLAGS) distdir-am - -distdir-am: $(DISTFILES) +distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -690,9 +687,9 @@ distdir-am: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) $(LIBRARIES) $(MANS) +all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(MANS) installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)"; do \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -731,11 +728,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/callback.Po - -rm -f ./$(DEPDIR)/cltest.Po - -rm -f ./$(DEPDIR)/dhcpctl.Po - -rm -f ./$(DEPDIR)/omshell.Po - -rm -f ./$(DEPDIR)/remote.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -781,11 +774,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/callback.Po - -rm -f ./$(DEPDIR)/cltest.Po - -rm -f ./$(DEPDIR)/dhcpctl.Po - -rm -f ./$(DEPDIR)/omshell.Po - -rm -f ./$(DEPDIR)/remote.Po + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -808,7 +797,7 @@ uninstall-man: uninstall-man1 uninstall-man3 .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libLIBRARIES \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-tags distdir dvi \ @@ -825,8 +814,6 @@ uninstall-man: uninstall-man1 uninstall-man3 uninstall-libLIBRARIES uninstall-man uninstall-man1 \ uninstall-man3 -.PRECIOUS: Makefile - # 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. diff --git a/dhcpctl/cltest2.c b/dhcpctl/cltest2.c new file mode 100644 index 00000000..26249a3e --- /dev/null +++ b/dhcpctl/cltest2.c @@ -0,0 +1,285 @@ +/* cltest2.c + + Example program that uses the dhcpctl library. */ + +/* + * Copyright (c) 2020 by Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Internet Systems Consortium, Inc. + * 950 Charter Street + * Redwood City, CA 94063 + * + * https://www.isc.org/ + * + * This software was contributed to Internet Systems Consortium + * by Brian Murrell. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include "omapip/result.h" +#include "dhcpctl.h" +#include "dhcpd.h" + +int main (int, char **); + +static void usage (char *s) { + fprintf (stderr, + "Usage: %s [-s ] [-p ]", s); + exit (1); +} + +static void fail_on_error(isc_result_t status, const char* message) { + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "%s: %s\n", + message, isc_result_totext (status)); + exit (1); + } +} + +isc_result_t wait_with_retry(dhcpctl_handle handle, struct timeval* timeout, int retries); + +void print_object(char *msg, dhcpctl_handle handle); + +/* Simple test program that exercises dhcpctl calls as follows: + * + * 1. Connect to the given server + * 2. Create a local host object with hostname "cltest2.host" + * 3. Attempt to open the remote host object + * 4. If the host does not exist, add a client id and create it + * 5. Disconnect + * 6. Reconnect + * 7. Refresh the host object + * + * Note that this program tests dhcpctl_timed_wait_for_completion() by calling + * it with extremely small timeouts. +*/ + +int main (argc, argv) + int argc; + char **argv; +{ + isc_result_t status; + dhcpctl_handle connection; + dhcpctl_handle host; + char* ip_address = "127.0.0.1"; + int port = 7911; + char* hostname = "cltest2.host"; + struct timeval timeout; + int i; + + for (i = 1; i < argc; i++) { + if (!strcmp (argv[i], "-s")) { + ip_address = argv[i]; + } else if (!strcmp (argv [i], "-p")) { + port=atoi(argv[i]); + } else if (argv[i][0] == '-') { + usage(argv[0]); + } + } + + /* Initialize dhcpctl */ + status = dhcpctl_initialize (); + fail_on_error(status ,"can't initialize dhcpctl"); + + /* Connect */ + connection = 0; + status = dhcpctl_connect (&connection, ip_address, port, 0); + fail_on_error(status ,"connect failed"); + + /* Create the host object */ + host = 0; + status = dhcpctl_new_object (&host, connection, "host"); + fail_on_error(status ,"new oject failed"); + + status = dhcpctl_set_string_value (host, hostname, "name"); + fail_on_error(status ,"cant set host name"); + + /* Attempt to open the object */ + status = dhcpctl_open_object (host, connection, 0); + timeout.tv_sec = 0; + timeout.tv_usec = 20; + status = wait_with_retry(host, &timeout, 2); + switch (status) { + case ISC_R_NOTFOUND: + /* Host doesn't exist add it. We set an id so the create will be valid. */ + status = dhcpctl_set_string_value (host, "abcdefg", "dhcp-client-identifier"); + fail_on_error(status ,"can't set client id"); + + status = dhcpctl_open_object (host, connection, + DHCPCTL_CREATE | DHCPCTL_EXCL); + fail_on_error(status, "open(create) failed"); + + status = wait_with_retry(host, &timeout, 2); + fail_on_error(status, "wait after open(create)"); + + print_object("Host created", host); + break; + + case ISC_R_SUCCESS: + print_object("Host exists", host); + break; + + default: + fail_on_error(status, "initial open failed, waiting for completion"); + break; + } + + + /* Now we'll test disconnect */ + status = dhcpctl_disconnect(&connection, 0); + fail_on_error(status, "can't disconnect"); + + /* Reconnect */ + status = dhcpctl_connect (&connection, ip_address, port, 0); + fail_on_error(status ,"can't reconnect"); + + /* Refresh the object */ + status = dhcpctl_object_refresh (connection, host); + fail_on_error(status , "can't refresh"); + + status = wait_with_retry(host, &timeout, 2); + fail_on_error(status , "wait after refresh failed"); + + print_object("After reconnect/refresh", host); + + exit (0); +} + +/* Function to call and optionally retry dhcp_timed_wait_for_completion() */ +isc_result_t wait_with_retry(dhcpctl_handle handle, struct timeval* timeout, int retries) { + isc_result_t status; + isc_result_t waitstatus; + struct timeval use_timeout; + + if (timeout) { + use_timeout.tv_sec = timeout->tv_sec; + use_timeout.tv_usec = timeout->tv_usec; + } else { + retries = 0; + } + + int tries = 0; + do { + if (tries++) { + printf ("wait retry #%d\n", tries); + /* Set the timeout value to 30 secs */ + use_timeout.tv_sec = 30; + use_timeout.tv_usec = 0; + } + + // Call timed wait. + status = dhcpctl_timed_wait_for_completion (handle, &waitstatus, + (timeout ? &use_timeout: 0)); + if (status == ISC_R_SUCCESS) { + return(waitstatus); + } + + if (status != ISC_R_TIMEDOUT) { + fprintf (stderr, "timed wait failed: %s\n", isc_result_totext (status)); + exit (1); + } + } while (--retries > 0); + + return (ISC_R_TIMEDOUT); +} + +/* Function to print out the values contained in an object. Largely + * stolen from omshell.c */ +void print_object(char* msg, dhcpctl_handle handle) { + dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)handle; + omapi_generic_object_t *object = (omapi_generic_object_t *)(r->inner); + char hex_buf[4096]; + int i; + + printf ("%s:\n",msg); + for (i = 0; i < object->nvalues; i++) { + omapi_value_t *v = object->values[i]; + + if (!object->values[i]) + continue; + + printf ("\t%.*s = ", (int)v->name->len, v->name->value); + + if (!v->value) { + printf ("\n"); + continue; + } + + switch (v->value->type) { + case omapi_datatype_int: + printf ("%d\n", v->value->u.integer); + break; + + case omapi_datatype_string: + printf ("\"%.*s\"\n", (int)v->value->u.buffer.len, + v->value->u.buffer.value); + break; + + case omapi_datatype_data: + print_hex_or_string(v->value->u.buffer.len, + v->value->u.buffer.value, + sizeof(hex_buf), hex_buf); + printf("%s\n", hex_buf); + break; + + case omapi_datatype_object: + printf ("\n"); + break; + } + } +} + +/* Dummy functions to appease linker */ +isc_result_t find_class (struct class **c, const char *n, const char *f, int l) +{ + return 0; +} +int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag) +{ + return 0; +} +void dhcp (struct packet *packet) { } +void bootp (struct packet *packet) { } + +#ifdef DHCPv6 +void dhcpv6(struct packet *packet) { } + +#ifdef DHCP4o6 +isc_result_t dhcpv4o6_handler(omapi_object_t *h) +{ + return ISC_R_NOTIMPLEMENTED; +} +#endif /* DHCP4o6 */ +#endif /* DHCPv6 */ + +int check_collection (struct packet *p, struct lease *l, struct collection *c) +{ + return 0; +} +void classify (struct packet *packet, struct class *class) { } + +isc_result_t dhcp_set_control_state (control_object_state_t oldstate, + control_object_state_t newstate) +{ + return ISC_R_SUCCESS; +} + diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c index 3c78bc19..e8834382 100644 --- a/dhcpctl/dhcpctl.c +++ b/dhcpctl/dhcpctl.c @@ -29,6 +29,10 @@ #include "dhcpd.h" #include #include "dhcpctl.h" +#include + + +/* #define DEBUG_DHCPCTL 1 */ omapi_object_type_t *dhcpctl_callback_type; omapi_object_type_t *dhcpctl_remote_type; @@ -97,6 +101,9 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection, dhcpctl_handle authinfo) { isc_result_t status; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_connect(%s:%d)", server_name, port); +#endif status = omapi_generic_new (connection, MDL); if (status != ISC_R_SUCCESS) { @@ -105,19 +112,35 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection, status = omapi_protocol_connect (*connection, server_name, (unsigned)port, authinfo); - if (status == ISC_R_SUCCESS) + if (status == ISC_R_SUCCESS) { +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_connect success"); +#endif return status; + } + if (status != DHCP_R_INCOMPLETE) { omapi_object_dereference (connection, MDL); +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_connect failed:%s", + isc_result_totext (status)); +#endif return status; } status = omapi_wait_for_completion (*connection, 0); if (status != ISC_R_SUCCESS) { omapi_object_dereference (connection, MDL); +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_connect, wait failed:%s", + isc_result_totext (status)); +#endif return status; } +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_connect success"); +#endif return status; } @@ -137,8 +160,58 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection, dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h, dhcpctl_status *s) { +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_wait_for_completion"); +#endif isc_result_t status; status = omapi_wait_for_completion (h, 0); + if (status != ISC_R_SUCCESS) { + return status; + } + if (h -> type == dhcpctl_remote_type) + *s = ((dhcpctl_remote_object_t *)h) -> waitstatus; + + return ISC_R_SUCCESS; +} + +/* dhcpctl_wait_for_completion + + synchronous + returns zero if the callback completes, a nonzero status if + there was some problem relating to the wait operation. The + status of the queued request will be stored through s, and + will also be either zero for success or nonzero for some kind + of failure. Never returns until completion or until the + connection to the server is lost. This performs the same + function as dhcpctl_set_callback and the subsequent callback, + for programs that want to do inline execution instead of using + callbacks. */ + +dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h, + dhcpctl_status *s, + struct timeval *t) +{ + isc_result_t status; + struct timeval adjusted_t; + +#ifdef DEBUG_DHCPCTL + if (t) { + log_debug ("dhcpctl_timed_wait_for_completion(%u.%u secs.usecs)", + (unsigned int)(t->tv_sec), + (unsigned int)(t->tv_usec)); + } else { + log_debug ("dhcpctl_timed_wait_for_completion(no timeout)"); + } +#endif + + if (t) { + struct timeval now; + gettimeofday (&now, (struct timezone *)0); + adjusted_t.tv_sec = now.tv_sec + t->tv_sec; + adjusted_t.tv_usec = now.tv_usec + t->tv_usec; + } + + status = omapi_wait_for_completion (h, (t ? &adjusted_t : 0)); if (status != ISC_R_SUCCESS) return status; if (h -> type == dhcpctl_remote_type) @@ -146,6 +219,7 @@ dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle h, return ISC_R_SUCCESS; } + /* dhcpctl_get_value synchronous @@ -168,6 +242,9 @@ dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *result, omapi_value_t *tv = (omapi_value_t *)0; unsigned len; int ip; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_get_value(%s)", value_name); +#endif status = omapi_get_value_str (h, (omapi_object_t *)0, value_name, &tv); if (status != ISC_R_SUCCESS) @@ -232,6 +309,10 @@ dhcpctl_status dhcpctl_get_boolean (int *result, isc_result_t status; dhcpctl_data_string data = (dhcpctl_data_string)0; int rv; + +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_get_boolean(%s)", value_name); +#endif status = dhcpctl_get_value (&data, h, value_name); if (status != ISC_R_SUCCESS) @@ -258,6 +339,9 @@ dhcpctl_status dhcpctl_set_value (dhcpctl_handle h, dhcpctl_data_string value, isc_result_t status; omapi_typed_data_t *tv = (omapi_typed_data_t *)0; omapi_data_string_t *name = (omapi_data_string_t *)0; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_value(%s)", value_name); +#endif status = omapi_data_string_new (&name, strlen (value_name), MDL); if (status != ISC_R_SUCCESS) @@ -291,6 +375,9 @@ dhcpctl_status dhcpctl_set_string_value (dhcpctl_handle h, const char *value, isc_result_t status; omapi_typed_data_t *tv = (omapi_typed_data_t *)0; omapi_data_string_t *name = (omapi_data_string_t *)0; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_string_value(%s)", value_name); +#endif status = omapi_data_string_new (&name, strlen (value_name), MDL); if (status != ISC_R_SUCCESS) @@ -324,6 +411,9 @@ dhcpctl_status dhcpctl_set_data_value (dhcpctl_handle h, omapi_typed_data_t *tv = (omapi_typed_data_t *)0; omapi_data_string_t *name = (omapi_data_string_t *)0; unsigned ll; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_data_value(%s)", value_name); +#endif ll = strlen (value_name); status = omapi_data_string_new (&name, ll, MDL); @@ -355,6 +445,9 @@ dhcpctl_status dhcpctl_set_null_value (dhcpctl_handle h, isc_result_t status; omapi_data_string_t *name = (omapi_data_string_t *)0; unsigned ll; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_null_value(%s)", value_name); +#endif ll = strlen (value_name); status = omapi_data_string_new (&name, ll, MDL); @@ -379,6 +472,9 @@ dhcpctl_status dhcpctl_set_boolean_value (dhcpctl_handle h, int value, isc_result_t status; omapi_typed_data_t *tv = (omapi_typed_data_t *)0; omapi_data_string_t *name = (omapi_data_string_t *)0; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_boolean_value(%s)", value_name); +#endif status = omapi_data_string_new (&name, strlen (value_name), MDL); if (status != ISC_R_SUCCESS) @@ -408,6 +504,9 @@ dhcpctl_status dhcpctl_set_int_value (dhcpctl_handle h, int value, isc_result_t status; omapi_typed_data_t *tv = (omapi_typed_data_t *)0; omapi_data_string_t *name = (omapi_data_string_t *)0; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_set_int_value(%s)", value_name); +#endif status = omapi_data_string_new (&name, strlen (value_name), MDL); if (status != ISC_R_SUCCESS) @@ -438,6 +537,9 @@ dhcpctl_status dhcpctl_object_update (dhcpctl_handle connection, isc_result_t status; omapi_object_t *message = (omapi_object_t *)0; dhcpctl_remote_object_t *ro; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_object_update"); +#endif if (h -> type != dhcpctl_remote_type) return DHCP_R_INVALIDARG; @@ -487,6 +589,9 @@ dhcpctl_status dhcpctl_object_refresh (dhcpctl_handle connection, isc_result_t status; omapi_object_t *message = (omapi_object_t *)0; dhcpctl_remote_object_t *ro; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_object_refresh"); +#endif if (h -> type != dhcpctl_remote_type) return DHCP_R_INVALIDARG; @@ -540,6 +645,9 @@ dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection, isc_result_t status; omapi_object_t *message = (omapi_object_t *)0; dhcpctl_remote_object_t *ro; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_object_remove"); +#endif if (h -> type != dhcpctl_remote_type) return DHCP_R_INVALIDARG; @@ -582,5 +690,40 @@ dhcpctl_status dhcpctl_object_remove (dhcpctl_handle connection, isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *vp, const char *file, int line) { +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_data_string_dereference"); +#endif return omapi_data_string_dereference (vp, file, line); } + +dhcpctl_status dhcpctl_disconnect (dhcpctl_handle *connection, + int force) +{ + isc_result_t status; +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_disconnect()"); +#endif + if (!connection || !((*connection)->outer) || + !((*connection)->outer->type) || + ((*connection)->outer->type != omapi_type_protocol) || + !((*connection)->outer->outer)) { + log_debug("dhcpctl_disconnect detected invalid arg"); + return DHCP_R_INVALIDARG; + } + + status = omapi_disconnect ((*connection)->outer->outer, force); + if (status == ISC_R_SUCCESS) { +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_disconnect success"); +#endif + omapi_object_dereference (connection, MDL); + return status; + } + +#ifdef DEBUG_DHCPCTL + log_debug("dhcpctl_disconnect failed:%s", + isc_result_totext (status)); +#endif + return status; +} + diff --git a/dhcpctl/dhcpctl.h b/dhcpctl/dhcpctl.h index 3c0da74b..0f779bd8 100644 --- a/dhcpctl/dhcpctl.h +++ b/dhcpctl/dhcpctl.h @@ -63,6 +63,11 @@ dhcpctl_status dhcpctl_initialize (void); dhcpctl_status dhcpctl_connect (dhcpctl_handle *, const char *, int, dhcpctl_handle); dhcpctl_status dhcpctl_wait_for_completion (dhcpctl_handle, dhcpctl_status *); + +dhcpctl_status dhcpctl_timed_wait_for_completion (dhcpctl_handle h, + dhcpctl_status *s, + struct timeval *t); + dhcpctl_status dhcpctl_get_value (dhcpctl_data_string *, dhcpctl_handle, const char *); dhcpctl_status dhcpctl_get_boolean (int *, dhcpctl_handle, const char *); @@ -116,4 +121,7 @@ isc_result_t dhcpctl_remote_stuff_values (omapi_object_t *, omapi_object_t *); isc_result_t dhcpctl_data_string_dereference (dhcpctl_data_string *, const char *, int); + +dhcpctl_status dhcpctl_disconnect (dhcpctl_handle *, int); + #endif /* _DHCPCTL_H_ */ diff --git a/dhcpctl/omshell.c b/dhcpctl/omshell.c index d5d31aa8..785f59a6 100644 --- a/dhcpctl/omshell.c +++ b/dhcpctl/omshell.c @@ -208,6 +208,7 @@ main(int argc, char **argv) { printf (" server \n"); printf (" key \n"); printf (" connect\n"); + printf (" disconnect\n"); printf (" new \n"); printf (" set = \n"); printf (" create\n"); @@ -427,6 +428,28 @@ main(int argc, char **argv) { connected = 1; break; + case DISCONNECT: + token = next_token (&val, (unsigned *)0, cfile); + if (token != END_OF_FILE && token != EOL) { + printf ("usage: disconnect\n"); + skip_to_semi (cfile); + break; + } + + if (!connected || !connection) { + fprintf (stderr, "not connected\n"); + break; + } + + status = dhcpctl_disconnect (&connection, 0); + if (status != ISC_R_SUCCESS) { + fprintf (stderr, "dhcpctl_disconnect: %s\n", + isc_result_totext (status)); + break; + } + connected = 0; + break; + case TOKEN_NEW: token = next_token (&val, (unsigned *)0, cfile); if ((!is_identifier (token) && token != STRING)) { -- cgit v1.2.1