New POC branch...
by Darryl L. Pierce
I've created a new branch in the git repo on fedorahosted.org, called
poc. On it I've pushed Ryan's virtio-serial code and my own C APIs for
the datahandler, muliplexer and unit tests.
You can start tracking and working against it with:
git checkout -b poc --track origin/poc
--
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
13 years, 10 months
[PATCH matahari] Add basic virtio code
by Ryan O'Hara
Here is a patch that adds handling of virtio-serial transport to
Mathari. This patch still has some warts. Specfically, I'd like to add
a function to read a "message" in. This would wrap the two vrtio_read
calls and simplify the code in main.cpp.
Also note that the message format is an absolute minimum and will need
to be modified. I suggest that we use a generic format that can be
used for requests and responses, and also be passed into the
datahandler.
Ryan
13 years, 10 months
A squashing of multiple patches.
by Darryl L. Pierce
This patch brings together refactoring the datahandler, multiplexer and
host APIs, as well as replacing all of the unit tests with Check tests.
With this, there are no other outstanding patches from me to be reviewed.
13 years, 10 months
[PATCH] Adding gnulib to our build environment.
by Darryl L. Pierce
The build environment now only requires a new user to:
1. clone the git repository
2. ./bootstrap
3. ./configure, and install any requirements
4. make
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
.gitignore | 17 +-
.gitmodules | 3 +
INSTALL | 290 --------------
Makefile.am | 4 +-
README-hacking | 54 +++
bootstrap | 855 +++++++++++++++++++++++++++++++++++++++++
bootstrap.conf | 67 ++++
configure.ac | 6 +
gnulib | 1 +
src/Makefile.am | 6 +-
src/host.cpp | 1 +
src/linux_platform.cpp | 1 +
src/main.cpp | 1 +
src/platform.cpp | 1 +
src/qmf/hostagent.cpp | 1 +
src/tests/Makefile.am | 7 +-
src/tests/testhostapis.cpp | 1 +
src/tests/testmultiplexer.cpp | 1 +
src/virtio/multiplexer.cpp | 4 +-
19 files changed, 1020 insertions(+), 301 deletions(-)
create mode 100644 .gitmodules
delete mode 100644 INSTALL
create mode 100644 README-hacking
create mode 100755 bootstrap
create mode 100644 bootstrap.conf
create mode 160000 gnulib
diff --git a/.gitignore b/.gitignore
index 8e12062..e4935e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,20 +1,25 @@
+
+*.o
+*.patch
+*~
+.deps
+/GNUmakefile
+/maint.mk
Makefile
Makefile.in
aclocal.m4
autom4te.cache
+build-aux
config.h
config.h.in
config.log
config.status
configure
depcomp
-.deps
install-sh
+lib
+m4
missing
-stamp-h1
-*.o
-*.patch
-*~
-
src/matahari
src/qmf/com
+stamp-h1
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..acb2669
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "gnulib"]
+ path = gnulib
+ url = git://git.sv.gnu.org/gnulib.git
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index c9fd2c0..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,290 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
-2006, 2007, 2008 Free Software Foundation, Inc.
-
- This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 6. Often, you can also type `make uninstall' to remove the installed
- files again.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *Note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
diff --git a/Makefile.am b/Makefile.am
index defbd32..4e89c84 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,6 @@
-SUBDIRS = src
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = lib src
rpm: clean
@(unset CDPATH ; $(MAKE) dist && cp $(distdir).tar.gz \
diff --git a/README-hacking b/README-hacking
new file mode 100644
index 0000000..f350426
--- /dev/null
+++ b/README-hacking
@@ -0,0 +1,54 @@
+-*- outline -*-
+
+These notes intend to help people working on the checked-out sources.
+These requirements do not apply when building from a distribution tarball.
+See also HACKING for more detailed Matahari contribution guidelines.
+
+* Requirements
+
+We've opted to keep only the highest-level sources in the GIT repository.
+This eases our maintenance burden, (fewer merges etc.), but imposes more
+requirements on anyone wishing to build from the just-checked-out sources.
+Note the requirements to build the released archive are much less and
+are just the requirements of the standard ./configure && make procedure.
+Specific development tools and versions will be checked for and listed by
+the bootstrap script.
+
+While building from a just-cloned source tree may require installing a
+few prerequisites, later, a plain `git pull && make' should be sufficient.
+
+* First GIT checkout
+
+You can get a copy of the source repository like this:
+
+ $ git clone git://git.fedorahosted.org/git/matahari.git
+ $ cd matahari
+
+As an optional step, if you already have a copy of the gnulib git
+repository on your hard drive, then you can use it as a reference to
+reduce download time and disk space requirements:
+
+ $ export GNULIB_SRCDIR=/path/to/gnulib
+
+The next step is to get all required pieces from gnulib,
+to run autoreconf, and to invoke ./configure:
+
+ $ ./autogen.sh
+
+And there you are! Just
+
+ $ make
+ $ make check
+
+At this point, there should be no difference between your local copy,
+and the GIT master copy:
+
+ $ git diff
+
+should output no difference.
+
+Enjoy!
+
+Local Variables:
+indent-tabs-mode: nil
+End:
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..2422549
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,855 @@
+#! /bin/sh
+# Print a version string.
+scriptversion=2010-05-17.18; # UTC
+
+# Bootstrap this package from checked-out sources.
+
+# Copyright (C) 2003-2010 Free Software Foundation, Inc.
+
+# 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 3 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Originally written by Paul Eggert. The canonical version of this
+# script is maintained as build-aux/bootstrap in gnulib, however, to
+# be useful to your project, you should place a copy of it under
+# version control in the top-level directory of your project. The
+# intent is that all customization can be done with a bootstrap.conf
+# file also maintained in your version control; gnulib comes with a
+# template build-aux/bootstrap.conf to get you started.
+
+# Please report bugs or propose patches to bug-gnulib(a)gnu.org.
+
+nl='
+'
+
+# Ensure file names are sorted consistently across platforms.
+LC_ALL=C
+export LC_ALL
+
+local_gl_dir=gl
+
+# Temporary directory names.
+bt='._bootmp'
+bt_regex=`echo "$bt"| sed 's/\./[.]/g'`
+bt2=${bt}2
+
+usage() {
+ cat <<EOF
+Usage: $0 [OPTION]...
+Bootstrap this package from the checked-out sources.
+
+Options:
+ --gnulib-srcdir=DIRNAME Specify the local directory where gnulib
+ sources reside. Use this if you already
+ have gnulib sources on your machine, and
+ do not want to waste your bandwidth downloading
+ them again. Defaults to \$GNULIB_SRCDIR.
+ --copy Copy files instead of creating symbolic links.
+ --force Attempt to bootstrap even if the sources seem
+ not to have been checked out.
+ --skip-po Do not download po files.
+
+If the file $0.conf exists in the same directory as this script, its
+contents are read as shell variables to configure the bootstrap.
+
+For build prerequisites, environment variables like \$AUTOCONF and \$AMTAR
+are honored.
+
+Running without arguments will suffice in most cases.
+EOF
+}
+
+# Configuration.
+
+# Name of the Makefile.am
+gnulib_mk=gnulib.mk
+
+# List of gnulib modules needed.
+gnulib_modules=
+
+# Any gnulib files needed that are not in modules.
+gnulib_files=
+
+# A function to be called after everything else in this script.
+# Override it via your own definition in bootstrap.conf.
+bootstrap_epilogue() { :; }
+
+# The command to download all .po files for a specified domain into
+# a specified directory. Fill in the first %s is the domain name, and
+# the second with the destination directory. Use rsync's -L and -r
+# options because the latest/%s directory and the .po files within are
+# all symlinks.
+po_download_command_format=\
+"rsync -Lrtvz 'translationproject.org::tp/latest/%s/' '%s'"
+
+extract_package_name='
+ /^AC_INIT(/{
+ /.*,.*,.*, */{
+ s///
+ s/[][]//g
+ s/)$//
+ p
+ q
+ }
+ s/AC_INIT(\[*//
+ s/]*,.*//
+ s/^GNU //
+ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ s/[^A-Za-z0-9_]/-/g
+ p
+ }
+'
+package=`sed -n "$extract_package_name" configure.ac` || exit
+gnulib_name=lib$package
+
+build_aux=build-aux
+source_base=lib
+m4_base=m4
+doc_base=doc
+tests_base=tests
+
+# Extra files from gnulib, which override files from other sources.
+gnulib_extra_files="
+ $build_aux/install-sh
+ $build_aux/missing
+ $build_aux/mdate-sh
+ $build_aux/texinfo.tex
+ $build_aux/depcomp
+ $build_aux/config.guess
+ $build_aux/config.sub
+ doc/INSTALL
+"
+
+# Additional gnulib-tool options to use. Use "\newline" to break lines.
+gnulib_tool_option_extras=
+
+# Other locale categories that need message catalogs.
+EXTRA_LOCALE_CATEGORIES=
+
+# Additional xgettext options to use. Use "\\\newline" to break lines.
+XGETTEXT_OPTIONS='\\\
+ --flag=_:1:pass-c-format\\\
+ --flag=N_:1:pass-c-format\\\
+ --flag=error:3:c-format --flag=error_at_line:5:c-format\\\
+'
+
+# Package bug report address and copyright holder for gettext files
+COPYRIGHT_HOLDER='Free Software Foundation, Inc.'
+MSGID_BUGS_ADDRESS=bug-$package(a)gnu.org
+
+# Files we don't want to import.
+excluded_files=
+
+# File that should exist in the top directory of a checked out hierarchy,
+# but not in a distribution tarball.
+checkout_only_file=README-hacking
+
+# Whether to use copies instead of symlinks.
+copy=false
+
+# Set this to '.cvsignore .gitignore' in bootstrap.conf if you want
+# those files to be generated in directories like lib/, m4/, and po/.
+# Or set it to 'auto' to make this script select which to use based
+# on which version control system (if any) is used in the source directory.
+vc_ignore=auto
+
+# find_tool ENVVAR NAMES...
+# -------------------------
+# Search for a required program. Use the value of ENVVAR, if set,
+# otherwise find the first of the NAMES that can be run (i.e.,
+# supports --version). If found, set ENVVAR to the program name,
+# die otherwise.
+find_tool ()
+{
+ find_tool_envvar=$1
+ shift
+ find_tool_names=$@
+ eval "find_tool_res=\$$find_tool_envvar"
+ if test x"$find_tool_res" = x; then
+ for i
+ do
+ if ($i --version </dev/null) >/dev/null 2>&1; then
+ find_tool_res=$i
+ break
+ fi
+ done
+ else
+ find_tool_error_prefix="\$$find_tool_envvar: "
+ fi
+ if test x"$find_tool_res" = x; then
+ echo >&2 "$0: one of these is required: $find_tool_names"
+ exit 1
+ fi
+ ($find_tool_res --version </dev/null) >/dev/null 2>&1 || {
+ echo >&2 "$0: ${find_tool_error_prefix}cannot run $find_tool_res --version"
+ exit 1
+ }
+ eval "$find_tool_envvar=\$find_tool_res"
+ eval "export $find_tool_envvar"
+}
+
+# Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6.
+find_tool SHA1SUM sha1sum gsha1sum shasum
+
+# Override the default configuration, if necessary.
+# Make sure that bootstrap.conf is sourced from the current directory
+# if we were invoked as "sh bootstrap".
+case "$0" in
+ */*) test -r "$0.conf" && . "$0.conf" ;;
+ *) test -r "$0.conf" && . ./"$0.conf" ;;
+esac
+
+
+if test "$vc_ignore" = auto; then
+ vc_ignore=
+ test -d .git && vc_ignore=.gitignore
+ test -d CVS && vc_ignore="$vc_ignore .cvsignore"
+fi
+
+# Translate configuration into internal form.
+
+# Parse options.
+
+for option
+do
+ case $option in
+ --help)
+ usage
+ exit;;
+ --gnulib-srcdir=*)
+ GNULIB_SRCDIR=`expr "X$option" : 'X--gnulib-srcdir=\(.*\)'`;;
+ --skip-po)
+ SKIP_PO=t;;
+ --force)
+ checkout_only_file=;;
+ --copy)
+ copy=true;;
+ *)
+ echo >&2 "$0: $option: unknown option"
+ exit 1;;
+ esac
+done
+
+if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then
+ echo "$0: Bootstrapping from a non-checked-out distribution is risky." >&2
+ exit 1
+fi
+
+# If $STR is not already on a line by itself in $FILE, insert it,
+# sorting the new contents of the file and replacing $FILE with the result.
+insert_sorted_if_absent() {
+ file=$1
+ str=$2
+ test -f $file || touch $file
+ echo "$str" | sort -u - $file | cmp - $file > /dev/null \
+ || echo "$str" | sort -u - $file -o $file \
+ || exit 1
+}
+
+# Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
+found_aux_dir=no
+grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \
+ >/dev/null && found_aux_dir=yes
+grep '^[ ]*AC_CONFIG_AUX_DIR('"$build_aux"')' configure.ac \
+ >/dev/null && found_aux_dir=yes
+if test $found_aux_dir = no; then
+ echo "$0: expected line not found in configure.ac. Add the following:" >&2
+ echo " AC_CONFIG_AUX_DIR([$build_aux])" >&2
+ exit 1
+fi
+
+# If $build_aux doesn't exist, create it now, otherwise some bits
+# below will malfunction. If creating it, also mark it as ignored.
+if test ! -d $build_aux; then
+ mkdir $build_aux
+ for dot_ig in x $vc_ignore; do
+ test $dot_ig = x && continue
+ insert_sorted_if_absent $dot_ig $build_aux
+ done
+fi
+
+# Note this deviates from the version comparison in automake
+# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
+# but this should suffice as we won't be specifying old
+# version formats or redundant trailing .0 in bootstrap.conf.
+# If we did want full compatibility then we should probably
+# use m4_version_compare from autoconf.
+sort_ver() { # sort -V is not generally available
+ ver1="$1"
+ ver2="$2"
+
+ # split on '.' and compare each component
+ i=1
+ while : ; do
+ p1=$(echo "$ver1" | cut -d. -f$i)
+ p2=$(echo "$ver2" | cut -d. -f$i)
+ if [ ! "$p1" ]; then
+ echo "$1 $2"
+ break
+ elif [ ! "$p2" ]; then
+ echo "$2 $1"
+ break
+ elif [ ! "$p1" = "$p2" ]; then
+ if [ "$p1" -gt "$p2" ] 2>/dev/null; then # numeric comparison
+ echo "$2 $1"
+ elif [ "$p2" -gt "$p1" ] 2>/dev/null; then # numeric comparison
+ echo "$1 $2"
+ else # numeric, then lexicographic comparison
+ lp=$(printf "$p1\n$p2\n" | LANG=C sort -n | tail -n1)
+ if [ "$lp" = "$p2" ]; then
+ echo "$1 $2"
+ else
+ echo "$2 $1"
+ fi
+ fi
+ break
+ fi
+ i=$(($i+1))
+ done
+}
+
+get_version() {
+ app=$1
+
+ $app --version >/dev/null 2>&1 || return 1
+
+ $app --version 2>&1 |
+ sed -n '# extract version within line
+ s/.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
+ t done
+
+ # extract version at start of line
+ s/^\([0-9]\{1,\}\.[.a-z0-9-]*\).*/\1/
+ t done
+
+ d
+
+ :done
+ #the following essentially does s/5.005/5.5/
+ s/\.0*\([1-9]\)/.\1/g
+ p
+ q'
+}
+
+check_versions() {
+ ret=0
+
+ while read app req_ver; do
+ # Honor $APP variables ($TAR, $AUTOCONF, etc.)
+ appvar=`echo $app | tr '[a-z]' '[A-Z]'`
+ test "$appvar" = TAR && appvar=AMTAR
+ eval "app=\${$appvar-$app}"
+ inst_ver=$(get_version $app)
+ if [ ! "$inst_ver" ]; then
+ echo "Error: '$app' not found" >&2
+ ret=1
+ elif [ ! "$req_ver" = "-" ]; then
+ latest_ver=$(sort_ver $req_ver $inst_ver | cut -d' ' -f2)
+ if [ ! "$latest_ver" = "$inst_ver" ]; then
+ echo "Error: '$app' version == $inst_ver is too old" >&2
+ echo " '$app' version >= $req_ver is required" >&2
+ ret=1
+ fi
+ fi
+ done
+
+ return $ret
+}
+
+print_versions() {
+ echo "Program Min_version"
+ echo "----------------------"
+ printf "$buildreq"
+ echo "----------------------"
+ # can't depend on column -t
+}
+
+if ! printf "$buildreq" | check_versions; then
+ test -f README-prereq &&
+ echo "See README-prereq for notes on obtaining these prerequisite programs:" >&2
+ echo
+ print_versions
+ exit 1
+fi
+
+echo "$0: Bootstrapping from checked-out $package sources..."
+
+# See if we can use gnulib's git-merge-changelog merge driver.
+if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
+ if git config merge.merge-changelog.driver >/dev/null ; then
+ :
+ elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
+ echo "initializing git-merge-changelog driver"
+ git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
+ git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
+ else
+ echo "consider installing git-merge-changelog from gnulib"
+ fi
+fi
+
+
+cleanup_gnulib() {
+ status=$?
+ rm -fr "$gnulib_path"
+ exit $status
+}
+
+git_modules_config () {
+ test -f .gitmodules && git config --file .gitmodules "$@"
+}
+
+gnulib_path=`git_modules_config submodule.gnulib.path`
+: ${gnulib_path=gnulib}
+
+# Get gnulib files.
+
+case ${GNULIB_SRCDIR--} in
+-)
+ if git_modules_config submodule.gnulib.url >/dev/null; then
+ echo "$0: getting gnulib files..."
+ git submodule init || exit $?
+ git submodule update || exit $?
+
+ elif [ ! -d "$gnulib_path" ]; then
+ echo "$0: getting gnulib files..."
+
+ trap cleanup_gnulib 1 2 13 15
+
+ shallow=
+ git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2'
+ git clone $shallow git://git.sv.gnu.org/gnulib "$gnulib_path" ||
+ cleanup_gnulib
+
+ trap - 1 2 13 15
+ fi
+ GNULIB_SRCDIR=$gnulib_path
+ ;;
+*)
+ # Use GNULIB_SRCDIR as a reference.
+ if test -d "$GNULIB_SRCDIR"/.git && \
+ git_modules_config submodule.gnulib.url >/dev/null; then
+ echo "$0: getting gnulib files..."
+ if git submodule -h|grep -- --reference > /dev/null; then
+ # Prefer the one-liner available in git 1.6.4 or newer.
+ git submodule update --init --reference "$GNULIB_SRCDIR" \
+ "$gnulib_path" || exit $?
+ else
+ # This fallback allows at least git 1.5.5.
+ if test -f "$gnulib_path"/gnulib-tool; then
+ # Since file already exists, assume submodule init already complete.
+ git submodule update || exit $?
+ else
+ # Older git can't clone into an empty directory.
+ rmdir "$gnulib_path" 2>/dev/null
+ git clone --reference "$GNULIB_SRCDIR" \
+ "$(git_modules_config submodule.gnulib.url)" "$gnulib_path" \
+ && git submodule init && git submodule update \
+ || exit $?
+ fi
+ fi
+ GNULIB_SRCDIR=$gnulib_path
+ fi
+ ;;
+esac
+
+gnulib_tool=$GNULIB_SRCDIR/gnulib-tool
+<$gnulib_tool || exit
+
+# Get translations.
+
+download_po_files() {
+ subdir=$1
+ domain=$2
+ echo "$0: getting translations into $subdir for $domain..."
+ cmd=`printf "$po_download_command_format" "$domain" "$subdir"`
+ eval "$cmd"
+}
+
+# Download .po files to $po_dir/.reference and copy only the new
+# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
+update_po_files() {
+ # Directory containing primary .po files.
+ # Overwrite them only when we're sure a .po file is new.
+ po_dir=$1
+ domain=$2
+
+ # Download *.po files into this dir.
+ # Usually contains *.s1 checksum files.
+ ref_po_dir="$po_dir/.reference"
+
+ test -d $ref_po_dir || mkdir $ref_po_dir || return
+ download_po_files $ref_po_dir $domain \
+ && ls "$ref_po_dir"/*.po 2>/dev/null |
+ sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
+
+ langs=`cd $ref_po_dir && echo *.po|sed 's/\.po//g'`
+ test "$langs" = '*' && langs=x
+ for po in $langs; do
+ case $po in x) continue;; esac
+ new_po="$ref_po_dir/$po.po"
+ cksum_file="$ref_po_dir/$po.s1"
+ if ! test -f "$cksum_file" ||
+ ! test -f "$po_dir/$po.po" ||
+ ! $SHA1SUM -c --status "$cksum_file" \
+ < "$new_po" > /dev/null; then
+ echo "updated $po_dir/$po.po..."
+ cp "$new_po" "$po_dir/$po.po" \
+ && $SHA1SUM < "$new_po" > "$cksum_file"
+ fi
+ done
+}
+
+case $SKIP_PO in
+'')
+ if test -d po; then
+ update_po_files po $package || exit
+ fi
+
+ if test -d runtime-po; then
+ update_po_files runtime-po $package-runtime || exit
+ fi;;
+esac
+
+symlink_to_dir()
+{
+ src=$1/$2
+ dst=${3-$2}
+
+ test -f "$src" && {
+
+ # If the destination directory doesn't exist, create it.
+ # This is required at least for "lib/uniwidth/cjk.h".
+ dst_dir=`dirname "$dst"`
+ if ! test -d "$dst_dir"; then
+ mkdir -p "$dst_dir"
+
+ # If we've just created a directory like lib/uniwidth,
+ # tell version control system(s) it's ignorable.
+ # FIXME: for now, this does only one level
+ parent=`dirname "$dst_dir"`
+ for dot_ig in x $vc_ignore; do
+ test $dot_ig = x && continue
+ ig=$parent/$dot_ig
+ insert_sorted_if_absent $ig `echo "$dst_dir"|sed 's,.*/,,'`
+ done
+ fi
+
+ if $copy; then
+ {
+ test ! -h "$dst" || {
+ echo "$0: rm -f $dst" &&
+ rm -f "$dst"
+ }
+ } &&
+ test -f "$dst" &&
+ cmp -s "$src" "$dst" || {
+ echo "$0: cp -fp $src $dst" &&
+ cp -fp "$src" "$dst"
+ }
+ else
+ test -h "$dst" &&
+ src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 &&
+ dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 &&
+ test "$src_i" = "$dst_i" || {
+ dot_dots=
+ case $src in
+ /*) ;;
+ *)
+ case /$dst/ in
+ *//* | */../* | */./* | /*/*/*/*/*/)
+ echo >&2 "$0: invalid symlink calculation: $src -> $dst"
+ exit 1;;
+ /*/*/*/*/) dot_dots=../../../;;
+ /*/*/*/) dot_dots=../../;;
+ /*/*/) dot_dots=../;;
+ esac;;
+ esac
+
+ echo "$0: ln -fs $dot_dots$src $dst" &&
+ ln -fs "$dot_dots$src" "$dst"
+ }
+ fi
+ }
+}
+
+cp_mark_as_generated()
+{
+ cp_src=$1
+ cp_dst=$2
+
+ if cmp -s "$cp_src" "$GNULIB_SRCDIR/$cp_dst"; then
+ symlink_to_dir "$GNULIB_SRCDIR" "$cp_dst"
+ elif cmp -s "$cp_src" "$local_gl_dir/$cp_dst"; then
+ symlink_to_dir $local_gl_dir "$cp_dst"
+ else
+ case $cp_dst in
+ *.[ch]) c1='/* '; c2=' */';;
+ *.texi) c1='@c '; c2= ;;
+ *.m4|*/Make*|Make*) c1='# ' ; c2= ;;
+ *) c1= ; c2= ;;
+ esac
+
+ # If the destination directory doesn't exist, create it.
+ # This is required at least for "lib/uniwidth/cjk.h".
+ dst_dir=`dirname "$cp_dst"`
+ test -d "$dst_dir" || mkdir -p "$dst_dir"
+
+ if test -z "$c1"; then
+ cmp -s "$cp_src" "$cp_dst" || {
+ # Copy the file first to get proper permissions if it
+ # doesn't already exist. Then overwrite the copy.
+ echo "$0: cp -f $cp_src $cp_dst" &&
+ rm -f "$cp_dst" &&
+ cp "$cp_src" "$cp_dst-t" &&
+ sed "s!$bt_regex/!!g" "$cp_src" > "$cp_dst-t" &&
+ mv -f "$cp_dst-t" "$cp_dst"
+ }
+ else
+ # Copy the file first to get proper permissions if it
+ # doesn't already exist. Then overwrite the copy.
+ cp "$cp_src" "$cp_dst-t" &&
+ (
+ echo "$c1-*- buffer-read-only: t -*- vi: set ro:$c2" &&
+ echo "${c1}DO NOT EDIT! GENERATED AUTOMATICALLY!$c2" &&
+ sed "s!$bt_regex/!!g" "$cp_src"
+ ) > $cp_dst-t &&
+ if cmp -s "$cp_dst-t" "$cp_dst"; then
+ rm -f "$cp_dst-t"
+ else
+ echo "$0: cp $cp_src $cp_dst # with edits" &&
+ mv -f "$cp_dst-t" "$cp_dst"
+ fi
+ fi
+ fi
+}
+
+version_controlled_file() {
+ dir=$1
+ file=$2
+ found=no
+ if test -d CVS; then
+ grep -F "/$file/" $dir/CVS/Entries 2>/dev/null |
+ grep '^/[^/]*/[0-9]' > /dev/null && found=yes
+ elif test -d .git; then
+ git rm -n "$dir/$file" > /dev/null 2>&1 && found=yes
+ elif test -d .svn; then
+ svn log -r HEAD "$dir/$file" > /dev/null 2>&1 && found=yes
+ else
+ echo "$0: no version control for $dir/$file?" >&2
+ fi
+ test $found = yes
+}
+
+slurp() {
+ for dir in . `(cd $1 && find * -type d -print)`; do
+ copied=
+ sep=
+ for file in `ls -a $1/$dir`; do
+ case $file in
+ .|..) continue;;
+ .*) continue;; # FIXME: should all file names starting with "." be ignored?
+ esac
+ test -d $1/$dir/$file && continue
+ for excluded_file in $excluded_files; do
+ test "$dir/$file" = "$excluded_file" && continue 2
+ done
+ if test $file = Makefile.am && test "X$gnulib_mk" != XMakefile.am; then
+ copied=$copied${sep}$gnulib_mk; sep=$nl
+ remove_intl='/^[^#].*\/intl/s/^/#/;'"s!$bt_regex/!!g"
+ sed "$remove_intl" $1/$dir/$file | cmp - $dir/$gnulib_mk > /dev/null || {
+ echo "$0: Copying $1/$dir/$file to $dir/$gnulib_mk ..." &&
+ rm -f $dir/$gnulib_mk &&
+ sed "$remove_intl" $1/$dir/$file >$dir/$gnulib_mk
+ }
+ elif { test "${2+set}" = set && test -r $2/$dir/$file; } ||
+ version_controlled_file $dir $file; then
+ echo "$0: $dir/$file overrides $1/$dir/$file"
+ else
+ copied=$copied$sep$file; sep=$nl
+ if test $file = gettext.m4; then
+ echo "$0: patching m4/gettext.m4 to remove need for intl/* ..."
+ rm -f $dir/$file
+ sed '
+ /^AC_DEFUN(\[AM_INTL_SUBDIR],/,/^]/c\
+ AC_DEFUN([AM_INTL_SUBDIR], [])
+ /^AC_DEFUN(\[gt_INTL_SUBDIR_CORE],/,/^]/c\
+ AC_DEFUN([gt_INTL_SUBDIR_CORE], [])
+ $a\
+ AC_DEFUN([gl_LOCK_EARLY], [])
+ ' $1/$dir/$file >$dir/$file
+ else
+ cp_mark_as_generated $1/$dir/$file $dir/$file
+ fi
+ fi || exit
+ done
+
+ for dot_ig in x $vc_ignore; do
+ test $dot_ig = x && continue
+ ig=$dir/$dot_ig
+ if test -n "$copied"; then
+ insert_sorted_if_absent $ig "$copied"
+ # If an ignored file name ends with .in.h, then also add
+ # the name with just ".h". Many gnulib headers are generated,
+ # e.g., stdint.in.h -> stdint.h, dirent.in.h ->..., etc.
+ # Likewise for .gperf -> .h, .y -> .c, and .sin -> .sed
+ f=`echo "$copied"|sed 's/\.in\.h$/.h/;s/\.sin$/.sed/;s/\.y$/.c/;s/\.gperf$/.h/'`
+ insert_sorted_if_absent $ig "$f"
+
+ # For files like sys_stat.in.h and sys_time.in.h, record as
+ # ignorable the directory we might eventually create: sys/.
+ f=`echo "$copied"|sed 's/sys_.*\.in\.h$/sys/'`
+ insert_sorted_if_absent $ig "$f"
+ fi
+ done
+ done
+}
+
+
+# Create boot temporary directories to import from gnulib and gettext.
+rm -fr $bt $bt2 &&
+mkdir $bt $bt2 || exit
+
+# Import from gnulib.
+
+gnulib_tool_options="\
+ --import\
+ --no-changelog\
+ --aux-dir $bt/$build_aux\
+ --doc-base $bt/$doc_base\
+ --lib $gnulib_name\
+ --m4-base $bt/$m4_base/\
+ --source-base $bt/$source_base/\
+ --tests-base $bt/$tests_base\
+ --local-dir $local_gl_dir\
+ $gnulib_tool_option_extras\
+"
+echo "$0: $gnulib_tool $gnulib_tool_options --import ..."
+$gnulib_tool $gnulib_tool_options --import $gnulib_modules &&
+slurp $bt || exit
+
+for file in $gnulib_files; do
+ symlink_to_dir "$GNULIB_SRCDIR" $file || exit
+done
+
+
+# Import from gettext.
+with_gettext=yes
+grep '^[ ]*AM_GNU_GETTEXT_VERSION(' configure.ac >/dev/null || \
+ with_gettext=no
+
+if test $with_gettext = yes; then
+ echo "$0: (cd $bt2; ${AUTOPOINT-autopoint}) ..."
+ cp configure.ac $bt2 &&
+ (cd $bt2 && ${AUTOPOINT-autopoint} && rm configure.ac) &&
+ slurp $bt2 $bt || exit
+fi
+rm -fr $bt $bt2 || exit
+
+# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
+# gnulib-populated directories. Such .m4 files would cause aclocal to fail.
+# The following requires GNU find 4.2.3 or newer. Considering the usual
+# portability constraints of this script, that may seem a very demanding
+# requirement, but it should be ok. Ignore any failure, which is fine,
+# since this is only a convenience to help developers avoid the relatively
+# unusual case in which a symlinked-to .m4 file is git-removed from gnulib
+# between successive runs of this script.
+find "$m4_base" "$source_base" \
+ -depth \( -name '*.m4' -o -name '*.[ch]' \) \
+ -type l -xtype l -delete > /dev/null 2>&1
+
+# Reconfigure, getting other files.
+
+# Skip autoheader if it's not needed.
+grep -E '^[ ]*AC_CONFIG_HEADERS?\>' configure.ac >/dev/null ||
+ AUTOHEADER=true
+
+for command in \
+ libtool \
+ "${ACLOCAL-aclocal} --force -I m4" \
+ "${AUTOCONF-autoconf} --force" \
+ "${AUTOHEADER-autoheader} --force" \
+ "${AUTOMAKE-automake} --add-missing --copy --force-missing"
+do
+ if test "$command" = libtool; then
+ use_libtool=0
+ # We'd like to use grep -E, to see if any of LT_INIT,
+ # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
+ # but that's not portable enough (e.g., for Solaris).
+ grep '^[ ]*A[CM]_PROG_LIBTOOL' configure.ac >/dev/null \
+ && use_libtool=1
+ grep '^[ ]*LT_INIT' configure.ac >/dev/null \
+ && use_libtool=1
+ test $use_libtool = 0 \
+ && continue
+ command="${LIBTOOLIZE-libtoolize} -c -f"
+ fi
+ echo "$0: $command ..."
+ $command || exit
+done
+
+
+# Get some extra files from gnulib, overriding existing files.
+for file in $gnulib_extra_files; do
+ case $file in
+ */INSTALL) dst=INSTALL;;
+ build-aux/*) dst=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
+ *) dst=$file;;
+ esac
+ symlink_to_dir "$GNULIB_SRCDIR" $file $dst || exit
+done
+
+if test $with_gettext = yes; then
+ # Create gettext configuration.
+ echo "$0: Creating po/Makevars from po/Makevars.template ..."
+ rm -f po/Makevars
+ sed '
+ /^EXTRA_LOCALE_CATEGORIES *=/s/=.*/= '"$EXTRA_LOCALE_CATEGORIES"'/
+ /^COPYRIGHT_HOLDER *=/s/=.*/= '"$COPYRIGHT_HOLDER"'/
+ /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$MSGID_BUGS_ADDRESS"'|
+ /^XGETTEXT_OPTIONS *=/{
+ s/$/ \\/
+ a\
+ '"$XGETTEXT_OPTIONS"' $${end_of_xgettext_options+}
+ }
+ ' po/Makevars.template >po/Makevars || exit 1
+
+ if test -d runtime-po; then
+ # Similarly for runtime-po/Makevars, but not quite the same.
+ rm -f runtime-po/Makevars
+ sed '
+ /^DOMAIN *=.*/s/=.*/= '"$package"'-runtime/
+ /^subdir *=.*/s/=.*/= runtime-po/
+ /^MSGID_BUGS_ADDRESS *=/s/=.*/= bug-'"$package"'@gnu.org/
+ /^XGETTEXT_OPTIONS *=/{
+ s/$/ \\/
+ a\
+ '"$XGETTEXT_OPTIONS_RUNTIME"' $${end_of_xgettext_options+}
+ }
+ ' po/Makevars.template >runtime-po/Makevars || exit 1
+
+ # Copy identical files from po to runtime-po.
+ (cd po && cp -p Makefile.in.in *-quot *.header *.sed *.sin ../runtime-po)
+ fi
+fi
+
+bootstrap_epilogue
+
+echo "$0: done. Now you can run './configure'."
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/bootstrap.conf b/bootstrap.conf
new file mode 100644
index 0000000..8d602c1
--- /dev/null
+++ b/bootstrap.conf
@@ -0,0 +1,67 @@
+# Bootstrap configuration.
+
+# Copyright (C) 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+
+# 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 3 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.
+
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# gnulib modules used by this package.
+gnulib_modules="
+maintainer-makefile
+strdup-posix
+"
+
+# Additional xgettext options to use. Use "\\\newline" to break lines.
+XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
+ --from-code=UTF-8\\\
+ --flag=asprintf:2:c-format --flag=vasprintf:2:c-format\\\
+ --flag=asnprintf:3:c-format --flag=vasnprintf:3:c-format\\\
+ --flag=wrapf:1:c-format\\\
+'
+
+# If "AM_GNU_GETTEXT(external" or "AM_GNU_GETTEXT([external]"
+# appears in configure.ac, exclude some unnecessary files.
+# Without grep's -E option (not portable enough, pre-configure),
+# the following test is ugly. Also, this depends on the existence
+# of configure.ac, not the obsolescent-named configure.in. But if
+# you're using this infrastructure, you should care about such things.
+
+gettext_external=0
+grep '^[ ]*AM_GNU_GETTEXT(external\>' configure.ac > /dev/null &&
+ gettext_external=1
+grep '^[ ]*AM_GNU_GETTEXT(\[external\]' configure.ac > /dev/null &&
+ gettext_external=1
+
+if test $gettext_external = 1; then
+ # Gettext supplies these files, but we don't need them since
+ # we don't have an intl subdirectory.
+ excluded_files='
+ m4/glibc2.m4
+ m4/intdiv0.m4
+ m4/lcmessage.m4
+ m4/lock.m4
+ m4/printf-posix.m4
+ m4/size_max.m4
+ m4/uintmax_t.m4
+ m4/ulonglong.m4
+ m4/visibility.m4
+ m4/xsize.m4
+ '
+fi
+
+# This is not a GNU package, so the default bug address is invalid,
+# and the translation project is not in use.
+MSGID_BUGS_ADDRESS=libvir-list(a)redhat.com
+COPYRIGHT_HOLDER='Red Hat, Inc.'
+SKIP_PO=true
+gnulib_mk=Makefile.am
diff --git a/configure.ac b/configure.ac
index a33956f..9fda954 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,6 +5,7 @@ dnl ---------------------------------------------------------------------
AC_PREREQ([2.65])
AC_INIT([Matahari], [0.1.0], [matahari(a)lists.fedorahosted.org])
AC_CONFIG_SRCDIR([src/linux_platform.cpp])
+AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([src/config.h])
AC_CONFIG_MACRO_DIR([m4])
dnl Make automake keep quiet about wildcards & other GNUmake-isms
@@ -19,8 +20,12 @@ AC_PROG_CC
AC_PROG_CPP
CFLAGS="$cflags_save"
+gl_EARLY
+
AC_PROG_CC_C_O
+gl_INIT
+
AC_CHECK_PROG(HASQMFGEN, qmf-gen, "yes")
if test x"$HASQMFGEN" = "x"; then
AC_MSG_ERROR([Missing QMF schema processor.])
@@ -59,6 +64,7 @@ dnl ---------------------------------------------------------------------
AC_CHECK_FUNCS([strdup strerror sysinfo uname])
AC_CONFIG_FILES([Makefile
+ lib/Makefile
src/Makefile
src/tests/Makefile])
AC_OUTPUT
diff --git a/gnulib b/gnulib
new file mode 160000
index 0000000..fcdbbe0
--- /dev/null
+++ b/gnulib
@@ -0,0 +1 @@
+Subproject commit fcdbbe0069c767a03f42f7615175ac03494de93a
diff --git a/src/Makefile.am b/src/Makefile.am
index 4429851..20532b0 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,7 @@
-INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/matahari $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS) $(UDEV_CFLAGS)
+NCLUDES = -I$(top_builddir)/lib -I$(top_srcdir)/lib -I$(top_srcdir)/src/qmf/com/redhat/matahari $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS) $(UDEV_CFLAGS)
+
+AM_CFLAGS = $(INCLUDES)
+AM_CXXFLAGS = $(INCLUDES)
sbin_PROGRAMS = matahari
@@ -37,5 +40,6 @@ CLEANFILES = $(generated_file_list) $(first)
matahari_CPPFLAGS = -fno-strict-aliasing
matahari_LDADD = -lpcre -lqmf -lqpidclient -lqpidcommon -ludev -lvirt
+matahari_LDADD += ../lib/libmatahari.a
dist_pkgdata_DATA = schema.xml
diff --git a/src/host.cpp b/src/host.cpp
index 39655d2..dfb83f5 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "host.h"
#include "platform.h"
diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp
index d79f947..8b70f37 100644
--- a/src/linux_platform.cpp
+++ b/src/linux_platform.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include <fstream>
#include <iomanip>
#include <iostream>
diff --git a/src/main.cpp b/src/main.cpp
index c0ffd94..27b2434 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include <qpid/agent/ManagementAgent.h>
#include <qpid/client/ConnectionSettings.h>
diff --git a/src/platform.cpp b/src/platform.cpp
index 69f528b..087cf2a 100644
--- a/src/platform.cpp
+++ b/src/platform.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "platform.h"
#include "linux_platform.h"
diff --git a/src/qmf/hostagent.cpp b/src/qmf/hostagent.cpp
index 682ad1c..94004d5 100644
--- a/src/qmf/hostagent.cpp
+++ b/src/qmf/hostagent.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "hostagent.h"
#include <qpid/agent/ManagementAgent.h>
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index a461cf1..13fea3d 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -4,8 +4,11 @@ bin_PROGRAMS = \
testmultiplexer
INCLUDES = \
+ -I$(top_builddir)/lib \
+ -I$(top_srcdir)/lib \
-I$(top_srcdir)/src
+
testmultiplexer_SOURCES = \
$(top_srcdir)/src/virtio/multiplexer.cpp \
$(top_srcdir)/src/virtio/multiplexer.h \
@@ -13,6 +16,7 @@ testmultiplexer_SOURCES = \
testmultiplexer.h
testmultiplexer_LDADD = -lcppunit
+testmultiplexer_LDADD += ../../lib/libgnu.a
testhostapis_SOURCES = \
$(top_srcdir)/src/host.cpp \
@@ -25,4 +29,5 @@ testhostapis_SOURCES = \
testhostapis.h
testhostapis_LDFLAGS = -L/usr/local/lib
-testhostapis_LDADD = -lcppunit $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
\ No newline at end of file
+testhostapis_LDADD = -lcppunit $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
+testhostapis_LDADD += ../../lib/libmatahari.a
diff --git a/src/tests/testhostapis.cpp b/src/tests/testhostapis.cpp
index 0a12786..9710700 100644
--- a/src/tests/testhostapis.cpp
+++ b/src/tests/testhostapis.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "testhostapis.h"
#include "host.h"
diff --git a/src/tests/testmultiplexer.cpp b/src/tests/testmultiplexer.cpp
index 8ed77fd..6208cc2 100644
--- a/src/tests/testmultiplexer.cpp
+++ b/src/tests/testmultiplexer.cpp
@@ -17,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "testmultiplexer.h"
#include "virtio/multiplexer.h"
diff --git a/src/virtio/multiplexer.cpp b/src/virtio/multiplexer.cpp
index 79f8b35..8f72ddc 100644
--- a/src/virtio/multiplexer.cpp
+++ b/src/virtio/multiplexer.cpp
@@ -1,5 +1,3 @@
-#include "multiplexer.h"
-
/* multiplexer.cpp - Copyright (C) 2010 Red Hat, Inc.
* Written by Darryl L. Pierce <dpierce(a)redhat.com>
*
@@ -19,6 +17,7 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
+#include <config.h>
#include "multiplexer.h"
// the singleton
@@ -60,3 +59,4 @@ Multiplexer::invokeAPI(string name, string input)
return result;
}
+
--
1.7.0.1
13 years, 10 months
Comprises one previous patch plus new changes...
by Darryl L. Pierce
This patch contains changes to remove the Platform C++ type and move all of
the code into conditionally compiled places in host.c.
It also folds in the previous patch to replace HostListener with C function
callbacks instead, and adds a second callback type for when the host wants
to update its status.
13 years, 10 months
Re: [Matahari] Releasing under GPLv3
by Andrew Beekhof
----- "Darryl L. Pierce" <dpierce(a)redhat.com> wrote:
> Is there any reason to keep Matahari under GPLv2 or can we move it to
> GPLv3?
Personally I prefer v2+.
v3 got a bit too restrictive (oh the irony) for my liking.
But its your code, if you want v3 I'd say its up to you.
You might need ACKs from anyone you got patches from in the past though.
13 years, 10 months
Releasing under GPLv3
by Darryl L. Pierce
Is there any reason to keep Matahari under GPLv2 or can we move it to
GPLv3?
--
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
13 years, 10 months
[PATCH matahari] Adds a byte stream data handler and refactors the multiplexer codebase.
by Darryl L. Pierce
From: Darryl L. Pierce <mcpierce(a)gmail.com>
A new type is defined, t_datahandler_payload, which carries the received
payload, the length of the payload, and the CRC value reported by the
receiver.
When a payload is processed, first its CRC32 value is verified against
the supplied CRC32 value. If it does not match, a failure response is
returned.
Next the request is parsed, it's type is validated as "request", and the
API name is extracted. If any of these fail, then a failure response is
returned.
When a response is generated, the format is validated.
The multiplexer functions were removed and replaced by simple C APIs.
The unit tests have all be moved into Check tests (C unit test
framework).
Added crc_lib, by Lammert Bies, for calculating CRC32 values.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
Makefile.am | 2 +-
configure.ac | 7 +-
src/Makefile.am | 10 +-
src/tests/.gitignore | 1 +
src/tests/Makefile.am | 26 ++-
src/tests/testdatahandler.c | 255 +++++++++++++++++++++++
src/tests/testmultiplexer.c | 179 ++++++++++++++++
src/tests/testmultiplexer.cpp | 109 ----------
src/tests/testmultiplexer.h | 46 ----
src/virtio/datahandler.c | 268 ++++++++++++++++++++++++
src/virtio/datahandler.h | 61 ++++++
src/virtio/lib_crc.c | 459 +++++++++++++++++++++++++++++++++++++++++
src/virtio/lib_crc.h | 66 ++++++
src/virtio/multiplexer.c | 122 +++++++++++
src/virtio/multiplexer.cpp | 62 ------
src/virtio/multiplexer.h | 46 +++--
16 files changed, 1469 insertions(+), 250 deletions(-)
create mode 100644 src/tests/testdatahandler.c
create mode 100644 src/tests/testmultiplexer.c
delete mode 100644 src/tests/testmultiplexer.cpp
delete mode 100644 src/tests/testmultiplexer.h
create mode 100644 src/virtio/datahandler.c
create mode 100644 src/virtio/datahandler.h
create mode 100644 src/virtio/lib_crc.c
create mode 100644 src/virtio/lib_crc.h
create mode 100644 src/virtio/multiplexer.c
delete mode 100644 src/virtio/multiplexer.cpp
diff --git a/Makefile.am b/Makefile.am
index defbd32..2e57d29 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = src
+SUBDIRS = src src/tests
rpm: clean
@(unset CDPATH ; $(MAKE) dist && cp $(distdir).tar.gz \
diff --git a/configure.ac b/configure.ac
index 3481c09..de181e6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,10 @@ AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
-AC_PROG_CPP
+AM_PROG_CC_C_O
+#AC_PROG_CPP
+
+AC_CHECK_LIB(xml2, xmlParseMemory, , [AC_MSG_ERROR([Missing libxml2 libraries.])])
AC_CHECK_PROG(HASQMFGEN, qmf-gen, "yes")
@@ -14,7 +17,7 @@ if test x"$HASQMFGEN" = "x"; then
AC_MSG_ERROR([Missing QMF schema processor.])
fi
-AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h unistd.h libudev.h])
+AC_CHECK_HEADERS([arpa/inet.h netinet/in.h sys/ioctl.h sys/socket.h unistd.h libudev.h libxml/parser.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
diff --git a/src/Makefile.am b/src/Makefile.am
index e55b299..0d64365 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/matahari $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS) $(UDEV_CFLAGS)
+INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/matahari -I/usr/include/libxml2 $(LIBVIRT_CFLAGS) $(PCRE_CFLAGS) $(UDEV_CFLAGS)
sbin_PROGRAMS = matahari
@@ -24,7 +24,11 @@ matahari_SOURCES = \
platform.h \
qmf/hostagent.cpp \
qmf/hostagent.h \
- virtio/multiplexer.cpp \
+ virtio/datahandler.c \
+ virtio/datahandler.h \
+ virtio/lib_crc.c \
+ virtio/lib_crc.h \
+ virtio/multiplexer.c \
virtio/multiplexer.h
$(generated_file_list): $(generated_file_list)
@@ -36,6 +40,6 @@ BUILT_SOURCES = $(generated_file_list) $(first)
CLEANFILES = $(generated_file_list) $(first)
matahari_CPPFLAGS = -fno-strict-aliasing
-matahari_LDADD = -lqmf -lqpidclient -lqpidcommon $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
+matahari_LDADD = -lqmf -lqpidclient -lqpidcommon -lxml2 $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
dist_pkgdata_DATA = schema.xml
diff --git a/src/tests/.gitignore b/src/tests/.gitignore
index 6d437f4..456f85d 100644
--- a/src/tests/.gitignore
+++ b/src/tests/.gitignore
@@ -1,2 +1,3 @@
+testdatahandler
testhostapis
testmultiplexer
diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
index a461cf1..a9583d7 100644
--- a/src/tests/Makefile.am
+++ b/src/tests/Makefile.am
@@ -1,18 +1,30 @@
bin_PROGRAMS = \
testhostapis \
- testmultiplexer
+ testmultiplexer \
+ testdatahandler
INCLUDES = \
- -I$(top_srcdir)/src
+ -I$(top_srcdir)/src \
+ -I/usr/include/libxml2
+
+testdatahandler_SOURCES = \
+ $(top_srcdir)/src/virtio/datahandler.c \
+ $(top_srcdir)/src/virtio/datahandler.h \
+ $(top_srcdir)/src/virtio/lib_crc.c \
+ $(top_srcdir)/src/virtio/lib_crc.h \
+ $(top_srcdir)/src/virtio/multiplexer.c \
+ $(top_srcdir)/src/virtio/multiplexer.h \
+ testdatahandler.c
+
+testdatahandler_LDADD = -lcheck -lxml2
testmultiplexer_SOURCES = \
- $(top_srcdir)/src/virtio/multiplexer.cpp \
+ $(top_srcdir)/src/virtio/multiplexer.c \
$(top_srcdir)/src/virtio/multiplexer.h \
- testmultiplexer.cpp \
- testmultiplexer.h
+ testmultiplexer.c
-testmultiplexer_LDADD = -lcppunit
+testmultiplexer_LDADD = -lcheck
testhostapis_SOURCES = \
$(top_srcdir)/src/host.cpp \
@@ -25,4 +37,4 @@ testhostapis_SOURCES = \
testhostapis.h
testhostapis_LDFLAGS = -L/usr/local/lib
-testhostapis_LDADD = -lcppunit $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
\ No newline at end of file
+testhostapis_LDADD = -lcppunit $(LIBVIRT_LIBS) $(PCRE_LIBS) $(UDEV_LIBS)
diff --git a/src/tests/testdatahandler.c b/src/tests/testdatahandler.c
new file mode 100644
index 0000000..09dfdb7
--- /dev/null
+++ b/src/tests/testdatahandler.c
@@ -0,0 +1,255 @@
+/* testdatahandler.c - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <check.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "virtio/datahandler.h"
+
+t_datahandler_payload payload;
+
+#define REPLACE_REQUEST(payload, content) {\
+ payload.request_payload = content;\
+ payload.request_length = strlen(content);\
+ payload.request_crc = datahandler_calculate_crc(content, strlen(content)); \
+ }
+
+#define APINAME "testapi"
+
+void
+setup(void)
+{
+ payload.request_payload = "\
+ <matahari type=\"request\" api=\"testapi\">\n\
+ <args>\n\
+ <arg name=\"foo\">bar</arg>\n\
+ </args>\n\
+ </matahari>";
+ payload.request_length = strlen(payload.request_payload);
+ payload.request_crc =
+ datahandler_calculate_crc(payload.request_payload,
+ payload.request_length);
+}
+
+void
+teardown(void)
+{}
+
+START_TEST (test_validate_crc)
+{
+ char* value = "123456789";
+ unsigned int length = strlen(value);
+
+ fail_unless (datahandler_calculate_crc(value, length) == 3421780262L,
+ "The returned CRC value was invalid.");
+}
+END_TEST
+
+int
+check_response(t_datahandler_payload payload, char* expression)
+{
+ int result = -1;
+
+ xmlDocPtr document = xmlParseMemory(payload.response_payload,
+ payload.response_length);
+ if(document)
+ {
+ xmlXPathContextPtr context = xmlXPathNewContext(document);
+
+ if(context)
+ {
+ xmlXPathObjectPtr xpathobj =
+ xmlXPathEvalExpression(BAD_CAST expression, context);
+
+ if(xpathobj && ! xmlXPathNodeSetIsEmpty(xpathobj->nodesetval))
+ {
+ result = 0;
+ }
+
+ if(xpathobj) xmlXPathFreeObject(xpathobj);
+ xmlXPathFreeContext(context);
+ }
+ xmlFreeDoc(document);
+ }
+
+ return result;
+}
+
+START_TEST (test_process_with_null_data)
+{
+ fail_unless (datahandler_process_payload(NULL) == -1,
+ "Call should have returned an error.");
+}
+END_TEST
+
+START_TEST (test_process_with_empty_data)
+{
+ REPLACE_REQUEST(payload, "");
+
+ fail_unless (!datahandler_process_payload(&payload),
+ "Call should not have failed.");
+ fail_unless (!check_response(payload, "/matahari[@type='failure']"),
+ "The response should have indicated a failure.");
+}
+END_TEST
+
+START_TEST (test_process_with_invalid_crc)
+{
+ payload.request_crc++;
+
+ fail_unless (!datahandler_process_payload(&payload),
+ "Called should not have failed.");
+ fail_unless (!check_response(payload, "/matahari[@type='failure']"),
+ "The response should have indicated failure.");
+}
+END_TEST
+
+#define REQUEST_SHOULD_NOT_HAVE_FAILED(payload) {\
+ fail_unless (!datahandler_process_payload(&payload),\
+ "Calls hould not have failed.");\
+ }
+
+#define RESPONSE_MUST_BE_A_FAILURE(payload) {\
+ fail_unless (!check_response(payload, "/matahari[@type='failure']"),\
+ "The response should have indicated a failure.");\
+ }
+START_TEST (test_process_with_invalid_xml)
+{
+ REPLACE_REQUEST(payload, "<farkle>");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_check_root)
+{
+ REPLACE_REQUEST(payload, "<matahatrack />");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_without_type)
+{
+ REPLACE_REQUEST(payload, "<matahari />");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_check_type)
+{
+ REPLACE_REQUEST(payload, "<matahari type=\"response\" api=\"foo\" />");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_without_api)
+{
+ REPLACE_REQUEST(payload, "<matahari type=\"request\" />");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_without_args)
+{
+ REPLACE_REQUEST(payload, "<matahari type=\"request\" api=\"test\">\
+ </matahari>");
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+const char*
+test_request_calls_api_callback(const char* payload)
+{
+ return "\
+ <response name=\"foo\">\
+ <element>\
+ <value name=\"bar\">Yo!</value>\
+ </element>\
+ </response>";
+}
+
+START_TEST (test_process_request_with_bad_api)
+{
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ RESPONSE_MUST_BE_A_FAILURE(payload);
+}
+END_TEST
+
+START_TEST (test_process_request_calls_api)
+{
+ multiplexer_register_api(APINAME, test_request_calls_api_callback);
+
+ REQUEST_SHOULD_NOT_HAVE_FAILED(payload);
+ fail_unless (!check_response(payload, "/matahari[@type='response']"),
+ "Response should have been of type 'response'.");
+}
+END_TEST
+
+Suite*
+datahandler_test_suite(void)
+{
+ Suite* result = suite_create("CRC");
+
+ TCase* tc_process = tcase_create("Process");
+ tcase_add_checked_fixture(tc_process, setup, teardown);
+ tcase_add_test(tc_process, test_validate_crc);
+ tcase_add_test(tc_process, test_process_with_null_data);
+ tcase_add_test(tc_process, test_process_with_empty_data);
+ tcase_add_test(tc_process, test_process_with_invalid_crc);
+ tcase_add_test(tc_process, test_process_with_invalid_xml);
+ tcase_add_test(tc_process, test_process_request_check_root);
+ tcase_add_test(tc_process, test_process_request_without_type);
+ tcase_add_test(tc_process, test_process_request_check_type);
+ tcase_add_test(tc_process, test_process_request_without_api);
+ tcase_add_test(tc_process, test_process_request_without_args);
+ tcase_add_test(tc_process, test_process_request_with_bad_api);
+ tcase_add_test(tc_process, test_process_request_calls_api);
+ suite_add_tcase(result, tc_process);
+
+ return result;
+}
+
+int
+main(int argc, char** argv)
+{
+ int failures;
+
+ Suite* suite = datahandler_test_suite();
+ SRunner* srunner = srunner_create(suite);
+
+ srunner_run_all(srunner, CK_NORMAL);
+ failures = srunner_ntests_failed(srunner);
+ srunner_free(srunner);
+
+ return (failures == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/tests/testmultiplexer.c b/src/tests/testmultiplexer.c
new file mode 100644
index 0000000..56395bf
--- /dev/null
+++ b/src/tests/testmultiplexer.c
@@ -0,0 +1,179 @@
+/* testmultiplexer.c - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <check.h>
+#include <stdlib.h>
+
+#include "virtio/multiplexer.h"
+
+void
+setup(void)
+{}
+
+void
+teardown(void)
+{}
+
+#define APINAME "testapi"
+#define CONTENT "<args />"
+
+const char*
+test_callback(const char* input)
+{
+ return NULL;
+}
+
+const char*
+test_new_callback(const char* input)
+{
+ return NULL;
+}
+
+START_TEST (test_register_with_null_name)
+{
+ fail_unless (multiplexer_register_api(NULL, NULL) == -1,
+ "Registration should not have succeeded");
+}
+END_TEST
+
+START_TEST (test_register_with_empty_name)
+{
+ fail_unless (multiplexer_register_api("", NULL) == -1,
+ "Registration should not have succeeded.");
+}
+END_TEST
+
+START_TEST (test_register_will_null_function)
+{
+ fail_unless (multiplexer_register_api(APINAME, NULL) == -1,
+ "Registration should not have succeeded");
+}
+END_TEST
+
+START_TEST (test_register_succeeds)
+{
+ fail_unless (!multiplexer_register_api(APINAME, test_callback),
+ "Registration should have succeeded.");
+ fail_unless (multiplexer_get_api_function(APINAME) == test_callback,
+ "The method was not actually registered.");
+}
+END_TEST
+
+START_TEST (test_register_with_existing_api_name)
+{
+ fail_unless (!multiplexer_register_api(APINAME, test_callback),
+ "Registration should have succeeded.");
+ fail_unless (!multiplexer_register_api(APINAME, test_new_callback),
+ "Registration should have succeeded.");
+ fail_unless (multiplexer_get_api_function(APINAME) == test_new_callback,
+ "The original API should have been replaced.");
+}
+END_TEST
+
+START_TEST (test_unregistered_api_returns_null)
+{
+ fail_if (multiplexer_get_api_function(APINAME),
+ "No callback should have been returned.");
+}
+END_TEST
+
+START_TEST (test_invoke_with_null_apiname)
+{
+ fail_unless (multiplexer_invoke_api(NULL, CONTENT) == NULL,
+ "The API call should have failed.");
+}
+END_TEST
+
+START_TEST (test_invoke_with_empty_apiname)
+{
+ fail_unless (multiplexer_invoke_api("", CONTENT) == NULL,
+ "The API call should have faile");
+}
+END_TEST
+
+START_TEST (test_invoke_unregistered_api)
+{
+ fail_unless (multiplexer_invoke_api("farkle", CONTENT) == NULL,
+ "The API call should have failed.");
+}
+END_TEST
+
+START_TEST (test_invoke_with_no_content)
+{
+ fail_unless (multiplexer_invoke_api(APINAME, NULL) == NULL,
+ "The API call should have failed.");
+}
+END_TEST
+
+const char*
+test_invoke_callback(const char* input)
+{
+ return input;
+}
+
+START_TEST (test_invoke_succeeds)
+{
+ multiplexer_register_api(APINAME, test_invoke_callback);
+
+ const char* result = multiplexer_invoke_api(APINAME, CONTENT);
+
+ fail_if (!result, "The API call should have succeeded.");
+ fail_unless (!strcmp(CONTENT, result), "The call returned the wrong value.");
+}
+END_TEST
+
+Suite*
+multiplexer_test_suite(void)
+{
+ Suite* result = suite_create("Multiplexer");
+
+ TCase* tc_register = tcase_create("Register");
+ tcase_add_checked_fixture(tc_register, setup, teardown);
+ tcase_add_test(tc_register, test_register_with_null_name);
+ tcase_add_test(tc_register, test_register_with_empty_name);
+ tcase_add_test(tc_register, test_register_will_null_function);
+ tcase_add_test(tc_register, test_register_succeeds);
+ tcase_add_test(tc_register, test_register_with_existing_api_name);
+ tcase_add_test(tc_register, test_unregistered_api_returns_null);
+ suite_add_tcase(result, tc_register);
+
+ TCase* tc_invoke = tcase_create("Invoke");
+ tcase_add_checked_fixture(tc_invoke, setup, teardown);
+ tcase_add_test(tc_invoke, test_invoke_with_null_apiname);
+ tcase_add_test(tc_invoke, test_invoke_unregistered_api);
+ tcase_add_test(tc_invoke, test_invoke_with_no_content);
+ tcase_add_test(tc_invoke, test_invoke_succeeds);
+ suite_add_tcase(result, tc_invoke);
+ return result;
+}
+
+int
+main(int argc, char** argv)
+{
+ int failures;
+
+ Suite* suite = multiplexer_test_suite();
+ SRunner* srunner = srunner_create(suite);
+
+ srunner_run_all(srunner, CK_NORMAL);
+ failures = srunner_ntests_failed(srunner);
+ srunner_free(srunner);
+
+ return (failures == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
diff --git a/src/tests/testmultiplexer.cpp b/src/tests/testmultiplexer.cpp
deleted file mode 100644
index 8ed77fd..0000000
--- a/src/tests/testmultiplexer.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/* testmultiplexer.cpp - Copyright (C) 2010 Red Hat, Inc.
- * Written by Darryl L. Pierce <dpierce(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include "testmultiplexer.h"
-
-#include "virtio/multiplexer.h"
-
-#include <cppunit/TestAssert.h>
-#include <cppunit/TestCaller.h>
-#include <cppunit/TestResult.h>
-#include <cppunit/TestSuite.h>
-#include <cppunit/ui/text/TestRunner.h>
-
-const string APINAME("testapifunction");
-
-const char*
-test_callback_function(const char* input)
-{
- return input;
-}
-
-TestMultiplexer::TestMultiplexer()
- :TestCase("TestMultiplexer")
-{}
-
-TestSuite*
-TestMultiplexer::suite()
-{
- CppUnit::TestSuite *result = new CppUnit::TestSuite("TestMultiplexer");
-
- result->addTest(new CppUnit::TestCaller<TestMultiplexer>
- ("testBadAPINameGetsNull",
- &TestMultiplexer::testUnregisteredAPIIsNull));
- result->addTest(new CppUnit::TestCaller<TestMultiplexer>
- ("testRegisterAPIMethod",
- &TestMultiplexer::testRegisterAPIMethod));
- result->addTest(new CppUnit::TestCaller<TestMultiplexer>
- ("testEnsureCallingAnUnregisteredAPIFails",
- &TestMultiplexer::testEnsureCallingAnUnregisteredAPIFails));
- result->addTest(new CppUnit::TestCaller<TestMultiplexer>
- ("testEnsureAPIIsCalled",
- &TestMultiplexer::testEnsureAPIIsCalled));
-
- return result;
-}
-
-void
-TestMultiplexer::setUp()
-{
- Multiplexer::instance()->registerAPI(APINAME, test_callback_function);
-}
-
-void
-TestMultiplexer::testUnregisteredAPIIsNull()
-{
- CPPUNIT_ASSERT(NULL == Multiplexer::instance()->getAPI(APINAME + "!"));
-}
-
-void
-TestMultiplexer::testRegisterAPIMethod()
-{
- t_apifunction apifunction = test_callback_function;
-
- CPPUNIT_ASSERT(apifunction == Multiplexer::instance()->getAPI(APINAME));
-}
-
-void
-TestMultiplexer::testEnsureCallingAnUnregisteredAPIFails()
-{
- string input = string("This is some input");
- string result = Multiplexer::instance()->invokeAPI(APINAME + "!", input);
-
- CPPUNIT_ASSERT(string("") == result);
-}
-
-void TestMultiplexer::testEnsureAPIIsCalled()
-{
- string expected = "This is what I expected";
- string result = Multiplexer::instance()->invokeAPI(APINAME, expected);
-
- CPPUNIT_ASSERT(expected == result);
-}
-
-int
-main(int argc, char** argv)
-{
- CppUnit::TextUi::TestRunner runner;
-
- runner.addTest(TestMultiplexer::suite());
- runner.run();
-
- return 0;
-}
diff --git a/src/tests/testmultiplexer.h b/src/tests/testmultiplexer.h
deleted file mode 100644
index 04cb9e5..0000000
--- a/src/tests/testmultiplexer.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __TESTMULTIPLEXER_H
-#define __TESTMULTIPLEXER_H
-
-/* testmultiplexer.h - Copyright (C) 2010 Red Hat, Inc.
- * Written by Darryl L. Pierce <dpierce(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include "virtio/multiplexer.h"
-
-#include <cppunit/TestCase.h>
-#include <cppunit/TestSuite.h>
-
-using namespace CppUnit;
-using namespace std;
-
-class TestMultiplexer : public CppUnit::TestCase
-{
- public:
- TestMultiplexer();
-
- static TestSuite* suite();
-
- void setUp();
-
- void testUnregisteredAPIIsNull();
- void testRegisterAPIMethod();
- void testEnsureCallingAnUnregisteredAPIFails();
- void testEnsureAPIIsCalled();
-};
-
-#endif
diff --git a/src/virtio/datahandler.c b/src/virtio/datahandler.c
new file mode 100644
index 0000000..3bf363c
--- /dev/null
+++ b/src/virtio/datahandler.c
@@ -0,0 +1,268 @@
+/* datahandler.cpp - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "virtio/datahandler.h"
+
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xpointer.h>
+#include "virtio/multiplexer.h"
+#include <string.h>
+#include "virtio/lib_crc.h"
+
+void
+_extract_api_and_make_call(t_datahandler_payload* payload, xmlDocPtr request);
+
+char*
+_create_error_content(const char* message)
+{
+ char* result = malloc(1000);
+
+ sprintf(result, "\
+ <response name=\"error\">\
+ <element>\
+ <value name=\"message\">%s</value>\
+ </element>\
+ </response>", message);
+
+ return result;
+}
+
+void
+_create_document_with_content(t_datahandler_payload* payload,
+ char* type,
+ const char* response,
+ unsigned int length)
+{
+ xmlDocPtr content = xmlNewDoc(BAD_CAST "1.0");
+ xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "matahari");
+ xmlNodePtr responses = xmlNewNode(NULL, BAD_CAST "responses");
+
+ xmlNewProp(root, BAD_CAST "type",BAD_CAST type);
+ xmlDocSetRootElement(content, root);
+ xmlAddChild(root, responses);
+
+ // parse the content
+ xmlDocPtr contentnode = xmlParseMemory(response, length);
+
+ xmlAddChild(responses, contentnode->children);
+
+ // set the payload response, crc and length
+ xmlChar* buffertext;
+ int buffersize;
+
+ xmlDocDumpFormatMemory(content, &buffertext, &buffersize, 1);
+ payload->response_payload = (char*) buffertext;
+ payload->response_length = buffersize;
+ payload->response_crc =
+ datahandler_calculate_crc(payload->response_payload,
+ payload->response_length);
+}
+
+void
+_prepare_request_payload(t_datahandler_payload* payload, const char* message,
+ t_matahari_message_type response_type)
+{
+ payload->response_type = response_type;
+
+ if(response_type == FAILURE)
+ {
+ char* response_message = _create_error_content(message);
+ _create_document_with_content(payload, "failure",
+ response_message, strlen(response_message));
+ free(response_message);
+ }
+ else
+ {
+ _create_document_with_content(payload, "response",
+ message, strlen(message));
+ }
+}
+
+void
+_request_failure(t_datahandler_payload* payload, const char* message)
+{
+ _prepare_request_payload(payload, message, FAILURE);
+}
+
+void
+_request_success(t_datahandler_payload* payload, const char* message)
+{
+ _prepare_request_payload(payload, message, RESPONSE);
+}
+
+int
+datahandler_process_payload(t_datahandler_payload* payload)
+{
+ int result = -1;
+
+ if(payload)
+ {
+ result = 0;
+
+ if(payload->request_length > 0)
+ {
+ // setup the response fields
+ payload->response_payload = 0;
+ payload->response_length = 0;
+ payload->response_crc = 0L;
+
+ unsigned long crc =
+ datahandler_calculate_crc(payload->request_payload,
+ payload->request_length);
+
+ if(crc == payload->request_crc)
+ {
+ xmlDocPtr request = xmlParseMemory(payload->request_payload,
+ payload->request_length);
+ xmlErrorPtr error = xmlGetLastError();
+
+ if(request != NULL && !error)
+ {
+ _extract_api_and_make_call(payload, request);
+ }
+ else
+ {
+ _request_failure(payload, "No request document found.");
+ }
+
+ if(request) xmlFreeDoc(request);
+ }
+ else
+ {
+ _request_failure(payload, "Request fails CRC check.");
+ }
+ }
+ else
+ {
+ _request_failure(payload, "No request payload present.");
+ }
+ }
+
+ return result;
+}
+
+unsigned long
+datahandler_calculate_crc(char* data, unsigned int length)
+{
+ unsigned long result = 0xffffffffL;
+ char* current = (char *)data;
+ unsigned int count = 0;
+
+ while(count < length)
+ {
+ result = update_crc_32(result, *current);
+ current++;
+ count++;
+ }
+
+ result ^= 0xffffffffL;
+
+ return result;
+}
+
+#define FREE_XPATH_OBJECT(pathobj) {\
+ if(pathobj) xmlXPathFreeObject(pathobj);\
+ pathobj = NULL;\
+ }
+
+void
+_extract_api_and_make_call(t_datahandler_payload* payload, xmlDocPtr request)
+{
+ xmlXPathContextPtr context = xmlXPathNewContext(request);
+ xmlXPathObjectPtr pathobj =
+ xmlXPathEvalExpression(BAD_CAST "/matahari/@type", context);
+
+ if(pathobj && !xmlXPathNodeSetIsEmpty(pathobj->nodesetval))
+ {
+ char* type = xmlXPathCastToString(pathobj);
+
+ if(!strncmp(type, "request", strlen("request")))
+ {
+ FREE_XPATH_OBJECT(pathobj);
+
+ pathobj = xmlXPathEvalExpression(BAD_CAST "/matahari/@api", context);
+
+ if(pathobj && !xmlXPathNodeSetIsEmpty(pathobj->nodesetval))
+ {
+ char* api = xmlXPathCastToString(pathobj);
+ FREE_XPATH_OBJECT(pathobj);
+
+ t_apifunction apifunction = multiplexer_get_api_function(api);
+
+ if(apifunction)
+ {
+ pathobj = xmlXPathEvalExpression(BAD_CAST "/matahari/args",
+ context);
+ if(pathobj && !xmlXPathNodeSetIsEmpty(pathobj->nodesetval))
+ {
+ xmlDocPtr args = xmlNewDoc(NULL);
+ xmlNodePtr argroot = xmlXPtrBuildNodeList(pathobj);
+
+ xmlDocSetRootElement(args, argroot);
+
+ xmlChar* contenttext;
+ int contentsize;
+
+ xmlDocDumpFormatMemory(args,
+ &contenttext, &contentsize, 1);
+
+ const char* response = apifunction(contenttext);
+ _request_success(payload, response);
+
+ free(contenttext);
+ if(args) xmlFreeDoc(args);
+ }
+ else
+ {
+ _request_failure(payload,
+ "Request did not contain arguments.");
+ }
+ }
+ else
+ {
+ _request_failure(payload, "Invalid API specified.");
+ }
+
+ free(api);
+ FREE_XPATH_OBJECT(pathobj);
+ }
+ else
+ {
+ _request_failure(payload, "Request did not specify an API.");
+ }
+
+ FREE_XPATH_OBJECT(pathobj);
+ }
+ else
+ {
+ _request_failure(payload, "Request was not of type 'request'.");
+ }
+
+ if(type) free(type);
+
+ FREE_XPATH_OBJECT(pathobj);
+ }
+ else
+ {
+ _request_failure(payload, "No API was specified.");
+ }
+
+ xmlXPathFreeContext(context);
+}
diff --git a/src/virtio/datahandler.h b/src/virtio/datahandler.h
new file mode 100644
index 0000000..4323280
--- /dev/null
+++ b/src/virtio/datahandler.h
@@ -0,0 +1,61 @@
+#ifndef __DATAHANDLER_H
+#define __DATAHANDLER_H
+
+/* datahandler.h - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {REQUEST, RESPONSE, FAILURE} t_matahari_message_type;
+
+/* A t_datahandler_payload struct holds the request payload
+ received from a remote system. After processing, it will
+ also hold the response payload and details.
+*/
+typedef struct
+{
+ char* request_id;
+ unsigned long request_crc;
+ char* request_payload;
+ unsigned int request_length;
+ t_matahari_message_type response_type;
+ unsigned long response_crc;
+ char* response_payload;
+ unsigned long response_length;
+} t_datahandler_payload;
+
+/* A function thatprocesses data received from a remote
+ source extracts and validates the actual request
+ within the payload.
+
+ It takes as argument a struct holding the request details,
+ and will attach the response details on completion.
+*/
+int datahandler_process_payload(t_datahandler_payload* payload);
+
+/* Calculates a CRC value for the supplied data. */
+unsigned long datahandler_calculate_crc(char* data, unsigned int length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/virtio/lib_crc.c b/src/virtio/lib_crc.c
new file mode 100644
index 0000000..26b6b99
--- /dev/null
+++ b/src/virtio/lib_crc.c
@@ -0,0 +1,459 @@
+#include "lib_crc.h"
+
+
+
+ /*******************************************************************\
+ * *
+ * Library : lib_crc *
+ * File : lib_crc.c *
+ * Author : Lammert Bies 1999-2008 *
+ * E-mail : info(a)lammertbies.nl *
+ * Language : ANSI C *
+ * *
+ * *
+ * Description *
+ * =========== *
+ * *
+ * The file lib_crc.c contains the private and public func- *
+ * tions used for the calculation of CRC-16, CRC-CCITT and *
+ * CRC-32 cyclic redundancy values. *
+ * *
+ * *
+ * Dependencies *
+ * ============ *
+ * *
+ * lib_crc.h CRC definitions and prototypes *
+ * *
+ * *
+ * Modification history *
+ * ==================== *
+ * *
+ * Date Version Comment *
+ * *
+ * 2008-04-20 1.16 Added CRC-CCITT calculation for Kermit *
+ * *
+ * 2007-04-01 1.15 Added CRC16 calculation for Modbus *
+ * *
+ * 2007-03-28 1.14 Added CRC16 routine for Sick devices *
+ * *
+ * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
+ * *
+ * 2005-05-14 1.12 Added CRC-CCITT with start value 0 *
+ * *
+ * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
+ * *
+ * 2005-02-04 1.10 Added CRC-DNP routines *
+ * *
+ * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
+ * *
+ * 1999-01-22 1.00 Initial source *
+ * *
+ \*******************************************************************/
+
+
+
+ /*******************************************************************\
+ * *
+ * #define P_xxxx *
+ * *
+ * The CRC's are computed using polynomials. The coefficients *
+ * for the algorithms are defined by the following constants. *
+ * *
+ \*******************************************************************/
+
+#define P_16 0xA001
+#define P_32 0xEDB88320L
+#define P_CCITT 0x1021
+#define P_DNP 0xA6BC
+#define P_KERMIT 0x8408
+#define P_SICK 0x8005
+
+
+
+ /*******************************************************************\
+ * *
+ * static int crc_tab...init *
+ * static unsigned ... crc_tab...[] *
+ * *
+ * The algorithms use tables with precalculated values. This *
+ * speeds up the calculation dramaticaly. The first time the *
+ * CRC function is called, the table for that specific calcu- *
+ * lation is set up. The ...init variables are used to deter- *
+ * mine if the initialization has taken place. The calculated *
+ * values are stored in the crc_tab... arrays. *
+ * *
+ * The variables are declared static. This makes them invisi- *
+ * ble for other modules of the program. *
+ * *
+ \*******************************************************************/
+
+static int crc_tab16_init = FALSE;
+static int crc_tab32_init = FALSE;
+static int crc_tabccitt_init = FALSE;
+static int crc_tabdnp_init = FALSE;
+static int crc_tabkermit_init = FALSE;
+
+static unsigned short crc_tab16[256];
+static unsigned long crc_tab32[256];
+static unsigned short crc_tabccitt[256];
+static unsigned short crc_tabdnp[256];
+static unsigned short crc_tabkermit[256];
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crc...tab(); *
+ * *
+ * Three local functions are used to initialize the tables *
+ * with values for the algorithm. *
+ * *
+ \*******************************************************************/
+
+static void init_crc16_tab( void );
+static void init_crc32_tab( void );
+static void init_crcccitt_tab( void );
+static void init_crcdnp_tab( void );
+static void init_crckermit_tab( void );
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned short update_crc_ccitt( unsigned long crc, char c ); *
+ * *
+ * The function update_crc_ccitt calculates a new CRC-CCITT *
+ * value based on the previous value of the CRC and the next *
+ * byte of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned short update_crc_ccitt( unsigned short crc, char c ) {
+
+ unsigned short tmp, short_c;
+
+ short_c = 0x00ff & (unsigned short) c;
+
+ if ( ! crc_tabccitt_init ) init_crcccitt_tab();
+
+ tmp = (crc >> 8) ^ short_c;
+ crc = (crc << 8) ^ crc_tabccitt[tmp];
+
+ return crc;
+
+} /* update_crc_ccitt */
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned short update_crc_sick( *
+ * unsigned long crc, char c, char prev_byte ); *
+ * *
+ * The function update_crc_sick calculates a new CRC-SICK *
+ * value based on the previous value of the CRC and the next *
+ * byte of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte ) {
+
+ unsigned short short_c, short_p;
+
+ short_c = 0x00ff & (unsigned short) c;
+ short_p = ( 0x00ff & (unsigned short) prev_byte ) << 8;
+
+ if ( crc & 0x8000 ) crc = ( crc << 1 ) ^ P_SICK;
+ else crc = crc << 1;
+
+ crc &= 0xffff;
+ crc ^= ( short_c | short_p );
+
+ return crc;
+
+} /* update_crc_sick */
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned short update_crc_16( unsigned short crc, char c ); *
+ * *
+ * The function update_crc_16 calculates a new CRC-16 value *
+ * based on the previous value of the CRC and the next byte *
+ * of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned short update_crc_16( unsigned short crc, char c ) {
+
+ unsigned short tmp, short_c;
+
+ short_c = 0x00ff & (unsigned short) c;
+
+ if ( ! crc_tab16_init ) init_crc16_tab();
+
+ tmp = crc ^ short_c;
+ crc = (crc >> 8) ^ crc_tab16[ tmp & 0xff ];
+
+ return crc;
+
+} /* update_crc_16 */
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned short update_crc_kermit( unsigned short crc, char c ); *
+ * *
+ * The function update_crc_kermit calculates a new CRC value *
+ * based on the previous value of the CRC and the next byte *
+ * of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned short update_crc_kermit( unsigned short crc, char c ) {
+
+ unsigned short tmp, short_c;
+
+ short_c = 0x00ff & (unsigned short) c;
+
+ if ( ! crc_tabkermit_init ) init_crckermit_tab();
+
+ tmp = crc ^ short_c;
+ crc = (crc >> 8) ^ crc_tabkermit[ tmp & 0xff ];
+
+ return crc;
+
+} /* update_crc_kermit */
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned short update_crc_dnp( unsigned short crc, char c ); *
+ * *
+ * The function update_crc_dnp calculates a new CRC-DNP value *
+ * based on the previous value of the CRC and the next byte *
+ * of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned short update_crc_dnp( unsigned short crc, char c ) {
+
+ unsigned short tmp, short_c;
+
+ short_c = 0x00ff & (unsigned short) c;
+
+ if ( ! crc_tabdnp_init ) init_crcdnp_tab();
+
+ tmp = crc ^ short_c;
+ crc = (crc >> 8) ^ crc_tabdnp[ tmp & 0xff ];
+
+ return crc;
+
+} /* update_crc_dnp */
+
+
+
+ /*******************************************************************\
+ * *
+ * unsigned long update_crc_32( unsigned long crc, char c ); *
+ * *
+ * The function update_crc_32 calculates a new CRC-32 value *
+ * based on the previous value of the CRC and the next byte *
+ * of the data to be checked. *
+ * *
+ \*******************************************************************/
+
+unsigned long update_crc_32( unsigned long crc, char c ) {
+
+ unsigned long tmp, long_c;
+
+ long_c = 0x000000ffL & (unsigned long) c;
+
+ if ( ! crc_tab32_init ) init_crc32_tab();
+
+ tmp = crc ^ long_c;
+ crc = (crc >> 8) ^ crc_tab32[ tmp & 0xff ];
+
+ return crc;
+
+} /* update_crc_32 */
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crc16_tab( void ); *
+ * *
+ * The function init_crc16_tab() is used to fill the array *
+ * for calculation of the CRC-16 with values. *
+ * *
+ \*******************************************************************/
+
+static void init_crc16_tab( void ) {
+
+ int i, j;
+ unsigned short crc, c;
+
+ for (i=0; i<256; i++) {
+
+ crc = 0;
+ c = (unsigned short) i;
+
+ for (j=0; j<8; j++) {
+
+ if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_16;
+ else crc = crc >> 1;
+
+ c = c >> 1;
+ }
+
+ crc_tab16[i] = crc;
+ }
+
+ crc_tab16_init = TRUE;
+
+} /* init_crc16_tab */
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crckermit_tab( void ); *
+ * *
+ * The function init_crckermit_tab() is used to fill the array *
+ * for calculation of the CRC Kermit with values. *
+ * *
+ \*******************************************************************/
+
+static void init_crckermit_tab( void ) {
+
+ int i, j;
+ unsigned short crc, c;
+
+ for (i=0; i<256; i++) {
+
+ crc = 0;
+ c = (unsigned short) i;
+
+ for (j=0; j<8; j++) {
+
+ if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_KERMIT;
+ else crc = crc >> 1;
+
+ c = c >> 1;
+ }
+
+ crc_tabkermit[i] = crc;
+ }
+
+ crc_tabkermit_init = TRUE;
+
+} /* init_crckermit_tab */
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crcdnp_tab( void ); *
+ * *
+ * The function init_crcdnp_tab() is used to fill the array *
+ * for calculation of the CRC-DNP with values. *
+ * *
+ \*******************************************************************/
+
+static void init_crcdnp_tab( void ) {
+
+ int i, j;
+ unsigned short crc, c;
+
+ for (i=0; i<256; i++) {
+
+ crc = 0;
+ c = (unsigned short) i;
+
+ for (j=0; j<8; j++) {
+
+ if ( (crc ^ c) & 0x0001 ) crc = ( crc >> 1 ) ^ P_DNP;
+ else crc = crc >> 1;
+
+ c = c >> 1;
+ }
+
+ crc_tabdnp[i] = crc;
+ }
+
+ crc_tabdnp_init = TRUE;
+
+} /* init_crcdnp_tab */
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crc32_tab( void ); *
+ * *
+ * The function init_crc32_tab() is used to fill the array *
+ * for calculation of the CRC-32 with values. *
+ * *
+ \*******************************************************************/
+
+static void init_crc32_tab( void ) {
+
+ int i, j;
+ unsigned long crc;
+
+ for (i=0; i<256; i++) {
+
+ crc = (unsigned long) i;
+
+ for (j=0; j<8; j++) {
+
+ if ( crc & 0x00000001L ) crc = ( crc >> 1 ) ^ P_32;
+ else crc = crc >> 1;
+ }
+
+ crc_tab32[i] = crc;
+ }
+
+ crc_tab32_init = TRUE;
+
+} /* init_crc32_tab */
+
+
+
+ /*******************************************************************\
+ * *
+ * static void init_crcccitt_tab( void ); *
+ * *
+ * The function init_crcccitt_tab() is used to fill the array *
+ * for calculation of the CRC-CCITT with values. *
+ * *
+ \*******************************************************************/
+
+static void init_crcccitt_tab( void ) {
+
+ int i, j;
+ unsigned short crc, c;
+
+ for (i=0; i<256; i++) {
+
+ crc = 0;
+ c = ((unsigned short) i) << 8;
+
+ for (j=0; j<8; j++) {
+
+ if ( (crc ^ c) & 0x8000 ) crc = ( crc << 1 ) ^ P_CCITT;
+ else crc = crc << 1;
+
+ c = c << 1;
+ }
+
+ crc_tabccitt[i] = crc;
+ }
+
+ crc_tabccitt_init = TRUE;
+
+} /* init_crcccitt_tab */
diff --git a/src/virtio/lib_crc.h b/src/virtio/lib_crc.h
new file mode 100644
index 0000000..ea5ca76
--- /dev/null
+++ b/src/virtio/lib_crc.h
@@ -0,0 +1,66 @@
+ /*******************************************************************\
+ * *
+ * Library : lib_crc *
+ * File : lib_crc.h *
+ * Author : Lammert Bies 1999-2008 *
+ * E-mail : info(a)lammertbies.nl *
+ * Language : ANSI C *
+ * *
+ * *
+ * Description *
+ * =========== *
+ * *
+ * The file lib_crc.h contains public definitions and proto- *
+ * types for the CRC functions present in lib_crc.c. *
+ * *
+ * *
+ * Dependencies *
+ * ============ *
+ * *
+ * none *
+ * *
+ * *
+ * Modification history *
+ * ==================== *
+ * *
+ * Date Version Comment *
+ * *
+ * 2008-04-20 1.16 Added CRC-CCITT routine for Kermit *
+ * *
+ * 2007-04-01 1.15 Added CRC16 calculation for Modbus *
+ * *
+ * 2007-03-28 1.14 Added CRC16 routine for Sick devices *
+ * *
+ * 2005-12-17 1.13 Added CRC-CCITT with initial 0x1D0F *
+ * *
+ * 2005-02-14 1.12 Added CRC-CCITT with initial 0x0000 *
+ * *
+ * 2005-02-05 1.11 Fixed bug in CRC-DNP routine *
+ * *
+ * 2005-02-04 1.10 Added CRC-DNP routines *
+ * *
+ * 2005-01-07 1.02 Changes in tst_crc.c *
+ * *
+ * 1999-02-21 1.01 Added FALSE and TRUE mnemonics *
+ * *
+ * 1999-01-22 1.00 Initial source *
+ * *
+ \*******************************************************************/
+
+
+
+#define CRC_VERSION "1.16"
+
+
+
+#define FALSE 0
+#define TRUE 1
+
+
+
+unsigned short update_crc_16( unsigned short crc, char c );
+unsigned long update_crc_32( unsigned long crc, char c );
+unsigned short update_crc_ccitt( unsigned short crc, char c );
+unsigned short update_crc_dnp( unsigned short crc, char c );
+unsigned short update_crc_kermit( unsigned short crc, char c );
+unsigned short update_crc_sick( unsigned short crc, char c, char prev_byte );
diff --git a/src/virtio/multiplexer.c b/src/virtio/multiplexer.c
new file mode 100644
index 0000000..677e24c
--- /dev/null
+++ b/src/virtio/multiplexer.c
@@ -0,0 +1,122 @@
+/* multiplexer.c - Copyright (C) 2010 Red Hat, Inc.
+ * Written by Darryl L. Pierce <dpierce(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA. A copy of the GNU General Public License is
+ * also available at http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include "multiplexer.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define APINAMELENGTH 255
+
+typedef struct _apifunction_list
+{
+ char apiname[APINAMELENGTH];
+ t_apifunction callback;
+ struct _apifunction_list* next;
+} t_apifunction_list;
+
+t_apifunction_list* _callbacks = NULL;
+
+int
+multiplexer_register_api(const char* apiname, t_apifunction callback)
+{
+ int result = -1;
+
+ if(apiname && strlen(apiname) && callback)
+ {
+ t_apifunction_list* newapi = NULL;
+ int existing = 0;
+
+ /* first see if the api is already registered */
+ newapi = _callbacks;
+ while(newapi && !existing)
+ {
+ if(!strcmp(newapi->apiname, apiname))
+ {
+ existing = 1;
+ }
+ else
+ {
+ newapi = newapi->next;
+ }
+ }
+
+ if(!newapi)
+ {
+ newapi = malloc(sizeof(t_apifunction_list));
+
+ strncpy(newapi->apiname, apiname, APINAMELENGTH);
+ newapi->callback = callback;
+ newapi->next = NULL;
+
+ if(_callbacks)
+ {
+ t_apifunction_list* tail = NULL;
+
+ while(tail->next) tail = tail->next;
+ tail->next = newapi;
+ }
+ else
+ {
+ _callbacks = newapi;
+ }
+ }
+ else
+ {
+ newapi->callback = callback;
+ }
+
+ result = 0;
+ }
+
+ return result;
+}
+
+t_apifunction
+multiplexer_get_api_function(const char* apiname)
+{
+ t_apifunction_list* current = _callbacks;
+
+ while(current)
+ {
+ if(!strcmp(apiname, current->apiname))
+ {
+ return current->callback;
+ }
+ current = current->next;
+ }
+
+ return NULL;
+}
+
+const char*
+multiplexer_invoke_api(const char* apiname, const char* content)
+{
+ const char* result = NULL;
+
+ t_apifunction api = multiplexer_get_api_function(apiname);
+
+ if(api)
+ {
+ result = api(content);
+ }
+
+ return result;
+}
diff --git a/src/virtio/multiplexer.cpp b/src/virtio/multiplexer.cpp
deleted file mode 100644
index 79f8b35..0000000
--- a/src/virtio/multiplexer.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-#include "multiplexer.h"
-
-/* multiplexer.cpp - Copyright (C) 2010 Red Hat, Inc.
- * Written by Darryl L. Pierce <dpierce(a)redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-#include "multiplexer.h"
-
-// the singleton
-Multiplexer* Multiplexer::_instance = new Multiplexer();
-
-typedef map<string, t_apifunction> APIMAP;
-
-Multiplexer::Multiplexer()
-{}
-
-Multiplexer*
-Multiplexer::instance()
-{
- return _instance;
-}
-
-void
-Multiplexer::registerAPI(string name, t_apifunction apifunction)
-{
- _apis.insert(APIMAP::value_type(string(name), apifunction));
-}
-
-t_apifunction
-Multiplexer::getAPI(string name)
-{
- return (*_apis.find(name)).second;
-}
-
-string
-Multiplexer::invokeAPI(string name, string input)
-{
- string result = string("");
- t_apifunction funcptr = (*_apis.find(name)).second;
-
- if(funcptr)
- {
- result = funcptr(input.c_str());
- }
-
- return result;
-}
diff --git a/src/virtio/multiplexer.h b/src/virtio/multiplexer.h
index 26a288c..5d00adf 100644
--- a/src/virtio/multiplexer.h
+++ b/src/virtio/multiplexer.h
@@ -20,29 +20,35 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
-#include <map>
-#include <string>
-
-using namespace std;
-
+/* Defines a function type that can be used as a callback
+ * for an API.
+ */
typedef const char*(*t_apifunction)(const char*);
-// Multiplexer processes the content received from a remote system.
-class Multiplexer
-{
- private:
- Multiplexer();
-
- static Multiplexer* _instance;
-
- map<string, t_apifunction> _apis;
+/* Registers a new API that can be called back.
+ *
+ * INPUT: The name of the api.
+ * The callback function to be invoked.
+ * OUTPUT: 0 on success, -1 on failure.
+ */
+int
+multiplexer_register_api(const char* name, t_apifunction callback);
- public:
- static Multiplexer* instance();
+/* Returns a pointer to the callback registered for an API.
+ *
+ * INPUT: The name of the API.
+ * OUTPUT: A pointer to the function, or NULL if the API is not registered.
+ */
+t_apifunction
+multiplexer_get_api_function(const char* name);
- void registerAPI(string apiname, t_apifunction apifunction);
- t_apifunction getAPI(string apiname);
- string invokeAPI(string apiname, string input);
-};
+/* Invokes the named API, passing in the supplied argument.
+ *
+ * INPUT: The name of the API.
+ * The content to pass to the API.
+ * OUTPUT: The result of the API call, or NULL if the API call failed.
+ */
+const char*
+multiplexer_invoke_api(const char* name, const char* content);
#endif
--
1.7.0.1
13 years, 10 months
Re: [Matahari] [PATCH matahari] Adds a byte stream data handler and refactors the multiplexer codebase.
by Darryl L. Pierce
On Tue, Jun 15, 2010 at 09:32:58AM +0200, Andrew Beekhof wrote:
> Looks pretty good.
> Do we know the license of the CRC code? That's probably important.
The code doesn't have an explicit license in it, so I've emailed the
author to ask permission to include the code. I'll plead ignorance on
what existing library might already provides a CRC32 function: any
recommendation?
> I think the t_datahandler_payload struct can be streamlined a bit -
> there's no real need for both request and response fields.
> The convention is to put "t_" at the end btw... ie. uint32_t.
> Also to use zero-length arrays for payloads.
>
> typedef struct
> {
> char* request_id;
> matahari_message_type_t payload_type;
> unsigned long payload_length;
> unsigned long payload_crc;
> char payload[0];
> } matahari_message_t;
>
>
> I'd also advise adding a MH_ prefix to the members of the
> matahari_message_type_t enum.
>
>
> multiplexer_get_api_function() is probably ok for now, but we might
> want to think about using a hash table to speed it up a bit.
I'll incorporate the feedback and send out an updated patch. Also I'll
remove any const char* references as well.
--
Darryl L. Pierce, Sr. Software Engineer @ Red Hat, Inc.
Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
13 years, 10 months
[PATCH] Replace the HostListener C++ type with a function prototype.
by Darryl L. Pierce
Since we're steering the total codebase (except the QMF transport) away
from C++, this piece needed to be replaced. So this patch introduces a
singly linked list that holds the registered functions that receive
callbacks on heartbeat events.
Signed-off-by: Darryl L. Pierce <dpierce(a)redhat.com>
---
configure.ac | 1 +
src/host.cpp | 94 ++++++++++++++++++++++++++++++++++---------------
src/host.h | 21 ++++-------
src/hostlistener.h | 34 ------------------
src/main.cpp | 13 ++++++-
src/qmf/hostagent.cpp | 7 +---
src/qmf/hostagent.h | 3 +-
7 files changed, 88 insertions(+), 85 deletions(-)
delete mode 100644 src/hostlistener.h
diff --git a/configure.ac b/configure.ac
index 3481c09..658fee3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@ AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
+AM_PROG_CC_C_O
AC_PROG_CPP
AC_CHECK_PROG(HASQMFGEN, qmf-gen, "yes")
diff --git a/src/host.cpp b/src/host.cpp
index 39655d2..a826545 100644
--- a/src/host.cpp
+++ b/src/host.cpp
@@ -20,23 +20,66 @@
#include "host.h"
#include "platform.h"
-#include <set>
-using namespace std;
+typedef struct _heartbeat_listener
+{
+ t_host_heartbeat_callback listener;
+ _heartbeat_listener* next;
+} t_heartbeat_listener;
+
+t_heartbeat_listener* listeners = NULL;
-set<HostListener*> _listeners;
-unsigned int _heartbeat_sequence;
+unsigned int _heartbeat_sequence = 0;
void
-host_register_listener(HostListener* listener)
+host_register_listener(t_host_heartbeat_callback listener)
{
- _listeners.insert(listener);
+ t_heartbeat_listener* current = new t_heartbeat_listener;
+
+ current->listener = listener;
+ current->next = NULL;
+
+ if(listeners)
+ {
+ t_heartbeat_listener* tail = listeners;
+ while(tail->next) tail = tail->next;
+ tail->next = current;
+ }
+ else
+ {
+ listeners = current;
+ }
}
void
-host_remove_listener(HostListener* listener)
+host_remove_listener(t_host_heartbeat_callback listener)
{
- _listeners.erase(listener);
+ t_heartbeat_listener* current = listeners;
+ t_heartbeat_listener* last = NULL;
+
+ while(current)
+ {
+ if (current->listener == listener)
+ {
+ if(current == listeners)
+ {
+ listeners = current->next;
+ }
+ else
+ {
+ last->next = current->next;
+ current->next = NULL;
+ }
+
+ delete current;
+ current = NULL;
+ }
+ else
+ {
+ last = current;
+ current = current->next;
+ }
+ }
}
void
@@ -47,44 +90,37 @@ host_update_event()
time_t __time;
time(&__time);
- for(set<HostListener*>::iterator iter = _listeners.begin();
- iter != _listeners.end();
- iter++)
- {
- (*iter)->heartbeat((unsigned long)__time,
- _heartbeat_sequence);
- }
+ t_heartbeat_listener* current = listeners;
- for(set<HostListener*>::iterator iter = _listeners.begin();
- iter != _listeners.end();
- iter++)
+ while(current)
{
- (*iter)->updated();
+ current->listener((unsigned long)time, _heartbeat_sequence);
+ current = current->next;
}
}
-string
+const char*
host_get_uuid()
{
- return Platform::instance()->getUUID();
+ return Platform::instance()->getUUID().c_str();
}
-string
+const char*
host_get_hostname()
{
- return Platform::instance()->getHostname();
+ return Platform::instance()->getHostname().c_str();
}
-string
+const char*
host_get_hypervisor()
{
- return Platform::instance()->getHypervisor();
+ return Platform::instance()->getHypervisor().c_str();
}
-string
+const char*
host_get_architecture()
{
- return Platform::instance()->getArchitecture();
+ return Platform::instance()->getArchitecture().c_str();
}
unsigned int
@@ -93,10 +129,10 @@ host_get_memory()
return Platform::instance()->getMemory();
}
-string
+const char*
host_get_cpu_model()
{
- return Platform::instance()->getCPUModel();
+ return Platform::instance()->getCPUModel().c_str();
}
unsigned int
diff --git a/src/host.h b/src/host.h
index dab88ad..530107c 100644
--- a/src/host.h
+++ b/src/host.h
@@ -20,30 +20,25 @@
* also available at http://www.gnu.org/copyleft/gpl.html.
*/
-#include <string>
-#include <set>
+typedef void(*t_host_heartbeat_callback)(unsigned long, unsigned int);
-#include "hostlistener.h"
+void host_register_listener(t_host_heartbeat_callback listener);
-using namespace std;
-
-void host_register_listener(HostListener* listener);
-
-void host_remove_istener(HostListener* listener);
+void host_remove_istener(t_host_heartbeat_callback listener);
void host_update_event();
-string host_get_uuid();
+const char* host_get_uuid();
-string host_get_hostname();
+const char* host_get_hostname();
-string host_get_hypervisor();
+const char* host_get_hypervisor();
-string host_get_architecture();
+const char* host_get_architecture();
unsigned int host_get_memory();
-string host_get_cpu_model();
+const char* host_get_cpu_model();
unsigned int host_get_number_of_cpu_cores();
diff --git a/src/hostlistener.h b/src/hostlistener.h
deleted file mode 100644
index 307ab92..0000000
--- a/src/hostlistener.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __HOSTLISTENER_H
-#define __HOSTLISTENER_H
-
-/* hostlistener.h - Copyright (C) 2009 Red Hat, Inc.
- * Written by Darryl Pierce <dpierce(a)redhat.com>.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA. A copy of the GNU General Public License is
- * also available at http://www.gnu.org/copyleft/gpl.html.
- */
-
-/*
- HostListener defines a type which receives notification
- whenever a Host event occurs.
- */
-class HostListener
-{
- public:
- virtual void heartbeat(unsigned long timestamp, unsigned int sequence) = 0;
- virtual void updated() = 0;
-};
-
-#endif
diff --git a/src/main.cpp b/src/main.cpp
index c0ffd94..d7f2b0a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -45,6 +45,8 @@ namespace _qmf = qmf::com::redhat::matahari;
// Global Variables
ManagementAgent::Singleton* singleton;
+HostAgent _hostagent;
+
void
shutdown(int /*signal*/)
{
@@ -64,6 +66,12 @@ print_usage()
printf("\t-p | --port specify broker port.\n");
}
+void
+sendHeartbeatToQmf(unsigned long timestamp, unsigned int sequence)
+{
+ _hostagent.heartbeat(timestamp, sequence);
+}
+
int
main(int argc, char **argv)
{
@@ -77,9 +85,10 @@ main(int argc, char **argv)
char *service = NULL;
int serverport = 5672;
+ host_register_listener(sendHeartbeatToQmf);
+
ConnectionSettings settings;
ManagementAgent *agent;
- HostAgent hostAgent;
struct option opt[] = {
{"help", no_argument, NULL, 'h'},
@@ -181,7 +190,7 @@ main(int argc, char **argv)
agent->init(settings, 5, false, ".magentdata");
// Get the info and post it to the broker
- hostAgent.setup(agent);
+ _hostagent.setup(agent);
while(1)
{
diff --git a/src/qmf/hostagent.cpp b/src/qmf/hostagent.cpp
index 682ad1c..ba74c61 100644
--- a/src/qmf/hostagent.cpp
+++ b/src/qmf/hostagent.cpp
@@ -23,13 +23,10 @@
#include "qmf/com/redhat/matahari/EventHeartbeat.h"
HostAgent::HostAgent()
-{
- host_register_listener(this);
-}
+{ }
HostAgent::~HostAgent()
-{
-}
+{ }
void
HostAgent::setup(ManagementAgent* agent)
diff --git a/src/qmf/hostagent.h b/src/qmf/hostagent.h
index 7f7bbaa..6744400 100644
--- a/src/qmf/hostagent.h
+++ b/src/qmf/hostagent.h
@@ -24,7 +24,6 @@
#include <string>
#include "host.h"
-#include "hostlistener.h"
#include "qmf/com/redhat/matahari/Host.h"
@@ -33,7 +32,7 @@ using namespace std;
namespace _qmf = qmf::com::redhat::matahari;
-class HostAgent : public Manageable, public HostListener
+class HostAgent : public Manageable
{
private:
_qmf::Host* _management_object;
--
1.7.0.1
13 years, 10 months