diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 354c8dcc..ddef492d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,10 +16,10 @@ jobs: # 1) checkout and compile natively - name: install cligen run: (git clone https://github.com/clicon/cligen.git && cd cligen && ./configure && make && sudo make install) - - name: install ssl and nghttp2 - run: sudo apt install -y libssl-dev libnghttp2-dev + - name: install dependencies + run: sudo apt install -y libssl-dev libnghttp2-dev curl-dev - name: configure run: ./configure # 2) Use docker for tests - name: make test # this is docker test - run: make test \ No newline at end of file + run: make test diff --git a/apps/restconf/restconf_main_native.c b/apps/restconf/restconf_main_native.c index 02defaf4..1f6f1004 100644 --- a/apps/restconf/restconf_main_native.c +++ b/apps/restconf/restconf_main_native.c @@ -567,6 +567,9 @@ restconf_accept_client(int fd, addr = &(in6->sin6_addr); break; } + default: + errno = EAFNOSUPPORT; + goto done; } if (rsock->rs_from_addr != NULL){ free(rsock->rs_from_addr); diff --git a/configure b/configure index 33aa03e1..310aa9dd 100755 --- a/configure +++ b/configure @@ -633,16 +633,21 @@ ac_ct_CXX CXXFLAGS CXX CPP +LOCALSTATEDIR +LIBDIR +SYSCONFDIR MIB_GENERATED_YANG_DIR YANG_STANDARD_DIR YANG_INSTALLDIR CLIXON_YANG_SCHEMA_MOUNT CLIXON_YANG_PATCH +LIBXML2_CFLAGS with_libxml2 HAVE_HTTP1 HAVE_LIBNGHTTP2 enable_netsnmp with_restconf +with_libcurl LINKAGE LIBSTATIC_SUFFIX SH_SUFFIX @@ -723,6 +728,7 @@ enable_debug with_cligen enable_yang_patch enable_yang_schema_mount +with_libcurl enable_publish with_restconf enable_http1 @@ -1390,6 +1396,8 @@ Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-cligen=dir Use CLIGEN installation in this dir + --without-libcurl Disable use of libcurl, affects publish + notification, including clixon_util_stream --with-restconf=native Integration with embedded web server (DEFAULT) --with-restconf=fcgi FCGI interface for stand-alone web rev-proxy eg nginx @@ -1398,7 +1406,8 @@ Optional Packages: Directory of generated YANG specs (default: $prefix/share/mib-yangs) --with-configfile=FILE Set default path to config file - --with-libxml2 Use gnome/libxml2 regex engine + --with-libxml2[=/path/to/xml2-config] + Use libxml2 regex engine --without-sigaction Don't use sigaction --with-yang-installdir=DIR Install Clixon yang files here (default: @@ -3413,6 +3422,7 @@ HAVE_HTTP1=false # SNMP tests require generated YANGs from MIBs +# Used in expansion in, e.g., example/main/example.xml.in # ac_ext=c @@ -4697,25 +4707,16 @@ $as_echo "#define CLIXON_YANG_SCHEMA_MOUNT 1" >>confdefs.h fi -# Experimental: Curl publish notification stream to eg Nginx nchan. -# Check whether --enable-publish was given. -if test "${enable_publish+set}" = set; then : - enableval=$enable_publish; - if test "$enableval" = no; then - ac_enable_publish=no - else - ac_enable_publish=yes - fi +# publish streams uses libcurl +# Check whether --with-libcurl was given. +if test "${with_libcurl+set}" = set; then : + withval=$with_libcurl; with_libcurl=$withval else - ac_enable_publish=no + with_libcurl=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: publish is $ac_enable_publish" >&5 -$as_echo "publish is $ac_enable_publish" >&6; } - -if test "$ac_enable_publish" = "yes"; then - # publish streams uses libcurl +if test "x${with_libcurl}" != "xno"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } @@ -4976,16 +4977,16 @@ fi done -for ac_header in curl.h +for ac_header in curl/curl.h do : - ac_fn_c_check_header_mongrel "$LINENO" "curl.h" "ac_cv_header_curl_h" "$ac_includes_default" -if test "x$ac_cv_header_curl_h" = xyes; then : + ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default" +if test "x$ac_cv_header_curl_curl_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define HAVE_CURL_H 1 +#define HAVE_CURL_CURL_H 1 _ACEOF else - as_fn_error $? "curl missing" "$LINENO" 5 + as_fn_error $? "curl header(s) missing" "$LINENO" 5 fi done @@ -5037,10 +5038,32 @@ else as_fn_error $? "libcurl missing" "$LINENO" 5 fi +fi + +# Experimental: Curl publish notification stream to eg Nginx nchan. +# Check whether --enable-publish was given. +if test "${enable_publish+set}" = set; then : + enableval=$enable_publish; + if test "$enableval" = no; then + ac_enable_publish=no + else + ac_enable_publish=yes + fi + +else + ac_enable_publish=no +fi + +if test "$ac_enable_publish" = "yes"; then + if test "x${with_libcurl}" = "xno"; then + as_fn_error $? "--enable-publish conflicts with --without-libcurl" "$LINENO" 5 + fi $as_echo "#define CLIXON_PUBLISH_STREAMS 1" >>confdefs.h fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: publish is $ac_enable_publish" >&5 +$as_echo "publish is $ac_enable_publish" >&6; } for ac_header in cligen/cligen.h do : @@ -5120,7 +5143,7 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: restconf mode ${with_restconf}" >&5 $as_echo "restconf mode ${with_restconf}" >&6; } # Actions for each specific package -if test "x${with_restconf}" == xfcgi; then +if test "x${with_restconf}" = xfcgi; then # Lives in libfcgi-dev { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FCGX_Init in -lfcgi" >&5 $as_echo_n "checking for FCGX_Init in -lfcgi... " >&6; } @@ -5172,7 +5195,7 @@ fi $as_echo "#define WITH_RESTCONF_FCGI 1" >>confdefs.h # For c-code that cant use strings -elif test "x${with_restconf}" == xnative; then +elif test "x${with_restconf}" = xnative; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_init_ssl in -lssl" >&5 $as_echo_n "checking for OPENSSL_init_ssl in -lssl... " >&6; } if ${ac_cv_lib_ssl_OPENSSL_init_ssl_+:} false; then : @@ -5374,7 +5397,7 @@ fi $as_echo "#define WITH_RESTCONF_NATIVE 1" >>confdefs.h # For c-code that cant use strings -elif test "x${with_restconf}" == xno; then +elif test "x${with_restconf}" = xno; then # Cant get around "no" as an answer for --without-restconf that is reset here to undefined with_restconf= else @@ -5657,6 +5680,16 @@ fi if test "${with_libxml2}"; then # Find libxml2 lib + if test -x "${with_libxml2}" 2>/dev/null; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml2 header files and libs" >&5 +$as_echo_n "checking for libxml2 header files and libs... " >&6; } + LIBXML2_CFLAGS="`${with_libxml2} --cflags`" + LIBS="$LIBS `${with_libxml2} --libs`" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBXML2_CFLAGS" >&5 +$as_echo "$LIBXML2_CFLAGS" >&6; } + else + LIBXML2_CFLAGS="-I/usr/include/libxml2" + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xmlRegexpCompile in -lxml2" >&5 $as_echo_n "checking for xmlRegexpCompile in -lxml2... " >&6; } if ${ac_cv_lib_xml2_xmlRegexpCompile+:} false; then : @@ -5731,7 +5764,7 @@ else fi -if test "x${with_sigaction}" == "xyes"; then +if test "x${with_sigaction}" = "xyes"; then for ac_func in sigaction do : ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" @@ -5815,6 +5848,15 @@ fi +# Expand for easy replacement in example/main/example.xml.in +# Special case is $libdir, which is composed from $exec_prefix +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +SYSCONFDIR=`eval echo $sysconfdir` +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` +LOCALSTATEDIR=`eval echo $localstatedir` + ac_config_files="$ac_config_files Makefile lib/Makefile lib/src/Makefile lib/clixon/Makefile apps/Makefile apps/cli/Makefile apps/backend/Makefile apps/netconf/Makefile apps/restconf/Makefile apps/snmp/Makefile include/Makefile etc/Makefile etc/clixonrc example/Makefile example/main/Makefile example/main/example.xml extras/rpm/Makefile docker/Makefile docker/clixon-dev/Makefile docker/example/Makefile docker/test/Makefile util/Makefile yang/Makefile yang/clixon/Makefile yang/mandatory/Makefile doc/Makefile test/Makefile test/config.sh test/cicd/Makefile test/vagrant/Makefile" cat >confcache <<\_ACEOF diff --git a/configure.ac b/configure.ac index c941465a..35fa1302 100644 --- a/configure.ac +++ b/configure.ac @@ -114,11 +114,13 @@ AC_SUBST(LIBS) AC_SUBST(SH_SUFFIX) AC_SUBST(LIBSTATIC_SUFFIX) AC_SUBST(LINKAGE) +AC_SUBST(with_libcurl) AC_SUBST(with_restconf) # Set to native or fcgi -> compile apps/restconf AC_SUBST(enable_netsnmp) # Enable build of apps/snmp AC_SUBST(HAVE_LIBNGHTTP2,false) # consider using neutral constant such as with-http2 AC_SUBST(HAVE_HTTP1,false) -AC_SUBST(with_libxml2) +AC_SUBST(with_libxml2) +AC_SUBST(LIBXML2_CFLAGS) AC_SUBST(CLIXON_YANG_PATCH) AC_SUBST(CLIXON_YANG_SCHEMA_MOUNT) # Where Clixon installs its YANG specs @@ -127,6 +129,10 @@ AC_SUBST(YANG_INSTALLDIR) AC_SUBST(YANG_STANDARD_DIR) # SNMP tests require generated YANGs from MIBs AC_SUBST(MIB_GENERATED_YANG_DIR) +# Used in expansion in, e.g., example/main/example.xml.in +AC_SUBST(SYSCONFDIR) +AC_SUBST(LIBDIR) +AC_SUBST(LOCALSTATEDIR) # AC_PROG_CC() @@ -212,8 +218,19 @@ if test "${enable_yang_schema_mount}" = "yes"; then AC_DEFINE(CLIXON_YANG_SCHEMA_MOUNT, 1, [Enable YANG schema mount, RFC 8528]) fi +# publish streams uses libcurl +AC_ARG_WITH([libcurl], + [AS_HELP_STRING([--without-libcurl], + [Disable use of libcurl, affects publish notification, including clixon_util_stream])], + [with_libcurl=$withval],[with_libcurl=yes]) +if test "x${with_libcurl}" != "xno"; then + AC_CHECK_HEADERS(curl/curl.h,[], AC_MSG_ERROR([curl header(s) missing])) + AC_CHECK_LIB(curl, curl_global_init,, AC_MSG_ERROR([libcurl missing])) +fi + # Experimental: Curl publish notification stream to eg Nginx nchan. -AC_ARG_ENABLE(publish, AS_HELP_STRING([--enable-publish],[Enable publish of notification streams using SSE and curl]),[ +AC_ARG_ENABLE(publish, AS_HELP_STRING([--enable-publish], + [Enable publish of notification streams using SSE and curl]),[ if test "$enableval" = no; then ac_enable_publish=no else @@ -221,14 +238,13 @@ AC_ARG_ENABLE(publish, AS_HELP_STRING([--enable-publish],[Enable publish of noti fi ], [ ac_enable_publish=no]) -AC_MSG_RESULT(publish is $ac_enable_publish) - if test "$ac_enable_publish" = "yes"; then - # publish streams uses libcurl - AC_CHECK_HEADERS(curl.h,[], AC_MSG_ERROR([curl missing])) - AC_CHECK_LIB(curl, curl_global_init,, AC_MSG_ERROR([libcurl missing])) + if test "x${with_libcurl}" = "xno"; then + AC_MSG_ERROR([--enable-publish conflicts with --without-libcurl]) + fi AC_DEFINE(CLIXON_PUBLISH_STREAMS, 1, [Enable publish of notification streams using SSE and curl]) fi +AC_MSG_RESULT(publish is $ac_enable_publish) AC_CHECK_HEADERS(cligen/cligen.h,, AC_MSG_ERROR([CLIgen missing. Try: git clone https://github.com/clicon/cligen.git])) @@ -244,11 +260,11 @@ AC_ARG_WITH([restconf], [with_restconf=native]) AC_MSG_RESULT(restconf mode ${with_restconf}) # Actions for each specific package -if test "x${with_restconf}" == xfcgi; then +if test "x${with_restconf}" = xfcgi; then # Lives in libfcgi-dev AC_CHECK_LIB(fcgi, FCGX_Init,, AC_MSG_ERROR([libfcgi-dev missing])) AC_DEFINE(WITH_RESTCONF_FCGI, 1, [Use fcgi restconf mode]) # For c-code that cant use strings -elif test "x${with_restconf}" == xnative; then +elif test "x${with_restconf}" = xnative; then AC_CHECK_LIB(ssl, OPENSSL_init_ssl ,, AC_MSG_ERROR([libssl missing])) AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, , AC_MSG_ERROR([libcrypto missing])) # Check if http/1 enabled @@ -283,7 +299,7 @@ elif test "x${with_restconf}" == xnative; then HAVE_LIBNGHTTP2=true fi AC_DEFINE(WITH_RESTCONF_NATIVE, 1, [Use native restconf mode]) # For c-code that cant use strings -elif test "x${with_restconf}" == xno; then +elif test "x${with_restconf}" = xno; then # Cant get around "no" as an answer for --without-restconf that is reset here to undefined with_restconf= else @@ -344,9 +360,17 @@ AC_CHECK_LIB(dl, dlopen) # Note this only enables the compiling of the code. In order to actually # use it you need to set Clixon config option CLICON_YANG_REGEXP to libxml2 AC_ARG_WITH([libxml2], - [AS_HELP_STRING([--with-libxml2],[Use gnome/libxml2 regex engine])]) + [AS_HELP_STRING([--with-libxml2[[=/path/to/xml2-config]]],[Use libxml2 regex engine])]) if test "${with_libxml2}"; then # Find libxml2 lib + if test -x "${with_libxml2}" 2>/dev/null; then + AC_MSG_CHECKING([for libxml2 header files and libs]) + LIBXML2_CFLAGS="`${with_libxml2} --cflags`" + LIBS="$LIBS `${with_libxml2} --libs`" + AC_MSG_RESULT([$LIBXML2_CFLAGS]) + else + LIBXML2_CFLAGS="-I/usr/include/libxml2" + fi AC_CHECK_LIB(xml2, xmlRegexpCompile,[], AC_MSG_ERROR([libxml2 not found])) fi @@ -361,7 +385,7 @@ AC_ARG_WITH( [with_sigaction=yes] ) -if test "x${with_sigaction}" == "xyes"; then +if test "x${with_sigaction}" = "xyes"; then AC_CHECK_FUNCS(sigaction) fi @@ -400,6 +424,15 @@ AC_ARG_ENABLE(nls) AH_BOTTOM([#include ]) +# Expand for easy replacement in example/main/example.xml.in +# Special case is $libdir, which is composed from $exec_prefix +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +SYSCONFDIR=`eval echo $sysconfdir` +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` +LOCALSTATEDIR=`eval echo $localstatedir` + AC_OUTPUT(Makefile lib/Makefile lib/src/Makefile diff --git a/example/main/Makefile.in b/example/main/Makefile.in index 78243822..aa94895d 100644 --- a/example/main/Makefile.in +++ b/example/main/Makefile.in @@ -69,7 +69,7 @@ endif with_restconf = @with_restconf@ -INCLUDES = -I$(includedir) @INCLUDES@ +INCLUDES = -I$(DESTDIR)$(includedir) @INCLUDES@ LINKAGE = @LINKAGE@ LDFLAGS = @LDFLAGS@ CPPFLAGS = @CPPFLAGS@ diff --git a/example/main/example.xml.in b/example/main/example.xml.in index 4cb2a3e4..c50a8975 100644 --- a/example/main/example.xml.in +++ b/example/main/example.xml.in @@ -1,23 +1,23 @@ - /usr/local/etc/example.xml + @SYSCONFDIR@/example.xml ietf-netconf:startup ietf-netconf:confirmed-commit clixon-restconf:allow-auth-none clixon-restconf:fcgi - /usr/local/share/clixon + @YANG_INSTALLDIR@ @YANG_STANDARD_DIR@ clixon-example example - /usr/local/lib/example/backend - /usr/local/lib/example/netconf - /usr/local/lib/example/restconf - /usr/local/lib/example/cli - /usr/local/lib/example/clispec - /usr/local/var/example/example.sock - /usr/local/var/example/example.pidfile + @LIBDIR@/example/backend + @LIBDIR@/example/netconf + @LIBDIR@/example/restconf + @LIBDIR@/example/cli + @LIBDIR@/example/clispec + @LOCALSTATEDIR@/run/example.sock + @LOCALSTATEDIR@/run/example.pid 0 0 - /usr/local/var/example + @LOCALSTATEDIR@/lib/misc init disabled true diff --git a/include/clixon_config.h.in b/include/clixon_config.h.in index 142e7611..fa506fc5 100644 --- a/include/clixon_config.h.in +++ b/include/clixon_config.h.in @@ -30,8 +30,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CLIGEN_CLIGEN_H -/* Define to 1 if you have the header file. */ -#undef HAVE_CURL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_CURL_CURL_H /* Define to 1 if you have the `getpeereid' function. */ #undef HAVE_GETPEEREID diff --git a/test/lib.sh b/test/lib.sh index 24e0b8c9..1538793a 100755 --- a/test/lib.sh +++ b/test/lib.sh @@ -554,7 +554,7 @@ function stop_backend(){ sleep 1 checkvalgrind fi - sudo pkill -f clixon_backend # extra ($BUSER?) +# sudo pkill -f clixon_backend # extra ($BUSER?) } # Wait for restconf to stop sending 502 Bad Gateway @@ -638,7 +638,7 @@ function wait_restconf(){ sleep 2 # some problems with valgrind fi - stty $STTYSETTINGS + stty $STTYSETTINGS >/dev/null } # Wait for restconf to stop diff --git a/test/test_restconf_internal.sh b/test/test_restconf_internal.sh index 2bedd838..9eb4538d 100755 --- a/test/test_restconf_internal.sh +++ b/test/test_restconf_internal.sh @@ -115,7 +115,7 @@ EOF err "No pid return value" "$retx" fi if $active; then - expect="^$activeClixon RESTCONF process/.*/clixon_restconf -f $cfg -D [0-9] .*$status20[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*Z$pid$" + expect="^$activeClixon RESTCONF process/.*/clixon_restconf -f $cfg -D [0-9] .*$status20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9]*Z$pid$" else # inactive, no startime or pid expect="^$activeClixon RESTCONF process/.*/clixon_restconf -f $cfg -D [0-9] .*$status$" @@ -320,6 +320,7 @@ if [ $BE -ne 0 ]; then fi # kill backend stop_backend -f $cfg + killall clixon_restconf fi # Restconf is enabled and restconf was running but was killed by stop ^. diff --git a/util/Makefile.in b/util/Makefile.in index 552cedda..536a8a65 100644 --- a/util/Makefile.in +++ b/util/Makefile.in @@ -46,7 +46,8 @@ localstatedir = @localstatedir@ sysconfdir = @sysconfdir@ HOST_VENDOR = @host_vendor@ with_restconf = @with_restconf@ -HAVE_LIBXML2 = @HAVE_LIBXML2@ +with_libcurl = @with_libcurl@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ SH_SUFFIX = @SH_SUFFIX@ @@ -102,7 +103,9 @@ APPSRC += clixon_util_dispatcher.c APPSRC += clixon_netconf_ssh_callhome.c APPSRC += clixon_netconf_ssh_callhome_client.c ifdef with_restconf -APPSRC += clixon_util_stream.c # Needs curl +ifdef with_libcurl +APPSRC += clixon_util_stream.c +endif ifeq ($(with_restconf), native) APPSRC += clixon_restconf_callhome_client.c endif @@ -150,7 +153,7 @@ clixon_util_xml_mod: clixon_util_xml_mod.c $(LIBDEPS) $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -D__PROGRAM__=\"$@\" $(LDFLAGS) $^ $(LIBS) -o $@ clixon_util_regexp: clixon_util_regexp.c $(LIBDEPS) - $(CC) $(INCLUDES) -I /usr/include/libxml2 $(CPPFLAGS) -D__PROGRAM__=\"$@\" $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CC) $(INCLUDES) $(LIBXML2_CFLAGS) $(CPPFLAGS) -D__PROGRAM__=\"$@\" $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@ clixon_util_socket: clixon_util_socket.c $(LIBDEPS) $(CC) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) -D__PROGRAM__=\"$@\" $(LDFLAGS) $^ $(LIBS) -o $@