From 5c5a0bf2c9f9cdd28668d9e04a423bb8bc373e3b Mon Sep 17 00:00:00 2001 From: David Smith Date: Mon, 1 May 2017 15:55:51 -0500 Subject: [PATCH] Added initial http web service server code. * httpd/Makefile.am * httpd/Makefile.in: Generated. * httpd/main.cxx: httpd main program source. * httpd/server.cxx: httpd server framework * httpd/server.h: httpd server include file * configure.ac: Make sure we have the microhttpd and uuid libraries before trying to build the httpd code. * Makefile.am: Added 'httpd' subdirectory. * Makefile.in: Regenerated. * config.in: Ditto. * configure: Ditto. --- Makefile.am | 2 +- Makefile.in | 6 +- config.in | 6 + configure | 203 ++++++++++++- configure.ac | 25 ++ httpd/Makefile.am | 33 +++ httpd/Makefile.in | 715 ++++++++++++++++++++++++++++++++++++++++++++++ httpd/main.cxx | 37 +++ httpd/server.cxx | 368 ++++++++++++++++++++++++ httpd/server.h | 114 ++++++++ 10 files changed, 1506 insertions(+), 3 deletions(-) create mode 100644 httpd/Makefile.am create mode 100644 httpd/Makefile.in create mode 100644 httpd/main.cxx create mode 100644 httpd/server.cxx create mode 100644 httpd/server.h diff --git a/Makefile.am b/Makefile.am index 2668f923e..92f35f85b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -324,7 +324,7 @@ if BUILD_SERVER rm -f $(DESTDIR)$(localstatedir)/log/stap-server/log endif -SUBDIRS = . java python stapdyn staprun stapbpf doc man po +SUBDIRS = . java python stapdyn staprun stapbpf doc man po httpd # NB: the gcov target above uses this to enumarate linked binaries' build directories DIST_SUBDIRS = testsuite $(SUBDIRS) EXTRA_DIST = m4/ChangeLog diff --git a/Makefile.in b/Makefile.in index 0f464bbf0..d8e7ff198 100644 --- a/Makefile.in +++ b/Makefile.in @@ -531,6 +531,8 @@ jsonc_CFLAGS = @jsonc_CFLAGS@ jsonc_LIBS = @jsonc_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ libvirt_CFLAGS = @libvirt_CFLAGS@ libvirt_LIBS = @libvirt_LIBS@ libxml2_CFLAGS = @libxml2_CFLAGS@ @@ -577,6 +579,8 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +uuid_CFLAGS = @uuid_CFLAGS@ +uuid_LIBS = @uuid_LIBS@ # we don't maintain a ChangeLog, which makes us non-GNU -> foreign AUTOMAKE_OPTIONS = no-dist foreign @@ -687,7 +691,7 @@ LDADD = EXAMPLE_SOURCE_DIR = $(srcdir)/testsuite/systemtap.examples EXAMPLE_META_FILES = $(EXAMPLE_SOURCE_DIR)/*/*.meta TEST_COV_DIR = coverage -SUBDIRS = . java python stapdyn staprun stapbpf doc man po +SUBDIRS = . java python stapdyn staprun stapbpf doc man po httpd # NB: the gcov target above uses this to enumarate linked binaries' build directories DIST_SUBDIRS = testsuite $(SUBDIRS) EXTRA_DIST = m4/ChangeLog diff --git a/config.in b/config.in index c145d4167..a3351251b 100644 --- a/config.in +++ b/config.in @@ -49,6 +49,9 @@ /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT +/* Define to 1 to enable http web service support in systemtap. */ +#undef HAVE_HTTP_SUPPORT + /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV @@ -83,6 +86,9 @@ /* Define to 1 if libxml2 development libraries are installed */ #undef HAVE_LIBXML2 +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_BPF_H + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H diff --git a/configure b/configure index 7a9707392..afa387e03 100755 --- a/configure +++ b/configure @@ -629,6 +629,12 @@ LTLIBOBJS LIBOBJS subdirs STAP_PREFIX +HAVE_HTTP_SUPPORT_FALSE +HAVE_HTTP_SUPPORT_TRUE +uuid_LIBS +uuid_CFLAGS +libmicrohttpd_LIBS +libmicrohttpd_CFLAGS STAP_EXTRA_VERSION LOCALEDIR ENABLE_NLS @@ -909,6 +915,7 @@ with_python3_probes with_selinux with_java with_extra_version +enable_http ' ac_precious_vars='build_alias host_alias @@ -942,7 +949,11 @@ jsonc_LIBS ncurses_CFLAGS ncurses_LIBS selinux_CFLAGS -selinux_LIBS' +selinux_LIBS +libmicrohttpd_CFLAGS +libmicrohttpd_LIBS +uuid_CFLAGS +uuid_LIBS' ac_subdirs_all='testsuite' # Initialize some variables set by options. @@ -1594,6 +1605,8 @@ Optional Features: etc. found). --enable-virt enable building of stapvirt support (default on if libvirt etc. found). + --disable-http Disable building http web compilation service, even + if we could Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -1671,6 +1684,12 @@ Some influential environment variables: C compiler flags for selinux, overriding pkg-config selinux_LIBS linker flags for selinux, overriding pkg-config + libmicrohttpd_CFLAGS + C compiler flags for libmicrohttpd, overriding pkg-config + libmicrohttpd_LIBS + linker flags for libmicrohttpd, overriding pkg-config + uuid_CFLAGS C compiler flags for uuid, overriding pkg-config + uuid_LIBS linker flags for uuid, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -12603,6 +12622,181 @@ _ACEOF STAP_EXTRA_VERSION="$stap_extra_version" +# Check whether --enable-http was given. +if test "${enable_http+set}" = set; then : + enableval=$enable_http; +fi + +have_http_support=no +if test "x$enable_http" != "xno"; then : + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmicrohttpd" >&5 +$as_echo_n "checking for libmicrohttpd... " >&6; } + +if test -n "$libmicrohttpd_CFLAGS"; then + pkg_cv_libmicrohttpd_CFLAGS="$libmicrohttpd_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd > 0.9.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd > 0.9.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libmicrohttpd_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd > 0.9.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$libmicrohttpd_LIBS"; then + pkg_cv_libmicrohttpd_LIBS="$libmicrohttpd_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd > 0.9.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd > 0.9.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_libmicrohttpd_LIBS=`$PKG_CONFIG --libs "libmicrohttpd > 0.9.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmicrohttpd > 0.9.0" 2>&1` + else + libmicrohttpd_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmicrohttpd > 0.9.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$libmicrohttpd_PKG_ERRORS" >&5 + + have_libmicrohttpd=false +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libmicrohttpd=false +else + libmicrohttpd_CFLAGS=$pkg_cv_libmicrohttpd_CFLAGS + libmicrohttpd_LIBS=$pkg_cv_libmicrohttpd_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_libmicrohttpd=true +fi + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid" >&5 +$as_echo_n "checking for uuid... " >&6; } + +if test -n "$uuid_CFLAGS"; then + pkg_cv_uuid_CFLAGS="$uuid_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid > 2.17.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid > 2.17.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_uuid_CFLAGS=`$PKG_CONFIG --cflags "uuid > 2.17.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$uuid_LIBS"; then + pkg_cv_uuid_LIBS="$uuid_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid > 2.17.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "uuid > 2.17.0") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_uuid_LIBS=`$PKG_CONFIG --libs "uuid > 2.17.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + uuid_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "uuid > 2.17.0" 2>&1` + else + uuid_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "uuid > 2.17.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$uuid_PKG_ERRORS" >&5 + + have_libuuid=false +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libuuid=false +else + uuid_CFLAGS=$pkg_cv_uuid_CFLAGS + uuid_LIBS=$pkg_cv_uuid_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_libuuid=true +fi + + if test "x$have_libmicrohttpd" == "xtrue" -a "x$have_libuuid" == "xtrue"; then : + have_http_support=yes +fi +fi + +if test "x$have_http_support" = "xyes"; then : + +$as_echo "#define HAVE_HTTP_SUPPORT 1" >>confdefs.h + +else + if test "x$enable_http" = "xyes"; then : + as_fn_error $? "http service support requested but not found" "$LINENO" 5 +fi + +fi + if test "x$have_http_support" = "xyes"; then + HAVE_HTTP_SUPPORT_TRUE= + HAVE_HTTP_SUPPORT_FALSE='#' +else + HAVE_HTTP_SUPPORT_TRUE='#' + HAVE_HTTP_SUPPORT_FALSE= +fi + + stap_prefix=$prefix test "$stap_prefix" = NONE && stap_prefix=$ac_default_prefix @@ -12640,6 +12834,8 @@ ac_config_files="$ac_config_files staprun/Makefile" ac_config_files="$ac_config_files stapbpf/Makefile" +ac_config_files="$ac_config_files httpd/Makefile" + ac_config_files="$ac_config_files staprun/run-staprun" ac_config_files="$ac_config_files staprun/guest/stapshd" @@ -12901,6 +13097,10 @@ if test -z "${HAVE_JAVA_TRUE}" && test -z "${HAVE_JAVA_FALSE}"; then as_fn_error $? "conditional \"HAVE_JAVA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_HTTP_SUPPORT_TRUE}" && test -z "${HAVE_HTTP_SUPPORT_FALSE}"; then + as_fn_error $? "conditional \"HAVE_HTTP_SUPPORT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -13532,6 +13732,7 @@ do "python/Makefile") CONFIG_FILES="$CONFIG_FILES python/Makefile" ;; "staprun/Makefile") CONFIG_FILES="$CONFIG_FILES staprun/Makefile" ;; "stapbpf/Makefile") CONFIG_FILES="$CONFIG_FILES stapbpf/Makefile" ;; + "httpd/Makefile") CONFIG_FILES="$CONFIG_FILES httpd/Makefile" ;; "staprun/run-staprun") CONFIG_FILES="$CONFIG_FILES staprun/run-staprun" ;; "staprun/guest/stapshd") CONFIG_FILES="$CONFIG_FILES staprun/guest/stapshd" ;; "staprun/guest/stapsh-daemon") CONFIG_FILES="$CONFIG_FILES staprun/guest/stapsh-daemon" ;; diff --git a/configure.ac b/configure.ac index 329200da2..5bee3139e 100644 --- a/configure.ac +++ b/configure.ac @@ -905,6 +905,30 @@ AS_IF([test "x$with_extra_version" != "xno"], [ AC_DEFINE_UNQUOTED(STAP_EXTRA_VERSION, "$stap_extra_version", [extra stap version code]) AC_SUBST(STAP_EXTRA_VERSION, "$stap_extra_version") +dnl Handle the option to build httpd web compiliation service +AC_ARG_ENABLE([http], + AS_HELP_STRING([--disable-http], + [Disable building http web compilation service, even if we could])) +have_http_support=no +AS_IF([test "x$enable_http" != "xno"], + [dnl Do we have the microhttpd library? + PKG_CHECK_MODULES([libmicrohttpd], [libmicrohttpd > 0.9.0], [have_libmicrohttpd=true], [have_libmicrohttpd=false]) + + dnl Do we have the uuid library? + PKG_CHECK_MODULES([uuid], [uuid > 2.17.0], [have_libuuid=true], [have_libuuid=false]) + + dnl If we have both libraries, we could build the httpd web + dnl complilation service. + AS_IF([test "x$have_libmicrohttpd" == "xtrue" -a "x$have_libuuid" == "xtrue"], [have_http_support=yes])]) + +AS_IF([test "x$have_http_support" = "xyes"], + [AC_DEFINE([HAVE_HTTP_SUPPORT], [1], + [Define to 1 to enable http web service support in systemtap.])], + [AS_IF([test "x$enable_http" = "xyes"], + [AC_MSG_ERROR([http service support requested but not found])]) +]) +AM_CONDITIONAL([HAVE_HTTP_SUPPORT], [test "x$have_http_support" = "xyes"]) + dnl This is here mainly to make sure that configure --prefix=... changes dnl the config.h files so files depending on it are recompiled dnl prefix is passed through indirectly in the Makefile.am AM_CPPFLAGS. @@ -937,6 +961,7 @@ AC_CONFIG_FILES([java/stapbm], [chmod +x java/stapbm]) AC_CONFIG_FILES(python/Makefile) AC_CONFIG_FILES(staprun/Makefile) AC_CONFIG_FILES(stapbpf/Makefile) +AC_CONFIG_FILES(httpd/Makefile) AC_CONFIG_FILES([staprun/run-staprun], [chmod +x staprun/run-staprun]) AC_CONFIG_FILES([staprun/guest/stapshd], [chmod +x staprun/guest/stapshd]) AC_CONFIG_FILES([staprun/guest/stapsh-daemon], [chmod +x staprun/guest/stapsh-daemon]) diff --git a/httpd/Makefile.am b/httpd/Makefile.am new file mode 100644 index 000000000..92fd3dec0 --- /dev/null +++ b/httpd/Makefile.am @@ -0,0 +1,33 @@ +# Makefile.am --- automake input file for systemtap + +AUTOMAKE_OPTIONS = subdir-objects + +AM_CFLAGS = -Wall -Wextra -Werror -Wunused -W -Wformat=2 +AM_CXXFLAGS = -Wall -Wextra -Werror -Wunused -W -Wformat=2 +AM_CPPFLAGS = -D_GNU_SOURCE +AM_CPPFLAGS += -I$(srcdir)/../includes +AM_CPPFLAGS += -I$(builddir)/../includes/sys +AM_CPPFLAGS += -DBINDIR='"$(bindir)"' -DSYSCONFDIR='"$(sysconfdir)"' -DPKGDATADIR='"${pkgdatadir}"' -DPKGLIBDIR='"$(pkglibexecdir)"' -DLOCALEDIR='"$(localedir)"' + +AM_CFLAGS += @PIECFLAGS@ +AM_CXXFLAGS += @PIECXXFLAGS@ +AM_LDFLAGS = @PIELDFLAGS@ + +if HAVE_HTTP_SUPPORT +pkglibexec_PROGRAMS = stap-httpd + +stap_httpd_SOURCES = main.cxx server.cxx +stap_httpd_CFLAGS = $(AM_CFLAGS) +stap_httpd_CXXFLAGS = $(AM_CXXFLAGS) +stap_httpd_CPPFLAGS = $(AM_CPPFLAGS) +stap_httpd_LDADD = -lpthread -lmicrohttpd -luuid +stap_httpd_LDFLAGS = $(AM_LDFLAGS) +endif + +BUILT_SOURCES = +CLEANFILES = + +# Arrange for the top-level git_version.h to be regenerated at every "make". +BUILT_SOURCES += git_version.stamp +git_version.stamp ../git_version.h: + $(MAKE) -C .. $(notdir $@) diff --git a/httpd/Makefile.in b/httpd/Makefile.in new file mode 100644 index 000000000..bb5b8ea6b --- /dev/null +++ b/httpd/Makefile.in @@ -0,0 +1,715 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Makefile.am --- automake input file for systemtap + +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__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@HAVE_HTTP_SUPPORT_TRUE@pkglibexec_PROGRAMS = stap-httpd$(EXEEXT) +subdir = httpd +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \ + $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/pkg.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(pkglibexecdir)" +PROGRAMS = $(pkglibexec_PROGRAMS) +@HAVE_HTTP_SUPPORT_TRUE@am_stap_httpd_OBJECTS = \ +@HAVE_HTTP_SUPPORT_TRUE@ stap_httpd-main.$(OBJEXT) \ +@HAVE_HTTP_SUPPORT_TRUE@ stap_httpd-server.$(OBJEXT) +stap_httpd_OBJECTS = $(am_stap_httpd_OBJECTS) +stap_httpd_DEPENDENCIES = +stap_httpd_LINK = $(CXXLD) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) \ + $(stap_httpd_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +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 = +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(stap_httpd_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATE = @DATE@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DYNINST_CXXFLAGS = @DYNINST_CXXFLAGS@ +DYNINST_LDFLAGS = @DYNINST_LDFLAGS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_NLS = @ENABLE_NLS@ +EXEEXT = @EXEEXT@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +JAVADIR = @JAVADIR@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LN_S = @LN_S@ +LOCALEDIR = @LOCALEDIR@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PIECFLAGS = @PIECFLAGS@ +PIECXXFLAGS = @PIECXXFLAGS@ +PIELDFLAGS = @PIELDFLAGS@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +PYTHON3 = @PYTHON3@ +PYTHON3_CONFIG = @PYTHON3_CONFIG@ +PYTHON3_CPPFLAGS = @PYTHON3_CPPFLAGS@ +PYTHON3_EXEC_PREFIX = @PYTHON3_EXEC_PREFIX@ +PYTHON3_PLATFORM = @PYTHON3_PLATFORM@ +PYTHON3_PREFIX = @PYTHON3_PREFIX@ +PYTHON3_VERSION = @PYTHON3_VERSION@ +PYTHON_CONFIG = @PYTHON_CONFIG@ +PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_UNKNOWN = @PYTHON_UNKNOWN@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STAP_EXTRA_VERSION = @STAP_EXTRA_VERSION@ +STAP_PREFIX = @STAP_PREFIX@ +STRIP = @STRIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +avahi_CFLAGS = @avahi_CFLAGS@ +avahi_LIBS = @avahi_LIBS@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dracutbindir = @dracutbindir@ +dracutstap = @dracutstap@ +dvidir = @dvidir@ +elfutils_abs_srcdir = @elfutils_abs_srcdir@ +exec_prefix = @exec_prefix@ +have_dvips = @have_dvips@ +have_fop = @have_fop@ +have_jar = @have_jar@ +have_javac = @have_javac@ +have_latex = @have_latex@ +have_ps2pdf = @have_ps2pdf@ +have_xmlto = @have_xmlto@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +jsonc_CFLAGS = @jsonc_CFLAGS@ +jsonc_LIBS = @jsonc_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libmicrohttpd_CFLAGS = @libmicrohttpd_CFLAGS@ +libmicrohttpd_LIBS = @libmicrohttpd_LIBS@ +libvirt_CFLAGS = @libvirt_CFLAGS@ +libvirt_LIBS = @libvirt_LIBS@ +libxml2_CFLAGS = @libxml2_CFLAGS@ +libxml2_LIBS = @libxml2_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +ncurses_CFLAGS = @ncurses_CFLAGS@ +ncurses_LIBS = @ncurses_LIBS@ +nss_CFLAGS = @nss_CFLAGS@ +nss_LIBS = @nss_LIBS@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +preferred_python = @preferred_python@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +py3execdir = @py3execdir@ +pyexecdir = @pyexecdir@ +python3dir = @python3dir@ +pythondir = @pythondir@ +sbindir = @sbindir@ +selinux_CFLAGS = @selinux_CFLAGS@ +selinux_LIBS = @selinux_LIBS@ +sharedstatedir = @sharedstatedir@ +sqlite3_CFLAGS = @sqlite3_CFLAGS@ +sqlite3_LIBS = @sqlite3_LIBS@ +srcdir = @srcdir@ +stap_LIBS = @stap_LIBS@ +stapbpf_LIBS = @stapbpf_LIBS@ +staplog_CPPFLAGS = @staplog_CPPFLAGS@ +staprun_LIBS = @staprun_LIBS@ +subdirs = @subdirs@ +support_section_question = @support_section_question@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +uuid_CFLAGS = @uuid_CFLAGS@ +uuid_LIBS = @uuid_LIBS@ +AUTOMAKE_OPTIONS = subdir-objects +AM_CFLAGS = -Wall -Wextra -Werror -Wunused -W -Wformat=2 @PIECFLAGS@ +AM_CXXFLAGS = -Wall -Wextra -Werror -Wunused -W -Wformat=2 \ + @PIECXXFLAGS@ $(am__empty) +AM_CPPFLAGS = -D_GNU_SOURCE -I$(srcdir)/../includes \ + -I$(builddir)/../includes/sys -DBINDIR='"$(bindir)"' \ + -DSYSCONFDIR='"$(sysconfdir)"' -DPKGDATADIR='"${pkgdatadir}"' \ + -DPKGLIBDIR='"$(pkglibexecdir)"' -DLOCALEDIR='"$(localedir)"' +AM_LDFLAGS = @PIELDFLAGS@ +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_SOURCES = main.cxx server.cxx +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_CFLAGS = $(AM_CFLAGS) +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_CXXFLAGS = $(AM_CXXFLAGS) +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_CPPFLAGS = $(AM_CPPFLAGS) +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_LDADD = -lpthread -lmicrohttpd -luuid +@HAVE_HTTP_SUPPORT_TRUE@stap_httpd_LDFLAGS = $(AM_LDFLAGS) + +# Arrange for the top-level git_version.h to be regenerated at every "make". +BUILT_SOURCES = git_version.stamp +CLEANFILES = +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .cxx .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign httpd/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign httpd/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-pkglibexecPROGRAMS: $(pkglibexec_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkglibexecdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkglibexecdir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(pkglibexecdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(pkglibexecdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-pkglibexecPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(pkglibexec_PROGRAMS)'; test -n "$(pkglibexecdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(pkglibexecdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(pkglibexecdir)" && rm -f $$files + +clean-pkglibexecPROGRAMS: + -test -z "$(pkglibexec_PROGRAMS)" || rm -f $(pkglibexec_PROGRAMS) + +stap-httpd$(EXEEXT): $(stap_httpd_OBJECTS) $(stap_httpd_DEPENDENCIES) $(EXTRA_stap_httpd_DEPENDENCIES) + @rm -f stap-httpd$(EXEEXT) + $(AM_V_CXXLD)$(stap_httpd_LINK) $(stap_httpd_OBJECTS) $(stap_httpd_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap_httpd-main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap_httpd-server.Po@am__quote@ + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +stap_httpd-main.o: main.cxx +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -MT stap_httpd-main.o -MD -MP -MF $(DEPDIR)/stap_httpd-main.Tpo -c -o stap_httpd-main.o `test -f 'main.cxx' || echo '$(srcdir)/'`main.cxx +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap_httpd-main.Tpo $(DEPDIR)/stap_httpd-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cxx' object='stap_httpd-main.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -c -o stap_httpd-main.o `test -f 'main.cxx' || echo '$(srcdir)/'`main.cxx + +stap_httpd-main.obj: main.cxx +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -MT stap_httpd-main.obj -MD -MP -MF $(DEPDIR)/stap_httpd-main.Tpo -c -o stap_httpd-main.obj `if test -f 'main.cxx'; then $(CYGPATH_W) 'main.cxx'; else $(CYGPATH_W) '$(srcdir)/main.cxx'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap_httpd-main.Tpo $(DEPDIR)/stap_httpd-main.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='main.cxx' object='stap_httpd-main.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -c -o stap_httpd-main.obj `if test -f 'main.cxx'; then $(CYGPATH_W) 'main.cxx'; else $(CYGPATH_W) '$(srcdir)/main.cxx'; fi` + +stap_httpd-server.o: server.cxx +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -MT stap_httpd-server.o -MD -MP -MF $(DEPDIR)/stap_httpd-server.Tpo -c -o stap_httpd-server.o `test -f 'server.cxx' || echo '$(srcdir)/'`server.cxx +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap_httpd-server.Tpo $(DEPDIR)/stap_httpd-server.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='server.cxx' object='stap_httpd-server.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -c -o stap_httpd-server.o `test -f 'server.cxx' || echo '$(srcdir)/'`server.cxx + +stap_httpd-server.obj: server.cxx +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -MT stap_httpd-server.obj -MD -MP -MF $(DEPDIR)/stap_httpd-server.Tpo -c -o stap_httpd-server.obj `if test -f 'server.cxx'; then $(CYGPATH_W) 'server.cxx'; else $(CYGPATH_W) '$(srcdir)/server.cxx'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/stap_httpd-server.Tpo $(DEPDIR)/stap_httpd-server.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='server.cxx' object='stap_httpd-server.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_httpd_CPPFLAGS) $(CPPFLAGS) $(stap_httpd_CXXFLAGS) $(CXXFLAGS) -c -o stap_httpd-server.obj `if test -f 'server.cxx'; then $(CYGPATH_W) 'server.cxx'; else $(CYGPATH_W) '$(srcdir)/server.cxx'; fi` + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(pkglibexecdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-pkglibexecPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-pkglibexecPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pkglibexecPROGRAMS + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-pkglibexecPROGRAMS cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic distclean-tags \ + 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-pkglibexecPROGRAMS install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-pkglibexecPROGRAMS + +.PRECIOUS: Makefile + +git_version.stamp ../git_version.h: + $(MAKE) -C .. $(notdir $@) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/httpd/main.cxx b/httpd/main.cxx new file mode 100644 index 000000000..f2f181b5c --- /dev/null +++ b/httpd/main.cxx @@ -0,0 +1,37 @@ +// systemtap compile-server web api server +// Copyright (C) 2017 Red Hat Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + +#include "server.h" + +extern "C" { +#include +#if 0 +#include +#include +#endif +} +//using namespace std; + +#define PAGE "ErrorBad data" + +class request_handler build_collection("build collection"); +class request_handler build("individual build"); + +int +main(int /*argc*/, char *const /*argv*/[]) +{ + server httpd(1234); + + httpd.add_request_handler("/builds", build_collection); + httpd.add_request_handler("/builds/[0-9]+", build); + // FIXME: Should this be pthread_cond_wait()/pthread_cond_timedwait()? + while (1) { + sleep(1); + } + return 0; +} diff --git a/httpd/server.cxx b/httpd/server.cxx new file mode 100644 index 000000000..50932bf7c --- /dev/null +++ b/httpd/server.cxx @@ -0,0 +1,368 @@ +#include "server.h" +#include + +extern "C" +{ +#include +#include +#include +} + +using namespace std; + +static int +get_key_values(void *cls, enum MHD_ValueKind /*kind*/, + const char *key, const char *value) +{ + map *kv_map = static_cast *>(cls); + + (*kv_map)[key] = value ? value : ""; + return MHD_YES; +} + + +struct connection_info +{ + static int + postdataiterator_shim(void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size); + + int postdataiterator(enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size); + + MHD_PostProcessor *postprocessor; + map post_params; + + connection_info(struct MHD_Connection *connection) + { + postprocessor + = MHD_create_post_processor(connection, 1024, + &connection_info::postdataiterator_shim, + this); + } + + ~connection_info() + { + if (postprocessor) + { + MHD_destroy_post_processor(postprocessor); + postprocessor = NULL; + } + } +}; + +int +connection_info::postdataiterator_shim(void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, + uint64_t off, + size_t size) +{ + connection_info *con_info = static_cast(cls); + + if (!cls) + return MHD_NO; + return con_info->postdataiterator(kind, key, filename, content_type, + transfer_encoding, data, off, size); +} + +int +connection_info::postdataiterator(enum MHD_ValueKind kind, + const char *key, + const char */*filename*/, + const char */*content_type*/, + const char */*transfer_encoding*/, + const char *data, + uint64_t /*off*/, + size_t /*size*/) +{ + if (key) { + return get_key_values(&post_params, kind, key, data); + } + return MHD_YES; +} + +static response +get_404_response() +{ + response error404(404); + error404.content = "

Not found

"; + return error404; +} + +response +request_handler::GET(const request &) +{ + return get_404_response(); +} +response +request_handler::PUT(const request &) +{ + return get_404_response(); +} +response +request_handler::POST(const request &) +{ + return get_404_response(); +} +response +request_handler::DELETE(const request &) +{ + return get_404_response(); +} + +void +server::add_request_handler(regex &url_path, request_handler &handler) +{ + // Use a lock_guard to ensure the mutex gets released even if an + // exception is thrown. + lock_guard lock(srv_mutex); + request_handlers.push_back(make_tuple(url_path, &handler)); +} + +void +server::add_request_handler(const char *url_path, request_handler &handler) +{ + regex url_path_regex(url_path); + + add_request_handler(url_path_regex, handler); +} + +int +server::access_handler_shim(void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **con_cls) +{ + server *srv = static_cast(cls); + + if (!cls) + return MHD_NO; + return srv->access_handler(connection, url, method, version, + upload_data, upload_data_size, con_cls); +} + +enum class request_method +{ + UNKNOWN = 0, + GET, + POST, + PUT, + DELETE, +}; + + +int +server::access_handler(struct MHD_Connection *connection, + const char *url, + const char *method, + const char */*version*/, + const char *upload_data, + size_t *upload_data_size, + void **con_cls) +{ + string url_str = url; + + if (! *con_cls) + { + // Allocate connection info struct here. + connection_info *con_info = new connection_info(connection); + if (!con_info) { + // FIXME: should we queue a response here? + return MHD_NO; + } + *con_cls = con_info; + return MHD_YES; + } + + // Convert the method string to an value. + request_method rq_method; + if (strcmp(method, MHD_HTTP_METHOD_GET) == 0) { + rq_method = request_method::GET; + } + else if (strcmp(method, MHD_HTTP_METHOD_POST) == 0) { + rq_method = request_method::POST; + } + else if (strcmp(method, MHD_HTTP_METHOD_PUT) == 0) { + rq_method = request_method::PUT; + } + else if (strcmp(method, MHD_HTTP_METHOD_DELETE) == 0) { + rq_method = request_method::DELETE; + } + else { + // We got a method we don't support. Fail. + return queue_response(get_404_response(), connection); + } + + request_handler *rh = NULL; + clog << "Looking for a matching request handler..." << endl; + { + // Use a lock_guard to ensure the mutex gets released even if an + // exception is thrown. + lock_guard lock(srv_mutex); + + // Search the request handlers for a matching entry. + for (auto it = request_handlers.begin(); + it != request_handlers.end(); it++) { + regex url_regex = get(*it); + smatch url_match; + if (regex_match(url_str, url_match, url_regex)) { + rh = get(*it); + clog << "Found a match with '" << rh->name << "'" << endl; + break; + } + } + } + + // If we didn't find a request handler, return an error. + if (rh == NULL) + return queue_response(get_404_response(), connection); + + // Prepare to call the appropriate request handler method by + // gathering up all the request info. + struct request rq_info; + enum MHD_ValueKind kind = ((rq_method == request_method::POST) + ? MHD_POSTDATA_KIND + : MHD_GET_ARGUMENT_KIND); + MHD_get_connection_values(connection, kind, &get_key_values, + &rq_info.params); + + // POST data might or might not have been handled by + // MHD_get_connection_values(). We have to post-process the POST + // data. + connection_info *con_info = static_cast(*con_cls); + if (*upload_data_size != 0) { + if (MHD_post_process(con_info->postprocessor, upload_data, + *upload_data_size) == MHD_NO) { + // FIXME: What should we do here? + return MHD_NO; + } + // Let MHD know we processed everything. + *upload_data_size = 0; + return MHD_YES; + } + else if (!con_info->post_params.empty()) { + // Copy all the POST parameters into the request parameters. + rq_info.params.insert(con_info->post_params.begin(), + con_info->post_params.end()); + con_info->post_params.clear(); + } + + // Now that all the request info has been gathered, call the right + // method and pass it the request info. + switch (rq_method) { + case request_method::GET: + return queue_response(rh->GET(rq_info), connection); + case request_method::POST: + return queue_response(rh->POST(rq_info), connection); + case request_method::PUT: + return queue_response(rh->PUT(rq_info), connection); + case request_method::DELETE: + return queue_response(rh->DELETE(rq_info), connection); + default: + return queue_response(get_404_response(), connection); + } +} + +int +server::queue_response(const response &response, MHD_Connection *connection) +{ + struct MHD_Response *mhd_response; + + mhd_response = MHD_create_response_from_buffer(response.content.length(), + (void *) response.content.c_str(), + MHD_RESPMEM_MUST_COPY); + if (mhd_response == NULL) { + return MHD_NO; + } + +#if 0 + for (const auto &header : response.headers) { + MHD_add_response_header(mhd_response, header.first.c_str(), + header.second.c_str()); + } +#endif + MHD_add_response_header(mhd_response, MHD_HTTP_HEADER_CONTENT_TYPE, response.content_type.c_str()); + +// MHD_add_response_header(mhd_response, MHD_HTTP_HEADER_SERVER, server_identifier_.c_str()); + int ret = MHD_queue_response(connection, response.status_code, + mhd_response); + MHD_destroy_response (mhd_response); + return ret; +} + +void +server::start() +{ + dmn_ipv4 = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY +#ifdef MHD_USE_EPOLL + | MHD_USE_EPOLL +#ifdef MHD_USE_EPOLL_TURBO + | MHD_USE_EPOLL_TURBO +#endif +#else +#ifdef MHD_USE_POLL + | MHD_USE_POLL +#endif +#endif + | MHD_USE_DEBUG, + port, + NULL, NULL, // default accept policy + &server::access_handler_shim, this, + MHD_OPTION_THREAD_POOL_SIZE, 4, + MHD_OPTION_NOTIFY_COMPLETED, + &server::request_completed_handler_shim, this, + MHD_OPTION_END); + + if (dmn_ipv4 == NULL) { + string msg = "Error starting microhttpd daemon on port " + to_string(port); + throw runtime_error(msg); + return; + } +} + +void +server::request_completed_handler_shim(void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe) +{ + server *srv = static_cast(cls); + + if (!cls) + return; + return srv->request_completed_handler(connection, con_cls, toe); +} + +void +server::request_completed_handler(struct MHD_Connection */*connection*/, + void **con_cls, + enum MHD_RequestTerminationCode /*toe*/) +{ + if (*con_cls) { + struct connection_info *con_info = (struct connection_info *)*con_cls; + delete con_info; + *con_cls = NULL; + } +} diff --git a/httpd/server.h b/httpd/server.h new file mode 100644 index 000000000..2a977ab4b --- /dev/null +++ b/httpd/server.h @@ -0,0 +1,114 @@ +#ifndef __SERVER_H__ +#define __SERVER_H__ + +#include +#include +#include +#include +#include +#include + +extern "C" +{ +#include +} + +using namespace std; + +struct response +{ + unsigned int status_code; + string content; + string content_type; + + response(const unsigned int code, + const string &type = "text/html; charset=UTF-8") : + status_code(code), content_type(type) + { + } +}; + +struct request +{ +#if 0 + endpoint_matches matches; +#endif + map params; +#if 0 + request_headers headers; + std::string body; +#endif +}; + +struct request_handler +{ + string name; + virtual response GET(const request &req); + virtual response PUT(const request &req); + virtual response POST(const request &req); + virtual response DELETE(const request &req); + + request_handler(string n) : name(n) {} +}; + +class server +{ +public: + void start(); + + server(uint16_t port) : port(port), dmn_ipv4(NULL) + { + start(); + } + + ~server() + { + } + +// void initialize(); +// void stop(); +// void wait(); + + void add_request_handler(regex &url_path, request_handler &handler); + void add_request_handler(const char *url_path, request_handler &handler); + +private: + mutex srv_mutex; + uint16_t port; + struct MHD_Daemon *dmn_ipv4; + // FIXME: IPv6 support needed + + // FIXME: should this be a map? + vector> request_handlers; + + static int access_handler_shim(void *cls, + struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **con_cls); + + int access_handler(struct MHD_Connection *connection, + const char *url, + const char *method, + const char *version, + const char *upload_data, + size_t *upload_data_size, + void **con_cls); + + static void + request_completed_handler_shim(void *cls, + struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe); + + void request_completed_handler(struct MHD_Connection *connection, + void **con_cls, + enum MHD_RequestTerminationCode toe); + + int queue_response(const response &response, MHD_Connection *connection); +}; + +#endif /* __SERVER_H__ */ -- 2.43.5