Index: /common/tags/common_1_1_2/configure
===================================================================
--- /common/tags/common_1_1_2/configure (revision 430)
+++ /common/tags/common_1_1_2/configure (revision 430)
@@ -0,0 +1,2608 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-profile        enable profiling"
+ac_help="$ac_help
+  --enable-bounds         enable bounds checking"
+ac_help="$ac_help
+  --enable-debug          enable debug messages and code"
+ac_help="$ac_help
+  --enable-debug-mem      enable memory debugging code"
+ac_help="$ac_help
+  --enable-ipv6           enable ipv6"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=base64.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:562: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+#  UCL checked $host_os and exited if we didn't recognize it.
+#  Let's be more optimistic for now.
+
+# XXX
+# Backwards compatability to UCL's -D<ostype> for now
+# All references to an OS should be replaced by references
+# to features!
+
+case "$host_os" in
+sunos*)
+	cat >> confdefs.h <<\EOF
+#define SunOS 1
+EOF
+
+	;;
+solaris*)
+	cat >> confdefs.h <<\EOF
+#define Solaris 1
+EOF
+
+	;;
+esac
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:609: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:639: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:690: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:722: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 733 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:764: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:769: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:797: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:829: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 844 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:850: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 861 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:867: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 878 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:884: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:911: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:940: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 945 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:953: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 970 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 988 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1009 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1044: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1049 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1119: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1124 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+for ac_hdr in stropts.h sys/filio.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1156: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1161 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in stdint.h inttypes.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1196: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1201 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1206: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Check for standard size types.  The defaults are only valid on some
+# systems so we hope that <inttypes.h> exists when they're wrong.
+echo $ac_n "checking for int8_t""... $ac_c" 1>&6
+echo "configure:1236: checking for int8_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_int8_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1241 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])int8_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_int8_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_int8_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_int8_t" 1>&6
+if test $ac_cv_type_int8_t = no; then
+  cat >> confdefs.h <<\EOF
+#define int8_t signed char
+EOF
+
+fi
+
+echo $ac_n "checking for int16_t""... $ac_c" 1>&6
+echo "configure:1269: checking for int16_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1274 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])int16_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_int16_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_int16_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_int16_t" 1>&6
+if test $ac_cv_type_int16_t = no; then
+  cat >> confdefs.h <<\EOF
+#define int16_t short
+EOF
+
+fi
+
+echo $ac_n "checking for int32_t""... $ac_c" 1>&6
+echo "configure:1302: checking for int32_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1307 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])int32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_int32_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_int32_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_int32_t" 1>&6
+if test $ac_cv_type_int32_t = no; then
+  cat >> confdefs.h <<\EOF
+#define int32_t long
+EOF
+
+fi
+
+echo $ac_n "checking for int64_t""... $ac_c" 1>&6
+echo "configure:1335: checking for int64_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1340 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])int64_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_int64_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_int64_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_int64_t" 1>&6
+if test $ac_cv_type_int64_t = no; then
+  cat >> confdefs.h <<\EOF
+#define int64_t long long
+EOF
+
+fi
+
+
+# Some systems have these in <stdint.h>, just to be difficult...
+echo $ac_n "checking for uint8_t in <stdint.h>""... $ac_c" 1>&6
+echo "configure:1370: checking for uint8_t in <stdint.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_uint8_t_in_stdint_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1375 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uint8_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_uint8_t_in_stdint_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_uint8_t_in_stdint_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_uint8_t_in_stdint_h" 1>&6
+if test $ucl_cv_uint8_t_in_stdint_h = "no"
+then
+	 echo $ac_n "checking for uint8_t""... $ac_c" 1>&6
+echo "configure:1395: checking for uint8_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uint8_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1400 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])uint8_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uint8_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uint8_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_uint8_t" 1>&6
+if test $ac_cv_type_uint8_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uint8_t unsigned char
+EOF
+
+fi
+
+fi
+
+echo $ac_n "checking for uint16_t in <stdint.h>""... $ac_c" 1>&6
+echo "configure:1430: checking for uint16_t in <stdint.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_uint16_t_in_stdint_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1435 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uint16_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_uint16_t_in_stdint_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_uint16_t_in_stdint_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_uint16_t_in_stdint_h" 1>&6
+if test $ucl_cv_uint16_t_in_stdint_h = "no"
+then
+	 echo $ac_n "checking for uint16_t""... $ac_c" 1>&6
+echo "configure:1455: checking for uint16_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uint16_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1460 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])uint16_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uint16_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uint16_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_uint16_t" 1>&6
+if test $ac_cv_type_uint16_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uint16_t unsigned short
+EOF
+
+fi
+
+fi
+
+echo $ac_n "checking for uint32_t in <stdint.h>""... $ac_c" 1>&6
+echo "configure:1490: checking for uint32_t in <stdint.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_uint32_t_in_stdint_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1495 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uint32_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_uint32_t_in_stdint_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_uint32_t_in_stdint_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_uint32_t_in_stdint_h" 1>&6
+if test $ucl_cv_uint32_t_in_stdint_h = "no"
+then
+	 echo $ac_n "checking for uint32_t""... $ac_c" 1>&6
+echo "configure:1515: checking for uint32_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uint32_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1520 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])uint32_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_uint32_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_uint32_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_uint32_t" 1>&6
+if test $ac_cv_type_uint32_t = no; then
+  cat >> confdefs.h <<\EOF
+#define uint32_t unsigned int
+EOF
+
+fi
+
+fi
+
+# The following two macros cause autoconf to complain.
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:1551: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 1558 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1569: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 1573 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:1584: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1604 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:1617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
+echo "configure:1641: checking whether char is unsigned" >&5
+if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$GCC" = yes; then
+  # GCC predefines this symbol on systems where it applies.
+cat > conftest.$ac_ext <<EOF
+#line 1648 "configure"
+#include "confdefs.h"
+#ifdef __CHAR_UNSIGNED__
+  yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "yes" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=yes
+else
+  rm -rf conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -f conftest*
+
+else
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1670 "configure"
+#include "confdefs.h"
+/* volatile prevents gcc2 from optimizing the test away on sparcs.  */
+#if !defined(__STDC__) || __STDC__ != 1
+#define volatile
+#endif
+main() {
+  volatile char c = 255; exit(c < 0);
+}
+EOF
+if { (eval echo configure:1680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_char_unsigned=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_char_unsigned=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
+if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
+  cat >> confdefs.h <<\EOF
+#define __CHAR_UNSIGNED__ 1
+EOF
+
+fi
+
+#
+# The (?which?) library does not work with unsigned characters.
+# Force the compiler to use signed chars.
+if test $ac_cv_c_char_unsigned = yes
+then
+	if test "$GCC" = yes
+	then
+		CFLAGS="$CFLAGS -fsigned-char"
+	else
+		case "$host_os" in
+		# I don't know when "-signed" was added to IRIX CC
+		# so err on the side of using it.
+		irix*)	CFLAGS="$CFLAGS -signed"
+			;;
+		# need e.g. --force-signed-chars=-signed
+		*)	{ echo "configure: error: I don't know how to force signed chars" 1>&2; exit 1; }
+			;;
+		esac
+	fi
+fi
+#  __CHAR_UNSIGNED__ will be defined; hope this is OK.
+
+# The following causes autoconf to complain.
+
+ac_safe=`echo "/dev/urandom" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for /dev/urandom""... $ac_c" 1>&6
+echo "configure:1729: checking for /dev/urandom" >&5
+if eval "test \"`echo '$''{'ac_cv_file_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: Cannot check for file existence when cross compiling" 1>&2; exit 1; }
+else
+  if test -r /dev/urandom; then
+    eval "ac_cv_file_$ac_safe=yes"
+  else
+    eval "ac_cv_file_$ac_safe=no"
+  fi
+fi
+fi
+if eval "test \"`echo '$ac_cv_file_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<\EOF
+#define HAVE_DEV_URANDOM 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+
+fi
+
+
+# If more files than mbus.c use vsnprintf, split it out into
+# vsnprintf.c and add it to AC_REPLACE_FUNCS
+echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6
+echo "configure:1758: checking for vsnprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1763 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vsnprintf(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char vsnprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vsnprintf) || defined (__stub___vsnprintf)
+choke me
+#else
+vsnprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_vsnprintf=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_vsnprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vsnprintf`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  :
+else
+  echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NEED_VSNPRINTF 1
+EOF
+
+fi
+
+
+# If inet_aton is actually needed somewhere, split it out into
+# inet_aton.c and add it to AC_REPLACE_FUNCS 
+#
+# AC_CHECK_FUNC succeeds on our IRIX 6.2 boxes, but it is not 
+# declared anywhere, use egrep header to check (ugh lame, but works)
+
+echo $ac_n "checking for inet_pton in <arpa/inet.h>""... $ac_c" 1>&6
+echo "configure:1817: checking for inet_pton in <arpa/inet.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_inet_pton_in_inet_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1822 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uint16_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_inet_pton_in_inet_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_inet_pton_in_inet_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_inet_pton_in_inet_h" 1>&6
+if test $ucl_cv_inet_pton_in_inet_h = "no"
+then
+	cat >> confdefs.h <<\EOF
+#define NEED_INET_PTON 1
+EOF
+
+	LIBOBJS="$LIBOBJS inet_pton.o"
+fi
+echo $ac_n "checking for inet_ntop in <arpa/inet.h>""... $ac_c" 1>&6
+echo "configure:1848: checking for inet_ntop in <arpa/inet.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_inet_ntop_in_inet_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1853 "configure"
+#include "confdefs.h"
+#include <stdint.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "uint16_t" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_inet_ntop_in_inet_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_inet_ntop_in_inet_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_inet_ntop_in_inet_h" 1>&6
+if test $ucl_cv_inet_ntop_in_inet_h = "no"
+then
+	cat >> confdefs.h <<\EOF
+#define NEED_INET_NTOP 1
+EOF
+
+	LIBOBJS="$LIBOBJS inet_ntop.o"
+fi
+
+
+
+
+echo $ac_n "checking for library containing socket""... $ac_c" 1>&6
+echo "configure:1883: checking for library containing socket" >&5
+if eval "test \"`echo '$''{'ac_cv_search_socket'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_socket="no"
+cat > conftest.$ac_ext <<EOF
+#line 1890 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:1901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_socket="none required"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_socket" = "no" && for i in socket; do
+LIBS="-l$i  $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1912 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char socket();
+
+int main() {
+socket()
+; return 0; }
+EOF
+if { (eval echo configure:1923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_socket="-l$i"
+break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_socket" 1>&6
+if test "$ac_cv_search_socket" != "no"; then
+  test "$ac_cv_search_socket" = "none required" || LIBS="$ac_cv_search_socket $LIBS"
+  
+else :
+  
+fi
+
+echo $ac_n "checking for library containing inet_addr""... $ac_c" 1>&6
+echo "configure:1945: checking for library containing inet_addr" >&5
+if eval "test \"`echo '$''{'ac_cv_search_inet_addr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_func_search_save_LIBS="$LIBS"
+ac_cv_search_inet_addr="no"
+cat > conftest.$ac_ext <<EOF
+#line 1952 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char inet_addr();
+
+int main() {
+inet_addr()
+; return 0; }
+EOF
+if { (eval echo configure:1963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_inet_addr="none required"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+test "$ac_cv_search_inet_addr" = "no" && for i in nsl; do
+LIBS="-l$i  $ac_func_search_save_LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1974 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char inet_addr();
+
+int main() {
+inet_addr()
+; return 0; }
+EOF
+if { (eval echo configure:1985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_search_inet_addr="-l$i"
+break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+LIBS="$ac_func_search_save_LIBS"
+fi
+
+echo "$ac_t""$ac_cv_search_inet_addr" 1>&6
+if test "$ac_cv_search_inet_addr" != "no"; then
+  test "$ac_cv_search_inet_addr" = "none required" || LIBS="$ac_cv_search_inet_addr $LIBS"
+  
+else :
+  
+fi
+
+# configure defaults CFLAGS to -g -O2
+# so a debug flag would have to fail to remove -g
+# and the optimize would have to modify or add the -O
+# flags:
+#  -debug:
+#       DEBUG2=$DEBUG
+#       AC_DEFINE(DEBUG)
+#  -optimize
+#       OPTIMIZE2=$OPTIMIZE
+#       AC_DEFINE(NDEBUG)
+#  -profile
+# Check whether --enable-profile or --disable-profile was given.
+if test "${enable_profile+set}" = set; then
+  enableval="$enable_profile"
+  if test $enableval = yes
+	then
+		if test "$GCC" = yes
+		then
+			CFLAGS="$CFLAGS -pg"
+		else
+			{ echo "configure: error: Don't know how to enable profiling for $CC" 1>&2; exit 1; }
+		fi
+	fi
+fi
+
+
+#  -bounds
+#       add -fbounds-checking to CFLAGS
+#       add -lcheck to LIBS
+# Check whether --enable-bounds or --disable-bounds was given.
+if test "${enable_bounds+set}" = set; then
+  enableval="$enable_bounds"
+  if test $enableval = yes
+	then
+		if test "$GCC" = yes
+		then
+			CFLAGS="$CFLAGS -fbounds-checking"
+			LIBS="$LIBS -lcheck"
+		else
+			{ echo "configure: error: Don't know how to enable profiling for $CC" 1>&2; exit 1; }
+		fi
+	fi
+fi
+
+
+#  others
+#       add as compile flag
+# also:
+# MBUS_ENCRYPT_BY_DEFAULT
+
+# -DDEBUG
+# -DDEBUG_MEM
+# -DNDEBUG
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+  if test $enableval = yes
+	then
+		cat >> confdefs.h <<\EOF
+#define DEBUG 1
+EOF
+
+	fi
+fi
+
+# Check whether --enable-debug-mem or --disable-debug-mem was given.
+if test "${enable_debug_mem+set}" = set; then
+  enableval="$enable_debug_mem"
+  if test $enableval = yes
+	then
+		cat >> confdefs.h <<\EOF
+#define DEBUG_MEM 1
+EOF
+
+	fi
+fi
+
+
+# Check whether --enable-ipv6 or --disable-ipv6 was given.
+if test "${enable_ipv6+set}" = set; then
+  enableval="$enable_ipv6"
+  if test $enableval = yes
+	then
+		cat >> confdefs.h <<\EOF
+#define HAVE_IPv6 1
+EOF
+
+	fi
+fi
+
+
+# Test below are IPv6 specific.  Their result has no bearing if HAVE_IPv6 is
+# not defined.  They are kept outside IPv6 enable check to keep code readable.
+
+echo $ac_n "checking for getipnodebyname in <netdb.h>""... $ac_c" 1>&6
+echo "configure:2101: checking for getipnodebyname in <netdb.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_getipnodebyname_in_netdb_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2106 "configure"
+#include "confdefs.h"
+#include <netdb.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "getipnodebyname" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_getipnodebyname_in_netdb_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_getipnodebyname_in_netdb_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_getipnodebyname_in_netdb_h" 1>&6
+if test $ucl_cv_getipnodebyname_in_netdb_h
+then
+	cat >> confdefs.h <<\EOF
+#define HAVE_GETIPNODEBYNAME 1
+EOF
+ 
+fi
+
+for ac_hdr in netinet6/in6.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2135: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2140 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for struct addrinfo in <netdb.h>""... $ac_c" 1>&6
+echo "configure:2173: checking for struct addrinfo in <netdb.h>" >&5
+if eval "test \"`echo '$''{'ucl_cv_st_addrinfo_in_netdb_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2178 "configure"
+#include "confdefs.h"
+#include <netdb.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "addrinfo" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ucl_cv_st_addrinfo_in_netdb_h=yes
+else
+  rm -rf conftest*
+  ucl_cv_st_addrinfo_in_netdb_h=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ucl_cv_st_addrinfo_in_netdb_h" 1>&6
+if test $ucl_cv_st_addrinfo_in_netdb_h
+then
+	cat >> confdefs.h <<\EOF
+#define HAVE_ST_ADDRINFO 1
+EOF
+ 
+fi
+
+echo $ac_n "checking for sin6_len in struct sockaddr_in6""... $ac_c" 1>&6
+echo "configure:2204: checking for sin6_len in struct sockaddr_in6" >&5
+if eval "test \"`echo '$''{'ucl_cv_sin6_len'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2209 "configure"
+#include "confdefs.h"
+
+		#ifdef HAVE_NETINET6_IN6_H
+		#include <netinet6/in6.h>
+		#else
+		#include <netinet/in.h>
+		#endif /* HAVE_NETINET_IN6_H */
+	
+int main() {
+
+		struct sockaddr_in6	s_in;
+		s_in.sin6_len = 0;
+	
+; return 0; }
+EOF
+if { (eval echo configure:2225: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ucl_cv_sin6_len=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ucl_cv_sin6_len=no
+	
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ucl_cv_sin6_len" 1>&6
+if test $ucl_cv_sin6_len = yes
+then
+	cat >> confdefs.h <<\EOF
+#define HAVE_SIN6_LEN 1
+EOF
+ 
+fi
+
+# GCC-specific warning flags
+if test "$GCC" = yes
+then
+        CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror"
+fi
+
+# Done, create the output files....
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Makefile uclconf.h:config.h.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@RANLIB@%$RANLIB%g
+s%@LIBOBJS@%$LIBOBJS%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="uclconf.h:config.h.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
Index: /common/tags/common_1_1_2/MODS
===================================================================
--- /common/tags/common_1_1_2/MODS (revision 432)
+++ /common/tags/common_1_1_2/MODS (revision 432)
@@ -0,0 +1,262 @@
+Common Code Library: Modification history
+
+v1.0.0  - Initial version, based on RAT v3.2.7
+	* 14 November 1998
+
+v1.0.1  - Added HMAC authentication code
+	- Added timeout to udp_recv()
+	- Added authentication of Mbus messages
+	- Added RTP library
+	- Added select and fd_set functions to net_udp.[ch]
+	- IPv6 code now runs on the pre-release stack for Solaris 2.7
+	- Mbus code support a configuration file on Unix, and the registry
+	  on Win32, to save/restore settings
+	- Add udp_host_addr() to get a text-version of the address to which
+	  a socket is bound.
+	- Set IPv6 ttl and loopback state correctly on Solaris
+	- Move mbus hearbeat code into this library
+	- Remove key expiry from the mbus code, since it created race
+	  conditions when multiple tools for a single conference were
+	  started either side of the expiry time.
+	- Update mbus addressing scheme - names are now sets of tokens, if the
+	  set of tokens in the destination address is a subset of the address 
+	  of the entity receiving that message then the message is accepted. An
+	  empty set is a valid destination address for a message, and that will
+	  be accepted by all receivers (ie: a wildcard).
+	- Remove channel ID from mbus code.
+	- Fix configure script to work with solaris 2.7 where inet_aton() and 
+	  inet_pton() have prototypes but no implementation.
+	* 31 March 1999 [rat v4.0.0]
+
+v1.0.2  - Assorted fixes to RTP library
+	- Fix bounds overruns in memory.c - will now run with -DDEBUG_MEM
+	  with the bounds checker on.
+	- Add timestamp to mbus packet headers.
+	- Add mbus_qmsgf()
+	- Cleanup mbus transmission path
+	- Add support for DES encryption to the mbus (on by default)
+	- Fix DES code
+	- Mbus keeps a cache of other entities, and only allows sending of
+	  reliable messages to known unicast addresses. 
+	- Mbus error function now takes a "type of error" argument
+	- Added xrealloc()
+	- Fix reordering of mbus messages
+	* 14 May 1999 [rat v4.0.1]
+
+v1.0.3  - Fix inet_aton() in net_udp.c
+	* 15 May 1999 [rat v4.0.2]
+
+v1.0.4  - Fix compilation with Microsoft IPv6 stack
+	- Solaris 2.5.1 doesn't have vsnprintf(), use vsprintf() instead
+	  and don't worry about the possible buffer overflow problems. 
+	  Reported by Holger Wirtz.
+	- Added mbus_addr_valid()
+	- Added timeout to mbus_recv()
+	- Fixes to mbus code from Dirk Kutscher
+	* 2 June 1999 [rat v4.0.3]
+
+v1.0.5  - Not quite sure what happened with this version, but if you have
+	  it it's probably not a good idea to use it! :-)
+
+v1.0.6  - Add ability to send to one port whilst receiving on another, 
+	  requested by Henning Schulzrinne.
+	- Add mbus_cmd_handler() to change the function handling the
+	  reception of mbus commands.
+	- Compilation fixes for Irix 6.5 contributed by Bob Olson.
+	- Add extra sanity checking to mbus_recv()
+	- Add extra sanity checking to mbus_parse_*
+	- Fix source address passed to mbus_recv() callback - was missing
+	  the "(" and ")" around it.
+	- Fix memory leak in mbus_recv()
+	- Fixes for configure script on 64 bit IRIX from Peter Orbaek
+	- Move base64 tests into test_base64.c and integrate with the test suite
+	* Released 5 July 1999 
+
+v1.0.7  - Add udp_exit to close sockets and leave multicast groups if necessary.
+	- Fix mbus_exit close sockets.
+	- Move the code to deal with the mbus configuration into mbus_config.c
+	  which will make it easier to write an mbus packet logger without code 
+	  duplication (such a logger can't easily be part of mbus.c, since it's
+	  needs conflict with correct protocol operation).
+	- Note that v1.3 of the Microsoft Research IPv6 stack requires an explicit
+	  route to be added for multicast traffic before a group can be joined. If
+	  you get errors in the IPV6_ADD_MEMBERSHIP setsockopt, this is probably
+	  the reason. We could specify an interface explicitly, but which one to
+	  pick?
+	- Updates to the IPv6 code for the Detexis Musica IPv6 stack
+	- Updates to the RTP code from Markus Germeier: time-out and delete sources,
+	  fix X but in RTP header, add support for sending BYE packets.
+	- Add inet_pton() and inet_ntop() implementations, for those platforms
+	  which are missing them.
+	- Add gettimeofday() workaround for win32
+	- Add drand48() workaround for win32
+	* Released 20 August 1999
+
+v1.0.8  - Add mbus_sent_all()
+	- Add loop count to mbus_recv(), so it will always return after 10
+	  packets have been received. The prevents a denial of service attack
+	  if packets are sent faster than the timeout period.
+	- Add binary tree.
+	- Add OpenBSD fixes from Angelos D. Keromytis
+	- Add Jerry Isdale's debug_dump() routine.
+	- Add fix to RTP init_seq() to correct bug(?) in RFC1889 which
+	  means we incorrectly report the one packet lost in the first
+	  reporting interval. Fix by Bill Fenner.
+	- Make the RTP create_source() routine return a pointer to the
+	  source. Patch from Bill Fenner.
+	- Changes to the probation code in rtp.c from Bill Fenner.
+	- Fix types in the RTP source struct.
+	- Add a SOURCE_CREATED event to the RTP callback.
+	- Add option to accept RTP packets before a corresponding RTCP
+	  packet has been received.
+	- Add RX_RR_EMPTY event to the RTP code, to indicate that an empty
+	  reception report (ie: no report blocks) has been received.
+	- Add RX_RTCP_START and RX_RTCP_FINISH events to the RTP code.
+	- debug_msg() now displays the pid
+	- The mbus code now maintains the list of active sources more correctly, 
+	  making mbus_addr_valid() useful
+	- rtp_init() now takes separate rx_port and tx_port, instead of a
+	  single port for both sending and receiving.
+	- Add rtp_get_addr(), rtp_get_rx_port(), rtp_get_tx_port() and rtp_get_ttl()
+	- Change return type of rtp_recv to int (was void).  Returns TRUE if
+	  packets were processed, FALSE otherwise.
+	- Timeout RRs from the RTP database, if they're not refreshed for
+	  3 times the RTCP reporting interval
+	- rtp_update() only expires sources once per reporting interval, to
+	  avoid burning too many cycles.
+	- Mbus updates contributed by Markus Germeier
+		- we now can configure the multicast address and port which the
+		  mbus should use in ~/.mbus 
+		- honor the SCOPE setting in ~/.mbus
+		- expire sources we haven't heard from for a while
+		- fixes small memory leak in remove_other_addr
+		- mbus_exit now sends a mbus.quit and cleans up other_* structures
+	- RTP updates contributed by Timur Friedman.
+		- Add support for RTCP APP packets
+		- Add support for a promiscuous mode to the RTP code, when in
+		  promiscuous mode there is no wait for a minimum number of RTP
+		  packets before recognizing a source.
+		- Add the functions rtp_setopt() and rtp_getopt() that can be used
+		  to control various options (right now just promiscuous mode).
+		- Split rtp_recv_data() into two functions.
+	* 5 October 1999
+
+v1.0.9  - Ignore ECONNREFUSED in net_udp.c
+	- Add mbus_rendezvous_waiting() and mbus_rendezvous_go() to enable
+	  easy rendezvous between multiple processes.
+	- Change rtp_setopt() and rtp_getopt() to take boolean options only.
+	- Remove rtp_weak_validation(), use rtp_setopt(RTP_OPT_WEAK_VALIDATION)
+	  instead.
+	- Delete RTP database entries which haven't been heard from for
+	  more than 5 times the RTCP reporting interval.
+	* 2 November 1999 [rat v4.1.1]
+
+v1.0.10 - Mbus updates from Markus Germeier, which fix compatibility with
+	  the Uni Bremen implementation:
+		- mbus.bye() signals an entity when it leaves. (mbus.quit commands
+		  an entity to leave)
+		- Generate and work with 64 bit DES keys. Generate parity bits for key.
+		  Check if key in configuration file sets parity bits correctly.
+		- mbus_heartbeat(m, 1) should send an mbus.hello() every second and
+		  not every two seconds
+		- HMAC-MD5 should read HMAC-MD5-96
+		- Honor the MBUS environment variable for the MBUS configuration file
+		- The TZI Mbus implementations generate spaces in configuration file,
+		  which mislead the UCL Mbus to dump core. Allow Spaces in .mbus
+		- Address must be unique
+		- Delete failed reliable messages if err_handler is present
+	- Fix uninitialized use of session->last_update in RTP code
+	- Fix assertion failures in RTP library when sending RTCP packets
+	- Recognize, but ignore, profile specific extensions to RTCP SR/RR packets
+	- Update RTCP reporting interval calculation
+	- Implement reverse reconsideration of RTCP reporting interval
+	- Fix tv_diff in rtp.c to handle negative results
+	- Remove rtp_get_encryption_key(), the user of the library is assumed to 
+	  remember the passphrase used and doesn't need access to the internal
+	  form of the key.
+	- GNU autoconf modifications from Bill Fenner
+	- Global change of integer types, and removal of compatibility defines:
+		u_int8  -> u_int8_t
+		u_int16 -> u_int16_t
+		u_int32 -> u_int32_t
+	  and the same for the signed varients.
+	- Implement encryption in the RTP code
+	- Ignore connection refused errors in IPv4 UDP send.
+	- Hide definition of struct mbus_config
+	- Add a version number to the mbus config file
+	- Fixes for FreeBSD v3.2 with INRIA IPv6 stack from Fred Templin
+	- Add configure check for sin6_len in struct sockaddr_in6 (seems
+	  that FreeBSD has this, but many systems don't)
+	- Fix batching of multiple mbus messages into one packet.
+	* 13 December 1999 [rat v4.1.2]
+
+v1.1.0  - Changed autoconf generated header to uclconf.h.
+	- Changed library name to uclmmbase to be consistent with other libs.   
+	- Add RTP_OPT_FILTER_MY_PACKETS
+	- Cleanup test routines
+	- Fix various potential buffer overflow problems
+	- Update copyright notices to welcome in the new millennium
+	- Previous versions of udp_send() would sometimes return -1 on error, 
+	  and would sometimes abort(). We now always return -1 and never abort.
+	- Add test routines for code in net_udp.c
+	- Fix SCOPE parameter in mbus configuration on windows
+	- Fix sending of hearbeat messages whilst in mbus.waiting() and mbus.go() loops
+	- Tidy up mbus_qmsg();
+	- Add workaround for buffer overflow bug in _dprintf() which caused
+	  a crash under Windows NT service pack 6. This is not a real fix, we
+	  need to use vsnprintf() in there, but Windows doesn't implement it
+	  and I don't have time before we give the demo... Sigh, only two
+	  days wasted.
+	- Fix buffer overflow in _dprintf() on Windows, using _vsnprintf().
+	- Update IPv6 support for Microsoft Research IPv6 stack, v1.4
+		- Use the versions of inet_ntop() and inet_pton() provided with the 
+		  IPv6 stack, but retain our own implementation when building with 
+		  IPv4 support only.
+		- Use getaddrinfo() rather than getnodebyname() to get our IPv6 address if
+		  running with the Microsoft Research IPv6 stack. 
+		- We now require getaddrinfo() to be present in all IPv6 stacks: those which
+		  do not have this call (eg: the Musica IPv6 stack) MUST provide a workaround
+		  implementation.
+	  versions of MSR IPv6 prior to 1.4 are no longer supported.
+	- Update IPv6 support for Red Hat Linux 6.1
+	- Fix generation of version.h on Win32
+	- Add VC++ project file to build the test suite under Win32
+	- Add extra debug code to the mbus library
+	- Rewrite mbus code: mbus_parser.[ch] exist now, and include routines moved from the
+	  main mbus.[ch] files. Note that the interface to the mbus_parse_*() functions has
+	  now changed and is not backwards compatible.
+	- Remove the mbus_addr() function, add an extra parameter to mbus_init() instead.
+	* 28 January 2000
+
+v1.1.1	- Add extra debugging code
+	* 1 February 2000
+
+v1.1.2	- Add routines for handling NTP format timestamps, in ntp.[ch]
+	- Add udp_addr_valid.
+        - Fix cname setup for Win32.
+	- Add udp_init_if() call, to open a UDP/IP socket bound to a
+	  specific interface
+	- Add rtp_init_if() call, to open an RTP socket bound to a 
+	  specific interface
+	- Add asarray.[ch] string holding associative array.
+	- Fix compilation with -Wwrite-strings and -Wcast-align
+	- Split mbus_addr_match() and mbus_add_identical() into mbus_addr.[ch]
+	* 14 February 2000
+
+
+Still to do...
+	- IPv6 code sometimes doesn't get the correct interface address,
+	  since it does a gethostbyname() and looks that up, yet that can
+	  return the IPv4 hostname only on some machines.
+	- Doesn't do DNS AAAA lookups when given a name rather than an IP address.
+	- Mbus code should check timestamp in received headers, and discard
+	  messages if it decreases, as a hinderance to replay attacks.
+	- Mbus code should be more paranoid about handling garbage inputs, we
+	  can likely get all sorts of buffer overflows by feeding random data
+	  into it.
+	- rtp_recv should split into rtp_select and rtp_recv. Jitter issues
+	  otherwise, as pointed out by Orion.
+	- Allow a callback for background processing during mbus_rendezvous_*()
+	- mbus_exit() queues an mbus.bye() message, but that never gets sent.
+	- Handling of SSRC collisions is broken.
+
Index: /common/tags/common_1_1_2/tests/test_mbus_addr.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_mbus_addr.c (revision 428)
+++ /common/tags/common_1_1_2/tests/test_mbus_addr.c (revision 428)
@@ -0,0 +1,108 @@
+/*
+ * FILE:    test_mbus_addr.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "mbus_addr.h"
+#include "test_mbus_addr.h"
+
+int strfind(const char *haystack, const char *needle_start, const char *needle_end);
+
+void test_mbus_addr(void)
+{
+	const char	haystack[] = "The quick brown fox jumped over the lazy dog";
+	const char	needle_1[] = "fox";
+	const char	needle_2[] = "fat fox jumping";
+	const char	needle_3[] = "The";
+	const char	needle_4[] = "dog";
+	const char	a1[] = "()";
+	const char	a2[] = "(one two three)";
+	const char	a3[] = "(four five six)";
+	const char	a4[] = "six four";
+	const char	a5[] = "three one two";
+
+	printf("Mbus addr (strfind).................... "); fflush(stdout);
+	if (!strfind(haystack, needle_1, needle_1 + strlen(needle_1) - 1)) {
+		printf("fail (1)\n");
+		goto match;
+	}
+	if (strfind(haystack, needle_2, needle_2 + strlen(needle_2) - 1)) {
+		printf("fail (2)\n");
+		goto match;
+	}
+	if (!strfind(haystack, needle_3, needle_3 + strlen(needle_1) - 1)) {
+		printf("fail (3)\n");
+		goto match;
+	}
+	if (!strfind(haystack, needle_4, needle_4 + strlen(needle_1) - 1)) {
+		printf("fail (4)\n");
+		goto match;
+	}
+	if (!strfind(haystack, needle_2 + 4, needle_2 + 7)) {
+		printf("fail (5)\n");
+		goto match;
+	}
+	printf("pass\n");
+
+match:
+	printf("Mbus addr (match)...................... "); fflush(stdout);
+	if (!mbus_addr_match(a2, a1)) {
+		printf("fail (1)\n");
+		goto identical;
+	}
+	if (mbus_addr_match(a2, a3)) {
+		printf("fail (2)\n");
+		goto identical;
+	}
+	if (!mbus_addr_match(a3, a4)) {
+		printf("fail (3)\n");
+		goto identical;
+	}
+	printf("pass\n");
+
+identical:
+	printf("Mbus addr (identical).................. "); fflush(stdout);
+	if (!mbus_addr_identical(a2, a5)) {
+		printf("fail (1)\n");
+		return;
+	}
+	if (mbus_addr_identical(a4, a3)) {
+		printf("fail (2)\n");
+		return;
+	}
+	printf("pass\n");
+}
+
Index: /common/tags/common_1_1_2/tests/test_net_udp.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_net_udp.h (revision 362)
+++ /common/tags/common_1_1_2/tests/test_net_udp.h (revision 362)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_net_udp.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_net_udp(void);
+
Index: /common/tags/common_1_1_2/tests/test_mbus_addr.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_mbus_addr.h (revision 428)
+++ /common/tags/common_1_1_2/tests/test_mbus_addr.h (revision 428)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_mbus_addr.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_mbus_addr(void);
+
Index: /common/tags/common_1_1_2/tests/test_memory.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_memory.c (revision 425)
+++ /common/tags/common_1_1_2/tests/test_memory.c (revision 425)
@@ -0,0 +1,121 @@
+/*
+ * FILE:    test_memory.c
+ * AUTHORS: Orion Hodson
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "drand48.h"
+#include "memory.h"
+#include "util.h"
+
+#include "test_memory.h"
+
+#ifdef DEBUG_MEM
+
+static size_t sz[] = {17, 32, 64, 81, 1024, 4096};
+
+static void 
+do_test()
+{
+        static char     *b[37];
+        static uint32_t  s[37];
+        uint32_t         i, idx, nslots, nszs, r;
+        uint32_t         allocations;
+
+        memset(b, 0, sizeof(b));
+        memset(s, 0, sizeof(s));
+
+        nszs = sizeof(sz)/sizeof(sz[0]);
+        nslots  = sizeof(b)/sizeof(b[0]);
+
+        /* test xmalloc */
+        for (allocations = 10; allocations < 1000000; allocations *= 10) {
+                for (i = 0; i < allocations; i++) {
+                        idx = drand48();
+                        idx = idx % nslots;
+                        if (b[idx] != NULL) {
+                                xfree(b[idx]);
+                        }
+                        r = drand48();
+                        b[idx] = (void*)xmalloc(sz[r % nszs]);
+                }
+
+                for(idx = 0; idx < nslots; idx++) {
+                        xmemchk();
+                        if (b[idx] != NULL) {
+                                xfree(b[idx]);
+                                b[idx] = NULL;
+                        }
+                        xmemchk();
+                }
+        }
+
+        /* test block alloc */
+        for (allocations = 10; allocations < 1000000; allocations *= 10) {
+                for (i = 0; i < allocations; i++) {
+                        idx = drand48();
+                        idx = idx % nslots;
+                        if (b[idx] != NULL) {
+                                block_free(b[idx], s[idx]);
+                        }
+                        r = drand48();
+                        s[idx] = sz[r % nszs];
+                        b[idx] = (void*)block_alloc(s[idx]);
+                }
+
+                for(idx = 0; idx < nslots; idx++) {
+                        xmemchk();
+                        if (b[idx] != NULL) {
+                                block_free(b[idx], s[idx]);
+                                b[idx] = NULL;
+                        }
+                        xmemchk();
+                }
+        }
+}
+
+
+void test_memory(void)
+{
+        printf("Memory................................. "); fflush(stdout);
+        do_test();
+        printf("pass\n");
+}
+#else
+void test_memory(void)
+{
+        return;
+}
+#endif /* DEBUG_MEM */
Index: /common/tags/common_1_1_2/tests/test_des.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_des.c (revision 362)
+++ /common/tags/common_1_1_2/tests/test_des.c (revision 362)
@@ -0,0 +1,263 @@
+/*
+ * FILE:    test_des.c
+ * AUTHORS: Colin Perkins
+ *
+ * The test vectors and outline structure of this are taken from Eric
+ * Young's destest.c from libdes, version 3.00 (7 October 1993). 
+ *
+ * Copyright (c) 1993 Eric Young
+ * All rights reserved.
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "qfDES.h"
+#include "test_des.h"
+
+#define NUM_TESTS 36
+
+static unsigned char key_data[NUM_TESTS][8]={
+	{0x12,0x34,0x57,0x79,0x9b,0xbc,0xdf,0xf1},
+	{0x0e,0x32,0x92,0x32,0xea,0x6d,0x0d,0x72},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+	{0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+	{0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+	{0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+	{0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+	{0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+	{0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+	{0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+	{0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+	{0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+	{0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+	{0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+	{0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+	{0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+	{0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+	{0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+	{0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+	{0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+	{0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+	{0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+	{0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+	{0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+	{0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+	{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
+	{0x87,0x87,0x87,0x87,0x87,0x87,0x87,0x87},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+	{0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+	{0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+	{0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+	{0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+	{0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+	{0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+	{0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+	{0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+	{0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+	{0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+	{0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+	{0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+	{0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+	{0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+	{0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+	{0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+	{0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+	{0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char crypt_data[NUM_TESTS][8]={
+	{0x85,0xe8,0x13,0x54,0x0f,0x0a,0xb4,0x05},
+	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+	{0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+	{0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+	{0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+	{0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+	{0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+	{0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+	{0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+	{0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+	{0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+	{0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+	{0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+	{0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+	{0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+	{0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+	{0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+	{0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+	{0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+	{0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+	{0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+	{0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+	{0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+	{0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+	{0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+	{0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+	{0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+	{0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+	{0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+	{0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+	{0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+	{0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+	{0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+	{0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+	{0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cbc_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc_iv[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_data[32]="7654321 Now is the time for ";
+
+static unsigned char cbc_ok[32]={
+	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+	0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+	0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifdef NDEF
+static unsigned char pcbc_ok[32]={
+	0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+	0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+	0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+	0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cksum_ok[8]={
+	0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[24],cfb_buf2[24],cfb_tmp[8];
+static unsigned char cfb_plain[24]={
+	0x4e,0x6f,0x77,0x20,0x69,0x73,
+	0x20,0x74,0x68,0x65,0x20,0x74,
+	0x69,0x6d,0x65,0x20,0x66,0x6f,
+	0x72,0x20,0x61,0x6c,0x6c,0x20};
+static unsigned char cfb_cipher[24]= {
+	0xf3,0x1f,0xda,0x07,0x01,0x14,
+	0x62,0xee,0x18,0x7f,0x43,0xd8,
+	0x0a,0x7c,0xd9,0xb5,0xb0,0xd2,
+	0x90,0xda,0x6e,0x5b,0x9a,0x87};
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_plain[24]={
+	0x4e,0x6f,0x77,0x20,0x69,0x73,
+	0x20,0x74,0x68,0x65,0x20,0x74,
+	0x69,0x6d,0x65,0x20,0x66,0x6f,
+	0x72,0x20,0x61,0x6c,0x6c,0x20};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]={
+	0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+	0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3};
+#endif
+
+void test_des(void)
+{
+	int 		i, j;
+	unsigned char	key[8], plain[8], crypt[8], buffer[8];
+	unsigned char	cbc_buffer[32], cbc_iv_buf[8];
+
+	printf("DES ECB................................ "); fflush(stdout);
+	for (i = 0; i < NUM_TESTS; i++) {
+		for (j = 0; j < 8; j++) {
+			key[j]   = key_data[i][j];
+			plain[j] = plain_data[i][j];
+			crypt[j] = crypt_data[i][j];
+		}
+		memcpy(buffer, crypt, 8);
+		qfDES_ECB_d(key, buffer, 8);
+		if (memcmp(buffer, plain, 8) != 0) {
+			printf("fail\n");
+			goto abort_ecb;
+		}
+		memcpy(buffer, plain, 8);
+		qfDES_ECB_e(key, buffer, 8);
+		if (memcmp(buffer, crypt, 8) != 0) {
+			printf("fail\n");
+			goto abort_ecb;
+		}
+		qfDES_ECB_d(key, buffer, 8);
+		if (memcmp(buffer, plain, 8) != 0) {
+			printf("fail\n");
+			goto abort_ecb;
+		}
+	}
+	printf("pass\n");
+abort_ecb:
+
+	printf("DES CBC................................ "); fflush(stdout);
+	memcpy(cbc_buffer, cbc_data, 32);
+	memcpy(cbc_iv_buf, cbc_iv, 8);
+	qfDES_CBC_e(cbc_key, cbc_buffer, 32, cbc_iv_buf);
+	if (memcmp(cbc_buffer, cbc_ok, 32) != 0) {
+		printf("fail\n");
+		return;
+	}
+	memcpy(cbc_iv_buf, cbc_iv, 8);
+	qfDES_CBC_d(cbc_key, cbc_buffer, 32, cbc_iv_buf);
+	if (memcmp(cbc_buffer, cbc_data, 32) != 0) {
+		printf("fail\n");
+		return;
+	}
+	printf("pass\n");
+}
+
Index: /common/tags/common_1_1_2/tests/test_memory.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_memory.h (revision 425)
+++ /common/tags/common_1_1_2/tests/test_memory.h (revision 425)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_memory.h
+ * AUTHORS: Orion Hodson
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_memory(void);
+
Index: /common/tags/common_1_1_2/tests/test.c
===================================================================
--- /common/tags/common_1_1_2/tests/test.c (revision 428)
+++ /common/tags/common_1_1_2/tests/test.c (revision 428)
@@ -0,0 +1,80 @@
+/*
+ * FILE:    test.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "version.h"
+#include "test_base64.h"
+#include "test_des.h"
+#include "test_md5.h"
+#include "test_memory.h"
+#include "test_net_udp.h"
+#include "test_mbus_parser.h"
+#include "test_mbus_addr.h"
+
+#ifdef WIN32
+#define WS_VERSION_ONE MAKEWORD(1,1)
+#define WS_VERSION_TWO MAKEWORD(2,2)
+#endif
+
+int main(int argc, char *argv[])
+{
+#ifdef WIN32
+	WSADATA WSAdata;
+	if (WSAStartup(WS_VERSION_TWO, &WSAdata) != 0 && WSAStartup(WS_VERSION_ONE, &WSAdata) != 0) {
+    		printf("Windows Socket initialization failed.\n");
+		return 1;
+	}
+	debug_msg("WSAStartup OK: %sz\nStatus:%s\n", WSAdata.szDescription, WSAdata.szSystemStatus);
+#endif
+
+	UNUSED(argc);
+	UNUSED(argv);
+	printf("Testing common multimedia library %s\n", CCL_VERSION);
+	test_base64();
+	test_des();
+	test_md5();
+        test_memory();
+	test_net_udp();
+	test_mbus_parser();
+	test_mbus_addr();
+#ifdef WIN32
+	Sleep(2000);
+	WSACleanup();
+#endif
+	return 0;
+}
+
Index: /common/tags/common_1_1_2/tests/test_des.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_des.h (revision 360)
+++ /common/tags/common_1_1_2/tests/test_des.h (revision 360)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_des.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_des(void);
+
Index: /common/tags/common_1_1_2/tests/test_mbus_parser.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_mbus_parser.c (revision 428)
+++ /common/tags/common_1_1_2/tests/test_mbus_parser.c (revision 428)
@@ -0,0 +1,47 @@
+/*
+ * FILE:    test_mbus_parser.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "mbus_parser.h"
+#include "test_mbus_parser.h"
+
+void test_mbus_parser(void)
+{
+	printf("Mbus parser............................ "); fflush(stdout);
+	printf("fail\n");
+}
+
Index: /common/tags/common_1_1_2/tests/test_base64.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_base64.c (revision 428)
+++ /common/tags/common_1_1_2/tests/test_base64.c (revision 428)
@@ -0,0 +1,70 @@
+/*
+ * FILE:    test_base64.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "base64.h"
+#include "test_base64.h"
+
+void test_base64(void)
+{
+	/* The string "Hello, world" should encode as "SGVsbG8sIHdvcmxk" */
+	const char	*input = "Hello, world";
+	char	 output[100];
+	char	 decode[100];
+	int	 i;
+
+	for (i = 0; i < 100; i++) {
+		output[i] = '\0';
+	}
+
+	printf("Base64 encode.......................... "); fflush(stdout);
+	i = base64encode(input, strlen(input), output, 100);
+	if ((i != 16) || (strncmp(output, "SGVsbG8sIHdvcmxk", i) != 0)) {
+		printf("fail\n");
+		return;
+	}
+	printf("pass\n");
+
+	printf("Base64 decode.......................... "); fflush(stdout);
+	i = base64decode(output, i, decode, 100);
+	if ((i != 12) || (strncmp(decode, "Hello, world", i) != 0)) {
+		printf("fail\n");
+		return;
+	}
+	printf("pass\n");
+}
+
Index: /common/tags/common_1_1_2/tests/test_md5.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_md5.c (revision 362)
+++ /common/tags/common_1_1_2/tests/test_md5.c (revision 362)
@@ -0,0 +1,79 @@
+/*
+ * FILE:    test_md5.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "md5.h"
+#include "test_md5.h"
+
+static int do_test(int len)
+{
+        unsigned char *input;
+        unsigned char  output[16];
+	int            i;
+	MD5_CTX        context;
+
+	input = (unsigned char *) xmalloc(len+1);
+	for (i = 0; i < len; i++) {
+		input[i] = lrand48() % 255;
+	}
+	input[len] = '\0';
+
+	MD5Init(&context);
+	MD5Update(&context, input, len);
+	MD5Final(output, &context); 
+
+	xfree(input);
+
+	return TRUE;
+}
+
+void test_md5(void)
+{
+	int	i, l;
+
+	printf("MD5.................................... "); fflush(stdout);
+	for (i = 0; i < 10000; i++) {
+		l = lrand48() % 1024;
+		if (do_test(l) == FALSE) {
+			printf("fail\n");
+			abort();
+		}
+	}
+	printf("pass\n");
+}
+
Index: /common/tags/common_1_1_2/tests/test_mbus_parser.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_mbus_parser.h (revision 428)
+++ /common/tags/common_1_1_2/tests/test_mbus_parser.h (revision 428)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_mbus_parser.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_mbus_parser(void);
+
Index: /common/tags/common_1_1_2/tests/test_base64.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_base64.h (revision 360)
+++ /common/tags/common_1_1_2/tests/test_base64.h (revision 360)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_base64.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_base64(void);
+
Index: /common/tags/common_1_1_2/tests/test_md5.h
===================================================================
--- /common/tags/common_1_1_2/tests/test_md5.h (revision 360)
+++ /common/tags/common_1_1_2/tests/test_md5.h (revision 360)
@@ -0,0 +1,37 @@
+/*
+ * FILE:    test_md5.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void test_md5(void);
+
Index: /common/tags/common_1_1_2/tests/testcommon.dsp
===================================================================
--- /common/tags/common_1_1_2/tests/testcommon.dsp (revision 383)
+++ /common/tags/common_1_1_2/tests/testcommon.dsp (revision 383)
@@ -0,0 +1,160 @@
+# Microsoft Developer Studio Project File - Name="testcommon" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=testcommon - Win32 Debug IPv6
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "testcommon.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "testcommon.mak" CFG="testcommon - Win32 Debug IPv6"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "testcommon - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "testcommon - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "testcommon - Win32 Debug IPv6" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "testcommon - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "testcommon - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "testcommon___Win32_Debug"
+# PROP BASE Intermediate_Dir "testcommon___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEBUG" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"\src\common\Debug"
+
+!ELSEIF  "$(CFG)" == "testcommon - Win32 Debug IPv6"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug IPv6"
+# PROP BASE Intermediate_Dir "Debug IPv6"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_IPv6"
+# PROP Intermediate_Dir "Debug_IPv6"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "\DDK\inc" /I "..\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "HAVE_IPv6" /D "DEBUG" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/testcommon.exe" /pdbtype:sept /libpath:"\src\common\Debug"
+# ADD LINK32 uclmm.lib winmm.lib wsock32.lib Ws2_32.lib kernel32.lib user32.lib advapi32.lib wship6.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"\src\common\Debug_IPv6" /libpath:"\src\IPv6Kit\lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "testcommon - Win32 Release"
+# Name "testcommon - Win32 Debug"
+# Name "testcommon - Win32 Debug IPv6"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\test.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_base64.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_des.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_net_udp.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\test_base64.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_des.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_md5.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\test_net_udp.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
Index: /common/tags/common_1_1_2/tests/test_net_udp.c
===================================================================
--- /common/tags/common_1_1_2/tests/test_net_udp.c (revision 423)
+++ /common/tags/common_1_1_2/tests/test_net_udp.c (revision 423)
@@ -0,0 +1,297 @@
+/*
+ * FILE:    test_net_udp.c
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "net_udp.h"
+#include "test_net_udp.h"
+
+#define BUFSIZE 1024
+
+static void randomize(char buf[], int buflen)
+{
+	int	i;
+
+	for (i = 0; i < buflen; i++) {
+		buf[i] = (lrand48() && 0xff00) >> 8;
+	}
+}
+
+void test_net_udp(void)
+{
+	struct timeval	 timeout;
+	socket_udp	*s1, *s2;
+	char		 buf1[BUFSIZE], buf2[BUFSIZE];
+	const char	*hname;
+	int		 rc;
+
+	srand48(time(NULL));
+
+	/**********************************************************************/
+	/* The first test is to loopback a packet to ourselves...             */
+	printf("UDP/IP networking (IPv4 loopback)...... "); fflush(stdout);
+	s1 = udp_init("127.0.0.1", 5000, 5000, 1);
+	if (s1 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+	randomize(buf1, BUFSIZE);
+	randomize(buf2, BUFSIZE);
+	if (udp_send(s1, buf1, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_loopback;
+	}
+	timeout.tv_sec  = 1;
+	timeout.tv_usec = 0;
+	udp_fd_zero();
+	udp_fd_set(s1);
+	rc = udp_select(&timeout);
+	if (rc < 0) {
+		perror("fail");
+		goto abort_loopback;
+	}
+	if (rc == 0) {
+		printf("fail: no data waiting\n");
+		goto abort_loopback;
+	}
+	if (!udp_fd_isset(s1)) {
+		printf("fail: no data on file descriptor\n");
+		goto abort_loopback;
+	}
+	if (udp_recv(s1, buf2, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_loopback;
+	}
+	if (memcmp(buf1, buf2, BUFSIZE) != 0) {
+		printf("fail: buffer corrupt\n");
+		goto abort_loopback;
+	}
+	printf("pass\n");
+abort_loopback:
+	hname = udp_host_addr(s1); /* we need this for the unicast test... */
+	udp_exit(s1);
+
+	/**********************************************************************/
+	/* Now we send a packet to ourselves via our real network address...  */
+	printf("UDP/IP networking (IPv4 unicast)....... "); fflush(stdout);
+	s1 = udp_init(hname, 5000, 5001, 1);
+	if (s1 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+
+	s2 = udp_init(hname, 5001, 5000, 1);
+	if (s2 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+
+	randomize(buf1, BUFSIZE);
+	randomize(buf2, BUFSIZE);
+	if (udp_send(s1, buf1, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_unicast;
+	}
+	timeout.tv_sec  = 1;
+	timeout.tv_usec = 0;
+	udp_fd_zero();
+	udp_fd_set(s1);
+	udp_fd_set(s2);
+	rc = udp_select(&timeout);
+	if (rc < 0) {
+		perror("fail");
+		goto abort_unicast;
+	}
+	if (rc == 0) {
+		printf("fail: no data waiting (no route to %s?)\n", hname);
+		goto abort_unicast;
+	}
+	if (!udp_fd_isset(s2)) {
+		printf("fail: no data on file descriptor\n");
+		goto abort_unicast;
+	}
+	if (udp_recv(s2, buf2, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_unicast;
+	}
+	if (memcmp(buf1, buf2, BUFSIZE) != 0) {
+		printf("fail: buffer corrupt\n");
+		goto abort_unicast;
+	}
+	printf("pass\n");
+abort_unicast:
+	udp_exit(s1);
+	udp_exit(s2);
+
+	/**********************************************************************/
+	/* Loopback a packet to ourselves via multicast...                    */
+	printf("UDP/IP networking (IPv4 multicast)..... "); fflush(stdout);
+	s1 = udp_init("224.2.0.1", 5000, 5000, 1);
+	if (s1 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+	randomize(buf1, BUFSIZE);
+	randomize(buf2, BUFSIZE);
+	if (udp_send(s1, buf1, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_multicast;
+	}
+	timeout.tv_sec  = 1;
+	timeout.tv_usec = 0;
+	udp_fd_zero();
+	udp_fd_set(s1);
+	rc = udp_select(&timeout);
+	if (rc < 0) {
+		perror("fail");
+		goto abort_multicast;
+	}
+	if (rc == 0) {
+		printf("fail: no data waiting (no multicast loopback route?)\n");
+		goto abort_multicast;
+	}
+	if (!udp_fd_isset(s1)) {
+		printf("fail: no data on file descriptor\n");
+		goto abort_multicast;
+	}
+	if (udp_recv(s1, buf2, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_multicast;
+	}
+	if (memcmp(buf1, buf2, BUFSIZE) != 0) {
+		printf("fail: buffer corrupt\n");
+		goto abort_multicast;
+	}
+	hname = udp_host_addr(s1); /* we need this for the unicast test... */
+	printf("pass\n");
+abort_multicast:
+	udp_exit(s1);
+
+#ifdef HAVE_IPv6
+	/**********************************************************************/
+	/* The first test is to loopback a packet to ourselves...             */
+	printf("UDP/IP networking (IPv6 loopback)...... "); fflush(stdout);
+	s1 = udp_init("::1", 5000, 5000, 1);
+	if (s1 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+	randomize(buf1, BUFSIZE);
+	randomize(buf2, BUFSIZE);
+	if (udp_send(s1, buf1, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_loopback_ipv6;
+	}
+	timeout.tv_sec  = 1;
+	timeout.tv_usec = 0;
+	udp_fd_zero();
+	udp_fd_set(s1);
+	rc = udp_select(&timeout);
+	if (rc < 0) {
+		perror("fail");
+		goto abort_loopback_ipv6;
+	}
+	if (rc == 0) {
+		printf("fail: no data waiting\n");
+		goto abort_loopback_ipv6;
+	}
+	if (!udp_fd_isset(s1)) {
+		printf("fail: no data on file descriptor\n");
+		goto abort_loopback_ipv6;
+	}
+	if (udp_recv(s1, buf2, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_loopback_ipv6;
+	}
+	if (memcmp(buf1, buf2, BUFSIZE) != 0) {
+		printf("fail: buffer corrupt\n");
+		goto abort_loopback_ipv6;
+	}
+	printf("pass\n");
+abort_loopback_ipv6:
+	udp_exit(s1);
+
+	/**********************************************************************/
+	/* Loopback a packet to ourselves via multicast. The address is the   */
+	/* SAP address, but we use a different port.                          */
+	printf("UDP/IP networking (IPv6 multicast)..... "); fflush(stdout);
+	s1 = udp_init("ff01::2:7ffe", 5000, 5000, 1);
+	if (s1 == NULL) {
+		printf("fail: cannot initialize socket\n");
+		return;
+	}
+	randomize(buf1, BUFSIZE);
+	randomize(buf2, BUFSIZE);
+	if (udp_send(s1, buf1, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_multicast_ipv6;
+	}
+	timeout.tv_sec  = 1;
+	timeout.tv_usec = 0;
+	udp_fd_zero();
+	udp_fd_set(s1);
+	rc = udp_select(&timeout);
+	if (rc < 0) {
+		perror("fail");
+		goto abort_multicast_ipv6;
+	}
+	if (rc == 0) {
+		printf("fail: no data waiting (no multicast loopback route?)\n");
+		goto abort_multicast_ipv6;
+	}
+	if (!udp_fd_isset(s1)) {
+		printf("fail: no data on file descriptor\n");
+		goto abort_multicast_ipv6;
+	}
+	if (udp_recv(s1, buf2, BUFSIZE) < 0) {
+		perror("fail");
+		goto abort_multicast_ipv6;
+	}
+	if (memcmp(buf1, buf2, BUFSIZE) != 0) {
+		printf("fail: buffer corrupt\n");
+		goto abort_multicast_ipv6;
+	}
+	hname = udp_host_addr(s1); /* we need this for the unicast test... */
+	printf("pass\n");
+abort_multicast_ipv6:
+	udp_exit(s1);
+#else
+	printf("UDP/IP networking (IPv6 loopback)...... disabled\n");
+	printf("UDP/IP networking (IPv6 unicast)....... disabled\n");
+	printf("UDP/IP networking (IPv6 multicast)..... disabled\n");
+#endif
+}
+
Index: /common/tags/common_1_1_2/common.dsw
===================================================================
--- /common/tags/common_1_1_2/common.dsw (revision 8)
+++ /common/tags/common_1_1_2/common.dsw (revision 8)
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "common"=.\common.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
Index: /common/tags/common_1_1_2/VERSION
===================================================================
--- /common/tags/common_1_1_2/VERSION (revision 407)
+++ /common/tags/common_1_1_2/VERSION (revision 407)
@@ -0,0 +1,1 @@
+1.1.2
Index: /common/tags/common_1_1_2/configure.in
===================================================================
--- /common/tags/common_1_1_2/configure.in (revision 430)
+++ /common/tags/common_1_1_2/configure.in (revision 430)
@@ -0,0 +1,257 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(base64.c)
+
+AC_CANONICAL_HOST
+
+#  UCL checked $host_os and exited if we didn't recognize it.
+#  Let's be more optimistic for now.
+
+# XXX
+# Backwards compatability to UCL's -D<ostype> for now
+# All references to an OS should be replaced by references
+# to features!
+
+case "$host_os" in
+sunos*)
+	AC_DEFINE(SunOS)
+	;;
+solaris*)
+	AC_DEFINE(Solaris)
+	;;
+esac
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_RANLIB
+
+AC_HEADER_STDC
+AC_C_CONST
+AC_TYPE_SIZE_T
+
+AC_CHECK_HEADERS(stropts.h sys/filio.h)
+AC_CHECK_HEADERS(stdint.h inttypes.h)
+
+# Check for standard size types.  The defaults are only valid on some
+# systems so we hope that <inttypes.h> exists when they're wrong.
+AC_CHECK_TYPE(int8_t,  signed char)
+AC_CHECK_TYPE(int16_t, short)
+AC_CHECK_TYPE(int32_t, long)
+AC_CHECK_TYPE(int64_t, long long)
+
+# Some systems have these in <stdint.h>, just to be difficult...
+AC_CACHE_CHECK(for uint8_t in <stdint.h>, ucl_cv_uint8_t_in_stdint_h,
+	AC_EGREP_HEADER(uint8_t,
+			stdint.h,
+			ucl_cv_uint8_t_in_stdint_h=yes,
+			ucl_cv_uint8_t_in_stdint_h=no))
+if test $ucl_cv_uint8_t_in_stdint_h = "no"
+then
+	 AC_CHECK_TYPE(uint8_t,  unsigned char)
+fi
+
+AC_CACHE_CHECK(for uint16_t in <stdint.h>, ucl_cv_uint16_t_in_stdint_h,
+	AC_EGREP_HEADER(uint16_t,
+			stdint.h,
+			ucl_cv_uint16_t_in_stdint_h=yes,
+			ucl_cv_uint16_t_in_stdint_h=no))
+if test $ucl_cv_uint16_t_in_stdint_h = "no"
+then
+	 AC_CHECK_TYPE(uint16_t,  unsigned short)
+fi
+
+AC_CACHE_CHECK(for uint32_t in <stdint.h>, ucl_cv_uint32_t_in_stdint_h,
+	AC_EGREP_HEADER(uint32_t,
+			stdint.h,
+			ucl_cv_uint32_t_in_stdint_h=yes,
+			ucl_cv_uint32_t_in_stdint_h=no))
+if test $ucl_cv_uint32_t_in_stdint_h = "no"
+then
+	 AC_CHECK_TYPE(uint32_t,  unsigned int)
+fi
+
+# The following two macros cause autoconf to complain.
+AC_C_BIGENDIAN
+AC_C_CHAR_UNSIGNED
+#
+# The (?which?) library does not work with unsigned characters.
+# Force the compiler to use signed chars.
+if test $ac_cv_c_char_unsigned = yes
+then
+	if test "$GCC" = yes
+	then
+		CFLAGS="$CFLAGS -fsigned-char"
+	else
+		case "$host_os" in
+		# I don't know when "-signed" was added to IRIX CC
+		# so err on the side of using it.
+		irix*)	CFLAGS="$CFLAGS -signed"
+			;;
+		# need e.g. --force-signed-chars=-signed
+		*)	AC_MSG_ERROR([I don't know how to force signed chars])
+			;;
+		esac
+	fi
+fi
+#  __CHAR_UNSIGNED__ will be defined; hope this is OK.
+
+# The following causes autoconf to complain.
+AC_CHECK_FILE(/dev/urandom,AC_DEFINE(HAVE_DEV_URANDOM))
+
+# If more files than mbus.c use vsnprintf, split it out into
+# vsnprintf.c and add it to AC_REPLACE_FUNCS
+AC_CHECK_FUNC(vsnprintf,,AC_DEFINE(NEED_VSNPRINTF))
+
+# If inet_aton is actually needed somewhere, split it out into
+# inet_aton.c and add it to AC_REPLACE_FUNCS 
+#
+# AC_CHECK_FUNC succeeds on our IRIX 6.2 boxes, but it is not 
+# declared anywhere, use egrep header to check (ugh lame, but works)
+
+AC_CACHE_CHECK(for inet_pton in <arpa/inet.h>, ucl_cv_inet_pton_in_inet_h,
+	AC_EGREP_HEADER(uint16_t,
+			stdint.h,
+			ucl_cv_inet_pton_in_inet_h=yes,
+			ucl_cv_inet_pton_in_inet_h=no))
+if test $ucl_cv_inet_pton_in_inet_h = "no"
+then
+	AC_DEFINE(NEED_INET_PTON)
+	LIBOBJS="$LIBOBJS inet_pton.o"
+fi
+AC_CACHE_CHECK(for inet_ntop in <arpa/inet.h>, ucl_cv_inet_ntop_in_inet_h,
+	AC_EGREP_HEADER(uint16_t,
+			stdint.h,
+			ucl_cv_inet_ntop_in_inet_h=yes,
+			ucl_cv_inet_ntop_in_inet_h=no))
+if test $ucl_cv_inet_ntop_in_inet_h = "no"
+then
+	AC_DEFINE(NEED_INET_NTOP)
+	LIBOBJS="$LIBOBJS inet_ntop.o"
+fi
+AC_SUBST(LIBOBJS)
+
+dnl AC_REPLACE_FUNCS(inet_pton inet_ntop)
+
+AC_SEARCH_LIBS(socket, socket)
+AC_SEARCH_LIBS(inet_addr, nsl)
+
+# configure defaults CFLAGS to -g -O2
+# so a debug flag would have to fail to remove -g
+# and the optimize would have to modify or add the -O
+# flags:
+#  -debug:
+#       DEBUG2=$DEBUG
+#       AC_DEFINE(DEBUG)
+#  -optimize
+#       OPTIMIZE2=$OPTIMIZE
+#       AC_DEFINE(NDEBUG)
+#  -profile
+AC_ARG_ENABLE(profile,
+	[  --enable-profile        enable profiling],
+	[if test $enableval = yes
+	then
+		if test "$GCC" = yes
+		then
+			CFLAGS="$CFLAGS -pg"
+		else
+			AC_ERROR([Don't know how to enable profiling for $CC])
+		fi
+	fi])
+
+#  -bounds
+#       add -fbounds-checking to CFLAGS
+#       add -lcheck to LIBS
+AC_ARG_ENABLE(bounds,
+	[  --enable-bounds         enable bounds checking],
+	[if test $enableval = yes
+	then
+		if test "$GCC" = yes
+		then
+			CFLAGS="$CFLAGS -fbounds-checking"
+			LIBS="$LIBS -lcheck"
+		else
+			AC_ERROR([Don't know how to enable profiling for $CC])
+		fi
+	fi])
+
+#  others
+#       add as compile flag
+# also:
+# MBUS_ENCRYPT_BY_DEFAULT
+
+# -DDEBUG
+# -DDEBUG_MEM
+# -DNDEBUG
+AC_ARG_ENABLE(debug,
+	[  --enable-debug          enable debug messages and code],
+	[if test $enableval = yes
+	then
+		AC_DEFINE(DEBUG)
+	fi])
+AC_ARG_ENABLE(debug-mem,
+	[  --enable-debug-mem      enable memory debugging code],
+	[if test $enableval = yes
+	then
+		AC_DEFINE(DEBUG_MEM)
+	fi])
+
+AC_ARG_ENABLE(ipv6,
+	[  --enable-ipv6           enable ipv6],
+	[if test $enableval = yes
+	then
+		AC_DEFINE(HAVE_IPv6)
+	fi])
+
+# Test below are IPv6 specific.  Their result has no bearing if HAVE_IPv6 is
+# not defined.  They are kept outside IPv6 enable check to keep code readable.
+
+AC_CACHE_CHECK(for getipnodebyname in <netdb.h>, ucl_cv_getipnodebyname_in_netdb_h,
+	AC_EGREP_HEADER(getipnodebyname,
+		netdb.h,
+		ucl_cv_getipnodebyname_in_netdb_h=yes,	
+		ucl_cv_getipnodebyname_in_netdb_h=no))
+if test $ucl_cv_getipnodebyname_in_netdb_h
+then
+	AC_DEFINE(HAVE_GETIPNODEBYNAME) 
+fi
+
+AC_CHECK_HEADERS(netinet6/in6.h)
+
+AC_CACHE_CHECK(for struct addrinfo in <netdb.h>, ucl_cv_st_addrinfo_in_netdb_h,
+	AC_EGREP_HEADER(addrinfo,
+		netdb.h,
+		ucl_cv_st_addrinfo_in_netdb_h=yes,	
+		ucl_cv_st_addrinfo_in_netdb_h=no))
+if test $ucl_cv_st_addrinfo_in_netdb_h
+then
+	AC_DEFINE(HAVE_ST_ADDRINFO) 
+fi
+
+AC_CACHE_CHECK(for sin6_len in struct sockaddr_in6, ucl_cv_sin6_len,
+	[AC_TRY_COMPILE([
+		#ifdef HAVE_NETINET6_IN6_H
+		#include <netinet6/in6.h>
+		#else
+		#include <netinet/in.h>
+		#endif /* HAVE_NETINET_IN6_H */
+	],[
+		struct sockaddr_in6	s_in;
+		s_in.sin6_len = 0;
+	],
+		ucl_cv_sin6_len=yes,	
+		ucl_cv_sin6_len=no
+	)])
+if test $ucl_cv_sin6_len = yes
+then
+	AC_DEFINE(HAVE_SIN6_LEN) 
+fi
+
+# GCC-specific warning flags
+if test "$GCC" = yes
+then
+        CFLAGS="$CFLAGS -W -Wall -Wwrite-strings -Wbad-function-cast -Wmissing-prototypes -Wcast-qual -Wmissing-declarations -Werror"
+fi
+
+# Done, create the output files....
+AC_CONFIG_HEADER(uclconf.h:config.h.in)
+AC_OUTPUT(Makefile)
Index: /common/tags/common_1_1_2/src/net_udp.c
===================================================================
--- /common/tags/common_1_1_2/src/net_udp.c (revision 428)
+++ /common/tags/common_1_1_2/src/net_udp.c (revision 428)
@@ -0,0 +1,664 @@
+/*
+ * FILE:     net_udp.c
+ * AUTHOR:   Colin Perkins 
+ * MODIFIED: Orion Hodson & Piers O'Hanlon
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* If this machine supports IPv6 the symbol HAVE_IPv6 should */
+/* be defined in either config_unix.h or config_win32.h. The */
+/* appropriate system header files should also be included   */
+/* by those files.                                           */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "inet_pton.h"
+#include "inet_ntop.h"
+#include "net_udp.h"
+
+#define IPv4	4
+#define IPv6	6
+
+/* This is pretty nasty but it's the simplest way to get round */
+/* the Detexis bug that means their MUSICA IPv6 stack uses     */
+/* IPPROTO_IP instead of IPPROTO_IPV6 in setsockopt calls      */
+/* We also need to define in6addr_any */
+#ifdef  MUSICA_IPV6
+#define	IPPROTO_IPV6	IPPROTO_IP
+struct	in6_addr	in6addr_any = {IN6ADDR_ANY_INIT};
+#endif
+
+#ifndef INADDR_NONE
+#define INADDR_NONE 0xffffffff
+#endif
+
+struct _socket_udp {
+	int	 	 mode;	/* IPv4 or IPv6 */
+        char	        *addr;
+	uint16_t	 rx_port;
+	uint16_t	 tx_port;
+	ttl_t	 	 ttl;
+	fd_t	 	 fd;
+	struct in_addr	 addr4;
+#ifdef HAVE_IPv6
+	struct in6_addr	 addr6;
+#endif /* HAVE_IPv6 */
+};
+
+#ifdef WIN32
+/* Want to use both Winsock 1 and 2 socket options, but since
+* IPv6 support requires Winsock 2 we have to add own backwards
+* compatibility for Winsock 1.
+*/
+#define SETSOCKOPT winsock_versions_setsockopt
+#else
+#define SETSOCKOPT setsockopt
+#endif /* WIN32 */
+
+/*****************************************************************************/
+/* Support functions...                                                      */
+/*****************************************************************************/
+
+static void
+socket_error(const char *msg)
+{
+#ifdef WIN32
+#define WSERR(x) {#x,x}
+	struct wse {
+		char  errname[20];
+		int errno;
+	};
+	struct wse ws_errs[] = {
+		WSERR(WSANOTINITIALISED), WSERR(WSAENETDOWN),     WSERR(WSAEACCES),
+		WSERR(WSAEINVAL),         WSERR(WSAEINTR),        WSERR(WSAEINPROGRESS),
+		WSERR(WSAEFAULT),         WSERR(WSAENETRESET),    WSERR(WSAENOBUFS),
+		WSERR(WSAENOTCONN),       WSERR(WSAENOTSOCK),     WSERR(WSAEOPNOTSUPP),
+		WSERR(WSAESHUTDOWN),      WSERR(WSAEWOULDBLOCK),  WSERR(WSAEMSGSIZE),
+		WSERR(WSAEHOSTUNREACH),   WSERR(WSAECONNABORTED), WSERR(WSAECONNRESET),
+		WSERR(WSAEADDRNOTAVAIL),  WSERR(WSAEAFNOSUPPORT), WSERR(WSAEDESTADDRREQ),
+		WSERR(WSAENETUNREACH),    WSERR(WSAETIMEDOUT),    WSERR(0)
+	};
+	
+	int i, e = WSAGetLastError();
+	i = 0;
+	while(ws_errs[i].errno && ws_errs[i].errno != e) {
+		i++;
+	}
+	printf("ERROR: %s, (%d - %s)\n", msg, e, ws_errs[i].errname);
+#else
+	perror(msg);
+#endif
+	abort();
+}
+
+#ifdef WIN32
+/* ws2tcpip.h defines these constants with different values from
+* winsock.h so files that use winsock 2 values but try to use 
+* winsock 1 fail.  So what was the motivation in changing the
+* constants ?
+*/
+#define WS1_IP_MULTICAST_IF     2 /* set/get IP multicast interface   */
+#define WS1_IP_MULTICAST_TTL    3 /* set/get IP multicast timetolive  */
+#define WS1_IP_MULTICAST_LOOP   4 /* set/get IP multicast loopback    */
+#define WS1_IP_ADD_MEMBERSHIP   5 /* add  an IP group membership      */
+#define WS1_IP_DROP_MEMBERSHIP  6 /* drop an IP group membership      */
+
+/* winsock_versions_setsockopt tries 1 winsock version of option 
+* optname and then winsock 2 version if that failed.
+*/
+
+static int
+winsock_versions_setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen)
+{
+	int success = -1;
+	switch (optname) {
+	case IP_MULTICAST_IF:
+		success = setsockopt(s, level, WS1_IP_MULTICAST_IF, optval, optlen);
+		break;
+	case IP_MULTICAST_TTL:
+		success = setsockopt(s, level, WS1_IP_MULTICAST_TTL, optval, optlen);
+		break;
+	case IP_MULTICAST_LOOP:
+		success = setsockopt(s, level, WS1_IP_MULTICAST_LOOP, optval, optlen);
+		break;
+	case IP_ADD_MEMBERSHIP: 
+		success = setsockopt(s, level, WS1_IP_ADD_MEMBERSHIP, optval, optlen);
+		break;
+	case IP_DROP_MEMBERSHIP: 
+		success = setsockopt(s, level, WS1_IP_DROP_MEMBERSHIP, optval, optlen);
+		break;
+	}
+	if (success != -1) {
+		return success;
+	}
+	return setsockopt(s, level, optname, optval, optlen);
+}
+#endif
+
+#ifdef NEED_INET_ATON
+#ifdef NEED_INET_ATON_STATIC
+static 
+#endif
+int inet_aton(const char *name, struct in_addr *addr)
+{
+	addr->s_addr = inet_addr(name);
+	return (addr->s_addr != (in_addr_t) INADDR_NONE);
+}
+#endif
+
+#ifdef NEED_IN6_IS_ADDR_MULTICAST
+#define IN6_IS_ADDR_MULTICAST(addr) ((addr)->s6_addr[0] == 0xffU)
+#endif
+
+#if defined(NEED_IN6_IS_ADDR_UNSPECIFIED) && defined(MUSICA_IPV6)
+#define IN6_IS_ADDR_UNSPECIFIED(addr) IS_UNSPEC_IN6_ADDR(*addr)
+#endif
+
+/*****************************************************************************/
+/* IPv4 specific functions...                                                */
+/*****************************************************************************/
+
+static int udp_addr_valid4(const char *dst)
+{
+        struct in_addr addr4;
+	if (inet_pton(AF_INET, dst, &addr4) || 
+            gethostbyname(dst) != NULL) {
+                return TRUE;
+        }
+        return FALSE;
+}
+
+static socket_udp *udp_init4(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl)
+{
+	int                 	 reuse = 1;
+	struct sockaddr_in  	 s_in;
+	struct in_addr		 iface_addr;
+	socket_udp         	*s = (socket_udp *)malloc(sizeof(socket_udp));
+	s->mode    = IPv4;
+	s->addr    = NULL;
+	s->rx_port = rx_port;
+	s->tx_port = tx_port;
+	s->ttl     = ttl;
+	if (inet_pton(AF_INET, addr, &s->addr4) != 1) {
+		struct hostent *h = gethostbyname(addr);
+		if (h == NULL) {
+                        free(s);
+			return NULL;
+		}
+		memcpy(&(s->addr4), h->h_addr_list[0], sizeof(s->addr4));
+	}
+	if (iface != NULL) {
+		if (inet_pton(AF_INET, iface, &iface_addr) != 1) {
+			debug_msg("Illegal interface specification\n");
+                        free(s);
+			return NULL;
+		}
+	} else {
+		iface_addr.s_addr = 0;
+	}
+	s->fd = socket(AF_INET, SOCK_DGRAM, 0);
+	if (s->fd < 0) {
+		socket_error("socket");
+		abort();
+	}
+	if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) {
+		socket_error("setsockopt SO_REUSEADDR");
+		abort();
+	}
+#ifdef SO_REUSEPORT
+	if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) {
+		socket_error("setsockopt SO_REUSEPORT");
+		abort();
+	}
+#endif
+	s_in.sin_family      = AF_INET;
+	s_in.sin_addr.s_addr = INADDR_ANY;
+	s_in.sin_port        = htons(rx_port);
+	if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) {
+		socket_error("bind");
+		abort();
+	}
+	if (IN_MULTICAST(ntohl(s->addr4.s_addr))) {
+		char            loop = 1;
+		struct ip_mreq  imr;
+		
+		imr.imr_multiaddr.s_addr = s->addr4.s_addr;
+		imr.imr_interface.s_addr = iface_addr.s_addr;
+		
+		if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) {
+			socket_error("setsockopt IP_ADD_MEMBERSHIP");
+			abort();
+		}
+#ifndef WIN32
+		if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) != 0) {
+			socket_error("setsockopt IP_MULTICAST_LOOP");
+			abort();
+		}
+#endif
+		if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *) &s->ttl, sizeof(s->ttl)) != 0) {
+			socket_error("setsockopt IP_MULTICAST_TTL");
+			abort();
+		}
+		if (iface_addr.s_addr != 0) {
+			if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &iface_addr, sizeof(iface_addr)) != 0) {
+				socket_error("setsockopt IP_MULTICAST_IF");
+				abort();
+			}
+		}
+	}
+        s->addr = strdup(addr);
+	return s;
+}
+
+static void udp_exit4(socket_udp *s)
+{
+	if (IN_MULTICAST(ntohl(s->addr4.s_addr))) {
+		struct ip_mreq  imr;
+		imr.imr_multiaddr.s_addr = s->addr4.s_addr;
+		imr.imr_interface.s_addr = INADDR_ANY;
+		if (SETSOCKOPT(s->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ip_mreq)) != 0) {
+			socket_error("setsockopt IP_DROP_MEMBERSHIP");
+			abort();
+		}
+	}
+	close(s->fd);
+        free(s->addr);
+	free(s);
+}
+
+static int udp_send4(socket_udp *s, char *buffer, int buflen)
+{
+	struct sockaddr_in	s_in;
+	
+	assert(s != NULL);
+	assert(s->mode == IPv4);
+	assert(buffer != NULL);
+	assert(buflen > 0);
+	
+	s_in.sin_family      = AF_INET;
+	s_in.sin_addr.s_addr = s->addr4.s_addr;
+	s_in.sin_port        = htons(s->tx_port);
+	return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in));
+}
+
+static const char *udp_host_addr4(void)
+{
+	static char    		 hname[MAXHOSTNAMELEN];
+	struct hostent 		*hent;
+	struct in_addr  	 iaddr;
+	
+	if (gethostname(hname, MAXHOSTNAMELEN) != 0) {
+		debug_msg("Cannot get hostname!");
+		abort();
+	}
+	hent = gethostbyname(hname);
+	assert(hent->h_addrtype == AF_INET);
+	memcpy(&iaddr.s_addr, hent->h_addr, sizeof(iaddr.s_addr));
+	strncpy(hname, inet_ntoa(iaddr), MAXHOSTNAMELEN);
+	return (const char*)hname;
+}
+
+/*****************************************************************************/
+/* IPv6 specific functions...                                                */
+/*****************************************************************************/
+
+static int udp_addr_valid6(const char *dst)
+{
+#ifdef HAVE_IPv6
+        struct in6_addr addr6;
+	switch (inet_pton(AF_INET6, dst, &addr6)) {
+        case 1:  
+                return TRUE;
+                break;
+        case 0: 
+                return FALSE;
+                break;
+        case -1: 
+                debug_msg("inet_pton failed\n");
+                errno = 0;
+        }
+#endif /* HAVE_IPv6 */
+        UNUSED(dst);
+        return FALSE;
+}
+
+static socket_udp *udp_init6(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl)
+{
+#ifdef HAVE_IPv6
+	int                 reuse = 1;
+	struct sockaddr_in6 s_in;
+	socket_udp         *s = (socket_udp *) malloc(sizeof(socket_udp));
+	s->mode    = IPv6;
+	s->addr    = NULL;
+	s->rx_port = rx_port;
+	s->tx_port = tx_port;
+	s->ttl     = ttl;
+	
+	if (iface != NULL) {
+		debug_msg("Not yet implemented\n");
+		abort();
+	}
+
+	if (inet_pton(AF_INET6, addr, &s->addr6) != 1) {
+		/* We should probably try to do a DNS lookup on the name */
+		/* here, but I'm trying to get the basics going first... */
+		debug_msg("IPv6 address conversion failed\n");
+                free(s);
+		return NULL;	
+	}
+	s->fd = socket(AF_INET6, SOCK_DGRAM, 0);
+	if (s->fd < 0) {
+		socket_error("socket");
+		abort();
+	}
+	if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuse, sizeof(reuse)) != 0) {
+		socket_error("setsockopt SO_REUSEADDR");
+		abort();
+	}
+#ifdef SO_REUSEPORT
+	if (SETSOCKOPT(s->fd, SOL_SOCKET, SO_REUSEPORT, (char *) &reuse, sizeof(reuse)) != 0) {
+		socket_error("setsockopt SO_REUSEPORT");
+		abort();
+	}
+#endif
+	
+	memset((char *)&s_in, 0, sizeof(s_in));
+	s_in.sin6_family = AF_INET6;
+	s_in.sin6_port   = htons(rx_port);
+#ifdef HAVE_SIN6_LEN
+	s_in.sin6_len    = sizeof(s_in);
+#endif
+	memcpy(s_in.sin6_addr.s6_addr, &s->addr6, sizeof(struct in6_addr));
+	if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) {
+		/* bind to group address failed, try generic address. */
+		s_in.sin6_addr = in6addr_any;
+		if (bind(s->fd, (struct sockaddr *) &s_in, sizeof(s_in)) != 0) {
+			socket_error("bind");
+			abort();
+		}
+	}
+	
+	if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) {
+		unsigned int      loop = 1;
+		struct ipv6_mreq  imr;
+#ifdef MUSICA_IPV6
+		imr.i6mr_interface = 1;
+		imr.i6mr_multiaddr = s->addr6;
+#else
+		imr.ipv6mr_multiaddr = s->addr6;
+		imr.ipv6mr_interface = 0;
+#endif
+		
+		if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &imr, sizeof(struct ipv6_mreq)) != 0) {
+			socket_error("setsockopt IPV6_ADD_MEMBERSHIP");
+			abort();
+		}
+		
+		if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &loop, sizeof(loop)) != 0) {
+			socket_error("setsockopt IPV6_MULTICAST_LOOP");
+			abort();
+		}
+		if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *) &ttl, sizeof(ttl)) != 0) {
+			socket_error("setsockopt IPV6_MULTICAST_HOPS");
+			abort();
+		}
+	}
+	assert(s != NULL);
+
+        s->addr = strdup(addr);
+	return s;
+#else
+	UNUSED(addr);
+	UNUSED(iface);
+	UNUSED(rx_port);
+	UNUSED(tx_port);
+	UNUSED(ttl);
+	return NULL;
+#endif
+}
+
+static void udp_exit6(socket_udp *s)
+{
+#ifdef HAVE_IPv6
+	if (IN6_IS_ADDR_MULTICAST(&(s->addr6))) {
+		struct ipv6_mreq  imr;
+#ifdef MUSICA_IPV6
+		imr.i6mr_interface = 1;
+		imr.i6mr_multiaddr = s->addr6;
+#else
+		imr.ipv6mr_multiaddr = s->addr6;
+		imr.ipv6mr_interface = 0;
+#endif
+		
+		if (SETSOCKOPT(s->fd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *) &imr, sizeof(struct ipv6_mreq)) != 0) {
+			socket_error("setsockopt IPV6_DROP_MEMBERSHIP");
+			abort();
+		}
+	}
+	close(s->fd);
+        free(s->addr);
+	free(s);
+#else
+	UNUSED(s);
+#endif  /* HAVE_IPv6 */
+}
+
+static int udp_send6(socket_udp *s, char *buffer, int buflen)
+{
+#ifdef HAVE_IPv6
+	struct sockaddr_in6	s_in;
+	
+	assert(s != NULL);
+	assert(s->mode == IPv6);
+	assert(buffer != NULL);
+	assert(buflen > 0);
+	
+	memset((char *)&s_in, 0, sizeof(s_in));
+	s_in.sin6_family = AF_INET6;
+	s_in.sin6_addr   = s->addr6;
+	s_in.sin6_port   = htons(s->tx_port);
+#ifdef HAVE_SIN6_LEN
+	s_in.sin6_len    = sizeof(s_in);
+#endif
+	return sendto(s->fd, buffer, buflen, 0, (struct sockaddr *) &s_in, sizeof(s_in));
+#else
+	UNUSED(s);
+	UNUSED(buffer);
+	UNUSED(buflen);
+	return -1;
+#endif
+}
+
+static const char *udp_host_addr6(socket_udp *s)
+{
+#ifdef HAVE_IPv6
+	static char		 hname[MAXHOSTNAMELEN];
+	int 			 gai_err;
+	struct addrinfo 	 hints, *ai;
+	struct sockaddr_in6 	 local;
+	int len = sizeof(local), result = 0;
+
+	memset((char *)&local, 0, len);
+	local.sin6_family = AF_INET6;
+#ifdef HAVE_SIN6_LEN
+	local.sin6_len    = len;
+#endif
+
+	if ((result = getsockname(s->fd,(struct sockaddr *)&local, &len)) < 0){
+		local.sin6_addr = in6addr_any;
+		local.sin6_port = 0;
+		debug_msg("getsockname failed\n");
+	}
+	if (IN6_IS_ADDR_UNSPECIFIED(&local.sin6_addr) || IN6_IS_ADDR_MULTICAST(&local.sin6_addr)) {
+		if (gethostname(hname, MAXHOSTNAMELEN) != 0) {
+			debug_msg("gethostname failed\n");
+			abort();
+		}
+		
+		hints.ai_protocol  = IPPROTO_IPV6;
+		hints.ai_flags     = AI_CANONNAME;
+		hints.ai_family    = PF_INET;
+		hints.ai_socktype  = SOCK_DGRAM;
+		hints.ai_protocol  = IPPROTO_IPV6;
+		hints.ai_addrlen   = 0;
+		hints.ai_canonname = NULL;
+		hints.ai_addr      = NULL;
+		hints.ai_next      = NULL;
+
+		if ((gai_err = getaddrinfo(hname, NULL, &hints, &ai))) {
+			debug_msg("getaddrinfo: %s: %s\n", hname, gai_strerror(gai_err));
+			abort();
+		}
+		
+		if (inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr), hname, MAXHOSTNAMELEN) == NULL) {
+			debug_msg("inet_ntop: %s: \n", hname);
+			abort();
+		}
+		freeaddrinfo(ai);
+		return (const char*)hname;
+	}
+	if (inet_ntop(AF_INET6, &local.sin6_addr, hname, MAXHOSTNAMELEN) == NULL) {
+		debug_msg("inet_ntop: %s: \n", hname);
+		abort();
+	}
+	return (const char*)hname;
+#else  /* HAVE_IPv6 */
+	UNUSED(s);
+	return "::";	/* The unspecified address... */
+#endif /* HAVE_IPv6 */
+}
+	
+/*****************************************************************************/
+/* Generic functions, which call the appropriate protocol specific routines. */
+/*****************************************************************************/
+
+int udp_addr_valid(const char *addr)
+{
+        return udp_addr_valid4(addr) | udp_addr_valid6(addr);
+}
+
+socket_udp *udp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl)
+{
+	return udp_init_if(addr, NULL, rx_port, tx_port, ttl);
+}
+
+socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl)
+{
+	socket_udp *res;
+	
+	if (strchr(addr, ':') == NULL) {
+		res = udp_init4(addr, iface, rx_port, tx_port, ttl);
+	} else {
+		res = udp_init6(addr, iface, rx_port, tx_port, ttl);
+	}
+	return res;
+}
+
+void udp_exit(socket_udp *s)
+{
+    switch(s->mode) {
+    case IPv4 : udp_exit4(s); break;
+    case IPv6 : udp_exit6(s); break;
+    default   : abort();
+    }
+}
+
+int udp_send(socket_udp *s, char *buffer, int buflen)
+{
+	switch (s->mode) {
+	case IPv4 : return udp_send4(s, buffer, buflen);
+	case IPv6 : return udp_send6(s, buffer, buflen);
+	default   : abort();
+	}
+	return -1;
+}
+
+int udp_recv(socket_udp *s, char *buffer, int buflen)
+{
+	/* Reads data into the buffer, returning the number of bytes read.   */
+	/* If no data is available, this returns the value zero immediately. */
+	/* Note: since we don't care about the source address of the packet  */
+	/* we receive, this function becomes protocol independent.           */
+	int		len;
+
+	assert(buffer != NULL);
+	assert(buflen > 0);
+
+	len = recvfrom(s->fd, buffer, buflen, 0, 0, 0);
+	if (len > 0) {
+		return len;
+	}
+	if (errno != ECONNREFUSED) {
+		socket_error("recvfrom");
+	}
+	return 0;
+}
+
+static fd_set	rfd;
+static fd_t	max_fd;
+
+void udp_fd_zero(void)
+{
+	FD_ZERO(&rfd);
+	max_fd = 0;
+}
+
+void udp_fd_set(socket_udp *s)
+{
+	FD_SET(s->fd, &rfd);
+	if (s->fd > (fd_t)max_fd) {
+		max_fd = s->fd;
+	}
+}
+
+int udp_fd_isset(socket_udp *s)
+{
+	return FD_ISSET(s->fd, &rfd);
+}
+
+int udp_select(struct timeval *timeout)
+{
+	return select(max_fd + 1, &rfd, NULL, NULL, timeout);
+}
+
+const char *udp_host_addr(socket_udp *s)
+{
+	switch (s->mode) {
+	case IPv4 : return udp_host_addr4();
+	case IPv6 : return udp_host_addr6(s);
+	default   : abort();
+	}
+	return NULL;
+}
+
Index: /common/tags/common_1_1_2/src/inet_pton.c
===================================================================
--- /common/tags/common_1_1_2/src/inet_pton.c (revision 340)
+++ /common/tags/common_1_1_2/src/inet_pton.c (revision 340)
@@ -0,0 +1,220 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef HAVE_INET_PTON
+#include "config_unix.h"
+#include "config_win32.h"
+#include "inet_pton.h"
+
+#define	IN6ADDRSZ	16
+#define	INADDRSZ	 4
+#define	INT16SZ		 2
+
+#ifndef	AF_INET6
+#define	AF_INET6	AF_MAX+1	/* just to let this compile */
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int	inet_pton4(const char *src, u_char *dst);
+static int	inet_pton6(const char *src, u_char *dst);
+
+/* int
+ * inet_pton(af, src, dst)
+ *	convert from presentation format (which usually means ASCII printable)
+ *	to network format (which is usually some kind of binary format).
+ * return:
+ *	1 if the address was valid for the specified address family
+ *	0 if the address wasn't valid (`dst' is untouched in this case)
+ *	-1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *	Paul Vixie, 1996.
+ */
+int
+inet_pton(af, src, dst)
+	int af;
+	const char *src;
+	void *dst;
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_pton4(src, dst));
+	case AF_INET6:
+		return (inet_pton6(src, dst));
+	default:
+		errno = EAFNOSUPPORT;
+		return (-1);
+	}
+	/* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *	like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *	1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *	does not touch `dst' unless it's returning 1.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+	const char *src;
+	u_char *dst;
+{
+	static const char digits[] = "0123456789";
+	int saw_digit, octets, ch;
+	u_char tmp[INADDRSZ], *tp;
+
+	saw_digit = 0;
+	octets = 0;
+	*(tp = tmp) = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = (char *) strchr(digits, ch)) != NULL) {
+			uint8_t new = *tp * 10 + (pch - digits);
+
+			if (new > 255)
+				return (0);
+			*tp = new;
+			if (! saw_digit) {
+				if (++octets > 4)
+					return (0);
+				saw_digit = 1;
+			}
+		} else if (ch == '.' && saw_digit) {
+			if (octets == 4)
+				return (0);
+			*++tp = 0;
+			saw_digit = 0;
+		} else
+			return (0);
+	}
+	if (octets < 4)
+		return (0);
+	/* bcopy(tmp, dst, INADDRSZ); */
+	memcpy(dst, tmp, INADDRSZ);
+	return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *	convert presentation level address to network order binary form.
+ * return:
+ *	1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *	(1) does not touch `dst' unless it's returning 1.
+ *	(2) :: in a full address is silently ignored.
+ * credit:
+ *	inspired by Mark Andrews.
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+	const char *src;
+	u_char *dst;
+{
+	static const char xdigits_l[] = "0123456789abcdef",
+			  xdigits_u[] = "0123456789ABCDEF";
+	u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
+	const char *xdigits, *curtok;
+	int ch, saw_xdigit;
+	unsigned val;
+
+	memset((tp = tmp), 0, IN6ADDRSZ);
+	endp = tp + IN6ADDRSZ;
+	colonp = NULL;
+	/* Leading :: requires some special handling. */
+	if (*src == ':')
+		if (*++src != ':')
+			return (0);
+	curtok = src;
+	saw_xdigit = 0;
+	val = 0;
+	while ((ch = *src++) != '\0') {
+		const char *pch;
+
+		if ((pch = (char *) strchr((xdigits = xdigits_l), ch)) == NULL)
+			pch = (char *) strchr((xdigits = xdigits_u), ch);
+		if (pch != NULL) {
+			val <<= 4;
+			val |= (pch - xdigits);
+			if (val > 0xffff)
+				return (0);
+			saw_xdigit = 1;
+			continue;
+		}
+		if (ch == ':') {
+			curtok = src;
+			if (!saw_xdigit) {
+				if (colonp)
+					return (0);
+				colonp = tp;
+				continue;
+			}
+			if (tp + INT16SZ > endp)
+				return (0);
+			*tp++ = (u_char) (val >> 8) & 0xff;
+			*tp++ = (u_char) val & 0xff;
+			saw_xdigit = 0;
+			val = 0;
+			continue;
+		}
+		if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
+		    inet_pton4(curtok, tp) > 0) {
+			tp += INADDRSZ;
+			saw_xdigit = 0;
+			break;	/* '\0' was seen by inet_pton4(). */
+		}
+		return (0);
+	}
+	if (saw_xdigit) {
+		if (tp + INT16SZ > endp)
+			return (0);
+		*tp++ = (u_char) (val >> 8) & 0xff;
+		*tp++ = (u_char) val & 0xff;
+	}
+	if (colonp != NULL) {
+		/*
+		 * Since some memmove()'s erroneously fail to handle
+		 * overlapping regions, we'll do the shift by hand.
+		 */
+		const int n = tp - colonp;
+		int i;
+
+		for (i = 1; i <= n; i++) {
+			endp[- i] = colonp[n - i];
+			colonp[n - i] = 0;
+		}
+		tp = endp;
+	}
+	if (tp != endp)
+		return (0);
+	/* bcopy(tmp, dst, IN6ADDRSZ); */
+	memcpy(dst, tmp, IN6ADDRSZ);
+	return (1);
+}
+
+#endif
+
Index: /common/tags/common_1_1_2/src/inet_ntop.c
===================================================================
--- /common/tags/common_1_1_2/src/inet_ntop.c (revision 340)
+++ /common/tags/common_1_1_2/src/inet_ntop.c (revision 340)
@@ -0,0 +1,193 @@
+/* This is from the BIND 4.9.4 release, modified to compile by itself */
+
+/* Copyright (c) 1996 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef HAVE_INET_NTOP
+#include "config_unix.h"
+#include "config_win32.h"
+#include "inet_ntop.h"
+
+#define	IN6ADDRSZ	16
+#define	INT16SZ		 2
+
+#ifndef	AF_INET6
+#define	AF_INET6	AF_MAX+1	/* just to let this compile */
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
+static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
+
+/* char *
+ * inet_ntop(af, src, dst, size)
+ *	convert a network format address to presentation format.
+ * return:
+ *	pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ *	Paul Vixie, 1996.
+ */
+const char *
+inet_ntop(af, src, dst, size)
+	int af;
+	const void *src;
+	char *dst;
+	size_t size;
+{
+	switch (af) {
+	case AF_INET:
+		return (inet_ntop4(src, dst, size));
+	case AF_INET6:
+		return (inet_ntop6(src, dst, size));
+	default:
+		errno = EAFNOSUPPORT;
+		return (NULL);
+	}
+	/* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *	format an IPv4 address, more or less like inet_ntoa()
+ * return:
+ *	`dst' (as a const)
+ * notes:
+ *	(1) uses no statics
+ *	(2) takes a u_char* not an in_addr as input
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+	const u_char *src;
+	char *dst;
+	size_t size;
+{
+	static const char fmt[] = "%u.%u.%u.%u";
+	char tmp[sizeof "255.255.255.255"];
+
+	sprintf(tmp, fmt, src[0], src[1], src[2], src[3]);
+	if ((size_t)strlen(tmp) > size) {
+		errno = ENOSPC;
+		return (NULL);
+	}
+	strcpy(dst, tmp);
+	return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *	convert IPv6 binary address into presentation (printable) format
+ * author:
+ *	Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+	const u_char *src;
+	char *dst;
+	size_t size;
+{
+	/*
+	 * Note that int32_t and int16_t need only be "at least" large enough
+	 * to contain a value of the specified size.  On some systems, like
+	 * Crays, there is no such thing as an integer variable with 16 bits.
+	 * Keep this in mind if you think this function should have been coded
+	 * to use pointer overlays.  All the world's not a VAX.
+	 */
+	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+	struct { int base, len; } best, cur;
+	uint32_t words[IN6ADDRSZ / INT16SZ];
+	int i;
+
+	/*
+	 * Preprocess:
+	 *	Copy the input (bytewise) array into a wordwise array.
+	 *	Find the longest run of 0x00's in src[] for :: shorthanding.
+	 */
+	memset(words, 0, sizeof words);
+	for (i = 0; i < IN6ADDRSZ; i++)
+		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+	best.base = -1;
+	cur.base = -1;
+	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+		if (words[i] == 0) {
+			if (cur.base == -1)
+				cur.base = i, cur.len = 1;
+			else
+				cur.len++;
+		} else {
+			if (cur.base != -1) {
+				if (best.base == -1 || cur.len > best.len)
+					best = cur;
+				cur.base = -1;
+			}
+		}
+	}
+	if (cur.base != -1) {
+		if (best.base == -1 || cur.len > best.len)
+			best = cur;
+	}
+	if (best.base != -1 && best.len < 2)
+		best.base = -1;
+
+	/*
+	 * Format the result.
+	 */
+	tp = tmp;
+	for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
+		/* Are we inside the best run of 0x00's? */
+		if (best.base != -1 && i >= best.base &&
+		    i < (best.base + best.len)) {
+			if (i == best.base)
+				*tp++ = ':';
+			continue;
+		}
+		/* Are we following an initial run of 0x00s or any real hex? */
+		if (i != 0)
+			*tp++ = ':';
+		/* Is this address an encapsulated IPv4? */
+		if (i == 6 && best.base == 0 &&
+		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+			if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+				return (NULL);
+			tp += strlen(tp);
+			break;
+		}
+		sprintf(tp, "%x", words[i]);
+		tp += strlen(tp);
+	}
+	/* Was it a trailing run of 0x00's? */
+	if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
+		*tp++ = ':';
+	*tp++ = '\0';
+
+	/*
+	 * Check for overflow, copy, and we're done.
+	 */
+	if ((size_t) (tp - tmp) > size) {
+		errno = ENOSPC;
+		return (NULL);
+	}
+	strcpy(dst, tmp);
+	return (dst);
+}
+
+#endif
+
Index: /common/tags/common_1_1_2/src/mbus_addr.c
===================================================================
--- /common/tags/common_1_1_2/src/mbus_addr.c (revision 428)
+++ /common/tags/common_1_1_2/src/mbus_addr.c (revision 428)
@@ -0,0 +1,122 @@
+/*
+ * FILE:     mbus_addr.c
+ * AUTHOR:   Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "mbus_addr.h"
+
+int strfind(const char *haystack, const char *needle_start, const char *needle_end)
+{
+	/* Returns TRUE if the string between needle_start and needle_end */
+	/* is found in haystack. The haystack MUST be zero terminated.    */
+	const char	*n, *h;
+	const char	*h_end = haystack + strlen(haystack);
+
+#ifdef DEBUG
+	/* Paranoia check that memory between needle_start and needle_end */
+	/* is a valid string, and doesn't contain a zero byte.            */
+	for (n = needle_start; n != needle_end; n++) {
+		assert(*n != '\0');
+	}
+#endif
+
+	n = needle_start;
+	h = haystack;
+
+	do {
+		if (*n == *h) {
+			n++;
+			h++;
+		} else {
+			h = h - (n - needle_start) + 1;
+			n = needle_start;
+		}
+	} while ((h < h_end) && (n <= needle_end));
+
+	if (n == (needle_end + 1)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+int mbus_addr_match(const char *a, const char *b)
+{
+	/* Compare the addresses "a" and "b". These may optionally be */
+	/* surrounded by "(" and ")" and may have an arbitrary amount */
+	/* of white space between components of the addresses. There  */
+	/* is a match if every word of address b is in address a.     */
+	/* NOTE: The strings passed to this function are stored for   */
+	/* later use and MUST NOT be modified by this routine.        */
+	const char	*y = NULL; 
+
+	assert(a != NULL);
+	assert(b != NULL);
+
+	if ((*a == '\0') || (*b == '\0')) {
+		/* Unspecified addresses never match... */
+		return FALSE;
+	}
+
+	/* Skip leading whitespace and '('... */
+	while (isspace((unsigned char)*a) || (*a == '(')) a++;
+	while (isspace((unsigned char)*b) || (*b == '(')) b++;
+
+	while ((*b != '\0') && (*b != ')')) {
+		/* Move b along through the string to the start of the next */
+		/* word. Move y along from that to the end of the word.     */
+		while (isspace((unsigned char)*b)) b++;
+		for (y = b; ((*y != ' ') && (*y != ')') && (*y != '\0')); y++) {
+			/* do nothing */
+		}
+		y--;
+		/* Check if the word between b and y is contained in the    */
+		/* string pointed to be a.                                  */
+		if (!strfind(a, b, y)) {
+			return FALSE;
+		}
+		b = ++y;
+	}		
+	return TRUE;
+}
+
+int mbus_addr_identical(const char *a, const char *b)
+{
+	/* A more restrictive version of mbus_addr_match. Returns TRUE  */
+	/* iff the addresses are identical (except, possibly, for order */
+	/* of the elements.                                             */
+	return mbus_addr_match(a, b) && mbus_addr_match(b, a);
+}
+
Index: /common/tags/common_1_1_2/src/mbus_config.h
===================================================================
--- /common/tags/common_1_1_2/src/mbus_config.h (revision 360)
+++ /common/tags/common_1_1_2/src/mbus_config.h (revision 360)
@@ -0,0 +1,77 @@
+/*
+ * FILE:    mbus_config.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MBUS_CONFIG
+#define _MBUS_CONFIG
+
+struct mbus_key {
+	char	*algorithm;
+	char	*key;
+	int	 key_len;
+};
+
+struct mbus_config;
+
+#define MBUS_CONFIG_VERSION	 1
+
+#define SCOPE_HOSTLOCAL       	 0
+#define SCOPE_HOSTLOCAL_NAME 	"HOSTLOCAL"
+#define SCOPE_LINKLOCAL       	 1
+#define SCOPE_LINKLOCAL_NAME 	"LINKLOCAL"
+
+#define MBUS_DEFAULT_NET_ADDR 	"224.255.222.239"
+#define MBUS_DEFAULT_NET_PORT 	 47000
+#define MBUS_DEFAULT_SCOPE    	 SCOPE_HOSTLOCAL
+#define MBUS_DEFAULT_SCOPE_NAME	 SCOPE_HOSTLOCAL_NAME
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+char *mbus_new_encrkey(void);
+char *mbus_new_hashkey(void);
+void mbus_lock_config_file(struct mbus_config *m);
+void mbus_unlock_config_file(struct mbus_config *m);
+void mbus_get_encrkey(struct mbus_config *m, struct mbus_key *key);
+void mbus_get_hashkey(struct mbus_config *m, struct mbus_key *key);
+void mbus_get_net_addr(struct mbus_config *m, char *net_addr, uint16_t *net_port, int *net_scope);
+int  mbus_get_version(struct mbus_config *m);
+struct mbus_config *mbus_create_config(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
Index: /common/tags/common_1_1_2/src/Makefile.in
===================================================================
--- /common/tags/common_1_1_2/src/Makefile.in (revision 428)
+++ /common/tags/common_1_1_2/src/Makefile.in (revision 428)
@@ -0,0 +1,59 @@
+#
+# Makefile for the common code library project. 
+# This probably requires GNU make.
+#
+
+DEFS   = @DEFS@
+CFLAGS = @CFLAGS@ $(DEFS)
+LIBS   = @LIBS@
+CC     = @CC@
+AR     = ar
+RANLIB = @RANLIB@
+HOST   = @host@
+TARGET = libuclmmbase.a
+
+exec_prefix=@exec_prefix@
+
+OBJS = crypt_random.o debug.o md5.o memory.o net_udp.o qfDES.o util.o hmac.o  \
+       base64.o ntp.o rtp.o drand48.o mbus_parser.o mbus_config.o mbus_addr.o \
+       mbus.o btree.o asarray.o @LIBOBJS@
+
+TEST_OBJS = test_base64.o test_des.o test_md5.o test_net_udp.o \
+            test_memory.o test_mbus_parser.o test_mbus_addr.o  \
+	    test.o
+
+SRCS = $(OBJS:%.o=%.c)
+
+all: version.h $(TARGET) test-libcommon
+
+test-libcommon: $(TEST_OBJS) $(TARGET)
+	$(CC) $(TEST_OBJS) $(CFLAGS) $(TARGET) $(LIBS) -o test-libcommon
+	
+$(TARGET): $(OBJS)
+	$(AR) r $(TARGET) $(OBJS)
+	$(RANLIB) $(TARGET)
+
+version.h:	VERSION
+	sed -e 's/.*/#define CCL_VERSION "v&"/' VERSION > version.h
+
+.c.o:
+	$(CC) $(CFLAGS) $(INC) -c $<
+
+clean:
+	-rm -f $(OBJS) $(TEST_OBJS) version.h $(TARGET) tags test-libcommon
+
+distclean:	clean
+	-rm -f Makefile config.status config.cache uclconf.h
+
+etags:
+	etags *.[ch]
+
+ctags:
+	ctags *.[ch]
+
+release:
+	cvs tag release-`cat VERSION | sed "s/\./-/g"`
+
+depend: $(SRCS)
+	makedepend $(DEFS) $(INC) $(SRCS)
+
Index: /common/tags/common_1_1_2/src/btree.c
===================================================================
--- /common/tags/common_1_1_2/src/btree.c (revision 403)
+++ /common/tags/common_1_1_2/src/btree.c (revision 403)
@@ -0,0 +1,458 @@
+/*
+ * FILE:     btree.c
+ * PROGRAM:  RAT
+ * AUTHOR:   O.Hodson
+ * MODIFIED: C.Perkins
+ * 
+ * Binary tree implementation - Mostly verbatim from:
+ *
+ * Introduction to Algorithms by Corman, Leisserson, and Rivest,
+ * MIT Press / McGraw Hill, 1990.
+ *
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "btree.h"
+
+typedef struct s_btree_node {
+        uint32_t       		 key;
+        void         		*data;
+        struct s_btree_node 	*parent;
+        struct s_btree_node 	*left;
+        struct s_btree_node 	*right;
+	uint32_t		 magic;
+} btree_node_t;
+
+struct s_btree {
+        btree_node_t   *root;
+	uint32_t	magic;
+	int		count;
+};
+
+/*****************************************************************************/
+/* Debugging functions...                                                    */
+/*****************************************************************************/
+
+#define BTREE_MAGIC      0x10101010
+#define BTREE_NODE_MAGIC 0x01010101
+
+static int btree_count;
+
+static void
+btree_validate_node(btree_node_t *node, btree_node_t *parent)
+{
+	assert(node->magic  == BTREE_NODE_MAGIC);
+	assert(node->parent == parent);
+	btree_count++;
+	if (node->left != NULL) {
+		btree_validate_node(node->left, node);
+	}
+	if (node->right != NULL) {
+		btree_validate_node(node->right, node);
+	}
+}
+
+static void
+btree_validate(btree_t *t)
+{
+	assert(t->magic == BTREE_MAGIC);
+#ifdef DEBUG
+	btree_count = 0;
+	if (t->root != NULL) {
+		btree_validate_node(t->root, NULL);
+	}
+	assert(btree_count == t->count);
+#endif
+}
+
+/*****************************************************************************/
+/* Utility functions                                                         */
+/*****************************************************************************/
+
+static btree_node_t*
+btree_min(btree_node_t *x)
+{
+        if (x == NULL) {
+                return NULL;
+        }
+        while(x->left) {
+                x = x->left;
+        }
+        return x;
+}
+
+static btree_node_t*
+btree_max(btree_node_t *x)
+{
+        if (x == NULL) {
+                return NULL;
+        }
+        while(x->right) {
+                x = x->right;
+        }
+        return x;
+}
+
+static btree_node_t*
+btree_successor(btree_node_t *x)
+{
+        btree_node_t *y;
+
+        if (x->right != NULL) {
+                return btree_min(x->right);
+        }
+
+        y = x->parent;
+        while (y != NULL && x == y->right) {
+                x = y;
+                y = y->parent;
+        }
+
+        return y;
+}
+
+static btree_node_t*
+btree_search(btree_node_t *x, uint32_t key)
+{
+        while (x != NULL && key != x->key) {
+                if (key < x->key) {
+                        x = x->left;
+                } else {
+                        x = x->right;
+                }
+        }
+        return x; 
+}
+
+static void
+btree_insert_node(btree_t *tree, btree_node_t *z) {
+        btree_node_t *x, *y;
+
+	btree_validate(tree);
+        y = NULL;
+        x = tree->root;
+        while (x != NULL) {
+                y = x;
+                assert(z->key != x->key);
+                if (z->key < x->key) {
+                        x = x->left;
+                } else {
+                        x = x->right;
+                }
+        }
+
+        z->parent = y;
+        if (y == NULL) {
+                tree->root = z;
+        } else if (z->key < y->key) {
+                y->left = z;
+        } else {
+                y->right = z;
+        }
+	tree->count++;
+	btree_validate(tree);
+}
+
+static btree_node_t*
+btree_delete_node(btree_t *tree, btree_node_t *z)
+{
+        btree_node_t *x, *y;
+
+	btree_validate(tree);
+        if (z->left == NULL || z->right == NULL) {
+                y = z;
+        } else {
+                y = btree_successor(z);
+        }
+
+        if (y->left != NULL) {
+                x = y->left;
+        } else {
+                x = y->right;
+        }
+
+        if (x != NULL) {
+                x->parent = y->parent;
+        }
+
+        if (y->parent == NULL) {
+                tree->root = x;
+        } else if (y == y->parent->left) {
+                y->parent->left = x;
+        } else {
+                y->parent->right = x;
+        }
+
+        z->key  = y->key;
+        z->data = y->data;
+
+	tree->count--;
+
+	btree_validate(tree);
+        return y;
+}
+
+/*****************************************************************************/
+/* Exported functions                                                        */
+/*****************************************************************************/
+
+int
+btree_create(btree_t **tree)
+{
+        btree_t *t = (btree_t*)xmalloc(sizeof(btree_t));
+        if (t) {
+		t->count = 0;
+		t->magic = BTREE_MAGIC;
+                t->root  = NULL;
+                *tree = t;
+                return TRUE;
+        }
+        return FALSE;
+}
+
+int
+btree_destroy(btree_t **tree)
+{
+        btree_t *t = *tree;
+
+	btree_validate(t);
+        if (t->root != NULL) {
+                debug_msg("Tree not empty - cannot destroy\n");
+                return FALSE;
+        }
+
+        xfree(t);
+        *tree = NULL;
+        return TRUE;
+}
+
+int
+btree_find(btree_t *tree, uint32_t key, void **d)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        x = btree_search(tree->root, key);
+        if (x != NULL) {
+                *d = x->data;
+                return TRUE;
+        }
+        return FALSE;
+}
+
+int 
+btree_add(btree_t *tree, uint32_t key, void *data)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        x = btree_search(tree->root, key);
+        if (x != NULL) {
+                debug_msg("Item already exists - key %ul\n", key);
+                return FALSE;
+        }
+
+        x = (btree_node_t *)xmalloc(sizeof(btree_node_t));
+        x->key    = key;
+        x->data   = data;
+        x->parent = NULL;
+	x->left   = NULL;
+	x->right  = NULL;
+	x->magic  = BTREE_NODE_MAGIC;
+        btree_insert_node(tree, x);
+
+        return TRUE;
+}
+
+int
+btree_remove(btree_t *tree, uint32_t key, void **data)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        x = btree_search(tree->root, key);
+        if (x == NULL) {
+                debug_msg("Item not on tree - key %ul\n", key);
+                *data = NULL;
+                return FALSE;
+        }
+
+        /* Note value that gets freed is not necessarily the the same
+         * as node that gets removed from tree since there is an
+         * optimization to avoid pointer updates in tree which means
+         * sometimes we just copy key and data from one node to
+         * another.  
+         */
+
+        *data = x->data;
+        x = btree_delete_node(tree, x);
+        xfree(x);
+
+        return TRUE;
+}
+
+int 
+btree_get_min_key(btree_t *tree, uint32_t *key)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        if (tree->root == NULL) {
+                return FALSE;
+        }
+
+        x = btree_min(tree->root);
+        if (x == NULL) {
+                return FALSE;
+        }
+        
+        *key = x->key;
+        return TRUE;
+}
+
+int 
+btree_get_max_key(btree_t *tree, uint32_t *key)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        if (tree->root == NULL) {
+                return FALSE;
+        }
+
+        x = btree_max(tree->root);
+        if (x == NULL) {
+                return FALSE;
+        }
+        
+        *key = x->key;
+        return TRUE;
+}
+
+int
+btree_get_next_key(btree_t *tree, uint32_t cur_key, uint32_t *next_key)
+{
+        btree_node_t *x;
+
+	btree_validate(tree);
+        x = btree_search(tree->root, cur_key);
+        if (x == NULL) {
+                return FALSE;
+        }
+        
+        x = btree_successor(x);
+        if (x == NULL) {
+                return FALSE;
+        }
+        
+        *next_key = x->key;
+        return TRUE;
+}
+
+/*****************************************************************************/
+/* Test code                                                                 */
+/*****************************************************************************/
+
+#ifdef TEST_BTREE
+
+static int
+btree_depth(btree_node_t *x)
+{
+        int l, r;
+
+        if (x == NULL) {
+                return 0;
+        }
+
+        l = btree_depth(x->left);
+        r = btree_depth(x->right);
+
+        if (l > r) {
+                return l + 1;
+        } else {
+                return r + 1;
+        }
+}
+
+#include <curses.h>
+
+static void
+btree_dump_node(btree_node_t *x, int depth, int c, int w)
+{
+        if (x == NULL) {
+                return;
+        }
+        
+        move(depth * 2, c);
+        printw("%lu", x->key);
+        refresh();
+
+        btree_dump_node(x->left,  depth + 1, c - w/2, w/2);
+        btree_dump_node(x->right, depth + 1, c + w/2, w/2);
+
+        return;
+}
+
+static void
+btree_dump(btree_t *b)
+{
+        initscr();
+        btree_dump_node(b->root, 0, 40, 48);
+        refresh();
+        endwin();
+}
+
+#include "stdlib.h"
+
+int 
+main()
+{
+        btree_t *b;
+        uint32_t i, *x;
+        uint32_t v[] = {15, 5, 16, 3, 12, 20, 10, 13, 18, 23, 6, 7}; 
+        uint32_t nv = sizeof(v) / sizeof(v[0]);
+
+        btree_create(&b);
+
+        for(i = 0; i < nv; i++) {
+                x = (uint32_t*)xmalloc(sizeof(uint32_t));
+                *x = (uint32_t)random();
+                if (btree_add(b, v[i], (void*)x) != TRUE) {
+                        printf("Fail Add %lu %lu\n", v[i], *x);
+                }
+        }
+    
+        printf("depth %d\n", btree_depth(b->root));
+        btree_dump(b);
+
+        sleep(3);
+        btree_remove(b, 5, (void*)&x);
+        btree_dump(b);
+        sleep(3);
+        btree_remove(b, 16, (void*)&x);
+        btree_dump(b);
+        sleep(3);
+        btree_remove(b, 13, (void*)&x);
+        btree_dump(b);
+
+        while (btree_get_root_key(b, &i)) {
+                if (btree_remove(b, i, (void*)&x) == FALSE) {
+                        fprintf(stderr, "Failed to remove %lu\n", i);
+                }
+                btree_dump(b);
+                sleep(1); 
+        }
+
+        if (btree_destroy(&b) == FALSE) {
+                printf("Failed to destroy \n");
+        }
+                
+        return 0;
+}
+
+#endif /* TEST_BTREE*/
+
+
Index: /common/tags/common_1_1_2/src/crypt_random.c
===================================================================
--- /common/tags/common_1_1_2/src/crypt_random.c (revision 327)
+++ /common/tags/common_1_1_2/src/crypt_random.c (revision 327)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1993 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * LBL random number generator.
+ *
+ * Written by Steve McCanne & Chris Torek (mccanne@ee.lbl.gov,
+ * torek@ee.lbl.gov), November, 1992.
+ *
+ * This implementation is based on ``Two Fast Implementations of
+ * the "Minimal Standard" Random Number Generator", David G. Carta,
+ * Communications of the ACM, Jan 1990, Vol 33 No 1.
+ */
+
+#include "config_win32.h"
+#include "config_unix.h"
+#include "crypt_random.h"
+
+static uint32_t randseed = 1;
+
+void
+lbl_srandom(uint32_t seed)
+{
+	randseed = seed;
+}
+
+uint32_t
+lbl_random(void)
+{
+#ifdef HAVE_DEV_URANDOM
+	int	fd, res, l;
+
+	fd = open("/dev/urandom", O_RDONLY);
+	if (fd == -1) {
+		perror("Cannot open random sequence generator");
+		abort();
+	}
+	l = read(fd, &res, sizeof(res));
+	if (l != sizeof(res)) {
+		perror("Cannot read random data");
+		abort();
+	}
+	close(fd);
+	return res;
+#else
+	register uint32_t x = randseed;
+	register uint32_t hi, lo, t;
+
+	hi = x / 127773;
+	lo = x % 127773;
+	t = 16807 * lo - 2836 * hi;
+	if (t <= 0)
+		t += 0x7fffffff;
+	randseed = t;
+	return (t);
+#endif
+}
+
Index: /common/tags/common_1_1_2/src/asarray.c
===================================================================
--- /common/tags/common_1_1_2/src/asarray.c (revision 424)
+++ /common/tags/common_1_1_2/src/asarray.c (revision 424)
@@ -0,0 +1,177 @@
+/*
+ * FILE:    asarray.c
+ *
+ * AUTHORS: Orion Hodson
+ *
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ */
+ 
+#ifndef HIDE_SOURCE_STRINGS
+static const char cvsid[] = 
+	"$Id$";
+#endif /* HIDE_SOURCE_STRINGS */
+
+#include "config_unix.h"
+#include "config_win32.h"
+
+#include "debug.h"
+#include "memory.h"
+#include "util.h"
+
+#include "asarray.h"
+
+typedef struct s_hash_tuple {
+        uint32_t hash;
+        char *key;
+        char *value;
+        struct s_hash_tuple *next;
+} hash_tuple;
+
+#define ASARRAY_SIZE 11
+
+struct _asarray {
+        hash_tuple *table[ASARRAY_SIZE];
+        int32_t     nitems[ASARRAY_SIZE];
+};
+
+static uint32_t 
+asarray_hash(const char *key)
+{
+        uint32_t hash = 0;
+
+        while(*key != '\0') {
+                hash = hash * 31;
+                hash += ((uint32_t)*key) + 1;
+                key++;
+        }
+
+        return hash;
+}
+
+int32_t
+asarray_add(asarray *pa, const char *key, const char *value)
+{
+        hash_tuple *t;
+        int row;
+
+        t = (hash_tuple*)xmalloc(sizeof(hash_tuple));
+        if (t) {
+                /* transfer values */
+                t->hash  = asarray_hash(key);
+                t->key   = xstrdup(key);
+                t->value = xstrdup(value);
+                /* Add to table */
+                row            = t->hash % ASARRAY_SIZE;
+                t->next        = pa->table[row];
+                pa->table[row] = t;
+                pa->nitems[row]++;
+                return TRUE;
+        }
+        return FALSE;
+}
+
+void
+asarray_remove(asarray *pa, const char *key)
+{
+        hash_tuple **t, *e;
+        uint32_t hash;
+        int row;
+
+        hash = asarray_hash(key);
+        row  = hash % ASARRAY_SIZE;
+        t    = &pa->table[row];
+        while((*t) != NULL) {
+                if ((hash == (*t)->hash) && 
+                    (strcmp(key, (*t)->key) == 0)) {
+                        e = *t;
+                        *t = e->next;
+                        xfree(e->key);
+                        xfree(e->value);
+                        xfree(e);
+                        pa->nitems[row]--;
+                        assert(pa->nitems[row] >= 0);
+                        break;
+                } else {
+                        t = &(*t)->next;
+                }
+        }
+}
+
+const char* 
+asarray_get_key_no(asarray *pa, int32_t index)
+{
+        int32_t row = 0;
+
+        index += 1;
+        while (row < ASARRAY_SIZE && index > pa->nitems[row]) {
+                index -= pa->nitems[row];
+                row++;
+        }
+
+        if (row < ASARRAY_SIZE) {
+                hash_tuple *t;
+                t = pa->table[row];
+                while(--index > 0) {
+                        assert(t->next != NULL);
+                        t = t->next;
+                }
+                return t->key;
+        }
+        return NULL;
+}
+
+/* asarray_lookup points value at actual value        */
+/* and return TRUE if key found.                      */
+int32_t
+asarray_lookup(asarray *pa, const char *key, char **value)
+{
+        hash_tuple *t;
+        int          row;
+        uint32_t     hash;
+
+        hash = asarray_hash(key);
+        row  = hash % ASARRAY_SIZE;
+
+        t = pa->table[row];
+        while(t != NULL) {
+                if (t->hash == hash && strcmp(key, t->key) == 0) {
+                        *value = t->value;
+                        return TRUE;
+                }
+                t = t->next;
+        }
+        *value = NULL;
+        return FALSE;
+}
+
+int32_t
+asarray_create(asarray **ppa)
+{
+        asarray *pa;
+        pa = (asarray*)xmalloc(sizeof(asarray));
+        if (pa != NULL) {
+                memset(pa, 0, sizeof(asarray));
+                *ppa = pa;
+                return TRUE;
+        }
+        return FALSE;
+}
+
+void
+asarray_destroy(asarray **ppa)
+{
+        asarray    *pa;
+        const char *key;
+
+        pa = *ppa;
+        assert(pa != NULL);
+
+        while ((key = asarray_get_key_no(pa, 0)) != NULL) {
+                asarray_remove(pa, key);
+        }
+
+        xfree(pa);
+        *ppa = NULL;
+        xmemchk();
+}
Index: /common/tags/common_1_1_2/src/net_udp.h
===================================================================
--- /common/tags/common_1_1_2/src/net_udp.h (revision 423)
+++ /common/tags/common_1_1_2/src/net_udp.h (revision 423)
@@ -0,0 +1,62 @@
+/*
+ * FILE:    net_udp.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _NET_UDP
+#define _NET_UDP
+
+typedef struct _socket_udp socket_udp;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int         udp_addr_valid(const char *addr);
+socket_udp *udp_init(const char *addr, uint16_t rx_port, uint16_t tx_port, int ttl);
+socket_udp *udp_init_if(const char *addr, const char *iface, uint16_t rx_port, uint16_t tx_port, int ttl);
+void        udp_exit(socket_udp *s);
+int         udp_send(socket_udp *s, char *buffer, int buflen);
+int         udp_recv(socket_udp *s, char *buffer, int buflen);
+int         udp_select(struct timeval *timeout);
+void        udp_fd_zero(void);
+void        udp_fd_set(socket_udp *s);
+int         udp_fd_isset(socket_udp *s);
+const char *udp_host_addr(socket_udp *s);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
Index: /common/tags/common_1_1_2/src/inet_pton.h
===================================================================
--- /common/tags/common_1_1_2/src/inet_pton.h (revision 379)
+++ /common/tags/common_1_1_2/src/inet_pton.h (revision 379)
@@ -0,0 +1,11 @@
+#ifndef HAVE_INET_PTON
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int inet_pton(int af, const char *src, void *dst);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* HAVE_INET_PTON */
Index: /common/tags/common_1_1_2/src/inet_ntop.h
===================================================================
--- /common/tags/common_1_1_2/src/inet_ntop.h (revision 379)
+++ /common/tags/common_1_1_2/src/inet_ntop.h (revision 379)
@@ -0,0 +1,11 @@
+#ifndef HAVE_INET_NTOP
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* HAVE_INET_NTOP */
Index: /common/tags/common_1_1_2/src/drand48.c
===================================================================
--- /common/tags/common_1_1_2/src/drand48.c (revision 211)
+++ /common/tags/common_1_1_2/src/drand48.c (revision 211)
@@ -0,0 +1,13 @@
+#include "config_unix.h"
+#include "config_win32.h"
+#include "drand48.h"
+
+#ifdef NEED_DRAND48
+
+double drand48(void)
+{
+        unsigned int x = (rand() << 16) | rand();
+	return ((double)x / (double)0xffffffff);
+}
+
+#endif
Index: /common/tags/common_1_1_2/src/mbus_addr.h
===================================================================
--- /common/tags/common_1_1_2/src/mbus_addr.h (revision 428)
+++ /common/tags/common_1_1_2/src/mbus_addr.h (revision 428)
@@ -0,0 +1,41 @@
+/*
+ * FILE:     mbus_addr.h
+ * AUTHOR:   Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+int     mbus_addr_match(const char *a, const char *b);
+int mbus_addr_identical(const char *a, const char *b);
+
+/* The strfind() function is mainly for internal use, but might be useful to others... */
+int strfind(const char *haystack, const char *needle_start, const char *needle_end);
+
Index: /common/tags/common_1_1_2/src/crypt_random.h
===================================================================
--- /common/tags/common_1_1_2/src/crypt_random.h (revision 314)
+++ /common/tags/common_1_1_2/src/crypt_random.h (revision 314)
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1993 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the Computer Systems
+ *	Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * LBL random number generator.
+ *
+ * Written by Steve McCanne & Chris Torek (mccanne@ee.lbl.gov,
+ * torek@ee.lbl.gov), November, 1992.
+ *
+ * This implementation is based on ``Two Fast Implementations of
+ * the "Minimal Standard" Random Number Generator", David G. Carta,
+ * Communications of the ACM, Jan 1990, Vol 33 No 1.
+ */
+
+void      lbl_srandom(uint32_t seed);
+uint32_t lbl_random(void);
+
Index: /common/tags/common_1_1_2/src/mbus.c
===================================================================
--- /common/tags/common_1_1_2/src/mbus.c (revision 428)
+++ /common/tags/common_1_1_2/src/mbus.c (revision 428)
@@ -0,0 +1,1008 @@
+/*
+ * FILE:     mbus.c
+ * AUTHOR:   Colin Perkins
+ * MODIFIED: Orion Hodson
+ *           Markus Germeier
+ * 
+ * Copyright (c) 1997-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "net_udp.h"
+#include "hmac.h"
+#include "qfDES.h"
+#include "base64.h"
+#include "gettimeofday.h"
+#include "mbus.h"
+#include "mbus_config.h"
+#include "mbus_parser.h"
+#include "mbus_addr.h"
+
+#define MBUS_BUF_SIZE	  1500
+#define MBUS_ACK_BUF_SIZE 1500
+#define MBUS_MAX_ADDR	    10
+#define MBUS_MAX_QLEN	    50 /* Number of messages we can queue with mbus_qmsg() */
+
+#define MBUS_MAGIC	0x87654321
+#define MBUS_MSG_MAGIC	0x12345678
+
+#ifdef NEED_VSNPRINTF
+static int vsnprintf(char *s, size_t buf_size, const char *format, va_list ap)
+{
+	/* Quick hack replacement for vsnprintf... note that this */
+	/* doesn't check for buffer overflows, and so is open to  */
+	/* many really nasty attacks!                             */
+	UNUSED(buf_size);
+        return vsprintf(s,format,ap);
+}
+#endif
+
+struct mbus_msg {
+	struct mbus_msg	*next;
+	struct timeval	 time;	/* Time the message was sent, to trigger a retransmit */
+	struct timeval	 ts;	/* Time the message was composed, the timestamp in the packet header */
+	char		*dest;
+	int		 reliable;
+	int		 complete;	/* Indicates that we've finished adding cmds to this message */
+	int		 seqnum;
+	int		 retransmit_count;
+	int		 message_size;
+	int		 num_cmds;
+	char		*cmd_list[MBUS_MAX_QLEN];
+	char		*arg_list[MBUS_MAX_QLEN];
+	uint32_t	 magic;		/* For debugging... */
+};
+
+struct mbus {
+	socket_udp	 	 *s;
+	char		 	 *addr;				/* Addresses we respond to. 					*/
+	int		 	  max_other_addr;
+	int		 	  num_other_addr;
+	char			**other_addr;			/* Addresses of other entities on the mbus. 			*/
+        struct timeval          **other_hello;                  /* Time of last mbus.hello we received from other entities      */
+	int		 	  seqnum;
+	struct mbus_msg	 	 *cmd_queue;			/* Queue of messages waiting to be sent */
+	struct mbus_msg	 	 *waiting_ack;			/* The last reliable message sent, if we have not yet got the ACK */
+	char		 	 *hashkey;
+	int		 	  hashkeylen;
+	char		 	 *encrkey;
+	int		 	  encrkeylen;
+	struct timeval	 	  last_heartbeat;		/* Last time we sent a heartbeat message */
+	struct mbus_config	 *cfg;
+	void (*cmd_handler)(char *src, char *cmd, char *arg, void *dat);
+	void (*err_handler)(int seqnum, int reason);
+	uint32_t		  magic;			/* For debugging...                                             */
+};
+
+static void mbus_validate(struct mbus *m)
+{
+#ifdef DEBUG
+	int	i;
+
+	assert(m->num_other_addr <= m->max_other_addr);
+	assert(m->num_other_addr >= 0);
+	for (i = 0; i < m->num_other_addr; i++) {
+		assert(m->other_addr[i]  != NULL);
+		assert(m->other_hello[i] != NULL);
+	}
+	for (i = m->num_other_addr + 1; i < m->max_other_addr; i++) {
+		assert(m->other_addr[i]  == NULL);
+		assert(m->other_hello[i] == NULL);
+	}
+#endif
+	assert(m->magic == MBUS_MAGIC);
+}
+
+static void mbus_msg_validate(struct mbus_msg *m)
+{
+#ifdef DEBUG
+	int	i;
+
+	assert((m->num_cmds < MBUS_MAX_QLEN) && (m->num_cmds >= 0));
+	for (i = 0; i < m->num_cmds; i++) {
+		assert(m->cmd_list[i] != NULL);
+		assert(m->arg_list[i] != NULL);
+	}
+	for (i = m->num_cmds + 1; i < MBUS_MAX_QLEN; i++) {
+		assert(m->cmd_list[i] == NULL);
+		assert(m->arg_list[i] == NULL);
+	}	
+	assert(m->dest != NULL);
+#endif
+	assert(m->magic == MBUS_MSG_MAGIC);
+}
+
+static void store_other_addr(struct mbus *m, char *a)
+{
+	/* This takes the address a and ensures it is stored in the   */
+	/* m->other_addr field of the mbus structure. The other_addr  */
+	/* field should probably be a hash table, but for now we hope */
+	/* that there are not too many entities on the mbus, so the   */
+	/* list is small.                                             */
+	int	i;
+
+	mbus_validate(m);
+
+	for (i = 0; i < m->num_other_addr; i++) {
+		if (mbus_addr_match(m->other_addr[i], a)) {
+			/* Already in the list... */
+			return;
+		}
+	}
+
+	if (m->num_other_addr == m->max_other_addr) {
+		/* Expand the list... */
+		m->max_other_addr *= 2;
+		m->other_addr = (char **) xrealloc(m->other_addr, m->max_other_addr * sizeof(char *));
+		m->other_hello = (struct timeval **) xrealloc(m->other_hello, m->max_other_addr * sizeof(struct timeval *));
+	}
+	m->other_hello[m->num_other_addr]=(struct timeval *)xmalloc(sizeof(struct timeval));
+	gettimeofday(m->other_hello[m->num_other_addr],NULL);
+	m->other_addr[m->num_other_addr++] = xstrdup(a);
+}
+
+static void remove_other_addr(struct mbus *m, char *a)
+{
+	/* Removes the address a from the m->other_addr field of the */
+	/* mbus structure.                                           */
+	int	i, j;
+
+	mbus_validate(m);
+
+	for (i = 0; i < m->num_other_addr; i++) {
+		if (mbus_addr_match(m->other_addr[i], a)) {
+			xfree(m->other_addr[i]);
+			xfree(m->other_hello[i]);
+			for (j = i+1; j < m->num_other_addr; j++) {
+				m->other_addr[j-1] = m->other_addr[j];
+				m->other_hello[j-1] = m->other_hello[j];
+			}
+			m->other_addr[m->num_other_addr  - 1] = NULL;
+			m->other_hello[m->num_other_addr - 1] = NULL;
+			m->num_other_addr--;
+		}
+	}
+}
+
+static void mark_activ_other_addr(struct mbus *m, char *a){
+	int i;
+	struct timeval	 t;
+    
+	mbus_validate(m);
+
+	gettimeofday(&t, NULL);
+	for (i = 0; i < m->num_other_addr; i++) {
+		if (mbus_addr_match(m->other_addr[i], a)) {
+			m->other_hello[i]->tv_sec=t.tv_sec;
+		}
+	}
+}
+
+static void remove_inactiv_other_addr(struct mbus *m, struct timeval t, int interval){
+	/* Remove addresses we haven't heard from for about 5 * interval */
+	/* Count backwards so it is safe to remove entries               */
+	int i;
+    
+	mbus_validate(m);
+
+	for (i=m->num_other_addr-1; i>=0; i--){
+		if ((t.tv_sec-(m->other_hello[i]->tv_sec)) > 5 * interval) {
+			debug_msg("remove dead entity (%s)\n", m->other_addr[i]);
+			remove_other_addr(m, m->other_addr[i]);
+		}
+	}
+}
+
+int mbus_addr_valid(struct mbus *m, char *addr)
+{
+	int	i;
+
+	mbus_validate(m);
+
+	for (i = 0; i < m->num_other_addr; i++) {
+		if (mbus_addr_match(m->other_addr[i], addr)) {
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+static int mbus_addr_unique(struct mbus *m, char *addr)
+{
+	int     i, n = 0;
+
+	mbus_validate(m);
+
+	for (i = 0; i < m->num_other_addr; i++) {
+		if (mbus_addr_match(m->other_addr[i], addr)) {
+			n++;
+		}
+	}
+	return n==1;
+}
+
+/* The mb_* functions are used to build an mbus message up in the */
+/* mb_buffer, and to add authentication and encryption before the */
+/* message is sent.                                               */
+char	 mb_cryptbuf[MBUS_BUF_SIZE];
+char	*mb_buffer;
+char	*mb_bufpos;
+
+#define MBUS_AUTH_LEN 16
+
+static void mb_header(int seqnum, int ts, char reliable, const char *src, const char *dst, int ackseq)
+{
+	xmemchk();
+	mb_buffer   = (char *) xmalloc(MBUS_BUF_SIZE + 1);
+	memset(mb_buffer,   0, MBUS_BUF_SIZE);
+	memset(mb_buffer, ' ', MBUS_AUTH_LEN);
+	mb_bufpos = mb_buffer + MBUS_AUTH_LEN;
+	sprintf(mb_bufpos, "\nmbus/1.0 %6d %9d %c (%s) %s ", seqnum, ts, reliable, src, dst);
+	mb_bufpos += 33 + strlen(src) + strlen(dst);
+	if (ackseq == -1) {
+		sprintf(mb_bufpos, "()\n");
+		mb_bufpos += 3;
+	} else {
+		sprintf(mb_bufpos, "(%6d)\n", ackseq);
+		mb_bufpos += 9;
+	}
+}
+
+static void mb_add_command(const char *cmnd, const char *args)
+{
+	int offset = strlen(cmnd) + strlen(args) + 5;
+
+	assert((mb_bufpos + offset - mb_buffer) < MBUS_BUF_SIZE);
+
+	sprintf(mb_bufpos, "%s (%s)\n", cmnd, args);
+	mb_bufpos += offset - 1; /* The -1 in offset means we're not NUL terminated - fix in mb_send */
+}
+
+static void mb_send(struct mbus *m)
+{
+	char		digest[16];
+	int		len;
+	unsigned char	initVec[8] = {0,0,0,0,0,0,0,0};
+ 
+	mbus_validate(m);
+
+	*(mb_bufpos++) = '\0';
+	assert((mb_bufpos - mb_buffer) < MBUS_BUF_SIZE);
+	assert(strlen(mb_buffer) < MBUS_BUF_SIZE);
+
+	/* Pad to a multiple of 8 bytes, so the encryption can work... */
+	while (((mb_bufpos - mb_buffer) % 8) != 0) {
+		*(mb_bufpos++) = '\0';
+	}
+	len = mb_bufpos - mb_buffer;
+	assert(len < MBUS_BUF_SIZE);
+	assert(strlen(mb_buffer) < MBUS_BUF_SIZE);
+
+	if (m->hashkey != NULL) {
+		/* Authenticate... */
+		hmac_md5(mb_buffer + MBUS_AUTH_LEN+1, strlen(mb_buffer) - (MBUS_AUTH_LEN+1), m->hashkey, m->hashkeylen, digest);
+		base64encode(digest, 12, mb_buffer, MBUS_AUTH_LEN);
+	}
+	if (m->encrkey != NULL) {
+		/* Encrypt... */
+		memset(mb_cryptbuf, 0, MBUS_BUF_SIZE);
+		memcpy(mb_cryptbuf, mb_buffer, len);
+		assert((len % 8) == 0);
+		assert(len < MBUS_BUF_SIZE);
+		assert(m->encrkeylen == 8);
+		qfDES_CBC_e(m->encrkey, mb_cryptbuf, len, initVec);
+		memcpy(mb_buffer, mb_cryptbuf, len);
+	}
+	udp_send(m->s, mb_buffer, len);
+	xfree(mb_buffer);
+}
+
+static void resend(struct mbus *m, struct mbus_msg *curr) 
+{
+	/* Don't need to check for buffer overflows: this was done in mbus_send() when */
+	/* this message was first transmitted. If it was okay then, it's okay now.     */
+	int	 i;
+
+	mbus_validate(m);
+
+	mb_header(curr->seqnum, curr->ts.tv_sec, (char)(curr->reliable?'R':'U'), m->addr, curr->dest, -1);
+	for (i = 0; i < curr->num_cmds; i++) {
+		mb_add_command(curr->cmd_list[i], curr->arg_list[i]);
+	}
+	mb_send(m);
+	curr->retransmit_count++;
+}
+
+void mbus_retransmit(struct mbus *m)
+{
+	struct mbus_msg	*curr = m->waiting_ack;
+	struct timeval	time;
+	long		diff;
+
+	mbus_validate(m);
+
+	if (!mbus_waiting_ack(m)) {
+		return;
+	}
+
+	mbus_msg_validate(curr);
+
+	gettimeofday(&time, NULL);
+
+	/* diff is time in milliseconds that the message has been awaiting an ACK */
+	diff = ((time.tv_sec * 1000) + (time.tv_usec / 1000)) - ((curr->time.tv_sec * 1000) + (curr->time.tv_usec / 1000));
+	if (diff > 10000) {
+		debug_msg("Reliable mbus message failed!\n");
+		if (m->err_handler == NULL) {
+			abort();
+		}
+		m->err_handler(curr->seqnum, MBUS_MESSAGE_LOST);
+		/* if we don't delete this failed message, the error handler
+                   gets triggered every time we call mbus_retransmit */
+		while (m->waiting_ack->num_cmds > 0) {
+		    m->waiting_ack->num_cmds--;
+		    xfree(m->waiting_ack->cmd_list[m->waiting_ack->num_cmds]);
+		    xfree(m->waiting_ack->arg_list[m->waiting_ack->num_cmds]);
+		}
+		xfree(m->waiting_ack->dest);
+		xfree(m->waiting_ack);
+		m->waiting_ack = NULL;
+		return;
+	} 
+	/* Note: We only send one retransmission each time, to avoid
+	 * overflowing the receiver with a burst of requests...
+	 */
+	if ((diff > 750) && (curr->retransmit_count == 2)) {
+		resend(m, curr);
+		return;
+	} 
+	if ((diff > 500) && (curr->retransmit_count == 1)) {
+		resend(m, curr);
+		return;
+	} 
+	if ((diff > 250) && (curr->retransmit_count == 0)) {
+		resend(m, curr);
+		return;
+	}
+}
+
+void mbus_heartbeat(struct mbus *m, int interval)
+{
+	struct timeval	curr_time;
+	char	*a = (char *) xmalloc(3);
+	sprintf(a, "()");
+
+	mbus_validate(m);
+
+	gettimeofday(&curr_time, NULL);
+	if (curr_time.tv_sec - m->last_heartbeat.tv_sec >= interval) {
+		mb_header(++m->seqnum, (int) curr_time.tv_sec, 'U', m->addr, "()", -1);
+		mb_add_command("mbus.hello", "");
+		mb_send(m);
+
+		m->last_heartbeat = curr_time;
+		/* Remove dead sources */
+		remove_inactiv_other_addr(m, curr_time, interval);
+	}
+	xfree(a);
+}
+
+int mbus_waiting_ack(struct mbus *m)
+{
+	mbus_validate(m);
+	return m->waiting_ack != NULL;
+}
+
+int mbus_sent_all(struct mbus *m)
+{
+	mbus_validate(m);
+	return (m->cmd_queue == NULL) && (m->waiting_ack == NULL);
+}
+
+struct mbus *mbus_init(void  (*cmd_handler)(char *src, char *cmd, char *arg, void *dat), 
+		       void  (*err_handler)(int seqnum, int reason),
+		       char  *addr)
+{
+	struct mbus		*m;
+	struct mbus_key	 	 k;
+	struct mbus_parser	*mp;
+	int		 	 i;
+	char            	*net_addr;
+	uint16_t         	 net_port;
+	int              	 net_scope;
+
+	m = (struct mbus *) xmalloc(sizeof(struct mbus));
+	if (m == NULL) {
+		debug_msg("Unable to allocate memory for mbus\n");
+		return NULL;
+	}
+
+	m->cfg = mbus_create_config();
+	mbus_lock_config_file(m->cfg);
+	net_addr = (char *) xmalloc(20);
+	mbus_get_net_addr(m->cfg, net_addr, &net_port, &net_scope);
+	m->s		  = udp_init(net_addr, net_port, net_port, net_scope);	
+	m->seqnum         = 0;
+	m->cmd_handler    = cmd_handler;
+	m->err_handler	  = err_handler;
+	m->num_other_addr = 0;
+	m->max_other_addr = 10;
+	m->other_addr     = (char **) xmalloc(sizeof(char *) * 10);
+	m->other_hello    = (struct timeval **) xmalloc(sizeof(struct timeval *) * 10);
+	for (i = 0; i < 10; i++) {
+		m->other_addr[i]  = NULL;
+		m->other_hello[i] = NULL;
+	}
+	m->cmd_queue	  = NULL;
+	m->waiting_ack	  = NULL;
+	m->magic          = MBUS_MAGIC;
+
+	mp = mbus_parse_init(xstrdup(addr));
+	if (!mbus_parse_lst(mp, &(m->addr))) {
+		debug_msg("Invalid mbus address\n");
+		abort();
+	}
+	mbus_parse_done(mp);
+	assert(m->addr != NULL);
+
+	gettimeofday(&(m->last_heartbeat), NULL);
+
+	mbus_get_encrkey(m->cfg, &k);
+	m->encrkey    = k.key;
+	m->encrkeylen = k.key_len;
+
+	mbus_get_hashkey(m->cfg, &k);
+	m->hashkey    = k.key;
+	m->hashkeylen = k.key_len;
+
+	mbus_unlock_config_file(m->cfg);
+
+	xfree(net_addr);
+
+	return m;
+}
+
+void mbus_cmd_handler(struct mbus *m, void  (*cmd_handler)(char *src, char *cmd, char *arg, void *dat))
+{
+	mbus_validate(m);
+	m->cmd_handler = cmd_handler;
+}
+
+static void mbus_flush_msgs(struct mbus_msg *queue)
+{
+        struct mbus_msg *curr, *next;
+        int i;
+
+        curr = queue;
+        while(curr) {
+                next = curr->next;
+                xfree(curr->dest);
+                for(i = 0; i < curr->num_cmds; i++) {
+                        xfree(curr->cmd_list[i]);
+                        xfree(curr->arg_list[i]);
+                }
+                curr = next;
+        }
+}
+
+void mbus_exit(struct mbus *m) 
+{
+        int i;
+
+        assert(m != NULL);
+	mbus_validate(m);
+
+	mbus_qmsg(m, "()", "mbus.bye", "", FALSE);
+	mbus_send(m);
+
+	/* FIXME: It should be a fatal error to call mbus_exit() if some messages are still outstanding. */
+	/*        We will need an mbus_flush() call first though, to ensure nothing is waiting.          */
+        mbus_flush_msgs(m->cmd_queue);
+        mbus_flush_msgs(m->waiting_ack);
+
+        if (m->encrkey != NULL) {
+                xfree(m->encrkey);
+        }
+        if (m->hashkey != NULL) {
+        	xfree(m->hashkey);
+	}
+
+        udp_exit(m->s);
+
+	/* Clean up other_* */
+	for (i=m->num_other_addr-1; i>=0; i--){
+	    remove_other_addr(m, m->other_addr[i]);
+	}
+
+        xfree(m->addr);
+	xfree(m->other_addr);
+	xfree(m->other_hello);
+	xfree(m->cfg);
+        xfree(m);
+}
+
+void mbus_send(struct mbus *m)
+{
+	/* Send one, or more, messages previosly queued with mbus_qmsg(). */
+	/* Messages for the same destination are batched together. Stops  */
+	/* when a reliable message is sent, until the ACK is received.    */
+	struct mbus_msg	*curr = m->cmd_queue;
+	int		 i;
+
+	mbus_validate(m);
+	if (m->waiting_ack != NULL) {
+		return;
+	}
+
+	while (curr != NULL) {
+		mbus_msg_validate(curr);
+		/* It's okay for us to send messages which haven't been marked as complete - */
+		/* that just means we're sending something which has the potential to have   */
+		/* more data piggybacked. However, if it's not complete it MUST be the last  */
+		/* in the list, or something has been reordered - which is bad.              */
+		if (!curr->complete) {
+			assert(curr->next == NULL);
+		}
+
+		if (curr->reliable) {
+		        if (!mbus_addr_valid(m, curr->dest)) {
+			    debug_msg("Trying to send reliably to an unknown address...\n");
+			    if (m->err_handler == NULL) {
+				abort();
+			    }
+			    m->err_handler(curr->seqnum, MBUS_DESTINATION_UNKNOWN);
+			}
+		        if (!mbus_addr_unique(m, curr->dest)) {
+			    debug_msg("Trying to send reliably but address is not unique...\n");
+			    if (m->err_handler == NULL) {
+				abort();
+			    }
+			    m->err_handler(curr->seqnum, MBUS_DESTINATION_NOT_UNIQUE);
+			}
+		}
+		/* Create the message... */
+		mb_header(curr->seqnum, curr->ts.tv_sec, (char)(curr->reliable?'R':'U'), m->addr, curr->dest, -1);
+		for (i = 0; i < curr->num_cmds; i++) {
+			mb_add_command(curr->cmd_list[i], curr->arg_list[i]);
+		}
+		mb_send(m);
+		
+		m->cmd_queue = curr->next;
+		if (curr->reliable) {
+			/* Reliable message, wait for the ack... */
+			gettimeofday(&(curr->time), NULL);
+			m->waiting_ack = curr;
+			return;
+		} else {
+			while (curr->num_cmds > 0) {
+				curr->num_cmds--;
+				xfree(curr->cmd_list[curr->num_cmds]); curr->cmd_list[curr->num_cmds] = NULL;
+				xfree(curr->arg_list[curr->num_cmds]); curr->arg_list[curr->num_cmds] = NULL;
+			}
+			xfree(curr->dest);
+			xfree(curr);
+		}
+		curr = m->cmd_queue;
+	}
+}
+
+void mbus_qmsg(struct mbus *m, const char *dest, const char *cmnd, const char *args, int reliable)
+{
+	/* Queue up a message for sending. The message is not */
+	/* actually sent until mbus_send() is called.         */
+	struct mbus_msg	*curr = m->cmd_queue;
+	struct mbus_msg	*prev = NULL;
+	int		 alen = strlen(cmnd) + strlen(args) + 4;
+	int		 i;
+
+	mbus_validate(m);
+	while (curr != NULL) {
+		mbus_msg_validate(curr);
+		if (!curr->complete) {
+			/* This message is still open for new commands. It MUST be the last in the */
+			/* cmd_queue, else commands will be reordered.                             */
+			assert(curr->next == NULL);
+			if (mbus_addr_identical(curr->dest, dest) &&
+		            (curr->num_cmds < MBUS_MAX_QLEN) && ((curr->message_size + alen) < (MBUS_BUF_SIZE - 500))) {
+				curr->num_cmds++;
+				curr->reliable |= reliable;
+				curr->cmd_list[curr->num_cmds-1] = xstrdup(cmnd);
+				curr->arg_list[curr->num_cmds-1] = xstrdup(args);
+				curr->message_size += alen;
+				mbus_msg_validate(curr);
+				return;
+			} else {
+				curr->complete = TRUE;
+			}
+		}
+		prev = curr;
+		curr = curr->next;
+	}
+	/* If we get here, we've not found an open message in the cmd_queue.  We */
+	/* have to create a new message, and add it to the end of the cmd_queue. */
+	curr = (struct mbus_msg *) xmalloc(sizeof(struct mbus_msg));
+	curr->magic            = MBUS_MSG_MAGIC;
+	curr->next             = NULL;
+	curr->dest             = xstrdup(dest);
+	curr->retransmit_count = 0;
+	curr->message_size     = alen + 60 + strlen(dest) + strlen(m->addr);
+	curr->seqnum           = m->seqnum++;
+	curr->reliable         = reliable;
+	curr->complete         = FALSE;
+	curr->num_cmds         = 1;
+	curr->cmd_list[0]      = xstrdup(cmnd);
+	curr->arg_list[0]      = xstrdup(args);
+	for (i = 1; i < MBUS_MAX_QLEN; i++) {
+		curr->cmd_list[i] = NULL;
+		curr->arg_list[i] = NULL;
+	}
+	if (prev == NULL) {
+		m->cmd_queue = curr;
+	} else {
+		prev->next = curr;
+	}
+	gettimeofday(&(curr->time), NULL);
+	gettimeofday(&(curr->ts),   NULL);
+	mbus_msg_validate(curr);
+}
+
+void mbus_qmsgf(struct mbus *m, const char *dest, int reliable, const char *cmnd, const char *format, ...)
+{
+	/* This is a wrapper around mbus_qmsg() which does a printf() style format into  */
+	/* a buffer. Saves the caller from having to a a malloc(), write the args string */
+	/* and then do a free(), and also saves worring about overflowing the buffer, so */
+	/* removing a common source of bugs!                                             */
+	char	buffer[MBUS_BUF_SIZE];
+	va_list	ap;
+
+	mbus_validate(m);
+	va_start(ap, format);
+#ifdef WIN32
+        _vsnprintf(buffer, MBUS_BUF_SIZE, format, ap);
+#else
+        vsnprintf(buffer, MBUS_BUF_SIZE, format, ap);
+#endif
+	va_end(ap);
+	mbus_qmsg(m, dest, cmnd, buffer, reliable);
+}
+
+int mbus_recv(struct mbus *m, void *data, struct timeval *timeout)
+{
+	char			*auth, *ver, *src, *dst, *ack, *r, *cmd, *param, *npos;
+	char	 		 buffer[MBUS_BUF_SIZE];
+	int	 		 buffer_len, seq, a, rx, ts, authlen, loop_count;
+	char	 		 ackbuf[MBUS_ACK_BUF_SIZE];
+	char	 		 digest[16];
+	unsigned char		 initVec[8] = {0,0,0,0,0,0,0,0};
+	struct timeval		 t;
+	struct mbus_parser	*mp, *mp2;
+
+	mbus_validate(m);
+
+	rx = FALSE;
+	loop_count = 0;
+	while (loop_count++ < 10) {
+		memset(buffer, 0, MBUS_BUF_SIZE);
+                assert(m->s != NULL);
+		udp_fd_zero();
+		udp_fd_set(m->s);
+		t.tv_sec  = timeout->tv_sec;
+		t.tv_usec = timeout->tv_usec;
+                if ((udp_select(&t) > 0) && udp_fd_isset(m->s)) {
+			buffer_len = udp_recv(m->s, buffer, MBUS_BUF_SIZE);
+			if (buffer_len > 0) {
+				rx = TRUE;
+			} else {
+				return rx;
+			}
+		} else {
+			return FALSE;
+		}
+
+		if (m->encrkey != NULL) {
+			/* Decrypt the message... */
+			if ((buffer_len % 8) != 0) {
+				debug_msg("Encrypted message not a multiple of 8 bytes in length\n");
+				continue;
+			}
+			memcpy(mb_cryptbuf, buffer, buffer_len);
+			memset(initVec, 0, 8);
+			qfDES_CBC_d(m->encrkey, mb_cryptbuf, buffer_len, initVec);
+			memcpy(buffer, mb_cryptbuf, buffer_len);
+		}
+
+		/* Sanity check that this is a vaguely sensible format message... Should prevent */
+		/* problems if we're fed complete garbage, but won't prevent determined hackers. */
+		if (strncmp(buffer + MBUS_AUTH_LEN + 1, "mbus/1.0", 8) != 0) {
+			continue;
+		}
+
+		mp = mbus_parse_init(buffer);
+		/* remove trailing 0 bytes */
+		npos = (char *) strchr(buffer,'\0');
+		if(npos!=NULL) {
+			buffer_len=npos-buffer;
+		}
+		/* Parse the authentication header */
+		if (!mbus_parse_sym(mp, &auth)) {
+			debug_msg("Failed to parse authentication header\n");
+			mbus_parse_done(mp);
+			continue;
+		}
+
+		/* Check that the packet authenticates correctly... */
+		authlen = strlen(auth);
+		hmac_md5(buffer + authlen + 1, buffer_len - authlen - 1, m->hashkey, m->hashkeylen, digest);
+		base64encode(digest, 12, ackbuf, 16);
+		if ((strlen(auth) != 16) || (strncmp(auth, ackbuf, 16) != 0)) {
+			debug_msg("Failed to authenticate message...\n");
+			mbus_parse_done(mp);
+			continue;
+		}
+
+		/* Parse the header */
+		if (!mbus_parse_sym(mp, &ver)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed version (1): %s\n",ver);
+			continue;
+		}
+		if (strcmp(ver, "mbus/1.0") != 0) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed version (2): %s\n",ver);
+			continue;
+		}
+		if (!mbus_parse_int(mp, &seq)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed seq\n");
+			continue;
+		}
+		if (!mbus_parse_int(mp, &ts)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed ts\n");
+			continue;
+		}
+		if (!mbus_parse_sym(mp, &r)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed reliable\n");
+			continue;
+		}
+		if (!mbus_parse_lst(mp, &src)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed src\n");
+			continue;
+		}
+		if (!mbus_parse_lst(mp, &dst)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed dst\n");
+			continue;
+		}
+		if (!mbus_parse_lst(mp, &ack)) {
+			mbus_parse_done(mp);
+			debug_msg("Parser failed ack\n");
+			continue;
+		}
+
+		store_other_addr(m, src);
+
+		/* Check if the message was addressed to us... */
+		if (mbus_addr_match(m->addr, dst)) {
+			/* ...if so, process any ACKs received... */
+			mp2 = mbus_parse_init(ack);
+			while (mbus_parse_int(mp2, &a)) {
+				if (mbus_waiting_ack(m)) {
+					if (m->waiting_ack->seqnum == a) {
+						while (m->waiting_ack->num_cmds > 0) {
+							m->waiting_ack->num_cmds--;
+							xfree(m->waiting_ack->cmd_list[m->waiting_ack->num_cmds]);
+							xfree(m->waiting_ack->arg_list[m->waiting_ack->num_cmds]);
+						}
+						xfree(m->waiting_ack->dest);
+						xfree(m->waiting_ack);
+						m->waiting_ack = NULL;
+					} else {
+						debug_msg("Got ACK %d but wanted %d\n", a, m->waiting_ack->seqnum);
+					}
+				} else {
+					debug_msg("Got ACK %d but wasn't expecting it\n", a);
+				}
+			}
+			mbus_parse_done(mp2);
+			/* ...if an ACK was requested, send one... */
+			if (strcmp(r, "R") == 0) {
+				char 		*newsrc = (char *) xmalloc(strlen(src) + 3);
+				struct timeval	 t;
+
+				sprintf(newsrc, "(%s)", src);	/* Yes, this is a kludge. */
+				gettimeofday(&t, NULL);
+				mb_header(++m->seqnum, (int) t.tv_sec, 'U', m->addr, newsrc, seq);
+				mb_send(m);
+				xfree(newsrc);
+			} else if (strcmp(r, "U") == 0) {
+				/* Unreliable message.... not need to do anything */
+			} else {
+				debug_msg("Message with invalid reliability field \"%s\" ignored\n", r);
+			}
+			/* ...and process the commands contained in the message */
+			while (mbus_parse_sym(mp, &cmd)) {
+				if (mbus_parse_lst(mp, &param)) {
+					char 		*newsrc = (char *) xmalloc(strlen(src) + 3);
+					sprintf(newsrc, "(%s)", src);	/* Yes, this is a kludge. */
+					/* Finally, we snoop on the message we just passed to the application, */
+					/* to do housekeeping of our list of known mbus sources...             */
+					if (strcmp(cmd, "mbus.bye") == 0) {
+						remove_other_addr(m, newsrc);
+					} 
+					if (strcmp(cmd, "mbus.hello") == 0) {
+						/* Mark this source as activ. We remove dead sources in mbus_heartbeat */
+						mark_activ_other_addr(m, newsrc);
+					}
+					m->cmd_handler(newsrc, cmd, param, data);
+					xfree(newsrc);
+				} else {
+					debug_msg("Unable to parse mbus command:\n");
+					debug_msg("cmd = %s\n", cmd);
+					debug_msg("arg = %s\n", param);
+					break;
+				}
+			}
+		}
+		mbus_parse_done(mp);
+	}
+	return rx;
+}
+
+#define RZ_HANDLE_WAITING 1
+#define RZ_HANDLE_GO      2
+
+struct mbus_rz {
+	char		*peer;
+	char		*token;
+	struct mbus	*m;
+	void		*data;
+	int		 mode;
+	void (*cmd_handler)(char *src, char *cmd, char *args, void *data);
+};
+
+static void rz_handler(char *src, char *cmd, char *args, void *data)
+{
+	struct mbus_rz		*r = (struct mbus_rz *) data;
+	struct mbus_parser	*mp;
+
+	if ((r->mode == RZ_HANDLE_WAITING) && (strcmp(cmd, "mbus.waiting") == 0)) {
+		char	*t;
+
+		mp = mbus_parse_init(args);
+		mbus_parse_str(mp, &t);
+		if (strcmp(mbus_decode_str(t), r->token) == 0) {
+                        if (r->peer != NULL) xfree(r->peer);
+			r->peer = xstrdup(src);
+		}
+		mbus_parse_done(mp);
+	} else if ((r->mode == RZ_HANDLE_GO) && (strcmp(cmd, "mbus.go") == 0)) {
+		char	*t;
+
+		mp = mbus_parse_init(args);
+		mbus_parse_str(mp, &t);
+		if (strcmp(mbus_decode_str(t), r->token) == 0) {
+                        if (r->peer != NULL) xfree(r->peer);
+			r->peer = xstrdup(src);
+		}
+		mbus_parse_done(mp);
+	} else {
+		r->cmd_handler(src, cmd, args, r->data);
+	}
+}
+
+char *mbus_rendezvous_waiting(struct mbus *m, char *addr, char *token, void *data)
+{
+	/* Loop, sending mbus.waiting(token) to "addr", until we get mbus.go(token) */
+	/* back from our peer. Any other mbus commands received whilst waiting are  */
+	/* processed in the normal manner, as if mbus_recv() had been called.       */
+	char		*token_e, *peer;
+	struct timeval	 timeout;
+	struct mbus_rz	*r;
+
+	mbus_validate(m);
+
+	r = (struct mbus_rz *) xmalloc(sizeof(struct mbus_rz));
+	r->peer        = NULL;
+	r->token       = token;
+	r->m           = m;
+	r->data        = data;
+	r->mode        = RZ_HANDLE_GO;
+	r->cmd_handler = m->cmd_handler;
+	m->cmd_handler = rz_handler;
+	token_e        = mbus_encode_str(token);
+	while (r->peer == NULL) {
+		timeout.tv_sec  = 0;
+		timeout.tv_usec = 100000;
+		mbus_heartbeat(m, 1);
+		mbus_qmsgf(m, addr, FALSE, "mbus.waiting", "%s", token_e);
+		mbus_send(m);
+		mbus_recv(m, r, &timeout);
+		mbus_retransmit(m);
+	}
+	m->cmd_handler = r->cmd_handler;
+	peer = r->peer;
+	xfree(r);
+	xfree(token_e);
+	return peer;
+}
+
+char *mbus_rendezvous_go(struct mbus *m, char *token, void *data)
+{
+	/* Wait until we receive mbus.waiting(token), then send mbus.go(token) back to   */
+	/* the sender of that message. Whilst waiting, other mbus commands are processed */
+	/* in the normal manner as if mbus_recv() had been called.                       */
+	char		*token_e, *peer;
+	struct timeval	 timeout;
+	struct mbus_rz	*r;
+
+	mbus_validate(m);
+
+	r = (struct mbus_rz *) xmalloc(sizeof(struct mbus_rz));
+	r->peer        = NULL;
+	r->token       = token;
+	r->m           = m;
+	r->data        = data;
+	r->mode        = RZ_HANDLE_WAITING;
+	r->cmd_handler = m->cmd_handler;
+	m->cmd_handler = rz_handler;
+	token_e        = mbus_encode_str(token);
+	while (r->peer == NULL) {
+		timeout.tv_sec  = 0;
+		timeout.tv_usec = 100000;
+		mbus_heartbeat(m, 1);
+		mbus_send(m);
+		mbus_recv(m, r, &timeout);
+		mbus_retransmit(m);
+	}
+
+	mbus_qmsgf(m, r->peer, TRUE, "mbus.go", "%s", token_e);
+	do {
+		mbus_heartbeat(m, 1);
+		mbus_retransmit(m);
+		mbus_send(m);
+		timeout.tv_sec  = 0;
+		timeout.tv_usec = 100000;
+		mbus_recv(m, r, &timeout);
+	} while (!mbus_sent_all(m));
+
+	m->cmd_handler = r->cmd_handler;
+	peer = r->peer;
+	xfree(r);
+	xfree(token_e);
+	return peer;
+}
+
Index: /common/tags/common_1_1_2/src/btree.h
===================================================================
--- /common/tags/common_1_1_2/src/btree.h (revision 314)
+++ /common/tags/common_1_1_2/src/btree.h (revision 314)
@@ -0,0 +1,63 @@
+/*
+ * FILE:    btree.h
+ * PROGRAM: RAT
+ * AUTHOR:  O.Hodson
+ * 
+ * Binary tree implementation - Mostly verbatim from:
+ *
+ * Introduction to Algorithms by Corman, Leisserson, and Rivest,
+ * MIT Press / McGraw Hill, 1990.
+ *
+ * Implementation assumes one data element per key is assigned.
+ *
+ * Thanks to Markus Geimeier <mager@tzi.de> for pointing out want
+ * btree_get_min_key and not btree_get_root_key for start point for tree
+ * iteration.
+ * 
+ */
+
+#ifndef __BTREE_H__
+#define __BTREE_H__
+
+typedef struct s_btree btree_t;
+
+/* btree_create fills the *tree with a new binary tree.  Returns TRUE on     */
+/* success and FALSE on failure.                                             */
+
+int  btree_create  (btree_t **tree);
+
+/* btree_destroy destroys tree.  If tree is not empty it cannot be destroyed */
+/* and call returns FALSE.  On success returns TRUE.                         */
+
+int btree_destroy (btree_t **tree);
+ 
+/* btree_add adds data for key to tree.  Returns TRUE on success, or FALSE   */
+/* if key is already on tree.  */
+
+int btree_add    (btree_t *tree, uint32_t key, void *data);
+
+/* btree_remove attempts to remove data from tree.  Returns TRUE on success  */
+/* and points *d at value stored for key.  FALSE is returned if key is not   */
+/* on tree.                                                                  */
+
+int btree_remove (btree_t *tree, uint32_t key, void **d);
+
+/* btree_find locates data for key and make *d point to it.  Returns TRUE if */
+/* data for key is found, FALSE otherwise.                                   */
+
+int btree_find   (btree_t *tree, uint32_t key, void **d);
+
+/* btree_get_min_key attempts to return minimum key of tree.  Function       */
+/* intended to help if list of keys is not stored elsewhere.  Returns TRUE   */
+/* and fills key with key if possible, FALSE otherwise                       */
+
+int btree_get_min_key (btree_t *tree, uint32_t *key);
+int btree_get_max_key (btree_t *tree, uint32_t *key);
+
+/* btree_get_next_key attempts to get the key above cur_key.  Returns        */
+/* TRUE and fills key with key if possible, FALSE otherwise.                 */
+
+int btree_get_next_key (btree_t *tree, uint32_t cur_key, uint32_t *next_key);
+
+#endif /* __BTREE_H__ */
+
Index: /common/tags/common_1_1_2/src/asarray.h
===================================================================
--- /common/tags/common_1_1_2/src/asarray.h (revision 424)
+++ /common/tags/common_1_1_2/src/asarray.h (revision 424)
@@ -0,0 +1,48 @@
+/*
+ * FILE:    asarray.h
+ * AUTHORS: Orion Hodson 
+ *
+ * Associative array for strings.  Perloined from RAT settings code.
+ *
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * $Id$
+ */
+
+#ifndef __AS_ARRAY_H
+#define __AS_ARRAY_H
+
+typedef struct _asarray asarray;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Associative array for strings only.  Makes own internal copies of
+ * keys and values.
+ *
+ * Functions that return use TRUE for success and FALSE for failure.
+ * Double pointers in arguments are filled in by the function being 
+ * called.
+ */
+
+int32_t     asarray_create  (asarray **ppa);
+void        asarray_destroy (asarray **ppa);
+
+int32_t     asarray_add    (asarray *pa, const char *key, const char *value);
+void        asarray_remove (asarray *pa, const char *key);
+int32_t     asarray_lookup (asarray *pa, const char *key, char **value);
+
+/* asarray_get_key - gets key corresponding to index'th entry in
+ * internal representation, has not relation to order <key,value>
+ * tuples added in.  This function exists to provide easy way to drain
+ * array one item at a time. 
+ */
+const char* asarray_get_key_no(asarray *pa, int32_t index);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __AS_ARRAY_H */
Index: /common/tags/common_1_1_2/src/hmac.c
===================================================================
--- /common/tags/common_1_1_2/src/hmac.c (revision 360)
+++ /common/tags/common_1_1_2/src/hmac.c (revision 360)
@@ -0,0 +1,147 @@
+/*
+ * FILE:    hmac.c
+ * AUTHORS: Colin Perkins
+ *
+ * HMAC message authentication (RFC2104)
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "md5.h"
+#include "hmac.h"
+
+void hmac_md5(unsigned char   *data,	   /* pointer to data stream        */
+	      int              data_len,   /* length of data stream         */
+	      unsigned char   *key, 	   /* pointer to authentication key */
+	      int              key_len,	   /* length of authentication key  */
+	      unsigned char    digest[16]) /* caller digest to be filled in */
+{
+        MD5_CTX       context;
+        unsigned char k_ipad[65];    /* inner padding - key XORd with ipad */
+        unsigned char k_opad[65];    /* outer padding - key XORd with opad */
+        unsigned char tk[16];
+        int           i;
+
+        /* If key is longer than 64 bytes reset it to key=MD5(key) */
+        if (key_len > 64) {
+                MD5_CTX      tctx;
+
+                MD5Init(&tctx);
+                MD5Update(&tctx, key, key_len);
+                MD5Final(tk, &tctx);
+
+                key     = tk;
+                key_len = 16;
+        }
+
+        /*
+         * The HMAC_MD5 transform looks like:
+         *
+         * MD5(K XOR opad, MD5(K XOR ipad, data))
+         *
+         * where K is an n byte key
+         * ipad is the byte 0x36 repeated 64 times
+         * opad is the byte 0x5c repeated 64 times
+         * and text is the data being protected
+         */
+
+        /* Start out by storing key in pads */
+        memset(k_ipad, 0, sizeof(k_ipad));
+        memset(k_opad, 0, sizeof(k_opad));
+        memcpy(k_ipad, key, key_len);
+        memcpy(k_opad, key, key_len);
+
+        /* XOR key with ipad and opad values */
+        for (i=0; i<64; i++) {
+                k_ipad[i] ^= 0x36;
+                k_opad[i] ^= 0x5c;
+        }
+        /*
+         * perform inner MD5
+         */
+        MD5Init(&context);                   /* init context for 1st pass */
+        MD5Update(&context, k_ipad, 64);     /* start with inner pad      */
+        MD5Update(&context, data, data_len); /* then text of datagram     */
+        MD5Final(digest, &context);          /* finish up 1st pass        */
+        /*
+         * perform outer MD5
+         */
+        MD5Init(&context);                   /* init context for 2nd pass */
+        MD5Update(&context, k_opad, 64);     /* start with outer pad      */
+        MD5Update(&context, digest, 16);     /* then results of 1st hash  */
+        MD5Final(digest, &context);          /* finish up 2nd pass        */
+}
+
+/*
+ * Test Vectors (Trailing '\0' of a character string not included in test):
+ * 
+ * key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+ * key_len =     16 bytes
+ * data =        "Hi There"
+ * data_len =    8  bytes
+ * digest =      0x9294727a3638bb1c13f48ef8158bfc9d
+ *
+ * key =         "Jefe"
+ * data =        "what do ya want for nothing?"
+ * data_len =    28 bytes
+ * digest =      0x750c783e6ab0b503eaa86e310a5db738
+ *
+ * key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ * key_len       16 bytes
+ * data =        0xDDDDDDDDDDDDDDDDDDDD...
+ *               ..DDDDDDDDDDDDDDDDDDDD...
+ *               ..DDDDDDDDDDDDDDDDDDDD...
+ *               ..DDDDDDDDDDDDDDDDDDDD...
+ *               ..DDDDDDDDDDDDDDDDDDDD
+ * data_len =    50 bytes
+ * digest =      0x56be34521d144c88dbb8c733f0e8b3f6
+ */
+
+#ifdef TEST_HMAC
+int main()
+{
+	unsigned char	*key  = "Jefe";
+	unsigned char	*data = "what do ya want for nothing?";
+	unsigned char	 digest[16];
+	int		 i;
+
+	hmac_md5(data, 28, key, 4, digest);
+	for (i = 0; i < 16; i++) {
+		printf("%02x", digest[i]);
+	}
+	printf("\n");
+
+	return 0;
+}
+#endif
+
Index: /common/tags/common_1_1_2/src/drand48.h
===================================================================
--- /common/tags/common_1_1_2/src/drand48.h (revision 212)
+++ /common/tags/common_1_1_2/src/drand48.h (revision 212)
@@ -0,0 +1,4 @@
+
+#ifdef NEED_DRAND48
+double drand48(void);
+#endif
Index: /common/tags/common_1_1_2/src/mbus.h
===================================================================
--- /common/tags/common_1_1_2/src/mbus.h (revision 428)
+++ /common/tags/common_1_1_2/src/mbus.h (revision 428)
@@ -0,0 +1,71 @@
+/*
+ * FILE:    mbus.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1997-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted, provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MBUS_H
+#define _MBUS_H
+
+/* Error codes... */
+#define MBUS_MESSAGE_LOST           1
+#define MBUS_DESTINATION_UNKNOWN    2
+#define MBUS_DESTINATION_NOT_UNIQUE 3
+
+struct mbus;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct mbus *mbus_init(void  (*cmd_handler)(char *src, char *cmd, char *arg, void *dat), 
+		       void  (*err_handler)(int seqnum, int reason),
+		       char  *addr);
+void         mbus_cmd_handler(struct mbus *m, void  (*cmd_handler)(char *src, char *cmd, char *arg, void *dat));
+void         mbus_exit(struct mbus *m);
+int          mbus_addr_valid(struct mbus *m, char *addr);
+void         mbus_qmsg(struct mbus *m, const char *dest, const char *cmnd, const char *args, int reliable);
+void         mbus_qmsgf(struct mbus *m, const char *dest, int reliable, const char *cmnd, const char *format, ...);
+void         mbus_send(struct mbus *m);
+int          mbus_recv(struct mbus *m, void *data, struct timeval *timeout);
+void         mbus_retransmit(struct mbus *m);
+void         mbus_heartbeat(struct mbus *m, int interval);
+int          mbus_waiting_ack(struct mbus *m);
+int          mbus_sent_all(struct mbus *m);
+char        *mbus_rendezvous_waiting(struct mbus *m, char *addr, char *token, void *data);
+char        *mbus_rendezvous_go(struct mbus *m, char *token, void *data);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
Index: /common/tags/common_1_1_2/src/util.c
===================================================================
--- /common/tags/common_1_1_2/src/util.c (revision 360)
+++ /common/tags/common_1_1_2/src/util.c (revision 360)
@@ -0,0 +1,304 @@
+/*
+ * FILE: util.c
+ * PROGRAM: RAT
+ * AUTHOR: Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson
+ * 
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "util.h"
+
+typedef struct s_block {
+	struct s_block  *next;
+} block;
+ 
+#define BLOCK_SIZE            5
+#define SIZE_TO_INDEX(s)      (((s) - 1) >> BLOCK_SIZE)
+#define INDEX_TO_SIZE(i)      (((i) + 1) << BLOCK_SIZE)
+#define MAX_SIZE              (1 << 17)
+#define MAX_INDEX             SIZE_TO_INDEX(MAX_SIZE)
+ 
+static block  *blocks[MAX_INDEX];
+static int     blocks_alloced;
+
+#ifdef DEBUG_MEM
+
+/* Block tracking for when things are going wrong */
+
+#define MAX_BLOCKS_OUT 1280
+static struct iovec blk_out[MAX_BLOCKS_OUT];
+static int          nblks_out;
+
+static int
+get_blk_idx_from_ptr(char *addr)
+{
+        int i;
+        for(i = 0; i < nblks_out; i++) {
+                if (blk_out[i].iov_base == addr) {
+                        return i;
+                }
+        }
+        return -1;
+}
+#endif /* DEBUG_MEM */
+ 
+void *
+_block_alloc(unsigned int size, const char *filen, int line)
+{
+	int         	 i;
+	unsigned int 	*c;
+	char        	*p;
+
+	assert(size > 0);
+	assert(size < MAX_SIZE);
+
+	i = SIZE_TO_INDEX(size);
+ 
+	if (blocks[i] != NULL) {
+		p = (char *)blocks[i];
+		blocks[i] = blocks[i]->next;
+                xclaim((char*)p - 8, filen, line);
+	} else {
+#ifdef DEBUG_MEM_BREAK
+                /* This can only go here if this file is merged with memory.c! [oh] */
+                mem_item[naddr].blen = size;
+#endif /* DEBUG_MEM_BREAK */
+		p = (char *) _xmalloc(INDEX_TO_SIZE(i) + 8,filen,line);
+		*((int *)p) = INDEX_TO_SIZE(i);
+		p += 8;
+                blocks_alloced++;
+	}
+	c = (unsigned int *)((char *)p - 8);
+	if (size > *c) {
+		fprintf(stderr, "block_alloc: block is too small %d %d!\n", size, *c);
+	}
+#ifdef DEBUG_MEM
+        if (blocks_alloced == MAX_BLOCKS_OUT) {
+                debug_msg("Too many blocks allocated.\n");
+                xmemdist(stderr);
+                xmemdmp();
+        }
+
+        blk_out[nblks_out].iov_base = (char*)c;
+        blk_out[nblks_out].iov_len  = size;
+        nblks_out++;
+#endif /* DEBUG_MEM */
+	c++;
+	*c = size;
+	assert(p != NULL);
+	return (void*)p;
+}
+
+void
+block_trash_check()
+{
+#ifdef DEBUG_MEM
+        int i,n,*c;
+        block *b;
+
+        for(i = 0; i<MAX_INDEX;i++) {
+                b = blocks[i];
+                n = 0;
+                while(b) {
+                        b = b->next;
+                        assert(n++ < blocks_alloced);
+                }
+        }
+        for (i = 0; i<nblks_out; i++) {
+                c = (int*)blk_out[i].iov_base;
+                c++;
+                assert((unsigned int)*c == (unsigned int)blk_out[i].iov_len);
+        }
+#endif  /* DEBUG_MEM */
+}
+
+void
+block_check(char *p)
+{
+#ifdef DEBUG_MEM
+        char *blk_base;
+        assert(p!=NULL);
+        blk_base = p-8;
+        assert(get_blk_idx_from_ptr(blk_base) != -1);
+#endif /* DEBUG_MEM */
+        UNUSED(p);
+}
+ 
+void
+_block_free(void *p, int size, int line)
+{
+	int     i, *c;
+#ifdef DEBUG_MEM
+        block *bp;
+        int    n;
+#endif /* DEBUG_MEM */
+        UNUSED(line);
+
+	c = (int *)((char *)p - 8);
+
+#ifdef DEBUG_MEM
+        n = get_blk_idx_from_ptr((char*)c);
+        if (n == -1) {
+                debug_msg("Freeing block (addr 0x%x, %d bytes) that was not allocated with block_alloc(?)\n", (int)c, *(c+1));
+                xfree(c);
+                assert(n != -1);
+        }
+#endif
+
+	if (size > *c) {
+		fprintf(stderr, "block_free: block was too small! %d %d\n", size, *c);
+	}
+	c++;
+	if (size != *c) {
+		fprintf(stderr, "block_free: Incorrect block size given! %d %d\n", size, *c);
+		assert(size == *c);
+	}
+ 
+	i = SIZE_TO_INDEX(size);
+#ifdef DEBUG_MEM
+        bp = blocks[i];
+        n = 0;
+        while(bp) {
+                if (bp == (block*)p) {
+                        debug_msg("already freed line %d\n", *((int *)p+1));
+                        assert(0);
+                }
+                bp = bp->next;
+                n++;
+        }
+        if (i >= 4) {
+                *((int*)p+1) = line;
+        }
+#endif /* DEBUG_MEM */
+	((block *)p)->next = blocks[i];
+	blocks[i] = (block *)p;
+#ifdef DEBUG_MEM
+        c--;
+        i = get_blk_idx_from_ptr((char*)c);
+        assert(i != -1);
+        memmove(blk_out+i, blk_out + i + 1, sizeof(struct iovec) * (nblks_out - i)); 
+        nblks_out --;
+#endif /* DEBUG_MEM */
+}
+
+void
+block_release_all(void)
+{
+    int i;
+    char *p,*q;
+
+    printf("Freeing memory: "); fflush(stdout);
+    for(i=0;i<MAX_INDEX;i++) {
+        p = (char*)blocks[i];
+        while(p) {
+            q = (char*)((block*)p)->next;
+            xfree(p-8);
+	    printf("+"); fflush(stdout);
+            p = q;
+        }
+    }
+    printf("\n");
+}
+
+void
+purge_chars(char *src, char *to_go)
+{
+        char *r, *w;
+        r = w = src;
+        while(*r) {
+                *w = *r;
+                if (!strchr(to_go, (int)*r)) {
+                        w++;
+                }
+                r++;
+        }
+        *w = '\0';
+}
+
+static int
+string_to_words(char *s, char**w, int max_words)
+{
+        int n;
+
+        n = 0;
+        w[0] = (char *) strtok(s, " ");
+        if (w[0] == NULL) {
+                return n;
+        }
+
+        while(++n < max_words) {
+                w[n] = (char *) strtok(NULL, " ");
+                if (w[n] == NULL) break;
+        }
+        return n;
+}
+
+int
+overlapping_words(const char *s1, const char *s2, int max_words)
+{
+        char *c1, *c2, **w1, **w2;
+        int nw1, nw2, nover, i, j;
+
+        c1 = xstrdup(s1);
+        c2 = xstrdup(s2);
+
+        w1 = (char**)xmalloc(sizeof(char*)*max_words);
+        w2 = (char**)xmalloc(sizeof(char*)*max_words);
+
+        nw1 = string_to_words(c1, w1, max_words);
+        nw2 = string_to_words(c2, w2, max_words);
+
+        nover = 0;
+        for(i = 0; i < nw1; i++) {
+                for(j = 0; j < nw2; j++) {
+                        if (strcmp(w1[i], w2[j]) == 0) {
+                                nover++;
+                                continue;
+                        }
+                }
+        }
+
+        xfree(w1);
+        xfree(w2);
+        xfree(c1);
+        xfree(c2);
+        
+        return nover;
+}
+
+
Index: /common/tags/common_1_1_2/src/README.qfdes
===================================================================
--- /common/tags/common_1_1_2/src/README.qfdes (revision 128)
+++ /common/tags/common_1_1_2/src/README.qfdes (revision 128)
@@ -0,0 +1,122 @@
+The qfDES code is derived from Saleem Bhatti's code, but has been significantly
+revised, debugged and updated. The following is the original README, followed
+by some other information which may be useful, taken from Eric Young's libdes.
+
+===============================================================================
+This is yet another implementation of DES in software, for those of us that
+don't have access to DES hardware. The library is fairly (but not quite)
+complete, as are the two progs, qf-des and qf-key. However, debugging and
+testing is still proceeding ...
+
+Quickie Roadmap
+---------------
+
+qf-des: Do DES on files (qf-des.c)
+qf-key: Generate keys and IVs (qf-key.c)
+
+libqfDES.a: library of DES stuff
+
+qfDES.h: Interface file for libqfDES.a
+qfDES.c: The DES function
+
+qfDES-print.c: For generating some of the DES macros and S-Box/P transforms
+
+qfDES-key.c: Key and IV generation
+
+qfDES-memory.c: Fiddling around with memory
+
+Disclaimer
+----------
+This version of the qfDES is for me only, so if you have it and are not me,
+then I take no responsibility for what happens when you use it!
+
+TTFN,
+--/Saleem
+
+===============================================================================
+
+Modes of DES
+Quite a bit of the following information has been taken from
+	AS 2805.5.2
+	Australian Standard
+	Electronic funds transfer - Requirements for interfaces,
+	Part 5.2: Modes of operation for an n-bit block cipher algorithm
+	Appendix A
+
+There are several different modes in which DES can be used, they are
+as follows.
+
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
+- 64 bits are enciphered at a time.
+- The order of the blocks can be rearranged without detection.
+- The same plaintext block always produces the same ciphertext block
+  (for the same key) making it vulnerable to a 'dictionary attack'.
+- An error will only affect one ciphertext block.
+
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
+- a multiple of 64 bits are enciphered at a time.
+- The CBC mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext blocks dependent on the
+  current and all preceding plaintext blocks and therefore blocks can not
+  be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- An error will affect the current and the following ciphertext blocks.
+
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The CFB mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext variables dependent on the
+  current and all preceding variables and therefore j-bit variables are
+  chained together and con not be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- The strength of the CFB mode depends on the size of k (maximal if
+  j == k).  In my implementation this is always the case.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- An error will affect the current and the following ciphertext variables.
+
+Output Feedback Mode (OFB) (des_ofb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The OFB mode produces the same ciphertext whenever the same
+  plaintext enciphered using the same key and starting variable.  More
+  over, in the OFB mode the same key stream is produced when the same
+  key and start variable are used.  Consequently, for security reasons
+  a specific start variable should be used only once for a given key.
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
+- The use of different start variables values prevents the same
+  plaintext enciphering to the same ciphertext, by producing different
+  key streams.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- OFB mode of operation does not extend ciphertext errors in the
+  resultant plaintext output.  Every bit error in the ciphertext causes
+  only one bit to be in error in the deciphered plaintext.
+- OFB mode is not self-synchronising.  If the two operation of
+  encipherment and decipherment get out of synchronism, the system needs
+  to be re-initialised.
+- Each re-initialisation should use a value of the start variable
+different from the start variable values used before with the same
+key.  The reason for this is that an identical bit stream would be
+produced each time from the same parameters.  This would be
+susceptible to a ' known plaintext' attack.
+
+Triple ECB Mode (des_3ecb_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key1 again.
+- As for ECB encryption but increases the effective key length to 112 bits.
+- If both keys are the same it is equivalent to encrypting once with
+  just one key.
+
+Triple CBC Mode (des_3cbc_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key1 again.
+- As for CBC encryption but increases the effective key length to 112 bits.
+- If both keys are the same it is equivalent to encrypting once with
+  just one key.
+===============================================================================
Index: /common/tags/common_1_1_2/src/hmac.h
===================================================================
--- /common/tags/common_1_1_2/src/hmac.h (revision 360)
+++ /common/tags/common_1_1_2/src/hmac.h (revision 360)
@@ -0,0 +1,41 @@
+/*
+ * FILE:    hmac.h
+ * AUTHORS: Colin Perkins
+ *
+ * HMAC message authentication (RFC2104)
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+void hmac_md5(unsigned char *data, int data_len, 
+              unsigned char *key,  int key_len,
+	      unsigned char  digest[16]);
+
Index: /common/tags/common_1_1_2/src/gettimeofday.c
===================================================================
--- /common/tags/common_1_1_2/src/gettimeofday.c (revision 214)
+++ /common/tags/common_1_1_2/src/gettimeofday.c (revision 214)
@@ -0,0 +1,17 @@
+#include "config_unix.h"
+#include "config_win32.h"
+#include "gettimeofday.h"
+
+#if defined(NEED_GETTIMEOFDAY) && defined(WIN32)
+
+int gettimeofday(struct timeval *tp, void *tz)
+{
+	struct _timeb timebuffer;   
+
+	_ftime( &timebuffer );
+	tp->tv_sec  = timebuffer.time;
+	tp->tv_usec = timebuffer.millitm * 1000;
+	return 0;
+}
+
+#endif
Index: /common/tags/common_1_1_2/src/util.h
===================================================================
--- /common/tags/common_1_1_2/src/util.h (revision 360)
+++ /common/tags/common_1_1_2/src/util.h (revision 360)
@@ -0,0 +1,66 @@
+/*
+ * FILE:    util.h
+ * PROGRAM: RAT
+ * AUTHOR:  Isidor Kouvelas + Colin Perkins + Orion Hodson
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define block_alloc(x)	_block_alloc(x,__FILE__,__LINE__)
+#define block_free(x,y) _block_free(x,y,__LINE__)
+
+void	*_block_alloc(unsigned size, const char *filen, int line);
+void	 _block_free(void *p, int size, int line);
+void	 block_release_all(void);
+void     block_trash_check(void);
+void     block_check(char *p);
+
+/* purge_chars: removes occurances of chars in to_go from src */
+void purge_chars(char *src, char *to_go); 
+
+/* overlapping_words: returns how many words match in two strings */
+int overlapping_words(const char *s1, const char *s2, int max_words);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif 
Index: /common/tags/common_1_1_2/src/md5.c
===================================================================
--- /common/tags/common_1_1_2/src/md5.c (revision 314)
+++ /common/tags/common_1_1_2/src/md5.c (revision 314)
@@ -0,0 +1,304 @@
+/*
+ * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/*
+ * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights
+ * reserved.
+ * 
+ * License to copy and use this software is granted provided that it is
+ * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
+ * in all material mentioning or referencing this software or this function.
+ * 
+ * License is also granted to make and use derivative works provided that such
+ * works are identified as "derived from the RSA Data Security, Inc. MD5
+ * Message-Digest Algorithm" in all material mentioning or referencing the
+ * derived work.
+ * 
+ * RSA Data Security, Inc. makes no representations concerning either the
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ * 
+ * These notices must be retained in any copies of any part of this
+ * documentation and/or software.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "md5.h"
+
+/*
+ * Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static unsigned char PADDING[64] = {
+	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/*
+ * ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/*
+ * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is
+ * separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/*
+ * Encodes input (uint32_t) into output (unsigned char). Assumes len is a
+ * multiple of 4.
+ */
+static void 
+Encode(unsigned char *output, uint32_t * input, unsigned int len)
+{
+	unsigned int    i, j;
+
+	assert((len % 4) == 0);
+
+	for (i = 0, j = 0; j < len; i++, j += 4) {
+		output[j] = (unsigned char) (input[i] & 0xff);
+		output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
+		output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
+		output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
+	}
+}
+
+/*
+ * Decodes input (unsigned char) into output (uint32_t). Assumes len is a
+ * multiple of 4.
+ */
+static void 
+Decode(uint32_t * output, unsigned char *input, unsigned int len)
+{
+	unsigned int    i, j;
+
+	for (i = 0, j = 0; j < len; i++, j += 4)
+		output[i] = ((uint32_t) input[j]) | (((uint32_t) input[j + 1]) << 8) |
+			(((uint32_t) input[j + 2]) << 16) | (((uint32_t) input[j + 3]) << 24);
+}
+
+/*
+ * MD5 basic transformation. Transforms state based on block.
+ */
+static void 
+MD5Transform(uint32_t state[4], unsigned char block[64])
+{
+	uint32_t           a = state[0], b = state[1], c = state[2], d = state[3],
+	                x[16];
+
+	Decode(x, block, 64);
+
+	/* Round 1 */
+	FF(a, b, c, d, x[0], S11, 0xd76aa478);	/* 1 */
+	FF(d, a, b, c, x[1], S12, 0xe8c7b756);	/* 2 */
+	FF(c, d, a, b, x[2], S13, 0x242070db);	/* 3 */
+	FF(b, c, d, a, x[3], S14, 0xc1bdceee);	/* 4 */
+	FF(a, b, c, d, x[4], S11, 0xf57c0faf);	/* 5 */
+	FF(d, a, b, c, x[5], S12, 0x4787c62a);	/* 6 */
+	FF(c, d, a, b, x[6], S13, 0xa8304613);	/* 7 */
+	FF(b, c, d, a, x[7], S14, 0xfd469501);	/* 8 */
+	FF(a, b, c, d, x[8], S11, 0x698098d8);	/* 9 */
+	FF(d, a, b, c, x[9], S12, 0x8b44f7af);	/* 10 */
+	FF(c, d, a, b, x[10], S13, 0xffff5bb1);	/* 11 */
+	FF(b, c, d, a, x[11], S14, 0x895cd7be);	/* 12 */
+	FF(a, b, c, d, x[12], S11, 0x6b901122);	/* 13 */
+	FF(d, a, b, c, x[13], S12, 0xfd987193);	/* 14 */
+	FF(c, d, a, b, x[14], S13, 0xa679438e);	/* 15 */
+	FF(b, c, d, a, x[15], S14, 0x49b40821);	/* 16 */
+
+	/* Round 2 */
+	GG(a, b, c, d, x[1], S21, 0xf61e2562);	/* 17 */
+	GG(d, a, b, c, x[6], S22, 0xc040b340);	/* 18 */
+	GG(c, d, a, b, x[11], S23, 0x265e5a51);	/* 19 */
+	GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);	/* 20 */
+	GG(a, b, c, d, x[5], S21, 0xd62f105d);	/* 21 */
+	GG(d, a, b, c, x[10], S22, 0x2441453);	/* 22 */
+	GG(c, d, a, b, x[15], S23, 0xd8a1e681);	/* 23 */
+	GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);	/* 24 */
+	GG(a, b, c, d, x[9], S21, 0x21e1cde6);	/* 25 */
+	GG(d, a, b, c, x[14], S22, 0xc33707d6);	/* 26 */
+	GG(c, d, a, b, x[3], S23, 0xf4d50d87);	/* 27 */
+	GG(b, c, d, a, x[8], S24, 0x455a14ed);	/* 28 */
+	GG(a, b, c, d, x[13], S21, 0xa9e3e905);	/* 29 */
+	GG(d, a, b, c, x[2], S22, 0xfcefa3f8);	/* 30 */
+	GG(c, d, a, b, x[7], S23, 0x676f02d9);	/* 31 */
+	GG(b, c, d, a, x[12], S24, 0x8d2a4c8a);	/* 32 */
+
+	/* Round 3 */
+	HH(a, b, c, d, x[5], S31, 0xfffa3942);	/* 33 */
+	HH(d, a, b, c, x[8], S32, 0x8771f681);	/* 34 */
+	HH(c, d, a, b, x[11], S33, 0x6d9d6122);	/* 35 */
+	HH(b, c, d, a, x[14], S34, 0xfde5380c);	/* 36 */
+	HH(a, b, c, d, x[1], S31, 0xa4beea44);	/* 37 */
+	HH(d, a, b, c, x[4], S32, 0x4bdecfa9);	/* 38 */
+	HH(c, d, a, b, x[7], S33, 0xf6bb4b60);	/* 39 */
+	HH(b, c, d, a, x[10], S34, 0xbebfbc70);	/* 40 */
+	HH(a, b, c, d, x[13], S31, 0x289b7ec6);	/* 41 */
+	HH(d, a, b, c, x[0], S32, 0xeaa127fa);	/* 42 */
+	HH(c, d, a, b, x[3], S33, 0xd4ef3085);	/* 43 */
+	HH(b, c, d, a, x[6], S34, 0x4881d05);	/* 44 */
+	HH(a, b, c, d, x[9], S31, 0xd9d4d039);	/* 45 */
+	HH(d, a, b, c, x[12], S32, 0xe6db99e5);	/* 46 */
+	HH(c, d, a, b, x[15], S33, 0x1fa27cf8);	/* 47 */
+	HH(b, c, d, a, x[2], S34, 0xc4ac5665);	/* 48 */
+
+	/* Round 4 */
+	II(a, b, c, d, x[0], S41, 0xf4292244);	/* 49 */
+	II(d, a, b, c, x[7], S42, 0x432aff97);	/* 50 */
+	II(c, d, a, b, x[14], S43, 0xab9423a7);	/* 51 */
+	II(b, c, d, a, x[5], S44, 0xfc93a039);	/* 52 */
+	II(a, b, c, d, x[12], S41, 0x655b59c3);	/* 53 */
+	II(d, a, b, c, x[3], S42, 0x8f0ccc92);	/* 54 */
+	II(c, d, a, b, x[10], S43, 0xffeff47d);	/* 55 */
+	II(b, c, d, a, x[1], S44, 0x85845dd1);	/* 56 */
+	II(a, b, c, d, x[8], S41, 0x6fa87e4f);	/* 57 */
+	II(d, a, b, c, x[15], S42, 0xfe2ce6e0);	/* 58 */
+	II(c, d, a, b, x[6], S43, 0xa3014314);	/* 59 */
+	II(b, c, d, a, x[13], S44, 0x4e0811a1);	/* 60 */
+	II(a, b, c, d, x[4], S41, 0xf7537e82);	/* 61 */
+	II(d, a, b, c, x[11], S42, 0xbd3af235);	/* 62 */
+	II(c, d, a, b, x[2], S43, 0x2ad7d2bb);	/* 63 */
+	II(b, c, d, a, x[9], S44, 0xeb86d391);	/* 64 */
+
+	state[0] += a;
+	state[1] += b;
+	state[2] += c;
+	state[3] += d;
+
+	/*
+	 * Zeroize sensitive information.
+	 */
+	memset((unsigned char *) x, 0, sizeof(x));
+}
+
+/*
+ * MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void 
+MD5Init(MD5_CTX * context)
+{
+	context->count[0] = context->count[1] = 0;
+	/* Load magic initialization constants.  */
+	context->state[0] = 0x67452301;
+	context->state[1] = 0xefcdab89;
+	context->state[2] = 0x98badcfe;
+	context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest operation,
+ * processing another message block, and updating the context.
+ */
+void 
+MD5Update(MD5_CTX * context, unsigned char *input, unsigned int inputLen)
+{
+	unsigned int    i, index, partLen;
+
+	/* Compute number of bytes mod 64 */
+	index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
+
+	/* Update number of bits */
+	if ((context->count[0] += ((uint32_t) inputLen << 3)) < ((uint32_t) inputLen << 3)) {
+		context->count[1]++;
+	}
+	context->count[1] += ((uint32_t) inputLen >> 29);
+
+	partLen = 64 - index;
+
+	/* Transform as many times as possible.  */
+	if (inputLen >= partLen) {
+		memcpy((unsigned char *) & context->buffer[index], (unsigned char *) input, partLen);
+		MD5Transform(context->state, context->buffer);
+
+		for (i = partLen; i + 63 < inputLen; i += 64) {
+			MD5Transform(context->state, &input[i]);
+		}
+		index = 0;
+	} else {
+		i = 0;
+	}
+	/* Buffer remaining input */
+	if ((inputLen - i) != 0) {
+		memcpy((unsigned char *) & context->buffer[index], (unsigned char *) & input[i], inputLen - i);
+	}
+}
+
+/*
+ * MD5 finalization. Ends an MD5 message-digest operation, writing the the
+ * message digest and zeroizing the context.
+ */
+void 
+MD5Final(unsigned char digest[16], MD5_CTX * context)
+{
+	unsigned char   bits[8];
+	unsigned int    index, padLen;
+
+	/* Save number of bits */
+	Encode(bits, context->count, 8);
+
+	/*
+	 * Pad out to 56 mod 64.
+	 */
+	index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
+	padLen = (index < 56) ? (56 - index) : (120 - index);
+	MD5Update(context, PADDING, padLen);
+
+	/* Append length (before padding) */
+	MD5Update(context, bits, 8);
+	/* Store state in digest */
+	Encode(digest, context->state, 16);
+
+	/*
+	 * Zeroize sensitive information.
+	 */
+	memset((unsigned char *) context, 0, sizeof(*context));
+}
+
Index: /common/tags/common_1_1_2/src/debug.c
===================================================================
--- /common/tags/common_1_1_2/src/debug.c (revision 413)
+++ /common/tags/common_1_1_2/src/debug.c (revision 413)
@@ -0,0 +1,177 @@
+/*
+ * FILE:    debug.c
+ * PROGRAM: RAT
+ * AUTHORS: Isidor Kouvelas 
+ *          Colin Perkins 
+ *          Mark Handley 
+ *          Orion Hodson
+ *          Jerry Isdale
+ * 
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+
+void _dprintf(const char *format, ...)
+{
+#ifdef DEBUG
+#ifdef WIN32
+        char msg[65535];
+        va_list ap;
+        
+        va_start(ap, format);
+	_vsnprintf(msg, 65535, format, ap);
+        va_end(ap);
+        OutputDebugString(msg);
+#else 
+        va_list ap;
+ 
+        va_start(ap, format);
+        vfprintf(stderr, format, ap);
+        va_end(ap);
+#endif /* WIN32 */
+#else
+        UNUSED (format);
+#endif /* DEBUG */
+}
+
+void debug_dump(void*lp, long len)
+{
+   char * p;
+   long i, j, start;
+   char Buff[80];
+   char stuffBuff[10];
+   char tmpBuf[10];
+  
+   _dprintf("Dump of %ld=%lx bytes\n",len, len);
+   start = 0L;
+   while (start < len)
+   {
+    /* start line with pointer position key */
+      p = (char*)lp + start;
+      sprintf(Buff,"%p: ",p);
+  
+    /* display each character as hex value */
+      for (i=start, j=0; j < 16; p++,i++, j++)
+      {
+         if (i < len)
+         {
+            sprintf(tmpBuf,"%X",((int)(*p) & 0xFF));
+  
+            if (strlen((char *)tmpBuf) < 2)
+            {
+               stuffBuff[0] = '0';
+               stuffBuff[1] = tmpBuf[0];
+               stuffBuff[2] = ' ';
+               stuffBuff[3] = '\0';
+            } else
+            {
+               stuffBuff[0] = tmpBuf[0];
+               stuffBuff[1] = tmpBuf[1];
+               stuffBuff[2] = ' ';
+               stuffBuff[3] = '\0';
+            }
+            strcat(Buff, stuffBuff);
+         } else
+            strcat(Buff," ");
+         if (j == 7) /* space between groups of 8 */
+            strcat(Buff," ");
+      }
+  
+    /* fill out incomplete lines */
+      for(;j<16;j++)
+      {
+         strcat(Buff,"   ");
+         if (j == 7)
+            strcat(Buff," ");
+      }
+      strcat(Buff,"  ");
+  
+    /* display each character as character value */
+      for (i=start,j=0,p=(char*)lp+start;
+         (i < len && j < 16); p++,i++, j++)
+      {
+         if ( ((*p) >= ' ') && ((*p) <= '~') )   /* test displayable */
+            sprintf(tmpBuf,"%c", *p);
+         else
+            sprintf(tmpBuf,"%c", '.');
+         strcat(Buff,tmpBuf);
+         if (j == 7)   /* space between groups of 8 */
+            strcat(Buff," ");
+      }
+      _dprintf("%s\n", Buff);
+      start = i;  /* next line starting byte */
+   }
+}
+
+void _debug_set_core_dir(const char *argv0)
+{
+#if defined(DEBUG) && !defined(WIN32)
+        struct stat s;
+        char coredir[64];
+        const char *appname;
+
+        appname = strrchr(argv0, '/');
+        if (appname == NULL) {
+                appname = argv0;
+        } else {
+                appname = appname + 1;
+        }
+
+        /* Should check length of appname, but this is debug code   */
+        /* and developers should know better than to have 64 char   */
+        /* app name.                                                */
+        sprintf(coredir, "core-%s", appname);
+
+        mkdir(coredir, S_IRWXU);
+        if (stat(coredir, &s) != 0) {
+                debug_msg("Could not stat %s\n", coredir);
+                return;
+        }
+        if (!S_ISDIR(s.st_mode)) {
+                debug_msg("Not a directory: %s\n", coredir);
+                return;
+        }
+        if (!(s.st_mode & S_IWUSR) || !(s.st_mode & S_IXUSR)) {
+                debug_msg("Cannot write in or change to %s\n", coredir);
+                return;
+        }
+        if (chdir(coredir)) {
+                perror(coredir);
+        }
+#endif /* DEBUG */
+        UNUSED(argv0);
+}
Index: /common/tags/common_1_1_2/src/gettimeofday.h
===================================================================
--- /common/tags/common_1_1_2/src/gettimeofday.h (revision 353)
+++ /common/tags/common_1_1_2/src/gettimeofday.h (revision 353)
@@ -0,0 +1,6 @@
+#ifdef NEED_GETTIMEOFDAY
+
+int gettimeofday(struct timeval *tp, void *);
+
+#endif
+
Index: /common/tags/common_1_1_2/src/md5.h
===================================================================
--- /common/tags/common_1_1_2/src/md5.h (revision 314)
+++ /common/tags/common_1_1_2/src/md5.h (revision 314)
@@ -0,0 +1,43 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* MD5 context. */
+typedef struct {
+  uint32_t state[4];             /* state (ABCD) */
+  uint32_t count[2];        	/* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];     /* input buffer */
+} MD5_CTX;
+
+void MD5Init(MD5_CTX *);
+void MD5Update(MD5_CTX *, unsigned char *, unsigned int);
+void MD5Final(unsigned char [16], MD5_CTX *);
+
+#ifdef __cplusplus
+}
+#endif
Index: /common/tags/common_1_1_2/src/debug.h
===================================================================
--- /common/tags/common_1_1_2/src/debug.h (revision 360)
+++ /common/tags/common_1_1_2/src/debug.h (revision 360)
@@ -0,0 +1,64 @@
+/*
+ * FILE:    debug.h
+ * PROGRAM: RAT
+ * AUTHOR:  Isidor Kouvelas + Colin Perkins + Mark Handley + Orion Hodson
+ * 
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RAT_DEBUG_H
+#define _RAT_DEBUG_H
+
+#define UNUSED(x)	(x=x)
+#define debug_msg	_dprintf("%d:%s:%d ", getpid(), __FILE__, __LINE__), _dprintf
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+void _dprintf(const char *format, ...);
+void debug_dump(void*lp, long len);
+
+void _debug_set_core_dir(const char *argv0);
+#ifdef DEBUG
+#define debug_set_core_dir(x) _debug_set_core_dir(x)
+#else 
+#define debug_set_core_dir(x)
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
Index: /common/tags/common_1_1_2/src/ntp.c
===================================================================
--- /common/tags/common_1_1_2/src/ntp.c (revision 408)
+++ /common/tags/common_1_1_2/src/ntp.c (revision 408)
@@ -0,0 +1,32 @@
+/*
+ * FILE:    ntp.h
+ * AUTHOR:  O.Hodson
+ * 
+ * NTP utility functions to make rtp and rtp round time calculation
+ * a little less painful.
+ *
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "gettimeofday.h"
+
+#include "ntp.h"
+
+#define SECS_BETWEEN_1900_1970 2208988800u
+
+void 
+ntp64_time(uint32_t *ntp_sec, uint32_t *ntp_frac)
+{
+        struct timeval now;
+
+        gettimeofday(&now, NULL);
+
+        /* NB ntp_frac is in units of 1 / (2^32 - 1) secs. */
+        *ntp_sec  = now.tv_sec + SECS_BETWEEN_1900_1970;
+        *ntp_frac = (now.tv_usec << 12) + (now.tv_usec << 8) - ((now.tv_usec * 3650) >> 6);
+}
Index: /common/tags/common_1_1_2/src/qfDES.c
===================================================================
--- /common/tags/common_1_1_2/src/qfDES.c (revision 301)
+++ /common/tags/common_1_1_2/src/qfDES.c (revision 301)
@@ -0,0 +1,927 @@
+/*****************************************************************************
+
+Saleem N. Bhatti
+February 1993
+
+Patch for Intel/Linux courtesy of Mark Handley & George Pavlou
+Added 2 August 1996, Saleem
+*****************************************************************************/
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "qfDES.h"
+#include "crypt_random.h"
+
+typedef unsigned long Word;
+
+#define B00 0x80000000
+#define B01 0x40000000
+#define B02 0x20000000
+#define B03 0x10000000
+#define B04 0x08000000
+#define B05 0x04000000
+#define B06 0x02000000
+#define B07 0x01000000
+#define B08 0x00800000
+#define B09 0x00400000
+#define B10 0x00200000
+#define B11 0x00100000
+#define B12 0x00080000
+#define B13 0x00040000
+#define B14 0x00020000
+#define B15 0x00010000
+#define B16 0x00008000
+#define B17 0x00004000
+#define B18 0x00002000
+#define B19 0x00001000
+#define B20 0x00000800
+#define B21 0x00000400
+#define B22 0x00000200
+#define B23 0x00000100
+#define B24 0x00000080
+#define B25 0x00000040
+#define B26 0x00000020
+#define B27 0x00000010
+#define B28 0x00000008
+#define B29 0x00000004
+#define B30 0x00000002
+#define B31 0x00000001
+
+#define INITIAL_PERMUTATION_AUX(_i0, _i1, _o0, _o1) \
+{ \
+_o0 = _o1 = 0; \
+_o0 |= (_i1 & B25) << 25; /* 58 */ \
+_o0 |= (_i1 & B17) << 16; /* 50 */ \
+_o0 |= (_i1 & B09) <<  7; /* 42 */ \
+_o0 |= (_i1 & B01) >>  2; /* 34 */ \
+_o0 |= (_i0 & B25) << 21; /* 26 */ \
+_o0 |= (_i0 & B17) << 12; /* 18 */ \
+_o0 |= (_i0 & B09) <<  3; /* 10 */ \
+_o0 |= (_i0 & B01) >>  6; /*  2 */ \
+_o0 |= (_i1 & B27) << 19; /* 60 */ \
+_o0 |= (_i1 & B19) << 10; /* 52 */ \
+_o0 |= (_i1 & B11) <<  1; /* 44 */ \
+_o0 |= (_i1 & B03) >>  8; /* 36 */ \
+_o0 |= (_i0 & B27) << 15; /* 28 */ \
+_o0 |= (_i0 & B19) <<  6; /* 20 */ \
+_o0 |= (_i0 & B11) >>  3; /* 12 */ \
+_o0 |= (_i0 & B03) >> 12; /*  4 */ \
+_o0 |= (_i1 & B29) << 13; /* 62 */ \
+_o0 |= (_i1 & B21) <<  4; /* 54 */ \
+_o0 |= (_i1 & B13) >>  5; /* 46 */ \
+_o0 |= (_i1 & B05) >> 14; /* 38 */ \
+_o0 |= (_i0 & B29) <<  9; /* 30 */ \
+_o0 |= (_i0 & B21)      ; /* 22 */ \
+_o0 |= (_i0 & B13) >>  9; /* 14 */ \
+_o0 |= (_i0 & B05) >> 18; /*  6 */ \
+_o0 |= (_i1 & B31) <<  7; /* 64 */ \
+_o0 |= (_i1 & B23) >>  2; /* 56 */ \
+_o0 |= (_i1 & B15) >> 11; /* 48 */ \
+_o0 |= (_i1 & B07) >> 20; /* 40 */ \
+_o0 |= (_i0 & B31) <<  3; /* 32 */ \
+_o0 |= (_i0 & B23) >>  6; /* 24 */ \
+_o0 |= (_i0 & B15) >> 15; /* 16 */ \
+_o0 |= (_i0 & B07) >> 24; /*  8 */ \
+_o1 |= (_i1 & B24) << 24; /* 57 */ \
+_o1 |= (_i1 & B16) << 15; /* 49 */ \
+_o1 |= (_i1 & B08) <<  6; /* 41 */ \
+_o1 |= (_i1 & B00) >>  3; /* 33 */ \
+_o1 |= (_i0 & B24) << 20; /* 25 */ \
+_o1 |= (_i0 & B16) << 11; /* 17 */ \
+_o1 |= (_i0 & B08) <<  2; /*  9 */ \
+_o1 |= (_i0 & B00) >>  7; /*  1 */ \
+_o1 |= (_i1 & B26) << 18; /* 59 */ \
+_o1 |= (_i1 & B18) <<  9; /* 51 */ \
+_o1 |= (_i1 & B10)      ; /* 43 */ \
+_o1 |= (_i1 & B02) >>  9; /* 35 */ \
+_o1 |= (_i0 & B26) << 14; /* 27 */ \
+_o1 |= (_i0 & B18) <<  5; /* 19 */ \
+_o1 |= (_i0 & B10) >>  4; /* 11 */ \
+_o1 |= (_i0 & B02) >> 13; /*  3 */ \
+_o1 |= (_i1 & B28) << 12; /* 61 */ \
+_o1 |= (_i1 & B20) <<  3; /* 53 */ \
+_o1 |= (_i1 & B12) >>  6; /* 45 */ \
+_o1 |= (_i1 & B04) >> 15; /* 37 */ \
+_o1 |= (_i0 & B28) <<  8; /* 29 */ \
+_o1 |= (_i0 & B20) >>  1; /* 21 */ \
+_o1 |= (_i0 & B12) >> 10; /* 13 */ \
+_o1 |= (_i0 & B04) >> 19; /*  5 */ \
+_o1 |= (_i1 & B30) <<  6; /* 63 */ \
+_o1 |= (_i1 & B22) >>  3; /* 55 */ \
+_o1 |= (_i1 & B14) >> 12; /* 47 */ \
+_o1 |= (_i1 & B06) >> 21; /* 39 */ \
+_o1 |= (_i0 & B30) <<  2; /* 31 */ \
+_o1 |= (_i0 & B22) >>  7; /* 23 */ \
+_o1 |= (_i0 & B14) >> 16; /* 15 */ \
+_o1 |= (_i0 & B06) >> 25; /*  7 */ \
+}
+
+#define FINAL_PERMUTATION_AUX(_i0, _i1, _o0, _o1) \
+{ \
+_o0 = _o1 = 0; \
+_o0 |= (_i1 & B07) <<  7; /* 40 */ \
+_o0 |= (_i0 & B07) <<  6; /*  8 */ \
+_o0 |= (_i1 & B15) << 13; /* 48 */ \
+_o0 |= (_i0 & B15) << 12; /* 16 */ \
+_o0 |= (_i1 & B23) << 19; /* 56 */ \
+_o0 |= (_i0 & B23) << 18; /* 24 */ \
+_o0 |= (_i1 & B31) << 25; /* 64 */ \
+_o0 |= (_i0 & B31) << 24; /* 32 */ \
+_o0 |= (_i1 & B06) >>  2; /* 39 */ \
+_o0 |= (_i0 & B06) >>  3; /*  7 */ \
+_o0 |= (_i1 & B14) <<  4; /* 47 */ \
+_o0 |= (_i0 & B14) <<  3; /* 15 */ \
+_o0 |= (_i1 & B22) << 10; /* 55 */ \
+_o0 |= (_i0 & B22) <<  9; /* 23 */ \
+_o0 |= (_i1 & B30) << 16; /* 63 */ \
+_o0 |= (_i0 & B30) << 15; /* 31 */ \
+_o0 |= (_i1 & B05) >> 11; /* 38 */ \
+_o0 |= (_i0 & B05) >> 12; /*  6 */ \
+_o0 |= (_i1 & B13) >>  5; /* 46 */ \
+_o0 |= (_i0 & B13) >>  6; /* 14 */ \
+_o0 |= (_i1 & B21) <<  1; /* 54 */ \
+_o0 |= (_i0 & B21)      ; /* 22 */ \
+_o0 |= (_i1 & B29) <<  7; /* 62 */ \
+_o0 |= (_i0 & B29) <<  6; /* 30 */ \
+_o0 |= (_i1 & B04) >> 20; /* 37 */ \
+_o0 |= (_i0 & B04) >> 21; /*  5 */ \
+_o0 |= (_i1 & B12) >> 14; /* 45 */ \
+_o0 |= (_i0 & B12) >> 15; /* 13 */ \
+_o0 |= (_i1 & B20) >>  8; /* 53 */ \
+_o0 |= (_i0 & B20) >>  9; /* 21 */ \
+_o0 |= (_i1 & B28) >>  2; /* 61 */ \
+_o0 |= (_i0 & B28) >>  3; /* 29 */ \
+_o1 |= (_i1 & B03) <<  3; /* 36 */ \
+_o1 |= (_i0 & B03) <<  2; /*  4 */ \
+_o1 |= (_i1 & B11) <<  9; /* 44 */ \
+_o1 |= (_i0 & B11) <<  8; /* 12 */ \
+_o1 |= (_i1 & B19) << 15; /* 52 */ \
+_o1 |= (_i0 & B19) << 14; /* 20 */ \
+_o1 |= (_i1 & B27) << 21; /* 60 */ \
+_o1 |= (_i0 & B27) << 20; /* 28 */ \
+_o1 |= (_i1 & B02) >>  6; /* 35 */ \
+_o1 |= (_i0 & B02) >>  7; /*  3 */ \
+_o1 |= (_i1 & B10)      ; /* 43 */ \
+_o1 |= (_i0 & B10) >>  1; /* 11 */ \
+_o1 |= (_i1 & B18) <<  6; /* 51 */ \
+_o1 |= (_i0 & B18) <<  5; /* 19 */ \
+_o1 |= (_i1 & B26) << 12; /* 59 */ \
+_o1 |= (_i0 & B26) << 11; /* 27 */ \
+_o1 |= (_i1 & B01) >> 15; /* 34 */ \
+_o1 |= (_i0 & B01) >> 16; /*  2 */ \
+_o1 |= (_i1 & B09) >>  9; /* 42 */ \
+_o1 |= (_i0 & B09) >> 10; /* 10 */ \
+_o1 |= (_i1 & B17) >>  3; /* 50 */ \
+_o1 |= (_i0 & B17) >>  4; /* 18 */ \
+_o1 |= (_i1 & B25) <<  3; /* 58 */ \
+_o1 |= (_i0 & B25) <<  2; /* 26 */ \
+_o1 |= (_i1 & B00) >> 24; /* 33 */ \
+_o1 |= (_i0 & B00) >> 25; /*  1 */ \
+_o1 |= (_i1 & B08) >> 18; /* 41 */ \
+_o1 |= (_i0 & B08) >> 19; /*  9 */ \
+_o1 |= (_i1 & B16) >> 12; /* 49 */ \
+_o1 |= (_i0 & B16) >> 13; /* 17 */ \
+_o1 |= (_i1 & B24) >>  6; /* 57 */ \
+_o1 |= (_i0 & B24) >>  7; /* 25 */ \
+}
+
+/* 64b -> 2x28b */
+#define PC1_AUX(_i0, _i1, _o0, _o1) \
+{ \
+_o0 = _o1 = 0; \
+_o0 |= (_i1 & B24) << 24; /* 57 */ \
+_o0 |= (_i1 & B16) << 15; /* 49 */ \
+_o0 |= (_i1 & B08) <<  6; /* 41 */ \
+_o0 |= (_i1 & B00) >>  3; /* 33 */ \
+_o0 |= (_i0 & B24) << 20; /* 25 */ \
+_o0 |= (_i0 & B16) << 11; /* 17 */ \
+_o0 |= (_i0 & B08) <<  2; /*  9 */ \
+_o0 |= (_i0 & B00) >>  7; /*  1 */ \
+_o0 |= (_i1 & B25) << 17; /* 58 */ \
+_o0 |= (_i1 & B17) <<  8; /* 50 */ \
+_o0 |= (_i1 & B09) >>  1; /* 42 */ \
+_o0 |= (_i1 & B01) >> 10; /* 34 */ \
+_o0 |= (_i0 & B25) << 13; /* 26 */ \
+_o0 |= (_i0 & B17) <<  4; /* 18 */ \
+_o0 |= (_i0 & B09) >>  5; /* 10 */ \
+_o0 |= (_i0 & B01) >> 14; /*  2 */ \
+_o0 |= (_i1 & B26) << 10; /* 59 */ \
+_o0 |= (_i1 & B18) <<  1; /* 51 */ \
+_o0 |= (_i1 & B10) >>  8; /* 43 */ \
+_o0 |= (_i1 & B02) >> 17; /* 35 */ \
+_o0 |= (_i0 & B26) <<  6; /* 27 */ \
+_o0 |= (_i0 & B18) >>  3; /* 19 */ \
+_o0 |= (_i0 & B10) >> 12; /* 11 */ \
+_o0 |= (_i0 & B02) >> 21; /*  3 */ \
+_o0 |= (_i1 & B27) <<  3; /* 60 */ \
+_o0 |= (_i1 & B19) >>  6; /* 52 */ \
+_o0 |= (_i1 & B11) >> 15; /* 44 */ \
+_o0 |= (_i1 & B03) >> 24; /* 36 */ \
+_o1 |= (_i1 & B30) << 30; /* 63 */ \
+_o1 |= (_i1 & B22) << 21; /* 55 */ \
+_o1 |= (_i1 & B14) << 12; /* 47 */ \
+_o1 |= (_i1 & B06) <<  3; /* 39 */ \
+_o1 |= (_i0 & B30) << 26; /* 31 */ \
+_o1 |= (_i0 & B22) << 17; /* 23 */ \
+_o1 |= (_i0 & B14) <<  8; /* 15 */ \
+_o1 |= (_i0 & B06) >>  1; /*  7 */ \
+_o1 |= (_i1 & B29) << 21; /* 62 */ \
+_o1 |= (_i1 & B21) << 12; /* 54 */ \
+_o1 |= (_i1 & B13) <<  3; /* 46 */ \
+_o1 |= (_i1 & B05) >>  6; /* 38 */ \
+_o1 |= (_i0 & B29) << 17; /* 30 */ \
+_o1 |= (_i0 & B21) <<  8; /* 22 */ \
+_o1 |= (_i0 & B13) >>  1; /* 14 */ \
+_o1 |= (_i0 & B05) >> 10; /*  6 */ \
+_o1 |= (_i1 & B28) << 12; /* 61 */ \
+_o1 |= (_i1 & B20) <<  3; /* 53 */ \
+_o1 |= (_i1 & B12) >>  6; /* 45 */ \
+_o1 |= (_i1 & B04) >> 15; /* 37 */ \
+_o1 |= (_i0 & B28) <<  8; /* 29 */ \
+_o1 |= (_i0 & B20) >>  1; /* 21 */ \
+_o1 |= (_i0 & B12) >> 10; /* 13 */ \
+_o1 |= (_i0 & B04) >> 19; /*  5 */ \
+_o1 |= (_i0 & B27) <<  3; /* 28 */ \
+_o1 |= (_i0 & B19) >>  6; /* 20 */ \
+_o1 |= (_i0 & B11) >> 15; /* 12 */ \
+_o1 |= (_i0 & B03) >> 24; /*  4 */ \
+}
+
+/* 2x28b -> 8x6b */
+#define PC2_AUX(_i0, _i1, _o0, _o1) \
+{ \
+_o0 = _o1 = 0; \
+_o0 |= (_i0 & B13) << 11; /* 14 */ \
+_o0 |= (_i0 & B16) << 13; /* 17 */ \
+_o0 |= (_i0 & B10) <<  6; /* 11 */ \
+_o0 |= (_i0 & B23) << 18; /* 24 */ \
+_o0 |= (_i0 & B00) >>  6; /*  1 */ \
+_o0 |= (_i0 & B04) >>  3; /*  5 */ \
+_o0 |= (_i0 & B02) >>  8; /*  3 */ \
+_o0 |= (_i0 & B27) << 16; /* 28 */ \
+_o0 |= (_i0 & B14) <<  2; /* 15 */ \
+_o0 |= (_i0 & B05) >>  8; /*  6 */ \
+_o0 |= (_i0 & B20) <<  6; /* 21 */ \
+_o0 |= (_i0 & B09) >>  6; /* 10 */ \
+_o0 |= (_i0 & B22) <<  4; /* 23 */ \
+_o0 |= (_i0 & B18) >>  1; /* 19 */ \
+_o0 |= (_i0 & B11) >>  9; /* 12 */ \
+_o0 |= (_i0 & B03) >> 18; /*  4 */ \
+_o0 |= (_i0 & B25) <<  3; /* 26 */ \
+_o0 |= (_i0 & B07) >> 16; /*  8 */ \
+_o0 |= (_i0 & B15) >> 11; /* 16 */ \
+_o0 |= (_i0 & B06) >> 21; /*  7 */ \
+_o0 |= (_i0 & B26) >>  2; /* 27 */ \
+_o0 |= (_i0 & B19) >> 10; /* 20 */ \
+_o0 |= (_i0 & B12) >> 18; /* 13 */ \
+_o0 |= (_i0 & B01) >> 30; /*  2 */ \
+_o1 |= (_i1 & B12) << 10; /* 41 */ \
+_o1 |= (_i1 & B23) << 20; /* 52 */ \
+_o1 |= (_i1 & B02) >>  2; /* 31 */ \
+_o1 |= (_i1 & B08) <<  3; /* 37 */ \
+_o1 |= (_i1 & B18) << 12; /* 47 */ \
+_o1 |= (_i1 & B26) << 19; /* 55 */ \
+_o1 |= (_i1 & B01) >>  9; /* 30 */ \
+_o1 |= (_i1 & B11)      ; /* 40 */ \
+_o1 |= (_i1 & B22) << 10; /* 51 */ \
+_o1 |= (_i1 & B16) <<  3; /* 45 */ \
+_o1 |= (_i1 & B04) >> 10; /* 33 */ \
+_o1 |= (_i1 & B19) <<  4; /* 48 */ \
+_o1 |= (_i1 & B15) >>  3; /* 44 */ \
+_o1 |= (_i1 & B20) <<  1; /* 49 */ \
+_o1 |= (_i1 & B10) >> 10; /* 39 */ \
+_o1 |= (_i1 & B27) <<  6; /* 56 */ \
+_o1 |= (_i1 & B05) >> 17; /* 34 */ \
+_o1 |= (_i1 & B24) <<  1; /* 53 */ \
+_o1 |= (_i1 & B17) >>  9; /* 46 */ \
+_o1 |= (_i1 & B13) >> 14; /* 42 */ \
+_o1 |= (_i1 & B21) >>  7; /* 50 */ \
+_o1 |= (_i1 & B07) >> 22; /* 36 */ \
+_o1 |= (_i1 & B00) >> 30; /* 29 */ \
+_o1 |= (_i1 & B03) >> 28; /* 32 */ \
+}
+
+static
+Word s_p0[64] =
+{ /* Combined S-Box1 and permutation P */
+0x00808200, 0x00000000, 0x00008000, 0x00808202,
+0x00808002, 0x00008202, 0x00000002, 0x00008000,
+0x00000200, 0x00808200, 0x00808202, 0x00000200,
+0x00800202, 0x00808002, 0x00800000, 0x00000002,
+0x00000202, 0x00800200, 0x00800200, 0x00008200,
+0x00008200, 0x00808000, 0x00808000, 0x00800202,
+0x00008002, 0x00800002, 0x00800002, 0x00008002,
+0x00000000, 0x00000202, 0x00008202, 0x00800000,
+0x00008000, 0x00808202, 0x00000002, 0x00808000,
+0x00808200, 0x00800000, 0x00800000, 0x00000200,
+0x00808002, 0x00008000, 0x00008200, 0x00800002,
+0x00000200, 0x00000002, 0x00800202, 0x00008202,
+0x00808202, 0x00008002, 0x00808000, 0x00800202,
+0x00800002, 0x00000202, 0x00008202, 0x00808200,
+0x00000202, 0x00800200, 0x00800200, 0x00000000,
+0x00008002, 0x00008200, 0x00000000, 0x00808002
+};
+
+static
+Word s_p1[64] =
+{ /* Combined S-Box2 and permutation P */
+0x40084010, 0x40004000, 0x00004000, 0x00084010,
+0x00080000, 0x00000010, 0x40080010, 0x40004010,
+0x40000010, 0x40084010, 0x40084000, 0x40000000,
+0x40004000, 0x00080000, 0x00000010, 0x40080010,
+0x00084000, 0x00080010, 0x40004010, 0x00000000,
+0x40000000, 0x00004000, 0x00084010, 0x40080000,
+0x00080010, 0x40000010, 0x00000000, 0x00084000,
+0x00004010, 0x40084000, 0x40080000, 0x00004010,
+0x00000000, 0x00084010, 0x40080010, 0x00080000,
+0x40004010, 0x40080000, 0x40084000, 0x00004000,
+0x40080000, 0x40004000, 0x00000010, 0x40084010,
+0x00084010, 0x00000010, 0x00004000, 0x40000000,
+0x00004010, 0x40084000, 0x00080000, 0x40000010,
+0x00080010, 0x40004010, 0x40000010, 0x00080010,
+0x00084000, 0x00000000, 0x40004000, 0x00004010,
+0x40000000, 0x40080010, 0x40084010, 0x00084000
+};
+
+static
+Word s_p2[64] =
+{ /* Combined S-Box3 and permutation P */
+0x00000104, 0x04010100, 0x00000000, 0x04010004,
+0x04000100, 0x00000000, 0x00010104, 0x04000100,
+0x00010004, 0x04000004, 0x04000004, 0x00010000,
+0x04010104, 0x00010004, 0x04010000, 0x00000104,
+0x04000000, 0x00000004, 0x04010100, 0x00000100,
+0x00010100, 0x04010000, 0x04010004, 0x00010104,
+0x04000104, 0x00010100, 0x00010000, 0x04000104,
+0x00000004, 0x04010104, 0x00000100, 0x04000000,
+0x04010100, 0x04000000, 0x00010004, 0x00000104,
+0x00010000, 0x04010100, 0x04000100, 0x00000000,
+0x00000100, 0x00010004, 0x04010104, 0x04000100,
+0x04000004, 0x00000100, 0x00000000, 0x04010004,
+0x04000104, 0x00010000, 0x04000000, 0x04010104,
+0x00000004, 0x00010104, 0x00010100, 0x04000004,
+0x04010000, 0x04000104, 0x00000104, 0x04010000,
+0x00010104, 0x00000004, 0x04010004, 0x00010100
+};
+
+static
+Word s_p3[64] =
+{ /* Combined S-Box4 and permutation P */
+0x80401000, 0x80001040, 0x80001040, 0x00000040,
+0x00401040, 0x80400040, 0x80400000, 0x80001000,
+0x00000000, 0x00401000, 0x00401000, 0x80401040,
+0x80000040, 0x00000000, 0x00400040, 0x80400000,
+0x80000000, 0x00001000, 0x00400000, 0x80401000,
+0x00000040, 0x00400000, 0x80001000, 0x00001040,
+0x80400040, 0x80000000, 0x00001040, 0x00400040,
+0x00001000, 0x00401040, 0x80401040, 0x80000040,
+0x00400040, 0x80400000, 0x00401000, 0x80401040,
+0x80000040, 0x00000000, 0x00000000, 0x00401000,
+0x00001040, 0x00400040, 0x80400040, 0x80000000,
+0x80401000, 0x80001040, 0x80001040, 0x00000040,
+0x80401040, 0x80000040, 0x80000000, 0x00001000,
+0x80400000, 0x80001000, 0x00401040, 0x80400040,
+0x80001000, 0x00001040, 0x00400000, 0x80401000,
+0x00000040, 0x00400000, 0x00001000, 0x00401040
+};
+
+static
+Word s_p4[64] =
+{ /* Combined S-Box5 and permutation P */
+0x00000080, 0x01040080, 0x01040000, 0x21000080,
+0x00040000, 0x00000080, 0x20000000, 0x01040000,
+0x20040080, 0x00040000, 0x01000080, 0x20040080,
+0x21000080, 0x21040000, 0x00040080, 0x20000000,
+0x01000000, 0x20040000, 0x20040000, 0x00000000,
+0x20000080, 0x21040080, 0x21040080, 0x01000080,
+0x21040000, 0x20000080, 0x00000000, 0x21000000,
+0x01040080, 0x01000000, 0x21000000, 0x00040080,
+0x00040000, 0x21000080, 0x00000080, 0x01000000,
+0x20000000, 0x01040000, 0x21000080, 0x20040080,
+0x01000080, 0x20000000, 0x21040000, 0x01040080,
+0x20040080, 0x00000080, 0x01000000, 0x21040000,
+0x21040080, 0x00040080, 0x21000000, 0x21040080,
+0x01040000, 0x00000000, 0x20040000, 0x21000000,
+0x00040080, 0x01000080, 0x20000080, 0x00040000,
+0x00000000, 0x20040000, 0x01040080, 0x20000080
+};
+
+static
+Word s_p5[64] =
+{ /* Combined S-Box6 and permutation P */
+0x10000008, 0x10200000, 0x00002000, 0x10202008,
+0x10200000, 0x00000008, 0x10202008, 0x00200000,
+0x10002000, 0x00202008, 0x00200000, 0x10000008,
+0x00200008, 0x10002000, 0x10000000, 0x00002008,
+0x00000000, 0x00200008, 0x10002008, 0x00002000,
+0x00202000, 0x10002008, 0x00000008, 0x10200008,
+0x10200008, 0x00000000, 0x00202008, 0x10202000,
+0x00002008, 0x00202000, 0x10202000, 0x10000000,
+0x10002000, 0x00000008, 0x10200008, 0x00202000,
+0x10202008, 0x00200000, 0x00002008, 0x10000008,
+0x00200000, 0x10002000, 0x10000000, 0x00002008,
+0x10000008, 0x10202008, 0x00202000, 0x10200000,
+0x00202008, 0x10202000, 0x00000000, 0x10200008,
+0x00000008, 0x00002000, 0x10200000, 0x00202008,
+0x00002000, 0x00200008, 0x10002008, 0x00000000,
+0x10202000, 0x10000000, 0x00200008, 0x10002008
+};
+
+static
+Word s_p6[64] =
+{ /* Combined S-Box7 and permutation P */
+0x00100000, 0x02100001, 0x02000401, 0x00000000,
+0x00000400, 0x02000401, 0x00100401, 0x02100400,
+0x02100401, 0x00100000, 0x00000000, 0x02000001,
+0x00000001, 0x02000000, 0x02100001, 0x00000401,
+0x02000400, 0x00100401, 0x00100001, 0x02000400,
+0x02000001, 0x02100000, 0x02100400, 0x00100001,
+0x02100000, 0x00000400, 0x00000401, 0x02100401,
+0x00100400, 0x00000001, 0x02000000, 0x00100400,
+0x02000000, 0x00100400, 0x00100000, 0x02000401,
+0x02000401, 0x02100001, 0x02100001, 0x00000001,
+0x00100001, 0x02000000, 0x02000400, 0x00100000,
+0x02100400, 0x00000401, 0x00100401, 0x02100400,
+0x00000401, 0x02000001, 0x02100401, 0x02100000,
+0x00100400, 0x00000000, 0x00000001, 0x02100401,
+0x00000000, 0x00100401, 0x02100000, 0x00000400,
+0x02000001, 0x02000400, 0x00000400, 0x00100001
+};
+
+static
+Word s_p7[64] =
+{ /* Combined S-Box8 and permutation P */
+0x08000820, 0x00000800, 0x00020000, 0x08020820,
+0x08000000, 0x08000820, 0x00000020, 0x08000000,
+0x00020020, 0x08020000, 0x08020820, 0x00020800,
+0x08020800, 0x00020820, 0x00000800, 0x00000020,
+0x08020000, 0x08000020, 0x08000800, 0x00000820,
+0x00020800, 0x00020020, 0x08020020, 0x08020800,
+0x00000820, 0x00000000, 0x00000000, 0x08020020,
+0x08000020, 0x08000800, 0x00020820, 0x00020000,
+0x00020820, 0x00020000, 0x08020800, 0x00000800,
+0x00000020, 0x08020020, 0x00000800, 0x00020820,
+0x08000800, 0x00000020, 0x08000020, 0x08020000,
+0x08020020, 0x08000000, 0x00020000, 0x08000820,
+0x00000000, 0x08020820, 0x00020020, 0x08000020,
+0x08020000, 0x08000800, 0x08000820, 0x00000000,
+0x08020820, 0x00020800, 0x00020800, 0x00000820,
+0x00000820, 0x00020020, 0x08000000, 0x08020800
+};
+
+#define INITIAL_PERMUTATION(t, regL, regR) \
+        INITIAL_PERMUTATION_AUX(t[0], t[1], regL, regR)
+
+#define FINAL_PERMUTATION(regR, regL, t) \
+        FINAL_PERMUTATION_AUX(regR, regL, t[0], t[1])
+
+#define PC1(k, regC, regD) \
+        PC1_AUX(k[0], k[1], regC, regD)
+
+#define PC2(regC, regD, k) \
+        PC2_AUX(regC, regD, k[0], k[1])
+
+unsigned char G_padChar = (char) 0; /* Default pad charcater */
+
+static Word ROTATE_LEFT(Word x) 
+{
+	Word	a;
+	a = (x & 0x80000000) >> 27;
+	return (x << 1) | a;
+}
+
+static Word ROTATE_RIGHT(Word x) 
+{
+	Word	a;
+	a = x & 0x00000010;
+	return (x >> 1) | (a << 27);
+}
+
+/*
+** The S Box transformations and the permutation P are combined in the vectors
+** s_p0 - s_p7. Permutation E and the MOD 2 addition with the intermediate key
+** are then done "inline" on each round. The intermediate key is already in a
+** a 8x6bit form because of the modified permuation PC2 used.
+*/
+
+#if !defined(WORDS_BIGENDIAN)
+
+#define DES(t, ik) \
+{ \
+    register Word l, r, reg32, round; \
+    register unsigned char *bb; \
+    INITIAL_PERMUTATION(t, l, r); \
+    for(bb = (unsigned char *) ik, round = 0x8000; round; bb += 8, round >>= 1) { \
+        register Word w = (r << 1) | (r >> 31); \
+        reg32  = s_p7[( w        & 0x3f) ^ bb[4]]; \
+        reg32 |= s_p6[((w >>= 4) & 0x3f) ^ bb[5]]; \
+        reg32 |= s_p5[((w >>= 4) & 0x3f) ^ bb[6]]; \
+        reg32 |= s_p4[((w >>= 4) & 0x3f) ^ bb[7]]; \
+        reg32 |= s_p3[((w >>= 4) & 0x3f) ^ bb[0]]; \
+        reg32 |= s_p2[((w >>= 4) & 0x3f) ^ bb[1]]; \
+        reg32 |= s_p1[((w >>  4) & 0x3f) ^ bb[2]]; \
+        reg32 |= s_p0[(((r & 0x1) << 5) | ((r & 0xf8000000) >> 27)) ^ bb[3]]; \
+        reg32 ^= l; \
+        l = r; \
+        r = reg32; \
+    } \
+    FINAL_PERMUTATION(r, l, t); \
+}
+
+
+#define MAKE_LITTLE_ENDIAN(t, s) \
+{ \
+    register unsigned int z, l = s/4; \
+    register Word *tp = (Word *) t; \
+    for(z = 0; z < l; ++z) tp[z] = htonl(tp[z]); \
+}
+
+#else /* WORDS_BIGENDIAN */
+
+#define DES(t, ik) \
+{ \
+    register Word l, r, reg32, round; \
+    register unsigned char *bb; \
+    INITIAL_PERMUTATION(t, l, r); \
+    for(bb = (unsigned char *) ik, round = 0x8000; round; bb += 8, round >>= 1) { \
+        register Word w = (r << 1) | (r >> 31); \
+        reg32  = s_p7[( w        & 0x3f) ^ bb[7]]; \
+        reg32 |= s_p6[((w >>= 4) & 0x3f) ^ bb[6]]; \
+        reg32 |= s_p5[((w >>= 4) & 0x3f) ^ bb[5]]; \
+        reg32 |= s_p4[((w >>= 4) & 0x3f) ^ bb[4]]; \
+        reg32 |= s_p3[((w >>= 4) & 0x3f) ^ bb[3]]; \
+        reg32 |= s_p2[((w >>= 4) & 0x3f) ^ bb[2]]; \
+        reg32 |= s_p1[((w >>  4) & 0x3f) ^ bb[1]]; \
+        reg32 |= s_p0[(((r & 0x1) << 5) | ((r & 0xf8000000) >> 27)) ^ bb[0]]; \
+        reg32 ^= l; \
+        l = r; \
+        r = reg32; \
+    } \
+    FINAL_PERMUTATION(r, l, t); \
+}
+
+#endif /* WORDS_BIGENDIAN */
+
+int
+qfDES(unsigned char	*key,
+      unsigned char	*data,
+      unsigned int 	 size,
+const QFDES_what   	 what,
+const QFDES_mode   	 mode,
+      unsigned char	*initVec)
+{
+    /* Store some info to optimise for multiple calls ... */
+    static unsigned char desKey[8], desKeys[128];
+    static Word 	*oldKey = (Word *) desKey,
+         		*keys   = (Word *) desKeys;
+    static QFDES_what 	oldWhat;
+    static QFDES_mode 	oldMode;
+    unsigned char 	b0[8], b1[8]; /* feedback blocks */
+    Word 		*newKey = (Word *) key, /* key from user */
+         		*text,                  /* text to be [en|de]crypted */
+         		*cb     = (Word *) b0,  /* the chained block in CBC mode */
+         		*cb1    = (Word *) b1;  /* a copy for use when decrypting */
+
+#if !defined(WORDS_BIGENDIAN)
+    unsigned int origSize = size;
+    MAKE_LITTLE_ENDIAN(key, 8);
+    MAKE_LITTLE_ENDIAN(data, origSize);
+#endif
+
+    /*
+    ** Check new key against old key
+    ** and set up intermediate keys.
+    */
+    if (newKey[0] != oldKey[0] || newKey[1] != oldKey[1]) {
+        Word c, d;  /* C and D registers */
+
+        oldKey[0] = newKey[0]; oldKey[1] = newKey[1];
+        oldWhat   = what;
+        oldMode   = mode;
+
+        PC1(newKey, c, d);
+
+        if ((what == qfDES_encrypt) || (mode == qfDES_cfb) || (mode == qfDES_ofb)) {
+		int 	 z;
+		Word	 r; 
+		Word	*k = keys; 
+		Word 	 rol[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+		for(z = 0; z < 16; z++, k += 2) { 
+			for (r = 0; r < rol[z]; r++) {
+				c = ROTATE_LEFT(c); 
+				d = ROTATE_LEFT(d);
+			}
+			PC2(c, d, k); 
+		}
+        } else {
+		int 	 z;
+		Word	 r; 
+		Word	*k = keys; 
+		Word 	 ror[16] = {0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
+
+		for(z = 0; z < 16; z++, k += 2) { 
+			r = 0;
+			while (ror[z] > r) {
+				r++;
+				c = ROTATE_RIGHT(c); 
+				d = ROTATE_RIGHT(d);
+			}
+			PC2(c, d, k); 
+		} 
+	}
+    } else if ((what != oldWhat) && ((mode == qfDES_ecb) || (mode == qfDES_cbc))) {
+        /*
+        ** Same key but different direction.
+        ** Reverse intermediate key sequence (ECB and CBC).
+        */
+        Word *ik1, *ik2, ik3[2];
+
+        for(ik1 = keys, ik2 = &(keys[30]); ik1 < ik2; ik1 += 2, ik2 -= 2) {
+            ik3[0] = ik1[0]; ik3[1] = ik1[1];
+            ik1[0] = ik2[0]; ik1[1] = ik2[1];
+            ik2[0] = ik3[0]; ik2[1] = ik3[1];
+        }
+
+        oldWhat = what;
+    }
+
+    /* Set up initilaisation vector */
+    if (mode != qfDES_ecb) {
+        if (initVec) {
+            { cb[0] = ((Word *) initVec)[0]; cb[1] = ((Word *) initVec)[1]; }
+        } else {
+            cb[0] = 0;
+	    cb[1] = 0;
+	}
+#if !defined(WORDS_BIGENDIAN)
+        MAKE_LITTLE_ENDIAN(cb, 8);
+#endif
+    }
+
+    /*
+    ** Lots of gotos and code duplication follow (arrgh) but it speeds
+    ** it up a wee bit!
+    ** What would be more useful is looking more carefully at the DES
+    ** permutations to produce more efficient versions of the macros
+    ** of the "auto-generated" versions used in qfDES-aux.c.
+    */
+
+    size >>= 3; /* this is always a multpile of 8 */
+
+    if (what == qfDES_encrypt) {
+        switch ((int) mode) {
+        case ((int) qfDES_ecb): goto _ECB_;
+        case ((int) qfDES_cbc): goto _CBC_encrypt_;
+        case ((int) qfDES_cfb): goto _CFB_encrypt_;
+        case ((int) qfDES_ofb): goto _OFB_;
+        }
+    }
+    else {
+        switch ((int) mode) {
+        case ((int) qfDES_ecb): goto _ECB_;
+        case ((int) qfDES_cbc): goto _CBC_decrypt_;
+        case ((int) qfDES_cfb): goto _CFB_decrypt_;
+        case ((int) qfDES_ofb): goto _OFB_;
+        }
+    }
+
+_ECB_:
+
+    /* ECB */
+    for(text = (Word *) data; size; --size, text += 2)
+        { DES(text, keys); }
+
+    goto _exit_qfDES_;
+
+_CBC_encrypt_:
+
+    /* CBC Encryption */
+    for(text = (Word *) data; size; --size, text += 2) {
+
+        /* chaining block */
+        text[0] ^= cb[0]; text[1] ^= cb[1];
+
+        DES(text, keys);
+
+        /* set up chaining block for next round */
+        cb[0] = text[0]; cb[1] = text[1];
+    }
+
+    goto _initVec_;
+
+_CBC_decrypt_:
+
+    /* CBC Decryption */
+    for(text = (Word *) data; size; --size, text += 2) {
+
+        /* set up chaining block */
+        /*
+        ** The decryption is done in place so I need
+        ** to copy this text block for the next round.
+        */
+        cb1[0] = text[0]; cb1[1] = text[1];
+
+        DES(text, keys);
+
+        /* chaining block for next round */
+        text[0] ^= cb[0]; text[1] ^= cb[1];
+
+        /*
+        ** Copy back the saved encrypted text - this makes
+        ** CBC decryption slower than CBC encryption.
+        */
+        cb[0] = cb1[0]; cb[1] = cb1[1];
+    }
+
+    goto _initVec_;
+
+_CFB_encrypt_:
+
+    /* CFB Encryption */
+    for(text = (Word *) data; size; --size, text += 2) {
+
+        /* use cb as the feedback block */
+        DES(cb, keys);
+
+        text[0] ^= cb[0]; text[1] ^= cb[1];
+
+        /* set up feedback block for next round */
+        cb[0] = text[0]; cb[1] = text[1];
+    }
+
+    goto _initVec_;
+
+_CFB_decrypt_:
+
+    /* CFB Decryption */
+    for(text = (Word *) data; size; --size, text += 2) {
+
+        /* set up feedback block */
+        /*
+        ** The decryption is done in place so I need
+        ** to copy this text block for the next round.
+        */
+        cb1[0] = text[0]; cb1[1] = text[1];
+
+        /* use cb as the feedback block */
+        DES(cb, keys);
+
+        text[0] ^= cb[0]; text[1] ^= cb[1];
+
+        /* set up feedback block for next round */
+        cb[0] = cb1[0]; cb[1] = cb1[1];
+    }
+
+    goto _initVec_;
+
+_OFB_:
+
+    /* OFB */
+    for(text = (Word *) data; size; --size, text += 2) {
+
+        /* use cb as the feed back block */
+        DES(cb, keys);
+
+        text[0] ^= cb[0]; text[1] ^= cb[1];
+    }
+
+_initVec_:
+
+    /*
+    ** Copy the final chained block back to initVec (CBC, CFB and OFB).
+    ** This allows the [en|de]cryption of large amounts of data in small
+    ** chunks.
+    */
+    if (initVec) {
+        ((Word *) initVec)[0] = cb[0];
+        ((Word *) initVec)[1] = cb[1];
+
+#if !defined(WORDS_BIGENDIAN)
+        MAKE_LITTLE_ENDIAN(initVec, 8);
+#endif
+    }
+
+_exit_qfDES_:
+
+#if !defined(WORDS_BIGENDIAN)
+    MAKE_LITTLE_ENDIAN(key, 8);
+    MAKE_LITTLE_ENDIAN(data, origSize);
+#endif
+
+    return 0;
+}
+
+/*
+** This function sets bit 8 of each byte to odd or even parity as requested.
+** It is assumed that the right-most bit of each byte is the parity bit.
+** Although this is really only used by the two key generation functions below,
+** it may be useful to someone.
+*/
+
+void qfDES_setParity(unsigned char *ptr, unsigned int size, const QFDES_parity parity)
+{
+    unsigned int i, mask, bits;
+
+    for(i = 0; i < size; ++i, ++ptr) {
+        for(mask = 0x80, bits = 0; mask > 0x01; mask >>= 1)
+            if (((unsigned int) *ptr) & mask) ++bits;
+
+        *ptr |= bits % 2 == (unsigned int) parity ? 0x00 : 0x01;
+    }
+}
+
+unsigned int qfDES_checkParity(unsigned char *ptr, unsigned int size, const QFDES_parity parity)
+{
+    unsigned int i, mask, bits, parityBit, parityErrors = 0;
+
+    for(i = 0; i < size; ++i, ++ptr) {
+        for(mask = 0x80, bits = 0; mask > 0x01; mask >>= 1)
+            if (((unsigned int) *ptr) & mask) ++bits;
+
+        parityBit = bits % 2 == (unsigned int) parity ? 0 : 1;
+
+        if ((((unsigned int) *ptr) & 0x1) != parityBit)
+            ++parityErrors;
+    }
+
+    return parityErrors;
+}
+
+static
+unsigned char weakKeys[18][8] =
+{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+ {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
+ {0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e},
+ {0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1},
+ {0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe},
+ {0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01},
+ {0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1},
+ {0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e},
+ {0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1},
+ {0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01},
+ {0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe},
+ {0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e},
+ {0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e},
+ {0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01},
+ {0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe},
+ {0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1}};
+
+/*
+** Although this is really only used by the key generation function below,
+** it may be handy to someone.
+*/
+
+int qfDES_checkWeakKeys(unsigned char *key)
+{
+    unsigned char *bp;
+    int i;
+
+    for(bp = weakKeys[i = 0]; i < 18; bp = weakKeys[++i])
+        if (memcmp((void *) key, (void *) bp, 8) == 0) return -1;
+
+    return 0;
+}
+
+/*
+** The following function attempts to genreate a random key or IV.
+** It relies on the randomness of the  of the random(3) function. Although
+** it is probably not particularly fast, keys and IV will most probably be
+** generated off-line so it does not matter too much.
+*/
+
+unsigned char *qfDES_generate(const QFDES_generate what)
+{
+    static
+    unsigned char buffer[8];
+    static
+    int flag = 0;
+
+    unsigned char *bp;
+    long mask = what == qfDES_key ? 0xfe : 0xff;
+
+    /* Set up a seed - 42 is the answer ... */
+    if (!flag) {
+        lbl_srandom((int) (getpid() * 42) ^ (int) time((time_t *) 0));
+        flag = 1;
+    }
+    do {
+
+        for(bp = buffer; bp <= &(buffer[7]); *bp++ = (unsigned char) (lbl_random() & mask));
+
+        if (what ==  qfDES_key)
+            qfDES_setParity(buffer, 8, qfDES_odd);
+
+    } while(what == qfDES_key ? qfDES_checkWeakKeys(buffer) : 0);
+
+    return buffer;
+}
+
+unsigned char
+qfDES_setPad(unsigned char pad)
+{ 
+    unsigned char b = G_padChar; G_padChar = pad; return b; 
+}
+
Index: /common/tags/common_1_1_2/src/rtp.c
===================================================================
--- /common/tags/common_1_1_2/src/rtp.c (revision 422)
+++ /common/tags/common_1_1_2/src/rtp.c (revision 422)
@@ -0,0 +1,2419 @@
+/*
+ * FILE:     rtp.c
+ * AUTHOR:   Colin Perkins   <c.perkins@cs.ucl.ac.uk>
+ * MODIFIED: Orion Hodson    <o.hodson@cs.ucl.ac.uk>
+ *           Markus Germeier <mager@tzi.de>
+ *           Bill Fenner     <fenner@research.att.com>
+ *           Timur Friedman  <timur@research.att.com>
+ *
+ * The routines in this file implement the Real-time Transport Protocol,
+ * RTP, as specified in RFC1889 with current updates under discussion in
+ * the IETF audio/video transport working group. Portions of the code are
+ * derived from the algorithms published in that specification.
+ *
+ * $Revision$ 
+ * $Date$
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London.
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "memory.h"
+#include "debug.h"
+#include "net_udp.h"
+#include "crypt_random.h"
+#include "drand48.h"
+#include "gettimeofday.h"
+#include "qfDES.h"
+#include "md5.h"
+#include "ntp.h"
+
+#include "rtp.h"
+
+#define MAX_DROPOUT    3000
+#define MAX_MISORDER   100
+#define MIN_SEQUENTIAL 2
+
+/*
+ * Definitions for the RTP/RTCP packets on the wire...
+ */
+
+#define RTP_SEQ_MOD        0x10000
+#define RTP_MAX_SDES_LEN   256
+
+#define RTCP_SR   200
+#define RTCP_RR   201
+#define RTCP_SDES 202
+#define RTCP_BYE  203
+#define RTCP_APP  204
+
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+	unsigned short  version:2;	/* packet type            */
+	unsigned short  p:1;		/* padding flag           */
+	unsigned short  count:5;	/* varies by payload type */
+	unsigned short  pt:8;		/* payload type           */
+#else
+	unsigned short  count:5;	/* varies by payload type */
+	unsigned short  p:1;		/* padding flag           */
+	unsigned short  version:2;	/* packet type            */
+	unsigned short  pt:8;		/* payload type           */
+#endif
+	uint16_t         length;	/* packet length          */
+} rtcp_common;
+
+typedef struct {
+	rtcp_common   common;	
+	union {
+		struct {
+			rtcp_sr		sr;
+			rtcp_rr       	rr[1];		/* variable-length list */
+		} sr;
+		struct {
+			uint32_t         ssrc;		/* source this RTCP packet is coming from */
+			rtcp_rr       	rr[1];		/* variable-length list */
+		} rr;
+		struct rtcp_sdes_t {
+			uint32_t	ssrc;
+			rtcp_sdes_item 	item[1];	/* list of SDES */
+		} sdes;
+		struct {
+			uint32_t         ssrc[1];	/* list of sources */
+							/* can't express the trailing text... */
+		} bye;
+		struct {
+			uint32_t         ssrc;           
+			uint8_t          name[4];
+			uint8_t          data[1];
+		} app;
+	} r;
+} rtcp_t;
+
+typedef struct _rtcp_rr_wrapper {
+	struct _rtcp_rr_wrapper	*next;
+	struct _rtcp_rr_wrapper	*prev;
+        uint32_t                  reporter_ssrc;
+	rtcp_rr			*rr;
+	struct timeval		*ts;	/* Arrival time of this RR */
+} rtcp_rr_wrapper;
+
+/*
+ * The RTP database contains source-specific information needed 
+ * to make it all work. 
+ */
+
+typedef struct _source {
+	struct _source	*next;
+	struct _source	*prev;
+	uint32_t	 ssrc;
+	char		*cname;
+	char		*name;
+	char		*email;
+	char		*phone;
+	char		*loc;
+	char		*tool;
+	char		*note;
+	rtcp_sr		*sr;
+	struct timeval	 last_sr;
+	struct timeval	 last_active;
+	int		 sender;
+	int		 got_bye;	/* TRUE if we've received an RTCP bye from this source */
+	uint32_t	 base_seq;
+	uint16_t	 max_seq;
+	uint32_t	 bad_seq;
+	uint32_t	 cycles;
+	int		 received;
+	int		 received_prior;
+	int		 expected_prior;
+	int		 probation;
+	uint32_t	 jitter;
+	uint32_t	 transit;
+	uint32_t	 magic;		/* For debugging... */
+} source;
+
+/* The size of the hash table used to hold the source database. */
+/* Should be large enough that we're unlikely to get collisions */
+/* when sources are added, but not too large that we waste too  */
+/* much memory. Sedgewick ("Algorithms", 2nd Ed, Addison-Wesley */
+/* 1988) suggests that this should be around 1/10th the number  */
+/* of entries that we expect to have in the database and should */
+/* be a prime number. Everything continues to work if this is   */
+/* too low, it just goes slower... for now we assume around 100 */
+/* participants is a sensible limit so we set this to 11.       */   
+#define RTP_DB_SIZE	11
+
+/*
+ *  Options for an RTP session are stored in the "options" struct.
+ */
+
+typedef struct {
+	int 	promiscuous_mode;
+	int	wait_for_rtcp;
+	int	filter_my_packets;
+} options;
+
+/*
+ * The "struct rtp" defines an RTP session.
+ */
+
+struct rtp {
+	socket_udp	*rtp_socket;
+	socket_udp	*rtcp_socket;
+	char		*addr;
+	uint16_t	 rx_port;
+	uint16_t	 tx_port;
+	int		 ttl;
+	uint32_t	 my_ssrc;
+	source		*db[RTP_DB_SIZE];
+        rtcp_rr_wrapper  rr[RTP_DB_SIZE][RTP_DB_SIZE]; 	/* Indexed by [hash(reporter)][hash(reportee)] */
+	options		*opt;
+	void		*userdata;
+	int		 invalid_rtp_count;
+	int		 invalid_rtcp_count;
+	int		 ssrc_count;
+	int		 ssrc_count_prev;		/* ssrc_count at the time we last recalculated our RTCP interval */
+	int		 sender_count;
+	int		 initial_rtcp;
+	double		 avg_rtcp_size;
+	int		 we_sent;
+	double		 rtcp_bw;
+	struct timeval	 last_update;
+	struct timeval	 last_rtcp_send_time;
+	struct timeval	 next_rtcp_send_time;
+	double		 rtcp_interval;
+	int		 sdes_count_pri;
+	int		 sdes_count_sec;
+	int		 sdes_count_ter;
+	uint16_t	 rtp_seq;
+	uint32_t	 rtp_pcount;
+	uint32_t	 rtp_bcount;
+        char            *encryption_key;
+	void (*callback)(struct rtp *session, rtp_event *event);
+	uint32_t	 magic;				/* For debugging...  */
+};
+
+static int filter_event(struct rtp *session, uint32_t ssrc)
+{
+	int	filter;
+
+	rtp_getopt(session, RTP_OPT_FILTER_MY_PACKETS, &filter);
+	return filter && (ssrc == rtp_my_ssrc(session));
+}
+
+static double tv_diff(struct timeval curr_time, struct timeval prev_time)
+{
+    /* Return curr_time - prev_time */
+    double	ct, pt;
+
+    ct = (double) curr_time.tv_sec + (((double) curr_time.tv_usec) / 1000000.0);
+    pt = (double) prev_time.tv_sec + (((double) prev_time.tv_usec) / 1000000.0);
+    return (ct - pt);
+}
+
+static void tv_add(struct timeval *ts, double offset)
+{
+	/* Add offset seconds to ts */
+	double offset_sec, offset_usec;
+
+	offset_usec = modf(offset, &offset_sec) * 1000000;
+	ts->tv_sec  += (long) offset_sec;
+	ts->tv_usec += (long) offset_usec;
+	if (ts->tv_usec > 1000000) {
+		ts->tv_sec++;
+		ts->tv_usec -= 1000000;
+	}
+}
+
+static int tv_gt(struct timeval a, struct timeval b)
+{
+	/* Returns (a>b) */
+	if (a.tv_sec > b.tv_sec) {
+		return TRUE;
+	}
+	if (a.tv_sec < b.tv_sec) {
+		return FALSE;
+	}
+	assert(a.tv_sec == b.tv_sec);
+	return a.tv_usec > b.tv_usec;
+}
+
+static int ssrc_hash(uint32_t ssrc)
+{
+	/* Hash from an ssrc to a position in the source database.   */
+	/* Assumes that ssrc values are uniformly distributed, which */
+	/* should be true but probably isn't (Rosenberg has reported */
+	/* that many implementations generate ssrc values which are  */
+	/* not uniformly distributed over the space, and the H.323   */
+	/* spec requires that they are non-uniformly distributed).   */
+	/* This routine is written as a function rather than inline  */
+	/* code to allow it to be made smart in future: probably we  */
+	/* should run MD5 on the ssrc and derive a hash value from   */
+	/* that, to ensure it's more uniformly distributed?          */
+	return ssrc % RTP_DB_SIZE;
+}
+
+static void insert_rr(struct rtp *session, uint32_t reporter_ssrc, rtcp_rr *rr, struct timeval *ts)
+{
+        /* Insert the reception report into the receiver report      */
+        /* database. This database is a two dimensional table of     */
+        /* rr_wrappers indexed by hashes of reporter_ssrc and        */
+        /* reportee_src.  The rr_wrappers in the database are        */
+        /* sentinels to reduce conditions in list operations.        */
+	/* The ts is used to determine when to timeout this rr.      */
+
+        rtcp_rr_wrapper *cur, *start;
+
+        start = &session->rr[ssrc_hash(reporter_ssrc)][ssrc_hash(rr->ssrc)];
+        cur   = start->next;
+
+        while (cur != start) {
+                if (cur->reporter_ssrc == reporter_ssrc && cur->rr->ssrc == rr->ssrc) {
+                        /* Replace existing entry in the database  */
+                        xfree(cur->rr);
+			xfree(cur->ts);
+                        cur->rr = rr;
+			cur->ts = (struct timeval *) xmalloc(sizeof(struct timeval));
+			memcpy(cur->ts, ts, sizeof(struct timeval));
+                        return;
+                }
+                cur = cur->next;
+        }
+        
+        /* No entry in the database so create one now. */
+        cur = (rtcp_rr_wrapper*)xmalloc(sizeof(rtcp_rr_wrapper));
+        cur->reporter_ssrc = reporter_ssrc;
+        cur->rr = rr;
+	cur->ts = (struct timeval *) xmalloc(sizeof(struct timeval));
+	memcpy(cur->ts, ts, sizeof(struct timeval));
+        /* Fix links */
+        cur->next       = start->next;
+        cur->next->prev = cur;
+        cur->prev       = start;
+        cur->prev->next = cur;
+
+        debug_msg("Created new rr entry for 0x%08lx from source 0x%08lx\n", rr->ssrc, reporter_ssrc);
+        return;
+}
+
+static void remove_rr(struct rtp *session, uint32_t ssrc)
+{
+	/* Remove any RRs from "s" which refer to "ssrc" as either   */
+        /* reporter or reportee.                                     */
+        rtcp_rr_wrapper *start, *cur, *tmp;
+        int i;
+
+        /* Remove rows, i.e. ssrc == reporter_ssrc                   */
+        for(i = 0; i < RTP_DB_SIZE; i++) {
+                start = &session->rr[ssrc_hash(ssrc)][i];
+                cur   = start->next;
+                while (cur != start) {
+                        if (cur->reporter_ssrc == ssrc) {
+                                tmp = cur;
+                                cur = cur->prev;
+                                tmp->prev->next = tmp->next;
+                                tmp->next->prev = tmp->prev;
+				xfree(tmp->ts);
+                                xfree(tmp->rr);
+                                xfree(tmp);
+                        }
+                        cur = cur->next;
+                }
+        }
+
+        /* Remove columns, i.e.  ssrc == reporter_ssrc */
+        for(i = 0; i < RTP_DB_SIZE; i++) {
+                start = &session->rr[i][ssrc_hash(ssrc)];
+                cur   = start->next;
+                while (cur != start) {
+                        if (cur->rr->ssrc == ssrc) {
+                                tmp = cur;
+                                cur = cur->prev;
+                                tmp->prev->next = tmp->next;
+                                tmp->next->prev = tmp->prev;
+				xfree(tmp->ts);
+                                xfree(tmp->rr);
+                                xfree(tmp);
+                        }
+                        cur = cur->next;
+                }
+        }
+}
+
+static void timeout_rr(struct rtp *session, struct timeval *curr_ts)
+{
+	/* Timeout any reception reports which have been in the database for more than 3 */
+	/* times the RTCP reporting interval without refresh.                            */
+        rtcp_rr_wrapper *start, *cur, *tmp;
+	rtp_event	 event;
+        int 		 i, j;
+
+        for(i = 0; i < RTP_DB_SIZE; i++) {
+        	for(j = 0; j < RTP_DB_SIZE; j++) {
+			start = &session->rr[i][j];
+			cur   = start->next;
+			while (cur != start) {
+				if (tv_diff(*curr_ts, *(cur->ts)) > (session->rtcp_interval * 3)) {
+					/* Signal the application... */
+					if (!filter_event(session, cur->reporter_ssrc)) {
+						event.ssrc = cur->reporter_ssrc;
+						event.type = RR_TIMEOUT;
+						event.data = cur->rr;
+						event.ts   = curr_ts;
+						session->callback(session, &event);
+					}
+					/* Delete this reception report... */
+					tmp = cur;
+					cur = cur->prev;
+					tmp->prev->next = tmp->next;
+					tmp->next->prev = tmp->prev;
+					xfree(tmp->ts);
+					xfree(tmp->rr);
+					xfree(tmp);
+				}
+				cur = cur->next;
+			}
+		}
+	}
+}
+
+static const rtcp_rr* get_rr(struct rtp *session, uint32_t reporter_ssrc, uint32_t reportee_ssrc)
+{
+        rtcp_rr_wrapper *cur, *start;
+
+        start = &session->rr[ssrc_hash(reporter_ssrc)][ssrc_hash(reportee_ssrc)];
+        cur   = start->next;
+        while (cur != start) {
+                if (cur->reporter_ssrc == reporter_ssrc &&
+                    cur->rr->ssrc      == reportee_ssrc) {
+                        return cur->rr;
+                }
+                cur = cur->next;
+        }
+        return NULL;
+}
+
+static void check_source(source *s)
+{
+	assert(s != NULL);
+	assert(s->magic == 0xc001feed);
+}
+
+static void check_database(struct rtp *session)
+{
+	/* This routine performs a sanity check on the database. */
+	/* This should not call any of the other routines which  */
+	/* manipulate the database, to avoid common failures.    */
+#ifdef DEBUG
+	source 	 	*s;
+	int	 	 source_count;
+	int		 chain;
+#endif
+	assert(session != NULL);
+	assert(session->magic == 0xfeedface);
+#ifdef DEBUG
+	/* Check that we have a database entry for our ssrc... */
+	/* We only do this check if ssrc_count > 0 since it is */
+	/* performed during initialisation whilst creating the */
+	/* source entry for my_ssrc.                           */
+	if (session->ssrc_count > 0) {
+		for (s = session->db[ssrc_hash(session->my_ssrc)]; s != NULL; s = s->next) {
+			if (s->ssrc == session->my_ssrc) {
+				break;
+			}
+		}
+		assert(s != NULL);
+	}
+
+	source_count = 0;
+	for (chain = 0; chain < RTP_DB_SIZE; chain++) {
+		/* Check that the linked lists making up the chains in */
+		/* the hash table are correctly linked together...     */
+		for (s = session->db[chain]; s != NULL; s = s->next) {
+			check_source(s);
+			source_count++;
+			if (s->prev == NULL) {
+				assert(s == session->db[chain]);
+			} else {
+				assert(s->prev->next == s);
+			}
+			if (s->next != NULL) {
+				assert(s->next->prev == s);
+			}
+			/* Check that the SR is for this source... */
+			if (s->sr != NULL) {
+				assert(s->sr->ssrc == s->ssrc);
+			}
+		}
+	}
+	/* Check that the number of entries in the hash table  */
+	/* matches session->ssrc_count                         */
+	assert(source_count == session->ssrc_count);
+#endif
+}
+
+static source *get_source(struct rtp *session, uint32_t ssrc)
+{
+	source *s;
+
+	check_database(session);
+	for (s = session->db[ssrc_hash(ssrc)]; s != NULL; s = s->next) {
+		if (s->ssrc == ssrc) {
+			check_source(s);
+			return s;
+		}
+	}
+	return NULL;
+}
+
+static source *create_source(struct rtp *session, uint32_t ssrc)
+{
+	/* Create a new source entry, and add it to the database.    */
+	/* The database is a hash table, using the separate chaining */
+	/* algorithm.                                                */
+	rtp_event	 event;
+	struct timeval	 event_ts;
+	source		*s = get_source(session, ssrc);
+	int		 h;
+
+	if (s != NULL) {
+		/* Source is already in the database... Mark it as */
+		/* active and exit (this is the common case...)    */
+		gettimeofday(&(s->last_active), NULL);
+		return s;
+	}
+	check_database(session);
+	/* This is a new source, we have to create it... */
+	h = ssrc_hash(ssrc);
+	s = (source *) xmalloc(sizeof(source));
+	s->magic          = 0xc001feed;
+	s->next           = session->db[h];
+	s->prev           = NULL;
+	s->ssrc           = ssrc;
+	s->cname          = NULL;
+	s->name           = NULL;
+	s->email          = NULL;
+	s->phone          = NULL;
+	s->loc            = NULL;
+	s->tool           = NULL;
+	s->note           = NULL;
+	s->sr             = NULL;
+	s->got_bye        = FALSE;
+	s->sender         = FALSE;
+	s->base_seq       = 0;
+	s->max_seq        = 0;
+	s->bad_seq        = 0;
+	s->cycles         = 0;
+	s->received       = 0;
+	s->received_prior = 0;
+	s->expected_prior = 0;
+	s->probation      = -1;
+	s->jitter         = 0;
+	s->transit        = 0;
+	gettimeofday(&(s->last_active), NULL);
+	/* Now, add it to the database... */
+	if (session->db[h] != NULL) {
+		session->db[h]->prev = s;
+	}
+	session->db[ssrc_hash(ssrc)] = s;
+	session->ssrc_count++;
+	check_database(session);
+
+	debug_msg("Created database entry for ssrc 0x%08lx\n", ssrc);
+        if (ssrc != session->my_ssrc) {
+                /* Do not send during rtp_init since application cannot map the address */
+                /* of the rtp session to anything since rtp_init has not returned yet.  */
+		if (!filter_event(session, ssrc)) {
+			gettimeofday(&event_ts, NULL);
+			event.ssrc = ssrc;
+			event.type = SOURCE_CREATED;
+			event.data = NULL;
+			event.ts   = &event_ts;
+			session->callback(session, &event);
+		}
+        }
+
+	return s;
+}
+
+static void delete_source(struct rtp *session, uint32_t ssrc)
+{
+	/* Remove a source from the RTP database... */
+	source		*s = get_source(session, ssrc);
+	int		 h = ssrc_hash(ssrc);
+	rtp_event	 event;
+	struct timeval	 event_ts;
+
+	assert(s != NULL);	/* Deleting a source which doesn't exist is an error... */
+
+	gettimeofday(&event_ts, NULL);
+
+	check_source(s);
+	check_database(session);
+	if (session->db[h] == s) {
+		/* It's the first entry in this chain... */
+		session->db[h] = s->next;
+		if (s->next != NULL) {
+			s->next->prev = NULL;
+		}
+	} else {
+		assert(s->prev != NULL);	/* Else it would be the first in the chain... */
+		s->prev->next = s->next;
+		if (s->next != NULL) {
+			s->next->prev = s->prev;
+		}
+	}
+	/* Free the memory allocated to a source... */
+	if (s->cname != NULL) xfree(s->cname);
+	if (s->name  != NULL) xfree(s->name);
+	if (s->email != NULL) xfree(s->email);
+	if (s->phone != NULL) xfree(s->phone);
+	if (s->loc   != NULL) xfree(s->loc);
+	if (s->tool  != NULL) xfree(s->tool);
+	if (s->note  != NULL) xfree(s->note);
+	if (s->sr    != NULL) xfree(s->sr);
+
+        remove_rr(session, ssrc); 
+
+	/* Reduce our SSRC count, and perform reverse reconsideration on the RTCP */
+	/* reporting interval (draft-ietf-avt-rtp-new-05.txt, section 6.3.4). To  */
+	/* make the transmission rate of RTCP packets more adaptive to changes in */
+	/* group membership, the following "reverse reconsideration" algorithm    */
+	/* SHOULD be executed when a BYE packet is received that reduces members  */
+	/* to a value less than pmembers:                                         */
+	/* o  The value for tn is updated according to the following formula:     */
+	/*       tn = tc + (members/pmembers)(tn - tc)                            */
+	/* o  The value for tp is updated according the following formula:        */
+	/*       tp = tc - (members/pmembers)(tc - tp).                           */
+	/* o  The next RTCP packet is rescheduled for transmission at time tn,    */
+	/*    which is now earlier.                                               */
+	/* o  The value of pmembers is set equal to members.                      */
+	session->ssrc_count--;
+	if (session->ssrc_count < session->ssrc_count_prev) {
+		tv_add(&(session->next_rtcp_send_time), (session->ssrc_count / session->ssrc_count_prev) 
+						     * tv_diff(session->next_rtcp_send_time, event_ts));
+		tv_add(&(session->last_rtcp_send_time), - ((session->ssrc_count / session->ssrc_count_prev) 
+						     * tv_diff(event_ts, session->next_rtcp_send_time)));
+		session->ssrc_count_prev = session->ssrc_count;
+	}
+
+	/* Signal to the application that this source is dead... */
+	if (!filter_event(session, ssrc)) {
+		event.ssrc = ssrc;
+		event.type = SOURCE_DELETED;
+		event.data = NULL;
+		event.ts   = &event_ts;
+		session->callback(session, &event);
+	}
+        xfree(s);
+	check_database(session);
+}
+
+static void init_seq(source *s, uint16_t seq)
+{
+	/* Taken from draft-ietf-avt-rtp-new-01.txt */
+	check_source(s);
+	s->base_seq = seq;
+	s->max_seq = seq;
+	s->bad_seq = RTP_SEQ_MOD + 1;
+	s->cycles = 0;
+	s->received = 0;
+	s->received_prior = 0;
+	s->expected_prior = 0;
+}
+
+static int update_seq(source *s, uint16_t seq)
+{
+	/* Taken from draft-ietf-avt-rtp-new-01.txt */
+	uint16_t udelta = seq - s->max_seq;
+
+	/*
+	 * Source is not valid until MIN_SEQUENTIAL packets with
+	 * sequential sequence numbers have been received.
+	 */
+	check_source(s);
+	if (s->probation) {
+		  /* packet is in sequence */
+		  if (seq == s->max_seq + 1) {
+				s->probation--;
+				s->max_seq = seq;
+				if (s->probation == 0) {
+					 init_seq(s, seq);
+					 s->received++;
+					 return 1;
+				}
+		  } else {
+				s->probation = MIN_SEQUENTIAL - 1;
+				s->max_seq = seq;
+		  }
+		  return 0;
+	} else if (udelta < MAX_DROPOUT) {
+		  /* in order, with permissible gap */
+		  if (seq < s->max_seq) {
+				/*
+				 * Sequence number wrapped - count another 64K cycle.
+				 */
+				s->cycles += RTP_SEQ_MOD;
+		  }
+		  s->max_seq = seq;
+	} else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
+		  /* the sequence number made a very large jump */
+		  if (seq == s->bad_seq) {
+				/*
+				 * Two sequential packets -- assume that the other side
+				 * restarted without telling us so just re-sync
+				 * (i.e., pretend this was the first packet).
+				 */
+				init_seq(s, seq);
+		  } else {
+				s->bad_seq = (seq + 1) & (RTP_SEQ_MOD-1);
+				return 0;
+		  }
+	} else {
+		  /* duplicate or reordered packet */
+	}
+	s->received++;
+	return 1;
+}
+
+static double rtcp_interval(struct rtp *session)
+{
+	/* Minimum average time between RTCP packets from this site (in   */
+	/* seconds).  This time prevents the reports from `clumping' when */
+	/* sessions are small and the law of large numbers isn't helping  */
+	/* to smooth out the traffic.  It also keeps the report interval  */
+	/* from becoming ridiculously small during transient outages like */
+	/* a network partition.                                           */
+	double const RTCP_MIN_TIME = 5.0;
+	/* Fraction of the RTCP bandwidth to be shared among active       */
+	/* senders.  (This fraction was chosen so that in a typical       */
+	/* session with one or two active senders, the computed report    */
+	/* time would be roughly equal to the minimum report time so that */
+	/* we don't unnecessarily slow down receiver reports.) The        */
+	/* receiver fraction must be 1 - the sender fraction.             */
+	double const RTCP_SENDER_BW_FRACTION = 0.25;
+	double const RTCP_RCVR_BW_FRACTION   = (1-RTCP_SENDER_BW_FRACTION);
+	/* To compensate for "unconditional reconsideration" converging   */
+	/* to a value below the intended average.                         */
+	double const COMPENSATION            = 2.71828 - 1.5;
+
+	double t;				              /* interval */
+	double rtcp_min_time = RTCP_MIN_TIME;
+	int n;			        /* no. of members for computation */
+	double rtcp_bw = session->rtcp_bw;
+
+	/* Very first call at application start-up uses half the min      */
+	/* delay for quicker notification while still allowing some time  */
+	/* before reporting for randomization and to learn about other    */
+	/* sources so the report interval will converge to the correct    */
+	/* interval more quickly.                                         */
+	if (session->initial_rtcp) {
+		rtcp_min_time /= 2;
+	}
+
+	/* If there were active senders, give them at least a minimum     */
+	/* share of the RTCP bandwidth.  Otherwise all participants share */
+	/* the RTCP bandwidth equally.                                    */
+	n = session->ssrc_count;
+	if (session->sender_count > 0 && session->sender_count < session->ssrc_count * RTCP_SENDER_BW_FRACTION) {
+		if (session->we_sent) {
+			rtcp_bw *= RTCP_SENDER_BW_FRACTION;
+			n = session->sender_count;
+		} else {
+			rtcp_bw *= RTCP_RCVR_BW_FRACTION;
+			n -= session->sender_count;
+		}
+	}
+
+	/* The effective number of sites times the average packet size is */
+	/* the total number of octets sent when each site sends a report. */
+	/* Dividing this by the effective bandwidth gives the time        */
+	/* interval over which those packets must be sent in order to     */
+	/* meet the bandwidth target, with a minimum enforced.  In that   */
+	/* time interval we send one report so this time is also our      */
+	/* average time between reports.                                  */
+	t = session->avg_rtcp_size * n / rtcp_bw;
+	if (t < rtcp_min_time) {
+		t = rtcp_min_time;
+	}
+	session->rtcp_interval = t;
+
+	/* To avoid traffic bursts from unintended synchronization with   */
+	/* other sites, we then pick our actual next report interval as a */
+	/* random number uniformly distributed between 0.5*t and 1.5*t.   */
+	return (t * (drand48() + 0.5)) / COMPENSATION;
+}
+
+#define MAXCNAMELEN	255
+
+static char *get_cname(socket_udp *s)
+{
+        /* Set the CNAME. This is "user@hostname" or just "hostname" if the username cannot be found. */
+        const char              *hname;
+        char                    *uname;
+        char                    *cname;
+#ifndef WIN32
+        struct passwd           *pwent;
+#else
+        char *name;
+        int   namelen;
+#endif
+
+        cname = (char *) xmalloc(MAXCNAMELEN + 1);
+        cname[0] = '\0';
+
+        /* First, fill in the username... */
+#ifdef WIN32
+        name = NULL;
+        namelen = 0;
+        GetUserName(NULL, &namelen);
+        if (namelen > 0) {
+                name = (char*)xmalloc(namelen+1);
+                GetUserName(name, &namelen);
+        } else {
+                uname = getenv("USER");
+                if (uname != NULL) {
+                        name = xstrdup(uname);
+                }
+        }
+        if (name != NULL) {
+                strncpy(cname, name, MAXCNAMELEN - 1);
+                strcat(cname, "@");
+                xfree(name);
+        }
+#else
+        pwent = getpwuid(getuid());
+        uname = pwent->pw_name;
+        if (uname != NULL) {
+                strncpy(cname, uname, MAXCNAMELEN - 1);
+                strcat(cname, "@");
+        }
+
+#endif
+        
+        /* Now the hostname. Must be dotted-quad IP address. */
+        hname = udp_host_addr(s);
+        strncpy(cname + strlen(cname), hname, MAXCNAMELEN - strlen(cname));
+        return cname;
+}
+
+static void init_opt(struct rtp *session)
+{
+	/* Default option settings. */
+	rtp_setopt(session, RTP_OPT_PROMISC,           FALSE);
+	rtp_setopt(session, RTP_OPT_WEAK_VALIDATION,   TRUE);
+	rtp_setopt(session, RTP_OPT_FILTER_MY_PACKETS, FALSE);
+}
+
+static void init_rng(const char *s)
+{
+        static uint32_t seed;
+        if (seed == 0) {
+                pid_t p = getpid();
+                while (*s) {
+                        seed += (uint32_t)*s++;
+                        seed = seed * 31 + 1;
+                }
+                seed = 1 + seed * 31 + (uint32_t)p;
+                srand48(seed);
+        }
+}
+
+struct rtp *rtp_init(char *addr, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, 
+                     void (*callback)(struct rtp *session, rtp_event *e),
+                     void *userdata)
+{
+	return rtp_init_if(addr, NULL, rx_port, tx_port, ttl, rtcp_bw, callback, userdata);
+}
+
+struct rtp *rtp_init_if(char *addr, char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, 
+                        void (*callback)(struct rtp *session, rtp_event *e),
+                        void *userdata)
+{
+	struct rtp 	*session;
+	int         	 i, j;
+	char		*cname;
+
+	assert(ttl >= 0 && ttl < 128);
+	assert(rx_port % 2 == 0);
+	assert(tx_port % 2 == 0);
+	session 		= (struct rtp *) xmalloc(sizeof(struct rtp));
+	session->magic		= 0xfeedface;
+	session->opt		= (options *) xmalloc(sizeof(options));
+	session->userdata	= userdata;
+	session->addr		= xstrdup(addr);
+	session->rx_port	= rx_port;
+	session->tx_port	= tx_port;
+	session->ttl		= ttl;
+	session->rtp_socket	= udp_init_if(addr, iface, rx_port, tx_port, ttl);
+	session->rtcp_socket	= udp_init_if(addr, iface, (uint16_t) (rx_port+1), (uint16_t) (tx_port+1), ttl);
+
+	init_opt(session);
+
+	if (session->rtp_socket == NULL || session->rtcp_socket == NULL) {
+		xfree(session);
+		return NULL;
+	}
+
+        init_rng(udp_host_addr(session->rtp_socket));
+
+	session->my_ssrc            = (uint32_t) lrand48();
+	session->callback           = callback;
+	session->invalid_rtp_count  = 0;
+	session->invalid_rtcp_count = 0;
+	session->ssrc_count         = 0;
+	session->ssrc_count_prev    = 0;
+	session->sender_count       = 0;
+	session->initial_rtcp       = TRUE;
+	session->avg_rtcp_size      = 70.0;	/* Guess for a sensible starting point... */
+	session->we_sent            = FALSE;
+	session->rtcp_bw            = rtcp_bw;
+	session->sdes_count_pri     = 0;
+	session->sdes_count_sec     = 0;
+	session->sdes_count_ter     = 0;
+	session->rtp_seq            = (uint16_t) lrand48();
+	session->rtp_pcount         = 0;
+	session->rtp_bcount         = 0;
+	gettimeofday(&(session->last_update), NULL);
+	gettimeofday(&(session->last_rtcp_send_time), NULL);
+	gettimeofday(&(session->next_rtcp_send_time), NULL);
+        session->encryption_key      = NULL;
+
+	/* Calculate when we're supposed to send our first RTCP packet... */
+	tv_add(&(session->next_rtcp_send_time), rtcp_interval(session));
+
+	/* Initialise the source database... */
+	for (i = 0; i < RTP_DB_SIZE; i++) {
+		session->db[i] = NULL;
+	}
+
+        /* Initialize sentinels in rr table */
+        for (i = 0; i < RTP_DB_SIZE; i++) {
+                for (j = 0; j < RTP_DB_SIZE; j++) {
+                        session->rr[i][j].next = &session->rr[i][j];
+                        session->rr[i][j].prev = &session->rr[i][j];
+                }
+        }
+
+	/* Create a database entry for ourselves... */
+	create_source(session, session->my_ssrc);
+	cname = get_cname(session->rtp_socket);
+	rtp_set_sdes(session, session->my_ssrc, RTCP_SDES_CNAME, cname, strlen(cname));
+	xfree(cname);	/* cname is copied by rtp_set_sdes()... */
+
+	return session;
+}
+
+int rtp_set_my_ssrc(struct rtp *session, uint32_t ssrc)
+{
+        source *s;
+        uint32_t h;
+        /* Sets my_ssrc when called immediately after rtp_init. */
+        /* Returns TRUE on success, FALSE otherwise.  Needed to */
+        /* co-ordinate SSRC's between LAYERED SESSIONS, SHOULD  */
+        /* NOT BE USED OTHERWISE.                               */
+        if (session->ssrc_count != 1 && session->sender_count != 0) {
+                return FALSE;
+        }
+        /* Remove existing source */
+        h = ssrc_hash(session->my_ssrc);
+        s = session->db[h];
+        session->db[h] = NULL;
+        /* Fill in new ssrc       */
+        session->my_ssrc = ssrc;
+        s->ssrc          = ssrc;
+        h                = ssrc_hash(ssrc);
+        /* Put source back        */
+        session->db[h]   = s;
+        return TRUE;
+}
+
+int rtp_setopt(struct rtp *session, int optname, int optval)
+{
+	assert((optval == TRUE) || (optval == FALSE));
+
+	switch (optname) {
+		case RTP_OPT_WEAK_VALIDATION:
+			session->opt->wait_for_rtcp = optval;
+			break;
+	        case RTP_OPT_PROMISC:
+			session->opt->promiscuous_mode = optval;
+			break;
+	        case RTP_OPT_FILTER_MY_PACKETS:
+			session->opt->filter_my_packets = optval;
+			break;
+        	default:
+			debug_msg("Ignoring unknown option (%d) in call to rtp_setopt().\n", optname);
+                        return FALSE;
+	}
+        return TRUE;
+}
+
+int rtp_getopt(struct rtp *session, int optname, int *optval)
+{
+	switch (optname) {
+		case RTP_OPT_WEAK_VALIDATION:
+			*optval = session->opt->wait_for_rtcp;
+                        break;
+        	case RTP_OPT_PROMISC:
+			*optval = session->opt->promiscuous_mode;
+                        break;
+	        case RTP_OPT_FILTER_MY_PACKETS:
+			*optval = session->opt->filter_my_packets;
+			break;
+        	default:
+                        *optval = 0;
+			debug_msg("Ignoring unknown option (%d) in call to rtp_getopt().\n", optname);
+                        return FALSE;
+	}
+        return TRUE;
+}
+
+void *rtp_get_userdata(struct rtp *session)
+{
+	check_database(session);
+	return session->userdata;
+}
+
+uint32_t rtp_my_ssrc(struct rtp *session)
+{
+	check_database(session);
+	return session->my_ssrc;
+}
+
+static int validate_rtp(rtp_packet *packet, int len)
+{
+	/* This function checks the header info to make sure that the packet */
+	/* is valid. We return TRUE if the packet is valid, FALSE otherwise. */
+	/* See Appendix A.1 of the RTP specification.                        */
+
+	/* We only accept RTPv2 packets... */
+	if (packet->v != 2) {
+		debug_msg("rtp_header_validation: v != 2\n");
+		return FALSE;
+	}
+	/* Check for valid payload types..... 72-76 are RTCP payload type numbers, with */
+	/* the high bit missing so we report that someone is running on the wrong port. */
+	if (packet->pt >= 72 && packet->pt <= 76) {
+		debug_msg("rtp_header_validation: payload-type invalid");
+		if (packet->m) {
+			debug_msg(" (RTCP packet on RTP port?)");
+		}
+		debug_msg("\n");
+		return FALSE;
+	}
+	/* Check that the length of the packet is sensible... */
+	if (len < (12 + (4 * packet->cc))) {
+		debug_msg("rtp_header_validation: packet length is smaller than the header\n");
+		return FALSE;
+	}
+	/* Check that the length of any header extension is sensible... */
+        if (packet->x) {
+		if (packet->extn_len > (len - 12 - (4 * packet->cc) - packet->p?packet->data[packet->data_len-1]:0)) {
+			debug_msg("rtp_header_validation: extension header is too big!\n");
+			return FALSE;
+		}
+        }
+	/* Check that the amount of padding specified is sensible. */
+	/* Note: have to include the size of any extension header! */
+	if (packet->p) {
+		int	payload_len = len - 12 - (packet->cc * 4) - (packet->extn_len * 4) - packet->extn_len>0?4:0;
+                if (packet->data[packet->data_len-1] > payload_len) {
+                        debug_msg("rtp_header_validation: padding greater than payload length\n");
+                        return FALSE;
+                }
+                if (packet->data[packet->data_len-1] < 1) {
+			debug_msg("rtp_header_validation: padding zero\n");
+			return FALSE;
+		}
+        }
+	return TRUE;
+}
+
+static void process_rtp(struct rtp *session, uint32_t curr_time, rtp_packet *packet, source *s)
+{
+	int		 i, d, transit;
+	rtp_event	 event;
+	struct timeval	 event_ts;
+
+	if (packet->cc > 0) {
+		for (i = 0; i < packet->cc; i++) {
+			create_source(session, packet->csrc[i]);
+		}
+	}
+	/* Update the source database... */
+	if (s->sender == FALSE) {
+		s->sender = TRUE;
+		session->sender_count++;
+	}
+	transit    = curr_time - packet->ts;
+	d      	   = transit - s->transit;
+	s->transit = transit;
+	if (d < 0) {
+		d = -d;
+	}
+	s->jitter += d - ((s->jitter + 8) / 16);
+	
+	/* Callback to the application to process the packet... */
+	if (!filter_event(session, packet->ssrc)) {
+		gettimeofday(&event_ts, NULL);
+		event.ssrc = packet->ssrc;
+		event.type = RX_RTP;
+		event.data = (void *) packet;	/* The callback function MUST free this! */
+		event.ts   = &event_ts;
+		session->callback(session, &event);
+	}
+}
+
+static void rtp_recv_data(struct rtp *session, uint32_t curr_time)
+{
+	/* This routine preprocesses an incoming RTP packet, deciding whether to process it. */
+	rtp_packet	*packet = (rtp_packet *) xmalloc(RTP_MAX_PACKET_LEN);
+	uint8_t		*buffer = ((uint8_t *) packet) + RTP_PACKET_HEADER_SIZE;
+	int		 buflen;
+	source		*s;
+	uint8_t 	 initVec[8] = {0,0,0,0,0,0,0,0};
+
+	buflen = udp_recv(session->rtp_socket, buffer, RTP_MAX_PACKET_LEN - RTP_PACKET_HEADER_SIZE);
+	if (buflen > 0) {
+		if (session->encryption_key != NULL) {
+			qfDES_CBC_d(session->encryption_key, buffer, buflen, initVec);
+		}
+		/* Convert header fields to host byte order... */
+		packet->seq      = ntohs(packet->seq);
+		packet->ts       = ntohl(packet->ts);
+		packet->ssrc     = ntohl(packet->ssrc);
+		/* Setup internal pointers, etc... */
+		if (packet->cc) {
+			packet->csrc = (uint32_t *)(buffer + 12);
+		} else {
+			packet->csrc = NULL;
+		}
+		if (packet->x) {
+			packet->extn     = buffer + 12 + (packet->cc * 4);
+			packet->extn_len = (packet->extn[2] << 16) | packet->extn[3];
+		} else {
+			packet->extn     = NULL;
+			packet->extn_len = 0;
+		}
+		packet->data     = buffer + 12 + (packet->cc * 4) + packet->extn_len;
+		packet->data_len = buflen - packet->extn_len - (packet->cc * 4) - 12;
+		if (validate_rtp(packet, buflen)) {
+                        int weak = 0, promisc = 0;
+                        rtp_getopt(session, RTP_OPT_WEAK_VALIDATION, &weak);
+			if (weak) {
+				s = get_source(session, packet->ssrc);
+			} else {
+				s = create_source(session, packet->ssrc);
+			}
+                        rtp_getopt(session, RTP_OPT_PROMISC, &promisc);
+			if (promisc) {
+				if (s == NULL) {
+					create_source(session, packet->ssrc);
+					s = get_source(session, packet->ssrc);
+				}
+				process_rtp(session, curr_time, packet, s);
+				return; /* We don't free "packet", that's done by the callback function... */
+			} 
+			if (s != NULL) {
+				if (s->probation == -1) {
+					s->probation = MIN_SEQUENTIAL;
+					s->max_seq   = packet->seq - 1;
+				}
+				if (update_seq(s, packet->seq)) {
+					process_rtp(session, curr_time, packet, s);
+					return;	/* we don't free "packet", that's done by the callback function... */
+				} else {
+					/* This source is still on probation... */
+					debug_msg("RTP packet from probationary source ignored...\n");
+				}
+			} else {
+				debug_msg("RTP packet from unknown source ignored\n");
+			}
+		} else {
+			session->invalid_rtp_count++;
+			debug_msg("Invalid RTP packet discarded\n");
+		}
+	}
+	xfree(packet);
+}
+
+static int validate_rtcp(uint8_t *packet, int len)
+{
+	/* Validity check for a compound RTCP packet. This function returns */
+	/* TRUE if the packet is okay, FALSE if the validity check fails.   */
+        /*                                                                  */
+	/* The following checks can be applied to RTCP packets [RFC1889]:   */
+        /* o RTP version field must equal 2.                                */
+        /* o The payload type field of the first RTCP packet in a compound  */
+        /*   packet must be equal to SR or RR.                              */
+        /* o The padding bit (P) should be zero for the first packet of a   */
+        /*   compound RTCP packet because only the last should possibly     */
+        /*   need padding.                                                  */
+        /* o The length fields of the individual RTCP packets must total to */
+        /*   the overall length of the compound RTCP packet as received.    */
+
+	rtcp_t	*pkt  = (rtcp_t *) packet;
+	rtcp_t	*end  = (rtcp_t *) (((char *) pkt) + len);
+	rtcp_t	*r    = pkt;
+	int	 l    = 0;
+	int	 last = 0;
+	int	 pc   = 1;
+
+	/* All RTCP packets must be compound packets (RFC1889, section 6.1) */
+	if (((ntohs(pkt->common.length) + 1) * 4) == len) {
+		debug_msg("Bogus RTCP packet: not a compound packet\n");
+		return FALSE;
+	}
+
+	/* Check the RTCP version, payload type and padding of the first in  */
+	/* the compund RTCP packet...                                        */
+	if (pkt->common.version != 2) {
+		debug_msg("Bogus RTCP packet: version number != 2 in the first sub-packet\n");
+		return FALSE;
+	}
+	if (pkt->common.p != 0) {
+		debug_msg("Bogus RTCP packet: padding bit is set on first packet in compound\n");
+		return FALSE;
+	}
+	if ((pkt->common.pt != RTCP_SR) && (pkt->common.pt != RTCP_RR)) {
+		debug_msg("Bogus RTCP packet: compund packet does not start with SR or RR\n");
+		return FALSE;
+	}
+
+	/* Check all following parts of the compund RTCP packet. The RTP version */
+	/* number must be 2, and the padding bit must be zero on all apart from  */
+	/* the last packet.                                                      */
+	do {
+		if (r->common.version != 2) {
+			debug_msg("Bogus RTCP packet: version number != 2 in sub-packet %d\n", pc);
+			return FALSE;
+		}
+		if (last == 1) {
+			debug_msg("Bogus RTCP packet: padding bit set before last in compound (sub-packet %d)\n", pc);
+			return FALSE;
+		}
+		if (r->common.p == 1) last = 1;
+		l += (ntohs(r->common.length) + 1) * 4;
+		r  = (rtcp_t *) (((uint32_t *) r) + ntohs(r->common.length) + 1);
+		pc++;	/* count of sub-packets, for debugging... */
+	} while (r < end);
+
+	/* Check that the length of the packets matches the length of the UDP */
+	/* packet in which they were received...                              */
+	if (l != len) {
+		debug_msg("Bogus RTCP packet: RTCP packet length does not match UDP packet length (%d != %d)\n", l, len);
+		return FALSE;
+	}
+	if (r != end) {
+		debug_msg("Bogus RTCP packet: RTCP packet length does not match UDP packet length (%p != %p)\n", r, end);
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static void process_report_blocks(struct rtp *session, rtcp_t *packet, uint32_t ssrc, rtcp_rr *rrp, struct timeval *event_ts)
+{
+	int i;
+	rtp_event	 event;
+	rtcp_rr		*rr;
+
+	/* ...process RRs... */
+	if (packet->common.count == 0) {
+		if (!filter_event(session, ssrc)) {
+			event.ssrc = ssrc;
+			event.type = RX_RR_EMPTY;
+			event.data = NULL;
+			event.ts   = event_ts;
+			session->callback(session, &event);
+		}
+	} else {
+		for (i = 0; i < packet->common.count; i++, rrp++) {
+			rr = (rtcp_rr *) xmalloc(sizeof(rtcp_rr));
+			rr->ssrc          = ntohl(rrp->ssrc);
+			rr->fract_lost    = rrp->fract_lost;	/* Endian conversion handled in the */
+			rr->total_lost    = rrp->total_lost;	/* definition of the rtcp_rr type.  */
+			rr->last_seq      = ntohl(rrp->last_seq);
+			rr->jitter        = ntohl(rrp->jitter);
+			rr->lsr           = ntohl(rrp->lsr);
+			rr->dlsr          = ntohl(rrp->dlsr);
+
+			/* Create a database entry for this SSRC, if one doesn't already exist... */
+			create_source(session, rr->ssrc);
+
+			/* Store the RR for later use... */
+			insert_rr(session, ssrc, rr, event_ts);
+
+			/* Call the event handler... */
+			if (!filter_event(session, ssrc)) {
+				event.ssrc = ssrc;
+				event.type = RX_RR;
+				event.data = (void *) rr;
+				event.ts   = event_ts;
+				session->callback(session, &event);
+			}
+		}
+	}
+}
+
+static void process_rtcp_sr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
+{
+	uint32_t	 ssrc;
+	rtp_event	 event;
+	rtcp_sr		*sr;
+	source		*s;
+
+	ssrc = ntohl(packet->r.sr.sr.ssrc);
+	s = create_source(session, ssrc);
+	if (s == NULL) {
+		debug_msg("Source 0x%08x invalid, skipping...\n", ssrc);
+		return;
+	}
+
+	/* Process the SR... */
+	sr = (rtcp_sr *) xmalloc(sizeof(rtcp_sr));
+	sr->ssrc          = ssrc;
+	sr->ntp_sec       = ntohl(packet->r.sr.sr.ntp_sec);
+	sr->ntp_frac      = ntohl(packet->r.sr.sr.ntp_frac);
+	sr->rtp_ts        = ntohl(packet->r.sr.sr.rtp_ts);
+	sr->sender_pcount = ntohl(packet->r.sr.sr.sender_pcount);
+	sr->sender_bcount = ntohl(packet->r.sr.sr.sender_bcount);
+
+	/* Store the SR for later retrieval... */
+	if (s->sr != NULL) {
+		xfree(s->sr);
+	}
+	s->sr = sr;
+	s->last_sr = *event_ts;
+
+	/* Call the event handler... */
+	if (!filter_event(session, ssrc)) {
+		event.ssrc = ssrc;
+		event.type = RX_SR;
+		event.data = (void *) sr;
+		event.ts   = event_ts;
+		session->callback(session, &event);
+	}
+
+	process_report_blocks(session, packet, ssrc, packet->r.sr.rr, event_ts);
+
+	if (((packet->common.count * 6) + 1) < (ntohs(packet->common.length) - 5)) {
+		debug_msg("Profile specific SR extension ignored\n");
+	}
+}
+
+static void process_rtcp_rr(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
+{
+	uint32_t		 ssrc;
+	source		*s;
+
+	ssrc = ntohl(packet->r.rr.ssrc);
+	s = create_source(session, ssrc);
+	if (s == NULL) {
+		debug_msg("Source 0x%08x invalid, skipping...\n", ssrc);
+		return;
+	}
+
+	process_report_blocks(session, packet, ssrc, packet->r.rr.rr, event_ts);
+
+	if (((packet->common.count * 6) + 1) < ntohs(packet->common.length)) {
+		debug_msg("Profile specific RR extension ignored\n");
+	}
+}
+
+static void process_rtcp_sdes(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
+{
+	int 			count = packet->common.count;
+	struct rtcp_sdes_t 	*sd   = &packet->r.sdes;
+	rtcp_sdes_item 		*rsp; 
+	rtcp_sdes_item		*rspn;
+	rtcp_sdes_item 		*end  = (rtcp_sdes_item *) ((uint32_t *)packet + packet->common.length + 1);
+	source 			*s;
+	rtp_event		 event;
+
+	while (--count >= 0) {
+		rsp = &sd->item[0];
+		if (rsp >= end) {
+			break;
+		}
+		sd->ssrc = ntohl(sd->ssrc);
+		s = create_source(session, sd->ssrc);
+		if (s == NULL) {
+			debug_msg("Can't get valid source entry for 0x%08x, skipping...\n", sd->ssrc);
+		} else {
+			for (; rsp->type; rsp = rspn ) {
+				rspn = (rtcp_sdes_item *)((char*)rsp+rsp->length+2);
+				if (rspn >= end) {
+					rsp = rspn;
+					break;
+				}
+				if (rtp_set_sdes(session, sd->ssrc, rsp->type, rsp->data, rsp->length)) {
+					if (!filter_event(session, sd->ssrc)) {
+						event.ssrc = sd->ssrc;
+						event.type = RX_SDES;
+						event.data = (void *) rsp;
+						event.ts   = event_ts;
+						session->callback(session, &event);
+					}
+				} else {
+					debug_msg("Invalid sdes item for source 0x%08x, skipping...\n", sd->ssrc);
+				}
+			}
+		}
+		sd = (struct rtcp_sdes_t *) ((uint32_t *)sd + (((char *)rsp - (char *)sd) >> 2)+1);
+	}
+	if (count >= 0) {
+		debug_msg("Invalid RTCP SDES packet, some items ignored.\n");
+	}
+}
+
+static void process_rtcp_bye(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
+{
+	int		 i;
+	uint32_t		 ssrc;
+	rtp_event	 event;
+	source		*s;
+
+	for (i = 0; i < packet->common.count; i++) {
+		ssrc = ntohl(packet->r.bye.ssrc[i]);
+		/* This is kind-of strange, since we create a source we are about to delete. */
+		/* This is done to ensure that the source mentioned in the event which is    */
+		/* passed to the user of the RTP library is valid, and simplify client code. */
+		create_source(session, ssrc);
+		/* Call the event handler... */
+		if (!filter_event(session, ssrc)) {
+			event.ssrc = ssrc;
+			event.type = RX_BYE;
+			event.data = NULL;
+			event.ts   = event_ts;
+			session->callback(session, &event);
+		}
+		/* Mark the source as ready for deletion. Sources are not deleted immediately */
+		/* since some packets may be delayed and arrive after the BYE...              */
+		s = get_source(session, ssrc);
+		s->got_bye = TRUE;
+		check_source(s);
+	}
+}
+
+static void process_rtcp_app(struct rtp *session, rtcp_t *packet, struct timeval *event_ts)
+{
+	uint32_t          ssrc;
+	rtp_event        event;
+	rtcp_app        *app;
+	source          *s;
+	int              data_len;
+
+
+	/* Update the database for this source. */
+	ssrc = ntohl(packet->r.app.ssrc);
+	create_source(session, ssrc);
+	s = get_source(session, ssrc);
+	if (s == NULL) {
+	        /* This should only occur in the event of database malfunction. */
+	        debug_msg("Source 0x%08x invalid, skipping...\n", ssrc);
+	        return;
+	}
+	check_source(s);
+
+	/* Copy the entire packet, converting the header (only) into host byte order. */
+	app = (rtcp_app *) xmalloc(RTP_MAX_PACKET_LEN);
+	app->version        = packet->common.version;
+	app->p              = packet->common.p;
+	app->subtype        = packet->common.count;
+	app->pt             = packet->common.pt;
+	app->length         = ntohs(packet->common.length);
+	app->ssrc           = ssrc;
+	app->name[0]        = packet->r.app.name[0];
+	app->name[1]        = packet->r.app.name[1];
+	app->name[2]        = packet->r.app.name[2];
+	app->name[3]        = packet->r.app.name[3];
+	data_len            = (app->length - 2) * 4;
+	memcpy(app->data, packet->r.app.data, data_len);
+
+	/* Callback to the application to process the app packet... */
+	if (!filter_event(session, ssrc)) {
+		event.ssrc = ssrc;
+		event.type = RX_APP;
+		event.data = (void *) app;       /* The callback function MUST free this! */
+		event.ts   = event_ts;
+		session->callback(session, &event);
+	}
+}
+
+static void rtp_process_ctrl(struct rtp *session, uint8_t *buffer, int buflen)
+{
+	/* This routine processes incoming RTCP packets */
+	rtp_event	 event;
+	struct timeval	 event_ts;
+	rtcp_t		*packet;
+	uint8_t 	 initVec[8] = {0,0,0,0,0,0,0,0};
+	int		 first;
+	uint32_t	 packet_ssrc = rtp_my_ssrc(session);
+
+	gettimeofday(&event_ts, NULL);
+	if (buflen > 0) {
+		if (session->encryption_key != NULL) {
+			/* Decrypt the packet... */
+			qfDES_CBC_d(session->encryption_key, buffer, buflen, initVec);
+			buffer += 4;	/* Skip the random prefix... */
+			buflen -= 4;
+		}
+		if (validate_rtcp(buffer, buflen)) {
+			first  = TRUE;
+			packet = (rtcp_t *) buffer;
+			while (packet < (rtcp_t *) (buffer + buflen)) {
+				switch (packet->common.pt) {
+					case RTCP_SR:
+						if (first && !filter_event(session, ntohl(packet->r.sr.sr.ssrc))) {
+							event.ssrc  = ntohl(packet->r.sr.sr.ssrc);
+							event.type  = RX_RTCP_START;
+							event.data  = &buflen;
+							event.ts    = &event_ts;
+							packet_ssrc = event.ssrc;
+							session->callback(session, &event);
+						}
+						process_rtcp_sr(session, packet, &event_ts);
+						break;
+					case RTCP_RR:
+						if (first && !filter_event(session, ntohl(packet->r.rr.ssrc))) {
+							event.ssrc  = ntohl(packet->r.rr.ssrc);
+							event.type  = RX_RTCP_START;
+							event.data  = &buflen;
+							event.ts    = &event_ts;
+							packet_ssrc = event.ssrc;
+							session->callback(session, &event);
+						}
+						process_rtcp_rr(session, packet, &event_ts);
+						break;
+					case RTCP_SDES:
+						if (first && !filter_event(session, ntohl(packet->r.sdes.ssrc))) {
+							event.ssrc  = ntohl(packet->r.sdes.ssrc);
+							event.type  = RX_RTCP_START;
+							event.data  = &buflen;
+							event.ts    = &event_ts;
+							packet_ssrc = event.ssrc;
+							session->callback(session, &event);
+						}
+						process_rtcp_sdes(session, packet, &event_ts);
+						break;
+					case RTCP_BYE:
+						if (first && !filter_event(session, ntohl(packet->r.bye.ssrc[0]))) {
+							event.ssrc  = ntohl(packet->r.bye.ssrc[0]);
+							event.type  = RX_RTCP_START;
+							event.data  = &buflen;
+							event.ts    = &event_ts;
+							packet_ssrc = event.ssrc;
+							session->callback(session, &event);
+						}
+						process_rtcp_bye(session, packet, &event_ts);
+						break;
+				        case RTCP_APP:
+						if (first && !filter_event(session, ntohl(packet->r.app.ssrc))) {
+							event.ssrc  = ntohl(packet->r.app.ssrc);
+							event.type  = RX_RTCP_START;
+							event.data  = &buflen;
+							event.ts    = &event_ts;
+							packet_ssrc = event.ssrc;
+							session->callback(session, &event);
+						}
+					        process_rtcp_app(session, packet, &event_ts);
+						break;
+					default: 
+						debug_msg("RTCP packet with unknown type (%d) ignored.\n", packet->common.pt);
+						break;
+				}
+				packet = (rtcp_t *) ((char *) packet + (4 * (ntohs(packet->common.length) + 1)));
+				first  = FALSE;
+			}
+			/* The constants here are 1/16 and 15/16 (section 6.3.3 of draft-ietf-avt-rtp-new-02.txt) */
+			session->avg_rtcp_size = (0.0625 * buflen) + (0.9375 * session->avg_rtcp_size);
+			/* Signal that we've finished processing this packet */
+			if (!filter_event(session, packet_ssrc)) {
+				event.ssrc = packet_ssrc;
+				event.type = RX_RTCP_FINISH;
+				event.data = NULL;
+				event.ts   = &event_ts;
+				session->callback(session, &event);
+			}
+		} else {
+			debug_msg("Invalid RTCP packet discarded\n");
+			session->invalid_rtcp_count++;
+		}
+	}
+}
+
+int rtp_recv(struct rtp *session, struct timeval *timeout, uint32_t curr_time)
+{
+	check_database(session);
+	udp_fd_zero();
+	udp_fd_set(session->rtp_socket);
+	udp_fd_set(session->rtcp_socket);
+	if (udp_select(timeout) > 0) {
+		if (udp_fd_isset(session->rtp_socket)) {
+			rtp_recv_data(session, curr_time);
+		}
+		if (udp_fd_isset(session->rtcp_socket)) {
+                        uint8_t		 buffer[RTP_MAX_PACKET_LEN];
+                        int		 buflen;
+                        buflen = udp_recv(session->rtcp_socket, buffer, RTP_MAX_PACKET_LEN);
+			rtp_process_ctrl(session, buffer, buflen);
+		}
+		check_database(session);
+                return TRUE;
+	}
+	check_database(session);
+        return FALSE;
+}
+
+int rtp_add_csrc(struct rtp *session, uint32_t csrc)
+{
+	check_database(session);
+	UNUSED(csrc);
+	return FALSE;
+}
+
+int rtp_set_sdes(struct rtp *session, uint32_t ssrc, uint8_t type, char *value, int length)
+{
+	source	*s;
+	char	*v;
+
+	check_database(session);
+
+	s = get_source(session, ssrc);
+	if (s == NULL) {
+		debug_msg("Invalid source 0x%08x\n", ssrc);
+		return FALSE;
+	}
+	check_source(s);
+
+	v = (char *) xmalloc(length + 1);
+	memset(v, '\0', length + 1);
+	memcpy(v, value, length);
+
+	switch (type) {
+		case RTCP_SDES_CNAME: 
+			if (s->cname) xfree(s->cname);
+			s->cname = v; 
+			break;
+		case RTCP_SDES_NAME:
+			if (s->name) xfree(s->name);
+			s->name = v; 
+			break;
+		case RTCP_SDES_EMAIL:
+			if (s->email) xfree(s->email);
+			s->email = v; 
+			break;
+		case RTCP_SDES_PHONE:
+			if (s->phone) xfree(s->phone);
+			s->phone = v; 
+			break;
+		case RTCP_SDES_LOC:
+			if (s->loc) xfree(s->loc);
+			s->loc = v; 
+			break;
+		case RTCP_SDES_TOOL:
+			if (s->tool) xfree(s->tool);
+			s->tool = v; 
+			break;
+		case RTCP_SDES_NOTE:
+			if (s->note) xfree(s->note);
+			s->note = v; 
+			break;
+		default :
+			debug_msg("Unknown SDES item (type=%d, value=%s)\n", type, v);
+                        xfree(v);
+			check_database(session);
+			return FALSE;
+	}
+	check_database(session);
+	return TRUE;
+}
+
+const char *rtp_get_sdes(struct rtp *session, uint32_t ssrc, uint8_t type)
+{
+	source	*s;
+
+	check_database(session);
+
+	s = get_source(session, ssrc);
+	if (s == NULL) {
+		debug_msg("Invalid source 0x%08x\n", ssrc);
+		return NULL;
+	}
+	check_source(s);
+
+	switch (type) {
+		case RTCP_SDES_CNAME: 
+			return s->cname;
+		case RTCP_SDES_NAME:
+			return s->name;
+		case RTCP_SDES_EMAIL:
+			return s->email;
+		case RTCP_SDES_PHONE:
+			return s->phone;
+		case RTCP_SDES_LOC:
+			return s->loc;
+		case RTCP_SDES_TOOL:
+			return s->tool;
+		case RTCP_SDES_NOTE:
+			return s->note;
+	}
+	debug_msg("Unknown SDES item (type=%d)\n", type);
+	return NULL;
+}
+
+const rtcp_sr *rtp_get_sr(struct rtp *session, uint32_t ssrc)
+{
+	/* Return the last SR received from this ssrc. The */
+	/* caller MUST NOT free the memory returned to it. */
+	source	*s;
+
+	check_database(session);
+
+	s = get_source(session, ssrc);
+	if (s == NULL) {
+		return NULL;
+	} 
+	check_source(s);
+	return s->sr;
+}
+
+const rtcp_rr *rtp_get_rr(struct rtp *session, uint32_t reporter, uint32_t reportee)
+{
+	check_database(session);
+        return get_rr(session, reporter, reportee);
+}
+
+int rtp_send_data(struct rtp *session, uint32_t ts, char pt, int m, int cc, uint32_t csrc[], 
+                  char *data, int data_len, char *extn, int extn_len)
+{
+	int		 buffer_len, i, rc, pad, pad_len;
+	uint8_t		*buffer;
+	rtp_packet	*packet;
+	uint8_t 	 initVec[8] = {0,0,0,0,0,0,0,0};
+
+	check_database(session);
+
+	buffer_len = data_len + extn_len + 12 + (4 * cc);
+
+	/* Do we need to pad this packet to a multiple of 64 bits? */
+	/* This is only needed if encryption is enabled, since DES */
+	/* only works on multiples of 64 bits. We just calculate   */
+	/* the amount of padding to add here, so we can reserve    */
+	/* space - the actual padding is added later.              */
+	if ((session->encryption_key != NULL) && ((buffer_len % 8) != 0)) {
+		pad         = TRUE;
+		pad_len     = 8 - (buffer_len % 8);
+		buffer_len += pad_len; 
+		assert((buffer_len % 8) == 0);
+	} else {
+		pad     = FALSE;
+		pad_len = 0;
+	}
+
+	/* Allocate memory for the packet... */
+	buffer     = (uint8_t *) xmalloc(buffer_len + RTP_PACKET_HEADER_SIZE);
+	packet     = (rtp_packet *) buffer;
+
+	/* These are internal pointers into the buffer... */
+	packet->csrc = (uint32_t *) (buffer + RTP_PACKET_HEADER_SIZE + 12);
+	packet->extn = (uint8_t  *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc));
+	packet->data = (uint8_t  *) (buffer + RTP_PACKET_HEADER_SIZE + 12 + (4 * cc) + extn_len);
+	/* ...and the actual packet header... */
+	packet->v    = 2;
+	packet->p    = pad;
+	packet->x    = (extn != NULL);
+	packet->cc   = cc;
+	packet->m    = m;
+	packet->pt   = pt;
+	packet->seq  = htons(session->rtp_seq++);
+	packet->ts   = htonl(ts);
+	packet->ssrc = htonl(rtp_my_ssrc(session));
+	/* ...now the CSRC list... */
+	for (i = 0; i < cc; i++) {
+		packet->csrc[i] = htonl(csrc[i]);
+	}
+	/* ...a header extension? */
+	memcpy(packet->extn, extn, extn_len);
+	/* ...and the media data... */
+	memcpy(packet->data, data, data_len);
+	/* ...and any padding... */
+	if (pad) {
+		for (i = 0; i < pad_len; i++) {
+			buffer[buffer_len + RTP_PACKET_HEADER_SIZE - pad_len + i] = 0;
+		}
+		buffer[buffer_len + RTP_PACKET_HEADER_SIZE - 1] = (char) pad_len;
+	}
+	
+	/* Finally, encrypt if desired... */
+	if (session->encryption_key != NULL) {
+		assert((buffer_len % 8) == 0);
+		qfDES_CBC_e(session->encryption_key, buffer + RTP_PACKET_HEADER_SIZE, buffer_len, initVec); 
+	}
+
+	rc = udp_send(session->rtp_socket, buffer + RTP_PACKET_HEADER_SIZE, buffer_len);
+	xfree(buffer);
+
+	/* Update the RTCP statistics... */
+	session->we_sent     = TRUE;
+	session->rtp_pcount += 1;
+	session->rtp_bcount += buffer_len;
+
+	check_database(session);
+	return rc;
+}
+
+static int format_report_blocks(rtcp_rr *rrp, int remaining_length, struct rtp *session)
+{
+	int nblocks = 0;
+	int h;
+	source *s;
+	struct timeval now;
+
+	gettimeofday(&now, NULL);
+
+	for (h = 0; h < RTP_DB_SIZE; h++) {
+		for (s = session->db[h]; s != NULL; s = s->next) {
+			check_source(s);
+			if ((nblocks == 31) || (remaining_length < 24)) {
+				break; /* Insufficient space for more report blocks... */
+			}
+			if (s->sender) {
+				/* Much of this is taken from A.3 of draft-ietf-avt-rtp-new-01.txt */
+				int	extended_max      = s->cycles + s->max_seq;
+       				int	expected          = extended_max - s->base_seq + 1;
+       				int	lost              = expected - s->received;
+				int	expected_interval = expected - s->expected_prior;
+       				int	received_interval = s->received - s->received_prior;
+       				int 	lost_interval     = expected_interval - received_interval;
+				int	fraction;
+				uint32_t lsr;
+				uint32_t dlsr;
+
+       				s->expected_prior = expected;
+       				s->received_prior = s->received;
+       				if (expected_interval == 0 || lost_interval <= 0) {
+					fraction = 0;
+       				} else {
+					fraction = (lost_interval << 8) / expected_interval;
+				}
+
+				if (s->sr == NULL) {
+					lsr = 0;
+					dlsr = 0;
+				} else {
+					lsr = ntp64_to_ntp32(s->sr->ntp_sec, s->sr->ntp_frac);
+					dlsr = (uint32_t)(tv_diff(now, s->last_sr) * 65536);
+				}
+				rrp->ssrc       = htonl(s->ssrc);
+				rrp->fract_lost = fraction;
+				rrp->total_lost = lost & 0x00ffffff;
+				rrp->last_seq   = htonl(extended_max);
+				rrp->jitter     = htonl(s->jitter / 16);
+				rrp->lsr        = htonl(lsr);
+				rrp->dlsr       = htonl(dlsr);
+				rrp++;
+				s->sender = FALSE;
+				remaining_length -= 24;
+				nblocks++;
+				session->sender_count--;
+				if (session->sender_count == 0) {
+					break; /* No point continuing, since we've reported on all senders... */
+				}
+			}
+		}
+	}
+	return nblocks;
+}
+
+static uint8_t *format_rtcp_sr(uint8_t *buffer, int buflen, struct rtp *session, uint32_t ts)
+{
+	/* Write an RTCP SR into buffer, returning a pointer to */
+	/* the next byte after the header we have just written. */
+	rtcp_t		*packet = (rtcp_t *) buffer;
+	int		 remaining_length;
+	uint32_t	 ntp_sec, ntp_frac;
+
+	assert(buflen >= 28);	/* ...else there isn't space for the header and sender report */
+
+	packet->common.version = 2;
+	packet->common.p       = 0;
+	packet->common.count   = 0;
+	packet->common.pt      = RTCP_SR;
+	packet->common.length  = htons(1);
+
+        ntp64_time(&ntp_sec, &ntp_frac);
+
+	packet->r.sr.sr.ssrc          = htonl(rtp_my_ssrc(session));
+	packet->r.sr.sr.ntp_sec       = htonl(ntp_sec);
+	packet->r.sr.sr.ntp_frac      = htonl(ntp_frac);
+	packet->r.sr.sr.rtp_ts        = htonl(ts);
+	packet->r.sr.sr.sender_pcount = htonl(session->rtp_pcount);
+	packet->r.sr.sr.sender_bcount = htonl(session->rtp_bcount);
+
+	/* Add report blocks, until we either run out of senders */
+	/* to report upon or we run out of space in the buffer.  */
+	remaining_length = buflen - 28;
+	packet->common.count = format_report_blocks(packet->r.sr.rr, remaining_length, session);
+	packet->common.length = htons((uint16_t) (6 + (packet->common.count * 6)));
+	return buffer + 28 + (24 * packet->common.count);
+}
+
+static uint8_t *format_rtcp_rr(uint8_t *buffer, int buflen, struct rtp *session)
+{
+	/* Write an RTCP RR into buffer, returning a pointer to */
+	/* the next byte after the header we have just written. */
+	rtcp_t		*packet = (rtcp_t *) buffer;
+	int		 remaining_length;
+
+	assert(buflen >= 8);	/* ...else there isn't space for the header */
+
+	packet->common.version = 2;
+	packet->common.p       = 0;
+	packet->common.count   = 0;
+	packet->common.pt      = RTCP_RR;
+	packet->common.length  = htons(1);
+	packet->r.rr.ssrc      = htonl(session->my_ssrc);
+
+	/* Add report blocks, until we either run out of senders */
+	/* to report upon or we run out of space in the buffer.  */
+	remaining_length = buflen - 8;
+	packet->common.count = format_report_blocks(packet->r.rr.rr, remaining_length, session);
+	packet->common.length = htons((uint16_t) (1 + (packet->common.count * 6)));
+	return buffer + 8 + (24 * packet->common.count);
+}
+
+static int add_sdes_item(uint8_t *buf, int buflen, int type, const char *val)
+{
+	/* Fill out an SDES item. It is assumed that the item is a NULL    */
+	/* terminated string.                                              */
+        rtcp_sdes_item *shdr = (rtcp_sdes_item *) buf;
+        int             namelen;
+
+        if (val == NULL) {
+                debug_msg("Cannot format SDES item. type=%d val=%xp\n", type, val);
+                return 0;
+        }
+        shdr->type = type;
+        namelen = strlen(val);
+        shdr->length = namelen;
+        strncpy(shdr->data, val, buflen - 2); /* The "-2" accounts for the other shdr fields */
+        return namelen + 2;
+}
+
+static uint8_t *format_rtcp_sdes(uint8_t *buffer, int buflen, uint32_t ssrc, struct rtp *session)
+{
+        /* From draft-ietf-avt-profile-new-00:                             */
+        /* "Applications may use any of the SDES items described in the    */
+        /* RTP specification. While CNAME information is sent every        */
+        /* reporting interval, other items should be sent only every third */
+        /* reporting interval, with NAME sent seven out of eight times     */
+        /* within that slot and the remaining SDES items cyclically taking */
+        /* up the eighth slot, as defined in Section 6.2.2 of the RTP      */
+        /* specification. In other words, NAME is sent in RTCP packets 1,  */
+        /* 4, 7, 10, 13, 16, 19, while, say, EMAIL is used in RTCP packet  */
+        /* 22".                                                            */
+	uint8_t		*packet = buffer;
+	rtcp_common	*common = (rtcp_common *) buffer;
+	const char	*item;
+	size_t		 remaining_len;
+        int              pad;
+
+	assert(buflen > (int) sizeof(rtcp_common));
+
+	common->version = 2;
+	common->p       = 0;
+	common->count   = 1;
+	common->pt      = RTCP_SDES;
+	common->length  = 0;
+	packet += sizeof(common);
+
+	*((uint32_t *) packet) = htonl(ssrc);
+	packet += 4;
+
+	remaining_len = buflen - (packet - buffer);
+	item = rtp_get_sdes(session, ssrc, RTCP_SDES_CNAME);
+	if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+		packet += add_sdes_item(packet, remaining_len, RTCP_SDES_CNAME, item);
+	}
+
+	remaining_len = buflen - (packet - buffer);
+	item = rtp_get_sdes(session, ssrc, RTCP_SDES_NOTE);
+	if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+		packet += add_sdes_item(packet, remaining_len, RTCP_SDES_NOTE, item);
+	}
+
+	remaining_len = buflen - (packet - buffer);
+	if ((session->sdes_count_pri % 3) == 0) {
+		session->sdes_count_sec++;
+		if ((session->sdes_count_sec % 8) == 0) {
+			/* Note that the following is supposed to fall-through the cases */
+			/* until one is found to send... The lack of break statements in */
+			/* the switch is not a bug.                                      */
+			switch (session->sdes_count_ter % 4) {
+			case 0: item = rtp_get_sdes(session, ssrc, RTCP_SDES_TOOL);
+				if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+					packet += add_sdes_item(packet, remaining_len, RTCP_SDES_TOOL, item);
+					break;
+				}
+			case 1: item = rtp_get_sdes(session, ssrc, RTCP_SDES_EMAIL);
+				if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+					packet += add_sdes_item(packet, remaining_len, RTCP_SDES_EMAIL, item);
+					break;
+				}
+			case 2: item = rtp_get_sdes(session, ssrc, RTCP_SDES_PHONE);
+				if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+					packet += add_sdes_item(packet, remaining_len, RTCP_SDES_PHONE, item);
+					break;
+				}
+			case 3: item = rtp_get_sdes(session, ssrc, RTCP_SDES_LOC);
+				if ((item != NULL) && ((strlen(item) + (size_t) 2) <= remaining_len)) {
+					packet += add_sdes_item(packet, remaining_len, RTCP_SDES_LOC, item);
+					break;
+				}
+			}
+			session->sdes_count_ter++;
+		} else {
+			item = rtp_get_sdes(session, ssrc, RTCP_SDES_NAME);
+			if (item != NULL) {
+				packet += add_sdes_item(packet, remaining_len, RTCP_SDES_NAME, item);
+			}
+		}
+	}
+	session->sdes_count_pri++;
+
+	/* Pad to a multiple of 4 bytes... */
+        pad = 4 - ((packet - buffer) & 0x3);
+        while (pad--) {
+               *packet++ = RTCP_SDES_END;
+        }
+
+	common->length = htons((uint16_t) (((int) (packet - buffer) / 4) - 1));
+
+	return packet;
+}
+
+static uint8_t *format_rtcp_app(uint8_t *buffer, int buflen, uint32_t ssrc, rtcp_app *app)
+{
+	/* Write an RTCP APP into the outgoing packet buffer. */
+	rtcp_app    *packet       = (rtcp_app *) buffer;
+	int          pkt_octets   = (app->length + 1) * 4;
+	int          data_octets  =  pkt_octets - 12;
+
+	assert(data_octets >= 0);          /* ...else not a legal APP packet.               */
+	assert(buflen      >  pkt_octets); /* ...else there isn't space for the APP packet. */
+
+	/* Copy one APP packet from "app" to "packet". */
+	packet->version        =   RTP_VERSION;
+	packet->p              =   app->p;
+	packet->subtype        =   app->subtype;
+	packet->pt             =   RTCP_APP;
+	packet->length         =   htons(app->length);
+	packet->ssrc           =   htonl(ssrc);
+	memcpy(packet->name, app->name, 4);
+	memcpy(packet->data, app->data, data_octets);
+
+	/* Return a pointer to the byte that immediately follows the last byte written. */
+	return buffer + pkt_octets;
+}
+
+static void send_rtcp(struct rtp *session, uint32_t ts,
+		     rtcp_app *(*appcallback)(struct rtp *session, uint32_t ts, int max_size))
+{
+	/* Construct and send an RTCP packet. The order in which packets are packed into a */
+	/* compound packet is defined by section 6.1 of draft-ietf-avt-rtp-new-03.txt and  */
+	/* we follow the recommended order.                                                */
+	uint8_t	   buffer[RTP_MAX_PACKET_LEN + 8];	/* The +8 is to allow for padding when encrypting */
+	uint8_t	  *ptr = buffer;
+	uint8_t   *old_ptr;
+	uint8_t   *lpt;		/* the last packet in the compound */
+	rtcp_app  *app;
+	uint8_t    initVec[8] = {0,0,0,0,0,0,0,0};
+
+	check_database(session);
+	/* If encryption is enabled, add a 32 bit random prefix to the packet */
+	if (session->encryption_key != NULL) {
+		*((uint32_t *) ptr) = lbl_random();
+		ptr += 4;
+	}
+
+	/* The first RTCP packet in the compound packet MUST always be a report packet...  */
+	if (session->we_sent) {
+		ptr = format_rtcp_sr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session, ts);
+	} else {
+		ptr = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session);
+	}
+	/* Add the appropriate SDES items to the packet... This should really be after the */
+	/* insertion of the additional report blocks, but if we do that there are problems */
+	/* with us being unable to fit the SDES packet in when we run out of buffer space  */
+	/* adding RRs. The correct fix would be to calculate the length of the SDES items  */
+	/* in advance and subtract this from the buffer length but this is non-trivial and */
+	/* probably not worth it.                                                          */
+	lpt = ptr;
+	ptr = format_rtcp_sdes(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), rtp_my_ssrc(session), session);
+
+	/* Following that, additional RR packets SHOULD follow if there are more than 31   */
+	/* senders, such that the reports do not fit into the initial packet. We give up   */
+	/* if there is insufficient space in the buffer: this is bad, since we always drop */
+	/* the reports from the same sources (those at the end of the hash table).         */
+	while ((session->sender_count > 0)  && ((RTP_MAX_PACKET_LEN - (ptr - buffer)) >= 8)) {
+		lpt = ptr;
+		ptr = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session);
+	}
+
+	/* Finish with as many APP packets as the application will provide. */
+	old_ptr = ptr;
+	if (appcallback) {
+		while ((app = (*appcallback)(session, ts, RTP_MAX_PACKET_LEN - (ptr - buffer)))) {
+			lpt = ptr;
+			ptr = format_rtcp_app(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), rtp_my_ssrc(session), app);
+			assert(ptr > old_ptr);
+			old_ptr = ptr;
+			assert(RTP_MAX_PACKET_LEN - (ptr - buffer) >= 0);
+		}
+	}
+
+	/* And encrypt if desired... */
+	if (session->encryption_key != NULL) {
+		if (((ptr - buffer) % 8) != 0) {
+			/* Add padding to the last packet in the compound, if necessary. */
+			/* We don't have to worry about overflowing the buffer, since we */
+			/* intentionally allocated it 8 bytes longer to allow for this.  */
+			int	padlen = 8 - ((ptr - buffer) % 8);
+			int	i;
+
+			for (i = 0; i < padlen; i++) {
+				*(ptr++) = '\0';
+			}
+			*ptr = (uint8_t) padlen;
+			assert(((ptr - buffer) % 8) == 0); 
+
+			((rtcp_t *) lpt)->common.p = TRUE;
+			((rtcp_t *) lpt)->common.length = htons((int16_t)(((ptr - lpt) / 4) - 1));
+		}
+		qfDES_CBC_e(session->encryption_key, buffer, ptr - buffer, initVec); 
+	}
+	udp_send(session->rtcp_socket, buffer, ptr - buffer);
+
+        /* Loop the data back to ourselves so local participant can */
+        /* query own stats when using unicast or multicast with no  */
+        /* loopback.                                                */
+        rtp_process_ctrl(session, buffer, ptr - buffer);
+	check_database(session);
+}
+
+void rtp_send_ctrl(struct rtp *session, uint32_t ts,
+                   rtcp_app *(*appcallback)(struct rtp *session, uint32_t ts, int max_size))
+{
+	/* Send an RTCP packet, if one is due... */
+	struct timeval	 curr_time;
+
+	check_database(session);
+	gettimeofday(&curr_time, NULL);
+	if (tv_gt(curr_time, session->next_rtcp_send_time)) {
+		/* The RTCP transmission timer has expired. The following */
+		/* implements draft-ietf-avt-rtp-new-02.txt section 6.3.6 */
+		int		 h;
+		source		*s;
+		struct timeval	 new_send_time;
+		double		 new_interval;
+
+		new_interval  = rtcp_interval(session);
+		new_send_time = session->last_rtcp_send_time;
+		tv_add(&new_send_time, new_interval);
+		if (tv_gt(curr_time, new_send_time)) {
+			send_rtcp(session, ts, appcallback);
+			session->initial_rtcp        = FALSE;
+			session->we_sent             = FALSE;
+			session->last_rtcp_send_time = curr_time;
+			session->next_rtcp_send_time = curr_time; 
+			tv_add(&(session->next_rtcp_send_time), new_interval);
+			/* We're starting a new RTCP reporting interval, zero out */
+			/* the per-interval statistics.                           */
+			session->sender_count = 0;
+			for (h = 0; h < RTP_DB_SIZE; h++) {
+				for (s = session->db[h]; s != NULL; s = s->next) {
+					check_source(s);
+					s->sender = FALSE;
+				}
+			}
+		} else {
+			session->next_rtcp_send_time = session->last_rtcp_send_time; 
+			tv_add(&(session->next_rtcp_send_time), new_interval);
+		}
+		session->ssrc_count_prev = session->ssrc_count;
+	} 
+	check_database(session);
+}
+
+void rtp_update(struct rtp *session)
+{
+	/* Perform housekeeping on the source database... */
+	int	 	 h;
+	source	 	*s, *n;
+	struct timeval	 curr_time;
+	double		 delay;
+
+	check_database(session);
+	gettimeofday(&curr_time, NULL);
+	if (tv_diff(curr_time, session->last_update) < session->rtcp_interval) {
+		/* We only cleanup once per RTCP reporting interval... */
+		check_database(session);
+		return;
+	}
+	session->last_update = curr_time;
+
+	for (h = 0; h < RTP_DB_SIZE; h++) {
+		for (s = session->db[h]; s != NULL; s = n) {
+			check_source(s);
+			n = s->next;
+			/* Expire sources which haven't been heard from for a long time.   */
+			/* Section 6.2.1 of the RTP specification details the timers used. */
+
+			/* How long since we last heard from this source?  */
+			delay = tv_diff(curr_time, s->last_active);
+			
+			/* Check if we've received a BYE packet from this source.    */
+			/* If we have, and it was received more than 2 seconds ago   */
+			/* then the source is deleted. The arbitrary 2 second delay  */
+			/* is to ensure that all delayed packets are received before */
+			/* the source is timed out.                                  */
+			if (s->got_bye && (delay > 2.0)) {
+				delete_source(session, s->ssrc);
+			}
+			/* If a source hasn't been heard from for more than 5 RTCP   */
+			/* reporting intervals, we delete it from our database...    */
+			if (delay > (session->rtcp_interval * 5)) {
+				delete_source(session, s->ssrc);
+			}
+		}
+	}
+
+	/* Timeout those reception reports which haven't been refreshed for a long time */
+	timeout_rr(session, &curr_time);
+	check_database(session);
+}
+
+void rtp_send_bye(struct rtp *session)
+{
+	/* The function sends an RTCP BYE packet. It should implement BYE reconsideration, */
+	/* at present it either: a) sends a BYE packet immediately (if there are less than */
+	/* 50 members in the group), or b) returns without sending a BYE (if there are 50  */
+	/* or more members). See draft-ietf-avt-rtp-new-01.txt (section 6.3.7).            */
+	uint8_t	 	 buffer[RTP_MAX_PACKET_LEN + 8];	/* + 8 to allow for padding when encrypting */
+	uint8_t		*ptr = buffer;
+	rtcp_common	*common;
+	uint8_t    	 initVec[8] = {0,0,0,0,0,0,0,0};
+
+	check_database(session);
+	/* If encryption is enabled, add a 32 bit random prefix to the packet */
+	if (session->encryption_key != NULL) {
+		*((uint32_t *) ptr) = lbl_random();
+		ptr += 4;
+	}
+
+	if (session->ssrc_count < 50) {
+		ptr    = format_rtcp_rr(ptr, RTP_MAX_PACKET_LEN - (ptr - buffer), session);    
+		common = (rtcp_common *) ptr;
+		
+		common->version = 2;
+		common->p       = 0;
+		common->count   = 1;
+		common->pt      = RTCP_BYE;
+		common->length  = htons(1);
+		ptr += sizeof(common);
+		
+		*((uint32_t *) ptr) = htonl(session->my_ssrc);  
+		ptr += 4;
+		
+		if (session->encryption_key != NULL) {
+			if (((ptr - buffer) % 8) != 0) {
+				/* Add padding to the last packet in the compound, if necessary. */
+				/* We don't have to worry about overflowing the buffer, since we */
+				/* intentionally allocated it 8 bytes longer to allow for this.  */
+				int	padlen = 8 - ((ptr - buffer) % 8);
+				int	i;
+
+				for (i = 0; i < padlen; i++) {
+					*(ptr++) = '\0';
+				}
+				*ptr = (uint8_t) padlen;
+
+				common->p      = TRUE;
+				common->length = htons((int16_t)(((ptr - (uint8_t *) common) / 4) - 1));
+			}
+			assert(((ptr - buffer) % 8) == 0); 
+			qfDES_CBC_e(session->encryption_key, buffer, ptr - buffer, initVec); 
+		}
+		udp_send(session->rtcp_socket, buffer, ptr - buffer);
+		/* Loop the data back to ourselves so local participant can */
+		/* query own stats when using unicast or multicast with no  */
+		/* loopback.                                                */
+		rtp_process_ctrl(session, buffer, ptr - buffer);
+	}
+	check_database(session);
+}
+
+void rtp_done(struct rtp *session)
+{
+	int i;
+        source *s, *n;
+
+	check_database(session);
+        /* In delete_source, check database gets called and this assumes */
+        /* first added and last removed is us.                           */
+	for (i = 0; i < RTP_DB_SIZE; i++) {
+                s = session->db[i];
+                while (s != NULL) {
+                        n = s->next;
+                        if (s->ssrc != session->my_ssrc) {
+                                delete_source(session,session->db[i]->ssrc);
+                        }
+                        s = n;
+                }
+	}
+
+	delete_source(session, session->my_ssrc);
+
+        if (session->encryption_key != NULL) {
+                xfree(session->encryption_key);
+        }
+
+	udp_exit(session->rtp_socket);
+	udp_exit(session->rtcp_socket);
+	xfree(session->addr);
+	xfree(session->opt);
+	xfree(session);
+}
+
+int rtp_set_encryption_key(struct rtp* session, const char *passphrase)
+{
+	/* Convert the user supplied key into a form suitable for use with RTP */
+	/* and install it as the active key. Passing in NULL as the passphrase */
+	/* disables encryption. The passphrase is converted into a DES key as  */
+	/* specified in RFC1890, that is:                                      */
+	/*   - convert to canonical form                                       */
+	/*   - derive an MD5 hash of the canonical form                        */
+	/*   - take the first 56 bits of the MD5 hash                          */
+	/*   - add parity bits to form a 64 bit key                            */
+	/* Note that versions of rat prior to 4.1.2 do not convert the pass-   */
+	/* phrase to canonical form before taking the MD5 hash, and so will    */
+	/* not be compatible for keys which are non-invarient under this step. */
+	char	*canonical_passphrase;
+	u_char	 hash[16];
+	MD5_CTX	 context;
+	int	 i, j, k;
+
+	check_database(session);
+        if (session->encryption_key != NULL) {
+                xfree(session->encryption_key);
+        }
+
+	if (passphrase == NULL) {
+		/* A NULL passphrase means disable encryption... */
+		session->encryption_key = NULL;
+		check_database(session);
+		return TRUE;
+	}
+
+	debug_msg("Enabling RTP/RTCP encryption\n");
+        session->encryption_key = (char *) xmalloc(8);
+
+	/* Step 1: convert to canonical form, comprising the following steps:  */
+	/*   a) convert the input string to the ISO 10646 character set, using */
+	/*      the UTF-8 encoding as specified in Annex P to ISO/IEC          */
+	/*      10646-1:1993 (ASCII characters require no mapping, but ISO     */
+	/*      8859-1 characters do);                                         */
+	/*   b) remove leading and trailing white space characters;            */
+	/*   c) replace one or more contiguous white space characters by a     */
+	/*      single space (ASCII or UTF-8 0x20);                            */
+	/*   d) convert all letters to lower case and replace sequences of     */
+	/*      characters and non-spacing accents with a single character,    */
+	/*      where possible.                                                */
+	canonical_passphrase = (char *) xstrdup(passphrase);	/* FIXME */
+
+	/* Step 2: derive an MD5 hash */
+	MD5Init(&context);
+	MD5Update(&context, (u_char *) canonical_passphrase, strlen(canonical_passphrase));
+	MD5Final((u_char *) hash, &context);
+
+	/* Step 3: take first 56 bits of the MD5 hash */
+	session->encryption_key[0] = hash[0];
+	session->encryption_key[1] = hash[0] << 7 | hash[1] >> 1;
+	session->encryption_key[2] = hash[1] << 6 | hash[2] >> 2;
+	session->encryption_key[3] = hash[2] << 5 | hash[3] >> 3;
+	session->encryption_key[4] = hash[3] << 4 | hash[4] >> 4;
+	session->encryption_key[5] = hash[4] << 3 | hash[5] >> 5;
+	session->encryption_key[6] = hash[5] << 2 | hash[6] >> 6;
+	session->encryption_key[7] = hash[6] << 1;
+
+	/* Step 4: add parity bits */
+	for (i = 0; i < 8; ++i) {
+		k = session->encryption_key[i] & 0xfe;
+		j = k;
+		j ^= j >> 4;
+		j ^= j >> 2;
+		j ^= j >> 1;
+		j = (j & 1) ^ 1;
+		session->encryption_key[i] = k | j;
+	}
+
+	check_database(session);
+	return TRUE;
+}
+
+char *rtp_get_addr(struct rtp *session)
+{
+	check_database(session);
+	return session->addr;
+}
+
+uint16_t rtp_get_rx_port(struct rtp *session)
+{
+	check_database(session);
+	return session->rx_port;
+}
+
+uint16_t rtp_get_tx_port(struct rtp *session)
+{
+	check_database(session);
+	return session->tx_port;
+}
+
+int rtp_get_ttl(struct rtp *session)
+{
+	check_database(session);
+	return session->ttl;
+}
+
Index: /common/tags/common_1_1_2/src/ntp.h
===================================================================
--- /common/tags/common_1_1_2/src/ntp.h (revision 408)
+++ /common/tags/common_1_1_2/src/ntp.h (revision 408)
@@ -0,0 +1,33 @@
+/*
+ * FILE:    ntp.h
+ * AUTHOR:  O.Hodson
+ * 
+ * NTP utility functions to make rtp and rtp round time calculation
+ * a little less painful.
+ *
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * $Id$
+ */
+
+#ifndef _NTP_H
+#define _NTP_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+        
+#define  ntp64_to_ntp32(ntp_sec, ntp_frac)          \
+               ((((ntp_sec)  & 0x0000ffff) << 16) | \
+                (((ntp_frac) & 0xffff0000) >> 16))
+
+#define  ntp32_sub(now, then) ((now) > (then)) ? ((now) - (then)) : ((now) - (then) + 0xffffffff)
+
+void     ntp64_time(uint32_t *ntp_sec, uint32_t *ntp_frac);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _NTP_H */
Index: /common/tags/common_1_1_2/src/qfDES.h
===================================================================
--- /common/tags/common_1_1_2/src/qfDES.h (revision 205)
+++ /common/tags/common_1_1_2/src/qfDES.h (revision 205)
@@ -0,0 +1,70 @@
+/*****************************************************************************
+
+
+
+
+Saleem N. Bhatti
+February 1993
+*****************************************************************************/
+
+#if !defined(_qfDES_h_)
+#define      _qfDES_h_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* what */
+typedef enum QFDES_what_e {qfDES_encrypt, qfDES_decrypt} QFDES_what;
+
+/* mode */
+typedef enum QFDES_mode_e {qfDES_ecb, qfDES_cbc, qfDES_cfb, qfDES_ofb} QFDES_mode;
+
+/* parity */
+typedef enum QFDES_parity_e {qfDES_even, qfDES_odd} QFDES_parity;
+
+/* key/IV generation */
+typedef enum QFDES_generate_e {qfDES_key, qfDES_iv} QFDES_generate;
+
+
+/* This does it all */
+int qfDES (unsigned char *key, unsigned char *data, unsigned int size, const QFDES_what what, const QFDES_mode mode, unsigned char *initVec);
+
+/* Handy macros */
+#define qfDES_ECB_e(_key, _data, _size) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_ecb, (unsigned char *) 0)
+#define qfDES_ECB_d(_key, _data, _size) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_ecb, (unsigned char *) 0)
+
+#define qfDES_CBC_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_cbc, _initVec)
+#define qfDES_CBC_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_cbc, _initVec)
+
+#define qfDES_CFB_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_cfb, _initVec)
+#define qfDES_CFB_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_cfb, _initVec)
+
+#define qfDES_OFB_e(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_encrypt, qfDES_ofb, _initVec)
+#define qfDES_OFB_d(_key, _data, _size, _initVec) qfDES(_key, _data, _size, qfDES_decrypt, qfDES_ofb, _initVec)
+
+/* Padded [m|re]alloc() */
+unsigned char    qfDES_setPad (unsigned char pad);
+
+#define qfDES_padSpace() qfDES_setPad((unsigned char) ' ')
+#define qfDES_padZero() qfDES_setPad((unsigned char) '\0')
+
+/* The size of text in a qfDES_malloc()ed block */
+#define qfDES_plainTextSize(_ptr, _size) (unsigned int) ((_size) - (unsigned int) (_ptr)[(_size) - 1])
+
+/* Keys */
+void qfDES_setParity (unsigned char *ptr, unsigned int size, const QFDES_parity parity);
+unsigned int qfDES_checkParity (unsigned char *ptr, unsigned int size, const QFDES_parity parity);
+
+unsigned char *qfDES_generate (const QFDES_generate what); /* returns a pointer to static memory */
+
+#define qfDES_generateKey() qfDES_generate(qfDES_key)
+#define qfDES_generateIV() qfDES_generate(qfDES_iv)
+
+int qfDES_checkWeakKeys (unsigned char *key);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !_qfDES_h_ */
Index: /common/tags/common_1_1_2/src/memory.c
===================================================================
--- /common/tags/common_1_1_2/src/memory.c (revision 429)
+++ /common/tags/common_1_1_2/src/memory.c (revision 429)
@@ -0,0 +1,518 @@
+/*
+ * FILE:    memory.c
+ * AUTHORS:  Isidor Kouvelas / Colin Perkins / Mark Handley / Orion Hodson
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "util.h"
+
+#ifdef DEBUG_MEM
+
+/* Custom memory routines are here, down to #else, defaults follow */
+
+#define MAX_ADDRS         65536
+#define MAGIC_MEMORY      0xdeadbeef
+#define MAGIC_MEMORY_SIZE 4
+
+/* Allocated block format is:
+ * <chk_header> <memory chunk...> <trailing magic number>
+ */
+
+typedef struct {
+        uint32_t key;   /* Original allocation number   */
+        uint32_t size;  /* Size of allocation requested */
+        uint32_t pad;   /* Alignment padding to 8 bytes */
+        uint32_t magic; /* Magic number                 */
+} chk_header;
+
+typedef struct s_alloc_blk {
+        uint32_t    key;     /* Key in table (ascending) */
+        chk_header *addr;
+        char       *filen;   /* file where allocated     */
+        int         line;    /* line where allocated     */
+        size_t      length;  /* size of allocation       */
+        int         blen;    /* size passed to block_alloc (if relevent) */
+        int         est;     /* time last touched in order of all allocation and reclaims */
+} alloc_blk;
+
+/* Table is ordered by key */
+static alloc_blk mem_item[MAX_ADDRS];
+
+static int   naddr = 0; /* number of allocations */
+static int   tick  = 1; /* xmemchk assumes this is one, do not change without checking why */
+static int   init  = 0;
+
+void xdoneinit(void) 
+{
+	init = tick++;
+}
+
+static int chk_header_okay(const chk_header *ch)
+{
+        const uint8_t *tm; /* tail magic */
+        assert(ch != NULL);
+
+        if (ch->key == MAGIC_MEMORY) {
+                fprintf(stderr, "ERROR: freed unit being checked\n");
+                abort();
+        }
+
+        tm = (const uint8_t*)ch;
+        tm += sizeof(chk_header) + ch->size;
+
+        if (ch->magic != MAGIC_MEMORY) {
+                fprintf(stderr, "ERROR: memory underrun\n");
+                abort();
+                return FALSE;
+        } else if (memcmp(tm, &ch->magic, MAGIC_MEMORY_SIZE)) {
+                fprintf(stderr, "ERROR: memory overrun\n");
+                abort();
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+static int mem_key_cmp(const void *a, const void *b) {
+        const alloc_blk *g, *h;
+        g = (const alloc_blk*)a;
+        h = (const alloc_blk*)b;
+        if (g->key < h->key) {
+                return -1;
+        } else if (g->key > h->key) {
+                return +1;
+        }
+        return 0;
+}
+
+static alloc_blk *mem_item_find(uint32_t key) {
+        void      *p;
+        alloc_blk  t;
+        t.key = key;
+        p = bsearch((const void*)&t, mem_item, naddr, sizeof(alloc_blk), mem_key_cmp);
+        return (alloc_blk*)p;
+}
+
+void xmemchk(void)
+{
+        uint32_t    last_key;
+        chk_header *ch;
+        int         i;
+
+	if (naddr > MAX_ADDRS) {
+		fprintf(stderr, "ERROR: Too many addresses for xmemchk()!\n");
+		abort();
+	}
+
+        last_key = 0;
+	for (i = 0; i < naddr; i++) {
+                /* Check for table corruption */
+                if (mem_item[i].key  < last_key) {
+                        fprintf(stderr, "Memory table keys out of order - fatal error");
+                        abort();
+                }
+                last_key = mem_item[i].key;
+                if (mem_item[i].addr == NULL) {
+                        fprintf(stderr, "Memory table entry reference null block - fatal error");
+                        abort();
+                }
+                if (mem_item[i].filen == NULL) {
+                        fprintf(stderr, "Memory table filename missing - fatal error");
+                        abort();
+                }
+                if ((size_t) strlen(mem_item[i].filen) != mem_item[i].length) {
+                        fprintf(stderr, "Memory table filename length corrupted - fatal error");
+                        abort();
+                }
+                
+                /* Check memory */
+                ch = mem_item[i].addr;
+                if (chk_header_okay(ch) == FALSE) {
+                        /* Chk header display which side has gone awry */
+			fprintf(stderr, "Memory check failed!\n");
+			fprintf(stderr, "addr: %p", mem_item[i].addr);
+                        fprintf(stderr, "  size: %6d", ch->size);
+                        fprintf(stderr, "  age: %6d", tick - mem_item[i].est);
+                        fprintf(stderr, "  file: %s", mem_item[i].filen);
+                        fprintf(stderr, "  line: %d", mem_item[i].line);
+                        fprintf(stderr, "\n");
+                        abort();
+                }
+        }
+}
+
+static int 
+alloc_blk_cmp_origin(const void *vab1, const void *vab2)
+{
+        const alloc_blk *ab1, *ab2;
+        int sc;
+        
+        ab1 = (const alloc_blk*)vab1;
+        ab2 = (const alloc_blk*)vab2;
+
+        if (ab1->filen == NULL || ab2->filen == NULL) {
+                if (ab1->filen == NULL && ab2->filen == NULL) {
+                        return 0;
+                } else if (ab1->filen == NULL) {
+                        return +1;
+                } else /* (ab2->filen == NULL)*/ {
+                        return -1;
+                }
+        }
+
+        sc = strcmp(ab1->filen, ab2->filen);
+        if (sc == 0) {
+                if (ab1->line > ab2->line) {
+                        return +1;
+                } else if (ab1->line == ab2->line) {
+                        return 0;
+                } else /* (ab1->line < ab2->line) */{
+                        return -1;
+                }
+        }
+
+        return sc;
+}
+
+static int
+alloc_blk_cmp_est(const void *vab1, const void *vab2)
+{
+        const alloc_blk *ab1, *ab2;
+
+        ab1 = (const alloc_blk*)vab1;        
+        ab2 = (const alloc_blk*)vab2;
+        
+        if (ab1->est > ab2->est) {
+                return +1;
+        } else if (ab1->est == ab2->est) {
+                return 0;
+        } else {
+                return -1;
+        }
+}
+
+void 
+xmemdmp(void)
+{
+	int i;
+        block_release_all();
+	if (naddr > MAX_ADDRS) {
+		printf("ERROR: Too many addresses for xmemdmp()!\n");
+		abort();
+	}
+
+        qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_est);
+
+        for (i=0; i<naddr; i++) {
+                printf("%5d",i);                               fflush(stdout);
+                printf("  addr: %p", mem_item[i].addr);        fflush(stdout);
+                printf("  size: %5d", mem_item[i].addr->size); fflush(stdout);
+                printf("  age: %6d", tick - mem_item[i].est);  fflush(stdout);
+                printf("  file: %s", mem_item[i].filen);       fflush(stdout);
+                printf(":%d", mem_item[i].line);               fflush(stdout);
+                if (mem_item[i].blen != 0) { 
+                        printf("  \tblen %d", mem_item[i].blen);   
+                        fflush(stdout);
+                }
+                printf("\n");
+        }
+	printf("Program initialisation finished at age %6d\n", tick-init);
+        qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp);
+}
+
+
+/* Because block_alloc recycles blocks we need to know which code
+ * fragment takes over responsibility for the memory.  */
+void 
+xclaim(void *addr, const char *filen, int line)
+{
+        alloc_blk *m;
+        chk_header *ch;
+        
+        ch = ((chk_header *)addr) - 1;
+        m  = mem_item_find(ch->key); 
+
+        if (chk_header_okay(ch) == FALSE) {
+                fprintf(stderr, "xclaim: memory corrupted\n");
+                abort();
+        }
+
+        if (m == NULL) {
+                fprintf(stderr, "xclaim: block not found\n");
+                abort();
+        }
+
+        free(m->filen);
+        m->filen  = strdup(filen);
+        m->length = strlen(filen);
+        m->line   = line;
+        m->est    = tick++;
+}
+
+void 
+xmemdist(FILE *fp)
+{
+        int i, last_line=-1, cnt=0, entry=0;
+        char *last_filen = NULL;
+
+        /* This is painful...I don't actually envisage running beyond this dump :-)
+         * 2 sorts are needed, one into order by file, and then back to key order.
+         */
+        qsort(mem_item, naddr, sizeof(mem_item[0]), alloc_blk_cmp_origin);
+        fprintf(fp, "# Distribution of memory allocated\n# <idx> <file> <line> <allocations>\n");
+        for(i = 0; i < naddr; i++) {
+                if (last_filen == NULL ||
+                    last_line  != mem_item[i].line ||
+                    strcmp(last_filen, mem_item[i].filen)) {
+                        if (last_filen != NULL) {
+                                fprintf(fp, "% 3d\n", cnt);
+                        }
+                        cnt = 0;
+                        last_filen = mem_item[i].filen;
+                        last_line  = mem_item[i].line;
+                        fprintf(fp, "% 3d %20s % 4d ", entry, last_filen, last_line);
+                        entry++;
+                }
+                cnt++;
+        }
+        fprintf(fp, "% 3d\n", cnt);
+        /* Restore order */
+        qsort(mem_item, naddr, sizeof(mem_item[0]), mem_key_cmp);
+}
+
+void 
+xfree(void *p)
+{
+        alloc_blk  *m;
+        chk_header *ch;
+        uint32_t size, delta, magic, idx;
+        
+	if (p == NULL) {
+		printf("ERROR: Attempt to free NULL pointer!\n");
+		abort();
+	}
+        ch = ((chk_header*)p) - 1;
+
+        /* Validate entry  */
+        if (chk_header_okay(ch) == FALSE) {
+                printf("ERROR: Freeing corrupted block\n");
+                abort();
+        }
+
+        /* Locate in table */
+        m = mem_item_find(ch->key);
+        if (m == NULL) {
+                printf("ERROR: Freeing unallocated or already free'd block\n");
+                abort();
+        }
+
+        /* Trash memory of allocated block, maybe noticed by apps when    
+         * deref'ing free'd */
+        size  = ch->size + sizeof(chk_header) + MAGIC_MEMORY_SIZE;
+        magic = MAGIC_MEMORY;
+        p     = (uint8_t*)ch;
+        while (size > 0) {
+                delta = min(size, 4);
+                memcpy(p, &magic, delta);
+                (uint8_t*)p += delta;
+                size        -= delta;
+        }
+
+        /* Free memory     */
+        free(ch);
+        free(m->filen);
+
+        /* Remove from table */
+        idx = m - mem_item;
+        if (naddr - idx > 0) {
+                memmove(&mem_item[idx], 
+                        &mem_item[idx + 1], 
+                        (naddr - idx - 1) * sizeof(alloc_blk));
+        }
+        naddr--;
+        xmemchk();
+}
+
+void *
+_xmalloc(unsigned size, const char *filen, int line)
+{
+        uint32_t   *j;
+        void       *p;
+        uint8_t    *t;
+        chk_header *ch;
+
+        p = (void*) malloc(size + sizeof(chk_header) + MAGIC_MEMORY_SIZE);
+
+	assert(p     != NULL);
+	assert(filen != NULL);
+
+        /* Fix block header */
+        ch = (chk_header*)p;
+        ch->key   = tick++;
+        ch->size  = size;
+        ch->magic = MAGIC_MEMORY;
+
+        /* Fill allocated memory with random numbers */
+        for (j = (uint32_t*)((chk_header *)p + 1); size > 4; size -= 4) {
+                *j++ = rand();
+        }
+        for (t = (uint8_t*)j; size > 0; size--) { 
+                *t++ = (uint8_t)(rand());
+        }
+        
+        /* Fix block tail */
+        memcpy(t, &ch->magic, MAGIC_MEMORY_SIZE);
+
+        /* Check set up okay */
+        if (chk_header_okay(ch) == FALSE) {
+                fprintf(stderr, "Implementation Error\n");
+                abort();
+        }
+
+        /* Add table entry */
+        mem_item[naddr].key    = ch->key;
+	mem_item[naddr].addr   = p;
+	mem_item[naddr].filen  = (char *)strdup(filen);
+	mem_item[naddr].line   = line;
+	mem_item[naddr].length = strlen(filen);
+        mem_item[naddr].blen   = 0;        /* block_alloc'ed len when appropriate     */
+        mem_item[naddr].est    = ch->key;  /* changes when block_alloc recycles block */
+        naddr ++;
+
+	if (naddr >= MAX_ADDRS) {
+		fprintf(stderr, "ERROR: Allocated too much! Table overflow in xmalloc()\n");
+		fprintf(stderr, "       Do you really need to allocate more than %d items?\n", MAX_ADDRS);
+		abort();
+	}
+        
+        if (chk_header_okay(ch) == FALSE) {
+                fprintf(stderr, "Implementation Error\n");
+                abort();
+        }
+        
+        return (uint8_t*)p + sizeof(chk_header);
+}
+
+void *
+_xrealloc(void *p, unsigned size, const char *filen, int line)
+{
+        alloc_blk  *m;
+        chk_header *ch;
+        uint8_t    *t;
+       
+        assert(p     != NULL);
+        assert(filen != NULL);
+	
+        ch = ((chk_header*) p) - 1;
+        m  = mem_item_find(ch->key);
+        if (m != NULL) {
+                /* Attempt reallocation */
+                m->addr = realloc((void*)ch, size + sizeof(chk_header) + MAGIC_MEMORY_SIZE);
+                if (m->addr == NULL) {
+                        debug_msg("realloc failed\n");
+                        return NULL;
+                }
+                /* Update table */
+                free(m->filen);
+                m->filen  = (char *) strdup(filen);
+                m->line   = line;
+                m->length = strlen(filen);
+                m->est    = tick++;
+                /* Fix chunk header */
+                ch->size  = size;
+                /* Fix trailer */
+                t = (uint8_t*)p + size;
+                memcpy(t, &ch->magic, MAGIC_MEMORY_SIZE);
+                /* Check block is okay */
+                if (chk_header_okay(ch) == FALSE) {
+                        fprintf(stderr, "Implementation Error\n");
+                        abort();
+                }
+                return p;
+	}
+	debug_msg("Trying to xrealloc() memory not which is not allocated\n");
+	abort();
+        return 0;
+}
+
+char *_xstrdup(const char *s1, const char *filen, int line)
+{
+	char 	*s2;
+  
+	s2 = (char *) _xmalloc(strlen(s1)+1, filen, line);
+	if (s2 != NULL) {
+		strcpy(s2, s1);
+        }
+	return (s2);
+}
+#else
+
+void xdoneinit (void) { return; }
+void xmemchk   (void) { return; }
+void xmemdmp   (void) { return; }
+
+void xclaim    (void *p, const char *filen, int line)
+{
+        UNUSED(p);
+        UNUSED(filen);
+        UNUSED(line);
+        return;
+}
+
+void xmemdist (FILE *f) { UNUSED(f); }
+void xfree    (void *x) { free(x); }
+
+void *_xmalloc(unsigned int size, const char *filen, int line) {
+        UNUSED(filen);
+        UNUSED(line);
+        return malloc(size);
+}
+
+void *_xrealloc(void *p, unsigned int size,const char *filen,int line) {
+        UNUSED(filen);
+        UNUSED(line);
+        return realloc(p, size);
+}
+char *_xstrdup(const char *s1, const char *filen, int line) {
+        UNUSED(filen);
+        UNUSED(line);
+        return strdup(s1);
+}
+
+#endif /* DEBUG_MEM */
Index: /common/tags/common_1_1_2/src/rtp.h
===================================================================
--- /common/tags/common_1_1_2/src/rtp.h (revision 421)
+++ /common/tags/common_1_1_2/src/rtp.h (revision 421)
@@ -0,0 +1,207 @@
+/*
+ * FILE:   rtp.h
+ * AUTHOR: Colin Perkins <c.perkins@cs.ucl.ac.uk>
+ *
+ * $Revision$ 
+ * $Date$
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London.
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __RTP_H__
+#define __RTP_H__
+
+#define RTP_VERSION 2
+#define RTP_PACKET_HEADER_SIZE	((sizeof(char *) * 2) + sizeof(uint32_t *) + (2 * sizeof(int)))
+#define RTP_MAX_PACKET_LEN 1500
+
+#if !defined(WORDS_BIGENDIAN) && !defined(WORDS_SMALLENDIAN)
+#error RTP library requires WORDS_BIGENDIAN or WORDS_SMALLENDIAN to be defined.
+#endif
+
+typedef struct {
+	/* The following are pointers to the data in the packet as    */
+	/* it came off the wire. The packet it read in such that the  */
+	/* header maps onto the latter part of this struct, and the   */
+	/* fields in this first part of the struct point into it. The */
+	/* entire packet can be freed by freeing this struct, without */
+	/* having to free the csrc, data and extn blocks separately.  */
+	/* WARNING: Don't change the size of the first portion of the */
+	/* struct without changing RTP_PACKET_HEADER_SIZE to match.   */
+	uint32_t	*csrc;
+	char		*data;
+	int		 data_len;
+	char		*extn;
+	int		 extn_len;
+	/* The following map directly onto the RTP packet header...   */
+#ifdef WORDS_BIGENDIAN
+	unsigned short   v:2;		/* packet type                */
+	unsigned short   p:1;		/* padding flag               */
+	unsigned short   x:1;		/* header extension flag      */
+	unsigned short   cc:4;		/* CSRC count                 */
+	unsigned short   m:1;		/* marker bit                 */
+	unsigned short   pt:7;		/* payload type               */
+#else
+	unsigned short   cc:4;		/* CSRC count                 */
+	unsigned short   x:1;		/* header extension flag      */
+	unsigned short   p:1;		/* padding flag               */
+	unsigned short   v:2;		/* packet type                */
+	unsigned short   pt:7;		/* payload type               */
+	unsigned short   m:1;		/* marker bit                 */
+#endif
+	uint16_t          seq;		/* sequence number            */
+	uint32_t          ts;		/* timestamp                  */
+	uint32_t          ssrc;		/* synchronization source     */
+	/* The csrc list, header extension and data follow, but can't */
+	/* be represented in the struct.                              */
+} rtp_packet;
+
+typedef struct {
+	uint32_t         ssrc;
+	uint32_t         ntp_sec;
+	uint32_t         ntp_frac;
+	uint32_t         rtp_ts;
+	uint32_t         sender_pcount;
+	uint32_t         sender_bcount;
+} rtcp_sr;
+
+typedef struct {
+	uint32_t	ssrc;		/* The ssrc to which this RR pertains */
+#ifdef WORDS_BIGENDIAN
+	uint32_t	fract_lost:8;
+	uint32_t	total_lost:24;
+#else
+	uint32_t	total_lost:24;
+	uint32_t	fract_lost:8;
+#endif	
+	uint32_t	last_seq;
+	uint32_t	jitter;
+	uint32_t	lsr;
+	uint32_t	dlsr;
+} rtcp_rr;
+
+typedef struct {
+	uint8_t		type;		/* type of SDES item              */
+	uint8_t		length;		/* length of SDES item (in bytes) */
+	char		data[1];	/* text, not zero-terminated      */
+} rtcp_sdes_item;
+
+typedef struct {
+#ifdef WORDS_BIGENDIAN
+	unsigned short  version:2;	/* RTP version            */
+	unsigned short  p:1;		/* padding flag           */
+	unsigned short  subtype:5;	/* application dependent  */
+#else
+	unsigned short  subtype:5;	/* application dependent  */
+	unsigned short  p:1;		/* padding flag           */
+	unsigned short  version:2;	/* RTP version            */
+#endif
+	unsigned short  pt:8;		/* packet type            */
+	uint16_t        length;		/* packet length          */
+	uint32_t        ssrc;
+	char            name[4];        /* four ASCII characters  */
+	char            data[1];        /* variable length field  */
+} rtcp_app;
+
+typedef struct {
+	uint32_t	 ssrc;
+	int		 type;
+	void		*data;
+	struct timeval	*ts;
+} rtp_event;
+
+/* rtp_event type values... */
+#define RX_RTP  	100
+#define RX_SR		101
+#define RX_RR   	102
+#define RX_SDES 	103
+#define RX_BYE  	104	/* Source is leaving the session, database entry is still valid */
+#define SOURCE_DELETED	105	/* Source has been removed from the database                    */
+#define SOURCE_CREATED	106
+#define RX_RR_EMPTY	107	/* We've received an empty reception report block                                               */
+#define RX_RTCP_START	108	/* We're about to start processing a compound RTCP packet. The SSRC is not valid in this event. */
+#define RX_RTCP_FINISH	109	/* We've just finished processing a compound RTCP packet. The SSRC is not valid in this event.  */
+#define RR_TIMEOUT	110
+#define RX_APP  	111
+
+/* RTP options */
+#define RTP_OPT_PROMISC     	  1
+#define RTP_OPT_WEAK_VALIDATION	  2
+#define RTP_OPT_FILTER_MY_PACKETS 3
+
+/* SDES packet types... */
+#define RTCP_SDES_END   0
+#define RTCP_SDES_CNAME 1
+#define RTCP_SDES_NAME  2
+#define RTCP_SDES_EMAIL 3
+#define RTCP_SDES_PHONE 4
+#define RTCP_SDES_LOC   5
+#define RTCP_SDES_TOOL  6
+#define RTCP_SDES_NOTE  7
+#define RTCP_SDES_PRIV  8
+
+struct rtp;
+
+struct rtp	*rtp_init(char *addr, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, 
+			  void (*callback)(struct rtp *session, rtp_event *e),
+			  void *user_data);
+struct rtp	*rtp_init_if(char *addr, char *iface, uint16_t rx_port, uint16_t tx_port, int ttl, double rtcp_bw, 
+			     void (*callback)(struct rtp *session, rtp_event *e),
+			     void *user_data);
+int 		 rtp_setopt(struct rtp *session, int optname, int optval);
+int 		 rtp_getopt(struct rtp *session, int optname, int *optval);
+void 		*rtp_get_userdata(struct rtp *session);
+int 		 rtp_recv(struct rtp *session, struct timeval *timeout, uint32_t curr_time);
+int 		 rtp_send_data(struct rtp *session, uint32_t ts, char pt, int m, int cc, uint32_t csrc[], 
+                               char *data, int data_len, char *extn, int extn_len);
+void 		 rtp_send_ctrl(struct rtp *session, uint32_t ts, 
+			       rtcp_app *(*appcallback)(struct rtp *session, uint32_t ts, int max_size));
+void 		 rtp_update(struct rtp *session);
+
+uint32_t	 rtp_my_ssrc(struct rtp *session);
+int		 rtp_add_csrc(struct rtp *session, uint32_t csrc);
+int		 rtp_valid_ssrc(struct rtp *session, uint32_t ssrc);
+int		 rtp_set_sdes(struct rtp *session, uint32_t ssrc, uint8_t type, char *value, int length);
+const char	*rtp_get_sdes(struct rtp *session, uint32_t ssrc, uint8_t type);
+const rtcp_sr	*rtp_get_sr(struct rtp *session, uint32_t ssrc);
+const rtcp_rr	*rtp_get_rr(struct rtp *session, uint32_t reporter, uint32_t reportee);
+void		 rtp_send_bye(struct rtp *session);
+void		 rtp_done(struct rtp *session);
+int              rtp_set_encryption_key(struct rtp *session, const char *passphrase);
+
+char 		*rtp_get_addr(struct rtp *session);
+uint16_t	 rtp_get_rx_port(struct rtp *session);
+uint16_t	 rtp_get_tx_port(struct rtp *session);
+int		 rtp_get_ttl(struct rtp *session);
+
+int              rtp_set_my_ssrc(struct rtp *session, uint32_t ssrc);
+
+#endif /* __RTP_H__ */
Index: /common/tags/common_1_1_2/src/config_unix.h
===================================================================
--- /common/tags/common_1_1_2/src/config_unix.h (revision 419)
+++ /common/tags/common_1_1_2/src/config_unix.h (revision 419)
@@ -0,0 +1,160 @@
+/*
+ *  config-unix.h
+ *
+ *  Unix specific definitions and includes
+ *  
+ *  $Revision$
+ *  $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef WIN32
+#ifndef _CONFIG_UNIX_H
+#define _CONFIG_UNIX_H
+
+#include "uclconf.h"
+
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <pwd.h>
+#include <signal.h>
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>   /* abs() */
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif /* HAVE_STROPTS_H */
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>  
+#endif /* HAVE_SYS_FILIO_H */
+
+#ifdef HAVE_IPv6
+
+#ifdef HAVE_NETINET6_IN6_H
+/* Expect IPV6_{JOIN,LEAVE}_GROUP in in6.h, otherwise expect                 */
+/* IPV_{ADD,DROP}_MEMBERSHIP in in.h                                         */
+#include <netinet6/in6.h>
+#else
+#include <netinet/in.h>
+#endif /* HAVE_NETINET_IN6_H */
+
+#ifndef IPV6_ADD_MEMBERSHIP
+#ifdef  IPV6_JOIN_GROUP
+#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#else
+#error  No definition of IPV6_ADD_MEMBERSHIP, please report to mm-tools@cs.ucl.ac.uk.
+#endif /* IPV6_JOIN_GROUP     */
+#endif /* IPV6_ADD_MEMBERSHIP */
+
+#ifndef IPV6_DROP_MEMBERSHIP
+#ifdef  IPV6_LEAVE_GROUP
+#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#else
+#error  No definition of IPV6_LEAVE_GROUP, please report to mm-tools@cs.ucl.ac.uk.
+#endif  /* IPV6_LEAVE_GROUP     */
+#endif  /* IPV6_DROP_MEMBERSHIP */
+
+#endif /* HAVE_IPv6 */
+
+#include <net/if.h>
+
+typedef u_char	ttl_t;
+typedef int	fd_t;
+
+#ifndef TRUE
+#define FALSE	0
+#define	TRUE	1
+#endif /* TRUE */
+
+#define USERNAMELEN	8
+
+#define max(a, b)	(((a) > (b))? (a): (b))
+#define min(a, b)	(((a) < (b))? (a): (b))
+
+#ifdef NDEBUG
+#define assert(x) if ((x) == 0) fprintf(stderr, "%s:%u: failed assertion\n", __FILE__, __LINE__)
+#else
+#include <assert.h>
+#endif
+
+#ifdef Solaris
+#ifdef __cplusplus
+extern "C" {
+#endif
+int gettimeofday(struct timeval *tp, void * );
+int gethostname(char *name, int namelen);
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif /* EXIT_SUCCESS */
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 7
+#endif /* EXIT_FAILURE */
+
+#endif /* _CONFIG_UNIX_H_ */
+#endif /* WIN32 */
Index: /common/tags/common_1_1_2/src/memory.h
===================================================================
--- /common/tags/common_1_1_2/src/memory.h (revision 360)
+++ /common/tags/common_1_1_2/src/memory.h (revision 360)
@@ -0,0 +1,70 @@
+/*
+ * FILE:    memory.h
+ * PROGRAM: RAT
+ * AUTHOR:  Isidor Kouvelas + Colin Perkins + Orion Hodson
+ *
+ * $Revision$
+ * $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RAT_MEMORY_H
+#define _RAT_MEMORY_H
+
+#define xrealloc(p,x)	_xrealloc(p, x,__FILE__,__LINE__)
+#define xmalloc(x)	_xmalloc(x,__FILE__,__LINE__)
+#define xstrdup(x)	_xstrdup(x,__FILE__,__LINE__)
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Debug Functions */
+void 	 xdoneinit(void);
+void	 xmemchk(void);
+void     xmemdmp(void);
+void     xclaim(void *p, const char *filen, int line);
+void     xmemdist(FILE *fp);
+
+/* Replacements for regular memory fn's */
+void	 xfree(void *x);
+void	*_xmalloc(unsigned size,const char *filen,int line);
+void	*_xrealloc(void *p,unsigned size,const char *filen,int line);
+char	*_xstrdup(const char *s1, const char *filen, int line);
+void	*_block_alloc(unsigned size, const char *filen, int line);
+void	 _block_free(void *p, int size, int line);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif 
Index: /common/tags/common_1_1_2/src/acconfig.h
===================================================================
--- /common/tags/common_1_1_2/src/acconfig.h (revision 412)
+++ /common/tags/common_1_1_2/src/acconfig.h (revision 412)
@@ -0,0 +1,62 @@
+/*
+ * Define this if you have a /dev/urandom which can supply good random numbers.
+ */
+#undef HAVE_DEV_URANDOM
+
+/*
+ * Define this if you want IPv6 support.
+ */
+#undef HAVE_IPv6
+
+/*
+ * V6 structures that host may or may not be present.
+ */
+#undef HAVE_ST_ADDRINFO
+#undef HAVE_GETIPNODEBYNAME
+#undef HAVE_SIN6_LEN
+
+/*
+ * Define these if your C library is missing some functions...
+ */
+#undef NEED_VSNPRINTF
+#undef NEED_INET_PTON
+#undef NEED_INET_NTOP
+
+/*
+ * If you don't have these types in <inttypes.h>, #define these to be
+ * the types you do have.
+ */
+#undef int8_t
+#undef int16_t
+#undef int32_t
+#undef int64_t
+#undef uint8_t
+#undef uint16_t
+#undef uint32_t
+
+/*
+ * Debugging:
+ * DEBUG: general debugging
+ * DEBUG_MEM: debug memory allocation
+ */
+#undef DEBUG
+#undef DEBUG_MEM
+
+/*
+ * #defines for operating system.
+ * THESE WANT TO GO AWAY!
+ * Any checks for a specific OS should be replaced by a check for
+ * a feature that OS supports or doesn't support.
+ */
+#undef SunOS
+#undef Solaris
+#undef Linux
+#undef HPUX
+
+@BOTTOM@
+
+#ifndef WORDS_BIGENDIAN
+#define WORDS_SMALLENDIAN
+#endif
+
+
Index: /common/tags/common_1_1_2/src/config.h.in
===================================================================
--- /common/tags/common_1_1_2/src/config.h.in (revision 412)
+++ /common/tags/common_1_1_2/src/config.h.in (revision 412)
@@ -0,0 +1,95 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if type char is unsigned and you are not using gcc.  */
+#ifndef __CHAR_UNSIGNED__
+#undef __CHAR_UNSIGNED__
+#endif
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/*
+ * Define this if you have a /dev/urandom which can supply good random numbers.
+ */
+#undef HAVE_DEV_URANDOM
+
+/*
+ * Define this if you want IPv6 support.
+ */
+#undef HAVE_IPv6
+
+/*
+ * V6 structures that host may or may not be present.
+ */
+#undef HAVE_ST_ADDRINFO
+#undef HAVE_GETIPNODEBYNAME
+#undef HAVE_SIN6_LEN
+
+/*
+ * Define these if your C library is missing some functions...
+ */
+#undef NEED_VSNPRINTF
+#undef NEED_INET_PTON
+#undef NEED_INET_NTOP
+
+/*
+ * If you don't have these types in <inttypes.h>, #define these to be
+ * the types you do have.
+ */
+#undef int8_t
+#undef int16_t
+#undef int32_t
+#undef int64_t
+#undef uint8_t
+#undef uint16_t
+#undef uint32_t
+
+/*
+ * Debugging:
+ * DEBUG: general debugging
+ * DEBUG_MEM: debug memory allocation
+ */
+#undef DEBUG
+#undef DEBUG_MEM
+
+/*
+ * #defines for operating system.
+ * THESE WANT TO GO AWAY!
+ * Any checks for a specific OS should be replaced by a check for
+ * a feature that OS supports or doesn't support.
+ */
+#undef SunOS
+#undef Solaris
+#undef Linux
+#undef HPUX
+
+/* Define if you have the <inttypes.h> header file.  */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have the <netinet6/in6.h> header file.  */
+#undef HAVE_NETINET6_IN6_H
+
+/* Define if you have the <stdint.h> header file.  */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <stropts.h> header file.  */
+#undef HAVE_STROPTS_H
+
+/* Define if you have the <sys/filio.h> header file.  */
+#undef HAVE_SYS_FILIO_H
+
+#ifndef WORDS_BIGENDIAN
+#define WORDS_SMALLENDIAN
+#endif
+
+
Index: /common/tags/common_1_1_2/src/win32/null.txt
===================================================================
--- /common/tags/common_1_1_2/src/win32/null.txt (revision 381)
+++ /common/tags/common_1_1_2/src/win32/null.txt (revision 381)
@@ -0,0 +1,2 @@
+
+
Index: /common/tags/common_1_1_2/src/win32/set.txt
===================================================================
--- /common/tags/common_1_1_2/src/win32/set.txt (revision 381)
+++ /common/tags/common_1_1_2/src/win32/set.txt (revision 381)
@@ -0,0 +1,1 @@
+set v=
Index: /common/tags/common_1_1_2/src/win32/echo.txt
===================================================================
--- /common/tags/common_1_1_2/src/win32/echo.txt (revision 381)
+++ /common/tags/common_1_1_2/src/win32/echo.txt (revision 381)
@@ -0,0 +1,4 @@
+echo #define CCL_VERSION "v%v%" > version.h
+
+
+
Index: /common/tags/common_1_1_2/src/mbus_parser.c
===================================================================
--- /common/tags/common_1_1_2/src/mbus_parser.c (revision 402)
+++ /common/tags/common_1_1_2/src/mbus_parser.c (revision 402)
@@ -0,0 +1,257 @@
+/*
+ * FILE:     mbus_parser.c
+ * AUTHOR:   Colin Perkins
+ * 
+ * Copyright (c) 1997-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "mbus_parser.h"
+
+#define MBUS_PARSER_MAGIC 0xbadface
+
+struct mbus_parser {
+	char	*buffer;	/* Temporary storage for parsing mbus commands 			*/
+	char	*bufend;	/* End of space allocated for parsing, to check for overflows 	*/
+	uint32_t magic;		/* For debugging...                                             */
+};
+
+struct mbus_parser *mbus_parse_init(char *str)
+{
+	struct mbus_parser	*m;
+
+	m = (struct mbus_parser *) xmalloc(sizeof(struct mbus_parser));
+	m->buffer = str;
+	m->bufend = str + strlen(str);
+	m->magic  = MBUS_PARSER_MAGIC;
+	return m;
+}
+
+void mbus_parse_done(struct mbus_parser *m)
+{
+	assert(m->magic == MBUS_PARSER_MAGIC);
+	xfree(m);
+}
+
+#define CHECK_OVERRUN if (m->buffer > m->bufend) {\
+	debug_msg("parse m->buffer overflow\n");\
+	return FALSE;\
+}
+
+int mbus_parse_lst(struct mbus_parser *m, char **l)
+{
+	int instr = FALSE;
+	int inlst = FALSE;
+
+	assert(m->magic == MBUS_PARSER_MAGIC);
+
+	*l = m->buffer;
+        while (isspace((unsigned char)*m->buffer)) {
+                m->buffer++;
+		CHECK_OVERRUN;
+        }
+	if (*m->buffer != '(') {
+		return FALSE;
+	}
+	*(m->buffer) = ' ';
+	while (*m->buffer != '\0') {
+		if ((*m->buffer == '"') && (*(m->buffer-1) != '\\')) {
+			instr = !instr;
+		}
+		if ((*m->buffer == '(') && (*(m->buffer-1) != '\\') && !instr) {
+			inlst = !inlst;
+		}
+		if ((*m->buffer == ')') && (*(m->buffer-1) != '\\') && !instr) {
+			if (inlst) {
+				inlst = !inlst;
+			} else {
+				*m->buffer = '\0';
+				m->buffer++;
+				CHECK_OVERRUN;
+				return TRUE;
+			}
+		}
+		m->buffer++;
+		CHECK_OVERRUN;
+	}
+	return FALSE;
+}
+
+int mbus_parse_str(struct mbus_parser *m, char **s)
+{
+	assert(m->magic == MBUS_PARSER_MAGIC);
+
+        while (isspace((unsigned char)*m->buffer)) {
+                m->buffer++;
+		CHECK_OVERRUN;
+        }
+	if (*m->buffer != '"') {
+		return FALSE;
+	}
+	*s = m->buffer++;
+	while (*m->buffer != '\0') {
+		if ((*m->buffer == '"') && (*(m->buffer-1) != '\\')) {
+			m->buffer++;
+			*m->buffer = '\0';
+			m->buffer++;
+			return TRUE;
+		}
+		m->buffer++;
+		CHECK_OVERRUN;
+	}
+	return FALSE;
+}
+
+int mbus_parse_sym(struct mbus_parser *m, char **s)
+{
+	assert(m->magic == MBUS_PARSER_MAGIC);
+
+        while (isspace((unsigned char)*m->buffer)) {
+                m->buffer++;
+		CHECK_OVERRUN;
+        }
+	if (!isgraph((unsigned char)*m->buffer)) {
+		return FALSE;
+	}
+	*s = m->buffer++;
+	while (!isspace((unsigned char)*m->buffer) && (*m->buffer != '\0')) {
+		m->buffer++;
+		CHECK_OVERRUN;
+	}
+	*m->buffer = '\0';
+	m->buffer++;
+	CHECK_OVERRUN;
+	return TRUE;
+}
+
+int mbus_parse_int(struct mbus_parser *m, int *i)
+{
+	char	*p;
+
+	assert(m->magic == MBUS_PARSER_MAGIC);
+
+        while (isspace((unsigned char)*m->buffer)) {
+                m->buffer++;
+		CHECK_OVERRUN;
+        }
+
+	*i = strtol(m->buffer, &p, 10);
+	if (((*i == LONG_MAX) || (*i == LONG_MIN)) && (errno == ERANGE)) {
+		debug_msg("integer out of range\n");
+		return FALSE;
+	}
+
+	if (p == m->buffer) {
+		return FALSE;
+	}
+	if (!isspace((unsigned char)*p) && (*p != '\0')) {
+		return FALSE;
+	}
+	m->buffer = p;
+	CHECK_OVERRUN;
+	return TRUE;
+}
+
+int mbus_parse_flt(struct mbus_parser *m, double *d)
+{
+	char	*p;
+
+	assert(m->magic == MBUS_PARSER_MAGIC);
+
+        while (isspace((unsigned char)*m->buffer)) {
+                m->buffer++;
+		CHECK_OVERRUN;
+        }
+
+	*d = strtod(m->buffer, &p);
+	if (errno == ERANGE) {
+		debug_msg("float out of range\n");
+		return FALSE;
+	}
+
+	if (p == m->buffer) {
+		return FALSE;
+	}
+	if (!isspace((unsigned char)*p) && (*p != '\0')) {
+		return FALSE;
+	}
+	m->buffer = p;
+	CHECK_OVERRUN;
+	return TRUE;
+}
+
+char *mbus_decode_str(char *s)
+{
+	int	l = strlen(s);
+	int	i, j;
+
+	/* Check that this an encoded string... */
+	assert(s[0]   == '\"');
+	assert(s[l-1] == '\"');
+
+	for (i=1,j=0; i < l - 1; i++,j++) {
+		if (s[i] == '\\') {
+			i++;
+		}
+		s[j] = s[i];
+	}
+	s[j] = '\0';
+	return s;
+}
+
+char *mbus_encode_str(const char *s)
+{
+	int 	 i, j;
+	int	 len = strlen(s);
+	char	*buf = (char *) xmalloc((len * 2) + 3);
+
+	for (i = 0, j = 1; i < len; i++,j++) {
+		if (s[i] == ' ') {
+			buf[j] = '\\';
+			buf[j+1] = ' ';
+			j++;
+		} else if (s[i] == '\"') {
+			buf[j] = '\\';
+			buf[j+1] = '\"';
+			j++;
+		} else {
+			buf[j] = s[i];
+		}
+	}
+	buf[0]   = '\"';
+	buf[j]   = '\"';
+	buf[j+1] = '\0';
+	return buf;
+}
+
Index: /common/tags/common_1_1_2/src/base64.c
===================================================================
--- /common/tags/common_1_1_2/src/base64.c (revision 428)
+++ /common/tags/common_1_1_2/src/base64.c (revision 428)
@@ -0,0 +1,134 @@
+/*
+ * FILE:   base64.c
+ * AUTHOR: Colin Perkins
+ *
+ * MIME base64 encoder/decoder described in rfc1521. This code is derived
+ * from version 2.7 of the Bellcore metamail package.
+ *
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
+ * 
+ * Permission to use, copy, modify, and distribute this material 
+ * for any purpose and without fee is hereby granted, provided 
+ * that the above copyright notice and this permission notice 
+ * appear in all copies, and that the name of Bellcore not be 
+ * used in advertising or publicity pertaining to this 
+ * material without the specific, prior written permission 
+ * of an authorized representative of Bellcore.  BELLCORE 
+ * MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY 
+ * OF THIS MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", 
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
+ * 
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "base64.h"
+
+static unsigned char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+int base64encode(const unsigned char *input, int input_length, unsigned char *output, int output_length)
+{
+	int	i = 0, j = 0;
+	int	pad;
+
+	assert(output_length >= (input_length * 4 / 3));
+
+	while (i < input_length) {
+		pad = 3 - (input_length - i);
+		if (pad == 2) {
+			output[j  ] = basis_64[input[i]>>2];
+			output[j+1] = basis_64[(input[i] & 0x03) << 4];
+			output[j+2] = '=';
+			output[j+3] = '=';
+		} else if (pad == 1) {
+			output[j  ] = basis_64[input[i]>>2];
+			output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)];
+			output[j+2] = basis_64[(input[i+1] & 0x0f) << 2];
+			output[j+3] = '=';
+		} else{
+			output[j  ] = basis_64[input[i]>>2];
+			output[j+1] = basis_64[((input[i] & 0x03) << 4) | ((input[i+1] & 0xf0) >> 4)];
+			output[j+2] = basis_64[((input[i+1] & 0x0f) << 2) | ((input[i+2] & 0xc0) >> 6)];
+			output[j+3] = basis_64[input[i+2] & 0x3f];
+		}
+		i += 3;
+		j += 4;
+	}
+	return j;
+}
+
+/* This assumes that an unsigned char is exactly 8 bits. Not portable code! :-) */
+static unsigned char index_64[128] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,   62, 0xff, 0xff, 0xff,   63,
+      52,   53,   54,   55,   56,   57,   58,   59,   60,   61, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff,    0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
+      15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+      41,   42,   43,   44,   45,   46,   47,   48,   49,   50,   51, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+#define char64(c)  ((c > 127) ? 0xff : index_64[(c)])
+
+int base64decode(const unsigned char *input, int input_length, unsigned char *output, int output_length)
+{
+	int		i = 0, j = 0, pad;
+	unsigned char	c[4];
+
+	assert(output_length >= (input_length * 3 / 4));
+	assert((input_length % 4) == 0);
+	while ((i + 3) < input_length) {
+		pad  = 0;
+		c[0] = char64(input[i  ]); pad += (c[0] == 0xff);
+		c[1] = char64(input[i+1]); pad += (c[1] == 0xff);
+		c[2] = char64(input[i+2]); pad += (c[2] == 0xff);
+		c[3] = char64(input[i+3]); pad += (c[3] == 0xff);
+		if (pad == 2) {
+			output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
+			output[j]   = (c[1] & 0x0f) << 4;
+		} else if (pad == 1) {
+			output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
+			output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
+			output[j]   = (c[2] & 0x03) << 6;
+		} else {
+			output[j++] = (c[0] << 2) | ((c[1] & 0x30) >> 4);
+			output[j++] = ((c[1] & 0x0f) << 4) | ((c[2] & 0x3c) >> 2);
+			output[j++] = ((c[2] & 0x03) << 6) | (c[3] & 0x3f);
+		}
+		i += 4;
+	}
+	return j;
+}
+
Index: /common/tags/common_1_1_2/src/mbus_parser.h
===================================================================
--- /common/tags/common_1_1_2/src/mbus_parser.h (revision 399)
+++ /common/tags/common_1_1_2/src/mbus_parser.h (revision 399)
@@ -0,0 +1,59 @@
+/*
+ * FILE:     mbus_parser.h
+ * AUTHOR:   Colin Perkins
+ * 
+ * Copyright (c) 2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MBUS_PARSER_H
+#define _MBUS_PARSER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct mbus_parser;
+
+struct mbus_parser 	*mbus_parse_init(char *str);
+void	 		 mbus_parse_done(struct mbus_parser *m);
+int			 mbus_parse_lst(struct mbus_parser *m, char **l);
+int			 mbus_parse_str(struct mbus_parser *m, char **s);
+int			 mbus_parse_sym(struct mbus_parser *m, char **s);
+int			 mbus_parse_int(struct mbus_parser *m, int *i);
+int			 mbus_parse_flt(struct mbus_parser *m, double *d);
+char			*mbus_decode_str(char *s);
+char			*mbus_encode_str(const char *s);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _MBUS_PARSER_H */
Index: /common/tags/common_1_1_2/src/base64.h
===================================================================
--- /common/tags/common_1_1_2/src/base64.h (revision 428)
+++ /common/tags/common_1_1_2/src/base64.h (revision 428)
@@ -0,0 +1,38 @@
+/*
+ * FILE:    base64.h
+ * AUTHORS: Colin Perkins
+ * 
+ * Copyright (c) 1998-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+int base64encode(const unsigned char *input, int input_length, unsigned char *output, int output_length);
+int base64decode(const unsigned char *input, int input_length, unsigned char *output, int output_length);
+
Index: /common/tags/common_1_1_2/src/mbus_config.c
===================================================================
--- /common/tags/common_1_1_2/src/mbus_config.c (revision 428)
+++ /common/tags/common_1_1_2/src/mbus_config.c (revision 428)
@@ -0,0 +1,747 @@
+/*
+ * FILE:     mbus_config.c
+ * AUTHOR:   Colin Perkins
+ * MODIFIED: Orion Hodson
+ *           Markus Germeier
+ * 
+ * Copyright (c) 1999-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config_unix.h"
+#include "config_win32.h"
+#include "debug.h"
+#include "memory.h"
+#include "crypt_random.h"
+#include "base64.h"
+#include "mbus.h"
+#include "mbus_config.h"
+
+#define MBUS_ENCRYPT_BY_DEFAULT
+#define MBUS_ENCRKEY_LEN      8
+#define MBUS_HASHKEY_LEN     12
+#define MBUS_BUF_SIZE	   1500
+#define MBUS_FILE_NAME   ".mbus"
+#define MBUS_FILE_NAME_LEN    5
+
+struct mbus_config {
+#ifdef WIN32
+	HKEY		  cfgKey;
+#else
+	fd_t		  cfgfd;
+#endif
+	int		  cfg_locked;
+};
+
+char *mbus_new_encrkey(void)
+{
+	char		*key;	/* The key we are going to return... */
+#ifdef MBUS_ENCRYPT_BY_DEFAULT
+	/* Create a new key, for use by the hashing routines. Returns */
+	/* a key of the form (DES,MTIzMTU2MTg5MTEyMQ==)               */
+	char		 random_string[MBUS_ENCRKEY_LEN];
+	char		 encoded_string[(MBUS_ENCRKEY_LEN*4/3)+4];
+	int		 encoded_length;
+	int		 i, j, k;
+
+	/* Step 1: generate a random string for the key... */
+	for (i = 0; i < MBUS_ENCRKEY_LEN; i++) {
+		random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
+	}
+
+	/* Step 2: fill in parity bits to make DES library happy */
+	for (i = 0; i < MBUS_ENCRKEY_LEN; ++i) {
+	        k = random_string[i] & 0xfe;
+		j = k;
+		j ^= j >> 4;
+		j ^= j >> 2;
+		j ^= j >> 1;
+		j = (j & 1) ^ 1;
+		random_string[i] = k | j;
+	}
+
+	/* Step 3: base64 encode that string... */
+	memset(encoded_string, 0, (MBUS_ENCRKEY_LEN*4/3)+4);
+	encoded_length = base64encode(random_string, MBUS_ENCRKEY_LEN, encoded_string, (MBUS_ENCRKEY_LEN*4/3)+4);
+
+	/* Step 4: put it all together to produce the key... */
+	key = (char *) xmalloc(encoded_length + 18);
+	sprintf(key, "(DES,%s)", encoded_string);
+#else
+	key = (char *) xmalloc(9);
+	sprintf(key, "(NOENCR)");
+#endif
+	return key;
+}
+
+char *mbus_new_hashkey(void)
+{
+	/* Create a new key, for use by the hashing routines. Returns  */
+	/* a key of the form (HMAC-MD5-96,MTIzMTU2MTg5MTEyMQ==)           */
+	char		 random_string[MBUS_HASHKEY_LEN];
+	char		 encoded_string[(MBUS_HASHKEY_LEN*4/3)+4];
+	int		 encoded_length;
+	int		 i;
+	char		*key;
+
+	/* Step 1: generate a random string for the key... */
+	for (i = 0; i < MBUS_HASHKEY_LEN; i++) {
+		random_string[i] = ((int32_t)lbl_random() | 0x000ff000) >> 24;
+	}
+	/* Step 2: base64 encode that string... */
+	memset(encoded_string, 0, (MBUS_HASHKEY_LEN*4/3)+4);
+	encoded_length = base64encode(random_string, MBUS_HASHKEY_LEN, encoded_string, (MBUS_HASHKEY_LEN*4/3)+4);
+
+	/* Step 3: put it all together to produce the key... */
+	key = (char *) xmalloc(encoded_length + 26);
+	sprintf(key, "(HMAC-MD5-96,%s)", encoded_string);
+
+	return key;
+}
+
+static void rewrite_config(struct mbus_config *m)
+{
+#ifdef WIN32
+	char		*hashkey = mbus_new_hashkey();
+	char		*encrkey = mbus_new_encrkey();
+	char		*scope   = MBUS_DEFAULT_SCOPE_NAME;
+	const uint32_t	 cver    = MBUS_CONFIG_VERSION;
+	const uint32_t	 port    = MBUS_DEFAULT_NET_PORT;
+	char		*addr    = xstrdup(MBUS_DEFAULT_NET_ADDR);
+	char		 buffer[MBUS_BUF_SIZE];
+	LONG		 status;
+
+	status = RegSetValueEx(m->cfgKey, "CONFIG_VERSION", 0, REG_DWORD, (const uint8_t *) &cver, sizeof(cver));
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set version: %s\n", buffer);
+		abort();
+	}
+	status = RegSetValueEx(m->cfgKey, "HASHKEY", 0, REG_SZ, hashkey, strlen(hashkey) + 1);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set hashkey: %s\n", buffer);
+		abort();
+	}	
+	status = RegSetValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, REG_SZ, encrkey, strlen(encrkey) + 1);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set encrkey: %s\n", buffer);
+		abort();
+	}	
+	status = RegSetValueEx(m->cfgKey, "SCOPE", 0, REG_SZ, scope, strlen(scope) + 1);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set scope: %s\n", buffer);
+		abort();
+	}	
+	status = RegSetValueEx(m->cfgKey, "ADDRESS", 0, REG_SZ, addr, strlen(addr) + 1);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set address: %s\n", buffer);
+		abort();
+	}	
+	status = RegSetValueEx(m->cfgKey, "PORT", 0, REG_DWORD, (const uint8_t *) &port, sizeof(port));
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to set port: %s\n", buffer);
+		abort();
+	}	
+	xfree(addr);
+#else
+	char	*hashkey = mbus_new_hashkey();
+	char	*encrkey = mbus_new_encrkey();
+	char	 buf[1024];
+
+	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
+		perror("Can't seek to start of config file");
+		abort();
+	}
+	sprintf(buf, "[MBUS]\nCONFIG_VERSION=%d\nHASHKEY=%s\nENCRYPTIONKEY=%s\nSCOPE=%s\nADDRESS=%s\nPORT=%d\n", 
+		MBUS_CONFIG_VERSION, hashkey, encrkey, MBUS_DEFAULT_SCOPE_NAME, MBUS_DEFAULT_NET_ADDR, MBUS_DEFAULT_NET_PORT);
+	write(m->cfgfd, buf, strlen(buf));
+	free(hashkey);
+	xfree(encrkey);
+#endif
+}
+
+void mbus_lock_config_file(struct mbus_config *m)
+{
+#ifdef WIN32
+	/* Open the registry and create the mbus entries if they don't exist   */
+	/* already. The default contents of the registry are random encryption */
+	/* and authentication keys, and node local scope.                      */
+	HKEY			key    = HKEY_CURRENT_USER;
+	LPCTSTR			subKey = "Software\\Mbone Applications\\mbus";
+	DWORD			disp;
+	char			buffer[MBUS_BUF_SIZE];
+	LONG			status;
+
+	status = RegCreateKeyEx(key, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &(m->cfgKey), &disp);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to open registry: %s\n", buffer);
+		abort();
+	}
+	if (disp == REG_CREATED_NEW_KEY) {
+		rewrite_config(m);
+		debug_msg("Created new registry entry...\n");
+	} else {
+		debug_msg("Opened existing registry entry...\n");
+	}
+#else
+	/* Obtain a valid lock on the mbus configuration file. This function */
+	/* creates the file, if one does not exist. The default contents of  */
+	/* this file are random authentication and encryption keys, and node */
+	/* local scope.                                                      */
+	struct flock	 l;
+	struct stat	 s;
+	char		*buf;
+	char		*cfg_file;
+	char            *cfg_loc;
+	int              cfg_loc_len;
+
+	cfg_loc = getenv("MBUS");
+	if (cfg_loc == NULL) {
+                cfg_loc = getenv("HOME");
+                if (cfg_loc == NULL) {
+                        /* The getpwuid() stuff is to determine the users    */
+                        /* home directory, into which we write a .mbus       */
+                        /* config file. The struct returned by getpwuid() is */
+                        /* statically allocated, so it's not necessary to    */
+                        /* free it afterwards.                               */
+                        struct passwd	*p;	
+                        p = getpwuid(getuid());
+                        if (p == NULL) {
+                                perror("Unable to get passwd entry");
+                                abort();	      
+                        }
+                        cfg_loc = p->pw_dir;
+                }
+	}
+
+	/* Check if config_loc is terminated by mbus config file name. If    */
+        /* it's not add it.  This is allows environment variable MBUS to     */
+        /* point to config file of directory of config file.                 */
+        cfg_loc_len = strlen(cfg_loc);
+	if (cfg_loc_len < MBUS_FILE_NAME_LEN ||
+	    strcmp(cfg_loc + cfg_loc_len - MBUS_FILE_NAME_LEN, MBUS_FILE_NAME)){
+                /* File location does not include config file name.          */
+                cfg_file = (char*)xmalloc(cfg_loc_len + MBUS_FILE_NAME_LEN + 2);
+                sprintf(cfg_file, "%s/%s", cfg_loc, MBUS_FILE_NAME);	
+	} else {
+                cfg_file = xstrdup(cfg_loc);
+	}
+        
+	m->cfgfd = open(cfg_file, O_RDWR | O_CREAT, 0600);
+	if (m->cfgfd == -1) {
+		perror("Unable to open mbus configuration file");
+		abort();
+	}
+	xfree(cfg_file);
+
+	/* We attempt to get a lock on the config file, blocking until  */
+	/* the lock can be obtained. The only time this should block is */
+	/* when another instance of this code has a write lock on the   */
+	/* file, because the contents are being updated.                */
+	l.l_type   = F_WRLCK;
+	l.l_start  = 0;
+	l.l_whence = SEEK_SET;
+	l.l_len    = 0;
+	if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
+		perror("Unable to lock mbus configuration file");
+		abort();
+	}
+
+	if (fstat(m->cfgfd, &s) != 0) {
+		perror("Unable to stat config file\n");
+		abort();
+	}
+	if (s.st_size == 0) {
+		/* Empty file, create with sensible defaults... */
+		rewrite_config(m);
+	} else {
+		/* Read in the contents of the config file... */
+		buf = (char *) xmalloc(s.st_size+1);
+		memset(buf, '\0', s.st_size+1);
+		if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
+			perror("Unable to read config file\n");
+			abort();
+		}
+		/* Check that the file contains sensible information...   */
+		/* This is rather a pathetic check, but it'll do for now! */
+		if (strncmp(buf, "[MBUS]", 6) != 0) {
+			debug_msg("Mbus config file has incorrect header\n");
+			abort();
+		}
+		xfree(buf);
+	}
+#endif
+	m->cfg_locked = TRUE;
+	if (mbus_get_version(m) < MBUS_CONFIG_VERSION) {
+		rewrite_config(m);
+		debug_msg("Updated Mbus configuration database.\n");
+	}
+	if (mbus_get_version(m) > MBUS_CONFIG_VERSION) {
+		debug_msg("Mbus configuration database has later version number than expected.\n");
+		debug_msg("Continuing, in the hope that the extensions are backwards compatible.\n");
+	}
+}
+
+void mbus_unlock_config_file(struct mbus_config *m)
+{
+#ifdef WIN32
+	LONG status;
+	char buffer[MBUS_BUF_SIZE];
+	
+	status = RegCloseKey(m->cfgKey);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to close registry: %s\n", buffer);
+		abort();
+	}
+	debug_msg("Closed registry entry...\n");
+#else
+	struct flock	l;
+
+	l.l_type   = F_UNLCK;
+	l.l_start  = 0;
+	l.l_whence = SEEK_SET;
+	l.l_len    = 0;
+	if (fcntl(m->cfgfd, F_SETLKW, &l) == -1) {
+		perror("Unable to unlock mbus configuration file");
+		abort();
+	}
+	close(m->cfgfd);
+	m->cfgfd = -1;
+#endif
+	m->cfg_locked = FALSE;
+}
+
+#ifndef WIN32
+static void mbus_get_key(struct mbus_config *m, struct mbus_key *key, const char *id)
+{
+	struct stat	 s;
+	char		*buf;
+	char		*line;
+	char		*tmp;
+	int		 pos;
+        int              linepos;
+
+	assert(m->cfg_locked);
+
+	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
+		perror("Can't seek to start of config file");
+		abort();
+	}
+	if (fstat(m->cfgfd, &s) != 0) {
+		perror("Unable to stat config file\n");
+		abort();
+	}
+	/* Read in the contents of the config file... */
+	buf = (char *) xmalloc(s.st_size+1);
+	memset(buf, '\0', s.st_size+1);
+	if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
+		perror("Unable to read config file\n");
+		abort();
+	}
+	
+	line = (char *) xmalloc(s.st_size+1);
+	sscanf(buf, "%s", line);
+	if (strcmp(line, "[MBUS]") != 0) {
+		debug_msg("Invalid .mbus file\n");
+		abort();
+	}
+	pos = strlen(line) + 1;
+	while (pos < s.st_size) {
+                /* get whole line and filter out spaces */
+                /* this is good enough for getting keys */
+                linepos=0;
+                do {
+                    while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n')
+                                                 ||(buf[pos+linepos]=='\t'))
+                        pos++;
+                    sscanf(buf+pos+linepos, "%s", line+linepos);                
+                    linepos = strlen(line);
+                } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1)));
+                pos += linepos + 1;
+		if (strncmp(line, id, strlen(id)) == 0) {
+			key->algorithm   = (char *) strdup(strtok(line+strlen(id), ",)"));
+			if (strcmp(key->algorithm, "NOENCR") != 0) {
+				key->key     = (char *) strtok(NULL  , ")");
+                                assert(key->key!=NULL);
+				key->key_len = strlen(key->key);
+				tmp = (char *) xmalloc(key->key_len);
+				key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
+				key->key = tmp;
+			} else {
+				key->key     = NULL;
+				key->key_len = 0;
+			}
+			xfree(buf);
+			xfree(line);
+			return;
+		}
+	}
+	debug_msg("Unable to read hashkey from config file\n");
+	xfree(buf);
+	xfree(line);
+}
+#endif
+
+void mbus_get_encrkey(struct mbus_config *m, struct mbus_key *key)
+{
+	/* This MUST be called while the config file is locked! */
+	int		 i, j, k;
+#ifdef WIN32
+	long		 status;
+	DWORD		 type;
+	char		*buffer;
+	int	 	 buflen = MBUS_BUF_SIZE;
+	char		*tmp;
+
+	assert(m->cfg_locked);
+	
+	/* Read the key from the registry... */
+	buffer = (char *) xmalloc(MBUS_BUF_SIZE);
+	status = RegQueryValueEx(m->cfgKey, "ENCRYPTIONKEY", 0, &type, buffer, &buflen);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get encrkey: %s\n", buffer);
+		abort();
+	}
+	assert(type == REG_SZ);
+	assert(buflen > 0);
+
+	/* Parse the key... */
+	key->algorithm   = strdup(strtok(buffer+1, ",)"));
+	if (strcmp(key->algorithm, "NOENCR") != 0) {
+		key->key     = (char *) strtok(NULL  , ")");
+		key->key_len = strlen(key->key);
+		tmp = (char *) xmalloc(key->key_len);
+		key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
+		key->key = tmp;
+	} else {
+		key->key     = NULL;
+		key->key_len = 0;
+	}
+	xfree(buffer);
+#else
+	mbus_get_key(m, key, "ENCRYPTIONKEY=(");
+#endif
+	if (strcmp(key->algorithm, "DES") == 0) {
+		assert(key->key != NULL);
+		assert(key->key_len == 8);
+
+		/* check parity bits */
+		for (i = 0; i < 8; ++i) 
+		{
+			k = key->key[i] & 0xfe;
+			j = k;
+			j ^= j >> 4;
+			j ^= j >> 2;
+			j ^= j >> 1;
+			j = (j & 1) ^ 1;
+			assert((key->key[i] & 0x01) == j);
+		}
+	}
+}
+
+void mbus_get_hashkey(struct mbus_config *m, struct mbus_key *key)
+{
+	/* This MUST be called while the config file is locked! */
+#ifdef WIN32
+	long	 status;
+	DWORD	 type;
+	char	*buffer;
+	int	 buflen = MBUS_BUF_SIZE;
+	char	*tmp;
+
+	assert(m->cfg_locked);
+	
+	/* Read the key from the registry... */
+	buffer = (char *) xmalloc(MBUS_BUF_SIZE);
+	status = RegQueryValueEx(m->cfgKey, "HASHKEY", 0, &type, buffer, &buflen);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get encrkey: %s\n", buffer);
+		abort();
+	}
+	assert(type == REG_SZ);
+	assert(buflen > 0);
+
+	/* Parse the key... */
+	key->algorithm   = strdup(strtok(buffer+1, ","));
+	key->key         = strtok(NULL  , ")");
+	key->key_len     = strlen(key->key);
+
+	/* Decode the key... */
+	tmp = (char *) xmalloc(key->key_len);
+	key->key_len = base64decode(key->key, key->key_len, tmp, key->key_len);
+	key->key = tmp;
+
+	xfree(buffer);
+#else
+	mbus_get_key(m, key, "HASHKEY=(");
+#endif
+}
+
+void mbus_get_net_addr(struct mbus_config *m, char *net_addr, uint16_t *net_port, int *net_scope)
+{
+#ifdef WIN32
+	long	 status;
+	DWORD	 type;
+	char	*buffer;
+	int	 buflen = MBUS_BUF_SIZE;
+	uint32_t port;
+
+	assert(m->cfg_locked);
+	
+	/* Read the key from the registry... */
+	buffer = (char *) xmalloc(MBUS_BUF_SIZE);
+        buflen = MBUS_BUF_SIZE;
+	status = RegQueryValueEx(m->cfgKey, "ADDRESS", 0, &type, buffer, &buflen);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get address: %s\n", buffer);
+		strcpy(net_addr, MBUS_DEFAULT_NET_ADDR);
+	} else {
+		assert(type == REG_SZ);
+		assert(buflen > 0);
+		strncpy(net_addr, buffer, buflen);
+	}
+
+	buflen = sizeof(port);
+	status = RegQueryValueEx(m->cfgKey, "PORT", 0, &type, (uint8_t *) &port, &buflen);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get port: %s\n", buffer);
+		*net_port  = MBUS_DEFAULT_NET_PORT;
+	} else {
+		assert(type == REG_DWORD);
+		assert(buflen == 4);
+		*net_port = (uint16_t) port;
+	}
+
+	buflen = MBUS_BUF_SIZE;
+	status = RegQueryValueEx(m->cfgKey, "SCOPE", 0, &type, buffer, &buflen);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get scope: %s\n", buffer);
+		*net_scope = MBUS_DEFAULT_SCOPE;
+	} else {
+		assert(type == REG_SZ);
+		assert(buflen > 0);
+		if (strncmp(buffer, SCOPE_HOSTLOCAL_NAME, strlen(SCOPE_HOSTLOCAL_NAME)) == 0) {
+			*net_scope = SCOPE_HOSTLOCAL;
+		} else if (strncmp(buffer, SCOPE_LINKLOCAL_NAME, strlen(SCOPE_LINKLOCAL_NAME)) == 0) {
+			*net_scope = SCOPE_LINKLOCAL;
+		} else {
+			debug_msg("Unrecognized scope: %s\n", buffer);
+			*net_scope = MBUS_DEFAULT_SCOPE;
+		}
+	}
+        xfree(buffer);
+#else
+	struct stat	 s;
+	char		*buf;
+	char		*line;
+	int		 pos;
+	int              pos2;
+        int              linepos;
+
+	int              scope;
+	char            *addr;
+	uint16_t        port;
+
+	assert(m->cfg_locked);
+
+	addr = (char *)xmalloc(20);
+	memset(addr, 0, 20);
+	port = 0;
+	scope = -1;
+	
+
+	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
+		perror("Can't seek to start of config file");
+		abort();
+	}
+	if (fstat(m->cfgfd, &s) != 0) {
+		perror("Unable to stat config file\n");
+		abort();
+	}
+	/* Read in the contents of the config file... */
+	buf = (char *) xmalloc(s.st_size+1);
+	memset(buf, '\0', s.st_size+1);
+	if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
+		perror("Unable to read config file\n");
+		abort();
+	}
+	
+	line = (char *) xmalloc(s.st_size+1);
+	sscanf(buf, "%s", line);
+	if (strcmp(line, "[MBUS]") != 0) {
+		debug_msg("Invalid .mbus file\n");
+		abort();
+	}
+	pos = strlen(line) + 1;
+	while (pos < s.st_size) {
+                /* get whole line and filter out spaces */
+                linepos=0;
+                do {
+                    while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n')
+                                                 ||(buf[pos+linepos]=='\t'))
+                        pos++;
+                    sscanf(buf+pos+linepos, "%s", line+linepos);                
+                    linepos = strlen(line);
+  
+                } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1)));
+                pos += linepos + 1;     
+		if (strncmp(line, "SCOPE", strlen("SCOPE")) == 0) {
+		    pos2 = strlen("SCOPE") + 1;
+		    if (strncmp(line+pos2, SCOPE_HOSTLOCAL_NAME, 
+				strlen(SCOPE_HOSTLOCAL_NAME)) == 0) {
+			scope = SCOPE_HOSTLOCAL;
+		    }
+		    if (strncmp(line+pos2, SCOPE_LINKLOCAL_NAME, 
+				strlen(SCOPE_LINKLOCAL_NAME)) == 0) {
+			scope = SCOPE_LINKLOCAL ;
+		    }
+		}
+		if (strncmp(line, "ADDRESS", strlen("ADDRESS")) == 0) {
+		    pos2 = strlen("ADDRESS") + 1;
+		    strncpy(addr, line+pos2, 16);
+		}
+		if (strncmp(line, "PORT", strlen("PORT")) == 0) {
+		    pos2 = strlen("PORT") + 1;
+		    port = atoi(line+pos2);
+		}
+		    
+	}
+	/* If we did not find all values, fill in the default ones */
+	*net_port  = (port>0)?port:MBUS_DEFAULT_NET_PORT;
+	*net_scope = (scope!=-1)?scope:MBUS_DEFAULT_SCOPE;
+	if (strlen(addr)>0) {
+		strncpy(net_addr, addr, 16);
+	} else {
+		strcpy(net_addr, MBUS_DEFAULT_NET_ADDR);
+	}
+	debug_msg("using Addr:%s Port:%d Scope:%s for MBUS\n", 
+		  net_addr, *net_port, (*net_scope==0)?SCOPE_HOSTLOCAL_NAME:SCOPE_LINKLOCAL_NAME);
+	xfree(buf);
+	xfree(line);
+	xfree(addr);
+#endif
+}
+
+int mbus_get_version(struct mbus_config *m)
+{
+#ifdef WIN32
+	long		status;
+	DWORD		type;
+	uint32_t	cver;
+	int		verl;
+	char		buffer[MBUS_BUF_SIZE];
+
+	assert(m->cfg_locked);
+	
+	/* Read the key from the registry... */
+        verl = sizeof(&cver);
+	status = RegQueryValueEx(m->cfgKey, "CONFIG_VERSION", 0, &type, (uint8_t *) &cver, &verl);
+	if (status != ERROR_SUCCESS) {
+		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, status, 0, buffer, MBUS_BUF_SIZE, NULL);
+		debug_msg("Unable to get version: %s\n", buffer);
+		return 0;
+	}
+	assert(type == REG_DWORD);
+	assert(verl == 4);
+	return cver;
+#else
+	struct stat	 s;
+	char		*buf;
+	char		*line;
+	int		 pos;
+	int              pos2;
+        int              linepos;
+	int		 version = 0;
+
+	assert(m->cfg_locked);
+
+	if (lseek(m->cfgfd, 0, SEEK_SET) == -1) {
+		perror("Can't seek to start of config file");
+		abort();
+	}
+	if (fstat(m->cfgfd, &s) != 0) {
+		perror("Unable to stat config file\n");
+		abort();
+	}
+	/* Read in the contents of the config file... */
+	buf = (char *) xmalloc(s.st_size+1);
+	memset(buf, '\0', s.st_size+1);
+	if (read(m->cfgfd, buf, s.st_size) != s.st_size) {
+		perror("Unable to read config file\n");
+		abort();
+	}
+	
+	line = (char *) xmalloc(s.st_size+1);
+	sscanf(buf, "%s", line);
+	if (strcmp(line, "[MBUS]") != 0) {
+		debug_msg("Invalid .mbus file\n");
+		abort();
+	}
+	pos = strlen(line) + 1;
+	while (pos < s.st_size) {
+                /* get whole line and filter out spaces */
+                linepos=0;
+                do {
+			while((buf[pos+linepos]==' ')||(buf[pos+linepos]=='\n') ||(buf[pos+linepos]=='\t')) {
+				pos++;
+			}
+			sscanf(buf+pos+linepos, "%s", line+linepos);                
+			linepos = strlen(line);
+                } while((buf[pos+linepos]!='\n') && (s.st_size>(pos+linepos+1)));
+                pos += linepos + 1;     
+		if (strncmp(line, "CONFIG_VERSION", strlen("CONFIG_VERSION")) == 0) {
+		    pos2    = strlen("CONFIG_VERSION") + 1;
+		    version = atoi(line+pos2);
+		}
+		    
+	}
+	xfree(buf);
+	xfree(line);
+	return version;
+#endif
+}
+
+struct mbus_config *mbus_create_config(void)
+{
+	return (struct mbus_config *) xmalloc(sizeof(struct mbus_config));
+}
+
Index: /common/tags/common_1_1_2/src/common.dsp
===================================================================
--- /common/tags/common_1_1_2/src/common.dsp (revision 431)
+++ /common/tags/common_1_1_2/src/common.dsp (revision 431)
@@ -0,0 +1,357 @@
+# Microsoft Developer Studio Project File - Name="common" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=common - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "common.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "common.mak" CFG="common - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "common - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "common - Win32 Debug IPv6" (based on "Win32 (x86) Static Library")
+!MESSAGE "common - Win32 Debug IPv6 Musica" (based on "Win32 (x86) Static Library")
+!MESSAGE "common - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "common - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "HAVE_INET_NTOP" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Release\uclmm.lib"
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug IPv6"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "common___Win32_Debug_IPv6"
+# PROP BASE Intermediate_Dir "common___Win32_Debug_IPv6"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_IPv6"
+# PROP Intermediate_Dir "Debug_IPv6"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\IPv6Kit\inc" /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "..\ipv6kit\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /D "NEED_IN6_IS_ADDR_MULTICAST" /D "HAVE_INET_PTON" /D "HAVE_INET_NTOP" /FR /YX /FD /GZ /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"Debug\uclmm.lib"
+# ADD LIB32 /nologo /out:"Debug_IPv6\uclmm.lib"
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug IPv6 Musica"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "common___Win32_Debug_IPv6_Musica"
+# PROP BASE Intermediate_Dir "common___Win32_Debug_IPv6_Musica"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug_IPv6_Musica"
+# PROP Intermediate_Dir "Debug_IPv6_Musica"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /I "\src\tcl-8.0\generic" /I "\src\tk-8.0\generic" /I "\src\tk-8.0\xlib" /I "\DDK\inc" /I "\src\MSR_IPv6_1.3\inc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /D "HAVE_IPv6" /D "BUILD_tcl" /D "BUILD_tk" /FR /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /I "\DDK\inc" /I "..\IPv6Kit\inc" /I "..\MUSICA\WINSOCK6" /D "_MBCS" /D "_LIB" /D "DEBUG_MEM" /D "BUILD_tcl" /D "BUILD_tk" /D "DEBUG" /D "WIN32" /D "_DEBUG" /D "HAVE_IPv6" /D "MUSICA_IPV6" /D "_WINNT" /D "_POSIX" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo /out:"Debug\uclmm.lib"
+# ADD LIB32 /nologo /out:"Debug\uclmm.lib"
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\tcl-8.0\generic" /I "..\tk-8.0\generic" /I "..\tk-8.0\xlib" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "DEBUG" /D "DEBUG_MEM" /FR /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Debug\uclmm.lib"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "common - Win32 Release"
+# Name "common - Win32 Debug IPv6"
+# Name "common - Win32 Debug IPv6 Musica"
+# Name "common - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\base64.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\crypt_random.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\debug.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\drand48.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\gettimeofday.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\hmac.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\inet_ntop.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\inet_pton.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_addr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_config.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_parser.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\memory.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_udp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\ntp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\qfDES.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\rtp.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\base64.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\btree.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\config_unix.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\config_win32.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\crypt_random.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\debug.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\drand48.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\gettimeofday.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\hmac.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inet_ntop.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\inet_pton.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_addr.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_config.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\mbus_parser.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\md5.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\memory.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\net_udp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ntp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\qfDES.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\rtp.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\util.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\version.h
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\VERSION
+
+!IF  "$(CFG)" == "common - Win32 Release"
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug IPv6"
+
+# Begin Custom Build
+InputPath=.\VERSION
+
+"version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	copy win32\set.txt + VERSION win32\vergen.bat 
+	copy win32\vergen.bat + win32\null.txt win32\vergen.bat 
+	copy win32\vergen.bat + win32\echo.txt win32\vergen.bat 
+	win32\vergen.bat 
+	move win32\version.h version.h 
+	erase win32\version.h 
+	erase win32\vergen.bat 
+	
+# End Custom Build
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug IPv6 Musica"
+
+!ELSEIF  "$(CFG)" == "common - Win32 Debug"
+
+# Begin Custom Build
+InputPath=.\VERSION
+
+"version.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+	copy win32\set.txt + VERSION win32\vergen.bat 
+	copy win32\vergen.bat + win32\null.txt win32\vergen.bat 
+	copy win32\vergen.bat + win32\echo.txt win32\vergen.bat 
+	win32\vergen.bat 
+	move win32\version.h version.h 
+	erase win32\version.h 
+	erase win32\vergen.bat 
+	
+# End Custom Build
+
+!ENDIF 
+
+# End Source File
+# End Target
+# End Project
Index: /common/tags/common_1_1_2/src/config_win32.h
===================================================================
--- /common/tags/common_1_1_2/src/config_win32.h (revision 365)
+++ /common/tags/common_1_1_2/src/config_win32.h (revision 365)
@@ -0,0 +1,215 @@
+/*
+ *  config-win32.h
+ *
+ *  Windows specific definitions and includes.
+ *  
+ *  $Revision$
+ *  $Date$
+ *
+ * Copyright (c) 1995-2000 University College London
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions 
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Computer Science
+ *      Department at University College London
+ * 4. Neither the name of the University nor of the Department may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef WIN32
+#ifndef _CONFIG_WIN32_H
+#define _CONFIG_WIN32_H
+
+#include <limits.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <memory.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>   /* abs() */
+#include <string.h>
+#ifndef MUSICA_IPV6
+#include <winsock2.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_IPv6
+#ifdef MUSICA_IPV6
+#include <winsock6.h>
+#else
+#include <ws2ip6.h>
+#endif
+#endif
+
+#ifndef MUSICA_IPV6
+#include <ws2tcpip.h>
+#endif
+
+#include <mmreg.h>
+#include <msacm.h>
+#include <mmsystem.h>
+#include <windows.h>
+#include <io.h>
+#include <process.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/timeb.h>
+
+typedef int		ttl_t;
+typedef unsigned int	fd_t;
+
+/*
+ * the definitions below are valid for 32-bit architectures and will have to
+ * be adjusted for 16- or 64-bit architectures
+ */
+typedef u_char		uint8_t;
+typedef u_short		uint16_t;
+typedef u_long		uint32_t;
+typedef char		int8_t;
+typedef short		int16_t;
+typedef long		int32_t;
+typedef __int64		int64_t;
+typedef unsigned long	in_addr_t;
+
+#ifndef TRUE
+#define FALSE	0
+#define	TRUE	1
+#endif /* TRUE */
+
+#define USERNAMELEN	8
+
+#define WORDS_SMALLENDIAN
+#define NEED_INET_ATON
+#define NEED_DRAND48
+#define NEED_GETTIMEOFDAY
+
+#ifdef NDEBUG
+#define assert(x) if ((x) == 0) fprintf(stderr, "%s:%u: failed assertion\n", __FILE__, __LINE__)
+#else
+#include <assert.h>
+#endif
+
+#include <time.h>		/* For clock_t */
+
+#define inline
+#define __inline     
+
+#define AUDIO_MICROPHONE	1
+#define AUDIO_LINE_IN		2
+#define AUDIO_CD            4
+#define AUDIO_SPEAKER		0
+#define AUDIO_HEADPHONE		1
+#define AUDIO_LINE_OUT		4
+
+#define srand48	srand
+#define lrand48 rand
+#define snprintf _snprintf
+
+#define IN_CLASSD(i)	(((long)(i) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(i)	IN_CLASSD(i)
+
+typedef char	*caddr_t;
+typedef int	ssize_t;
+
+typedef struct iovec {
+	caddr_t	iov_base;
+	ssize_t	iov_len;
+} iovec_t;
+
+struct msghdr {
+	caddr_t		msg_name;
+	int		msg_namelen;
+	struct iovec	*msg_iov;
+	int		msg_iovlen;
+	caddr_t		msg_accrights;
+	int		msg_accrightslen;
+};
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN	256
+#endif
+
+#define _SYS_NMLN	9
+struct utsname {
+	char sysname[_SYS_NMLN];
+	char nodename[_SYS_NMLN];
+	char release[_SYS_NMLN];
+	char version[_SYS_NMLN];
+	char machine[_SYS_NMLN];
+};
+
+struct timezone {
+	int tz_minuteswest;
+	int tz_dsttime;
+};
+
+typedef int pid_t;
+typedef int uid_t;
+typedef int gid_t;
+    
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+int uname(struct utsname *);
+int getopt(int, char * const *, const char *);
+int strncasecmp(const char *, const char*, int len);
+int srandom(int);
+int random(void);
+int gethostid(void);
+int getuid(void);
+int getgid(void);
+int getpid(void);
+int nice(int);
+int usleep(unsigned int);
+time_t time(time_t *);
+
+const char * w32_make_version_info(char * rat_verion);
+
+#define strcasecmp  _stricmp
+#define strncasecmp _strnicmp
+
+int  RegGetValue(HKEY *, char *, char*, char*, int);
+void ShowMessage(int level, char *msg);
+
+#define bcopy(from,to,len) memcpy(to,from,len)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define ECONNREFUSED	WSAECONNREFUSED
+#define ENETUNREACH		WSAENETUNREACH
+#define EHOSTUNREACH	WSAEHOSTUNREACH
+#define EWOULDBLOCK		WSAEWOULDBLOCK
+
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT	WSAEAFNOSUPPORT
+#endif
+
+#define M_PI		3.14159265358979323846
+
+#endif 
+#endif
Index: /common/tags/common_1_1_2/COPYRIGHT
===================================================================
--- /common/tags/common_1_1_2/COPYRIGHT (revision 360)
+++ /common/tags/common_1_1_2/COPYRIGHT (revision 360)
@@ -0,0 +1,35 @@
+Copyright (C) 1995-2000 University College London
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, is permitted provided that the following conditions 
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+   must display the following acknowledgement:
+     This product includes software developed by the Computer Science
+     Department at University College London
+4. Neither the name of the University nor of the Department may be used
+   to endorse or promote products derived from this software without
+   specific prior written permission.
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
+EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+This product includes software developed by the Computer Systems
+Engineering Group at Lawrence Berkeley Laboratory.
+
+Encryption features of this software use the RSA Data Security, Inc. MD5
+Message-Digest Algorithm.
Index: /common/tags/common_1_1_2/config.guess
===================================================================
--- /common/tags/common_1_1_2/config.guess (revision 301)
+++ /common/tags/common_1_1_2/config.guess (revision 301)
@@ -0,0 +1,951 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+	if test $UNAME_RELEASE = "V4.0"; then
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+	fi
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	cat <<EOF >dummy.s
+	.globl main
+	.ent main
+main:
+	.frame \$30,0,\$26,0
+	.prologue 0
+	.long 0x47e03d80 # implver $0
+	lda \$2,259
+	.long 0x47e20c21 # amask $2,$1
+	srl \$1,8,\$2
+	sll \$2,2,\$2
+	sll \$0,3,\$0
+	addl \$1,\$0,\$0
+	addl \$2,\$0,\$0
+	ret \$31,(\$26),1
+	.end main
+EOF
+	${CC-cc} dummy.s -o dummy 2>/dev/null
+	if test "$?" = 0 ; then
+		./dummy
+		case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+		esac
+	fi
+	rm -f dummy.s dummy
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-cbm-sysv4
+	exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    arc64:OpenBSD:*:*)
+	echo mips64el-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hkmips:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    arm32:NetBSD:*:*)
+	echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:NetBSD:*:*)
+	echo m68k-atari-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:NetBSD:*:*)
+	echo m68k-sun-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3*:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:NetBSD:*:*)
+	echo m68k-apple-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:NetBSD:*:*)
+        echo powerpc-apple-netbsd${UNAME_RELEASE}
+        exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	sed 's/^	//' << EOF >dummy.c
+	int main (argc, argv) int argc; char **argv; {
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	${CC-cc} dummy.c -o dummy \
+	  && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && rm dummy.c dummy && exit 0
+	rm -f dummy.c dummy
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+	if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+	     -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		sed 's/^		//' << EOF >dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+		rm -f dummy.c dummy
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:4)
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=4.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
+              sed 's/^              //' << EOF >dummy.c
+              #include <stdlib.h>
+              #include <unistd.h>
+              
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif 
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+              
+                  switch (cpu) 
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0: 
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits) 
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif 
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+	(${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy`
+	rm -f dummy.c dummy
+	esac
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	sed 's/^	//' << EOF >dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+	rm -f dummy.c dummy
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i?86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+	echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE}
+	exit 0 ;;
+    CRAY-2:*:*:*)
+	echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+	echo m68k-hp-netbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:NetBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:Linux:*:*)
+	# uname on the ARM produces all sorts of strangeness, and we need to
+	# filter it out.
+	case "$UNAME_MACHINE" in
+	  arm* | sa110*)	      UNAME_MACHINE="arm" ;;
+	esac
+
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us.
+	ld_help_string=`ld --help 2>&1`
+	ld_supported_emulations=`echo $ld_help_string \
+			 | sed -ne '/supported emulations:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported emulations: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_emulations" in
+	  i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+	  i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+	  sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  armlinux)   echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+	  elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+	esac
+
+	if test "${UNAME_MACHINE}" = "alpha" ; then
+		sed 's/^	//'  <<EOF >dummy.s
+		.globl main
+		.ent main
+	main:
+		.frame \$30,0,\$26,0
+		.prologue 0
+		.long 0x47e03d80 # implver $0
+		lda \$2,259
+		.long 0x47e20c21 # amask $2,$1
+		srl \$1,8,\$2
+		sll \$2,2,\$2
+		sll \$0,3,\$0
+		addl \$1,\$0,\$0
+		addl \$2,\$0,\$0
+		ret \$31,(\$26),1
+		.end main
+EOF
+		LIBC=""
+		${CC-cc} dummy.s -o dummy 2>/dev/null
+		if test "$?" = 0 ; then
+			./dummy
+			case "$?" in
+			7)
+				UNAME_MACHINE="alpha"
+				;;
+			15)
+				UNAME_MACHINE="alphaev5"
+				;;
+			14)
+				UNAME_MACHINE="alphaev56"
+				;;
+			10)
+				UNAME_MACHINE="alphapca56"
+				;;
+			16)
+				UNAME_MACHINE="alphaev6"
+				;;
+			esac	
+
+			objdump --private-headers dummy | \
+			  grep ld.so.1 > /dev/null
+			if test "$?" = 0 ; then
+				LIBC="libc1"
+			fi
+		fi	
+		rm -f dummy.s dummy
+		echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+	elif test "${UNAME_MACHINE}" = "mips" ; then
+	  cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+	  rm -f dummy.c dummy
+	else
+	  # Either a pre-BFD a.out linker (linux-gnuoldld)
+	  # or one that does not give us useful --help.
+	  # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+	  # If ld does not provide *any* "supported emulations:"
+	  # that means it is gnuoldld.
+	  echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+	  test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+	  case "${UNAME_MACHINE}" in
+	  i?86)
+	    VENDOR=pc;
+	    ;;
+	  *)
+	    VENDOR=unknown;
+	    ;;
+	  esac
+	  # Determine whether the default compiler is a.out or elf
+	  cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+	  ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+	  rm -f dummy.c dummy
+	fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+	fi
+	exit 0 ;;
+    i?86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    i?86:UnixWare:*:*)
+	if /bin/uname -X 2>/dev/null >/dev/null ; then
+	  (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+	    && UNAME_MACHINE=i586
+	fi
+	echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
+	exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    M68*:*:R3V[567]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    i?86:LynxOS:2.*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:*:6*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
Index: /common/tags/common_1_1_2/.cvsignore
===================================================================
--- /common/tags/common_1_1_2/.cvsignore (revision 301)
+++ /common/tags/common_1_1_2/.cvsignore (revision 301)
@@ -0,0 +1,9 @@
+config.status
+config.log
+config.cache
+config.h
+Makefile
+test-libcommon
+version.h
+.pure
+.devel
Index: /common/tags/common_1_1_2/README
===================================================================
--- /common/tags/common_1_1_2/README (revision 433)
+++ /common/tags/common_1_1_2/README (revision 433)
@@ -0,0 +1,5 @@
+UCL Common Code Library
+
+Routines common to a number of multimedia tools. This library is required
+to build RAT v3.2.7 or later, and may be needed for other UCL tools.
+
Index: /common/tags/common_1_1_2/config.sub
===================================================================
--- /common/tags/common_1_1_2/config.sub (revision 301)
+++ /common/tags/common_1_1_2/config.sub (revision 301)
@@ -0,0 +1,955 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+	echo Configuration name missing. 1>&2
+	echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+	echo "or     $0 ALIAS" 1>&2
+	echo where ALIAS is a recognized configuration type. 1>&2
+	exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+	*local*)
+		echo $1
+		exit 0
+		;;
+	*)
+	;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple)
+		os=
+		basic_machine=$1
+		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+		| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+		| 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
+		| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+		| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+		| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+		| mipstx39 | mipstx39el \
+		| sparc | sparclet | sparclite | sparc64 | v850)
+		basic_machine=$basic_machine-unknown
+		;;
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i[34567]86)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+	      | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+	      | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+	      | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+	      | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
+	      | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+	      | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+	      | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+	      | sparc64-* | mips64-* | mipsel-* \
+	      | mips64el-* | mips64orion-* | mips64orionel-*  \
+	      | mipstx39-* | mipstx39el-* \
+	      | f301-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-cbm
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-cbm
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-cbm
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	cray2)
+		basic_machine=cray2-cray
+		os=-unicos
+		;;
+	[ctj]90-cray)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i[34567]86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i[34567]86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i[34567]86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i[34567]86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	mipsel*-linux*)
+		basic_machine=mipsel-unknown
+		os=-linux-gnu
+		;;
+	mips*-linux*)
+		basic_machine=mips-unknown
+		os=-linux-gnu
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+        pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | nexen)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | k6 | 6x86)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | nexen-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | k6-* | 6x86-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=rs6000-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+	        ;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+	        ;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	xmp)
+		basic_machine=xmp-cray
+		os=-unicos
+		;;
+        xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	mips)
+		if [ x$os = x-linux-gnu ]; then
+			basic_machine=mips-unknown
+		else
+			basic_machine=mips-mips
+		fi
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sparc)
+		basic_machine=sparc-sun
+		;;
+        cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+	      | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -uxpv* | -beos*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-ns2 )
+	        os=-nextstep2
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+        *-gould)
+		os=-sysv
+		;;
+        *-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+        *-sgi)
+		os=-irix
+		;;
+        *-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f301-fujitsu)
+		os=-uxpv
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-vxsim* | -vxworks*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
Index: /common/tags/common_1_1_2/install-sh
===================================================================
--- /common/tags/common_1_1_2/install-sh (revision 301)
+++ /common/tags/common_1_1_2/install-sh (revision 301)
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
