summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
committerIgor Pashev <pashev.igor@gmail.com>2014-10-26 12:33:50 +0400
commit47e6e7c84f008a53061e661f31ae96629bc694ef (patch)
tree648a07f3b5b9d67ce19b0fd72e8caa1175c98f1a /src/include
downloadpcp-debian.tar.gz
Debian 3.9.10debian/3.9.10debian
Diffstat (limited to 'src/include')
-rw-r--r--src/include/GNUmakefile51
-rw-r--r--src/include/builddefs.in706
-rw-r--r--src/include/buildrules192
-rw-r--r--src/include/pcp.conf.in206
-rw-r--r--src/include/pcp.env95
-rw-r--r--src/include/pcp.mingw75
-rw-r--r--src/include/pcp/GNUmakefile42
-rw-r--r--src/include/pcp/config.h.in685
-rw-r--r--src/include/pcp/config32.h23
-rw-r--r--src/include/pcp/config64.h23
-rw-r--r--src/include/pcp/configsz.h.in24
-rw-r--r--src/include/pcp/fault.h64
-rw-r--r--src/include/pcp/impl.h1488
-rw-r--r--src/include/pcp/import.h67
-rwxr-xr-xsrc/include/pcp/mk_pmdbg58
-rw-r--r--src/include/pcp/mmv_dev.h84
-rw-r--r--src/include/pcp/mmv_stats.h108
-rw-r--r--src/include/pcp/platform_defs.h.in13
-rw-r--r--src/include/pcp/pmafm.h47
-rw-r--r--src/include/pcp/pmapi.h884
-rw-r--r--src/include/pcp/pmda.h725
-rw-r--r--src/include/pcp/pmtime.h107
-rw-r--r--src/include/pcp/trace.h110
-rw-r--r--src/include/pcp/trace_dev.h95
24 files changed, 5972 insertions, 0 deletions
diff --git a/src/include/GNUmakefile b/src/include/GNUmakefile
new file mode 100644
index 0000000..a6c1ce8
--- /dev/null
+++ b/src/include/GNUmakefile
@@ -0,0 +1,51 @@
+#
+# Copyright (c) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+TOPDIR = ../..
+include $(TOPDIR)/src/include/builddefs
+-include ./GNUlocaldefs
+
+CONFFILES = builddefs pcp.conf
+LSRCFILES = builddefs.in buildrules pcp.conf.in pcp.env pcp.mingw
+
+LDIRT = builddefs.install
+
+SUBDIRS = pcp
+
+default :: default_pcp
+
+default_pcp : $(SUBDIRS) pcp.conf builddefs.install
+ $(SUBDIRS_MAKERULE)
+
+include $(BUILDRULES)
+
+install :: default_pcp install_pcp
+
+install_pcp : $(SUBDIRS) default_pcp
+ $(INSTALL) -m 644 pcp.conf $(PCP_ETC_DIR)/pcp.conf
+ifeq "$(TARGET_OS)" "mingw"
+ $(INSTALL) -m 644 pcp.mingw $(PCP_ETC_DIR)/pcp.env
+else
+ $(INSTALL) -m 644 pcp.env $(PCP_ETC_DIR)/pcp.env
+endif
+ $(INSTALL) -m 644 buildrules $(PCP_INC_DIR)/buildrules
+ $(INSTALL) -m 644 builddefs.install $(PCP_INC_DIR)/builddefs
+ $(SUBDIRS_MAKERULE)
+
+builddefs.install : builddefs
+ sed -e 's;^include .*pcp.conf;include $$(PCP_DIR)/etc/pcp.conf;' \
+ -e 's;^BUILDRULES.*=.*buildrules;BUILDRULES = $$\(PCP_INC_DIR\)/buildrules;' \
+ -e 's;^INSTALL_SH.*=.*install-sh;INSTALL_SH = $$\(PCP_BINADM_DIR\)/install-sh;' \
+ -e 's;^GENPMDA.*=.*genpmda;GENPMDA = $$\(PCP_BIN_DIR\)/genpmda;' \
+ < builddefs > builddefs.install
diff --git a/src/include/builddefs.in b/src/include/builddefs.in
new file mode 100644
index 0000000..337b265
--- /dev/null
+++ b/src/include/builddefs.in
@@ -0,0 +1,706 @@
+#
+# Copyright (c) 2012-2014 Red Hat.
+# Copyright (c) 2008 Aconex. All Rights Reserved.
+# Copyright (c) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+# Common gmake macros for building
+#
+# @configure_input@
+#
+ifndef _BUILDDEFS_INCLUDED_
+_BUILDDEFS_INCLUDED_ = 1
+
+ifndef _PCP_CONF_INCLUDED_
+_PCP_CONF_INCLUDED_ = 1
+include $(TOPDIR)/src/include/pcp.conf
+endif
+
+# General package information
+PACKAGE_VERSION ?= @PACKAGE_VERSION@
+PACKAGE_MAJOR ?= @PACKAGE_MAJOR@
+PACKAGE_MINOR ?= @PACKAGE_MINOR@
+PACKAGE_REVISION ?= @PACKAGE_REVISION@
+PACKAGE_BUILD ?= @PACKAGE_BUILD@
+PACKAGE_NAME ?= pcp
+PACKAGE_CONFIGURE ?= @PACKAGE_CONFIGURE@
+PACKAGE_DISTRIBUTION ?= @PACKAGE_DISTRIBUTION@
+SGI_CHROOT_BUILD ?= 0
+SGI_ISSP_BUILD ?= 0
+
+BUILDRULES = $(TOPDIR)/src/include/buildrules
+
+# LCFLAGS, LLDFLAGS, LLDLIBS, LDIRT may be specified in local makefiles.
+
+# turn on all warnings by default
+ifeq "@cc_is_gcc@" "yes"
+WARN_OFF = -Wall
+else
+WARN_OFF =
+endif
+
+LIBPCP_ABIDIR ?= src
+PCPLIB_LDFLAGS = -L$(TOPDIR)/src/libpcp/$(LIBPCP_ABIDIR) \
+ -L$(TOPDIR)/src/libpcp_pmda/$(LIBPCP_ABIDIR)
+# backward compatibility
+PCP_LIBS = $(PCPLIB_LDFLAGS)
+
+# platform-specific CFLAGS, LDLIBS, and shared library extension
+#
+# Note:
+# Need PCFLAGS setting here to match the CFLAGS settings in
+# ../../configure.ac (likewise for PLDFLAGS and LDFLAGS).
+#
+TARGET_OS = @target_os@
+PCFLAGS = @PCFLAGS@
+PLDFLAGS = @PLDFLAGS@
+ifneq (, $(filter linux kfreebsd gnu, $(TARGET_OS)))
+DSOSUFFIX = so
+endif
+ifeq "$(TARGET_OS)" "darwin"
+DSOSUFFIX = dylib
+CASE_INSENSITIVE_FS=1
+endif
+ifeq "$(TARGET_OS)" "mingw"
+DSOSUFFIX = dll
+EXECSUFFIX = .exe
+SHELLSUFFIX = .sh
+PLDLIBS = -lwsock32
+endif
+ifeq "$(TARGET_OS)" "solaris"
+PLDFLAGS += -fPIC
+PLDLIBS = -lnsl -lsocket -lresolv -ldl -lposix4
+DSOSUFFIX = so
+endif
+ifeq "$(TARGET_OS)" "aix"
+DSOSUFFIX = so
+# -qcpluscmt
+# allow C++-style // as comment preamble
+# -brtl
+# use run-time linker
+# -bnoipath
+# do not use path to DSOs from the build, use default search path
+# rules
+# (and does not accept -Wall as a valid option)
+PLDFLAGS += -brtl -bnoipath
+WARN_OFF =
+endif
+ifeq "$(TARGET_OS)" "freebsd"
+DSOSUFFIX = so
+endif
+ifeq "$(TARGET_OS)" "netbsd"
+DSOSUFFIX = so
+endif
+
+CFLAGS_ABI = @cflags_abi@
+CFLAGS_OPT = -O2 -g
+CFLAGS += $(PCFLAGS) $(LCFLAGS) $(WARN_OFF) $(CFLAGS_OPT) \
+ -DPCP_DEBUG -DPCP_VERSION=\"$(PCP_VERSION)\" \
+ -I$(TOPDIR)/src/include -I$(TOPDIR)/src/include/pcp
+
+PIECFLAGS = @PIECFLAGS@
+PIELDFLAGS = @PIELDFLAGS@
+INVISIBILITY = @INVISIBILITY@ # hide shared library symbols
+
+NSSCFLAGS = @NSSCFLAGS@
+NSPRCFLAGS = @NSPRCFLAGS@
+SASLCFLAGS = @SASLCFLAGS@
+AVAHICFLAGS = @avahi_CFLAGS@
+
+LDFLAGS += $(PLDFLAGS) $(WARN_OFF) $(PCP_LIBS) $(LLDFLAGS)
+
+SRCFILES = GNUmakefile $(HFILES) $(CFILES) $(CXXFILES) $(MFILES) \
+ $(LSRCFILES) $(LFILES) $(YFILES) $(PYFILES)
+
+LDLIBS = $(LLDLIBS) $(PLDLIBS)
+MAKEOPTS = --no-print-directory
+
+ifdef PROJECT
+QTDIRDIRT = build debug release .obj .ui .moc .qrc *.xcodeproj *.app
+QTDIRT = *.a *.o ui_* moc_* qrc_* Info.plist Makefile* object_script.*
+endif
+DEPDIRT = dep dep.bak
+MANDIRT = *.[1-9].gz *.[1-9].bz2 *.[1-9].lzma *.[1-9].xz *.[1-9].tmp
+LIBDIRT = $(LIBTARGET) $(STATICLIBTARGET)
+CDIRT = $(OBJECTS) $(CMDTARGET) $(CXXMDTARGET)
+DIRT = $(LDIRT) $(DEPDIRT) $(MANDIRT) $(QTDIRT) $(CDIRT) $(LIBDIRT)
+DIRDIRT = $(LDIRDIRT) $(QTDIRDIRT)
+
+OBJECTS = $(ASFILES:.s=.o) \
+ $(CFILES:.c=.o) \
+ $(CXXFILES:.cxx=.o) \
+ $(FFILES:.f=.o) \
+ $(LFILES:.l=.o) \
+ $(YFILES:%.y=%.tab.o)
+
+#NB: don't override $(MAKE); gnumake sets it well, propagating -j etc.
+#MAKE = @make@
+CC = @cc@
+CXX = @cxx@
+LD = @ld@
+AWK = @awk@
+SED = @sed@
+CPP = @cpp@
+LEX = @lex@
+YACC = @yacc@
+ECHO = @echo@
+LN_S = @LN_S@
+GREP = @grep@
+GIT = @GIT@
+PYTHON = @PYTHON@
+DTRACE = @DTRACE@
+QMAKE = @qmake@
+
+INSTALL_SH = $(TOPDIR)/install-sh
+INSTALL = $(INSTALL_SH) -o $(PCP_USER_INSTALL) -g $(PCP_GROUP_INSTALL)
+
+CCF = $(CC) $(CFLAGS)
+CXXF = $(CXX) $(CFLAGS) $(CXXFLAGS)
+# NB: don't use $(MAKEF), since that suppresses gnumake's subdir parallelization
+#MAKEF = $(MAKE) $(MAKEOPTS)
+LDF = $(LD) $(LDFLAGS)
+MAKEDEPEND = @makedepend@
+
+ifeq "$(TARGET_OS)" "freebsd"
+# gmake on FreeBSD has a strange default rule that passes insufficient
+# flags to cc/ld for the link step. This change prevents errors like
+# undefined reference to `__stack_chk_fail_local'
+#
+LDFLAGS += $(CFLAGS)
+endif
+
+ZIP = @gzip@
+BZIP2 = @bzip2@
+LZMA = @lzma@
+XZ = @xz@
+TAR = @tar@
+RPMPROG = @rpmprog@
+PACKAGE_MAKER = @package_maker@
+HDIUTIL = @hdiutil@
+MKINSTALLP = @mkinstallp@
+DLLTOOL = @dlltool@
+RPMBUILD= @rpmbuild@
+RPM = @rpm@
+POD2MAN = @pod2man@
+DPKG = @dpkg@
+MAKEPKG = @makepkg@
+GENPMDA = $(TOPDIR)/src/genpmda/genpmda
+PKGMK = @pkgmk@
+MD5SUM = @md5sum@
+XMLTO = @xmlto@
+DBLATEX = @dblatex@
+PUBLICAN = @publican@
+BOOK_TOOLCHAIN = @book_toolchain@
+
+HAVE_GZIPPED_MANPAGES = @have_gzipped_manpages@
+HAVE_BZIP2ED_MANPAGES = @have_bzip2ed_manpages@
+HAVE_LZMAED_MANPAGES = @have_lzmaed_manpages@
+HAVE_XZED_MANPAGES = @have_xzed_manpages@
+PCP_MAN_DIR = @pcp_man_dir@
+PCP_BOOKS_DIR = @pcp_books_dir@
+PCP_ICONS_DIR = @pcp_icons_dir@
+PCP_DESKTOP_DIR = @pcp_desktop_dir@
+
+NEED_OLD_TBL_HEADER = @need_old_tbl_header@
+RDYNAMIC_FLAG = @rdynamic_flag@
+QT_RELEASE = @qt_release@
+
+ENABLE_SHARED = @enable_shared@
+ENABLE_SECURE = @enable_secure@
+ENABLE_PROBES = @enable_probes@
+ENABLE_AVAHI = @enable_avahi@
+ENABLE_QT = @enable_qt@
+ENABLE_SYSTEMD = @enable_systemd@
+ENABLE_PAPI = @enable_papi@
+
+# additional libraries needed for particular functions
+LIB_FOR_BASENAME = @lib_for_basename@
+LIB_FOR_DLOPEN = @lib_for_dlopen@
+LIB_FOR_REGEX = @lib_for_regex@
+LIB_FOR_MATH = @lib_for_math@
+LIB_FOR_READLINE = @lib_for_readline@
+LIB_FOR_CURSES = @lib_for_curses@
+LIB_FOR_PTHREADS = @lib_for_pthreads@
+LIB_FOR_RT = @lib_for_rt@
+LIB_FOR_NSS = @lib_for_nss@
+LIB_FOR_NSPR = @lib_for_nspr@
+LIB_FOR_SASL = @lib_for_sasl@
+LIB_FOR_SSL = @lib_for_ssl@
+LIB_FOR_AVAHI = @lib_for_avahi@
+LIB_FOR_ATOMIC = @lib_for_atomic@
+
+HAVE_LIBMICROHTTPD = @HAVE_LIBMICROHTTPD@
+HAVE_RPMLIB = @HAVE_RPMLIB@
+
+SHELL = /bin/sh
+IMAGES_DIR = $(TOPDIR)/all-images
+DIST_DIR = $(TOPDIR)/dist
+
+# env vars to be set before you can run a PCP binary in the build
+# environment ... needed for tools like newhelp
+#
+# default, then special case for different platforms
+#
+RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf LD_LIBRARY_PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$LD_LIBRARY_PATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp
+ifeq "$(TARGET_OS)" "darwin"
+RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf DYLD_LIBRARY_PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$DYLD_LIBRARY_PATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp
+endif
+ifeq "$(TARGET_OS)" "aix"
+RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf LIBPATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$LIBPATH HOME=`pwd` PCP_ALT_CPP=$(TOPDIR)/src/pmcpp/pmcpp
+endif
+ifeq "$(TARGET_OS)" "mingw"
+RUN_IN_BUILD_ENV = PCP_CONF=$(TOPDIR)/src/include/pcp.conf PATH=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$$PATH USERPROFILE=`pwd` PCP_ALT_CPP=`pwd`/$(TOPDIR)/src/pmcpp/pmcpp
+endif
+
+SUBDIRS_MAKERULE = \
+ +for d in `echo $^ `; do \
+ if test -d "$$d" -a -f "$$d/GNUmakefile"; then \
+ $(ECHO) === $$d ===; \
+ $(MAKE) $(MAKEOPTS) -C $$d $@ || exit $$?; \
+ fi; \
+ done
+
+# prepare symbols file for the GNU toolchain (linker) for DSO PMDAs
+VERSION_SCRIPT_MAKERULE = \
+ @rm -f $@; \
+ echo "{" >$@; \
+ echo " global: $(PMDAINIT);" >>$@; \
+ echo " local: *;" >>$@; \
+ echo "};" >>$@; \
+
+# prepare domain.h used during the PMDA build process for each PMDA
+DOMAIN_MAKERULE = \
+ @rm -f $@; \
+ echo "/*" >$@; \
+ echo " * built from $<" >>$@; \
+ echo " */" >>$@; \
+ $(AWK) <$< '\
+ $$1=="\#define" && $$2 == "$(DOMAIN)" {\
+ print "\#define $(DOMAIN) " $$3 >>"$@"; found++ \
+ }\
+ END {\
+ if (found == 0) { \
+ print "Botch: no define for domain $(DOMAIN) in $<"; \
+ system("rm '$@'"); \
+ exit(1) \
+ }\
+ if (found > 1) { \
+ print "Botch: multiple defines for domain $(DOMAIN) in $<";\
+ print "... see $@ for details"; \
+ system("rm '$@'"); \
+ exit(1) \
+ }\
+ exit(0) \
+ }' || ( rm -f $@ && false )
+
+DOMAIN_PERLRULE = \
+ @export perldomain=`sed -n \
+ -e '/PCP::PMDA->new/s/[^0-9]*$$//' \
+ -e '/PCP::PMDA->new/s/^[^0-9]*//p' pmda$(IAM).pl`; \
+ $(AWK) <$< '\
+ BEGIN {\
+ domain = toupper("$(IAM)") \
+ }\
+ $$1=="\#define" && $$2 == domain { \
+ pmd=$$3; found++ \
+ }\
+ END {\
+ if (found == 0) {\
+ print "Botch: no define for domain " domain " in $<"; \
+ exit(1) \
+ }\
+ if (found > 1) {\
+ print "Botch: multiple defines of domain " domain " in $<";\
+ exit(1) \
+ }\
+ if (pmd != "'"$$perldomain"'") {\
+ print "Botch: domain number in ../../pmns/stdpmid (" pmd ") does not match domain number in Perl source ("'"$$perldomain"'")"; \
+ exit(1) \
+ }\
+ exit(0) \
+ }'
+
+DOMAIN_PYTHONRULE = \
+ @export pythondomain=`sed -n \
+ -e '/PMDA(/s/[^0-9]*$$//' \
+ -e '/PMDA(/s/^[^0-9]*//p' $(PYSCRIPT)`; \
+ $(AWK) <$< '\
+ BEGIN {\
+ domain = toupper("$(IAM)") \
+ }\
+ $$1=="\#define" && $$2 == domain { \
+ pmd=$$3; found++ \
+ }\
+ END {\
+ if (found == 0) {\
+ print "Botch: no define for domain " domain " in $<"; \
+ exit(1) \
+ }\
+ if (found > 1) {\
+ print "Botch: multiple defines of domain " domain " in $<";\
+ exit(1) \
+ }\
+ if (pmd != "'"$$pythondomain"'") {\
+ print "Botch: domain number in ../../pmns/stdpmid (" pmd ") does not match domain number in Python source ("'"$$pythondomain"'")"; \
+ exit(1) \
+ }\
+ exit(0) \
+ }'
+
+POD_OPTIONS = --section=$(MAN_SECTION) --release=$(PCP_VERSION) \
+ --center="Performance Co-Pilot" --date="Performance Co-Pilot"
+POD_MAKERULE = $(POD2MAN) $(POD_OPTIONS) $^ $@
+
+ifeq "$(TARGET_OS)" "mingw"
+INSTALL_MAN =
+else
+INSTALL_MAN = \
+ test -z "$$MAN_PAGES" && MAN_PAGES="$(MAN_PAGES)"; \
+ for d in `echo $$MAN_PAGES`; do \
+ first=true; \
+ base=`echo $$d | sed -e 's/\.[0-9]//g'`; \
+ $(AWK) <$$d ' \
+BEGIN { state=0; print "'"$$base"'" } \
+$$1==".ds" { ds["\\\\\\*\\("$$2] = $$3 } \
+$$1==".SH" && $$2=="NAME" { state=1; next } \
+$$1==".SH" && state==1 { exit } \
+/^\./ { next } \
+state==1 { for (i=1;i<=NF;i++) { \
+ if ($$i=="\\-" || $$i=="-") exit; \
+ gsub ("\\\\f3", "", $$i); gsub ("\\\\f1.*", "", $$i); \
+ for ( d in ds ) sub (d, ds[d], $$i); \
+ print $$i \
+ } \
+ }' \
+ | LC_COLLATE=POSIX $(PCP_SORT_PROG) -u \
+ | while read m; do \
+ [ -z "$$m" -o "$$m" = "\\" ] && continue; \
+ t=$(MAN_DEST)/$$m.$(MAN_SECTION); \
+ if $$first; then \
+ _tfx= ;\
+ if $(NEED_OLD_TBL_HEADER) ; then \
+ $(SED) -e "1s/^'\\\\\"! tbl.*/'\\\\\" t/" $$d > $$d.tmp; _tfx=.tmp; \
+ fi; \
+ if $(HAVE_GZIPPED_MANPAGES) ; then \
+ $(ZIP) -c $$d$$_tfx > $$d.gz; _tfx=.gz; _sfx=.gz; \
+ fi; \
+ if $(HAVE_BZIP2ED_MANPAGES) ; then \
+ $(BZIP2) -c $$d$$_tfx > $$d.bz2; _tfx=.bz2; _sfx=.bz2; \
+ fi; \
+ if $(HAVE_LZMAED_MANPAGES) ; then \
+ $(LZMA) -c $$d$$_tfx > $$d.lzma; _tfx=.lzma; _sfx=.lzma; \
+ fi; \
+ if $(HAVE_XZED_MANPAGES) ; then \
+ $(XZ) -c $$d$$_tfx > $$d.xz; _tfx=.xz; _sfx=.xz; \
+ fi; \
+ u=$$m.$(MAN_SECTION)$$_sfx; \
+ echo $(INSTALL) -m 644 $${d}$$_tfx $${t}$$_sfx; \
+ $(INSTALL) -m 644 $${d}$$_tfx $${t}$$_sfx; \
+ else \
+ if test ! -z $(CASE_INSENSITIVE_FS) -a $(CASE_INSENSITIVE_FS); then \
+ if test "`echo $$u | tr 'a-z' 'A-Z'`" != "`basename $${t}$$_sfx | tr 'a-z' 'A-Z'`"; then \
+ echo $(INSTALL) -S $$u $${t}$$_sfx; \
+ $(INSTALL) -S $$u $${t}$$_sfx; \
+ fi \
+ else \
+ echo $(INSTALL) -S $$u $${t}$$_sfx; \
+ $(INSTALL) -S $$u $${t}$$_sfx; \
+ fi \
+ fi; \
+ first=false; \
+ done; \
+ done
+endif
+
+PERL_INSTALL_BASE = @perl_install_base@
+PERL_INSTALLDIRS = @perl_installdirs@
+
+# MakeMaker INSTALL_BASE needs to be unset for proper vendor_perl paths to be used for --prefix=/usr;
+ifeq "$(PERL_INSTALL_BASE)" "/usr"
+ifneq "$(TARGET_OS)" "darwin"
+MAKEMAKER_EXTRA_OPTIONS=
+else
+MAKEMAKER_EXTRA_OPTIONS=INSTALL_BASE=$(PERL_INSTALL_BASE) INSTALLBASE=$(PERL_INSTALL_BASE)
+endif
+else
+MAKEMAKER_EXTRA_OPTIONS=INSTALL_BASE=$(PERL_INSTALL_BASE) INSTALLBASE=$(PERL_INSTALL_BASE)
+endif
+
+PERL_MAKE_MAKEFILE = \
+ export PCP_TOPDIR=`cd $(TOPDIR) && pwd`; \
+ NSS_CFLAGS="$(NSS_CFLAGS)" NSPR_CFLAGS="$(NSPR_CFLAGS)" \
+ TARGET_OS="$(TARGET_OS)" CC="$(CC) $(CFLAGS_ABI)" perl Makefile.PL $(MAKEMAKER_EXTRA_OPTIONS) $(MAKEMAKER_OPTIONS)
+
+# Collect files from a Perl "make -f Makefile install" below
+# src/perl to build the PCP Perl packaging list, and also clean up
+# the installed files to remove unwanted files and make the DSO
+# executable
+#
+# Usage is $(call PERL_GET_FILELIST,listfile,base)
+# where listfile is something like $(TOPDIR)/perl-pcp-pmda.list and
+# base is the DSO basename like PMDA.
+#
+# We need different versions for the different installation and
+# packaging regimes.
+#
+ifeq "$(PACKAGE_DISTRIBUTION)" "debian"
+# For Debian packaging, this is not needed
+PERL_GET_FILELIST =
+else
+ifeq "$(PACKAGE_DISTRIBUTION)" "gentoo"
+# Gentoo cannot rely on the .packlist files from the install, so create
+# a temporary pack.list file
+PERL_GET_FILELIST = \
+ $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT \
+ | tee pack.list; \
+ sed -n -e '/\.bs$$/d' -e 's/\.[0-9]pm$$/&.gz/' -e "s@^Installing $$DIST_ROOT@@p" <pack.list >$(1) || exit 1; \
+ if [ -s $(1) ]; then rm -f pack.list; \
+ else echo "Arrgh ... no files to include in package via $(1), see pack.list"; exit 1; \
+ fi; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name perllocal.pod -exec rm -f '{}' ';' ; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name \*.bs -exec rm -f '{}' ';' ; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name $(2).so -exec chmod 755 '{}' ';'
+else
+ifeq "$(PACKAGE_DISTRIBUTION)" "freebsd"
+# FreeBSD Perl packaging is a broken mystery at this point in time
+# 1. there is no .packlist files being created
+# 2. $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT does not work
+# so disable the packaging pro tem
+PERL_GET_FILELIST =
+else
+# Everyone else ... includes the RPM-based packaging platforms
+ifeq "$(PACKAGE_DISTRIBUTION)" "mandriva"
+ man_suffix=lzma
+else
+ man_suffix=gz
+endif
+PERL_GET_FILELIST = \
+ $(PERLMAKE) -f Makefile install DESTDIR=$$DIST_ROOT; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name .packlist -exec mv '{}' $(1) ';' ; \
+ if [ -s $(1) ] ; then \
+ _sfx=.gz; \
+ $(HAVE_BZIP2ED_MANPAGES) && _sfx=.bz2; \
+ $(HAVE_LZMAED_MANPAGES) && _sfx=.lzma; \
+ $(HAVE_XZED_MANPAGES) && _sfx=.xz; \
+ sed -n -e '/\.bs$$/d' -e 's/\.[0-9]pm$$/&'"$$_sfx/" -e "s@^$$DIST_ROOT@@p" $(1) >$(1).tmp; \
+ mv $(1).tmp $1; \
+ else echo "Arrgh ... no files to include in package via $(1)"; exit 1; \
+ fi; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name perllocal.pod -exec rm -f '{}' ';' ; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name \*.bs -exec rm -f '{}' ';' ; \
+ find $$DIST_ROOT/$(PERL_INSTALL_BASE) -name $(2).so -exec chmod 755 '{}' ';'
+endif
+endif
+endif
+
+# Create perl manifest files explicitly for some distributions
+ifeq "$(shell [ '$(PACKAGE_DISTRIBUTION)' = cocoa \
+ -o '$(PACKAGE_DISTRIBUTION)' = macosx \
+ -o '$(PACKAGE_DISTRIBUTION)' = gentoo \
+ -o '$(PACKAGE_DISTRIBUTION)' = solaris \
+ -o '$(PACKAGE_DISTRIBUTION)' = freebsd \
+ ] && echo 1)" "1"
+# Gather installed Perl files before packaging
+PERL_INSTALL = \
+ if [ -n "$(DIST_MANIFEST)" ]; then \
+ if [ "`echo $(TOPDIR)/perl-pcp-*.list`" != "$(TOPDIR)/perl-pcp-*.list" ]; then \
+ cat $(TOPDIR)/perl-pcp-*.list | while read f; do \
+ bn=`basename $$f .gz`; \
+ dn=`dirname $$f`; \
+ $(INSTALL) -d $$dn || exit 1; \
+ src=`find */blib -name $$bn`; \
+ if [ -x $$src ] ; then mode=0755; else mode=0644; fi; \
+ $(INSTALL) -m $$mode $$src $$dn/$$bn || exit 1; \
+ done; \
+ fi; \
+ fi
+else
+PERL_INSTALL =
+endif
+
+SYSTEMD_CFLAGS=@SYSTEMD_CFLAGS@
+SYSTEMD_LIBS=@SYSTEMD_LIBS@
+PMDA_SYSTEMD=@PMDA_SYSTEMD@
+
+IB_LIBS=@IB_LIBS@
+PMDA_INFINIBAND=@PMDA_INFINIBAND@
+
+
+#
+# Python platform-specific installation quirks
+PYTHON_PREFIX=@python_prefix@
+SETUP_PY_BUILD_OPTIONS = --include-dirs=$(TOPDIR)/src/include
+SETUP_PY_BUILD_OPTIONS += --library-dirs=$(TOPDIR)/src/libpcp/src:$(TOPDIR)/src/libpcp_pmda/src:$(TOPDIR)/src/libpcp_gui/src:$(TOPDIR)/src/libpcp_import/src:$(TOPDIR)/src/libpcp_mmv/src
+SETUP_PY_INSTALL_OPTIONS = --skip-build
+SETUP_PY_INSTALL_OPTIONS += --root=$${DIST_ROOT-/}
+SETUP_PY_INSTALL_OPTIONS += --record=$(TOPDIR)/python-pcp.list
+ifeq "$(PYTHON_PREFIX)" "/usr"
+ifeq "$(PACKAGE_DISTRIBUTION)" "debian"
+SETUP_PY_INSTALL_OPTIONS += --install-layout=deb
+endif
+else
+SETUP_PY_INSTALL_OPTIONS += --prefix=$(PYTHON_PREFIX)
+endif
+# RPM byte-compiles and installs results in our DIST_ROOT, cater for this:
+ifeq "$(shell [ '$(TARGET_OS)' = linux -a '$(PACKAGE_DISTRIBUTION)' != gentoo \
+ ] && echo 1)" "1"
+# Linux and not Gentoo (which needs tarball packaging)
+PYTHON_INSTALL = \
+ $(AWK) '{print} /.pyc$$/ {sub(/.pyc$$/,".pyo"); print}' \
+ < $(TOPDIR)/python-pcp.list > $(TOPDIR)/python-pcp.list.rpm; \
+ cat $(TOPDIR)/python-pcp.list.rpm | while read f; do \
+ touch $${DIST_ROOT-/}$$f; \
+ done
+else
+ifeq "$(shell [ '$(PACKAGE_DISTRIBUTION)' = cocoa \
+ -o '$(PACKAGE_DISTRIBUTION)' = macosx \
+ -o '$(PACKAGE_DISTRIBUTION)' = gentoo \
+ -o '$(PACKAGE_DISTRIBUTION)' = solaris \
+ -o '$(PACKAGE_DISTRIBUTION)' = freebsd \
+ ] && echo 1)" "1"
+# Gather installed Python files before packaging
+# Lines in python-pcp.list are like this
+# /usr/lib/python2.7/site-packages/pcp.py
+# /usr/lib/python2.7/site-packages/pcp.pyc
+# /usr/lib/python2.7/site-packages/pmapi.so
+# /usr/lib/python2.7/site-packages/pcp-0.2-py2.7.egg-info
+#
+# Matching build artifacts are below src/python/build
+#
+PYTHON_INSTALL = \
+ if [ -n "$(DIST_MANIFEST)" ]; then \
+ cat $(TOPDIR)/python-pcp.list \
+ | while read f; do \
+ bn=`basename $$f`; \
+ dn=`dirname $$f`; \
+ $(INSTALL) -d $$dn || exit 1; \
+ src=`find $(TOPDIR)/src/python/build -name $$bn`; \
+ $(INSTALL) $$src $$f || exit 1; \
+ done; \
+ fi
+else
+PYTHON_INSTALL =
+endif
+endif
+
+# Qt magic for build/installs across all the supported platforms
+ifeq ($(PCP_PLATFORM),darwin)
+QTMAKE = $(QMAKE) -spec macx-g++ CONFIG+=$(QT_RELEASE) && make -f Makefile
+MACBUILD = build/$(QT_RELEASE)/$(COMMAND).app/Contents
+BINARY = $(MACBUILD)/MacOS/$(COMMAND)
+LNMAKE = test ! -f $(BINARY) -o -L $(COMMAND) || $(LN_S) $(BINARY) $(COMMAND)
+WINDOW = mac
+endif
+ifeq ($(PCP_PLATFORM),mingw)
+QTMAKE = $(QMAKE) CONFIG+=$(QT_RELEASE) && $(MAKE) -f Makefile
+BINARY = $(QT_RELEASE)/$(COMMAND)
+LNMAKE =
+WINDOW = win
+endif
+ifeq "$(findstring $(PCP_PLATFORM),darwin mingw)" ""
+QTMAKE = $(QMAKE) CONFIG+=$(QT_RELEASE) && $(MAKE) $(MAKEOPTS) -f Makefile
+BINARY = build/$(QT_RELEASE)/$(COMMAND)
+LNMAKE = test ! -f $(BINARY) -o -L $(COMMAND) || $(LN_S) $(BINARY) $(COMMAND)
+WINDOW = x11
+endif
+
+ifeq ($(PCP_PLATFORM),darwin)
+INSTALL_DIRECTORY_HIERARCHY=\
+ d=$(1); while [ "$$d" != "$(2)" -a "$$d" != "/" -a "$$d" != "." ] ; do \
+ echo $$d; d=`dirname $$d`; done | sort | while read id; do \
+ $(INSTALL) -m 755 -d $$id || exit 1; done
+
+INSTALL_QT_RESOURCES=\
+ printf "[Paths]\nPlugins=/Library/PCP/Plugins\n\n" > qt.conf; \
+ $(INSTALL) -m 644 qt.conf $(1)/qt.conf; \
+ rm qt.conf; \
+ find frameworks -type d -name qt_menu.nib | while read nib; do \
+ $(INSTALL) -m 755 -d $(1)/qt_menu.nib || exit 1; \
+ find $$nib -type f | while read nibs; do \
+ f=`basename $$nibs`; \
+ $(INSTALL) -m 644 $$nibs $(1)/qt_menu.nib/$$f || exit 1; \
+ done; \
+ done
+
+MAC_APPSUPPORT_DIR=/Library/PCP
+MAC_FRAMEWORKS_DIR=$(MAC_APPSUPPORT_DIR)/Frameworks
+
+# WARNING!
+# This rule modified the binary it was given, once modified the
+# binary cannot be used with this rule again.
+# If the binary is installed then it's important to call this
+# rule before calling install rule for the binary.
+INSTALL_QT_FRAMEWORKS=\
+ otool -L $(1) | awk '{if (NR != 1) {print $$1}}' |\
+ egrep 'Qt.*\.framework' | while read qt; do \
+ tdir=`dirname $$qt`; \
+ install_name_tool -change $$qt $(MAC_FRAMEWORKS_DIR)/$$qt $(1);\
+ $(call INSTALL_DIRECTORY_HIERARCHY,$(MAC_FRAMEWORKS_DIR)/$$tdir,/Library/PCP); \
+ mkdir -p frameworks/$$tdir || exit 1; \
+ fwqt="frameworks/$$qt"; \
+ cp /Library/Frameworks/$$qt frameworks/$$qt || exit 1; \
+ otool -L $$fwqt | awk '{if (NR != 1) {print $$1}}' |\
+ egrep 'Qt.*\.framework' | while read dep; do \
+ install_name_tool -change $$dep $(MAC_FRAMEWORKS_DIR)/$$dep $$fwqt;\
+ done; \
+ $(INSTALL) frameworks/$$qt $(MAC_FRAMEWORKS_DIR)/$$qt; \
+ if [ -d /Library/Frameworks/$$tdir/Resources ] ; then \
+ $(INSTALL) -d $(MAC_FRAMEWORKS_DIR)/$$tdir/Resources; \
+ (cd /Library/Frameworks/$$tdir; find Resources -type f) | \
+ while read rf; do \
+ rfpath="$$tdir/$$rf"; rfd=`dirname $$rfpath`; \
+ fwpath="frameworks/$$rfpath"; brfd=`basename $$rfd`; \
+ mkdir -p frameworks/$$rfd || exit 1; \
+ cp /Library/Frameworks/$$rfpath $$fwpath || exit 1; \
+ [ $$brfd != qt_menu.nib ] || continue; \
+ $(INSTALL) -d $(MAC_FRAMEWORKS_DIR)/$$rfd || exit 1; \
+ $(INSTALL) $$fwpath $(MAC_FRAMEWORKS_DIR)/$$rfpath;\
+ done \
+ fi; done
+endif
+
+
+# For targets that should always be rebuilt,
+# define a target that is never up-to-date.
+# Targets needing this should depend on $(_FORCE)
+_FORCE = __force_build
+
+PCP_USER = @pcp_user@
+PCP_GROUP = @pcp_group@
+PCP_USER_INSTALL = @pcp_user_install@
+PCP_GROUP_INSTALL = @pcp_group_install@
+
+PCPLIB = -lpcp
+ifneq "$(PCPLIB)" "$(LIB_FOR_BASENAME)"
+PCPLIB += $(LIB_FOR_BASENAME)
+endif
+ifeq "$(ENABLE_SHARED)" "no"
+PCPLIB += $(LIB_FOR_MATH) $(LIB_FOR_PTHREADS) $(LIB_FOR_DLOPEN) $(LIB_FOR_RT)
+endif
+PCP_GUILIB = -lpcp_gui $(PCPLIB)
+PCP_PMDALIB = -lpcp_pmda $(PCPLIB)
+PCP_TRACELIB = -lpcp_trace $(PCPLIB)
+
+ifdef PCP_ALTLIBS
+ifeq ($(PCP_LIB_DIR),$(PCP_LIB32_DIR))
+PCP_ALTLIBS =
+else
+ifneq "$(findstring $(MAKECMDGOALS),clean clobber)" ""
+PCP_ALTLIBS =
+endif
+endif
+endif
+
+BUILD_PMMGR=@BUILD_PMMGR@
+
+endif # _BUILDDEFS_INCLUDED_
diff --git a/src/include/buildrules b/src/include/buildrules
new file mode 100644
index 0000000..6471029
--- /dev/null
+++ b/src/include/buildrules
@@ -0,0 +1,192 @@
+#
+# Copyright (c) 2013-2014 Red Hat.
+# Copyright (c) 2007 Aconex. All Rights Reserved.
+# Copyright (c) 2000,2003,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# Common build rules for gmake
+#
+ifndef _BUILDRULES_INCLUDED_
+_BUILDRULES_INCLUDED_ = 1
+
+ifndef _BUILDDEFS_INCLUDED_
+include $(TOPDIR)/src/include/builddefs
+endif
+
+#
+# Standard targets
+#
+ifdef CMDTARGET
+$(CMDTARGET) : $(SUBDIRS) $(OBJECTS)
+ $(CCF) -o $(CMDTARGET) $(LDFLAGS) $(OBJECTS) $(LDLIBS)
+endif
+ifdef CXXMDTARGET
+$(CXXMDTARGET) : $(SUBDIRS) $(OBJECTS)
+ $(CXXF) -o $(CXXMDTARGET) $(LDFLAGS) $(OBJECTS) $(LDLIBS)
+endif
+
+# GNU make has a built-in recipe for .cc / .C / .cpp, but not for .cxx -> .o
+.cxx.o:
+ $(CXXF) $(CXXFLAGS) -c $< -o $@
+.SUFFIXES: .cxx
+
+ifdef LIBTARGET
+ifneq (, $(filter linux freebsd kfreebsd netbsd mingw gnu, $(TARGET_OS)))
+_SHAREDOPTS = -shared -Wl,-soname,$(LIBTARGET)
+endif
+ifeq ($(TARGET_OS), solaris)
+_SHAREDOPTS = -shared -fpic
+endif
+ifeq ($(TARGET_OS), darwin)
+# libtool doesnt understand -dynamiclib so we need both
+_SHAREDOPTS = -fPIC -dynamic -dynamiclib -flat_namespace -undefined suppress -headerpad_max_install_names -arch i386
+ifeq ($(PACKAGE_DISTRIBUTION), cocoa)
+_SHAREDOPTS += -arch x86_64
+endif
+endif
+ifeq ($(TARGET_OS), aix)
+_SHAREDOPTS = -qmkshrobj
+endif
+
+ifdef VERSION_SCRIPT
+ifneq ($(INVISIBILITY),)
+ifeq ($(TARGET_OS), darwin)
+# Mac OS X ld(1) takes a different format for the symbols file
+# _SHAREDOPTS += -Wl,-exported_symbols_list $(VERSION_SCRIPT)
+else
+_SHAREDOPTS += -Wl,--version-script=$(VERSION_SCRIPT)
+endif
+endif
+endif
+
+$(LIBTARGET) : $(SUBDIRS) $(OBJECTS)
+ $(CC) $(LDFLAGS) $(_SHAREDOPTS) -o $(LIBTARGET) $(OBJECTS) $(LDLIBS) $(LIB_FOR_DLOPEN) $(LIB_FOR_BASENAME)
+endif
+
+ifdef STATICLIBTARGET
+$(STATICLIBTARGET) : $(SUBDIRS) $(OBJECTS)
+ifeq ($(TARGET_OS), darwin)
+ libtool -static -o $(STATICLIBTARGET) $?
+else
+ $(AR) cr $(STATICLIBTARGET) $?
+endif
+endif
+
+ifdef WINDOWLINKS
+windowlinks:
+ @for l in $(WINDOWLINKS) ; do \
+ if [ ! -L $$l -a ! -f $$l ] ; then \
+ $(LN_S) $(WINDOW)_$$l $$l ; \
+ fi \
+ done
+endif
+
+# Suffix rule to support transition for YFILES to OBJECTS
+%.tab.h : %.y
+ $(YACC) -d -b `basename $< .y` $<
+
+%.tab.c : %.y
+ $(YACC) -d -b `basename $< .y` $<
+
+# Dealing with quirks of the various packaging mechanisms
+%.py: %.python
+ $(LN_S) $< $@
+
+%.pl: %.perl
+ $(LN_S) $< $@
+
+# Suffix rule to support transition for XML to PDF (books)
+%.pdf: %.xml
+ifeq ($(BOOK_TOOLCHAIN),publican)
+ $(PUBLICAN) build --langs=en-US --formats=pdf
+endif
+ifeq ($(BOOK_TOOLCHAIN),xmlto)
+ $(XMLTO) --with-fop pdf $^
+endif
+ifeq ($(BOOK_TOOLCHAIN),dblatex)
+ $(DBLATEX) --type pdf $^
+endif
+
+ifeq ($(TARGET_OS), mingw)
+#
+# .exe rule for Windows
+#
+.SUFFIXES: .exe
+.o.exe:
+ $(CCF) -o $* $(LDFLAGS) $(OBJECTS) $(LDLIBS)
+endif
+
+clean clobber :: $(SUBDIRS) $(PRO_SUBDIRS) $(SNIA_SUBDIRS)
+ rm -rf $(DIRT)
+ @rm -fr $(DIRDIRT)
+ $(SUBDIRS_MAKERULE)
+
+realclean distclean: clean
+ rm -f $(TOPDIR)/src/include/builddefs \
+ $(TOPDIR)/src/include/pcp.conf \
+ $(TOPDIR)/src/include/pcp/config.h \
+ $(TOPDIR)/src/include/pcp/configsz.h \
+ $(TOPDIR)/src/include/pcp/platform_defs.h \
+ $(TOPDIR)/src/include/pcp/pmdbg.h
+ rm -f $(TOPDIR)/build/GNUlocaldefs
+ rm -f $(TOPDIR)/pcp.lsm
+
+#
+# Never blow away subdirs
+#
+ifdef SUBDIRS
+.PRECIOUS: $(SUBDIRS)
+endif
+
+endif
+
+$(_FORCE):
+
+# The depend target does not depend on any other targets (even though it
+# actually depends on CFILES and HFILES). This is because there are several
+# places where we generate header files (e.g. domain.h is generated for each
+# subdir below src/pmdas, and domain.h in turn depends on src/pmns/stdpmid,
+# which itself a generated file ...). As a result, you can't run make
+# depend after make clobber, because the generated files will be missing.
+#
+# So running makedepend is for development use when you change a header
+# somewhere and you need to be sure everything that depends on that header
+# will be remade properly.
+
+.PHONY : depend $(_FORCE)
+
+depend : $(SUBDIRS)
+ $(SUBDIRS_MAKERULE)
+ touch dep
+ $(MAKEDEPEND) -fdep -- $(CFLAGS) -- $(CFILES)
+
+#
+# include dep, but only if it exists
+-include dep
+
+# Support for building multiple versions of the same library
+ifneq ($(PCP_ALTLIBS),)
+$(PCP_ALTLIBS):
+ rm -rf $@
+ mkdir $@
+ cp GNUlocaldefs.$@ $@/GNUlocaldefs
+ $(MAKE) -C src SLDEST=../$@ SLSRC=../src libsrc_symlinks
+endif
+
+libsrc_symlinks:
+ test -n "$(SLDEST)" -a -d $(SLDEST)
+ for f in $(SRCFILES); do \
+ if [ -e $(SLDEST)/$$f -a ! -L $(SLDEST)/$$f ] ; then \
+ echo "$$f exists in $(SLDEST) and not a symlink"; exit 1; \
+ fi; \
+ rm -f $(SLDEST)/$$f; $(LN_S) $(SLSRC)/$$f $(SLDEST)/$$f || exit 1; \
+ done
diff --git a/src/include/pcp.conf.in b/src/include/pcp.conf.in
new file mode 100644
index 0000000..3d4feb4
--- /dev/null
+++ b/src/include/pcp.conf.in
@@ -0,0 +1,206 @@
+#
+# Copyright (c) 2013 Red Hat.
+# Copyright (c) 2000-2001,2003 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# This file defines the directories and paths used by PCP
+# and is installed as the file /etc/pcp.conf for use at run-time.
+#
+# Note: the syntax of this file must allow processing to generate
+# correct variable assignments for both sh and make,
+# hence there should be no spaces immediately before or after
+# the equals in each assignment, no quoting on the right of the
+# equals although the value may contain embedded spaces.
+#
+# Shell scripts should never source this file directly, rather they
+# should use this file indirectly by sourcing /etc/pcp.env, i.e.
+# . $PCP_DIR/etc/pcp.env
+# this will handle the quoting and white space issues and set all
+# "variables" beginning with PCP_ in this file into the environment.
+# The defaults may be over-ridden by setting $PCP_CONF in the environment
+# as the full path to an alternate version of this file.
+#
+# The "standard paths" reflect the directory structure that is used by
+# default on the platform on which this file is installed.
+#
+
+# directory for _this_ file ... useful in the build
+# Standard path: /etc
+PCP_ETC_DIR=@pcp_etc_dir@
+
+# directory for PCP configuration files
+# Standard path: /etc/pcp
+PCP_SYSCONF_DIR=@pcp_sysconf_dir@
+
+# directory for rc/startup scripts
+# Standard path: /etc/init.d
+PCP_RC_DIR=@pcp_rc_dir@
+
+# directory for sysconfig controls
+# Standard path: /etc/sysconf (Redhat-specific)
+# <empty> if no sysconfig support
+PCP_SYSCONFIG_DIR=@pcp_sysconfig_dir@
+
+# directory for public binaries
+# Standard path: /usr/bin
+PCP_BIN_DIR=@pcp_bin_dir@
+
+# directory for private PCP binaries (not run directly by users)
+# Standard path is platform dependent, but generally one of
+# /usr/libexec/pcp/bin or /usr/lib/pcp/bin or /usr/share/pcp/bin
+PCP_BINADM_DIR=@pcp_binadm_dir@
+
+# directory for runtime shared libraries, libpcp.so, etc.
+# Standard path: /usr/lib
+PCP_LIB_DIR=@pcp_lib_dir@
+PCP_LIB32_DIR=@pcp_lib32_dir@
+
+# directory for shared PCP files (shareable for diskless)
+# Standard path: /usr/share/pcp
+# Subdirectories: bin lib
+PCP_SHARE_DIR=@pcp_share_dir@
+
+# directory for headers
+# Standard path: /usr/include/pcp
+PCP_INC_DIR=@pcp_inc_dir@
+
+# parent directory of man pages
+# Standard path: /usr/man
+# Subdirectories: man1 man3 man5
+PCP_MAN_DIR=@pcp_man_dir@
+
+# directory for non-shared (i.e. system local) PCP files
+# Standard path: /var/lib/pcp
+# Subdirectories: config pmns (note see $PCP_PMDAS_DIR) for pmdas
+PCP_VAR_DIR=@pcp_var_dir@
+
+# path to pmcd config file
+# Standard path: $PCP_SYSCONF_DIR/pmcd/pmcd.conf
+PCP_PMCDCONF_PATH=@pcp_pmcdconf_path@
+
+# path to pmcd options file
+# Standard path: $PCP_SYSCONF_DIR/pmcd/pmcd.options
+PCP_PMCDOPTIONS_PATH=@pcp_pmcdoptions_path@
+
+# path to site-local pmcd startup script
+# Standard path: $PCP_SYSCONF_DIR/pmcd/rc.local
+PCP_PMCDRCLOCAL_PATH=@pcp_pmcdrclocal_path@
+
+# path to pmproxy options file
+# Standard path: $PCP_SYSCONF_DIR/pmproxy/pmproxy.options
+PCP_PMPROXYOPTIONS_PATH=@pcp_pmproxyoptions_path@
+
+# path to pmwebd options file
+# Standard path: $PCP_SYSCONF_DIR/pmwebd/pmwebd.options
+PCP_PMWEBDOPTIONS_PATH=@pcp_pmwebdoptions_path@
+
+# path to pmmgr options file
+# Standard path: $PCP_SYSCONF_DIR/pmmgr/pmmgr.options
+PCP_PMMGROPTIONS_PATH=@pcp_pmmgroptions_path@
+
+# path to pmie control file
+# Standard path: $PCP_SYSCONF_DIR/pmie/control
+PCP_PMIECONTROL_PATH=@pcp_pmiecontrol_path@
+
+# path to pmsnap control file
+# Standard path: $PCP_SYSCONF_DIR/pmsnap/control
+PCP_PMSNAPCONTROL_PATH=@pcp_pmsnapcontrol_path@
+
+# path to pmlogger control file
+# Standard path: $PCP_SYSCONF_DIR/pmlogger/control
+PCP_PMLOGGERCONTROL_PATH=@pcp_pmloggercontrol_path@
+
+# directory for PCP PMDAs
+# Standard path: /var/lib/pcp/pmdas
+# Subdirectories: one per PMDA
+PCP_PMDAS_DIR=@pcp_pmdas_dir@
+
+# directory for PCP pid files
+# Standard path: /var/run/pcp
+PCP_RUN_DIR=@pcp_run_dir@
+
+# directory for PCP logs
+# Standard path: /var/log/pcp
+# Subdirectories: pmcd pmlogger pmie
+PCP_LOG_DIR=@pcp_log_dir@
+
+# directory for PCP temp status files
+# Standard path: /var/lib/pcp/tmp
+# Subdirectories: pmie pmlogger
+PCP_TMP_DIR=@pcp_tmp_dir@
+
+# directory for PCP temp work files
+# Standard path: /var/tmp
+PCP_TMPFILE_DIR=@pcp_tmpfile_dir@
+
+# directory for PCP documentation
+# Standard path: /usr/share/doc/pcp
+PCP_DOC_DIR=@pcp_doc_dir@
+PCP_HTML_DIR=@pcp_html_dir@
+
+# directory for PCP demos and examples
+# Standard path: /usr/share/pcp/demos
+PCP_DEMOS_DIR=@pcp_demos_dir@
+
+# awk
+PCP_AWK_PROG="@awk@"
+
+# unix-like sort
+PCP_SORT_PROG=@sort@
+
+# tools needed to rebuild things on the target platform
+PCP_MAKE_PROG=@make@
+PCP_CC_PROG="@cc@ @cflags_abi@"
+
+# echo
+# for lines without newline, use
+# $PCP_ECHO_PROG $PCP_ECHO_N "string""$PCP_ECHO_C"
+PCP_ECHO_PROG=@echo@
+PCP_ECHO_N=@echo_n@
+PCP_ECHO_C=@echo_c@
+
+# write to the system log
+PCP_SYSLOG_PROG=@pcp_syslog_prog@
+
+# running process list
+PCP_PS_PROG=@pcp_ps_prog@
+PCP_PS_HAVE_BSD=@pcp_ps_have_bsd@
+PCP_PS_ALL_FLAGS=@pcp_ps_all_flags@
+
+# locate executables
+PCP_WHICH_PROG=@which@
+
+# host operating system
+PCP_PLATFORM=@target_os@
+PCP_PLATFORM_PATHS=@pcp_platform_paths@
+
+# PCP version
+PCP_VERSION=@PACKAGE_VERSION@
+
+# confirmation dialog
+PCP_XCONFIRM_PROG=@ac_xconfirm_prog@
+
+# mpi
+PCP_MPI_DIRS=@pcp_mpi_dirs@
+
+# default account for running daemons (preferably unprivileged)
+# Standard user: "pcp" and group: "pcp"
+PCP_USER=@pcp_user@
+PCP_GROUP=@pcp_group@
+
+# directory for SASL configuration files
+# Standard path: /etc/sasl2
+PCP_SASLCONF_DIR=@pcp_saslconf_dir@
+
+# directory for systemd unit files
+# Standard path: /usr/lib/systemd/systemd
+PCP_SYSTEMDUNIT_DIR=@pcp_systemdunit_dir@
diff --git a/src/include/pcp.env b/src/include/pcp.env
new file mode 100644
index 0000000..d0ccab2
--- /dev/null
+++ b/src/include/pcp.env
@@ -0,0 +1,95 @@
+#
+# Copyright (c) 2000,2003 Silicon Graphics, Inc. All Rights Reserved.
+# Copyright (c) 2010 Aconex. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# This file is sourced by PCP scripts to set the environment
+# variables defined in the file named $PCP_CONF (or /etc/pcp.conf
+# if $PCP_CONF is not defined). Any variable already defined in
+# the environment is not changed.
+#
+# Note: any variables NOT starting with PCP_ will be ignored.
+# This is a security issue so don't change it.
+# Note also, this (variant of this) file is not used on Windows.
+#
+if [ -z "$PCP_ENV_DONE" ]
+then
+ if [ -n "$PCP_CONF" ]
+ then
+ __CONF="$PCP_CONF"
+ elif [ -n "$PCP_DIR" ]
+ then
+ __CONF="$PCP_DIR/etc/pcp.conf"
+ else
+ __CONF=/etc/pcp.conf
+ fi
+ if [ ! -f "$__CONF" ]
+ then
+ echo "pcp.env: Fatal Error: \"$__CONF\" not found" >&2
+ exit 1
+ fi
+ eval `sed -e 's/"//g' $__CONF \
+ | awk -F= '
+/^PCP_/ && NF == 2 {
+ exports=exports" "$1
+ printf "%s=${%s:-\"%s\"}\n", $1, $1, $2
+} END {
+ print "export", exports
+}'`
+ export PCP_ENV_DONE=y
+fi
+
+# Always need to set $PATH ... sudo -E leaves $PCP_ENV_DONE set, but
+# clears/resets $PATH. Note that order is important: any paths with
+# PCP-specific binaries should end up ahead of more generic paths in
+# the final $PATH to avoid conflicts on names of non-pcp binaries.
+#
+for dir in ${PCP_BIN_DIR} ${PCP_BINADM_DIR} \
+ ${PCP_SHARE_DIR}/bin ${PCP_PLATFORM_PATHS}
+do
+ if [ -d $dir ]
+ then
+ if echo ":$PATH:" | grep ":$dir:" >/dev/null 2>&1
+ then
+ :
+ else
+ PATH="$dir:$PATH"
+ fi
+ fi
+done
+export PATH
+
+_get_pids_by_name()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _get_pids_by_name process-name" >&2
+ exit 1
+ fi
+
+ # Algorithm ... all ps(1) variants have a time of the form MM:SS
+ # or HH:MM:SS or HH:MM.SS before the psargs field, so we're using
+ # this as the search anchor.
+ #
+ # Matches with $1 (process-name) occur if the first psarg is $1
+ # or ends in /$1 ... the matching uses sed's regular expressions,
+ # so passing a regex into $1 will work.
+
+ $PCP_PS_PROG $PCP_PS_ALL_FLAGS \
+ | sed -n \
+ -e 's/$/ /' \
+ -e 's/[ ][ ]*/ /g' \
+ -e 's/^ //' \
+ -e 's/^[^ ]* //' \
+ -e "/[0-9][:\.][0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \
+ -e "/[0-9][:\.][0-9][0-9] *$1 /s/ .*//p"
+}
diff --git a/src/include/pcp.mingw b/src/include/pcp.mingw
new file mode 100644
index 0000000..871e16b
--- /dev/null
+++ b/src/include/pcp.mingw
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2000,2003 Silicon Graphics, Inc. All Rights Reserved.
+# Copyright (c) 2010 Aconex. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# This file is sourced by PCP scripts to set the environment
+# variables defined in the file named $PCP_CONF (or /etc/pcp.conf
+# if $PCP_CONF is not defined). Any variable already defined in
+# the environment is not changed.
+#
+# Note: any variables NOT starting with PCP_ will be ignored.
+# This is a security issue so don't change it.
+# Note also, this variant of pcp.env is *only* used on Windows.
+#
+if [ -z "$PCP_ENV_DONE" ]
+then
+ __CONF=${PCP_CONF-/etc/pcp.conf}
+ if [ ! -f "$__CONF" ]
+ then
+ echo "pcp.env: Fatal Error: \"$__CONF\" not found" >&2
+ exit 1
+ fi
+ export PCP_DIR=/c/MinGW/sys/1.0
+ export PCP_CONF=$PCP_DIR/etc/pcp.conf
+ eval export `PATH=/lib:$PATH $PCP_DIR/libexec/pcp/bin/pmconfig.exe -s`
+ export PATH="/sbin:/bin:/lib:/etc:${PCP_BIN_DIR}:${PCP_BINADM_DIR}:${PCP_SHARE_DIR}/bin:${PCP_SHARE_DIR}/lib:${PCP_PLATFORM_PATHS}"
+ export PCP_ENV_DONE=y
+fi
+
+mkaf() {
+ mkaf.sh $@
+}
+pmafm() {
+ pmafm.sh $@
+}
+pmsignal() {
+ pmsignal.sh $@
+}
+
+_get_pids_by_name()
+{
+ if [ $# -ne 1 ]
+ then
+ echo "Usage: _get_pids_by_name process-name" >&2
+ exit 1
+ fi
+
+ # Algorithm ... all ps(1) variants have a time of the form MM:SS
+ # or HH:MM:SS or HH:MM.SS before the psargs field, so we're using
+ # this as the search anchor.
+ #
+ # Matches with $1 (process-name) occur if the first psarg is $1
+ # or ends in /$1 ... the matching uses sed's regular expressions,
+ # so passing a regex into $1 will work.
+
+ $PCP_PS_PROG $PCP_PS_ALL_FLAGS \
+ | sed -n \
+ -e 's/$/ /' \
+ -e 's/[ ][ ]*/ /g' \
+ -e 's/^ //' \
+ -e 's/^[^ ]* //' \
+ -e "/[0-9][:\.][0-9][0-9] *[^ ]*\\$1\.exe /s/ .*//p" \
+ -e "/[0-9][:\.][0-9][0-9] *[^ ]*\/$1 /s/ .*//p" \
+ -e "/[0-9][:\.][0-9][0-9] *$1\.exe /s/ .*//p" \
+ -e "/[0-9][:\.][0-9][0-9] *$1 /s/ .*//p"
+}
diff --git a/src/include/pcp/GNUmakefile b/src/include/pcp/GNUmakefile
new file mode 100644
index 0000000..4aaf310
--- /dev/null
+++ b/src/include/pcp/GNUmakefile
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2013-2014 Red Hat.
+# Copyright (c) 2000,2004 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+
+TOPDIR = ../../..
+include $(TOPDIR)/src/include/builddefs
+-include ./GNUlocaldefs
+
+HFILES = pmapi.h impl.h pmda.h pmtime.h pmafm.h import.h \
+ trace.h trace_dev.h mmv_stats.h mmv_dev.h \
+ config32.h config64.h
+INFILES = config.h.in configsz.h.in platform_defs.h.in
+CONFFILES = config.h configsz.h platform_defs.h
+GENERATED_HFILES = pmdbg.h $(CONFFILES)
+
+LSRCFILES = mk_pmdbg fault.h $(INFILES)
+LDIRT = $(GENERATED_HFILES)
+
+default :: default_pcp
+
+default_pcp : $(HEADERS) $(GENERATED_HFILES)
+
+include $(BUILDRULES)
+
+install :: default_pcp install_pcp
+
+install_pcp : default_pcp
+ $(INSTALL) -m 644 $(HFILES) $(GENERATED_HFILES) $(PCP_INC_DIR)
+
+pmdbg.h : pmapi.h impl.h
+ ./mk_pmdbg
diff --git a/src/include/pcp/config.h.in b/src/include/pcp/config.h.in
new file mode 100644
index 0000000..ae1ccdd
--- /dev/null
+++ b/src/include/pcp/config.h.in
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 2003 Moser, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004,2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PCP_CONFIG_H
+#define _PCP_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <time.h>
+
+/*
+ * The type of timestamps in struct stat: either HAVE_STAT_TIMESPEC,
+ * HAVE_STAT_TIMESPEC_T, HAVE_STAT_TIMESTRUC or HAVE_STAT_TIME_T
+ */
+#undef HAVE_STAT_TIMESPEC_T
+#undef HAVE_STAT_TIMESTRUC
+#undef HAVE_STAT_TIMESPEC
+#undef HAVE_STAT_TIME_T
+
+/* HAVE_ST_MTIME if stat.st_mtime has a ``spec'' on the end */
+#undef HAVE_ST_MTIME_WITH_SPEC
+
+/* HAVE_ST_MTIME if stat.st_mtime has an ``e'' on the end */
+#undef HAVE_ST_MTIME_WITH_E
+
+/* if your compiler supports LL sufix on 64 bit int constants */
+#undef HAVE_CONST_LONGLONG
+
+/*
+ * HAVE_UNDERBAR_ENVIRON if extern char **_environ is defined
+ * (else extern char **environ will be used)
+ */
+#undef HAVE_UNDERBAR_ENVIRON
+
+/*
+ * If the pointer-to-function arguments to scandir()
+ * are (*scanfn)(const struct dirent *dep)
+ * Otherwise ``const'' will be omitted.
+ */
+#undef HAVE_CONST_DIRENT
+
+/*
+ * If the dirent structure contains a directory offset field.
+ */
+#undef HAVE_DIRENT_D_OFF
+
+/* Defined if printf %p -> 0x prefix for value */
+#undef HAVE_PRINTF_P_PFX
+#ifdef HAVE_PRINTF_P_PFX
+#define PRINTF_P_PFX ""
+#else
+#define PRINTF_P_PFX "0x"
+#endif
+
+/* Defined if bit fields are allocated left-to-right within a word */
+#undef HAVE_BITFIELDS_LTOR
+
+/* if compiler can cast __uint64_t to double */
+#undef HAVE_CAST_U64_DOUBLE
+
+/*
+ * long and pointer must be either 32 bit or 64 bit
+ *
+ * This is complicated by RPMs "multilib" feature, which requires there
+ * to be no differences between header files on 32 and 64 bit platforms.
+ */
+#undef HAVE_BITS_WORDSIZE_H
+#ifdef HAVE_BITS_WORDSIZE_H
+# include <bits/wordsize.h>
+# if __WORDSIZE == 32
+# include "config32.h"
+# elif __WORDSIZE == 64
+# include "config64.h"
+# else
+# error "Unknown word size"
+# endif
+#else
+# include "configsz.h"
+#endif
+
+/* Define if header file is available */
+#undef HAVE_FCNTL_H
+#undef HAVE_LIMITS_H
+#undef HAVE_MALLOC_H
+#undef HAVE_STRINGS_H
+#undef HAVE_SYSLOG_H
+#undef HAVE_UNISTD_H
+#undef HAVE_STDDEF_H
+#undef HAVE_SCHED_H
+#undef HAVE_DLFCN_H
+#undef HAVE_DL_H
+#undef HAVE_SYS_TIME_H
+#undef HAVE_SYS_TIMEB_H
+#undef HAVE_SYS_TIMES_H
+#undef HAVE_SYS_SYSINFO_H
+#undef HAVE_SYS_SYSTEMINFO_H
+#undef HAVE_SYS_RESOURCE_H
+#undef HAVE_SYS_PRCTL_H
+#undef HAVE_ENDIAN_H
+#undef HAVE_STANDARDS_H
+#undef HAVE_SYS_BYTEORDER_H
+#undef HAVE_PTHREAD_H
+#undef HAVE_LIBGEN_H
+#undef HAVE_SYS_PARAM_H
+#undef HAVE_SYS_MMAN_H
+#undef HAVE_SYS_UN_H
+#undef HAVE_STDINT_H
+#undef HAVE_VALUES_H
+#undef HAVE_IEEEFP_H
+#undef HAVE_MATH_H
+#undef HAVE_PWD_H
+#undef HAVE_GRP_H
+#undef HAVE_REGEX_H
+#undef HAVE_TERMIO_H
+#undef HAVE_TERMIOS_H
+#undef HAVE_SYS_TERMIOS_H
+#undef HAVE_SYS_IOCTL_H
+#undef HAVE_SYS_WAIT_H
+#undef HAVE_WINDOWS_H
+#undef HAVE_WINSOCK2_H
+#undef HAVE_WS2TCPIP_H
+#undef HAVE_EXECINFO_H
+#undef HAVE_IPTYPES_H
+#undef HAVE_NETDB_H
+#undef HAVE_SYS_SOCKET_H
+#undef HAVE_NETINET_IN_H
+#undef HAVE_NETINET_TCP_H
+#undef HAVE_ARPA_INET_H
+
+#undef HAVE_SYS_ENDIAN_H
+#undef HAVE_SYS_MACHINE_H
+#undef HAVE_MACHINE_ENDIAN_H
+
+#undef HAVE_AI_ADDRCONFIG
+
+#if defined(HAVE_MALLOC_H)
+#include <malloc.h>
+#endif
+#if defined(HAVE_STDDEF_H)
+#include <stddef.h>
+#endif
+#if defined(HAVE_SYSLOG_H)
+#include <syslog.h>
+#endif
+#if defined(HAVE_WINSOCK2_H)
+#include <winsock2.h>
+#endif
+#if defined(HAVE_WINDOWS_H)
+#include <windows.h>
+#endif
+#if defined(HAVE_WS2TCPIP_H)
+#include <ws2tcpip.h>
+#endif
+
+/* HAVE_NETWORK_BYTEORDER for big endian systems (not Intel) */
+#if defined(HAVE_ENDIAN_H)
+#include <endian.h>
+#elif defined(HAVE_SYS_ENDIAN_H)
+#include <sys/endian.h>
+#elif defined(HAVE_MACHINE_ENDIAN_H)
+#include <machine/endian.h>
+#endif
+#if defined(HAVE_ENDIAN_H) || defined(HAVE_SYS_ENDIAN_H) || defined(HAVE_MACHINE_ENDIAN_H)
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
+#define HAVE_NETWORK_BYTEORDER
+#endif
+#endif
+
+#if defined(HAVE_SYS_BYTEORDER_H)
+#include <sys/byteorder.h>
+#if defined(_BIG_ENDIAN)
+#define HAVE_NETWORK_BYTEORDER
+#endif
+#endif
+
+#if defined(HAVE_SYS_MACHINE_H)
+#include <sys/machine.h>
+#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
+#define HAVE_NETWORK_BYTEORDER
+#endif
+#endif
+
+/* define which libraries are available */
+#undef HAVE_SECURE_SOCKETS
+#undef HAVE_STATIC_PROBES
+#undef HAVE_SERVICE_DISCOVERY
+#undef HAVE_AVAHI
+#undef HAVE_LIBREGEX
+#undef HAVE_READLINE
+
+/* define which libc functions are available */
+#undef HAVE_WAIT3
+
+#undef HAVE_MKTIME
+#undef HAVE_CLOCK_GETTIME
+#undef HAVE_NANOSLEEP
+#undef HAVE_USLEEP
+#undef HAVE_UNSETENV
+
+#undef HAVE_SELECT
+#undef HAVE_SOCKET
+#undef HAVE_GETHOSTNAME
+#undef HAVE_GETPEERUCRED
+#undef HAVE_GETPEEREID
+
+#undef HAVE_UNAME
+#undef HAVE_SYSLOG
+#undef HAVE___CLONE
+#undef HAVE_PIPE2
+#undef HAVE_FCNTL
+
+#undef HAVE_PRCTL
+#undef HAVE_SETLINEBUF
+#undef HAVE_WAITPID
+#undef HAVE_ATEXIT
+#undef HAVE_KILL
+
+#undef HAVE_CHOWN
+#undef HAVE_GETCWD
+#undef HAVE_SCANDIR
+#undef HAVE_MKSTEMP
+
+#undef HAVE_GETUID
+#undef HAVE_GETGID
+#undef HAVE_GETGRENT
+#undef HAVE_GETGRENT_R
+#undef HAVE_GETGRNAM
+#undef HAVE_GETGRNAM_R
+#undef HAVE_GETGRGID
+#undef HAVE_GETGRGID_R
+#undef HAVE_GETPWENT
+#undef HAVE_GETPWENT_R
+#undef HAVE_GETPWNAM
+#undef HAVE_GETPWNAM_R
+#undef HAVE_GETPWUID
+#undef HAVE_GETPWUID_R
+
+#undef HAVE_BRK
+#undef HAVE_SBRK
+#undef HAVE_POSIX_MEMALIGN
+#undef HAVE_MEMALIGN
+#undef HAVE_VALLOC
+
+#undef HAVE_SIGNAL
+#undef HAVE_SIGHOLD
+#undef HAVE_SIGRELSE
+#undef HAVE_TCGETATTR
+#undef GWINSZ_IN_SYS_IOCTL
+
+#undef HAVE_REGEX
+#undef HAVE_REGCMP
+#undef HAVE_REGEXEC
+#undef HAVE_REGCOMP
+
+#undef HAVE_STRTOD
+#undef HAVE_STRTOL
+#undef HAVE_STRTOLL
+#undef HAVE_STRTOULL
+#undef HAVE_STRNDUP
+#undef HAVE_STRCHRNUL
+
+#undef HAVE_DLOPEN
+#undef HAVE_FPCLASSIFY
+#undef HAVE_ISNAN
+#undef HAVE_ISNANF
+#undef HAVE_FLOG10
+#undef HAVE_POW
+#undef HAVE_DIRNAME
+#undef HAVE_BASENAME
+#undef HAVE_SYSINFO
+#undef HAVE_TRACE_BACK_STACK
+#undef HAVE_BACKTRACE
+#undef HAVE_READDIR64
+
+/* if termio signals are supported */
+#ifdef HAVE_TERMIOS_H
+#ifdef HAVE_TCGETATTR
+#define HAVE_TERMIO_SIGNALS
+#endif
+#endif
+
+/* if the /proc pseudo filesystem exists */
+#undef HAVE_PROCFS
+
+/* Infiniband API version information */
+#undef HAVE_PORT_PERFORMANCE_QUERY_VIA
+#undef HAVE_PMA_QUERY_VIA
+
+#ifndef ULONGLONG_MAX
+#define ULONGLONG_MAX (__uint64_t)18446744073709551615ULL
+#endif
+
+#ifndef LONGLONG_MAX
+#define LONGLONG_MAX (__int64_t)9223372036854775807LL
+#endif
+
+/* some types only known by some compilers */
+#undef uint_t
+#undef __int32_t
+#undef __uint32_t
+#undef __int64_t
+#undef __uint64_t
+
+/* Check if __psint_t is set to something meaningful */
+#undef HAVE___PSINT_T
+#ifndef HAVE___PSINT_T
+#ifdef HAVE_32BIT_PTR
+typedef int __psint_t;
+#elif defined HAVE_64BIT_PTR
+#ifdef HAVE_64BIT_LONG
+typedef long __psint_t;
+#else
+/* This is a very strange architecture, which has 64 bit pointers but
+ * not 64 bit longs. So, I'd just punt here and assume long long is Ok */
+typedef long long __psint_t;
+#endif
+#else
+#error Unknown pointer size - not 32 and not 64
+#endif
+#endif
+
+/* Check if ptrdiff_t type is available */
+#undef HAVE_PTRDIFF_T
+#ifndef HAVE_PTRDIFF_T
+#define ptrdiff_t long
+#endif
+
+/*
+ * User and group accounts - POSIX uid_t/gid_t combo or Win32 SID
+ */
+#undef HAVE_UID_T
+#undef HAVE_GID_T
+#undef HAVE_SID
+#if defined(HAVE_UID_T) && defined(HAVE_GID_T)
+typedef uid_t __pmUserID;
+typedef gid_t __pmGroupID;
+#elif defined(HAVE_SID)
+typedef SID __pmUserID;
+typedef SID __pmGroupID;
+#else
+bozo! unclear how to represent users and groups for this platform
+#endif
+
+/*
+ * socklen_t is not always defined, so use __pmSockLen abstraction
+ */
+#undef HAVE_SOCKLEN_T
+#ifdef HAVE_SOCKLEN_T
+#include <sys/types.h>
+#include <sys/socket.h>
+typedef socklen_t __pmSockLen;
+#else
+typedef int __pmSockLen;
+#endif
+
+/*
+ * MAXNAMELEN hides in may places and may have alias names ...
+ */
+#ifndef MAXNAMELEN
+#include <stdio.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if !defined(MAXNAMELEN) && defined(FILENAME_MAX)
+/* posix version of the bsd MAXNAMELEN macro */
+#define MAXNAMELEN FILENAME_MAX
+#endif
+#endif
+#ifndef MAXNAMELEN
+bozo! need to find where MAXNAMELEN is defined for this platform
+#endif
+
+/*
+ * MAXPATHLEN hides in many places and may have alias names ...
+ */
+#ifndef MAXPATHLEN
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#if !defined(MAXPATHLEN) && defined(PATH_MAX)
+/* posix version of the bsd MAXPATHLEN macro */
+#define MAXPATHLEN PATH_MAX
+#endif
+#endif
+#ifndef MAXPATHLEN
+/* bozo! need to find where MAXPATHLEN is defined for this platform */
+#define PATH_MAX 4096
+#define MAXPATHLEN PATH_MAX
+#endif
+
+/*
+ * MAXHOSTNAMELEN hides in many places and may also have aliases ...
+ */
+#ifndef MAXHOSTNAMELEN
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#endif
+#ifndef MAXHOSTNAMELEN
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#endif
+#ifndef MAXHOSTNAMELEN
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#endif
+#ifndef MAXHOSTNAMELEN
+#ifdef HAVE_IPTYPES_H
+#include <iptypes.h>
+#define MAXHOSTNAMELEN MAX_HOSTNAME_LEN
+#endif
+#endif
+#ifndef MAXHOSTNAMELEN
+/* bozo! need to find where MAXHOSTNAMELEN is defined for this platform*/
+#define MAXHOSTNAMELEN 4096
+#endif
+
+#ifndef HAVE_FLOG10
+#if !defined(flog10)
+#define flog10(x) (float)log10((double)x)
+#endif
+#endif
+
+#if !defined(WORD_BIT)
+#define WORD_BIT 32
+#endif
+
+#undef RETSIGTYPE
+#ifndef RETSIGTYPE
+#define RETSIGTYPE void
+#endif
+
+#undef HAVE_SIGPF
+#ifndef HAVE_SIGPF
+/* The return type of signal() */
+typedef void (*SIG_PF) (int);
+#endif
+
+#undef HAVE_SA_SIGINFO
+#undef HAVE_SIGPIPE
+#undef HAVE_SIGHUP
+
+#undef HAVE_WAIT_INCLUDES_SIGNAL
+#ifndef HAVE_WAIT_INCLUDES_SIGNAL
+#include <signal.h>
+#endif
+
+#undef HAVE_PR_TERMCHILD
+#undef HAVE_PR_SET_PDEATHSIG
+
+#ifdef HAVE_LIBGEN_H
+#include <libgen.h>
+#endif
+
+/* thread support options */
+#undef HAVE_PTHREAD_MUTEX_T
+#undef HAVE_PTHREAD_BARRIER_T
+#undef HAVE___THREAD
+
+#undef HAVE_FNDELAY
+#if !defined(HAVE_FNDELAY)
+/* Only Solaris is known to need this so far */
+#ifndef FNDELAY
+#define FNDELAY O_NDELAY
+#endif
+#endif
+
+#undef HAVE_ALTZONE
+#undef HAVE_STRFTIME_z
+#undef HAVE_STRERROR_R_PTR
+
+#undef HAVE_STRUCT_TIMESPEC
+#undef HAVE_STRUCT_SOCKADDR_UN
+#undef HAVE_STRUCT_UCRED
+
+#ifndef HAVE_VALLOC
+#define valloc(x) malloc(x)
+#endif
+
+/* Determine if we are on a Linux box */
+#undef IS_LINUX
+
+/* Determine if we are on a Solaris box */
+#undef IS_SOLARIS
+
+/* Determine if we are on an AIX box */
+#undef IS_AIX
+
+/* Determine if we are on a FreeBSD box */
+#undef IS_FREEBSD
+
+/* Determine if we are on a GNU box */
+#undef IS_GNU
+
+/* Determine if we are on a NetBSD box */
+#undef IS_NETBSD
+
+/* Determine if we are on a Mac OS X box */
+#undef IS_DARWIN
+#ifdef IS_DARWIN
+#define DLOPEN_NO_WARN
+#define st_atim st_atimespec /* workaround */
+#define st_mtim st_mtimespec /* workaround */
+#define st_ctim st_ctimespec /* workaround */
+#endif
+
+/* Determine if we are on Windows with MinGW compiler */
+#undef IS_MINGW
+#ifdef IS_MINGW
+
+#ifdef PCP_VERSION /* used to reduce namespace pollution */
+#define EHOSTDOWN WSAEHOSTDOWN
+#define ENODATA WSANO_DATA
+extern const char *wsastrerror(int);
+
+#define HAVE_PIPE1
+#define HAVE_MKDIR2
+#define HAVE_RENAME2
+#define HAVE_DLOPEN
+#define HAVE_FNDELAY
+
+#define MAP_FAILED NULL
+#define O_NDELAY 0
+#define SIGHUP (NSIG+1)
+#define SIGUSR1 (NSIG+2)
+#define SIGBUS (NSIG+3)
+#define S_IRGRP 0
+#define S_IWGRP 0
+#define S_IROTH 0
+#define S_IWOTH 0
+#define S_IRWXG 0
+#define S_IRWXO 0
+#define S_ISVTX 0
+
+#define fcntl(f, cmd, ...) 0
+#define mkdir2(path, mode) mkdir(path)
+#define rename2(a, b) (unlink(b), rename(a,b))
+#define realpath(path, pp) strcpy(pp, path)
+#define pipe1(fds) _pipe(fds, 4096, O_BINARY)
+
+extern void setlinebuf(FILE *);
+extern char *index(const char *, int);
+extern char *rindex(const char *, int);
+extern char *strcasestr(const char *, const char *);
+extern long int lrand48(void);
+extern void srand48(long int);
+
+#ifdef HAVE_STRUCT_TIMESPEC
+/*
+ * This is a bit odd ... but for MinGW, struct timespec is not in
+ * <time.h> but _is_ in <pthread.h> ... the structure (sec, nanosec)
+ * is what we want, so include <pthread.h>
+ */
+#include <pthread.h>
+#endif
+
+extern int nanosleep(const struct timespec *, struct timespec *);
+extern unsigned int sleep(unsigned int);
+
+enum { RTLD_NOW, RTLD_LAZY };
+extern void *dlopen(const char *, int);
+extern char *dlerror(void);
+extern void *dlsym(void *, const char *);
+extern int dlclose(void *);
+
+extern void openlog(const char *, int, int);
+extern void syslog(int, const char *, ...);
+extern void closelog(void);
+#endif
+enum { LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR,
+ LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG,
+ LOG_PID, LOG_CONS, LOG_DAEMON };
+
+#ifdef LIBPCP_INTERNAL
+#define INTERN __declspec(dllexport)
+#define EXTERN
+#else
+#define INTERN
+#define EXTERN __declspec(dllimport)
+#endif
+
+#define setoserror(n) (errno = (n)) /* not SetLastError() */
+#define oserror() errno /* not GetLastError() */
+#define neterror() WSAGetLastError()
+#define hosterror() WSAGetLastError()
+#define osstrerror() strerror(GetLastError())
+#define osstrerror_r(buf, len) pmErrStr_r(-GetLastError(), buf, len)
+#define netstrerror() strerror(WSAGetLastError())
+#define netstrerror_r(buf, len) pmErrStr_r(-WSAGetLastError(), buf, len)
+#define hoststrerror() strerror(WSAGetLastError())
+
+#else /*!MINGW*/
+#define INTERN
+#define EXTERN extern
+
+#define setoserror(n) (errno = (n))
+#define oserror() errno
+#define neterror() errno
+#define hosterror() h_errno
+#define osstrerror() strerror(errno)
+#define osstrerror_r(buf, len) pmErrStr_r(-errno, buf, len)
+#define netstrerror() strerror(errno)
+#define netstrerror_r(buf, len) pmErrStr_r(-errno, buf, len)
+#define hoststrerror() hstrerror(h_errno)
+#endif
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+#ifndef FD_CLOEXEC
+#define FD_CLOEXEC 0
+#endif
+
+/*
+ * run-time environment that is in libc for most platforms, but for some
+ * we need to provide our own implementation
+ */
+#ifndef HAVE_DIRNAME
+extern char *dirname(char *);
+#endif
+#ifndef HAVE_BASENAME
+extern char *basename(char *);
+#endif
+#ifndef HAVE_STRNDUP
+extern char *strndup(const char *, size_t);
+#endif
+#ifndef HAVE_STRCHRNUL
+extern char *strchrnul(const char *, int);
+#endif
+#ifndef HAVE_STRCHRNUL
+extern char *strchrnul(const char *, int c);
+#endif
+
+#ifdef HAVE_CONST_DIRENT
+#define const_dirent const struct dirent
+#else
+#define const_dirent struct dirent
+#endif
+
+#ifndef HAVE_SCANDIR
+struct dirent;
+extern int scandir(const char *, struct dirent ***,
+ int(*filter)(const_dirent *),
+ int(*compare)(const_dirent **, const_dirent **));
+extern int alphasort(const_dirent **, const_dirent **);
+#endif
+
+#ifndef HAVE_MKDIR2
+#define mkdir2(path,mode) mkdir(path,mode)
+#endif
+
+#ifndef HAVE_RENAME2
+#define rename2(path,target) rename(path,target)
+#endif
+
+#ifndef HAVE_PIPE1
+#define pipe1(fds) pipe(fds)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PCP_CONFIG_H */
diff --git a/src/include/pcp/config32.h b/src/include/pcp/config32.h
new file mode 100644
index 0000000..64eba4c
--- /dev/null
+++ b/src/include/pcp/config32.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PCP_CONFIG32_H
+#define _PCP_CONFIG32_H
+
+/* #undef HAVE_64BIT_LONG */
+#define HAVE_32BIT_LONG 1
+#define HAVE_32BIT_PTR 1
+/* #undef HAVE_64BIT_PTR */
+
+#endif /* _PCP_CONFIG32_H */
diff --git a/src/include/pcp/config64.h b/src/include/pcp/config64.h
new file mode 100644
index 0000000..4bae2ee
--- /dev/null
+++ b/src/include/pcp/config64.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PCP_CONFIG64_H
+#define _PCP_CONFIG64_H
+
+#define HAVE_64BIT_LONG 1
+/* #undef HAVE_32BIT_LONG */
+/* #undef HAVE_32BIT_PTR */
+#define HAVE_64BIT_PTR 1
+
+#endif /* _PCP_CONFIG64_H */
diff --git a/src/include/pcp/configsz.h.in b/src/include/pcp/configsz.h.in
new file mode 100644
index 0000000..4a06e40
--- /dev/null
+++ b/src/include/pcp/configsz.h.in
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Red Hat.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PCP_CONFIGSZ_H
+#define _PCP_CONFIGSZ_H
+
+/* long and pointer must be either 32 bit or 64 bit */
+#undef HAVE_64BIT_LONG
+#undef HAVE_32BIT_LONG
+#undef HAVE_32BIT_PTR
+#undef HAVE_64BIT_PTR
+
+#endif /* _PCP_CONFIGSZ_H */
diff --git a/src/include/pcp/fault.h b/src/include/pcp/fault.h
new file mode 100644
index 0000000..511609f
--- /dev/null
+++ b/src/include/pcp/fault.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2011 Ken McDonell. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+
+#ifndef _FAULT_H
+#define _FAULT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Routines to support fault injection infrastructure
+ *
+ * Build libpcp with -DPM_FAULT_INJECTION to enable all of this.
+ */
+extern void __pmFaultInject(const char *, int);
+extern void __pmFaultSummary(FILE *f);
+
+#ifdef PM_FAULT_INJECTION
+extern int __pmFault_arm;
+#define PM_FAULT_POINT(ident, class) __pmFaultInject(ident, class)
+#ifdef malloc
+#undef malloc
+#endif
+#define malloc(x) __pmFault_malloc(x)
+extern void *__pmFault_malloc(size_t);
+#ifdef realloc
+#undef realloc
+#endif
+#define realloc(x,y) __pmFault_realloc(x,y)
+extern void *__pmFault_realloc(void *, size_t);
+#ifdef strdup
+#undef strdup
+#endif
+#define strdup(x) __pmFault_strdup(x)
+extern char *__pmFault_strdup(const char *);
+#define PM_FAULT_CHECK(class) if (__pmFault_arm == PM_FAULT_PMAPI) { __pmFault_arm = 0; return PM_ERR_FAULT; }
+#else
+#define PM_FAULT_POINT(ident, class)
+#define PM_FAULT_CHECK(class)
+#endif
+
+/*
+ * Classes of fault types (second arg to __pmFaultInject())
+ */
+#define PM_FAULT_ALLOC 100
+#define PM_FAULT_PMAPI 101
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FAULT_H */
diff --git a/src/include/pcp/impl.h b/src/include/pcp/impl.h
new file mode 100644
index 0000000..c139fe1
--- /dev/null
+++ b/src/include/pcp/impl.h
@@ -0,0 +1,1488 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 2008-2009 Aconex. All Rights Reserved.
+ * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _IMPL_H
+#define _IMPL_H
+
+#include <time.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+/*
+ * Thread-safe support ... #define to enable thread-safe protection of
+ * global data structures and mutual exclusion when required.
+ *
+ * We require pthread.h and working mutex, the rest can be faked
+ * by the libpcp itself.
+ */
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_T)
+#define PM_MULTI_THREAD 1
+#include <pthread.h>
+typedef pthread_mutex_t __pmMutex;
+#else
+typedef void * __pmMutex;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This defines the routines, macros and data structures that are used
+ * in the Performance Metrics Collection Subsystem (PMCS) below the
+ * PMAPI.
+ */
+
+/*
+ * internal libpcp state ... PM_STATE_APPL means we are at or above the
+ * PMAPI in a state where PMAPI calls can safely be made ... PM_STATE_PMCS
+ * means we are in the PMCD, or a PMDA, or low-level PDU code, and
+ * PMAPI calls are a bad idea.
+ */
+#define PM_STATE_APPL 0
+#define PM_STATE_PMCS 1
+
+extern void __pmSetInternalState(int);
+extern int __pmGetInternalState(void);
+
+/*
+ * PMCD connections come here by default, over-ride with $PMCD_PORT in
+ * environment
+ */
+#define SERVER_PORT 44321
+#define SERVER_PROTOCOL "pcp"
+/*
+ * port that clients connect to pmproxy(1) on by default, over-ride with
+ * $PMPROXY_PORT in environment
+ */
+#define PROXY_PORT 44322
+#define PROXY_PROTOCOL "proxy"
+
+/*
+ * port that clients connect to pmwebd(1) by default
+ */
+#define PMWEBD_PORT 44323
+#define PMWEBD_PROTOCOL "http"
+
+/*
+ * Internally, this is how to decode a PMID!
+ * - flag is to denote state internally in some operations
+ * - domain is usually the unique domain number of a PMDA, but DYNAMIC_PMID
+ * (number 511) is reserved for PMIDs representing the root of a
+ * dynamic subtree in the PMNS (and in this case the real domain number
+ * is encoded in the cluster field)
+ * - cluster and item together uniquely identify a metric within a domain
+ */
+#define DYNAMIC_PMID 511
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int flag : 1;
+ unsigned int domain : 9;
+ unsigned int cluster : 12;
+ unsigned int item : 10;
+#else
+ unsigned int item : 10;
+ unsigned int cluster : 12;
+ unsigned int domain : 9;
+ unsigned int flag : 1;
+#endif
+} __pmID_int;
+
+static inline __pmID_int *
+__pmid_int(pmID *idp)
+{
+ /* avoid gcc's warning about dereferencing type-punned pointers */
+ return (__pmID_int *)idp;
+}
+
+static inline unsigned int
+pmid_item(pmID id)
+{
+ return __pmid_int(&id)->item;
+}
+
+static inline unsigned int
+pmid_cluster(pmID id)
+{
+ return __pmid_int(&id)->cluster;
+}
+
+static inline unsigned int
+pmid_domain(pmID id)
+{
+ return __pmid_int(&id)->domain;
+}
+
+static inline pmID
+pmid_build(unsigned int domain, unsigned int cluster, unsigned int item)
+{
+ pmID id;
+ __pmID_int idint;
+
+ idint.flag = 0;
+ idint.domain = domain;
+ idint.cluster = cluster;
+ idint.item = item;
+ memcpy(&id, &idint, sizeof(id));
+ return id;
+}
+
+/*
+ * Internally, this is how to decode an Instance Domain Identifier
+ * - flag is to denote state internally in some operations
+ * - domain is usually the unique domain number of a PMDA, but DYNAMIC_PMID
+ * (number 511) is reserved (see above for PMID encoding rules)
+ * - serial uniquely identifies an InDom within a domain
+ */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ int flag : 1;
+ unsigned int domain : 9;
+ unsigned int serial : 22;
+#else
+ unsigned int serial : 22;
+ unsigned int domain : 9;
+ int flag : 1;
+#endif
+} __pmInDom_int;
+
+static inline __pmInDom_int *
+__pmindom_int(pmInDom *idp)
+{
+ /* avoid gcc's warning about dereferencing type-punned pointers */
+ return (__pmInDom_int *)idp;
+}
+
+static inline unsigned int
+pmInDom_domain(pmInDom id)
+{
+ return __pmindom_int(&id)->domain;
+}
+
+static inline unsigned int
+pmInDom_serial(pmInDom id)
+{
+ return __pmindom_int(&id)->serial;
+}
+
+static inline pmInDom
+pmInDom_build(unsigned int domain, unsigned int serial)
+{
+ pmInDom ind;
+ __pmInDom_int indint;
+
+ indint.flag = 0;
+ indint.domain = domain;
+ indint.serial = serial;
+ memcpy(&ind, &indint, sizeof(ind));
+ return ind;
+}
+
+/*
+ * internal structure of a PMNS node
+ */
+typedef struct __pmnsNode {
+ struct __pmnsNode *parent;
+ struct __pmnsNode *next;
+ struct __pmnsNode *first;
+ struct __pmnsNode *hash; /* used as "last" in build, then pmid hash synonym */
+ char *name;
+ pmID pmid;
+} __pmnsNode;
+
+/*
+ * internal structure of a PMNS tree
+ */
+typedef struct __pmnsTree {
+ __pmnsNode *root; /* root of tree structure */
+ __pmnsNode **htab; /* hash table of nodes keyed on pmid */
+ int htabsize; /* number of nodes in the table */
+ char *symbol; /* store all names contiguously */
+ int contiguous; /* is data stored contiguously ? */
+ int mark_state; /* the total mark value for trimming */
+} __pmnsTree;
+
+
+/* used by pmnsmerge... */
+extern __pmnsTree *__pmExportPMNS(void);
+
+/* for PMNS in archives */
+extern int __pmNewPMNS(__pmnsTree **);
+extern void __pmFreePMNS(__pmnsTree *);
+extern void __pmUsePMNS(__pmnsTree *); /* for debugging */
+extern int __pmFixPMNSHashTab(__pmnsTree *, int, int);
+extern int __pmAddPMNSNode(__pmnsTree *, int, const char *);
+
+
+/* return true if the named pmns file has changed */
+extern int __pmHasPMNSFileChanged(const char *);
+
+/* standard log file set up */
+extern FILE *__pmOpenLog(const char *, const char *, FILE *, int *);
+extern FILE *__pmRotateLog(const char *, const char *, FILE *, int *);
+/* make __pmNotifyErr also add entries to syslog */
+extern void __pmSyslog(int);
+/* standard error, warning and info wrapper for syslog(3C) */
+extern void __pmNotifyErr(int, const char *, ...) __PM_PRINTFLIKE(2,3);
+
+/*
+ * These are for debugging only (but are present in the shipped libpcp)
+ */
+EXTERN int pmDebug;
+#define DBG_TRACE_PDU 1 /* PDU send and receive */
+#define DBG_TRACE_FETCH 2 /* dump pmFetch results */
+#define DBG_TRACE_PROFILE 4 /* trace profile changes */
+#define DBG_TRACE_VALUE 8 /* metric value conversions */
+#define DBG_TRACE_CONTEXT 16 /* trace PMAPI context changes */
+#define DBG_TRACE_INDOM 32 /* instance domain operations */
+#define DBG_TRACE_PDUBUF 64 /* PDU buffer management */
+#define DBG_TRACE_LOG 128 /* generic archive log operations */
+#define DBG_TRACE_LOGMETA (1<<8) /* meta data in archives */
+#define DBG_TRACE_OPTFETCH (1<<9) /* optFetch tracing */
+#define DBG_TRACE_AF (1<<10) /* trace async timer events */
+#define DBG_TRACE_APPL0 (1<<11) /* reserved for applications */
+#define DBG_TRACE_APPL1 (1<<12) /* reserved for applications */
+#define DBG_TRACE_APPL2 (1<<13) /* reserved for applications */
+#define DBG_TRACE_PMNS (1<<14) /* PMNS operations */
+#define DBG_TRACE_LIBPMDA (1<<15) /* libpcp_pmda */
+#define DBG_TRACE_TIMECONTROL (1<<16) /* time control api */
+#define DBG_TRACE_PMC (1<<17) /* metrics class */
+#define DBG_TRACE_DERIVE (1<<18) /* derived metrics */
+#define DBG_TRACE_LOCK (1<<19) /* lock tracing */
+#define DBG_TRACE_INTERP (1<<20) /* interpolate mode for archives */
+#define DBG_TRACE_CONFIG (1<<21) /* configuration parameters */
+#define DBG_TRACE_LOOP (1<<22) /* pmLoop tracing */
+#define DBG_TRACE_FAULT (1<<23) /* fault injection tracing */
+#define DBG_TRACE_AUTH (1<<24) /* authentication tracing */
+#define DBG_TRACE_DISCOVERY (1<<25) /* service discovery tracing */
+/* not yet allocated, bits (1<<26) ... (1<<29) */
+#define DBG_TRACE_DESPERATE (1<<30) /* verbose/desperate level */
+
+extern int __pmParseDebug(const char *);
+extern void __pmDumpResult(FILE *, const pmResult *);
+extern void __pmDumpHighResResult(FILE *, const pmHighResResult *);
+extern void __pmPrintStamp(FILE *, const struct timeval *);
+extern void __pmPrintHighResStamp(FILE *, const struct timespec *);
+extern void __pmPrintTimespec(FILE *, const __pmTimespec *);
+extern void __pmPrintTimeval(FILE *, const __pmTimeval *);
+extern void __pmPrintDesc(FILE *, const pmDesc *);
+extern void __pmFreeResultValues(pmResult *);
+extern char *__pmPDUTypeStr_r(int, char *, int);
+extern const char *__pmPDUTypeStr(int); /* NOT thread-safe */
+extern void __pmDumpNameSpace(FILE *, int);
+extern void __pmDumpNameNode(FILE *, __pmnsNode *, int);
+extern void __pmDumpStack(FILE *);
+EXTERN int __pmLogReads;
+
+#ifdef PCP_DEBUG
+extern void __pmDumpIDList(FILE *, int, const pmID *);
+extern void __pmDumpNameList(FILE *, int, char **);
+extern void __pmDumpStatusList(FILE *, int, const int *);
+extern void __pmDumpNameAndStatusList(FILE *, int, char **, int *);
+#endif
+
+/*
+ * Logs and archives of performance metrics (not to be confused
+ * with diagnostic logs for error messages, etc.)
+ *
+ * __pmLogCtl log control
+ * __pmLogTI temporal index record
+ */
+
+/*
+ * Hashed Data Structures for the Processing of Logs and Archives
+ */
+typedef struct __pmHashNode {
+ struct __pmHashNode *next;
+ unsigned int key;
+ void *data;
+} __pmHashNode;
+
+typedef struct __pmHashCtl {
+ int nodes;
+ int hsize;
+ __pmHashNode **hash;
+ __pmHashNode *next;
+ unsigned int index;
+} __pmHashCtl;
+
+typedef enum {
+ PM_HASH_WALK_START = 0,
+ PM_HASH_WALK_NEXT,
+ PM_HASH_WALK_STOP,
+ PM_HASH_WALK_DELETE_NEXT,
+ PM_HASH_WALK_DELETE_STOP,
+} __pmHashWalkState;
+
+extern void __pmHashInit(__pmHashCtl *);
+typedef __pmHashWalkState(*__pmHashWalkCallback)(const __pmHashNode *, void *);
+extern void __pmHashWalkCB(__pmHashWalkCallback, void *, const __pmHashCtl *);
+extern __pmHashNode *__pmHashWalk(__pmHashCtl *, __pmHashWalkState);
+extern __pmHashNode *__pmHashSearch(unsigned int, __pmHashCtl *);
+extern int __pmHashAdd(unsigned int, void *, __pmHashCtl *);
+extern int __pmHashDel(unsigned int, void *, __pmHashCtl *);
+extern void __pmHashClear(__pmHashCtl *);
+
+/*
+ * External file and internal (below PMAPI) format for an archive label
+ * Note: int is OK here, because configure ensures int is a 32-bit integer
+ */
+typedef struct {
+ int ill_magic; /* PM_LOG_MAGIC | log format version no. */
+ int ill_pid; /* PID of logger */
+ __pmTimeval ill_start; /* start of this log */
+ int ill_vol; /* current log volume no. */
+ char ill_hostname[PM_LOG_MAXHOSTLEN];/* name of collection host */
+ char ill_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */
+} __pmLogLabel;
+
+/*
+ * unfortunately, in this version, PCP archives are limited to no
+ * more than 2 Gbytes ...
+ */
+typedef __uint32_t __pm_off_t;
+
+/*
+ * Temporal Index Record
+ * Note: int is OK here, because configure ensures int is a 32-bit integer
+ */
+typedef struct {
+ __pmTimeval ti_stamp; /* now */
+ int ti_vol; /* current log volume no. */
+ __pm_off_t ti_meta; /* end of meta data file */
+ __pm_off_t ti_log; /* end of metrics log file */
+} __pmLogTI;
+
+/*
+ * Log/Archive Control
+ */
+typedef struct {
+ int l_refcnt; /* number of contexts using this log */
+ char *l_name; /* external log base name */
+ FILE *l_tifp; /* temporal index */
+ FILE *l_mdfp; /* meta data */
+ FILE *l_mfp; /* current metrics log */
+ int l_curvol; /* current metrics log volume no. */
+ int l_state; /* (when writing) log state */
+ __pmHashCtl l_hashpmid; /* PMID hashed access */
+ __pmHashCtl l_hashindom; /* instance domain hashed access */
+ __pmHashCtl l_hashrange; /* ptr to first and last value in log for */
+ /* each metric */
+ int l_minvol; /* (when reading) lowest known volume no. */
+ int l_maxvol; /* (when reading) highest known volume no. */
+ int l_numseen; /* (when reading) size of l_seen */
+ int *l_seen; /* (when reading) volumes opened OK */
+ __pmLogLabel l_label; /* (when reading) log label */
+ __pm_off_t l_physend; /* (when reading) offset to physical EOF */
+ /* for last volume */
+ __pmTimeval l_endtime; /* (when reading) timestamp at logical EOF */
+ int l_numti; /* (when reading) no. temporal index entries */
+ __pmLogTI *l_ti; /* (when reading) temporal index */
+ __pmnsTree *l_pmns; /* namespace from meta data */
+} __pmLogCtl;
+
+/* l_state values */
+#define PM_LOG_STATE_NEW 0
+#define PM_LOG_STATE_INIT 1
+
+/*
+ * Return the argument if it's a valid filename else return NULL
+ * (note: this function could be replaced with a call to access(),
+ * but is retained for historical reasons).
+ */
+extern const char *__pmFindPMDA(const char *);
+
+/*
+ * Internal instance profile states
+ */
+#define PM_PROFILE_INCLUDE 0 /* include all, exclude some */
+#define PM_PROFILE_EXCLUDE 1 /* exclude all, include some */
+
+/* Profile entry (per instance domain) */
+typedef struct __pmInDomProfile {
+ pmInDom indom; /* instance domain */
+ int state; /* include all or exclude all */
+ int instances_len; /* length of instances array */
+ int *instances; /* array of instances */
+} __pmInDomProfile;
+
+/* Instance profile for all domains */
+typedef struct __pmProfile {
+ int state; /* default global state */
+ int profile_len; /* length of profile array */
+ __pmInDomProfile *profile; /* array of instance profiles */
+} __pmProfile;
+
+/*
+ * Dump the instance profile, for a particular instance domain
+ * If indom == PM_INDOM_NULL, then print all instance domains
+ */
+extern void __pmDumpProfile(FILE *, int, const __pmProfile *);
+
+/*
+ * Result structure for instance domain queries
+ * Only the PMDAs and pmcd need to know about this.
+ */
+typedef struct __pmInResult {
+ pmInDom indom; /* instance domain */
+ int numinst; /* may be 0 */
+ int *instlist; /* instance ids, may be NULL */
+ char **namelist; /* instance names, may be NULL */
+} __pmInResult;
+extern void __pmDumpInResult(FILE *, const __pmInResult *);
+
+/* instance profile methods */
+extern int __pmProfileSetSent(void);
+extern void __pmFreeProfile(__pmProfile *);
+extern __pmInDomProfile *__pmFindProfile(pmInDom, const __pmProfile *);
+extern int __pmInProfile(pmInDom, const __pmProfile *, int);
+extern void __pmFreeInResult(__pmInResult *);
+
+/*
+ * Version and capabilities information for PDU exchanges
+ */
+
+#define UNKNOWN_VERSION 0
+#define PDU_VERSION2 2
+#define PDU_VERSION PDU_VERSION2
+
+#define PDU_OVERRIDE2 -1002
+
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int zero : 1; /* ensure this is zero for 1.x compatibility */
+ unsigned int version : 7; /* PDU_VERSION collector protocol preference */
+ unsigned int licensed : 8; /* ensure this is one for 2.x compatibility */
+ unsigned int features : 16; /* advertised (enabled) collector features */
+#else
+ unsigned int features : 16;
+ unsigned int licensed : 8;
+ unsigned int version : 7;
+ unsigned int zero : 1;
+#endif
+} __pmPDUInfo;
+
+/*
+ * Host specification allowing one or more pmproxy host, and port numbers
+ * within the one string, i.e. pmcd host specifications of the form:
+ * host:port,port@proxy:port,port
+ */
+typedef struct {
+ char *name; /* hostname (always valid) */
+ int *ports; /* array of host port numbers */
+ int nports; /* number of ports in host port array */
+} pmHostSpec;
+
+extern int __pmParseHostSpec(const char *, pmHostSpec **, int *, char **);
+extern int __pmUnparseHostSpec(pmHostSpec *, int, char *, size_t);
+extern void __pmFreeHostSpec(pmHostSpec *, int);
+
+typedef enum {
+ PCP_ATTR_NONE = 0,
+ PCP_ATTR_PROTOCOL = 1, /* either pcp:/pcps: protocol (libssl) */
+ PCP_ATTR_SECURE = 2, /* relaxed/enforced pcps mode (libssl) */
+ PCP_ATTR_COMPRESS = 3, /* compression flag, no value (libnss) */
+ PCP_ATTR_USERAUTH = 4, /* user auth flag, no value (libsasl) */
+ PCP_ATTR_USERNAME = 5, /* user login identity (libsasl) */
+ PCP_ATTR_AUTHNAME = 6, /* authentication name (libsasl) */
+ PCP_ATTR_PASSWORD = 7, /* passphrase-based secret (libsasl) */
+ PCP_ATTR_METHOD = 8, /* use authentication method (libsasl) */
+ PCP_ATTR_REALM = 9, /* realm to authenticate in (libsasl) */
+ PCP_ATTR_UNIXSOCK = 10, /* AF_UNIX socket + SO_PEERCRED (unix) */
+ PCP_ATTR_USERID = 11, /* uid - user identifier (posix) */
+ PCP_ATTR_GROUPID = 12, /* gid - group identifier (posix) */
+ PCP_ATTR_LOCAL = 13, /* AF_UNIX socket with localhost fallback */
+ PCP_ATTR_PROCESSID = 14, /* pid - process identifier (posix) */
+} __pmAttrKey;
+
+extern __pmAttrKey __pmLookupAttrKey(const char *, size_t);
+extern int __pmAttrKeyStr_r(__pmAttrKey, char *, size_t);
+extern int __pmAttrStr_r(__pmAttrKey, const char *, char *, size_t);
+
+extern int __pmParseHostAttrsSpec(
+ const char *, pmHostSpec **, int *, __pmHashCtl *, char **);
+extern int __pmUnparseHostAttrsSpec(
+ pmHostSpec *, int, __pmHashCtl *, char *, size_t);
+extern void __pmFreeHostAttrsSpec(pmHostSpec *, int, __pmHashCtl *);
+extern void __pmFreeAttrsSpec(__pmHashCtl *);
+
+/*
+ * Control for connection to a PMCD
+ */
+typedef struct {
+ __pmMutex pc_lock; /* mutex pmcd ipc */
+ int pc_refcnt; /* number of contexts using this socket */
+ int pc_fd; /* socket for comm with pmcd */
+ /* ... -1 means no connection */
+ pmHostSpec *pc_hosts; /* pmcd and proxy host specifications */
+ int pc_nhosts; /* number of pmHostSpec entries */
+ int pc_timeout; /* set if connect times out */
+ int pc_tout_sec; /* timeout for __pmGetPDU */
+ time_t pc_again; /* time to try again */
+} __pmPMCDCtl;
+
+extern int __pmConnectPMCD(pmHostSpec *, int, int, __pmHashCtl *);
+extern int __pmConnectLocal(__pmHashCtl *);
+extern int __pmAuxConnectPMCD(const char *);
+extern int __pmAuxConnectPMCDPort(const char *, int);
+extern int __pmAuxConnectPMCDUnixSocket(const char *);
+
+extern int __pmAddHostPorts(pmHostSpec *, int *, int);
+extern void __pmDropHostPort(pmHostSpec *);
+extern void __pmConnectGetPorts(pmHostSpec *);
+
+/*
+ * SSL/TLS/IPv6 support via NSS/NSPR.
+ */
+extern int __pmSecureServerSetup(const char *, const char *);
+extern void __pmSecureServerShutdown(void);
+extern int __pmSecureServerHandshake(int, int, __pmHashCtl *);
+extern int __pmSecureClientHandshake(int, int, const char *, __pmHashCtl *);
+
+typedef fd_set __pmFdSet;
+typedef struct __pmSockAddr __pmSockAddr;
+typedef struct __pmHostEnt __pmHostEnt;
+
+extern int __pmCreateSocket(void);
+extern int __pmCreateIPv6Socket(void);
+extern int __pmCreateUnixSocket(void);
+extern void __pmCloseSocket(int);
+
+extern int __pmSetSockOpt(int, int, int, const void *, __pmSockLen);
+extern int __pmGetSockOpt(int, int, int, void *, __pmSockLen *);
+extern int __pmConnect(int, void *, __pmSockLen);
+extern int __pmBind(int, void *, __pmSockLen);
+extern int __pmListen(int, int);
+extern int __pmAccept(int, void *, __pmSockLen *);
+extern ssize_t __pmWrite(int, const void *, size_t);
+extern ssize_t __pmRead(int, void *, size_t);
+extern ssize_t __pmSend(int, const void *, size_t, int);
+extern ssize_t __pmRecv(int, void *, size_t, int);
+extern int __pmConnectTo(int, const __pmSockAddr *, int);
+extern int __pmConnectCheckError(int);
+extern int __pmConnectRestoreFlags(int, int);
+extern int __pmSocketClosed(void);
+extern int __pmGetFileStatusFlags(int);
+extern int __pmSetFileStatusFlags(int, int);
+extern int __pmGetFileDescriptorFlags(int);
+extern int __pmSetFileDescriptorFlags(int, int);
+
+extern int __pmFD(int);
+extern void __pmFD_CLR(int, __pmFdSet *);
+extern int __pmFD_ISSET(int, __pmFdSet *);
+extern void __pmFD_SET(int, __pmFdSet *);
+extern void __pmFD_ZERO(__pmFdSet *);
+extern void __pmFD_COPY(__pmFdSet *, const __pmFdSet *);
+extern int __pmSelectRead(int, __pmFdSet *, struct timeval *);
+extern int __pmSelectWrite(int, __pmFdSet *, struct timeval *);
+
+extern __pmSockAddr *__pmSockAddrAlloc(void);
+extern void __pmSockAddrFree(__pmSockAddr *);
+extern size_t __pmSockAddrSize(void);
+extern void __pmSockAddrInit(__pmSockAddr *, int, int, int);
+extern int __pmSockAddrCompare(const __pmSockAddr *, const __pmSockAddr *);
+extern __pmSockAddr *__pmSockAddrDup(const __pmSockAddr *);
+extern __pmSockAddr *__pmSockAddrMask(__pmSockAddr *, const __pmSockAddr *);
+extern void __pmSockAddrSetFamily(__pmSockAddr *, int);
+extern int __pmSockAddrGetFamily(const __pmSockAddr *);
+extern void __pmSockAddrSetPort(__pmSockAddr *, int);
+extern int __pmSockAddrGetPort(const __pmSockAddr *);
+extern void __pmSockAddrSetScope(__pmSockAddr *, int);
+extern void __pmSockAddrSetPath(__pmSockAddr *, const char *);
+extern int __pmSockAddrIsLoopBack(const __pmSockAddr *);
+extern int __pmSockAddrIsInet(const __pmSockAddr *);
+extern int __pmSockAddrIsIPv6(const __pmSockAddr *);
+extern int __pmSockAddrIsUnix(const __pmSockAddr *);
+extern char * __pmSockAddrToString(const __pmSockAddr *);
+extern __pmSockAddr *__pmStringToSockAddr(const char *);
+extern __pmSockAddr *__pmLoopBackAddress(int);
+extern __pmSockAddr *__pmSockAddrFirstSubnetAddr(const __pmSockAddr *, int);
+extern __pmSockAddr *__pmSockAddrNextSubnetAddr(__pmSockAddr *, int);
+
+extern __pmHostEnt * __pmHostEntAlloc(void);
+extern void __pmHostEntFree(__pmHostEnt *);
+extern __pmSockAddr *__pmHostEntGetSockAddr(const __pmHostEnt *, void **);
+extern char * __pmHostEntGetName(__pmHostEnt *);
+
+extern __pmHostEnt * __pmGetAddrInfo(const char *);
+extern char * __pmGetNameInfo(__pmSockAddr *);
+
+/*
+ * Query server features - used for expressing protocol capabilities
+ */
+typedef enum {
+ PM_SERVER_FEATURE_SECURE = 0,
+ PM_SERVER_FEATURE_COMPRESS,
+ PM_SERVER_FEATURE_IPV6,
+ PM_SERVER_FEATURE_AUTH,
+ PM_SERVER_FEATURE_CREDS_REQD,
+ PM_SERVER_FEATURE_UNIX_DOMAIN,
+ PM_SERVER_FEATURE_DISCOVERY,
+ PM_SERVER_FEATURES
+} __pmServerFeature;
+
+extern int __pmServerHasFeature(__pmServerFeature);
+extern int __pmServerSetFeature(__pmServerFeature);
+extern int __pmServerClearFeature(__pmServerFeature);
+extern int __pmServerCreatePIDFile(const char *, int);
+extern int __pmServerAddPorts(const char *);
+extern int __pmServerAddInterface(const char *);
+extern void __pmServerSetLocalSocket(const char *);
+extern int __pmServerSetLocalCreds(int, __pmHashCtl *);
+extern void __pmServerSetServiceSpec(const char *);
+typedef void (*__pmServerCallback)(__pmFdSet *, int, int);
+extern void __pmServerAddNewClients(__pmFdSet *, __pmServerCallback);
+extern int __pmServerAddToClientFdSet(__pmFdSet *, int);
+extern int __pmServerOpenRequestPorts(__pmFdSet *, int);
+extern void __pmServerCloseRequestPorts(void);
+extern void __pmServerDumpRequestPorts(FILE *);
+extern char *__pmServerRequestPortString(int, char *, size_t);
+
+/* Service broadcasting, for servers. */
+typedef struct __pmServerPresence __pmServerPresence;
+extern __pmServerPresence *__pmServerAdvertisePresence(const char *, int);
+extern void __pmServerUnadvertisePresence(__pmServerPresence *);
+
+/*
+ * Per-context controls for archives and logs
+ */
+typedef struct {
+ __pmLogCtl *ac_log; /* global logging and archive control */
+ long ac_offset; /* fseek ptr for archives */
+ int ac_vol; /* volume for ac_offset */
+ int ac_serial; /* serial access pattern for archives */
+ __pmHashCtl ac_pmid_hc; /* per PMID controls for INTERP */
+ double ac_end; /* time at end of archive */
+ void *ac_want; /* used in interp.c */
+ void *ac_unbound; /* used in interp.c */
+ void *ac_cache; /* used in interp.c */
+ int ac_cache_idx; /* used in interp.c */
+} __pmArchCtl;
+
+/*
+ * PMAPI context. We keep an array of these,
+ * one for each context created by the application.
+ */
+typedef struct {
+ __pmMutex c_lock; /* mutex for multi-thread access */
+ int c_type; /* HOST, ARCHIVE, LOCAL or FREE */
+ int c_mode; /* current mode PM_MODE_* */
+ __pmPMCDCtl *c_pmcd; /* pmcd control for HOST contexts */
+ __pmArchCtl *c_archctl; /* log control for ARCHIVE contexts */
+ __pmTimeval c_origin; /* pmFetch time origin / current time */
+ int c_delta; /* for updating origin */
+ int c_sent; /* profile has been sent to pmcd */
+ __pmProfile *c_instprof; /* instance profile */
+ void *c_dm; /* derived metrics, if any */
+ int c_flags; /* ctx flags (set via type/env/attrs) */
+ __pmHashCtl c_attrs; /* various optional context attributes */
+} __pmContext;
+
+#define __PM_MODE_MASK 0xffff
+
+#define PM_CONTEXT_FREE -1 /* special type */
+
+/*
+ * Convert opaque context handle to __pmContext pointer
+ */
+extern __pmContext *__pmHandleToPtr(int);
+
+/*
+ * Dump the current context (source details + instance profile),
+ * for a particular instance domain.
+ * If indom == PM_INDOM_NULL, then print all all instance domains
+ */
+extern void __pmDumpContext(FILE *, int, pmInDom);
+
+/*
+ * pmFetch helper routines, providing hooks for derivations.
+ */
+extern int __pmPrepareFetch(__pmContext *, int, const pmID *, pmID **);
+extern int __pmFinishResult(__pmContext *, int, pmResult **);
+
+/*
+ * Protocol data unit support
+ * Note: int is OK here, because configure ensures int is a 32-bit integer
+ */
+typedef struct {
+ int len; /* length of pdu_header + PDU */
+ int type; /* PDU type */
+ int from; /* pid of PDU originator */
+} __pmPDUHdr;
+
+typedef __uint32_t __pmPDU;
+/*
+ * round a size up to the next multiple of a __pmPDU size
+ *
+ * PM_PDU_SIZE is in units of __pmPDU size
+ * PM_PDU_SIZE_BYTES is in units of bytes
+ */
+#define PM_PDU_SIZE(x) (((x)+sizeof(__pmPDU)-1)/sizeof(__pmPDU))
+#define PM_PDU_SIZE_BYTES(x) (sizeof(__pmPDU)*PM_PDU_SIZE(x))
+
+/* Types of credential PDUs (c_type) */
+#define CVERSION 0x1
+
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int c_type: 8; /* Credentials PDU type */
+ unsigned int c_vala: 8;
+ unsigned int c_valb: 8;
+ unsigned int c_valc: 8;
+#else
+ unsigned int c_valc: 8;
+ unsigned int c_valb: 8;
+ unsigned int c_vala: 8;
+ unsigned int c_type: 8;
+#endif
+} __pmCred;
+
+/* Flags for CVERSION credential PDUs, and __pmPDUInfo features */
+#define PDU_FLAG_SECURE (1U<<0)
+#define PDU_FLAG_COMPRESS (1U<<1)
+#define PDU_FLAG_AUTH (1U<<2)
+#define PDU_FLAG_CREDS_REQD (1U<<3)
+#define PDU_FLAG_SECURE_ACK (1U<<4)
+#define PDU_FLAG_NO_NSS_INIT (1U<<5)
+
+/* Credential CVERSION PDU elements look like this */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int c_type: 8; /* Credentials PDU type */
+ unsigned int c_version: 8; /* PCP protocol version */
+ unsigned int c_flags: 16; /* All feature requests */
+#else
+ unsigned int c_flags: 16;
+ unsigned int c_version: 8;
+ unsigned int c_type: 8;
+#endif
+} __pmVersionCred;
+
+extern int __pmXmitPDU(int, __pmPDU *);
+extern int __pmGetPDU(int, int, int, __pmPDU **);
+extern int __pmGetPDUCeiling(void);
+extern int __pmSetPDUCeiling(int);
+
+EXTERN unsigned int *__pmPDUCntIn;
+EXTERN unsigned int *__pmPDUCntOut;
+extern void __pmSetPDUCntBuf(unsigned *, unsigned *);
+
+/* timeout options for PDU handling */
+#define TIMEOUT_NEVER 0
+#define TIMEOUT_DEFAULT -1
+/*#define TIMEOUT_ASYNC -2*/
+#define TIMEOUT_CONNECT -3
+
+/* mode options for __pmGetPDU */
+#define ANY_SIZE 0 /* replacement for old PDU_BINARY */
+#define LIMIT_SIZE 2 /* replacement for old PDU_CLIENT */
+
+extern __pmPDU *__pmFindPDUBuf(int);
+extern void __pmPinPDUBuf(void *);
+extern int __pmUnpinPDUBuf(void *);
+extern void __pmCountPDUBuf(int, int *, int *);
+
+#define PDU_START 0x7000
+#define PDU_ERROR 0x7000
+#define PDU_RESULT 0x7001
+#define PDU_PROFILE 0x7002
+#define PDU_FETCH 0x7003
+#define PDU_DESC_REQ 0x7004
+#define PDU_DESC 0x7005
+#define PDU_INSTANCE_REQ 0x7006
+#define PDU_INSTANCE 0x7007
+#define PDU_TEXT_REQ 0x7008
+#define PDU_TEXT 0x7009
+#define PDU_CONTROL_REQ 0x700a
+#define PDU_CREDS 0x700c
+#define PDU_PMNS_IDS 0x700d
+#define PDU_PMNS_NAMES 0x700e
+#define PDU_PMNS_CHILD 0x700f
+#define PDU_PMNS_TRAVERSE 0x7010
+#define PDU_AUTH 0x7011
+#define PDU_FINISH 0x7011
+#define PDU_MAX (PDU_FINISH - PDU_START)
+
+/*
+ * Unit of space allocation for PDU buffer.
+ */
+#define PDU_CHUNK 1024
+
+/*
+ * PDU encoding formats
+ * These have been retired ...
+ * #define PDU_BINARY 0
+ * #define PDU_ASCII 1
+ * And this has been replaced by LIMIT_SIZE for __pmGetPDU
+ * #define PDU_CLIENT 2
+ */
+
+/*
+ * Anonymous PDU sender, when context does not matter, e.g. PDUs from
+ * a PMDA sent to PMCD
+ */
+#define FROM_ANON 0
+
+extern int __pmSendError(int, int, int);
+extern int __pmDecodeError(__pmPDU *, int *);
+extern int __pmSendXtendError(int, int, int, int);
+extern int __pmDecodeXtendError(__pmPDU *, int *, int *);
+extern int __pmSendResult(int, int, const pmResult *);
+extern int __pmEncodeResult(int, const pmResult *, __pmPDU **);
+extern int __pmDecodeResult(__pmPDU *, pmResult **);
+extern int __pmSendProfile(int, int, int, __pmProfile *);
+extern int __pmDecodeProfile(__pmPDU *, int *, __pmProfile **);
+extern int __pmSendFetch(int, int, int, __pmTimeval *, int, pmID *);
+extern int __pmDecodeFetch(__pmPDU *, int *, __pmTimeval *, int *, pmID **);
+extern int __pmSendDescReq(int, int, pmID);
+extern int __pmDecodeDescReq(__pmPDU *, pmID *);
+extern int __pmSendDesc(int, int, pmDesc *);
+extern int __pmDecodeDesc(__pmPDU *, pmDesc *);
+extern int __pmSendInstanceReq(int, int, const __pmTimeval *, pmInDom, int, const char *);
+extern int __pmDecodeInstanceReq(__pmPDU *, __pmTimeval *, pmInDom *, int *, char **);
+extern int __pmSendInstance(int, int, __pmInResult *);
+extern int __pmDecodeInstance(__pmPDU *, __pmInResult **);
+extern int __pmSendTextReq(int, int, int, int);
+extern int __pmDecodeTextReq(__pmPDU *, int *, int *);
+extern int __pmSendText(int, int, int, const char *);
+extern int __pmDecodeText(__pmPDU *, int *, char **);
+extern int __pmSendCreds(int, int, int, const __pmCred *);
+extern int __pmDecodeCreds(__pmPDU *, int *, int *, __pmCred **);
+extern int __pmSendIDList(int, int, int, const pmID *, int);
+extern int __pmDecodeIDList(__pmPDU *, int, pmID *, int *);
+extern int __pmSendNameList(int, int, int, char **, const int *);
+extern int __pmDecodeNameList(__pmPDU *, int *, char ***, int **);
+extern int __pmSendChildReq(int, int, const char *, int);
+extern int __pmDecodeChildReq(__pmPDU *, char **, int *);
+extern int __pmSendTraversePMNSReq(int, int, const char *);
+extern int __pmDecodeTraversePMNSReq(__pmPDU *, char **);
+extern int __pmSendAuth(int, int, int, const char *, int);
+extern int __pmDecodeAuth(__pmPDU *, int *, char **, int *);
+
+#if defined(HAVE_64BIT_LONG)
+
+/*
+ * A pmValue contains the union of a 32-bit int and a pointer. In the world
+ * of 64-bit pointers, a pmValue is therefore larger than in the 32-bit world.
+ * The structures below are used in all PDUs containing pmResults to ensure
+ * 32-bit and 64-bit programs exchanging PDUs can communicate.
+ * Note that a pmValue can only hold a 32-bit value in situ regardless of
+ * whether the pointer size is 32 or 64 bits.
+ */
+
+typedef struct {
+ int inst; /* instance identifier */
+ union {
+ unsigned int pval; /* offset into PDU buffer for value */
+ int lval; /* 32-bit value in situ */
+ } value;
+} __pmValue_PDU;
+
+typedef struct {
+ pmID pmid; /* metric identifier */
+ int numval; /* number of values */
+ int valfmt; /* value style */
+ __pmValue_PDU vlist[1]; /* set of instances/values */
+} __pmValueSet_PDU;
+
+#elif defined(HAVE_32BIT_LONG)
+
+/* In the 32-bit world, structures may be used in PDUs as defined */
+
+typedef pmValue __pmValue_PDU;
+typedef pmValueSet __pmValueSet_PDU;
+
+#else
+bozo - unknown size of long !!!
+#endif
+
+/*
+ * For the help text PDUs, the type (PM_TEXT_ONELINE or PM_TEXT_HELP)
+ * is 'or'd with the following to encode the request for a PMID or
+ * a pmInDom ...
+ * Note the values must therefore be (a) bit fields and (b) different
+ * to the public macros PM_TEXT_* in pmapi.h
+ */
+#define PM_TEXT_PMID 4
+#define PM_TEXT_INDOM 8
+
+/*
+ * no mem today, my love has gone away ....
+ */
+extern void __pmNoMem(const char *, size_t, int);
+#define PM_FATAL_ERR 1
+#define PM_RECOV_ERR 0
+
+/*
+ * Startup handling:
+ * set program name, as used in __pmNotifyErr() ... default is "pcp"
+ * set default user for __pmSetProcessIdentity() ... default is "pcp"
+ */
+EXTERN char *pmProgname;
+extern int __pmSetProgname(const char *);
+extern int __pmGetUsername(char **);
+
+/*
+ * Cleanup handling:
+ * shutdown various components in libpcp, releasing all resources
+ * (local context PMDAs, any global NSS socket state, etc).
+ */
+extern int __pmShutdown(void);
+
+/*
+ * Map platform error values to PMAPI error codes.
+ */
+extern int __pmMapErrno(int);
+
+/*
+ * __pmLogInDom is used to hold the instance identifiers for an instance
+ * domain internally ... if multiple sets are observed over time, these
+ * are linked together in reverse chronological order
+ * -- externally we write these as
+ * timestamp
+ * indom <- note, added wrt indom_t
+ * numinst
+ * inst[0], .... inst[numinst-1]
+ * nameindex[0] .... nameindex[numinst-1]
+ * string (name) table, all null-byte terminated
+ *
+ * NOTE: 3 types of allocation
+ * (1)
+ * buf is NULL,
+ * namelist and instlist have been allocated
+ * separately and so must each be freed.
+ * (2)
+ * buf is NOT NULL, allinbuf == 1,
+ * all allocations were in the buffer and so only
+ * the buffer should be freed,
+ * (3)
+ * buf is NOT NULL, allinbuf == 0,
+ * as well as buffer allocation,
+ * the namelist has been allocated separately and so
+ * both the buf and namelist should be freed.
+ */
+typedef struct _indom_t {
+ struct _indom_t *next;
+ __pmTimeval stamp;
+ int numinst;
+ int *instlist;
+ char **namelist;
+ int *buf;
+ int allinbuf;
+} __pmLogInDom;
+
+/*
+ * record header in the metadata log file ... len (by itself) also is
+ * used as a trailer
+ */
+typedef struct {
+ int len; /* record length, includes header and trailer */
+ int type; /* see TYPE_* #defines below */
+} __pmLogHdr;
+
+#define TYPE_DESC 1 /* header, pmDesc, trailer */
+#define TYPE_INDOM 2 /* header, __pmLogInDom, trailer */
+
+extern void __pmLogPutIndex(const __pmLogCtl *, const __pmTimeval *);
+
+extern const char *__pmLogName_r(const char *, int, char *, int);
+extern const char *__pmLogName(const char *, int); /* NOT thread-safe */
+extern FILE *__pmLogNewFile(const char *, int);
+extern int __pmLogCreate(const char *, const char *, int, __pmLogCtl *);
+#define PMLOGREAD_NEXT 0
+#define PMLOGREAD_TO_EOF 1
+extern int __pmLogRead(__pmLogCtl *, int, FILE *, pmResult **, int);
+extern int __pmLogWriteLabel(FILE *, const __pmLogLabel *);
+extern int __pmLogOpen(const char *, __pmContext *);
+extern int __pmLogLoadLabel(__pmLogCtl *, const char *);
+extern int __pmLogLoadIndex(__pmLogCtl *);
+extern int __pmLogLoadMeta(__pmLogCtl *);
+extern void __pmLogClose(__pmLogCtl *);
+extern void __pmLogCacheClear(FILE *);
+
+extern int __pmLogPutDesc(__pmLogCtl *, const pmDesc *, int, char **);
+extern int __pmLogLookupDesc(__pmLogCtl *, pmID, pmDesc *);
+extern int __pmLogPutInDom(__pmLogCtl *, pmInDom, const __pmTimeval *, int, int *, char **);
+extern int __pmLogGetInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int **, char ***);
+extern int __pmLogLookupInDom(__pmLogCtl *, pmInDom, __pmTimeval *, const char *);
+extern int __pmLogNameInDom(__pmLogCtl *, pmInDom, __pmTimeval *, int, char **);
+
+extern int __pmLogPutResult(__pmLogCtl *, __pmPDU *);
+extern int __pmLogPutResult2(__pmLogCtl *, __pmPDU *);
+extern int __pmLogFetch(__pmContext *, int, pmID *, pmResult **);
+extern int __pmLogFetchInterp(__pmContext *, int, pmID *, pmResult **);
+extern void __pmLogSetTime(__pmContext *);
+extern void __pmLogResetInterp(__pmContext *);
+extern void __pmFreeInterpData(__pmContext *);
+
+extern int __pmLogChangeVol(__pmLogCtl *, int);
+extern int __pmLogChkLabel(__pmLogCtl *, FILE *, __pmLogLabel *, int);
+extern int __pmGetArchiveEnd(__pmLogCtl *, struct timeval *);
+
+/* struct for maintaining information about pmlogger ports */
+typedef struct {
+ int pid; /* process id of logger */
+ int port; /* internet port for logger control */
+ char *pmcd_host; /* host pmlogger is collecting from */
+ char *archive; /* archive base pathname */
+ char *name; /* file name (minus dirname) */
+} __pmLogPort;
+
+/* Returns control port info for a pmlogger given its pid.
+ * If pid == PM_LOG_ALL_PIDS, get all pmloggers' control ports.
+ * If pid == PM_LOG_PRIMARY_PID, get primar logger's control port.
+ * Note: do NOT free any part of result returned via the parameter.
+ *
+ * __pmLogFindPort(const char *hostname, int pid, __pmLogPort **result);
+ */
+extern int __pmLogFindPort(const char *, int, __pmLogPort **);
+
+#define PM_LOG_PRIMARY_PID 0 /* symbolic pid for primary logger */
+#define PM_LOG_PRIMARY_PORT 0 /* symbolic port for primary pmlogger */
+#define PM_LOG_ALL_PIDS -1 /* symbolic pid for all pmloggers */
+#define PM_LOG_NO_PID -2 /* not a valid pid for pmlogger */
+#define PM_LOG_NO_PORT -2 /* not a valid port for pmlogger */
+
+extern const char *__pmLogLocalSocketDefault(int, char *buf, size_t bufSize);
+extern const char *__pmLogLocalSocketUser(int, char *buf, size_t bufSize);
+
+/* time utils */
+extern time_t __pmMktime(struct tm *);
+
+/* reverse ctime and time interval parsing */
+extern int __pmParseCtime(const char *, struct tm *, char **);
+extern int __pmConvertTime(struct tm *, struct timeval *, struct timeval *);
+extern int __pmParseTime(const char *, struct timeval *, struct timeval *,
+ struct timeval *, char **);
+
+/* manipulate internal timestamps */
+extern double __pmTimevalSub(const __pmTimeval *, const __pmTimeval *);
+
+/* 32-bit file checksum */
+extern __int32_t __pmCheckSum(FILE *);
+
+/* check for localhost */
+extern int __pmIsLocalhost(const char *);
+
+/*
+ * struct timeval manipulations
+ */
+extern double __pmtimevalAdd(const struct timeval *, const struct timeval *);
+extern double __pmtimevalSub(const struct timeval *, const struct timeval *);
+extern double __pmtimevalToReal(const struct timeval *);
+extern void __pmtimevalFromReal(double, struct timeval *);
+extern void __pmtimevalSleep(struct timeval);
+extern void __pmtimevalPause(struct timeval);
+extern void __pmtimevalNow(struct timeval *);
+
+typedef struct {
+ char *label; /* label to name tz */
+ char *tz; /* env $TZ */
+ int handle; /* handle from pmNewZone() */
+} pmTimeZone;
+
+/*
+ * event tracing for monitoring time between events
+ */
+extern void __pmEventTrace(const char *); /* NOT thread-safe */
+extern void __pmEventTrace_r(const char *, int *, double *, double *);
+
+/*
+ * More IPC protocol stuff
+ */
+
+typedef int (*__pmConnectHostType)(int, int);
+
+extern int __pmSetSocketIPC(int);
+extern int __pmSetVersionIPC(int, int);
+extern int __pmSetDataIPC(int, void *);
+extern int __pmDataIPCSize(void);
+extern int __pmLastVersionIPC(void);
+extern int __pmVersionIPC(int);
+extern int __pmSocketIPC(int);
+extern int __pmDataIPC(int, void *);
+extern void __pmOverrideLastFd(int);
+extern void __pmPrintIPC(void);
+extern void __pmResetIPC(int);
+
+/* safely insert an atom value into a pmValue */
+extern int __pmStuffValue(const pmAtomValue *, pmValue *, int);
+
+/*
+ * Optimized fetch bundling ("optfetch") services
+ */
+typedef struct __optreq {
+ struct __optreq *r_next; /* next request */
+ struct __fetchctl *r_fetch; /* back ptr */
+ pmDesc *r_desc; /* pmDesc for request pmID */
+ int r_numinst; /* request instances */
+ int *r_instlist; /* request instances */
+ void *r_aux; /* generic pointer to aux data */
+} optreq_t;
+
+typedef struct __pmidctl {
+ struct __pmidctl *p_next; /* next pmid control */
+ optreq_t *p_rqp; /* first request for this metric */
+ pmID p_pmid; /* my pmID */
+ int p_numinst; /* union over requests */
+ int *p_instlist; /* union over requests */
+ void *p_aux; /* generic pointer to aux data */
+} pmidctl_t;
+
+typedef struct __indomctl {
+ struct __indomctl *i_next; /* next indom control */
+ pmidctl_t *i_pmp; /* first metric, in this group */
+ pmInDom i_indom; /* my pmInDom */
+ int i_numinst; /* arg for pmAddProfile */
+ int *i_instlist; /* arg for pmAddProfile */
+ void *i_aux; /* generic pointer to aux data */
+} indomctl_t;
+
+typedef struct __fetchctl {
+ struct __fetchctl *f_next; /* next fetch control */
+ indomctl_t *f_idp; /* first indom, in this group */
+ int f_state; /* state changes during updates */
+ int f_cost; /* used internally for optimization */
+ int f_newcost; /* used internally for optimization */
+ int f_numpmid; /* arg for pmFetch() */
+ pmID *f_pmidlist; /* arg for pmFetch() */
+ void *f_aux; /* generic pointer to aux data */
+} fetchctl_t;
+
+/* states relevant to user */
+#define OPT_STATE_NEW 1 /* newly created group */
+#define OPT_STATE_PMID 2 /* list of pmids changed */
+#define OPT_STATE_PROFILE 4 /* instance profile changed */
+
+/* states used during optimization */
+#define OPT_STATE_UMASK 7 /* preserve user state bits */
+#define OPT_STATE_XREQ 8 /* things that may have changed */
+#define OPT_STATE_XPMID 16
+#define OPT_STATE_XINDOM 32
+#define OPT_STATE_XFETCH 64
+#define OPT_STATE_XPROFILE 128
+
+/*
+ * Objective function parameters
+ */
+typedef struct {
+ int c_pmid; /* cost per PMD for PMIDs in a fetch */
+ int c_indom; /* cost per PMD for indoms in a fetch */
+ int c_fetch; /* cost of a new fetch group */
+ int c_indomsize; /* expected numer of instances for an indom */
+ int c_xtrainst; /* cost of retrieving an unwanted metric inst */
+ int c_scope; /* cost opt., 0 for incremental, 1 for global */
+} optcost_t;
+
+#define OPT_COST_INFINITY 0x7fffffff
+
+extern void __pmOptFetchAdd(fetchctl_t **, optreq_t *);
+extern int __pmOptFetchDel(fetchctl_t **, optreq_t *);
+extern void __pmOptFetchRedo(fetchctl_t **);
+extern void __pmOptFetchDump(FILE *, const fetchctl_t *);
+extern void __pmOptFetchGetParams(optcost_t *);
+extern void __pmOptFetchPutParams(optcost_t *);
+
+/* work out local timezone */
+extern char *__pmTimezone(void); /* NOT thread-safe */
+extern char *__pmTimezone_r(char *, int);
+
+/*
+ */
+
+/*
+ * Generic access control routines
+ */
+extern int __pmAccAddOp(unsigned int);
+
+extern int __pmAccAddHost(const char *, unsigned int, unsigned int, int);
+extern int __pmAccAddUser(const char *, unsigned int, unsigned int, int);
+extern int __pmAccAddGroup(const char *, unsigned int, unsigned int, int);
+
+extern int __pmAccAddClient(__pmSockAddr *, unsigned int *);
+extern int __pmAccAddAccount(const char *, const char *, unsigned int *);
+extern void __pmAccDelClient(__pmSockAddr *);
+extern void __pmAccDelAccount(const char *, const char *);
+
+extern void __pmAccDumpHosts(FILE *);
+extern void __pmAccDumpUsers(FILE *);
+extern void __pmAccDumpGroups(FILE *);
+extern void __pmAccDumpLists(FILE *);
+
+extern int __pmAccSaveHosts(void);
+extern int __pmAccSaveUsers(void);
+extern int __pmAccSaveGroups(void);
+extern int __pmAccSaveLists(void);
+
+extern int __pmAccRestoreHosts(void);
+extern int __pmAccRestoreUsers(void);
+extern int __pmAccRestoreGroups(void);
+extern int __pmAccRestoreLists(void);
+
+extern void __pmAccFreeSavedHosts(void);
+extern void __pmAccFreeSavedUsers(void);
+extern void __pmAccFreeSavedGroups(void);
+extern void __pmAccFreeSavedLists(void);
+
+/*
+ * platform independent process routines
+ */
+extern int __pmProcessExists(pid_t);
+extern int __pmProcessTerminate(pid_t, int);
+extern pid_t __pmProcessCreate(char **, int *, int *);
+extern int __pmProcessDataSize(unsigned long *);
+extern int __pmProcessRunTimes(double *, double *);
+extern int __pmSetProcessIdentity(const char *);
+
+/*
+ * platform independent memory mapped file handling
+ */
+extern void *__pmMemoryMap(int, size_t, int);
+extern void __pmMemoryUnmap(void *, size_t);
+
+/*
+ * platform independent signal handling
+ */
+typedef void (*__pmSignalHandler)(int);
+extern int __pmSetSignalHandler(int, __pmSignalHandler);
+
+/*
+ * platform independent environment and filesystem path access
+ */
+typedef void (*__pmConfigCallback)(char *, char *, char *);
+EXTERN const __pmConfigCallback __pmNativeConfig;
+extern void __pmConfig(__pmConfigCallback);
+extern char *__pmNativePath(char *);
+extern int __pmAbsolutePath(char *);
+extern int __pmPathSeparator(void);
+extern int __pmMakePath(const char *, mode_t);
+
+/*
+ * discover configurable features of the shared libraries
+ */
+typedef void (*__pmAPIConfigCallback)(const char *, const char *);
+extern void __pmAPIConfig(__pmAPIConfigCallback);
+extern const char *__pmGetAPIConfig(const char *);
+
+/*
+ * internals of argument parsing for special circumstances
+ */
+extern void __pmStartOptions(pmOptions *);
+extern void __pmAddOptArchive(pmOptions *, char *);
+extern void __pmAddOptArchiveList(pmOptions *, char *);
+extern void __pmAddOptArchiveFolio(pmOptions *, char *);
+extern void __pmAddOptHost(pmOptions *, char *);
+extern void __pmAddOptHostList(pmOptions *, char *);
+extern void __pmEndOptions(pmOptions *);
+
+/*
+ * AF - general purpose asynchronous event management routines
+ */
+extern int __pmAFregister(const struct timeval *, void *, void (*)(int, void *));
+extern int __pmAFunregister(int);
+extern void __pmAFblock(void);
+extern void __pmAFunblock(void);
+extern int __pmAFisempty(void);
+
+/*
+ * private PDU protocol between pmlc and pmlogger
+ */
+#define LOG_PDU_VERSION2 2 /* private pdus & PCP 2.0 error codes */
+#define LOG_PDU_VERSION LOG_PDU_VERSION2
+
+#define LOG_REQUEST_NEWVOLUME 1
+#define LOG_REQUEST_STATUS 2
+#define LOG_REQUEST_SYNC 3
+
+typedef struct {
+ __pmTimeval ls_start; /* start time for log */
+ __pmTimeval ls_last; /* last time log written */
+ __pmTimeval ls_timenow; /* current time */
+ int ls_state; /* state of log (from __pmLogCtl) */
+ int ls_vol; /* current volume number of log */
+ __int64_t ls_size; /* size of current volume */
+ char ls_hostname[PM_LOG_MAXHOSTLEN];
+ /* name of pmcd host */
+ char ls_fqdn[PM_LOG_MAXHOSTLEN];
+ /* fully qualified domain name of pmcd host */
+ char ls_tz[PM_TZ_MAXLEN];
+ /* $TZ at collection host */
+ char ls_tzlogger[PM_TZ_MAXLEN];
+ /* $TZ at pmlogger */
+} __pmLoggerStatus;
+
+#define PDU_LOG_CONTROL 0x8000
+#define PDU_LOG_STATUS 0x8001
+#define PDU_LOG_REQUEST 0x8002
+
+extern int __pmConnectLogger(const char *, int *, int *);
+extern int __pmSendLogControl(int, const pmResult *, int, int, int);
+extern int __pmDecodeLogControl(const __pmPDU *, pmResult **, int *, int *, int *);
+extern int __pmSendLogRequest(int, int);
+extern int __pmDecodeLogRequest(const __pmPDU *, int *);
+extern int __pmSendLogStatus(int, __pmLoggerStatus *);
+extern int __pmDecodeLogStatus(__pmPDU *, __pmLoggerStatus **);
+
+/* logger timeout helper function */
+extern int __pmLoggerTimeout(void);
+
+/*
+ * other interfaces shared by pmlc and pmlogger
+ */
+
+extern int __pmControlLog(int, const pmResult *, int, int, int, pmResult **);
+
+#define PM_LOG_OFF 0 /* state */
+#define PM_LOG_MAYBE 1
+#define PM_LOG_ON 2
+
+#define PM_LOG_MANDATORY 11 /* control */
+#define PM_LOG_ADVISORY 12
+#define PM_LOG_ENQUIRE 13
+
+/* macros for logging control values from __pmControlLog() */
+#define PMLC_SET_ON(val, flag) \
+ (val) = ((val) & ~0x1) | ((flag) & 0x1)
+#define PMLC_GET_ON(val) \
+ ((val) & 0x1)
+#define PMLC_SET_MAND(val, flag) \
+ (val) = ((val) & ~0x2) | (((flag) & 0x1) << 1)
+#define PMLC_GET_MAND(val) \
+ (((val) & 0x2) >> 1)
+#define PMLC_SET_AVAIL(val, flag) \
+ (val) = ((val) & ~0x4) | (((flag) & 0x1) << 2)
+#define PMLC_GET_AVAIL(val) \
+ (((val) & 0x4) >> 2)
+#define PMLC_SET_INLOG(val, flag) \
+ (val) = ((val) & ~0x8) | (((flag) & 0x1) << 3)
+#define PMLC_GET_INLOG(val) \
+ (((val) & 0x8) >> 3)
+
+#define PMLC_SET_STATE(val, state) \
+ (val) = ((val) & ~0xf) | ((state) & 0xf)
+#define PMLC_GET_STATE(val) \
+ ((val) & 0xf)
+
+/* 28 bits of delta, 32 bits of state */
+#define PMLC_MAX_DELTA 0x0fffffff
+
+#define PMLC_SET_DELTA(val, delta) \
+ (val) = ((val) & 0xf) | ((delta) << 4)
+#define PMLC_GET_DELTA(val) \
+ ((((val) & ~0xf) >> 4) & PMLC_MAX_DELTA)
+
+/*
+ * helper functions to register client identity with pmcd for export
+ * via pmcd.client.whoami
+ */
+extern char *__pmGetClientId(int, char **);
+extern int __pmSetClientIdArgv(int, char **);
+extern int __pmSetClientId(const char *);
+
+/*
+ * Adding/deleting/clearing the list of DSO PMDAs supported for
+ * PM_CONTEXT_LOCAL contexts
+ */
+#define PM_LOCAL_ADD 1
+#define PM_LOCAL_DEL 2
+#define PM_LOCAL_CLEAR 3
+extern int __pmLocalPMDA(int, int, const char *, const char *);
+extern char *__pmSpecLocalPMDA(const char *);
+
+/*
+ * Helper methods for packed arrays of event records
+ */
+extern int __pmCheckEventRecords(pmValueSet *, int);
+extern int __pmCheckHighResEventRecords(pmValueSet *, int);
+extern void __pmDumpEventRecords(FILE *, pmValueSet *, int);
+extern void __pmDumpHighResEventRecords(FILE *, pmValueSet *, int);
+
+/* Get nanosecond precision timestamp from system clocks */
+extern int __pmGetTimespec(struct timespec *);
+
+/* Anonymous metric registration (uses derived metrics support) */
+extern int __pmRegisterAnon(const char *, int);
+
+/*
+ * Multi-thread support
+ * Use PM_MULTI_THREAD_DEBUG for lock debugging with -Dlock[,appl?...]
+ */
+extern void __pmInitLocks(void);
+extern int __pmLock(void *, const char *, int);
+extern int __pmUnlock(void *, const char *, int);
+
+/*
+ * Each of these scopes defines one or more PMAPI routines that will
+ * not allow calls from more than one thread.
+ */
+#define PM_SCOPE_DSO_PMDA 0
+#define PM_SCOPE_ACL 1
+#define PM_SCOPE_AF 2
+#define PM_SCOPE_LOGPORT 3
+#define PM_SCOPE_MAX 3
+extern int __pmMultiThreaded(int);
+
+#define PM_INIT_LOCKS() __pmInitLocks()
+#define PM_MULTIPLE_THREADS(x) __pmMultiThreaded(x)
+#define PM_LOCK(lock) __pmLock(&(lock), __FILE__, __LINE__)
+#define PM_UNLOCK(lock) __pmUnlock(&(lock), __FILE__, __LINE__)
+
+#ifdef HAVE_PTHREAD_MUTEX_T
+extern pthread_mutex_t __pmLock_libpcp; /* big libpcp lock */
+#else
+extern void *__pmLock_libpcp; /* symbol exposure */
+#endif
+
+/*
+ * Service discovery with options.
+ * The 4th argument is a pointer to a mask of flags for boolean options
+ * and status. It is set and tested using the following bits.
+ */
+#define PM_SERVICE_DISCOVERY_INTERRUPTED 0x1
+#define PM_SERVICE_DISCOVERY_RESOLVE 0x2
+
+extern int __pmDiscoverServicesWithOptions(const char *,
+ const char *,
+ const char *,
+ const volatile unsigned *,
+ char ***);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IMPL_H */
diff --git a/src/include/pcp/import.h b/src/include/pcp/import.h
new file mode 100644
index 0000000..82b5be3
--- /dev/null
+++ b/src/include/pcp/import.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012-2013 Red Hat.
+ * Copyright (c) 2010 Ken McDonell. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef _IMPORT_H
+#define _IMPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* core libpcp_import API routines */
+extern int pmiStart(const char *, int);
+extern int pmiUseContext(int);
+extern int pmiEnd(void);
+extern int pmiSetHostname(const char *);
+extern int pmiSetTimezone(const char *);
+extern int pmiAddMetric(const char *, pmID, int, pmInDom, int, pmUnits);
+extern int pmiAddInstance(pmInDom, const char *, int);
+extern int pmiPutValue(const char *, const char *, const char *);
+extern int pmiGetHandle(const char *, const char *);
+extern int pmiPutValueHandle(int, const char *);
+extern int pmiWrite(int, int);
+extern int pmiPutResult(const pmResult *);
+
+/* helper routines */
+extern pmID pmiID(int, int, int);
+extern pmInDom pmiInDom(int, int);
+extern pmUnits pmiUnits(int, int, int, int, int, int);
+
+/* diagnostic routines */
+#define PMI_MAXERRMSGLEN 128 /* safe size to accomodate any error message */
+extern char *pmiErrStr_r(int, char *, int);
+extern const char *pmiErrStr(int); /* cannot ever be made thread-safe */
+extern void pmiDump(void);
+
+/* libpcp_import error codes */
+#define PMI_ERR_BASE 20000
+#define PMI_ERR_DUPMETRICNAME (-PMI_ERR_BASE-1) /* Metric name already defined */
+#define PMI_ERR_DUPMETRICID (-PMI_ERR_BASE-2) /* Metric pmID already defined */
+#define PMI_ERR_DUPINSTNAME (-PMI_ERR_BASE-3) /* External instance name already defined */
+#define PMI_ERR_DUPINSTID (-PMI_ERR_BASE-4) /* Internal instance identifer already defined */
+#define PMI_ERR_INSTNOTNULL (-PMI_ERR_BASE-5) /* Non-null instance expected for a singular metric */
+#define PMI_ERR_INSTNULL (-PMI_ERR_BASE-6) /* Null instance not allowed for a non-singular metric */
+#define PMI_ERR_BADHANDLE (-PMI_ERR_BASE-7) /* Illegal handle */
+#define PMI_ERR_DUPVALUE (-PMI_ERR_BASE-8) /* Value already assigned for singular metric */
+#define PMI_ERR_BADTYPE (-PMI_ERR_BASE-9) /* Illegal metric type */
+#define PMI_ERR_BADSEM (-PMI_ERR_BASE-10) /* Illegal metric semantics */
+#define PMI_ERR_NODATA (-PMI_ERR_BASE-11) /* No data to output */
+#define PMI_ERR_BADMETRICNAME (-PMI_ERR_BASE-12) /* Illegal metric name */
+#define PMI_ERR_BADTIMESTAMP (-PMI_ERR_BASE-13) /* Illegal result timestamp */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IMPORT_H */
diff --git a/src/include/pcp/mk_pmdbg b/src/include/pcp/mk_pmdbg
new file mode 100755
index 0000000..a234f3b
--- /dev/null
+++ b/src/include/pcp/mk_pmdbg
@@ -0,0 +1,58 @@
+#!/bin/sh
+#
+# Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# Create pmdbg.h from impl.h
+
+if [ -f ../pcp.conf ]
+then
+ # needed for $PCP_SORT_PROG
+ . ../pcp.conf
+else
+ echo "mk_pmdbg: cannot find pcp.conf"
+ exit 1
+fi
+
+if [ ! -f impl.h ]
+then
+ echo "mk_pmdbg: cannot find impl.h"
+ exit 1
+fi
+
+rm -f pmdbg.h
+cat <<End-of-File >pmdbg.h
+/*
+ * Built from impl.h by mk_pmdbg. Any modifications will be lost.
+ */
+
+typedef const struct {
+ const char *name;
+ const int bit;
+} debug_map_t;
+
+static const debug_map_t debug_map[] = {
+End-of-File
+
+sed -n <impl.h \
+ -e '/#define[ ]*DBG_TRACE_/{
+s/#define[ ]*\(DBG_TRACE_\)\([A-Z0-9_]*\).*/ { "\2", \1\2 },/p
+}' \
+| $PCP_SORT_PROG >>pmdbg.h
+
+cat <<End-of-File >>pmdbg.h
+};
+
+static const int num_debug = sizeof(debug_map) / sizeof(debug_map[0]);
+End-of-File
+
+exit 0
diff --git a/src/include/pcp/mmv_dev.h b/src/include/pcp/mmv_dev.h
new file mode 100644
index 0000000..92e3b8e
--- /dev/null
+++ b/src/include/pcp/mmv_dev.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2001,2009 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Aconex. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+#ifndef _MMV_DEV_H
+#define _MMV_DEV_H
+
+#define MMV_VERSION 1
+
+typedef enum {
+ MMV_TOC_INDOMS = 1, /* mmv_disk_indom_t */
+ MMV_TOC_INSTANCES = 2, /* mmv_disk_instance_t */
+ MMV_TOC_METRICS = 3, /* mmv_disk_metric_t */
+ MMV_TOC_VALUES = 4, /* mmv_disk_value_t */
+ MMV_TOC_STRINGS = 5, /* mmv_disk_string_t */
+} mmv_toc_type_t;
+
+/* The way the Table Of Contents is written into the file */
+typedef struct {
+ mmv_toc_type_t type; /* What is it? */
+ __int32_t count; /* Number of entries */
+ __uint64_t offset; /* Offset of section from file start */
+} mmv_disk_toc_t;
+
+typedef struct {
+ __uint32_t serial; /* Unique identifier */
+ __uint32_t count; /* Number of instances */
+ __uint64_t offset; /* Offset of first instance */
+ __uint64_t shorttext; /* Offset of short help text string */
+ __uint64_t helptext; /* Offset of long help text string */
+} mmv_disk_indom_t;
+
+typedef struct {
+ __uint64_t indom; /* Offset into files indom section */
+ __uint32_t padding; /* zero filled, alignment bits */
+ __int32_t internal; /* Internal instance ID */
+ char external[MMV_NAMEMAX]; /* External instance ID */
+} mmv_disk_instance_t;
+
+typedef struct {
+ char payload[MMV_STRINGMAX]; /* NULL terminated string */
+} mmv_disk_string_t;
+
+typedef struct {
+ char name[MMV_NAMEMAX];
+ __uint32_t item; /* Unique identifier */
+ mmv_metric_type_t type;
+ mmv_metric_sem_t semantics;
+ pmUnits dimension;
+ __int32_t indom; /* Instance domain number */
+ __uint32_t padding; /* zero filled, alignment bits */
+ __uint64_t shorttext; /* Offset of short help text string */
+ __uint64_t helptext; /* Offset of long help text string */
+} mmv_disk_metric_t;
+
+typedef struct {
+ pmAtomValue value; /* Union of all possible value types */
+ __int64_t extra; /* INTEGRAL(starttime)/STRING(offset) */
+ __uint64_t metric; /* Offset into the metric section */
+ __uint64_t instance; /* Offset into the instance section */
+} mmv_disk_value_t;
+
+typedef struct {
+ char magic[4]; /* MMV\0 */
+ __int32_t version; /* version */
+ __uint64_t g1; /* Generation numbers */
+ __uint64_t g2;
+ __int32_t tocs; /* Number of toc entries */
+ mmv_stats_flags_t flags;
+ __int32_t process; /* client process identifier (flags) */
+ __int32_t cluster; /* preferred PMDA cluster identifier */
+} mmv_disk_header_t;
+
+#endif /* _MMV_DEV_H */
diff --git a/src/include/pcp/mmv_stats.h b/src/include/pcp/mmv_stats.h
new file mode 100644
index 0000000..12f53d7
--- /dev/null
+++ b/src/include/pcp/mmv_stats.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Red Hat.
+ * Copyright (C) 2009 Aconex. All Rights Reserved.
+ * Copyright (C) 2001,2009 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+#ifndef _MMV_STATS_H
+#define _MMV_STATS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MMV_NAMEMAX 64
+#define MMV_STRINGMAX 256
+
+typedef enum mmv_metric_type {
+ MMV_TYPE_NOSUPPORT = PM_TYPE_NOSUPPORT,
+ MMV_TYPE_I32 = PM_TYPE_32, /* 32-bit signed integer */
+ MMV_TYPE_U32 = PM_TYPE_U32, /* 32-bit unsigned integer */
+ MMV_TYPE_I64 = PM_TYPE_64, /* 64-bit signed integer */
+ MMV_TYPE_U64 = PM_TYPE_U64, /* 64-bit unsigned integer */
+ MMV_TYPE_FLOAT = PM_TYPE_FLOAT, /* 32-bit floating point */
+ MMV_TYPE_DOUBLE = PM_TYPE_DOUBLE,/* 64-bit floating point */
+ MMV_TYPE_STRING = PM_TYPE_STRING,/* NULL-terminate string */
+ MMV_TYPE_ELAPSED = 9, /* 64-bit elapsed time */
+} mmv_metric_type_t;
+
+typedef enum mmv_metric_sem {
+ MMV_SEM_COUNTER = PM_SEM_COUNTER,
+ MMV_SEM_INSTANT = PM_SEM_INSTANT,
+ MMV_SEM_DISCRETE = PM_SEM_DISCRETE,
+} mmv_metric_sem_t;
+
+typedef struct mmv_instances {
+ __int32_t internal; /* Internal instance ID */
+ char external[MMV_NAMEMAX]; /* External instance ID */
+} mmv_instances_t;
+
+typedef struct mmv_indom {
+ __uint32_t serial; /* Unique identifier */
+ __uint32_t count; /* Number of instances */
+ mmv_instances_t * instances; /* Internal/external IDs */
+ char * shorttext; /* Short help text string */
+ char * helptext; /* Long help text string */
+} mmv_indom_t;
+
+typedef struct mmv_metric {
+ char name[MMV_NAMEMAX];
+ __uint32_t item; /* Unique identifier */
+ mmv_metric_type_t type;
+ mmv_metric_sem_t semantics;
+ pmUnits dimension;
+ __uint32_t indom; /* Indom serial */
+ char * shorttext; /* Short help text string */
+ char * helptext; /* Long help text string */
+} mmv_metric_t;
+
+#ifdef HAVE_BITFIELDS_LTOR
+#define MMV_UNITS(a,b,c,d,e,f) {a,b,c,d,e,f,0}
+#else
+#define MMV_UNITS(a,b,c,d,e,f) {0,f,e,d,c,b,a}
+#endif
+
+typedef enum mmv_stats_flags {
+ MMV_FLAG_NOPREFIX = 0x1, /* Don't prefix metric names by filename */
+ MMV_FLAG_PROCESS = 0x2, /* Indicates process check on PID needed */
+} mmv_stats_flags_t;
+
+extern void * mmv_stats_init(const char *, int, mmv_stats_flags_t,
+ const mmv_metric_t *, int,
+ const mmv_indom_t *, int);
+extern void mmv_stats_stop(const char *, void *);
+
+extern pmAtomValue * mmv_lookup_value_desc(void *, const char *, const char *);
+extern void mmv_inc_value(void *, pmAtomValue *, double);
+extern void mmv_set_value(void *, pmAtomValue *, double);
+extern void mmv_set_string(void *, pmAtomValue *, const char *, int);
+
+extern void mmv_stats_add(void *, const char *, const char *, double);
+extern void mmv_stats_inc(void *, const char *, const char *);
+extern void mmv_stats_set(void *, const char *, const char *, double);
+extern void mmv_stats_add_fallback(void *, const char *, const char *,
+ const char *, double);
+extern void mmv_stats_inc_fallback(void *, const char *, const char *,
+ const char *);
+extern pmAtomValue * mmv_stats_interval_start(void *, pmAtomValue *,
+ const char *, const char *);
+extern void mmv_stats_interval_end(void *, pmAtomValue *);
+extern void mmv_stats_set_string(void *, const char *,
+ const char *, const char *);
+extern void mmv_stats_set_strlen(void *, const char *,
+ const char *, const char *, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MMV_STATS_H */
diff --git a/src/include/pcp/platform_defs.h.in b/src/include/pcp/platform_defs.h.in
new file mode 100644
index 0000000..091657e
--- /dev/null
+++ b/src/include/pcp/platform_defs.h.in
@@ -0,0 +1,13 @@
+/*
+ * @configure_input@
+ */
+#ifndef _PCP_PLATFORM_DEFS_H
+#define _PCP_PLATFORM_DEFS_H
+
+#include "config.h"
+
+/* printf candy ... */
+#define FMT_PID @fmt_pid@
+#define FMT_PTHREAD @fmt_pthread@
+
+#endif /* _PCP_PLATFORM_DEFS_H */
diff --git a/src/include/pcp/pmafm.h b/src/include/pcp/pmafm.h
new file mode 100644
index 0000000..d1330e5
--- /dev/null
+++ b/src/include/pcp/pmafm.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+
+#ifndef _PMAFM_H
+#define _PMAFM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Recording session support
+ */
+#define PM_REC_ON 40
+#define PM_REC_OFF 41
+#define PM_REC_DETACH 43
+#define PM_REC_STATUS 44
+#define PM_REC_SETARG 45
+
+typedef struct {
+ FILE *f_config; /* caller writes pmlogger configuration here */
+ int fd_ipc; /* IPC channel to pmlogger */
+ char *logfile; /* full pathname for pmlogger error logfile */
+ pid_t pid; /* process id for pmlogger */
+ int status; /* exit status, -1 if unknown */
+} pmRecordHost;
+
+extern FILE *pmRecordSetup(const char *, const char *, int);
+extern int pmRecordAddHost(const char *, int, pmRecordHost **);
+extern int pmRecordControl(pmRecordHost *, int, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PMAFM_H */
diff --git a/src/include/pcp/pmapi.h b/src/include/pcp/pmapi.h
new file mode 100644
index 0000000..be4b45e
--- /dev/null
+++ b/src/include/pcp/pmapi.h
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2012-2014 Red Hat.
+ * Copyright (c) 1997,2004 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _PMAPI_H
+#define _PMAPI_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+
+/*
+ * Platform and environment customization
+ */
+#include "platform_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PMAPI_VERSION_2 2
+#define PMAPI_VERSION PMAPI_VERSION_2
+
+/*
+ * -------- Naming Services --------
+ */
+typedef unsigned int pmID; /* Metric Identifier */
+#define PM_ID_NULL 0xffffffff
+
+typedef unsigned int pmInDom; /* Instance-Domain */
+#define PM_INDOM_NULL 0xffffffff
+#define PM_IN_NULL 0xffffffff
+
+#define PM_NS_DEFAULT NULL /* default name */
+
+/*
+ * Encoding for the units (dimensions Time and Space) and scale
+ * for Performance Metric Values
+ *
+ * For example, a pmUnits struct of
+ * { 1, -1, 0, PM_SPACE_MBYTE, PM_TIME_SEC, 0 }
+ * represents Mbytes/sec, while
+ * { 0, 1, -1, 0, PM_TIME_HOUR, 6 }
+ * represents hours/million-events
+ */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ signed int dimSpace : 4; /* space dimension */
+ signed int dimTime : 4; /* time dimension */
+ signed int dimCount : 4; /* event dimension */
+ unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */
+ unsigned int scaleTime : 4; /* one of PM_TIME_* below */
+ signed int scaleCount : 4; /* one of PM_COUNT_* below */
+ unsigned int pad : 8;
+#else
+ unsigned int pad : 8;
+ signed int scaleCount : 4; /* one of PM_COUNT_* below */
+ unsigned int scaleTime : 4; /* one of PM_TIME_* below */
+ unsigned int scaleSpace : 4; /* one of PM_SPACE_* below */
+ signed int dimCount : 4; /* event dimension */
+ signed int dimTime : 4; /* time dimension */
+ signed int dimSpace : 4; /* space dimension */
+#endif
+} pmUnits; /* dimensional units and scale of value */
+
+/* pmUnits.scaleSpace */
+#define PM_SPACE_BYTE 0 /* bytes */
+#define PM_SPACE_KBYTE 1 /* Kilobytes (1024) */
+#define PM_SPACE_MBYTE 2 /* Megabytes (1024^2) */
+#define PM_SPACE_GBYTE 3 /* Gigabytes (1024^3) */
+#define PM_SPACE_TBYTE 4 /* Terabytes (1024^4) */
+#define PM_SPACE_PBYTE 5 /* Petabytes (1024^5) */
+#define PM_SPACE_EBYTE 6 /* Exabytes (1024^6) */
+/* pmUnits.scaleTime */
+#define PM_TIME_NSEC 0 /* nanoseconds */
+#define PM_TIME_USEC 1 /* microseconds */
+#define PM_TIME_MSEC 2 /* milliseconds */
+#define PM_TIME_SEC 3 /* seconds */
+#define PM_TIME_MIN 4 /* minutes */
+#define PM_TIME_HOUR 5 /* hours */
+/*
+ * pmUnits.scaleCount (e.g. count events, syscalls, interrupts, etc.)
+ * -- these are simply powers of 10, and not enumerated here,
+ * e.g. 6 for 10^6, or -3 for 10^-3
+ */
+#define PM_COUNT_ONE 0 /* 1 */
+
+/* Performance Metric Descriptor */
+typedef struct {
+ pmID pmid; /* unique identifier */
+ int type; /* base data type (see below) */
+ pmInDom indom; /* instance domain */
+ int sem; /* semantics of value (see below) */
+ pmUnits units; /* dimension and units */
+} pmDesc;
+
+/* pmDesc.type -- data type of metric values */
+#define PM_TYPE_NOSUPPORT -1 /* not implemented in this version */
+#define PM_TYPE_32 0 /* 32-bit signed integer */
+#define PM_TYPE_U32 1 /* 32-bit unsigned integer */
+#define PM_TYPE_64 2 /* 64-bit signed integer */
+#define PM_TYPE_U64 3 /* 64-bit unsigned integer */
+#define PM_TYPE_FLOAT 4 /* 32-bit floating point */
+#define PM_TYPE_DOUBLE 5 /* 64-bit floating point */
+#define PM_TYPE_STRING 6 /* array of char */
+#define PM_TYPE_AGGREGATE 7 /* arbitrary binary data (aggregate) */
+#define PM_TYPE_AGGREGATE_STATIC 8 /* static pointer to aggregate */
+#define PM_TYPE_EVENT 9 /* packed pmEventArray */
+#define PM_TYPE_HIGHRES_EVENT 10 /* packed pmHighResEventArray */
+#define PM_TYPE_UNKNOWN 255 /* used in pmValueBlock, not pmDesc */
+
+/* pmDesc.sem -- semantics/interpretation of metric values */
+#define PM_SEM_COUNTER 1 /* cumulative counter (monotonic increasing) */
+ /* was PM_SEM_RATE, no longer used now */
+#define PM_SEM_INSTANT 3 /* instantaneous value, continuous domain */
+#define PM_SEM_DISCRETE 4 /* instantaneous value, discrete domain */
+
+#define PM_ERR_BASE2 12345
+#define PM_ERR_BASE PM_ERR_BASE2
+
+/* PMAPI Error Conditions */
+
+#define PM_ERR_GENERIC (-PM_ERR_BASE-0) /* Generic error, already reported above */
+#define PM_ERR_PMNS (-PM_ERR_BASE-1) /* Problems parsing PMNS definitions */
+#define PM_ERR_NOPMNS (-PM_ERR_BASE-2) /* PMNS not accessible */
+#define PM_ERR_DUPPMNS (-PM_ERR_BASE-3) /* Attempt to reload the PMNS */
+#define PM_ERR_TEXT (-PM_ERR_BASE-4) /* Oneline or help text is not available */
+#define PM_ERR_APPVERSION (-PM_ERR_BASE-5) /* Metric not supported by this version of monitored application */
+#define PM_ERR_VALUE (-PM_ERR_BASE-6) /* Missing metric value(s) */
+/* retired PM_ERR_LICENSE (-PM_ERR_BASE-7) Current PCP license does not permit this operation */
+#define PM_ERR_TIMEOUT (-PM_ERR_BASE-8) /* Timeout waiting for a response from PMCD */
+#define PM_ERR_NODATA (-PM_ERR_BASE-9) /* Empty archive log file */
+#define PM_ERR_RESET (-PM_ERR_BASE-10) /* pmcd reset or configuration changed */
+/* retired PM_ERR_FILE (-PM_ERR_BASE-11) Cannot locate a file */
+#define PM_ERR_NAME (-PM_ERR_BASE-12) /* Unknown metric name */
+#define PM_ERR_PMID (-PM_ERR_BASE-13) /* Unknown or illegal metric identifier */
+#define PM_ERR_INDOM (-PM_ERR_BASE-14) /* Unknown or illegal instance domain identifier */
+#define PM_ERR_INST (-PM_ERR_BASE-15) /* Unknown or illegal instance identifier */
+#define PM_ERR_UNIT (-PM_ERR_BASE-16) /* Illegal pmUnits specification */
+#define PM_ERR_CONV (-PM_ERR_BASE-17) /* Impossible value or scale conversion */
+#define PM_ERR_TRUNC (-PM_ERR_BASE-18) /* Truncation in value conversion */
+#define PM_ERR_SIGN (-PM_ERR_BASE-19) /* Negative value in conversion to unsigned */
+#define PM_ERR_PROFILE (-PM_ERR_BASE-20) /* Explicit instance identifier(s) required */
+#define PM_ERR_IPC (-PM_ERR_BASE-21) /* IPC protocol failure */
+/* retired PM_ERR_NOASCII (-PM_ERR_BASE-22) ASCII format not supported for this PDU */
+#define PM_ERR_EOF (-PM_ERR_BASE-23) /* IPC channel closed */
+#define PM_ERR_NOTHOST (-PM_ERR_BASE-24) /* Operation requires context with host source of metrics */
+#define PM_ERR_EOL (-PM_ERR_BASE-25) /* End of PCP archive log */
+#define PM_ERR_MODE (-PM_ERR_BASE-26) /* Illegal mode specification */
+#define PM_ERR_LABEL (-PM_ERR_BASE-27) /* Illegal label record at start of a PCP archive log file */
+#define PM_ERR_LOGREC (-PM_ERR_BASE-28) /* Corrupted record in a PCP archive log */
+#define PM_ERR_NOTARCHIVE (-PM_ERR_BASE-29) /* Operation requires context with archive source of metrics */
+#define PM_ERR_LOGFILE (-PM_ERR_BASE-30) /* Missing archive file */
+#define PM_ERR_NOCONTEXT (-PM_ERR_BASE-31) /* Attempt to use an illegal context */
+#define PM_ERR_PROFILESPEC (-PM_ERR_BASE-32) /* NULL pmInDom with non-NULL instlist */
+#define PM_ERR_PMID_LOG (-PM_ERR_BASE-33) /* Metric not defined in the PCP archive log */
+#define PM_ERR_INDOM_LOG (-PM_ERR_BASE-34) /* Instance domain identifier not defined in the PCP archive log */
+#define PM_ERR_INST_LOG (-PM_ERR_BASE-35) /* Instance identifier not defined in the PCP archive log */
+#define PM_ERR_NOPROFILE (-PM_ERR_BASE-36) /* Missing profile - protocol botch */
+#define PM_ERR_NOAGENT (-PM_ERR_BASE-41) /* No pmcd agent for domain of request */
+#define PM_ERR_PERMISSION (-PM_ERR_BASE-42) /* No permission to perform requested operation */
+#define PM_ERR_CONNLIMIT (-PM_ERR_BASE-43) /* PMCD connection limit for this host exceeded */
+#define PM_ERR_AGAIN (-PM_ERR_BASE-44) /* try again. Info not currently available */
+#define PM_ERR_ISCONN (-PM_ERR_BASE-45) /* already connected */
+#define PM_ERR_NOTCONN (-PM_ERR_BASE-46) /* not connected */
+#define PM_ERR_NEEDPORT (-PM_ERR_BASE-47) /* port name required */
+/* retired PM_ERR_WANTACK (-PM_ERR_BASE-48) can not send due to pending acks */
+#define PM_ERR_NONLEAF (-PM_ERR_BASE-49) /* PMNS node is not a leaf node */
+/* retired PM_ERR_OBJSTYLE (-PM_ERR_BASE-50) user/kernel object style mismatch */
+/* retired PM_ERR_PMCDLICENSE (-PM_ERR_BASE-51) PMCD is not licensed to accept connections */
+#define PM_ERR_TYPE (-PM_ERR_BASE-52) /* Unknown or illegal metric type */
+#define PM_ERR_THREAD (-PM_ERR_BASE-53) /* Operation not supported for multi-threaded applications */
+
+/* retired PM_ERR_CTXBUSY (-PM_ERR_BASE-97) Context is busy */
+#define PM_ERR_TOOSMALL (-PM_ERR_BASE-98) /* Insufficient elements in list */
+#define PM_ERR_TOOBIG (-PM_ERR_BASE-99) /* Result size exceeded */
+#define PM_ERR_FAULT (-PM_ERR_BASE-100) /* QA fault injected */
+
+#define PM_ERR_PMDAREADY (-PM_ERR_BASE-1048) /* now ready to respond */
+#define PM_ERR_PMDANOTREADY (-PM_ERR_BASE-1049) /* not yet ready to respond */
+#define PM_ERR_NYI (-PM_ERR_BASE-8999) /* Functionality not yet implemented [end-of-range mark] */
+
+/*
+ * Report PMAPI errors messages
+ */
+extern char *pmErrStr(int); /* NOT thread-safe */
+extern char *pmErrStr_r(int, char *, int);
+/* safe size for a pmErrStr_r buffer to accommodate all error messages */
+#define PM_MAXERRMSGLEN 128
+
+/*
+ * Load a Performance Metrics Name Space
+ */
+extern int pmLoadNameSpace(const char *);
+extern int pmLoadASCIINameSpace(const char *, int);
+extern void pmUnloadNameSpace(void);
+
+/*
+ * Where is PMNS located - added for distributed PMNS.
+ */
+extern int pmGetPMNSLocation(void);
+#define PMNS_LOCAL 1
+#define PMNS_REMOTE 2
+#define PMNS_ARCHIVE 3
+
+/*
+ * Trim a name space with respect to the current context
+ * (usually from an archive, or after processing an archive)
+ */
+extern int pmTrimNameSpace(void);
+
+/*
+ * Expand a list of names to a list of metrics ids
+ */
+extern int pmLookupName(int, char **, pmID *);
+
+/*
+ * Find the names of descendent nodes in the PMNS
+ * and in the latter case get the status of each child.
+ */
+extern int pmGetChildren(const char *, char ***);
+extern int pmGetChildrenStatus(const char *, char ***, int **);
+#define PMNS_LEAF_STATUS 0 /* leaf node in PMNS tree */
+#define PMNS_NONLEAF_STATUS 1 /* non-terminal node in PMNS tree */
+
+/*
+ * Reverse Lookup: find name(s) given a metric id
+ */
+extern int pmNameID(pmID, char **); /* one */
+extern int pmNameAll(pmID, char ***); /* all */
+
+/*
+ * Handy recursive descent of the PMNS
+ */
+extern int pmTraversePMNS(const char *, void(*)(const char *));
+extern int pmTraversePMNS_r(const char *, void(*)(const char *, void *), void *);
+
+/*
+ * Given a metric, find it's descriptor (caller supplies buffer for desc),
+ * from the current context.
+ */
+extern int pmLookupDesc(pmID, pmDesc *);
+
+/*
+ * Return the internal instance identifier, from the current context,
+ * given an instance domain and the external instance name.
+ * Archive variant scans the union of the indom entries in the archive
+ * log.
+ */
+extern int pmLookupInDom(pmInDom, const char *);
+extern int pmLookupInDomArchive(pmInDom, const char *);
+
+/*
+ * Return the external instance name, from the current context,
+ * given an instance domain and the internal instance identifier.
+ * Archive variant scans the union of the indom entries in the archive
+ * log.
+ */
+extern int pmNameInDom(pmInDom, int, char **);
+extern int pmNameInDomArchive(pmInDom, int, char **);
+
+/*
+ * Return all of the internal instance identifiers (instlist) and external
+ * instance names (namelist) for the given instance domain in the current
+ * context.
+ * Archive variant returns the union of the indom entries in the archive
+ * log.
+ */
+extern int pmGetInDom(pmInDom, int **, char ***);
+extern int pmGetInDomArchive(pmInDom, int **, char ***);
+
+/*
+ * Given context ID, return the host name associated with that context,
+ * or the empty string if no name can be found
+ */
+extern const char *pmGetContextHostName(int);
+extern char *pmGetContextHostName_r(int, char *, int);
+
+/*
+ * Return the handle of the current context
+ */
+extern int pmWhichContext(void);
+
+/*
+ * Destroy a context and close its connection
+ */
+extern int pmDestroyContext(int);
+
+/*
+ * Establish a new context (source of performance data + instance profile)
+ * for the named host
+ */
+extern int pmNewContext(int, const char *);
+#define PM_CONTEXT_UNDEF -1 /* current context is undefined */
+#define PM_CONTEXT_HOST 1 /* host via pmcd */
+#define PM_CONTEXT_ARCHIVE 2 /* PCP archive */
+#define PM_CONTEXT_LOCAL 3 /* local host, no pmcd connection */
+#define PM_CONTEXT_TYPEMASK 0xff /* mask to separate types / flags */
+/* #define PM_CTXFLAG_SHALLOW (1U<<8) -- don't actually connect to host */
+/* #define PM_CTXFLAG_EXCLUSIVE (1U<<9) -- don't share socket among ctxts */
+#define PM_CTXFLAG_SECURE (1U<<10)/* encrypted socket comms channel */
+#define PM_CTXFLAG_COMPRESS (1U<<11)/* compressed socket host channel */
+#define PM_CTXFLAG_RELAXED (1U<<12)/* encrypted if possible else not */
+#define PM_CTXFLAG_AUTH (1U<<13)/* make authenticated connection */
+
+/*
+ * Duplicate current context -- returns handle to new one for pmUseContext()
+ */
+extern int pmDupContext(void);
+
+/*
+ * Restore (previously established or duplicated) context
+ */
+extern int pmUseContext(int);
+
+/*
+ * Reconnect an existing context (when pmcd dies, etc). All existing context
+ * settings are preserved and the previous context settings are restored.
+ */
+extern int pmReconnectContext(int);
+
+/*
+ * Add to instance profile.
+ * If pmInDom == PM_INDOM_NULL, then all instance domains are selected.
+ * If no inst parameters are given, then all instances are selected.
+ * e.g. to select all available instances in all domains,
+ * then use pmAddProfile(PM_INDOM_NULL, 0, NULL).
+ */
+extern int pmAddProfile(pmInDom, int, int *);
+
+/*
+ * Delete from instance profile.
+ * Similar (but negated) functional semantics to pmProfileAdd.
+ * E.g. to disable all instances in all domains then use
+ * pmDelProfile(PM_INDOM_NULL, 0, NULL).
+ */
+extern int pmDelProfile(pmInDom, int, int *);
+
+/*
+ * ---------- Collection services ----------
+ *
+ * Result from pmFetch is encoded as a timestamp and vector of pointers
+ * to pmValueSet instances (one per PMID in the result).
+ * Each pmValueSet has a PMID, a value count, a value format, and a vector of
+ * instance-value pairs. Aggregate, string and non-int values are returned
+ * via one further level of indirection using pmValueBlocks.
+ *
+ * timeStamp
+ * ->pmID
+ * value format
+ * instance, value
+ * instance, value
+ * ... etc
+ *
+ * ->pmID
+ * value format
+ * instance, value
+ * ... etc
+ *
+ *
+ * Notes on pmValueBlock
+ * 0. may be used for arbitrary binary data
+ * 1. only ever allocated dynamically, and vbuf expands to accommodate
+ * an arbitrary value (don't believe the [1] size!)
+ * 2. len is the length of the len field + the real size of vbuf
+ * (which includes the null-byte terminator if there is one)
+ */
+typedef struct {
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int vtype : 8; /* value type */
+ unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */
+#else
+ unsigned int vlen : 24; /* bytes for vtype/vlen + vbuf */
+ unsigned int vtype : 8; /* value type */
+#endif
+ char vbuf[1]; /* the value */
+} pmValueBlock;
+
+#define PM_VAL_HDR_SIZE 4 /* bytes for the vtype/vlen header */
+#define PM_VAL_VLEN_MAX 0x00ffffff /* maximum vbuf[] size */
+
+typedef struct {
+ int inst; /* instance identifier */
+ union {
+ pmValueBlock *pval; /* pointer to value-block */
+ int lval; /* integer value insitu (lval 'cuz it WAS a long) */
+ } value;
+} pmValue;
+
+typedef struct {
+ pmID pmid; /* metric identifier */
+ int numval; /* number of values */
+ int valfmt; /* value style */
+ pmValue vlist[1]; /* set of instances/values */
+} pmValueSet;
+
+/* values for valfmt */
+#define PM_VAL_INSITU 0 /* value.lval is it */
+#define PM_VAL_DPTR 1 /* value.pval->vbuf is it, and dynamic alloc */
+#define PM_VAL_SPTR 2 /* value.pval->vbuf is it, and static alloc */
+
+
+/* Result returned by pmFetch() */
+typedef struct {
+ struct timeval timestamp; /* time stamped by collector */
+ int numpmid; /* number of PMIDs */
+ pmValueSet *vset[1]; /* set of value sets, one per PMID */
+} pmResult;
+
+/* High resolution event timer result from pmUnpackHighResEventRecords() */
+typedef struct {
+ struct timespec timestamp; /* time stamped by collector */
+ int numpmid; /* number of PMIDs */
+ pmValueSet *vset[1]; /* set of value sets, one per PMID */
+} pmHighResResult;
+
+/* Generic Union for Value-Type conversions */
+typedef union {
+ __int32_t l; /* 32-bit signed */
+ __uint32_t ul; /* 32-bit unsigned */
+ __int64_t ll; /* 64-bit signed */
+ __uint64_t ull; /* 64-bit unsigned */
+ float f; /* 32-bit floating point */
+ double d; /* 64-bit floating point */
+ char *cp; /* char ptr */
+ pmValueBlock *vbp; /* pmValueBlock ptr */
+} pmAtomValue;
+
+/*
+ * Fetch metrics. Value/instances returned depends on current instance profile.
+ * By default, all available instances for each requested metric id are
+ * returned. The metrics argument is terminated with PM_NULL_ID
+ *
+ * The value sets returned are in the same order as the metrics argument,
+ * and the number of value sets returned is guaranteed to be the same as
+ * the number of metrics in the agument.
+ */
+extern int pmFetch(int, pmID *, pmResult **);
+
+/*
+ * PMCD state changes returned as pmFetch function result for PM_CONTEXT_HOST
+ * contexts, i.e. when communicating with PMCD
+ */
+#define PMCD_NO_CHANGE 0
+#define PMCD_ADD_AGENT 1
+#define PMCD_RESTART_AGENT 2
+#define PMCD_DROP_AGENT 4
+
+/*
+ * Variant that is used to return a pmResult from an archive
+ */
+extern int pmFetchArchive(pmResult **);
+
+/*
+ * struct timeval is sometimes 2 x 64-bit ... we use a 2 x 32-bit format for
+ * PDUs, internally within libpcp and for (external) archive logs
+ */
+typedef struct {
+ __int32_t tv_sec; /* seconds since Jan. 1, 1970 */
+ __int32_t tv_usec; /* and microseconds */
+} __pmTimeval;
+
+typedef struct {
+ __int64_t tv_sec; /* seconds since Jan. 1, 1970 */
+ __int64_t tv_nsec; /* and nanoseconds */
+} __pmTimespec;
+
+/*
+ * Label Record at the start of every log file - as exported above
+ * the PMAPI ...
+ * NOTE MAXHOSTNAMELEN is a bad choice here for ll_hostname[], as
+ * it may vary on different hosts ... we use PM_LOG_MAXHOSTLEN instead, and
+ * size this to be the same as MAXHOSTNAMELEN in IRIX 5.3
+ * NOTE that the struct timeval means we have another struct (__pmLogLabel)
+ * for internal use that has a __pmTimeval in place of the struct timeval.
+ */
+#define PM_TZ_MAXLEN 40
+#define PM_LOG_MAXHOSTLEN 64
+#define PM_LOG_MAGIC 0x50052600
+#define PM_LOG_VERS02 0x2
+#define PM_LOG_VOL_TI -2 /* temporal index */
+#define PM_LOG_VOL_META -1 /* meta data */
+typedef struct {
+ int ll_magic; /* PM_LOG_MAGIC | log format version no. */
+ pid_t ll_pid; /* PID of logger */
+ struct timeval ll_start; /* start of this log */
+ char ll_hostname[PM_LOG_MAXHOSTLEN]; /* name of collection host */
+ char ll_tz[PM_TZ_MAXLEN]; /* $TZ at collection host */
+} pmLogLabel;
+
+/*
+ * Get the label record from the current archive context, and discover
+ * when the archive ends
+ */
+extern int pmGetArchiveLabel(pmLogLabel *);
+extern int pmGetArchiveEnd(struct timeval *);
+
+/* Free result buffer */
+extern void pmFreeResult(pmResult *);
+extern void pmFreeHighResResult(pmHighResResult *);
+
+/* Value extract from pmValue and type conversion */
+extern int pmExtractValue(int, const pmValue *, int, pmAtomValue *, int);
+
+/* Print single pmValue */
+extern void pmPrintValue(FILE *, int, int, const pmValue *, int);
+
+/* Scale conversion, based on value format, value type and scale */
+extern int pmConvScale(int, const pmAtomValue *, const pmUnits *, pmAtomValue *,
+ const pmUnits *);
+
+/* Sort instances for each metric within a pmResult */
+extern void pmSortInstances(pmResult *);
+
+/* Adjust collection time and/or mode for pmFetch */
+extern int pmSetMode(int, const struct timeval *, int);
+#define PM_MODE_LIVE 0
+#define PM_MODE_INTERP 1
+#define PM_MODE_FORW 2
+#define PM_MODE_BACK 3
+
+/* Modify the value of one or more metrics */
+extern int pmStore(const pmResult *);
+
+/* Get help and descriptive text */
+extern int pmLookupText(pmID, int, char **);
+extern int pmLookupInDomText(pmInDom, int, char **);
+#define PM_TEXT_ONELINE 1
+#define PM_TEXT_HELP 2
+
+/*
+ * Some handy formatting routines for messages, and other output
+ */
+extern const char *pmIDStr(pmID); /* NOT thread-safe */
+extern char *pmIDStr_r(pmID, char *, int);
+extern const char *pmInDomStr(pmInDom); /* NOT thread-safe */
+extern char *pmInDomStr_r(pmInDom, char *, int);
+extern const char *pmTypeStr(int); /* NOT thread-safe */
+extern char *pmTypeStr_r(int, char *, int);
+extern const char *pmUnitsStr(const pmUnits *); /* NOT thread-safe */
+extern char *pmUnitsStr_r(const pmUnits *, char *, int);
+extern const char *pmAtomStr(const pmAtomValue *, int); /* NOT thread-safe */
+extern char *pmAtomStr_r(const pmAtomValue *, int, char *, int);
+extern const char *pmNumberStr(double); /* NOT thread-safe */
+extern char *pmNumberStr_r(double, char *, int);
+extern const char *pmEventFlagsStr(int); /* NOT thread-safe */
+extern char *pmEventFlagsStr_r(int, char *, int);
+
+/* Extended time base definitions and macros */
+#define PM_XTB_FLAG 0x1000000
+
+#define PM_XTB_SET(type) (PM_XTB_FLAG | ((type) << 16))
+#define PM_XTB_GET(x) (((x) & PM_XTB_FLAG) ? (((x) & 0xff0000) >> 16) : -1)
+
+/* Parse -t, -S, -T, -A and -O options */
+extern int pmParseInterval(const char *, struct timeval *, char **);
+extern int pmParseTimeWindow(
+ const char *, const char *, const char *, const char *,
+ const struct timeval *, const struct timeval *,
+ struct timeval *, struct timeval *, struct timeval *, char **);
+
+/* Reporting timezone */
+extern int pmUseZone(const int);
+extern int pmNewZone(const char *);
+extern int pmNewContextZone(void);
+extern int pmWhichZone(char **);
+extern char *pmCtime(const time_t *, char *);
+extern struct tm *pmLocaltime(const time_t *, struct tm *);
+
+/* Parse host:metric[instances] or archive/metric[instances] */
+typedef struct {
+ int isarch; /* source type: 0 -> live host, 1 -> archive, 2 -> local context */
+ char *source; /* name of source host or archive */
+ char *metric; /* name of metric */
+ int ninst; /* number of instances, 0 -> all */
+ char *inst[1]; /* array of instance names */
+} pmMetricSpec;
+
+/* Parsing of host:metric[instances] or archive/metric[instances] */
+extern int pmParseMetricSpec(const char *, int, char *, pmMetricSpec **,
+ char **);
+extern void pmFreeMetricSpec(pmMetricSpec *p);
+
+/*
+ * Configurable error reporting
+ */
+#ifdef __GNUC__
+# define __PM_PRINTFLIKE(idx,cnt) __attribute__ ((format (printf, idx,cnt)))
+#else
+# define __PM_PRINTFLIKE(idx,cnt)
+#endif
+
+extern int pmprintf(const char *, ...) __PM_PRINTFLIKE(1,2);
+extern int pmflush(void);
+
+/*
+ * Wrapper for config/environment variables. Warning: this will exit() with
+ * a FATAL error if /etc/pcp.conf does not exist and $PCP_CONF is not set.
+ * Return values point to strings in the environment.
+ */
+extern char *pmGetConfig(const char *);
+
+/*
+ * Common command line argument parsing interfaces
+ */
+
+#define PMAPI_OPTIONS "A:a:D:gh:n:O:p:S:s:T:t:VZ:z?"
+#define PMAPI_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) }
+#define PMAPI_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) }
+#define PMAPI_OPTIONS_END { NULL, 0, 0, 0, NULL }
+
+#define PMOPT_ALIGN { "align", 1, 'A', "TIME", \
+ "align sample times on natural boundaries" }
+#define PMOPT_ARCHIVE { "archive", 1, 'a', "FILE", \
+ "metrics source is a PCP log archive" }
+#define PMOPT_DEBUG { "debug", 1, 'D', "DBG", \
+ NULL }
+#define PMOPT_GUIMODE { "guimode", 0, 'g', 0, \
+ "start in GUI mode with new time control" }
+#define PMOPT_HOST { "host", 1, 'h', "HOST", \
+ "metrics source is PMCD on host" }
+#define PMOPT_HOSTSFILE { "hostsfile", 1, 'H', "FILE", \
+ "read metric source hosts from a file" }
+#define PMOPT_SPECLOCAL { "spec-local", 1, 'K', "SPEC", \
+ "optional additional PMDA spec for local connection" }
+#define PMOPT_LOCALPMDA { "local-PMDA", 0, 'L', 0, \
+ "metrics source is local connection to a PMDA" }
+#define PMOPT_NAMESPACE { "namespace", 1, 'n', "FILE", \
+ "use an alternative PMNS" }
+#define PMOPT_DUPNAMES { "dupnames", 1, 'N', "FILE", \
+ "use an alternative PMNS (duplicate names allowed)" }
+#define PMOPT_ORIGIN { "origin", 1, 'O', "TIME", \
+ "initial sample time within the time window" }
+#define PMOPT_GUIPORT { "guiport", 1, 'p', "N", \
+ "port for connection to existing time control" }
+#define PMOPT_START { "start", 1, 'S', "TIME", \
+ "start of the time window" }
+#define PMOPT_SAMPLES { "samples", 1, 's', "N", \
+ "terminate after this many samples" }
+#define PMOPT_FINISH { "finish", 1, 'T', "TIME", \
+ "end of the time window" }
+#define PMOPT_INTERVAL { "interval", 1, 't', "DELTA", \
+ "sampling interval" }
+#define PMOPT_VERSION { "version", 0, 'V', 0, \
+ "display version number and exit" }
+#define PMOPT_TIMEZONE { "timezone", 1, 'Z', "TZ", \
+ "set reporting timezone" }
+#define PMOPT_HOSTZONE { "hostzone", 0, 'z', 0, \
+ "set reporting timezone to local time of metrics source" }
+#define PMOPT_HELP { "help", 0, '?', 0, \
+ "show this usage message and exit" }
+
+#define PMAPI_GENERAL_OPTIONS \
+ PMAPI_OPTIONS_HEADER("General options"), \
+ PMOPT_ALIGN, \
+ PMOPT_ARCHIVE, \
+ PMOPT_DEBUG, \
+ PMOPT_GUIMODE, \
+ PMOPT_HOST, \
+ PMOPT_NAMESPACE, \
+ PMOPT_ORIGIN, \
+ PMOPT_GUIPORT, \
+ PMOPT_START, \
+ PMOPT_SAMPLES, \
+ PMOPT_FINISH, \
+ PMOPT_INTERVAL, \
+ PMOPT_TIMEZONE, \
+ PMOPT_HOSTZONE, \
+ PMOPT_VERSION, \
+ PMOPT_HELP
+
+/* long-only standard options */
+#define PMLONGOPT_ARCHIVE_LIST "archive-list"
+#define PMOPT_ARCHIVE_LIST { PMLONGOPT_ARCHIVE_LIST, 1, 0, "FILES", \
+ "comma-separated list of metric source archives" }
+#define PMLONGOPT_ARCHIVE_FOLIO "archive-folio"
+#define PMOPT_ARCHIVE_FOLIO { PMLONGOPT_ARCHIVE_FOLIO, 1, 0, "FILE", \
+ "read metric source archives from a folio" }
+#define PMLONGOPT_HOST_LIST "host-list"
+#define PMOPT_HOST_LIST { PMLONGOPT_HOST_LIST, 1, 0, "HOSTS", \
+ "comma-separated list of metric source hosts" }
+
+/* pmOptions flags */
+#define PM_OPTFLAG_INIT (1<<0) /* initialisation done */
+#define PM_OPTFLAG_DONE (1<<1) /* parsing is complete */
+#define PM_OPTFLAG_MULTI (1<<2) /* allow multi-context */
+#define PM_OPTFLAG_USAGE_ERR (1<<3) /* argument parse fail */
+#define PM_OPTFLAG_RUNTIME_ERR (1<<4) /* any runtime failure */
+#define PM_OPTFLAG_EXIT (1<<5) /* tool should exit(0) */
+#define PM_OPTFLAG_POSIX (1<<6) /* POSIXLY_CORRECT set */
+#define PM_OPTFLAG_MIXED (1<<7) /* allow hosts+archives */
+#define PM_OPTFLAG_ENV_ONLY (1<<8) /* use env options only */
+#define PM_OPTFLAG_LONG_ONLY (1<<9) /* use long options only */
+#define PM_OPTFLAG_BOUNDARIES (1<<10) /* calculate time window */
+#define PM_OPTFLAG_STDOUT_TZ (1<<11) /* write timezone change */
+#define PM_OPTFLAG_NOFLUSH (1<<12) /* caller issues pmflush */
+#define PM_OPTFLAG_QUIET (1<<13) /* silence getopt errors */
+
+struct __pmOptions;
+typedef int (*pmOptionOverride)(int, struct __pmOptions *);
+
+typedef struct {
+ const char * long_opt;
+ int has_arg;
+ int short_opt;
+ const char * argname;
+ const char * message;
+} pmLongOptions;
+
+typedef struct __pmOptions {
+ int version;
+ int flags;
+
+ /* in: define set of all options */
+ const char * short_options;
+ pmLongOptions * long_options;
+ const char * short_usage;
+
+ /* in: method for general override */
+ pmOptionOverride override;
+
+ /* out: usual getopt information */
+ int index;
+ int optind;
+ int opterr;
+ int optopt;
+ char *optarg;
+
+ /* internals; do not ever access */
+ int __initialized;
+ char * __nextchar;
+ int __ordering;
+ int __posixly_correct;
+ int __first_nonopt;
+ int __last_nonopt;
+
+ /* out: error count */
+ int errors;
+
+ /* out: PMAPI options and values */
+ int context; /* PM_CONTEXT_{HOST,ARCHIVE,LOCAL} */
+ int nhosts;
+ int narchives;
+ char ** hosts;
+ char ** archives;
+ struct timeval start;
+ struct timeval finish;
+ struct timeval origin;
+ struct timeval interval;
+ char * align_optarg;
+ char * start_optarg;
+ char * finish_optarg;
+ char * origin_optarg;
+ char * guiport_optarg;
+ char * timezone;
+ int samples;
+ int guiport;
+ int padding;
+ unsigned int guiflag : 1;
+ unsigned int tzflag : 1;
+ unsigned int nsflag : 1;
+ unsigned int Lflag : 1;
+ unsigned int zeroes : 28;
+} pmOptions;
+
+extern int pmgetopt_r(int, char *const *, pmOptions *);
+extern int pmGetOptions(int, char *const *, pmOptions *);
+extern int pmGetContextOptions(int, pmOptions *);
+extern void pmUsageMessage(pmOptions *);
+extern void pmFreeOptions(pmOptions *);
+
+/*
+ * Derived Metrics support
+ */
+extern int pmLoadDerivedConfig(const char *);
+extern char *pmRegisterDerived(const char *, const char *);
+extern char *pmDerivedErrStr(void);
+
+/*
+ * Event Record support
+ */
+typedef struct {
+ pmID ep_pmid;
+ /* vtype and vlen fields the format same as for pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ep_type : 8; /* value type */
+ unsigned int ep_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ep_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ep_type : 8; /* value type */
+#endif
+ /* actual value (vbuf) goes here ... */
+} pmEventParameter;
+
+typedef struct {
+ __pmTimeval er_timestamp; /* must be 2 x 32-bit format */
+ unsigned int er_flags; /* event record characteristics */
+ int er_nparams; /* number of er_param[] entries */
+ pmEventParameter er_param[1];
+} pmEventRecord;
+
+typedef struct {
+ __pmTimespec er_timestamp; /* must be 2 x 64-bit format */
+ unsigned int er_flags; /* event record characteristics */
+ int er_nparams; /* number of er_param[] entries */
+ pmEventParameter er_param[1];
+} pmHighResEventRecord;
+
+/* Potential flags bits set in er_flags (above) */
+#define PM_EVENT_FLAG_POINT (1U<<0) /* an observation, default type */
+#define PM_EVENT_FLAG_START (1U<<1) /* marking start of a new event */
+#define PM_EVENT_FLAG_END (1U<<2) /* completion of a traced event */
+#define PM_EVENT_FLAG_ID (1U<<3) /* 1st parameter is a trace ID */
+#define PM_EVENT_FLAG_PARENT (1U<<4) /* 2nd parameter is parents ID */
+#define PM_EVENT_FLAG_MISSED (1U<<31)/* nparams shows #missed events */
+
+typedef struct {
+ /* align initial declarations with start of pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ea_type : 8; /* value type */
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ea_type : 8; /* value type */
+#endif
+ /* real event records start here */
+ int ea_nrecords; /* number of ea_record[] entries */
+ pmEventRecord ea_record[1];
+} pmEventArray;
+
+typedef struct {
+ /* align initial declarations with start of pmValueBlock */
+#ifdef HAVE_BITFIELDS_LTOR
+ unsigned int ea_type : 8; /* value type */
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+#else
+ unsigned int ea_len : 24; /* bytes for type/len + vbuf */
+ unsigned int ea_type : 8; /* value type */
+#endif
+ /* real event records start here */
+ int ea_nrecords; /* number of ea_record[] entries */
+ pmHighResEventRecord ea_record[1];
+} pmHighResEventArray;
+
+/* Unpack a PM_TYPE_EVENT value into a set on pmResults */
+extern int pmUnpackEventRecords(pmValueSet *, int, pmResult ***);
+
+/* Free set of pmResults from pmUnpackEventRecords */
+extern void pmFreeEventResult(pmResult **);
+
+/* Unpack a PM_TYPE_HIGHRES_EVENT value into a set on pmHighResResults */
+extern int pmUnpackHighResEventRecords(pmValueSet *, int, pmHighResResult ***);
+
+/* Free set of pmHighResResults from pmUnpackEventRecords */
+extern void pmFreeHighResEventResult(pmHighResResult **);
+
+/* Service discovery, for clients. */
+#define PM_SERVER_SERVICE_SPEC "pmcd"
+#define PM_SERVER_PROXY_SPEC "pmproxy"
+#define PM_SERVER_WEBD_SPEC "pmwebd"
+
+extern int pmDiscoverServices(const char *, const char *, char ***);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PMAPI_H */
diff --git a/src/include/pcp/pmda.h b/src/include/pcp/pmda.h
new file mode 100644
index 0000000..0b6eba1
--- /dev/null
+++ b/src/include/pcp/pmda.h
@@ -0,0 +1,725 @@
+/*
+ * Copyright (c) 2013-2014 Red Hat.
+ * Copyright (c) 1995,2005 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef _PMDA_H
+#define _PMDA_H
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * libpcp_pmda interface versions
+ */
+#define PMDA_INTERFACE_2 2 /* new function arguments */
+#define PMDA_INTERFACE_3 3 /* 3-state return from fetch callback */
+#define PMDA_INTERFACE_4 4 /* dynamic pmns */
+#define PMDA_INTERFACE_5 5 /* client context in pmda and */
+ /* 4-state return from fetch callback */
+#define PMDA_INTERFACE_6 6 /* client security attributes in pmda */
+#define PMDA_INTERFACE_LATEST 6
+
+/*
+ * Type of I/O connection to PMCD (pmdaUnknown defaults to pmdaPipe)
+ */
+typedef enum {pmdaPipe, pmdaInet, pmdaUnix, pmdaUnknown, pmdaIPv6} pmdaIoType;
+
+/*
+ * Instance description: index and name
+ */
+typedef struct {
+ int i_inst; /* internal instance identifier */
+ char *i_name; /* external instance identifier */
+} pmdaInstid;
+
+/*
+ * Instance domain description: unique instance id, number of instances in
+ * this domain, and the list of instances (not null terminated).
+ */
+typedef struct {
+ pmInDom it_indom; /* indom, filled in */
+ int it_numinst; /* number of instances */
+ pmdaInstid *it_set; /* instance identifiers */
+} pmdaIndom;
+
+/*
+ * Metric description: handle for extending description, and the description.
+ */
+typedef struct {
+ void *m_user; /* for users external use */
+ pmDesc m_desc; /* metric description */
+} pmdaMetric;
+
+/*
+ * Type of function call back used by pmdaFetch.
+ */
+typedef int (*pmdaFetchCallBack)(pmdaMetric *, unsigned int, pmAtomValue *);
+
+/*
+ * return values for a pmdaFetchCallBack method
+ */
+#define PMDA_FETCH_NOVALUES 0
+#define PMDA_FETCH_STATIC 1
+#define PMDA_FETCH_DYNAMIC 2 /* free avp->vp after __pmStuffValue */
+
+/*
+ * Type of function call back used by pmdaMain to clean up a pmResult structure
+ * after a fetch.
+ */
+typedef void (*pmdaResultCallBack)(pmResult *);
+
+/*
+ * Type of function call back used by pmdaMain on receipt of each PDU to check
+ * availability, etc.
+ */
+typedef int (*pmdaCheckCallBack)(void);
+
+/*
+ * Type of function call back used by pmdaMain after each PDU has been
+ * processed.
+ */
+typedef void (*pmdaDoneCallBack)(void);
+
+/*
+ * Type of function call back used by pmdaMain when a client context is
+ * closed by PMCD.
+ */
+typedef void (*pmdaEndContextCallBack)(int);
+
+/*
+ * Forward declarations of structures so that inclusion of (internal) impl.h
+ * header file is not mandated if this header file is included.
+ */
+typedef struct __pmnsTree pmdaNameSpace;
+typedef struct __pmHashCtl pmdaHashTable;
+typedef struct __pmProfile pmdaInProfile;
+typedef struct __pmInResult pmdaInResult;
+
+/*
+ * libpcp_pmda extension structure.
+ *
+ * The fields of this structure are initialised using pmdaDaemon() or pmdaDSO()
+ * (if the agent is a daemon or a DSO respectively), pmdaGetOpt() and
+ * pmdaInit().
+ *
+ */
+typedef struct {
+
+ unsigned int e_flags; /* PMDA_EXT_FLAG_* bit field */
+ void *e_ext; /* used internally within libpcp_pmda */
+
+ char *e_sockname; /* socket name to pmcd */
+ char *e_name; /* name of this pmda */
+ char *e_logfile; /* path to log file */
+ char *e_helptext; /* path to help text */
+ int e_status; /* =0 is OK */
+ int e_infd; /* input file descriptor from pmcd */
+ int e_outfd; /* output file descriptor to pmcd */
+ int e_port; /* port to pmcd */
+ int e_singular; /* =0 for singular values */
+ int e_ordinal; /* >=0 for non-singular values */
+ int e_direct; /* =1 if pmid map to meta table */
+ int e_domain; /* metrics domain */
+ int e_nmetrics; /* number of metrics */
+ int e_nindoms; /* number of instance domains */
+ int e_help; /* help text comes via this handle */
+ pmdaInProfile *e_prof; /* last received profile */
+ pmdaIoType e_io; /* connection type to pmcd */
+ pmdaIndom *e_indoms; /* instance domain table */
+ pmdaIndom *e_idp; /* used in instance domain expansion */
+ pmdaMetric *e_metrics; /* metric description table */
+
+ pmdaResultCallBack e_resultCallBack; /* callback to clean up pmResult after fetch */
+ pmdaFetchCallBack e_fetchCallBack; /* callback to assign metric values in fetch */
+ pmdaCheckCallBack e_checkCallBack; /* callback on receipt of a PDU */
+ pmdaDoneCallBack e_doneCallBack; /* callback after PDU has been processed */
+ /* added for PMDA_INTERFACE_5 */
+ int e_context; /* client context id from pmcd */
+ pmdaEndContextCallBack e_endCallBack; /* callback after client context closed */
+} pmdaExt;
+
+#define PMDA_EXT_FLAG_DIRECT 0x01 /* direct mapped PMID metric table */
+#define PMDA_EXT_FLAG_HASHED 0x02 /* hashed PMID metric table lookup */
+#define PMDA_EXT_SETUPDONE 0x04 /* __pmdaSetup() has been called */
+#define PMDA_EXT_CONNECTED 0x08 /* pmdaConnect() done */
+#define PMDA_EXT_NOTREADY 0x10 /* pmcd connection marked NOTREADY */
+
+/*
+ * Optionally restrict symbol visibility for DSO PMDAs
+ *
+ * When compiled with -fvisibility=hidden this directive can be used
+ * to set up the init routine so that it is the only symbol exported
+ * by the DSO PMDA. This gives the compiler opportunity to generate
+ * more optimal code as well as ensuring that just the one symbol is
+ * exported (which is a good idea in itself).
+ */
+#ifdef __GNUC__
+# define __PMDA_INIT_CALL __attribute__ ((visibility ("default")))
+#else
+# define __PMDA_INIT_CALL
+#endif
+
+/*
+ * Interface Definitions for PMDA DSO Interface
+ * The new interface structure makes use of a union to manage new revisions
+ * cleanly. The structure for each new version must be backward compatible
+ * to all of the previous versions (i.e. contain earlier fields unchanged).
+ *
+ * The domain field is set by pmcd(1) in the case of a DSO PMDA, and by
+ * pmdaDaemon and pmdaGetOpt in the case of a Daemon PMDA. It should not be
+ * modified.
+ */
+typedef struct {
+ int domain; /* performance metrics domain id */
+ struct {
+ unsigned int pmda_interface : 8; /* PMDA DSO interface version */
+ unsigned int pmapi_version : 8; /* PMAPI version */
+ unsigned int flags : 16; /* optional feature flags */
+ } comm; /* set/return communication and version info */
+ int status; /* return initialization status here */
+
+ union {
+
+/*
+ * Interface Version 2 and 3 (PCP 2.0)
+ * PMDA_INTERFACE_2 and PMDA_INTERFACE_3
+ */
+
+ struct {
+ pmdaExt *ext;
+ int (*profile)(pmdaInProfile *, pmdaExt *);
+ int (*fetch)(int, pmID *, pmResult **, pmdaExt *);
+ int (*desc)(pmID, pmDesc *, pmdaExt *);
+ int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *);
+ int (*text)(int, int, char **, pmdaExt *);
+ int (*store)(pmResult *, pmdaExt *);
+ } any, two, three;
+
+/*
+ * Interface Version 4 (dynamic pmns support) and Version 5 (client context
+ * in PMDA).
+ * PMDA_INTERFACE_4, PMDA_INTERFACE_5
+ */
+
+ struct {
+ pmdaExt *ext;
+ int (*profile)(pmdaInProfile *, pmdaExt *);
+ int (*fetch)(int, pmID *, pmResult **, pmdaExt *);
+ int (*desc)(pmID, pmDesc *, pmdaExt *);
+ int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *);
+ int (*text)(int, int, char **, pmdaExt *);
+ int (*store)(pmResult *, pmdaExt *);
+ int (*pmid)(const char *, pmID *, pmdaExt *);
+ int (*name)(pmID, char ***, pmdaExt *);
+ int (*children)(const char *, int, char ***, int **, pmdaExt *);
+ } four, five;
+
+/*
+ * Interface Version 6 (client context security attributes in PMDA).
+ * PMDA_INTERFACE_6
+ */
+ struct {
+ pmdaExt *ext;
+ int (*profile)(pmdaInProfile *, pmdaExt *);
+ int (*fetch)(int, pmID *, pmResult **, pmdaExt *);
+ int (*desc)(pmID, pmDesc *, pmdaExt *);
+ int (*instance)(pmInDom, int, char *, pmdaInResult **, pmdaExt *);
+ int (*text)(int, int, char **, pmdaExt *);
+ int (*store)(pmResult *, pmdaExt *);
+ int (*pmid)(const char *, pmID *, pmdaExt *);
+ int (*name)(pmID, char ***, pmdaExt *);
+ int (*children)(const char *, int, char ***, int **, pmdaExt *);
+ int (*attribute)(int, int, const char *, int, pmdaExt *);
+ } six;
+
+ } version;
+
+} pmdaInterface;
+
+/*
+ * PM_CONTEXT_LOCAL support
+ */
+typedef struct {
+ int domain;
+ char *name;
+ char *init;
+ void *handle;
+ pmdaInterface dispatch;
+} __pmDSO;
+
+extern __pmDSO *__pmLookupDSO(int /*domain*/);
+
+/* Macro that can be used to create each metrics' PMID. */
+#define PMDA_PMID(x,y) (((x)<<10)|(y))
+
+/* Macro for pmUnits bitmap in a pmDesc declaration */
+#ifdef HAVE_BITFIELDS_LTOR
+#define PMDA_PMUNITS(a,b,c,d,e,f) {a,b,c,d,e,f,0}
+#else
+#define PMDA_PMUNITS(a,b,c,d,e,f) {0,f,e,d,c,b,a}
+#endif
+
+/* Command line option processing macros and data structures */
+
+#define PMDA_OPTIONS "D:d:h:i:l:pu:U:"
+#define PMDA_OPTIONS_HEADER(s) { "", 0, '-', 0, (s) }
+#define PMDA_OPTIONS_TEXT(s) { "", 0, '|', 0, (s) }
+#define PMDA_OPTIONS_END { NULL, 0, 0, 0, NULL }
+
+#define PMDAOPT_DEBUG { "debug", 1, 'D', "DBG", \
+ NULL }
+#define PMDAOPT_DOMAIN { "domain", 1, 'd', "NUM", \
+ "use domain (numeric) for metrics domain of PMDA" }
+#define PMDAOPT_HELPTEXT { "helpfile", 1, 'h', "FILE", \
+ "path to PMDA metrics help text file" }
+#define PMDAOPT_INET { "inet", 1, 'i', "PORT", \
+ "pmcd IPv4 connection service name or numeric port" }
+#define PMDAOPT_IPV6 { "ipv6", 1, '6', "PORT", \
+ "pmcd IPv6 connection service name or numeric port" }
+#define PMDAOPT_LOGFILE { "log", 1, 'l', "FILE", \
+ "write log to FILE rather than using default log name" }
+#define PMDAOPT_PIPE { "pipe", 0, 'p', 0, \
+ "use a pipe for communication with pmcd" }
+#define PMDAOPT_UNIX { "unix", 1, 'u', "FILE", \
+ "use a unix domain socket for communication with pmcd" }
+#define PMDAOPT_USERNAME { "username", 1, 'U', "USER", \
+ "run the PMDA using the named user account" }
+
+struct __pmdaOptions;
+typedef int (*pmdaOptionOverride)(int, struct __pmdaOptions *);
+
+typedef struct __pmdaOptions {
+ int version;
+ int flags;
+ const char * short_options;
+ pmLongOptions * long_options;
+ const char * short_usage;
+ pmdaOptionOverride override;
+
+ /* out: usual getopt information */
+ int index;
+ int optind;
+ int opterr;
+ int optopt;
+ char *optarg;
+
+ /* internals; do not ever access */
+ int __initialized;
+ char * __nextchar;
+ int __ordering;
+ int __posixly_correct;
+ int __first_nonopt;
+ int __last_nonopt;
+
+ /* out: error count */
+ int errors;
+
+ /* out: PMDA options (non-pmdaInterface options) */
+ char * username;
+} pmdaOptions;
+
+
+/*
+ * PMDA Setup Routines.
+ *
+ * pmdaGetOpt
+ * pmdaGetOptions
+ * pmdaUsageMessage
+ * Replacements for pmgetopt_r(3) which strip out the standard PMDA flags
+ * before returning the next command line option. The standard PMDA
+ * flags are PMDA_OPTIONS which will initialise the pmdaExt structure
+ * with the IPC details, path to the log and help file, domain number,
+ * and the user account under which the PMDA should run.
+ * An error counter will be incremented if there was an error parsing any
+ * of these options.
+ *
+ * pmdaDaemon
+ * Setup the pmdaInterface structure for a daemon and initialise
+ * the pmdaExt structure with the PMDA's name, domain and path to
+ * the log file and help file. The libpcp internal state is also
+ * initialised.
+ *
+ * pmdaDSO
+ * Setup the pmdaInterface structure for a DSO and initialise the
+ * pmdaExt structure with the PMDA's name and help file.
+ *
+ * pmdaOpenLog
+ * Redirects stderr to the logfile.
+ *
+ * pmdaSetFlags
+ * Allow behaviour flags to be set to enable features, such as to request
+ * libpcp_pmda internally use direct or hashed PMID metric table mapping.
+ * Can be called multiple times - effects are cumulative - no flag can be
+ * cleared, although libpcp_pmda may disable a flag later on if it cannot
+ * enact the requested behaviour.
+ *
+ * pmdaInit
+ * Further initialises the pmdaExt structure with the instance domain and
+ * metric structures. Unique identifiers are applied to each instance
+ * domain and metric. Also open the help text file and checks whether the
+ * metrics can be directly mapped.
+ *
+ * pmdaConnect
+ * Connect to the PMCD process using the method set in the pmdaExt e_io
+ * field.
+ *
+ * pmdaMain
+ * Loop which receives PDUs and dispatches the callbacks. Must be called
+ * by a daemon PMDA.
+ *
+ * pmdaSetResultCallBack
+ * Allows an application specific routine to be specified for cleaning up
+ * a pmResult after a fetch. Most PMDAs should not use this.
+ *
+ * pmdaSetFetchCallBack
+ * Allows an application specific routine to be specified for completing a
+ * pmAtom structure with a metrics value. This must be set if pmdaFetch is
+ * used as the fetch callback.
+ *
+ * pmdaSetCheckCallBack
+ * Allows an application specific routine to be called upon receipt of any
+ * PDU. For all PDUs except PDU_PROFILE, a result less than zero
+ * indicates an error. If set to zero (which is also the default),
+ * the callback is ignored.
+ *
+ * pmdaSetDoneCallBack
+ * Allows an application specific routine to be called after each PDU is
+ * processed. The result is ignored. If set to zero (which is also
+ * the default), the callback is ignored.
+ *
+ * pmdaSetEndContextCallBack
+ * Allows an application specific routine to be called when a
+ * PMCD context is closed, so any per-context state can be cleaned
+ * up. If set to zero (which is also the default), the callback
+ * is ignored.
+ */
+
+extern int pmdaGetOpt(int, char *const *, const char *, pmdaInterface *, int *);
+extern int pmdaGetOptions(int, char *const *, pmdaOptions *, pmdaInterface *);
+extern void pmdaUsageMessage(pmdaOptions *);
+extern void pmdaDaemon(pmdaInterface *, int, char *, int , char *, char *);
+extern void pmdaDSO(pmdaInterface *, int, char *, char *);
+extern void pmdaOpenLog(pmdaInterface *);
+extern void pmdaSetFlags(pmdaInterface *, int);
+extern void pmdaInit(pmdaInterface *, pmdaIndom *, int, pmdaMetric *, int);
+extern void pmdaConnect(pmdaInterface *);
+
+extern void pmdaMain(pmdaInterface *);
+
+extern void pmdaSetResultCallBack(pmdaInterface *, pmdaResultCallBack);
+extern void pmdaSetFetchCallBack(pmdaInterface *, pmdaFetchCallBack);
+extern void pmdaSetCheckCallBack(pmdaInterface *, pmdaCheckCallBack);
+extern void pmdaSetDoneCallBack(pmdaInterface *, pmdaDoneCallBack);
+extern void pmdaSetEndContextCallBack(pmdaInterface *, pmdaEndContextCallBack);
+
+/*
+ * Callbacks to PMCD which should be adequate for most PMDAs.
+ * NOTE: if pmdaFetch is used, e_callback must be specified in the pmdaExt
+ * structure.
+ *
+ * pmdaProfile
+ * Store the instance profile away for the next fetch.
+ *
+ * pmdaFetch
+ * Resize the pmResult and call e_callback in the pmdaExt structure
+ * for each metric instance required by the profile.
+ *
+ * pmdaInstance
+ * Return description of instances and instance domains.
+ *
+ * pmdaDesc
+ * Return the metric desciption.
+ *
+ * pmdaText
+ * Return the help text for the metric.
+ *
+ * pmdaStore
+ * Store a value into a metric. This is a no-op.
+ *
+ * pmdaPMID
+ * Return the PMID for a named metric within a dynamic subtree
+ * of the PMNS.
+ *
+ * pmdaName
+ * Given a PMID, return the names of all matching metrics within a
+ * dynamic subtree of the PMNS.
+ *
+ * pmdaChildren
+ * If traverse == 0, return the names of all the descendent children
+ * and their status, given a named metric in a dynamic subtree of
+ * the PMNS (this is the pmGetChildren or pmGetChildrenStatus variant).
+ * If traverse == 1, return the full names of all descendent metrics
+ * (this is the pmTraversePMNS variant, with the status added)
+ *
+ * pmdaAttribute
+ * Inform the agent about security aspects of a client connection,
+ * such as the authenticated userid. Passed in a client identifier,
+ * numeric PCP_ATTR, pointer to the associated value, and the length
+ * of the value.
+ */
+
+extern int pmdaProfile(pmdaInProfile *, pmdaExt *);
+extern int pmdaFetch(int, pmID *, pmResult **, pmdaExt *);
+extern int pmdaInstance(pmInDom, int, char *, pmdaInResult **, pmdaExt *);
+extern int pmdaDesc(pmID, pmDesc *, pmdaExt *);
+extern int pmdaText(int, int, char **, pmdaExt *);
+extern int pmdaStore(pmResult *, pmdaExt *);
+extern int pmdaPMID(const char *, pmID *, pmdaExt *);
+extern int pmdaName(pmID, char ***, pmdaExt *);
+extern int pmdaChildren(const char *, int, char ***, int **, pmdaExt *);
+extern int pmdaAttribute(int, int, const char *, int, pmdaExt *);
+
+/*
+ * PMDA "help" text manipulation
+ */
+extern int pmdaOpenHelp(char *);
+extern void pmdaCloseHelp(int);
+extern char *pmdaGetHelp(int, pmID, int);
+extern char *pmdaGetInDomHelp(int, pmInDom, int);
+
+/*
+ * Dynamic metric table manipulation
+ *
+ * pmdaDynamicPMNS
+ * Register a new dynamic namespace sub-tree associated with one or more
+ * PMID clusters. Callbacks are passed in to deal with PMDA-specific
+ * components (names, help text, metric duplication, and table sizing).
+ *
+ * pmdaDynamicLookupName
+ * Perform PMDA name lookup operations for the name callback, for dynamic
+ * metrics.
+ *
+ * pmdaDynamicLookupPMID
+ * Perform PMDA reverse name lookup operations for the PMID callback, for
+ * dynamic metrics.
+ *
+ * pmdaDynamicLookupText
+ * Perform PMDA help text lookup operations for dynamic metrics.
+ *
+ * pmdaDynamicMetricTable
+ * Install a new metric table for the PMDA, after changes to the set of
+ * metrics which the PMDA must export (IOW, dynamic metrics are in use).
+ *
+ * pmdaRehash
+ * Update the metrictable within the pmdaExt structure with new (dynamic)
+ * metrics and recompute the hash table used for optimised lookup. Aids
+ * PMDAs with large numbers of metrics to get closer to directly mapped
+ * PMID lookup time, rather than multiple linear table scans per fetch.
+ * [NOTE: can be used by any interface version, not only dynamic metrics]
+ */
+typedef int (*pmdaUpdatePMNS)(pmdaExt *, pmdaNameSpace **);
+typedef int (*pmdaUpdateText)(pmdaExt *, pmID, int, char **);
+typedef void (*pmdaUpdateMetric)(pmdaMetric *, pmdaMetric *, int);
+typedef void (*pmdaCountMetrics)(int *, int *);
+extern void pmdaDynamicPMNS(const char *, int *, int,
+ pmdaUpdatePMNS, pmdaUpdateText,
+ pmdaUpdateMetric, pmdaCountMetrics,
+ pmdaMetric *, int);
+extern int pmdaDynamicSetClusterMask(const char *, unsigned int);
+extern pmdaNameSpace *pmdaDynamicLookupName(pmdaExt *, const char *);
+extern pmdaNameSpace *pmdaDynamicLookupPMID(pmdaExt *, pmID);
+extern int pmdaDynamicLookupText(pmID, int, char **, pmdaExt *);
+extern void pmdaDynamicMetricTable(pmdaExt *);
+
+extern void pmdaRehash(pmdaExt *, pmdaMetric *, int);
+
+/*
+ * Dynamic names interface (version 4) helper routines.
+ *
+ * pmdaTreePMID
+ * when a pmdaNameSpace is being used, this provides
+ * an implementation for the four.pmid() interface.
+ *
+ * pmdaTreeName
+ * when a pmdaNameSpace is being used, this provides
+ * an implementation for the four.name() interface.
+ *
+ * pmdaTreeChildren
+ * when a pmdaNameSpace is being used, this provides
+ * an implementation for the four.children() interface.
+ *
+ * pmdaTreeRebuildHash
+ * iterate over a pmdaNameSpace and (re)build the hash
+ * for any subsequent PMID -> name (reverse) lookups
+ *
+ * pmdaTreeSize
+ * returns the numbers of entries in a pmdaNameSpace.
+ */
+extern int pmdaTreePMID(pmdaNameSpace *, const char *, pmID *);
+extern int pmdaTreeName(pmdaNameSpace *, pmID, char ***);
+extern int pmdaTreeChildren(pmdaNameSpace *, const char *, int, char ***, int **);
+extern void pmdaTreeRebuildHash(pmdaNameSpace *, int);
+extern int pmdaTreeSize(pmdaNameSpace *);
+
+/*
+ * PMDA instance domain cache support
+ *
+ * pmdaCacheStore
+ * add entry into the cache, or change state, assigns internal
+ * instance identifier
+ *
+ * pmdaCacheStoreKey
+ * add entry into the cache, or change state, caller provides "hint"
+ * for internal instance identifier
+ *
+ * pmdaCacheLookup
+ * fetch entry based on internal instance identifier
+ *
+ * pmdaCacheLookupName
+ * fetch entry based on external instance name
+ *
+ * pmdaCacheLookupKey
+ * fetch entry based on key as "hint", like pmdaCacheStoreKey()
+ *
+ * pmdaCacheOp
+ * service routines to load, unload, mark as write-thru, purge,
+ * count entries, etc
+ *
+ * pmdaCachePurge
+ * cull inactive entries
+ */
+extern int pmdaCacheStore(pmInDom, int, const char *, void *);
+extern int pmdaCacheStoreKey(pmInDom, int, const char *, int, const void *, void *);
+extern int pmdaCacheLookup(pmInDom, int, char **, void **);
+extern int pmdaCacheLookupName(pmInDom, const char *, int *, void **);
+extern int pmdaCacheLookupKey(pmInDom, const char *, int, const void *, char **, int *, void **);
+extern int pmdaCacheOp(pmInDom, int);
+extern int pmdaCachePurge(pmInDom, time_t);
+
+#define PMDA_CACHE_LOAD 1
+#define PMDA_CACHE_ADD 2
+#define PMDA_CACHE_HIDE 3
+#define PMDA_CACHE_CULL 4
+#define PMDA_CACHE_EMPTY 5
+#define PMDA_CACHE_SAVE 6
+#define PMDA_CACHE_STRINGS 7
+#define PMDA_CACHE_ACTIVE 8
+#define PMDA_CACHE_INACTIVE 9
+#define PMDA_CACHE_SIZE 10
+#define PMDA_CACHE_SIZE_ACTIVE 11
+#define PMDA_CACHE_SIZE_INACTIVE 12
+#define PMDA_CACHE_REUSE 13
+#define PMDA_CACHE_WALK_REWIND 14
+#define PMDA_CACHE_WALK_NEXT 15
+#define PMDA_CACHE_CHECK 16
+#define PMDA_CACHE_REORG 17
+#define PMDA_CACHE_SYNC 18
+#define PMDA_CACHE_DUMP 19
+#define PMDA_CACHE_DUMP_ALL 20
+
+/*
+ * Internal libpcp_pmda routines.
+ *
+ * __pmdaCntInst
+ * Returns the number of instances for an entry in the instance domain
+ * table.
+ *
+ * __pmdaStartInst
+ * Setup for __pmdaNextInst to iterate over an instance domain.
+ *
+ * __pmdaNextInst
+ * Step through an instance domain, returning instances one at a
+ * time.
+ *
+ * __pmdaMainPDU
+ * Use this when you need to override pmdaMain and construct
+ * your own loop.
+ * Call this function in the _body_ of your loop.
+ * See pmdaMain code for an example.
+ * Returns negative int on failure, 0 otherwise.
+ *
+ * __pmdaInFd
+ * This returns the file descriptor that is used to get the
+ * PDU from pmcd.
+ * One may use the fd to do a select call in a custom main loop.
+ * Returns negative int on failure, file descriptor otherwise.
+ *
+ * __pmdaCacheDumpAll and __pmdaCacheDump
+ * print out cache contents
+ */
+
+extern int __pmdaCntInst(pmInDom, pmdaExt *);
+extern void __pmdaStartInst(pmInDom, pmdaExt *);
+extern int __pmdaNextInst(int *, pmdaExt *);
+
+extern int __pmdaMainPDU(pmdaInterface *);
+extern int __pmdaInFd(pmdaInterface *);
+
+extern void __pmdaCacheDumpAll(FILE *, int);
+extern void __pmdaCacheDump(FILE *, pmInDom, int);
+
+/*
+ * Client Context support
+ */
+extern int pmdaGetContext(void);
+extern void __pmdaSetContext(int);
+
+/*
+ * Event Record support
+ */
+extern int pmdaEventNewArray(void);
+extern int pmdaEventResetArray(int);
+extern int pmdaEventReleaseArray(int);
+extern int pmdaEventAddRecord(int, struct timeval *, int);
+extern int pmdaEventAddMissedRecord(int, struct timeval *, int);
+extern int pmdaEventAddParam(int, pmID, int, pmAtomValue *);
+extern pmEventArray *pmdaEventGetAddr(int);
+
+/*
+ * High Resolution Timer Event Record support
+ */
+extern int pmdaEventNewHighResArray(void);
+extern int pmdaEventResetHighResArray(int);
+extern int pmdaEventReleaseHighResArray(int);
+extern int pmdaEventAddHighResRecord(int, struct timespec *, int);
+extern int pmdaEventAddHighResMissedRecord(int, struct timespec *, int);
+extern int pmdaEventHighResAddParam(int, pmID, int, pmAtomValue *);
+extern pmHighResEventArray *pmdaEventHighResGetAddr(int);
+
+/*
+ * Event Queue support
+ */
+extern int pmdaEventNewQueue(const char *, size_t);
+extern int pmdaEventNewActiveQueue(const char *, size_t, unsigned int);
+extern int pmdaEventQueueHandle(const char *);
+extern int pmdaEventQueueAppend(int, void *, size_t, struct timeval *);
+extern int pmdaEventQueueClients(int, pmAtomValue *);
+extern int pmdaEventQueueCounter(int, pmAtomValue *);
+extern int pmdaEventQueueBytes(int, pmAtomValue *);
+extern int pmdaEventQueueMemory(int, pmAtomValue *);
+
+typedef int (*pmdaEventDecodeCallBack)(int,
+ void *, size_t, struct timeval *, void *);
+extern int pmdaEventQueueRecords(int, pmAtomValue *, int,
+ pmdaEventDecodeCallBack, void *);
+
+extern int pmdaEventNewClient(int);
+extern int pmdaEventEndClient(int);
+extern int pmdaEventClients(pmAtomValue *);
+
+typedef int (*pmdaEventApplyFilterCallBack)(void *, void *, size_t);
+typedef void (*pmdaEventReleaseFilterCallBack)(void *);
+extern int pmdaEventSetFilter(int, int, void *,
+ pmdaEventApplyFilterCallBack, pmdaEventReleaseFilterCallBack);
+extern int pmdaEventSetAccess(int, int, int);
+
+extern char *__pmdaEventPrint(const char *, int, char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PMDA_H */
diff --git a/src/include/pcp/pmtime.h b/src/include/pcp/pmtime.h
new file mode 100644
index 0000000..86db5a3
--- /dev/null
+++ b/src/include/pcp/pmtime.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2006-2007 Aconex. All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ */
+#ifndef PMTIME_H
+#define PMTIME_H
+
+#include <sys/time.h>
+
+typedef enum {
+ PM_TCTL_SET = (1<<0), // client -> server
+ PM_TCTL_STEP = (1<<1), // server -> clients
+ PM_TCTL_TZ = (1<<2), // server -> clients
+ PM_TCTL_VCRMODE = (1<<3), // server -> clients
+ PM_TCTL_VCRMODE_DRAG= (1<<4), // server -> clients
+ PM_TCTL_GUISHOW = (1<<5), // client -> server
+ PM_TCTL_GUIHIDE = (1<<6), // client -> server
+ PM_TCTL_BOUNDS = (1<<7), // client -> server
+ PM_TCTL_ACK = (1<<8), // client -> server (except handshake)
+} pm_tctl_command;
+
+typedef enum {
+ PM_STATE_STOP = 0,
+ PM_STATE_FORWARD = 1,
+ PM_STATE_BACKWARD = 2,
+} pm_tctl_state;
+
+typedef enum {
+ PM_MODE_STEP = 0,
+ PM_MODE_NORMAL = 1,
+ PM_MODE_FAST = 2,
+} pm_tctl_mode;
+
+typedef enum {
+ PM_SOURCE_NONE = -1,
+ PM_SOURCE_HOST = 0,
+ PM_SOURCE_ARCHIVE = 1,
+} pm_tctl_source;
+
+#define PMTIME_MAGIC 0x54494D45 /* "TIME" */
+
+typedef struct {
+ unsigned int magic;
+ unsigned int length;
+ pm_tctl_command command;
+ pm_tctl_source source;
+ pm_tctl_state state;
+ pm_tctl_mode mode;
+ struct timeval delta;
+ struct timeval position;
+ struct timeval start; /* archive only */
+ struct timeval end; /* archive only */
+ char data[0]; /* arbitrary length info (e.g. $TZ) */
+} pmTime;
+
+extern int pmTimeSendAck(int, struct timeval *);
+extern int pmTimeConnect(int, pmTime *);
+extern int pmTimeShowDialog(int, int);
+extern int pmTimeRecv(int, pmTime **);
+
+/*
+ * Time state management API for simple clients
+ */
+
+typedef void (*pmTimeStateResume)(void);
+typedef void (*pmTimeStateRewind)(void);
+typedef void (*pmTimeStateExited)(void);
+typedef void (*pmTimeStateBoundary)(void);
+typedef void (*pmTimeStatePosition)(struct timeval);
+typedef void (*pmTimeStateInterval)(struct timeval);
+typedef void (*pmTimeStateStepped)(struct timeval);
+typedef void (*pmTimeStateNewZone)(char *, char *);
+
+typedef struct {
+ pmTimeStateResume resume;
+ pmTimeStateRewind rewind;
+ pmTimeStateExited exited;
+ pmTimeStateBoundary boundary;
+ pmTimeStatePosition position;
+ pmTimeStateInterval interval;
+ pmTimeStateStepped stepped;
+ pmTimeStateNewZone newzone;
+ struct timeval delta;
+ int fd;
+ int showgui;
+ int context;
+ int padding;
+} pmTimeControls;
+
+extern pmTime *pmTimeStateSetup(pmTimeControls *, int, int,
+ struct timeval, struct timeval,
+ struct timeval, struct timeval, char *, char *);
+extern void pmTimeStateAck(pmTimeControls *, pmTime *);
+extern void pmTimeStateMode(int, struct timeval, struct timeval *);
+extern int pmTimeStateVector(pmTimeControls *, pmTime *);
+extern void pmTimeStateBounds(pmTimeControls *, pmTime *);
+
+#endif /* PMTIME_H */
diff --git a/src/include/pcp/trace.h b/src/include/pcp/trace.h
new file mode 100644
index 0000000..af64d79
--- /dev/null
+++ b/src/include/pcp/trace.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#ifndef _TRACE_H
+#define _TRACE_H
+
+/*
+ * Transaction monitoring PMDA (trace) public interface.
+ *
+ * An example program using this interface can be found at
+ * $PCP_DEMOS_DIR/trace/demo.c and contains further doumentation.
+ * Also refer to the pmdatrace(1) and pmdatrace(3) man pages and
+ * the Performance Co-Pilot Programmer's Guide.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Add a new entry to the table of transactions currently being monitored,
+ * or update an existing entry.
+ */
+extern int pmtracebegin(const char *);
+
+/*
+ * Make measurements recorded for the given transaction tag available
+ * through the trace PMDA.
+ */
+extern int pmtraceend(const char *);
+
+/*
+ * Cancel a transaction which began from an earlier call to pmtracebegin,
+ * without exporting new data through the trace PMDA.
+ */
+extern int pmtraceabort(const char *);
+
+/*
+ * An alternate form of measurement can be obtained using pmtracepoint.
+ * This is a count-only measurement, and will result in the trace PMDA
+ * exporting the number of times a given code point is passed (ie. the
+ * the number of times a particular label has been passed to pmtracepoint.
+ */
+extern int pmtracepoint(const char *);
+
+/*
+ * An extension to pmtracepoint is pmtraceobs, with similar semantics to
+ * pmtracepoint except allowing an arbitrary numeric value (double) to be
+ * exported up through the PMAPI.
+ */
+extern int pmtraceobs(const char *, double);
+
+/*
+ * Similar to pmtraceobs is pmtracecounter, with the only difference
+ * being the way the trace PMDA exports the given numeric value to
+ * PMAPI clients (exported with counter semantics, rather than with
+ * instantaneous semantics which is the case with pmtraceobs).
+ */
+extern int pmtracecounter(const char *, double);
+
+/*
+ * Should any of these routines return a negative value, the return value
+ * can be passed to pmtraceerrstr for the associated error message.
+ * This performs a lookup into a static error message table, so the returned
+ * pointer must not be freed.
+ */
+extern char *pmtraceerrstr(int);
+
+#define PMTRACE_ERR_BASE 12000
+#define PMTRACE_ERR_TAGNAME (-PMTRACE_ERR_BASE-0)
+#define PMTRACE_ERR_INPROGRESS (-PMTRACE_ERR_BASE-1)
+#define PMTRACE_ERR_NOPROGRESS (-PMTRACE_ERR_BASE-2)
+#define PMTRACE_ERR_NOSUCHTAG (-PMTRACE_ERR_BASE-3)
+#define PMTRACE_ERR_TAGTYPE (-PMTRACE_ERR_BASE-4)
+#define PMTRACE_ERR_TAGLENGTH (-PMTRACE_ERR_BASE-5)
+#define PMTRACE_ERR_IPC (-PMTRACE_ERR_BASE-6)
+#define PMTRACE_ERR_ENVFORMAT (-PMTRACE_ERR_BASE-7)
+#define PMTRACE_ERR_TIMEOUT (-PMTRACE_ERR_BASE-8)
+#define PMTRACE_ERR_VERSION (-PMTRACE_ERR_BASE-9)
+#define PMTRACE_ERR_PERMISSION (-PMTRACE_ERR_BASE-10)
+#define PMTRACE_ERR_CONNLIMIT (-PMTRACE_ERR_BASE-11)
+
+/*
+ * Diagnostic and state switching
+ */
+extern int pmtracestate(int code);
+
+#define PMTRACE_STATE_NONE 0 /* default: synchronous and no diagnostics */
+#define PMTRACE_STATE_API 1 /* debug: processing just below the API */
+#define PMTRACE_STATE_COMMS 2 /* debug: shows network-related activity */
+#define PMTRACE_STATE_PDU 4 /* debug: shows app<->PMDA IPC traffic */
+#define PMTRACE_STATE_PDUBUF 8 /* debug: internal IPC buffer management */
+#define PMTRACE_STATE_NOAGENT 16 /* debug: no PMDA communications at all */
+#define PMTRACE_STATE_ASYNC 32 /* control: use asynchronous PDU protocol */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TRACE_H */
diff --git a/src/include/pcp/trace_dev.h b/src/include/pcp/trace_dev.h
new file mode 100644
index 0000000..a237a97
--- /dev/null
+++ b/src/include/pcp/trace_dev.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 1997-2001,2003 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#ifndef _TRACE_DEV_H
+#define _TRACE_DEV_H
+
+#ifndef _PLATFORM_DEFS_H
+#include "platform_defs.h"
+#endif
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+
+#define MAXTAGNAMELEN 256
+
+#define TRACE_ENV_HOST "PCP_TRACE_HOST"
+#define TRACE_ENV_PORT "PCP_TRACE_PORT"
+#define TRACE_ENV_TIMEOUT "PCP_TRACE_TIMEOUT"
+#define TRACE_ENV_NOAGENT "PCP_TRACE_NOAGENT"
+#define TRACE_ENV_REQTIMEOUT "PCP_TRACE_REQTIMEOUT"
+#define TRACE_ENV_RECTIMEOUT "PCP_TRACE_RECONNECT"
+#define TRACE_PORT 4323
+#define TRACE_PDU_VERSION 1
+
+#define TRACE_TYPE_TRANSACT 1
+#define TRACE_TYPE_POINT 2
+#define TRACE_TYPE_OBSERVE 3
+#define TRACE_TYPE_COUNTER 4
+#define TRACE_FIRST_TYPE TRACE_TYPE_TRANSACT
+#define TRACE_LAST_TYPE TRACE_TYPE_COUNTER
+
+/*
+ * Protocol data unit (PDU) support snarfed from impl.h, pdu.c and pdubuf.c
+ */
+typedef struct {
+ int len; /* length of pdu_header + PDU */
+ int type; /* PDU type */
+ int from; /* pid of PDU originator */
+} __pmTracePDUHdr;
+
+typedef __uint32_t __pmTracePDU;
+
+extern int __pmtracexmitPDU(int, __pmTracePDU *);
+extern int __pmtracegetPDU(int, int, __pmTracePDU **);
+
+/* for __pmtracegetPDU */
+#define TRACE_TIMEOUT_NEVER 0
+#define TRACE_TIMEOUT_DEFAULT -1
+
+/* unit of space allocation for PDU buffer. */
+#define TRACE_PDU_CHUNK 1024
+
+extern __pmTracePDU *__pmtracefindPDUbuf(int);
+extern void __pmtracepinPDUbuf(void *);
+extern int __pmtraceunpinPDUbuf(void *);
+extern int __pmtracemoreinput(int);
+extern void __pmtracenomoreinput(int);
+
+
+#define TRACE_PDU_BASE 0x7050
+#define TRACE_PDU_ACK 0x7050
+#define TRACE_PDU_DATA 0x7051
+#define TRACE_PDU_MAX 2
+
+extern int __pmtracesendack(int, int);
+extern int __pmtracedecodeack(__pmTracePDU *, int *);
+extern int __pmtracesenddata(int, char *, int, int, double);
+extern int __pmtracedecodedata(__pmTracePDU *, char **, int *, int *, int *, double *);
+
+#define TRACE_PROTOCOL_FINAL -1
+#define TRACE_PROTOCOL_QUERY 0
+#define TRACE_PROTOCOL_ASYNC 1
+#define TRACE_PROTOCOL_SYNC 2
+
+extern int __pmtraceprotocol(int);
+
+extern int __pmstate;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TRACE_DEV_H */