[netperf-dev] netperf4 commit notice r211 - in branches/gobject_migration: src suites/multi

raj at netperf.org raj at netperf.org
Mon Mar 12 14:41:41 PST 2007


Author: raj
Date: 2007-03-12 14:41:39 -0800 (Mon, 12 Mar 2007)
New Revision: 211

Added:
   branches/gobject_migration/src/netlib4.c
Removed:
   branches/gobject_migration/suites/multi/Makefile
Modified:
   branches/gobject_migration/src/netperf-control.c
   branches/gobject_migration/src/netperf-netserver.c
   branches/gobject_migration/src/netperf-test.c
   branches/gobject_migration/src/netperf-test.h
   branches/gobject_migration/src/nettest_bsd.c
Log:
still more baby steps

Added: branches/gobject_migration/src/netlib4.c
===================================================================
--- branches/gobject_migration/src/netlib4.c	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/netlib4.c	2007-03-12 22:41:39 UTC (rev 211)
@@ -0,0 +1,2372 @@
+char netlib4_id[]="\
+@(#)netlib4.c (c) Copyright 2005, Hewlett-Packard Company, $Id: netlib.c 200 2007-03-01 19:23:41Z raj $";
+
+/*
+
+This file is part of netperf4.
+
+Netperf4 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.
+
+Netperf4 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.
+
+In addition, as a special exception, the copyright holders give
+permission to link the code of netperf4 with the OpenSSL project's
+"OpenSSL" library (or with modified versions of it that use the same
+license as the "OpenSSL" library), and distribute the linked
+executables.  You must obey the GNU General Public License in all
+respects for all of the code used other than "OpenSSL".  If you modify
+this file, you may extend this exception to your version of the file,
+but you are not obligated to do so.  If you do not wish to do so,
+delete this exception statement from your version.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
+#ifdef _AIX
+#include <sys/thread.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_UIO_H
+#include <sys/uio.h>
+#endif
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+# include <glib.h>
+# include <gmodule.h>
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
+#define NETLIB
+
+#include "netperf.h"
+
+/* perhaps we should hoist all these up into netperf.h? */
+#include <glib-object.h>
+#include "netperf-netserver.h"
+#include "netperf-test.h"
+#include "netperf-control.h"
+
+#undef NETLIB
+
+#include "netlib.h"
+#include "netmsg.h"
+
+extern int debug;
+extern FILE * where;
+
+extern GHashTable *test_hash;
+extern GHashTable *test_set_hash;
+extern GHashTable *server_hash;
+
+HIST
+HIST_new(void){
+  HIST h;
+  h = (HIST) malloc(sizeof(struct histogram_struct));
+  if (h) {
+    HIST_clear(h);
+  }
+  return h;
+}
+
+void
+HIST_clear(HIST h){
+  int i;
+  for(i = 0; i < 10; i++){
+#ifdef HAVE_GETHRTIME
+    h->hundred_nsec[i] = 0;
+#endif
+    h->unit_usec[i] = 0;
+    h->ten_usec[i] = 0;
+    h->hundred_usec[i] = 0;
+    h->unit_msec[i] = 0;
+    h->ten_msec[i] = 0;
+    h->hundred_msec[i] = 0;
+    h->unit_sec[i] = 0;
+    h->ten_sec[i] = 0;
+  }
+  h->ridiculous = 0;
+  h->total = 0;
+}
+
+#ifdef HAVE_GETHRTIME
+
+void
+HIST_add_nano(register HIST h, hrtime_t *begin, hrtime_t *end)
+{
+  register int64_t val;
+
+  val = (*end) - (*begin);
+  h->total++;
+  val = val/100;
+  if (val <= 9) h->hundred_nsec[val]++;
+  else {
+    val = val/10;
+    if (val <= 9) h->unit_usec[val]++;
+    else {
+      val = val/10;
+      if (val <= 9) h->ten_usec[val]++;
+      else {
+        val = val/10;
+        if (val <= 9) h->hundred_usec[val]++;
+        else {
+          val = val/10;
+          if (val <= 9) h->unit_msec[val]++;
+          else {
+            val = val/10;
+            if (val <= 9) h->ten_msec[val]++;
+            else {
+              val = val/10;
+              if (val <= 9) h->hundred_msec[val]++;
+              else {
+                val = val/10;
+                if (val <= 9) h->unit_sec[val]++;
+                else {
+                  val = val/10;
+                  if (val <= 9) h->ten_sec[val]++;
+                  else h->ridiculous++;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+#endif
+
+
+void
+HIST_add(register HIST h, int time_delta)
+{
+  register int val;
+  h->total++;
+  val = time_delta;
+  if(val <= 9) h->unit_usec[val]++;
+  else {
+    val = val/10;
+    if(val <= 9) h->ten_usec[val]++;
+    else {
+      val = val/10;
+      if(val <= 9) h->hundred_usec[val]++;
+      else {
+        val = val/10;
+        if(val <= 9) h->unit_msec[val]++;
+        else {
+          val = val/10;
+          if(val <= 9) h->ten_msec[val]++;
+          else {
+            val = val/10;
+            if(val <= 9) h->hundred_msec[val]++;
+            else {
+              val = val/10;
+              if(val <= 9) h->unit_sec[val]++;
+              else {
+                val = val/10;
+                if(val <= 9) h->ten_sec[val]++;
+                else h->ridiculous++;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+static xmlAttrPtr
+set_hist_attribute(xmlNodePtr hist, char *name, uint64_t *row)
+{
+  int         i,j;
+  xmlAttrPtr  ap   = NULL;
+  char        values[256];
+  
+  values[0] = 0;
+  for (i = 0, j = 0; i < 10; i++) {
+    j += g_snprintf(&(values[j]), 256-j, ":%5"PRId64, row[i]);
+  }
+  ap = xmlSetProp(hist, (xmlChar *)name, (xmlChar *)values);
+  return(ap);
+}
+
+
+xmlNodePtr
+HIST_stats_node(HIST h, char *name)
+{
+
+  xmlNodePtr  hist;
+  xmlAttrPtr  ap;
+  char        value_str[32];
+  
+
+  if ((hist = xmlNewNode(NULL,(xmlChar *)"hist_stats")) != NULL) {
+    ap = xmlSetProp(hist, (xmlChar *)"hist_name", (xmlChar *)name);
+#ifdef HAVE_GETHRTIME
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "hundred_nsec", h->hundred_nsec);
+    }
+#endif
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "unit_usec", h->unit_usec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "ten_usec", h->ten_usec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "hundred_usec", h->hundred_usec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "unit_msec", h->unit_msec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "ten_msec", h->ten_msec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "hundred_msec", h->hundred_msec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "unit_sec", h->unit_sec);
+    }
+    if (ap != NULL) {
+      ap = set_hist_attribute(hist, "ten_sec", h->ten_sec);
+    }
+    if (ap != NULL) {
+      sprintf(value_str,": %4"PRId64,h->ridiculous);
+      ap = xmlSetProp(hist, (xmlChar *)"plus_100_sec", (xmlChar *)value_str);
+    }
+    if (ap != NULL) {
+      sprintf(value_str,": %4"PRId64,h->total);
+      ap = xmlSetProp(hist, (xmlChar *)"hist_total", (xmlChar *)value_str);
+    }
+    if (ap == NULL) {
+      xmlFreeNode(hist);
+      hist = NULL;
+    }
+  }
+  return(hist);
+}
+
+
+void
+HIST_report(FILE *fd, xmlNodePtr hist)
+{
+   int         i;
+   xmlChar    *string;
+   
+   string = xmlGetProp(hist, (const xmlChar *)"hist_name");
+   fprintf(fd, "\nHISTOGRAM REPORT for %s\n", string);
+   fprintf(fd, "              ");
+   for (i=0; i<10; i++) {
+     fprintf(fd, ":%5d",i);
+   }
+   fprintf(fd, "\n");
+   fprintf(fd, "--------------");
+   for (i=0; i<10; i++) {
+     fprintf(fd, "+-----");
+   }
+   fprintf(fd, "\n");
+   string = xmlGetProp(hist, (const xmlChar *)"hundred_nsec");
+   if (string) {
+     fprintf(fd, "HUNDRED_NSEC  %s\n", string);
+   }
+   string = xmlGetProp(hist, (const xmlChar *)"unit_usec");
+   fprintf(fd, "UNIT_USEC     %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"ten_usec");
+   fprintf(fd, "TEN_USEC      %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"hundred_usec");
+   fprintf(fd, "HUNDRED_USEC  %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"unit_msec");
+   fprintf(fd, "UNIT_MSEC     %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"ten_msec");
+   fprintf(fd, "TEN_MSEC      %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"hundred_msec");
+   fprintf(fd, "HUNDRED_MSEC  %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"unit_sec");
+   fprintf(fd, "UNIT_SEC      %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"ten_sec");
+   fprintf(fd, "TEN_SEC       %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"plus_100_sec");
+   fprintf(fd, "100_PLUS_SEC  %s\n", string);
+   string = xmlGetProp(hist, (const xmlChar *)"hist_total");
+   fprintf(fd, "HIST_TOTAL    %s\n", string);
+   fprintf(fd, "\n");
+   fflush(fd);
+}
+
+
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+
+static void
+kill_all_tests_in_hash(NetperfTest *test_hash)
+{
+
+  /* REVISIT replace this with some g_hash_table_foreach() calls on
+     the test objects in the test_hash */
+#ifdef notdef
+  for (i = 0; i < TEST_HASH_BUCKETS; i ++) {
+    h = &test_hash[i];
+    /* mutex locking is not required because only one 
+       netserver thread looks at these data structures sgb */
+    test = h->test;
+    while (test != NULL) {
+      /* tell each test to die */
+      test->state_req = TEST_DEAD;
+      test = test->next;
+    }
+  }
+  empty_hash_buckets = 0;
+  while(empty_hash_buckets < TEST_HASH_BUCKETS) {
+    empty_hash_buckets = 0;
+    g_usleep(1000000);
+    /* the original code had a check_test_state() call here, but we
+       can ass-u-me that the check_test_state_callback() timeout
+       function is running in the event loop */
+    for (i = 0; i < TEST_HASH_BUCKETS; i++) {
+      if (test_hash[i].test == NULL) {
+        empty_hash_buckets++;
+      }
+    }
+  }
+#endif
+}
+
+
+
+/* given a filename, return the first path to the file that stats
+   successfully - which is either the name already given, or that name
+   with NETPERFDIR prepended. */
+
+int
+netperf_complete_filename(char *name, char *full, int fulllen) {
+  char path[PATH_MAX+1];
+  int  ret;
+
+  struct stat buf;
+
+  if (0 == NETPERF_STAT(name,&buf)) {
+    /* the name resolved where we are - either there is a match in
+       CWD, or they specified a full path name, I wonder if we need to
+       worry about explicit null termination of full? raj 2006-02-27 */
+    strncpy(full,name,fulllen);
+    full[fulllen-1] = '\0';
+    ret = strlen(full);
+  }
+  else {
+    /* very simple, even simplistic - since the stat above didn't
+       work, we presume that the name given wasn't a full one, so we
+       just slap the NETPERFDIR and path separator in front of the
+       name and try again. */
+    NETPERF_SNPRINTF(path,PATH_MAX,"%s%s%s",NETPERFDIR,G_DIR_SEPARATOR_S,name);
+    path[PATH_MAX] = '\0';
+    if (0 == NETPERF_STAT(path,&buf)) {
+      strncpy(full,path,fulllen);
+      full[fulllen-1] = '\0';
+      ret = strlen(full);
+    }
+    else {
+      ret = -1;
+    }
+  }
+  return ret;
+}
+
+#ifdef HAVE_GETHRTIME
+
+void
+netperf_timestamp(hrtime_t *timestamp)
+{
+  *timestamp = gethrtime();
+}
+
+uint64_t
+delta_nano(hrtime_t *begin, hrtime_t *end)
+{
+  int64_t nsecs;
+  nsecs = (*end) - (*begin);
+  return(nsecs);
+}
+
+int
+delta_micro(hrtime_t *begin, hrtime_t *end)
+{
+  int64_t nsecs;
+  nsecs = (*end) - (*begin);
+  return(nsecs/1000);
+}
+
+int
+delta_milli(hrtime_t *begin, hrtime_t *end)
+{
+  int64_t nsecs;
+  nsecs = (*end) - (*begin);
+  return(nsecs/1000000);
+}
+
+
+#elif defined HAVE_GETTIMEOFDAY
+
+void
+netperf_timestamp(struct timeval *timestamp)
+{
+  gettimeofday(timestamp,NULL);
+}
+
+ /* return the difference (in micro seconds) between two timeval */
+ /* timestamps */
+int
+delta_micro(struct timeval *begin,struct timeval *end)
+
+{
+
+  int usecs, secs;
+
+  if (end->tv_usec < begin->tv_usec) {
+    /* borrow a second from the tv_sec */
+    end->tv_usec += 1000000;
+    end->tv_sec--;
+  }
+  usecs = end->tv_usec - begin->tv_usec;
+  secs  = end->tv_sec - begin->tv_sec;
+
+  usecs += (secs * 1000000);
+
+  return(usecs);
+
+}
+ /* return the difference (in milliseconds) between two timeval
+    timestamps */
+int
+delta_milli(struct timeval *begin,struct timeval *end)
+
+{
+
+  int usecs, secs;
+
+  if (end->tv_usec < begin->tv_usec) {
+    /* borrow a second from the tv_sec */
+    end->tv_usec += 1000000;
+    end->tv_sec--;
+  }
+  usecs = end->tv_usec - begin->tv_usec;
+  secs  = end->tv_sec - begin->tv_sec;
+
+  usecs += (secs * 1000000);
+
+  return(usecs/1000);
+
+}
+#else
+
+void
+netperf_timestamp(struct timeval *timestamp)
+{
+  timestamp->tv_sec = 0;
+  timestamp->tv_usec = 0;
+}
+
+ /* return the difference (in micro seconds) between two timeval */
+ /* timestamps */
+int
+delta_micro(struct timeval *begin,struct timeval *end)
+
+{
+
+  return(1000000000);
+
+}
+ /* return the difference (in milliseconds) between two timeval
+    timestamps */
+int
+delta_milli(struct timeval *begin,struct timeval *end)
+
+{
+
+  return(1000000000);
+
+}
+
+#endif /* HAVE_GETHRTIME */
+
+/* This routine will return the two arguments to the calling routine. */
+/* If the second argument is not specified, and there is no comma, */
+/* then the value of the second argument will be the same as the */
+/* value of the first. If there is a comma, then the value of the */
+/* second argument will be the value of the second argument ;-) */
+void
+break_args(char *s, char *arg1, char *arg2)
+
+{
+  char *ns;
+
+  ns = strchr(s,',');
+  if (ns) {
+    /* there was a comma arg2 should be the second arg*/
+    *ns++ = '\0';
+    while ((*arg2++ = *ns++) != '\0');
+  }
+  else {
+    /* there was not a comma, we can use ns as a temp s */
+    /* and arg2 should be the same value as arg1 */
+    ns = s;
+    while ((*arg2++ = *ns++) != '\0');
+  };
+  while ((*arg1++ = *s++) != '\0');
+}
+
+/* break_args_explicit
+
+   this routine is somewhat like break_args in that it will separate a
+   pair of comma-separated values.  however, if there is no comma,
+   this version will not ass-u-me that arg2 should be the same as
+   arg1. raj 2005-02-04 */
+void
+break_args_explicit(char *s, char *arg1, char *arg2)
+
+{
+  char *ns;
+
+  ns = strchr(s,',');
+  if (ns) {
+    /* there was a comma arg2 should be the second arg*/
+    *ns++ = '\0';
+    while ((*arg2++ = *ns++) != '\0');
+  }
+  else {
+    /* there was not a comma, so we should make sure that arg2 is \0
+       lest something become confused. raj 2005-02-04 */
+    *arg2 = '\0';
+  };
+  while ((*arg1++ = *s++) != '\0');
+
+}
+
+/* given a string with possible values for setting an address family,
+   convert that into one of the AF_mumble values - AF_INET, AF_INET6,
+   AF_UNSPEC as apropriate. the family_string is compared in a
+   case-insensitive manner */
+
+int
+parse_address_family(char family_string[])
+{
+
+  char temp[10];  /* gotta love magic constants :) */
+
+
+  strncpy(temp,family_string,10);
+
+  if (debug) {
+    fprintf(where,
+	    "Attempting to parse address family from %s derived from %s\n",
+	    temp,
+	    family_string);
+  }
+#if defined(AF_INET6)
+  if (strstr(temp,"6")) {
+    return(AF_INET6);
+  }
+#endif
+  if (strstr(temp,"inet") ||
+      strstr(temp,"4")) {
+    return(AF_INET);
+  }
+  if (strstr(temp,"unspec") ||
+      strstr(temp,"0")) {
+    return(AF_UNSPEC);
+  }
+  fprintf(where,
+	  "WARNING! %s not recognized as an address family, using AF_UNPSEC\n",
+	  family_string);
+  fprintf(where,
+	  "Are you sure netperf was configured for that address family?\n");
+  fflush(where);
+  return(AF_UNSPEC);
+}
+
+static void  
+test_state_to_string(int value, char *string)
+{
+  char *state; 
+
+  switch (value) {
+  case TEST_PREINIT:
+    state = "PRE ";
+    break;
+  case TEST_INIT:
+    state = "INIT";
+    break;
+  case TEST_IDLE:
+    state = "IDLE";
+    break;
+  case TEST_MEASURE:
+    state = "MEAS";
+    break;
+  case TEST_LOADED:
+    state = "LOAD";
+    break;
+  case TEST_ERROR:
+    state = "ERR ";
+    break;
+  case TEST_DEAD:
+    state = "DEAD";
+    break;
+  default:
+    state = "ILLG";
+    break;
+  }
+  strcpy(string,state);
+}
+
+void
+report_test_status(NetperfTest *test)
+{
+  char        current[8];
+  char        requested[8];
+  char        reported[8];
+
+
+  /* since this is not actual netperf-test object code, we should
+     probably be using property calls to extract the state from the
+     object */
+
+  test_state_to_string(test->state,     reported );
+  test_state_to_string(test->new_state, current  );
+  test_state_to_string(test->state_req, requested);
+
+  fprintf(where,"%4s %4s %15s  %4s %4s %4s\n",
+          test->server_id,test->id,test->test_name,
+          reported, current, requested);
+  fflush(where);
+}
+
+void
+report_servers_test_status(NetperfNetserver *server)
+{
+
+  /* REVISIT this needs to be converted to a g_hash_table_foreach()
+     call which is given the netserver's ID for comparison */
+#ifdef notdef
+  fprintf(where,"\n\n%4s %4s %15s  %4s %4s %4s\n",
+          "srvr","tst","test_name","CURR","TEST","RQST");
+  for (i = 0; i < TEST_HASH_BUCKETS; i ++) {
+    h = &test_hash[i];
+    NETPERF_MUTEX_LOCK(h->hash_lock);
+        test = h->test;
+
+    while (test != NULL) {
+      if (!xmlStrcmp(test->server_id,server->id)) {
+        report_test_status(test);
+      }
+      test = test->next;
+    }
+    NETPERF_MUTEX_UNLOCK(h->hash_lock);
+  }
+#endif
+}
+
+
+/* this should probably become part of the netperf-test.c file as it
+   is doing stuff with the test hash? */
+void
+display_test_hash()
+{
+
+  if (debug) {
+    /* REVISIT needs to convert to a g_hash_table_foreach */
+#ifdef notdef
+    for (i=0;i < TEST_HASH_BUCKETS; i++) {
+      test = test_hash[i].test;
+      fprintf(where,"test_hash[%d]=%p\n",i,test_hash[i].test);
+      while (test) {
+        fprintf(where,"\ttest->id %s, test->state %d\n",
+                test->id,test->state);
+        test = test->next;
+      }
+      fflush(where);
+    }
+#endif
+  }
+}
+
+char *
+npe_to_str(int npe_error) {
+  switch (npe_error) {
+  case NPE_SUCCESS:
+    return("NPE_SUCCESS");
+    break;
+  case  NPE_COMMANDED_TO_EXIT_NETPERF:
+    return("NPE_COMMANDED_TO_EXIT_NETPERF");
+    break;
+  case NPE_TEST_SET_NOT_FOUND:
+    return("NPE_TEST_SET_NOT_FOUND");
+    break;
+  case NPE_BAD_TEST_RANGE:
+    return("NPE_BAD_TEST_RANGE");
+    break;
+  case NPE_BAD_TEST_ID:
+    return(" NPE_BAD_TEST_ID");
+    break;
+  case NPE_SYS_STATS_DROPPED:
+    return("NPE_SYS_STATS_DROPPED");
+    break;
+  case NPE_TEST_STATS_DROPPED:
+    return("NPE_TEST_STATS_DROPPED");
+    break;
+  case NPE_TEST_NOT_FOUND:
+    return("NPE_TEST_NOT_FOUND");
+    break;
+  case NPE_TEST_FOUND_IN_ERROR_STATE:
+    return("NPE_TEST_FOUND_IN_ERROR_STATE");
+    break;
+  case NPE_TEST_INITIALIZED_FAILED:
+    return("NPE_TEST_INITIALIZED_FAILED");
+    break;
+  case NPE_TEST_INIT_FAILED:
+    return("NPE_TEST_INIT_FAILED");
+    break;
+  case NPE_INIT_TEST_XMLCOPYNODE_FAILED:
+    return("NPE_INIT_TEST_XMLCOPYNODE_FAILED");
+    break;
+  case NPE_INIT_TEST_XMLNEWDOC_FAILED:
+    return(" NPE_INIT_TEST_XMLNEWDOC_FAILED");
+    break;
+  case NPE_EMPTY_MSG:
+    return("NPE_EMPTY_MSG");
+    break;
+  case NPE_UNEXPECTED_MSG:
+    return("NPE_UNEXPECTED_MSG");
+    break;
+  case NPE_ALREADY_CONNECTED:
+    return("NPE_ALREADY_CONNECTED");
+    break;
+  case NPE_BAD_VERSION:
+    return("NPE_BAD_VERSION");
+    break;
+  case NPE_XMLCOPYNODE_FAILED:
+    return("NPE_XMLCOPYNODE_FAILED");
+    break;
+  case NPE_PTHREAD_MUTEX_INIT_FAILED:
+    return("NPE_PTHREAD_MUTEX_INIT_FAILED");
+    break;
+  case NPE_PTHREAD_RWLOCK_INIT_FAILED:
+    return("NPE_PTHREAD_RWLOCK_INIT_FAILED");
+    break;
+  case NPE_PTHREAD_COND_WAIT_FAILED:
+    return("NPE_PTHREAD_COND_WAIT_FAILED");
+    break;
+  case NPE_PTHREAD_DETACH_FAILED:
+    return("NPE_PTHREAD_DETACH_FAILED");
+    break;
+  case NPE_PTHREAD_CREATE_FAILED:
+    return("NPE_PTHREAD_CREATE_FAILED");
+    break;
+  case NPE_DEPENDENCY_NOT_PRESENT:
+    return("NPE_DEPENDENCY_NOT_PRESENT");
+    break;
+  case NPE_DEPENDENCY_ERROR:
+    return("NPE_DEPENDENCY_ERROR");
+    break;
+  case NPE_UNKNOWN_FUNCTION_TYPE:
+    return("NPE_UNKNOWN_FUNCTION_TYPE");
+    break;
+  case NPE_FUNC_NAME_TOO_LONG:
+    return("NPE_FUNC_NAME_TOO_LONG");
+    break;
+  case NPE_FUNC_NOT_FOUND:
+    return("NPE_FUNC_NOT_FOUND");
+    break;
+  case NPE_LIBRARY_NOT_LOADED:
+    return("NPE_LIBRARY_NOT_LOADED");
+    break;
+  case NPE_ADD_TO_EVENT_LIST_FAILED:
+    return("NPE_ADD_TO_EVENT_LIST_FAILED");
+    break;
+  case NPE_CONNECT_FAILED:
+    return("NPE_CONNECT_FAILED");
+    break;
+  case NPE_MALLOC_FAILED6:
+    return("NPE_MALLOC_FAILED6");
+    break;
+  case NPE_MALLOC_FAILED5:
+    return("NPE_MALLOC_FAILED5");
+    break;
+  case NPE_MALLOC_FAILED4:
+    return("NPE_MALLOC_FAILED4");
+    break;
+  case NPE_MALLOC_FAILED3:
+    return("NPE_MALLOC_FAILED3");
+    break;
+  case NPE_MALLOC_FAILED2:
+    return("NPE_MALLOC_FAILED2");
+    break;
+  case NPE_MALLOC_FAILED1:
+    return("NPE_MALLOC_FAILED1");
+    break;
+  case NPE_REMOTE_CLOSE:
+    return("NPE_REMOTE_CLOSE");
+    break;
+  case NPE_SEND_VERSION_XMLNEWNODE_FAILED:
+    return("NPE_SEND_VERSION_XMLNEWNODE_FAILED");
+    break;
+  case NPE_SEND_VERSION_XMLSETPROP_FAILED:
+    return("NPE_SEND_VERSION_XMLSETPROP_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_XMLDOCDUMPMEMORY_FAILED:
+    return("NPE_SEND_CTL_MSG_XMLDOCDUMPMEMORY_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_XMLCOPYNODE_FAILED:
+    return("NPE_SEND_CTL_MSG_XMLCOPYNODE_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_XMLNEWNODE_FAILED:
+    return("NPE_SEND_CTL_MSG_XMLNEWNODE_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_XMLNEWDTD_FAILED:
+    return("NPE_SEND_CTL_MSG_XMLNEWDTD_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_XMLNEWDOC_FAILED:
+    return("NPE_SEND_CTL_MSG_XMLNEWDOC_FAILED");
+    break;
+  case NPE_SEND_CTL_MSG_FAILURE:
+    return("NPE_SEND_CTL_MSG_FAILURE");
+    break;
+  case NPE_SHASH_ADD_FAILED:
+    return("NPE_SHASH_ADD_FAILED");
+    break;
+  case NPE_XMLPARSEMEMORY_ERROR:
+    return("NPE_XMLPARSEMEMORY_ERROR");
+    break;
+  case NPE_NEG_MSG_BYTES:
+    return("NPE_NEG_MSG_BYTES");
+    break;
+  case NPE_TIMEOUT:
+    return("NPE_TIMEOUT");
+    break;
+  case NPE_SET_THREAD_LOCALITY_FAILED:
+    return("NPE_SET_THREAD_LOCALITY_FAILED");
+    break;
+  default:
+    return("Unmapped Error");
+  }
+}
+
+int
+add_test_to_hash(NetperfTest *new_test)
+{
+
+  /* REVISIT this needs to be converted to a g_hash_table_replace() call */
+#ifdef notdef
+  hash_value = TEST_HASH_VALUE(new_test->id);
+
+  /* don't forget to add error checking one day */
+  NETPERF_MUTEX_LOCK(test_hash[hash_value].hash_lock);
+
+  new_test->next = test_hash[hash_value].test;
+  test_hash[hash_value].test = new_test;
+
+  NETPERF_MUTEX_UNLOCK(test_hash[hash_value].hash_lock);
+#endif
+  return(NPE_SUCCESS);
+}
+
+void
+delete_test(const xmlChar *id)
+{
+  /* the removal of the test from any existing test set is done elsewhere */
+
+  /* we presume that the id is of the form [a-zA-Z][0-9]+ and so will
+     call atoi on id and mod that with the TEST_HASH_BUCKETS */
+
+  /* REVISIT this needs to become a g_hash_table_remove() call */
+#ifdef notdef
+  hash_value = TEST_HASH_VALUE(id);
+
+  /* don't forget to add error checking one day */
+  NETPERF_MUTEX_LOCK(test_hash[hash_value].hash_lock);
+
+  prev_test    = &(test_hash[hash_value].test);
+  test_pointer = test_hash[hash_value].test;
+  while (test_pointer != NULL) {
+    if (!xmlStrcmp(test_pointer->id,id)) {
+      /* we have a match */
+      *prev_test = test_pointer->next;
+      free(test_pointer);
+      break;
+    }
+    prev_test    = &(test_pointer->next);
+    test_pointer = test_pointer->next;
+  }
+
+  NETPERF_MUTEX_UNLOCK(test_hash[hash_value].hash_lock);
+#endif
+}
+
+test_t *
+find_test_in_hash(const xmlChar *id)
+{
+  /* we presume that the id is of the form [a-zA-Z][0-9]+ and so will
+     call atoi on id and mod that with the TEST_HASH_BUCKETS */
+
+  /* REVISIT this needs to become a g_hash_table_lookup() call */
+#ifdef notdef
+
+  hash_value = TEST_HASH_VALUE(id);
+
+  /* don't forget to add error checking one day */
+  NETPERF_MUTEX_LOCK(test_hash[hash_value].hash_lock);
+
+  test_pointer = test_hash[hash_value].test;
+  while (test_pointer != NULL) {
+    if (!xmlStrcmp(test_pointer->id,id)) {
+      /* we have a match */
+      break;
+    }
+    test_pointer = test_pointer->next;
+  }
+
+  NETPERF_MUTEX_UNLOCK(test_hash[hash_value].hash_lock);
+  return(test_pointer);
+#endif
+  return(NULL);
+}
+
+
+void
+dump_addrinfo(FILE *dumploc, struct addrinfo *info,
+              xmlChar *host, xmlChar *port, int family)
+{
+  struct sockaddr *ai_addr;
+  struct addrinfo *temp;
+  temp=info;
+
+  g_fprintf(dumploc,
+	  "getaddrinfo returned the following for host '%s' ",
+	  host ? (char *)host : "n/a");
+  g_fprintf(dumploc,
+	  "port '%s' ",
+	  port ? (char *)port : "n/a");
+  fprintf(dumploc, "family %d\n", family);
+  while (temp) {
+    /* I was under the impression that g_fprintf would be kind with
+    things like NULL string pointers, but when porting to Solaris,
+    this started dumping core, so we start to workaround it. raj
+    2006-06-29 */
+    g_fprintf(dumploc,
+	      "\tcannonical name: '%s'\n",
+	      temp->ai_canonname ? temp->ai_canonname : "n/a");
+    g_fprintf(dumploc,
+	      "\tflags: %x family: %d: socktype: %d protocol %d addrlen %d\n",
+	      temp->ai_flags,
+	      temp->ai_family,
+	      temp->ai_socktype,
+	      temp->ai_protocol,
+	      temp->ai_addrlen);
+    ai_addr = temp->ai_addr;
+    if (ai_addr != NULL) {
+      g_fprintf(dumploc,
+		"\tsa_family: %d sadata: %d %d %d %d %d %d\n",
+		ai_addr->sa_family,
+		(u_char)ai_addr->sa_data[0],
+		(u_char)ai_addr->sa_data[1],
+		(u_char)ai_addr->sa_data[2],
+		(u_char)ai_addr->sa_data[3],
+		(u_char)ai_addr->sa_data[4],
+		(u_char)ai_addr->sa_data[5]);
+    }
+    temp = temp->ai_next;
+  }
+  fflush(dumploc);
+}
+
+/* for libtool, we have an extra level of indirection to "normalize"
+   the names of shared libraries, which means we have to open that
+   file and look for the line with the "real" platform-specific shared
+   library name.  that or use the liblt stuff, which does not appear
+   to be thread-safe, or the documentation is very out of date. raj
+   2005-10-10
+
+   for those who are making their own test libraries, we do not want
+   to dictate they use libtool, so if the "la" file actually ends in
+   something other than ".la" we will ass-u-me that it is an actual
+   library file and pass that back unscathed.  at some point this will
+   also be the place where we follow LD_LIBRARY_PATH and the like so
+   one does not have to fully-qualify the names. raj 2005-10-25
+
+   this is not the prettiest code ever produced.  it could and
+   probably should be a lot cleaner, but messing with pointers and
+   strings has never been a great deal of fun.
+
+   we probably need to check if "la" is already a fully qualified path
+   name and simply pass it back if it is...  */
+
+void
+map_la_to_lib(xmlChar *la, char *lib) {
+
+  FILE *la_file;
+  int ret;
+  char *last_paren;
+  char s1[132];
+  char name[NETPERF_MAX_TEST_LIBRARY_NAME];
+  char *s2=name;
+  char *dlname=NULL;
+  char *libdir=NULL;
+  int file_len;
+  char *temp;
+  char *ld_library_path = NULL;
+  char full_path[PATH_MAX];
+  struct stat buf;
+
+
+  /* if we have no environment variables, this will not be
+     overwritten */
+  strncpy(full_path,(char *)la,PATH_MAX);
+
+  /* for now, we will first look for NETPERF_LIBRARY_PATH, then
+     LD_LIBRARY_PATH, then SHLIB_PATH. raj 2005-10-25 */
+  temp = getenv("NETPERF_LIBRARY_PATH");
+  if (NULL == temp) {
+    temp = getenv("LD_LIBRARY_PATH");
+    if (NULL == temp) {
+      /* OK, there was no LD_LIBRARY_PATH, was there a SHLIB_PATH? I
+	 wonder which if these should have precedence? */
+      temp = getenv("SHLIB_PATH");
+      if (NULL == temp) {
+	/* OK, there were no paths at all, lets do our own internal
+	   path, which one day really aught to be based on $(libdir)
+	   from the make environment. raj 2006-02-22 */
+	temp = ".:"LIBDIR;
+      }
+    }
+  }
+
+  if (NULL != temp) {
+    ld_library_path = malloc(strlen(temp)+1);
+  }
+
+  if (NULL != ld_library_path) {
+    gchar **tokens;
+    int tok;
+    /* OK, start trapsing down the path until we find a match */
+    strcpy(ld_library_path,temp);
+    tokens = g_strsplit(ld_library_path,":",15);
+    for (tok = 0; tokens[tok] != NULL; tok++) {
+      g_snprintf(full_path,PATH_MAX,"%s%s%s",tokens[tok],G_DIR_SEPARATOR_S,la);
+      if (g_stat(full_path,&buf) == 0) {
+	/* we have a winner, time to go */
+	break;
+      }
+      else {
+	/* put-back the original la file */
+	strncpy(full_path,(char *)la,PATH_MAX);
+      }
+    }
+    g_strfreev(tokens);
+  }
+
+  /* so, after all that, is it really a ".la" file or is it some other
+     file. I wonder if we should ask that first and then ass-u-me that
+     the dlopen will do the right thing instead of doing all the stuff
+     with the environment variables - only looking at them if it is an
+     "la" file?  raj 2005-10-26 */
+  file_len = strlen(full_path);
+  if ((full_path[file_len-1] != 'a') ||
+      (full_path[file_len-2] != 'l') ||
+      (full_path[file_len-3] != '.')) {
+    /* we will ass-u-me it is an actual library file name */
+    strcpy(lib,full_path);
+  }
+  else {
+    la_file = fopen(full_path,"r");
+    if (la_file != NULL) {
+      /* time to start trapsing through the file */
+      while ((ret = fscanf(la_file,
+			   "%s",
+			   s1)) != EOF) {
+	if (ret == 1) {
+	  /* algorithm depends on only one dlname and one libdir line in file */
+	  ret = sscanf(s1,"dlname='%s",s2);
+	  if (ret == 1) { 
+	    /* we got our match. because %s matches until the next white space
+	       the trailing single quote is in the string, which means we need
+	       to nuke it */
+	    last_paren = strchr(s2,'\'');
+	    if (last_paren != NULL) {
+	      *last_paren = '\0';
+	    }
+	    dlname = s2;
+	    s2 = s2 + 1 + strlen(dlname);
+	    if ((dlname != NULL) && (libdir != NULL)) {
+	      break;
+	    }
+	  } else {
+	    ret = sscanf(s1,"libdir='%s",s2);
+	    if (ret == 1) {
+	      /* we got our match. because %s matches until the next white space
+		 the trailing single quote is in the string, which means we need
+		 to nuke it */
+	      last_paren = strchr(s2,'\'');
+	      if (last_paren != NULL) {
+		*last_paren = '\0';
+	      }
+	      libdir = s2;
+	      s2 = s2 + 1 + strlen(libdir);
+	      if ((dlname != NULL) && (libdir != NULL)) {
+		break;
+	      }
+	    }
+	  }
+	}
+	/* "digest" the rest of the line, adapted from some stuff
+	   found in a web search */
+	fscanf(la_file,"%*[^\n]");   /* Skip to the End of the Line */
+	fscanf(la_file,"%*1[\n]");   /* Skip One Newline */
+	strcpy(lib,"dlnamefound");
+      }
+      strcpy(lib,libdir);
+      strcat(lib,G_DIR_SEPARATOR_S);
+      strcat(lib,dlname);
+    }
+    else {
+      strcpy(lib,"libfilenotfound");
+    }
+  }
+  if (debug) {
+    fprintf(where,"map_la_to_lib returning '%s' from '%s'\n",lib,(char *)la);
+  }
+  if (ld_library_path) free(ld_library_path);
+}
+
+/* attempt to open a library file by prepending path components to
+   it */
+GModule *
+open_library_path(const gchar *library_name, const gchar *pathvar, gboolean pathvarispath) {
+
+  const gchar *path;
+  gchar **path_elts;
+  int   index;
+  gchar *filename;
+  GModule *handle = NULL;
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s is going to use %s as the envvar\n",
+	      __func__,
+	      pathvar);
+    fflush(where);
+  }
+  if (pathvarispath) {
+    /* the pathvar variable is already a path and not an environment
+       variable */
+    path = pathvar;
+  }
+  else {
+    path = g_getenv(pathvar);
+  }
+
+  if (debug) {
+    /* I _thought_ that g_fprintf was cool with NULL string pointers
+       until we got to the Solaris port at which point this started
+       dumping core like there was no tomorrow.  rather than await a
+       fix to g_fprintf that may never come, we'll work around it. raj
+       2006-06-29 */
+    g_fprintf(where,
+	      "%s was given %s for envvar %s and pathvarispath %d\n",
+	      __func__,
+	      path ? path : "NULL",
+	      pathvar,
+	      pathvarispath);
+    fflush(where);
+  }
+
+  if (path) {
+    path_elts = g_strsplit(path,G_SEARCHPATH_SEPARATOR_S,0);
+    for (index = 0; ((path_elts[index] != NULL) 
+		     && (NULL == handle)); index++) {
+      if (debug) {
+	g_fprintf(where,
+		  "%s is trying path element %s with %s\n",
+		  __func__,
+		  path_elts[index],
+		  library_name);
+	fflush(where);
+      }
+      filename = g_build_filename(path_elts[index], library_name,NULL);
+      handle = g_module_open(filename,0);
+    }
+  g_strfreev(path_elts);
+  }
+
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s is returning handle %p\n",
+	      __func__,
+	      handle);
+    fflush(where);
+  }
+  return(handle);
+}
+
+/* attempt to open a library file, first "straight-up" and if that
+   fails, prepending various path components to it. */
+GModule *
+open_library(const gchar *library_name) {
+
+  GModule *handle;
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s was asked to open a library based on the name %s\n",
+	      __func__,
+	      library_name);
+    fflush(where);
+  }
+  handle = g_module_open(library_name,0);
+
+  /* so, if that didn't work, and the library_name was not an absolute
+     path, we will try to prepend some path components */
+
+  if ((NULL == handle) && 
+      !g_path_is_absolute(library_name)) {
+    handle = open_library_path(library_name,"NETPERF_LIBRARY_PATH", FALSE);
+    if (NULL == handle)
+      handle = open_library_path(library_name,"LD_LIBRARY_PATH", FALSE);
+    if (NULL == handle)
+      handle = open_library_path(library_name,"SHLIB_PATH", FALSE);
+    if (NULL == handle)
+      handle = open_library_path(library_name,"Path", FALSE);
+    if (NULL == handle)
+      handle = open_library_path(library_name,
+				 "." G_SEARCHPATH_SEPARATOR_S LIBDIR,
+				 TRUE);
+  }
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s's attempted open of library file '%s' returning %p",
+	      __func__,
+	      library_name,
+	      handle);
+    if (handle == NULL) {
+      g_fprintf(where,
+		" in failure g_module_open error '%s'\n",
+		g_module_error());
+    }
+    else {
+      g_fprintf(where,
+		" in success\n");
+    }
+  }
+  return(handle);
+}
+
+GenReport
+get_report_function(xmlNodePtr cmd)
+{
+  xmlChar  *la_file;
+  xmlChar  *fname;
+  GenReport func;
+
+  gboolean ret;
+  GModule  *lib_handle;
+
+
+  /* first we do the xml stuff */
+  la_file   = xmlGetProp(cmd, (const xmlChar *)"library");
+  fname = xmlGetProp(cmd, (const xmlChar *)"function");
+
+  /* now we do the dlopen/gmodule magic */
+
+  lib_handle = open_library(la_file);
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s's open of library file via '%s' returned %p\n",
+	      __func__,
+	      (char *)la_file,
+	      lib_handle);
+  }
+
+  /* we are all done with the la_file variable so free it */
+  free(la_file);
+
+  ret  = g_module_symbol(lib_handle,fname,(gpointer *)&func);
+  if (debug) {
+    fprintf(where,"symbol lookup of function '%s' returned %p\n",
+            fname, func);
+    if (func == NULL) {
+      fprintf(where,"g_module_symbol error '%s'\n",g_module_error());
+    }
+    fflush(where);
+  }
+
+  return(func);
+}
+
+/* should this be part of netperf-test.c? */
+int
+get_test_function(NetperfTest *test, const xmlChar *func)
+{
+  int tmp = debug;
+  GModule *lib_handle = test->library_handle;
+  gboolean ret;
+  xmlChar *fname;
+  void    *fptr = NULL;
+  int      fnlen = 0;
+  int      rc = NPE_FUNC_NAME_TOO_LONG;
+  char     func_name[NETPERF_MAX_TEST_FUNCTION_NAME];
+  xmlChar *la_file;
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s enter test %p func %s\n",
+	      __func__,
+	      test,
+	      func);
+    fflush(where);
+  }
+
+  if (lib_handle == NULL) {
+    /* load the library for the test */
+    la_file   = xmlGetProp(test->node,(const xmlChar *)"library");
+    if (debug) {
+      g_fprintf(where,
+		"%s looking to open library %p\n",
+		__func__,
+		la_file);
+      fflush(where);
+    }
+
+    lib_handle = open_library(la_file);
+    free(la_file);
+    test->library_handle = lib_handle;
+  }
+
+  fname = xmlGetProp(test->node,func);
+  if (!fname) {
+    fnlen = 0;
+  }
+  else {
+    fnlen = strlen((char *)fname);
+  }
+  if (debug) {
+    if (fname) {
+      fprintf(where,"func = '%s'  fname = '%s' fname[0] = %c fnlen = %d\n",
+	      (char *)func, fname, fname[0], fnlen);
+    }
+    else {
+      fprintf(where,"func = '%s'  fname = '' fname[0] = '' fnlen = %d\n",
+	      (char *)func, fnlen);
+    }
+    fflush(where);
+  }
+
+  if (fnlen < NETPERF_MAX_TEST_FUNCTION_NAME) {
+    if (fnlen) {
+      strcpy(func_name,(char *)fname);
+      rc = NPE_SUCCESS;
+    } else {
+      xmlChar *tname      = test->test_name;
+      int      tnlen = strlen((char *)tname);
+
+      strcpy(func_name,(char *)tname);
+      if (debug) {
+        fprintf(where,"func_name = '%s' tnlen = %d\n",
+                (char *)func_name, tnlen);
+        fflush(where);
+      }
+
+      if (!xmlStrcmp(func,(const xmlChar *)"test_clear")) {
+        if (strlen("_clear_stats") < (size_t)(NETPERF_MAX_TEST_FUNCTION_NAME-tnlen)) {
+          strcat(func_name,"_clear_stats");
+          rc = NPE_SUCCESS;
+        } else {
+          rc = NPE_FUNC_NAME_TOO_LONG;
+        }
+      } else if (!xmlStrcmp(func,(const xmlChar *)"test_stats")) {
+        if (strlen("_get_stats") < (size_t)(NETPERF_MAX_TEST_FUNCTION_NAME-tnlen)) {
+          strcat(func_name,"_get_stats");
+          rc = NPE_SUCCESS;
+        } else {
+          rc = NPE_FUNC_NAME_TOO_LONG;
+        }
+      } else if (!xmlStrcmp(func,(const xmlChar *)"test_decode")) {
+        if (strlen("_decode_stats") < (size_t)(NETPERF_MAX_TEST_FUNCTION_NAME-tnlen)) {
+          strcat(func_name,"_decode_stats");
+          rc = NPE_SUCCESS;
+        } else {
+          rc = NPE_FUNC_NAME_TOO_LONG;
+        }
+      } else {
+        rc = NPE_UNKNOWN_FUNCTION_TYPE;
+      }
+    }
+    if (debug) {
+      fprintf(where,"func_name = '%s'\n", (char *)func_name);
+      fflush(where);
+    }
+    if (rc == NPE_SUCCESS) {
+      ret = g_module_symbol(lib_handle,func_name,&fptr);
+      if (debug) {
+        fprintf(where,"symbol lookup of func_name '%s' returned %p\n",
+                func_name, fptr);
+        if (fptr == NULL) {
+	  fprintf(where,"g_module_symbol error '%s'\n",g_module_error());
+        }
+        fflush(where);
+      }
+      if (fptr == NULL) {
+        if (lib_handle) {
+          rc = NPE_FUNC_NOT_FOUND;
+        } else {
+          rc = NPE_LIBRARY_NOT_LOADED;
+        }
+      }
+    }
+  } else {
+    rc = NPE_FUNC_NAME_TOO_LONG;
+  }
+
+  if (!xmlStrcmp(func,(const xmlChar *)"test_name")) {
+    test->test_name    = fname;
+    test->test_func    = (NetperfTestFunc)fptr;
+  } else if (!xmlStrcmp(func,(const xmlChar *)"test_clear")) {
+    test->test_clear   = (NetperfTestClear)fptr;
+    xmlFree(fname);
+  } else if (!xmlStrcmp(func,(const xmlChar *)"test_stats")) {
+    test->test_stats   = (NetperfTestStats)fptr;
+    xmlFree(fname);
+  } else if (!xmlStrcmp(func,(const xmlChar *)"test_decode")) {
+    test->test_decode  = (NetperfTestDecode)fptr;
+    xmlFree(fname);
+  } else {
+    rc = NPE_UNKNOWN_FUNCTION_TYPE;
+    xmlFree(fname);
+  }
+
+  if (rc != NPE_SUCCESS) {
+    if (debug) {
+      fprintf(where,
+              "get_test_function: error %d occured getting function %s\n",
+              rc,func_name);
+      fflush(where);
+    }
+  }
+  debug = tmp;
+  return(rc);
+}
+
+/* this routine exists because there is no architected way to get a
+   "native" thread id out of a GThread.  we need a native thread ID to
+   allow the main netserver thread to bind a test thread to a
+   specified CPU/processor set/locality domain. so, we use the
+   launch_pad routine to allow the newly created thread to store a
+   "pthread_self" into the test structure. the netserver thread, when
+   it see's the test thread is in the idle state can then assign the
+   affinity to the thread. raj 2006-03-30 */
+
+void *
+launch_pad(void *data) {
+  thread_launch_state_t *launch_state;
+  test_t *test;
+
+  NETPERF_DEBUG_ENTRY(debug,where);
+
+  launch_state = data;
+  test = launch_state->data_arg;
+
+#ifdef G_THREADS_IMPL_POSIX
+  /* hmm, I wonder if I have to worry about alignment */
+#ifdef _AIX
+  /* bless its heart, AIX wants its CPU binding routine to be given a
+     kernel thread ID and not a pthread id.  isn't that special. */
+  test->native_thread_id_ptr = malloc(sizeof(tid_t));
+  if (test->native_thread_id_ptr) {
+    *(tid_t *)(test->native_thread_id_ptr) = thread_self();
+  }
+  if (debug) {
+    fprintf(where,"%s my thread id is %d\n",__func__,thread_self());
+    fflush(where);
+  }
+#elif defined(__sun)
+#include <sys/lwp.h>
+  /* well, bless _its_ heart, Solaris wants something other than a
+     pthread_id for its binding calls too.  isn't that special... raj
+     2006-06-28 */
+  test->native_thread_id_ptr = malloc(sizeof(lwpid_t));
+  if (test->native_thread_id_ptr) {
+    *(lwpid_t *)(test->native_thread_id_ptr) = _lwp_self();
+  }
+  if (debug) {
+    fprintf(where,"%s my thread id is %d\n",__func__,_lwp_self());
+    fflush(where);
+  }
+#else
+  test->native_thread_id_ptr = malloc(sizeof(pthread_t));
+  if (test->native_thread_id_ptr) {
+    *(pthread_t *)(test->native_thread_id_ptr) = pthread_self();
+  }
+  if (debug) {
+    fprintf(where,"%s my thread id is %ld\n",__func__,pthread_self());
+    fflush(where);
+  }
+#endif
+#else
+#ifdef __sun
+#include <sys/lwp.h>
+  /* well, bless _its_ heart, Solaris wants something other than a
+     pthread_id for its binding calls too.  isn't that special...  No,
+     your eyes are not deceiving you - this code is appearing in two
+     places because it would seem that glib-2.0 on Solaris may be
+     compiled using Sun's old threads stuff rather than pthreads. raj
+     2006-06-28 */
+  test->native_thread_id_ptr = malloc(sizeof(lwpid_t));
+  if (test->native_thread_id_ptr) {
+    *(lwpid_t *)(test->native_thread_id_ptr) = _lwp_self();
+  }
+  if (debug) {
+    fprintf(where,"%s my thread id is %d\n",__func__,_lwp_self());
+    fflush(where);
+  }
+#else
+  test->native_thread_id_ptr = NULL;
+#endif
+#endif
+  /* and now, call the routine we really want to run. at some point we
+     should bring those values onto the stack so we can free the
+     thread_launch_state_t I suppose. */
+  return (launch_state->start_routine)(launch_state->data_arg);
+}
+
+/* I would have used the NETPERF_THREAD_T abstraction, but that would
+   make netlib.h dependent on netperf.h and I'm not sure I want to do
+   that. raj 2006-03-02 */
+int
+launch_thread(GThread **tid, void *(*start_routine)(void *), void *data)
+
+{
+  int rc;
+
+  NETPERF_THREAD_T temp_tid;
+
+  temp_tid = g_thread_create_full(start_routine,   /* what to run */	
+                                  data, /* what it should use */
+                                  0,    /* default stack size */
+                                  FALSE, /* not joinable */
+                                  TRUE,  /* bound - make it system scope */
+                                  G_THREAD_PRIORITY_NORMAL,
+                                  NULL);
+
+  if (NULL != temp_tid) {
+    rc = 0;
+    *tid = temp_tid;
+  }
+  else {
+    rc = -1;
+  }
+  return(rc);
+}
+
+
+
+int
+strtofam(xmlChar *familystr)
+{
+
+  if (debug) {
+    fprintf(where, "strtofam called with %s\n", familystr);
+    fflush(where);
+  }
+
+  if (!xmlStrcmp(familystr,(const xmlChar *)"AF_INET")) {
+    return(AF_INET);
+  } else if (!xmlStrcmp(familystr,(const xmlChar *)"AF_UNSPEC")) {
+    return(AF_UNSPEC);
+#ifdef AF_INET6
+  } else if (!xmlStrcmp(familystr,(const xmlChar *)"AF_INET6")) {
+    return(AF_INET6);
+#endif /* AF_INET6 */
+  } else {
+    /* we should never get here if the validator is doing its thing */
+    fprintf(where, "strtofam: unknown address family %s\n",familystr);
+    fflush(where);
+    return(-1);
+  }
+}
+
+
+/*
+  establish_listen()
+
+Set-up a listen socket for netserver or a test thread so netperf or dependent
+test thread can connect or communicate with it.
+
+*/
+
+SOCKET
+establish_listen(char *hostname, char *service, int af, netperf_socklen_t *addrlenp)
+{
+  SOCKET sockfd;
+  int error;
+  int count;
+  int len = *addrlenp;
+  int one = 1;
+  struct addrinfo hints, *res, *res_temp;
+
+  if (debug) {
+    fprintf(where,
+	    "establish_listen: host '%s' service '%s' af %d socklen %d\n",
+	    hostname ? hostname : "n/a",
+	    service ? service : "n/a",
+	    af,
+	    len);
+    fflush(where);
+  }
+
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family   = af;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags    = AI_PASSIVE;
+
+  count = 0;
+  do {
+    error = getaddrinfo(hostname,
+			service,
+			&hints,
+			&res);
+    count += 1;
+    if (error == EAI_AGAIN) {
+      if (debug) {
+        fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
+        fflush(where);
+      }
+      g_usleep(1000);
+    }
+  } while ((error == EAI_AGAIN) && (count <= 5));
+
+  if (error) {
+    fprintf(where,
+            "establish_listen: could not resolve host '%s' service '%s'\n",
+            hostname,service);
+    fprintf(where,"\tgetaddrinfo returned %d %s\n",
+            error,gai_strerror(error));
+    fflush(where);
+    return(-1);
+  }
+
+
+  if (debug) {
+    dump_addrinfo(where, res, (xmlChar *)hostname,
+                  (xmlChar *)service, AF_UNSPEC);
+  }
+
+  res_temp = res;
+
+  do {
+
+    sockfd = socket(res_temp->ai_family,
+                    res_temp->ai_socktype,
+                    res_temp->ai_protocol);
+    if (sockfd == INVALID_SOCKET) {
+      if (debug) {
+        fprintf(where,"establish_listen: socket error trying next one\n");
+        fflush(where);
+      }
+      continue;
+    }
+    /* The Windows DDK compiler is quite picky about pointers so we
+       cast one as a void to placate it. */
+    if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(void *)&one,sizeof(one)) == 
+	SOCKET_ERROR) {
+      fprintf(where,"establish_listen: SO_REUSEADDR failed\n");
+      fflush(where);
+    }
+    if (bind(sockfd, res_temp->ai_addr, res_temp->ai_addrlen) == 0) {
+      break;
+    }
+    fprintf(where,"establish_listen: bind error close and try next\n");
+    fflush(where);
+    CLOSE_SOCKET(sockfd);
+  } while ( (res_temp = res_temp->ai_next) != NULL );
+
+  if (res_temp == NULL) {
+    fprintf(where,"establish_listen: allocate server socket failed\n");
+    fflush(where);
+    sockfd = -1;
+  } else if (listen (sockfd,20) == -1) {
+    fprintf(where,"establish_listen: setting the listen backlog failed\n");
+    fflush(where);
+    CLOSE_SOCKET(sockfd);
+    sockfd = -1;
+  } else {
+    if (addrlenp) *addrlenp = res_temp->ai_addrlen;
+  }
+
+  freeaddrinfo(res);
+
+  return (sockfd);
+
+}
+
+
+
+/*
+  establish_control()
+
+set-up the control connection between netperf and the netserver so we
+can actually run some tests. if we cannot establish the control
+connection, that may or may not be a good thing, so we will let the
+caller decide what to do.
+
+to assist with pesky end-to-end-unfriendly things like firewalls, we
+allow the caller to specify both the remote hostname and port, and the
+local addressing info.  i believe that in theory it is possible to
+have an IPv4 endpoint and an IPv6 endpoint communicate with one
+another, but for the time being, we are only going to take-in one
+requested address family parameter. this means that the only way
+(iirc) that we might get a mixed-mode connection would be if the
+address family is specified as AF_UNSPEC, and getaddrinfo() returns
+different families for the local and server names.
+
+the "names" can also be IP addresses in ASCII string form.
+
+raj 2003-02-27 */
+
+SOCKET
+establish_control(xmlChar *hostname,
+                  xmlChar *port,
+                  int      remfam,
+                  xmlChar *localhost,
+                  xmlChar *localport,
+                  int      locfam)
+{
+  int not_connected;
+  SOCKET control_sock;
+  int count;
+  int error;
+
+  struct addrinfo   hints;
+  struct addrinfo  *local_res;
+  struct addrinfo  *remote_res;
+  struct addrinfo  *local_res_temp;
+  struct addrinfo  *remote_res_temp;
+
+  if (debug) {
+    fprintf(where,
+            "establish_control called with host '%s' port '%s' remfam %d\n",
+            hostname,
+            port,
+            remfam);
+    fprintf(where,
+            "\t\tlocal '%s' port '%s' locfam %d\n",
+            localhost,
+            localport,
+            locfam);
+    fflush(where);
+  }
+
+  /* first, we do the remote */
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = remfam;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_protocol = IPPROTO_TCP;
+  hints.ai_flags = 0;
+  count = 0;
+  do {
+    error = getaddrinfo((char *)hostname,
+                        (char *)port,
+                        &hints,
+                        &remote_res);
+    count += 1;
+    if (error == EAI_AGAIN) {
+      if (debug) {
+        fprintf(where,"Sleeping on getaddrinfo EAI_AGAIN\n");
+        fflush(where);
+      }
+      g_usleep(1000);
+    }
+  } while ((error == EAI_AGAIN) && (count <= 5));
+
+  if (error) {
+    printf("establish control: could not resolve remote '%s' port '%s' af %d",
+           hostname,
+           port,
+           remfam);
+    printf("\n\tgetaddrinfo returned %d %s\n",
+           error,
+           gai_strerror(error));
+    return(-1);
+  }
+
+  if (debug) {
+    dump_addrinfo(where, remote_res, hostname, port, remfam);
+  }
+
+  /* now we do the local */
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = locfam;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_protocol = IPPROTO_TCP;
+  hints.ai_flags = AI_PASSIVE;
+  count = 0;
+  do {
+    count += 1;
+    error = getaddrinfo((char *)localhost,
+                           (char *)localport,
+                           &hints,
+                           &local_res);
+    if (error == EAI_AGAIN) {
+      if (debug) {
+        fprintf(where,
+                "Sleeping on getaddrinfo(%s,%s) EAI_AGAIN count %d \n",
+                localhost,
+                localport,
+                count);
+        fflush(where);
+      }
+      g_usleep(1000);
+    }
+  } while ((error == EAI_AGAIN) && (count <= 5));
+
+  if (error) {
+    printf("establish control: could not resolve local '%s' port '%s' af %d",
+           localhost,
+           localport,
+           locfam);
+    printf("\n\tgetaddrinfo returned %d %s\n",
+           error,
+           gai_strerror(error));
+    return(-1);
+  }
+
+  if (debug) {
+    dump_addrinfo(where, local_res, localhost, localport, locfam);
+  }
+
+  not_connected = 1;
+  local_res_temp = local_res;
+  remote_res_temp = remote_res;
+  /* we want to loop through all the possibilities. looping on the
+     local addresses will be handled within the while loop.  I suppose
+     these is some more "C-expert" way to code this, but it has not
+     lept to mind just yet :)  raj 2003-02024 */
+
+  while (remote_res_temp != NULL) {
+
+    /* I am guessing that we should use the address family of the
+       local endpoint, and we will not worry about mixed family types
+       - presumeably the stack or other transition mechanisms will be
+       able to deal with that for us. famous last words :)  raj 2003-02-26 */
+    control_sock = socket(local_res_temp->ai_family,
+                          SOCK_STREAM,
+                          0);
+    if (control_sock == INVALID_SOCKET) {
+      /* at some point we'll need a more generic "display error"
+         message for when/if we use GUIs and the like. unlike a bind
+         or connect failure, failure to allocate a socket is
+         "immediately fatal" and so we return to the caller. raj 2003-02-24 */
+      if (debug) {
+        perror("establish_control: unable to allocate control socket");
+      }
+      return(-1);
+    }
+
+    if (connect(control_sock,
+                remote_res_temp->ai_addr,
+                remote_res_temp->ai_addrlen) == 0) {
+      /* we have successfully connected to the remote netserver */
+      if (debug) {
+        fprintf(where,
+		"successful connection to remote netserver at %s and %s\n",
+		hostname,
+		port);
+	fflush(where);
+      }
+      not_connected = 0;
+      /* this should get us out of the while loop */
+      break;
+    } else {
+      /* the connect call failed */
+      if (debug) {
+        fprintf(where, "establish_control: connect failed, errno %d\n",errno);
+        fprintf(where, "    trying next address combination\n");
+        fflush(where);
+      }
+    }
+
+    if ((local_res_temp = local_res_temp->ai_next) == NULL) {
+      /* wrap the local and move to the next server, don't forget to
+         close the current control socket. raj 2003-02-24 */
+      local_res_temp = local_res;
+      /* the outer while conditions will deal with the case when we
+         get to the end of all the possible remote addresses. */
+      remote_res_temp = remote_res_temp->ai_next;
+      /* it is simplest here to just close the control sock. since
+         this is not a performance critical section of code, we
+         don't worry about overheads for socket allocation or
+         close. raj 2003-02-24 */
+    }
+    CLOSE_SOCKET(control_sock);
+  }
+
+  /* we no longer need the addrinfo stuff */
+  freeaddrinfo(local_res);
+  freeaddrinfo(remote_res);
+
+  /* so, we are either connected or not */
+  if (not_connected) {
+    fprintf(where, "establish control: are you sure there is a netserver listening on %s at port %s?\n",hostname,port);
+    fflush(where);
+    return(-1);
+  }
+  /* at this point, we are connected.  we probably want some sort of
+     version check with the remote at some point. raj 2003-02-24 */
+  return(control_sock);
+}
+
+
+void
+netlib_init()
+{
+}
+
+/* this is used only by netserver and we will want to think of
+   something different to do for it before long */
+#ifdef notdef
+
+static gboolean
+allocate_netperf(GIOChannel *source, xmlDocPtr message, gpointer data) {
+  gboolean ret;
+  xmlChar  * from_nid;
+  xmlChar  * my_nid;
+  xmlNodePtr msg;
+  xmlNodePtr cur;
+  server_t *netperf;
+  global_state_t *global_state;
+
+  global_state = data;
+
+  msg = xmlDocGetRootElement(message);
+  if (msg == NULL) {
+    g_fprintf(stderr,"empty document\n");
+    ret = FALSE;
+  } 
+  else {
+    cur = msg->xmlChildrenNode;
+    if (xmlStrcmp(cur->name,(const xmlChar *)"version")!=0) {
+      if (debug) {
+	g_fprintf(where,
+		  "%s: Received an unexpected first message\n", __func__);
+	fflush(where);
+      }
+      ret = FALSE;
+    } 
+    else {
+      /* require the caller to ensure the netperf isn't already around */
+      my_nid   = xmlStrdup(xmlGetProp(msg,(const xmlChar *)"tonid"));
+      from_nid = xmlStrdup(xmlGetProp(msg,(const xmlChar *)"fromnid"));
+
+      if ((netperf = (server_t *)malloc(sizeof(server_t))) == NULL) {
+	g_fprintf(where,"%s: malloc failed\n", __func__);
+	exit(1);
+      }
+      memset(netperf,0,sizeof(server_t));
+      netperf->id        = from_nid;
+      netperf->my_nid    = my_nid;
+#ifdef G_OS_WIN32
+      netperf->sock      = g_io_channel_win32_get_fd(source);
+#else
+      netperf->sock       = g_io_channel_unix_get_fd(source);
+#endif
+      netperf->source    = source;
+      netperf->state     = NSRV_PREINIT;
+      netperf->state_req = NSRV_WORK;
+      netperf->thread_id       = NULL;
+      netperf->next      = NULL;
+      
+      add_server_to_specified_hash(global_state->server_hash, netperf, FALSE);
+      ret = TRUE;
+    }
+  }
+  return ret;
+}
+#endif
+
+
+/* read_n_available_bytes is now in netperf-control.c since it is part
+   of the control connection code executed by a control connection
+   object */
+
+/* given a buffer with a complete control message, XML parse it and
+   then send it on its way. */
+gboolean
+xml_parse_control_message(gchar *message, gsize length) {
+  
+  xmlDocPtr xml_message;
+  gchar *key;
+  gboolean ret;
+  NetperfNetserver *netserver;
+
+  NETPERF_DEBUG_ENTRY(debug,where);
+
+  if (debug) {
+    g_fprintf(where,
+	      "%s asked to parse %d byte message '%*s'\n",
+	      __func__,
+	      length,
+	      length,
+	      message);
+  }
+  if ((xml_message = xmlParseMemory(message, length)) != NULL) {
+    /* got the message, run with it */
+    if (debug) {
+      g_fprintf(where,
+		"%s:xmlParseMemory parsed a %d byte message at %p giving doc at %p\n",
+		__func__,
+		length,
+		message,
+		xml_message);
+    }
+#ifdef notdef
+    /* we used to see if this was the first message on the control
+       connection, which was related to this routine being used only
+       by netserver.c and not netperf.c et al.  we will have to
+       figure-out something else to do in that case. */
+    /* was this the first message on the control connection? */
+    if (global_state->first_message) {
+      allocate_netperf(source,xml_message,data);
+      global_state->first_message = FALSE;
+    }
+#endif
+    /* extract the netserver id from the to portion of the message */
+    key = xmlGetProp(xml_message, (const xmlChar *)"tonid");
+
+    if (NULL != key) {
+      /* lookup its destination and send it on its way. we need to be
+	 certain that netserver.c has added a suitable entry to a
+	 netperf_netserver_hash like netperf.c does. */
+      
+      netserver = g_hash_table_lookup(server_hash,key);
+
+      /* should this be a signal sent to the netserver object, a
+	 method we invoke, or a property we attempt to set? I suspect
+	 just about any of those would actually work, question is
+	 which to use? if we start with either a signal or a property
+	 we won't be dereferencing anything from the object pointer
+	 here which I suppose is a good thing. REVISIT we used to call
+	 a routine called process_message with a pointer to the server
+	 structure and a pointer to the message */
+      g_signal_emit_by_name(netserver,"new-message",xml_message);
+      /* REVISIT this - should we have a return value from the signal?
+	 */
+      ret = TRUE;
+    }
+    else {
+      ret = FALSE;
+    }
+  }
+  else {
+    if (debug) {
+      g_fprintf(where,
+		"%s: xmlParseMemory gagged on a %d byte message at %p\n",
+		__func__,
+		length,
+		message);
+    }
+    ret = FALSE;
+  }
+  NETPERF_DEBUG_EXIT(debug,where);
+  return(ret);
+}
+
+/* handle_control_connection_eof is now in netperf-control.c since
+   that is part of the control connection object code */
+
+/* not sure if this should be here, or be a control connection object
+   method - probably should be a control connection object method */
+int
+write_to_control_connection(GIOChannel *source,
+			    xmlNodePtr body,
+			    xmlChar *nid,
+			    const xmlChar *fromnid) {
+
+  int rc;
+  int32_t length;
+
+  gchar *chars_to_send;
+
+  xmlDocPtr doc;
+  xmlDtdPtr dtd;
+  xmlNodePtr message_header;
+  xmlNodePtr new_node;
+  char *control_message;
+  int  control_message_len;
+  gsize bytes_written;
+  GError *error = NULL;
+  GIOStatus status;
+
+  if (debug) {
+    fprintf(where,
+            "%s: called with channel %p and message node at %p",
+	    __func__,
+	    source,
+            body);
+    fprintf(where,
+            " type %s destined for nid %s from nid %s\n",
+            body->name,
+            nid,
+            fromnid);
+    fflush(where);
+  }
+
+  if ((doc = xmlNewDoc((xmlChar *)"1.0")) != NULL) {
+    /* zippity do dah */
+    doc->standalone = 0;
+    dtd = xmlCreateIntSubset(doc,(xmlChar *)"message",NULL,NETPERF_DTD_FILE);
+    if (dtd != NULL) {
+      if (((message_header = xmlNewNode(NULL,(xmlChar *)"message")) != NULL) &&
+          (xmlSetProp(message_header,(xmlChar *)"tonid",nid) != NULL) &&
+          (xmlSetProp(message_header,(xmlChar *)"fromnid",fromnid) != NULL)) {
+        /* zippity ay */
+        xmlDocSetRootElement(doc,message_header);
+        /* it certainly would be nice to not have to do this with two
+           calls... raj 2003-02-28 */
+        if (((new_node = xmlDocCopyNode(body,doc,1)) != NULL) &&
+            (xmlAddChild(message_header, new_node) != NULL)) {
+	  /* IF there were a call where I could specify the buffer,
+	     then we wouldn't have to copy this again to get things
+	     contiguous with the "header" - then again, if the glib IO
+	     channel stuff offered a gathering write call it wouldn't
+	     matter... raj 2006-03-24 */
+          xmlDocDumpMemory(doc,
+                           (xmlChar **)&control_message,
+                           &control_message_len);
+          if (control_message_len > 0) {
+            /* what a wonderful day */
+
+	    length = control_message_len;
+
+	    if (debug) {
+	      g_fprintf(where,
+			"%s allocating %d bytes\n",
+			__func__,
+			length+NETPERF_MESSAGE_HEADER_SIZE);
+	    }
+
+	    chars_to_send = g_malloc(length+NETPERF_MESSAGE_HEADER_SIZE);
+
+	    /* if glib IO channels offered a gathering write, this
+	       silliness wouldn't be necessary.  yes, they offer
+	       buffered I/O and I could do two writes and then a
+	       flush, but dagnabit, if I could just call sendmsg()
+	       before, so no extra copies, no flushes, it certainly
+	       would be nice to be able to do the same with an IO
+	       channel. raj 2006-03-24 */
+
+            /* the message length send via the network does not include
+               the length itself... raj 2003-02-27 */
+            length = htonl(strlen(control_message));
+
+	    /* first copy the "header" ... */
+	    memcpy(chars_to_send,
+		   &length,
+		   NETPERF_MESSAGE_HEADER_SIZE);
+	    if (debug) {
+	      g_fprintf(where,
+			"%s copied %d bytes to %p\n",
+			__func__,
+			NETPERF_MESSAGE_HEADER_SIZE,
+			chars_to_send);
+	    }
+	    /* ... now copy the "data" */
+	    memcpy(chars_to_send+NETPERF_MESSAGE_HEADER_SIZE,
+		   control_message,
+		   control_message_len);
+
+	    if (debug) {
+	      g_fprintf(where,
+			"%s copied %d bytes to %p\n",
+			__func__,
+			control_message_len,
+			chars_to_send+NETPERF_MESSAGE_HEADER_SIZE);
+	    }
+
+	    /* and finally, send the data */
+            status = g_io_channel_write_chars(source,
+					      chars_to_send,
+					      control_message_len +
+					        NETPERF_MESSAGE_HEADER_SIZE,
+					      &bytes_written,
+					      &error);
+
+            if (debug) {
+              /* first display the header */
+              fprintf(where, "Sending %d byte message\n",
+                      control_message_len);
+              fprintf(where, "|%*s| ",control_message_len,control_message);
+              fflush(where);
+            }
+            if (bytes_written == 
+		(control_message_len+NETPERF_MESSAGE_HEADER_SIZE)) {
+	      if (debug) {
+		fprintf(where,"was successful\n");
+	      }
+              rc = NPE_SUCCESS;
+            } else {
+              rc = NPE_SEND_CTL_MSG_FAILURE;
+	      if (debug) {
+		fprintf(where,"failed\n");
+	      }
+            }
+	    g_free(chars_to_send);
+	    /* this may not be the 100% correct place for this */
+	    xmlFreeDoc(doc);
+	    free(control_message);
+          } else {
+            rc = NPE_SEND_CTL_MSG_XMLDOCDUMPMEMORY_FAILED;
+          }
+        } else {
+          rc = NPE_SEND_CTL_MSG_XMLCOPYNODE_FAILED;
+        }
+      } else {
+        rc = NPE_SEND_CTL_MSG_XMLNEWNODE_FAILED;
+      }
+    } else {
+      rc = NPE_SEND_CTL_MSG_XMLNEWDTD_FAILED;
+    }
+  } else {
+    rc = NPE_SEND_CTL_MSG_XMLNEWDOC_FAILED;
+  }
+  return(rc);
+
+}
+/* read_from_control_connection is in netperf-control.c as part of the
+   control connection object code */
+
+
+/* recv_control_message is toast since everything for reading from or
+   writing to the control connection is to be done through a
+   GIOChannel */
+
+
+/* this should probably be a routine in netperf-netserver.c associated
+   with a netserver object? */
+void
+report_server_error(NetperfNetserver *server)
+{
+  int i;
+
+
+  i = server->err_rc - NPE_MIN_ERROR_NUM;
+  fprintf(where,
+          "server %s entered error state %d from %s error code %d %s\n",
+	  server->id,
+	  server->state_req,
+	  server->err_fn,
+	  server->err_rc,
+          NP_ERROR_NAMES[i]);
+  fflush(where);
+}
+
+const char *
+netperf_error_name(int rc)
+{
+  int i;
+
+
+  i = rc - NPE_MIN_ERROR_NUM;
+  return(NP_ERROR_NAMES[i]);
+}

Modified: branches/gobject_migration/src/netperf-control.c
===================================================================
--- branches/gobject_migration/src/netperf-control.c	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/netperf-control.c	2007-03-12 22:41:39 UTC (rev 211)
@@ -34,6 +34,12 @@
 #include "config.h"
 #endif
 
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <arpa/inet.h>
+
 #include <glib-object.h>
 #include <stdio.h>
 #include "netperf-control.h"
@@ -252,7 +258,6 @@
 					   GParamSpec *pspec) {
 
   NetperfControl *control;
-  guint state;
 
   control = NETPERF_CONTROL(object);
 

Modified: branches/gobject_migration/src/netperf-netserver.c
===================================================================
--- branches/gobject_migration/src/netperf-netserver.c	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/netperf-netserver.c	2007-03-12 22:41:39 UTC (rev 211)
@@ -40,6 +40,10 @@
 #include <stdio.h>
 #endif
 
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
 #include "netperf.h"
 #include "netlib.h"
 #include "netperf-netserver.h"
@@ -884,7 +888,6 @@
   xmlNodePtr dependency_data;
   xmlChar   *testid;
   NetperfTest   *test;
-  int        hash_value;
 
 
   testid = xmlGetProp(msg,(const xmlChar *)"tid");
@@ -1410,7 +1413,6 @@
 					   GParamSpec *pspec) {
 
   NetperfNetserver *netserver;
-  guint state;
 
   netserver = NETPERF_NETSERVER(object);
 

Modified: branches/gobject_migration/src/netperf-test.c
===================================================================
--- branches/gobject_migration/src/netperf-test.c	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/netperf-test.c	2007-03-12 22:41:39 UTC (rev 211)
@@ -42,8 +42,13 @@
 #include <stdlib.h>
 #endif
 
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
 #include <glib-object.h>
-#include <stdio.h>
+
+#include "netperf.h"
 #include "netperf-test.h"
 
 enum {
@@ -357,8 +362,10 @@
    affinity to the thread. raj 2006-03-30 */
 
 void *
-netperf_test_launch_pad(NetperfTest *test) {
+netperf_test_launch_pad(void *arg) {
 
+  NetperfTest *test = arg;
+
   NETPERF_DEBUG_ENTRY(test->debug,test->where);
 
 #ifdef G_THREADS_IMPL_POSIX
@@ -425,9 +432,6 @@
   return (test->test_func)(test);
 }
 
-/* I would have used the NETPERF_THREAD_T abstraction, but that would
-   make netlib.h dependent on netperf.h and I'm not sure I want to do
-   that. raj 2006-03-02 */
 static void netperf_test_launch_thread(NetperfTest *test)
 {
 
@@ -508,7 +512,6 @@
 					   GParamSpec *pspec) {
 
   NetperfTest *test;
-  guint state;
 
   test = NETPERF_TEST(object);
 

Modified: branches/gobject_migration/src/netperf-test.h
===================================================================
--- branches/gobject_migration/src/netperf-test.h	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/netperf-test.h	2007-03-12 22:41:39 UTC (rev 211)
@@ -75,7 +75,7 @@
 			     [strong|weak] object reference  to the
 			     netserver object? */
 
-  gchar  *node;      /* the XML document node containing the servers
+  xmlNodePtr  node;      /* the XML document node containing the servers
 			configuration data */
 
   guint32  debug;    /* should the test generate debug output? */
@@ -156,17 +156,17 @@
                                   report statistics nodes returned by
                                   tests from this library. */
 
-  void  *received_stats;   /* a node to which all test_stats received
-			      by netperf from this test are appended
-			      as children */
+  xmlNodePtr  received_stats;   /* a node to which all test_stats
+				   received by netperf from this test
+				   are appended as children */
 
-  void  *dependent_data;   /* a pointer to test-specific things to
-			      return to the test which depends on this
-			      test */
+  xmlNodePtr  dependent_data;   /* a pointer to test-specific things
+				   to return to the test which depends
+				   on this test */
 
-  void  *dependency_data;  /* a pointer to test-specific things
-			      returned by the test on which this test
-			      is dependent */
+  xmlNodePtr  dependency_data;  /* a pointer to test-specific things
+				   returned by the test on which this
+				   test is dependent */
 
   void *test_specific_data;    /* a pointer to test-specific things -
                                   config settings for the test, places

Modified: branches/gobject_migration/src/nettest_bsd.c
===================================================================
--- branches/gobject_migration/src/nettest_bsd.c	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/src/nettest_bsd.c	2007-03-12 22:41:39 UTC (rev 211)
@@ -131,6 +131,8 @@
 
 #include "netperf.h"
 
+#include "netlib.h"
+
 #include "nettest_bsd.h"
 
 #include "netconfidence.h"
@@ -305,67 +307,7 @@
 
 
 
-static void
-dump_addrinfo(FILE *dumploc, struct addrinfo *info,
-              xmlChar *host, xmlChar *port, int family)
-{
-  struct sockaddr *ai_addr;
-  struct addrinfo *temp;
-  temp=info;
 
-  fprintf(dumploc, "getaddrinfo returned the following for host '%s' ", host);
-  fprintf(dumploc, "port '%s' ", port);
-  fprintf(dumploc, "family %d\n", family);
-  while (temp) {
-    fprintf(dumploc,
-            "\tcannonical name: '%s'\n",temp->ai_canonname);
-    fprintf(dumploc,
-            "\tflags: %d family: %d: socktype: %d protocol %d addrlen %d\n",
-            temp->ai_flags,
-            temp->ai_family,
-            temp->ai_socktype,
-            temp->ai_protocol,
-            temp->ai_addrlen);
-    ai_addr = temp->ai_addr;
-    if (ai_addr != NULL) {
-      fprintf(dumploc,
-              "\tsa_family: %d sadata: %d %d %d %d %d %d\n",
-              ai_addr->sa_family,
-              (u_char)ai_addr->sa_data[0],
-              (u_char)ai_addr->sa_data[1],
-              (u_char)ai_addr->sa_data[2],
-              (u_char)ai_addr->sa_data[3],
-              (u_char)ai_addr->sa_data[4],
-              (u_char)ai_addr->sa_data[5]);
-    }
-    temp = temp->ai_next;
-  }
-  fflush(dumploc);
-}
-
-
-#ifdef notdef
-static int
-strtofam(xmlChar *familystr)
-{
-  if (!xmlStrcmp(familystr,(const xmlChar *)"AF_INET")) {
-    return(AF_INET);
-  } 
-  else if (!xmlStrcmp(familystr,(const xmlChar *)"AF_UNSPEC")) {
-    return(AF_UNSPEC);
-#ifdef AF_INET6
-  }
-  else if (!xmlStrcmp(familystr,(const xmlChar *)"AF_INET6")) {
-    return(AF_INET6);
-#endif /* AF_INET6 */
-  }
-  else {
-    /* we should never get here if the validator is doing its thing */
-    return(-1);
-  }
-}
-#endif
-
 static void
 get_dependency_data(test_t *test, int type, int protocol)
 {
@@ -3040,8 +2982,6 @@
 recv_udp_rr_meas(test_t *test)
 {
   int               len;
-  int               bytes_left;
-  char             *req_ptr;
   uint32_t          new_state;
   bsd_data_t       *my_data;
   struct sockaddr   peeraddr;

Deleted: branches/gobject_migration/suites/multi/Makefile
===================================================================
--- branches/gobject_migration/suites/multi/Makefile	2007-03-12 15:52:21 UTC (rev 210)
+++ branches/gobject_migration/suites/multi/Makefile	2007-03-12 22:41:39 UTC (rev 211)
@@ -1,460 +0,0 @@
-# Makefile.in generated by automake 1.7.9 from Makefile.am.
-# suites/multi/Makefile.  Generated from Makefile.in by configure.
-
-# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-# Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-
-
-srcdir = .
-top_srcdir = ../..
-
-pkgdatadir = $(datadir)/netperf
-pkglibdir = $(libdir)/netperf
-pkgincludedir = $(includedir)/netperf
-top_builddir = ../..
-
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = /usr/bin/install -c
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-host_triplet = i686-pc-linux-gnu
-ACLOCAL = ${SHELL} /home/raj/netperf4_gobject/missing --run aclocal-1.7
-AMDEP_FALSE = #
-AMDEP_TRUE = 
-AMTAR = ${SHELL} /home/raj/netperf4_gobject/missing --run tar
-AR = ar
-AUTOCONF = ${SHELL} /home/raj/netperf4_gobject/missing --run autoconf
-AUTOHEADER = ${SHELL} /home/raj/netperf4_gobject/missing --run autoheader
-AUTOMAKE = ${SHELL} /home/raj/netperf4_gobject/missing --run automake-1.7
-AWK = mawk
-CC = gcc
-CCDEPMODE = depmode=gcc3
-CFLAGS = -g -O2 -pthread -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  
-CPP = gcc -E
-CPPFLAGS =  -D_REENTRANT -D_GNU_SOURCE
-CXX = g++
-CXXCPP = g++ -E
-CXXDEPMODE = depmode=gcc3
-CXXFLAGS = -g -O2
-CYGPATH_W = echo
-DEFS = -DHAVE_CONFIG_H
-DEPDIR = .deps
-ECHO = echo
-ECHO_C = 
-ECHO_N = -n
-ECHO_T = 
-EGREP = /bin/grep -E
-EXEEXT = 
-F77 = 
-FFLAGS = 
-GLIB_CFLAGS = -pthread -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include  
-GLIB_GENMARSHAL = glib-genmarshal
-GLIB_LIBS = -pthread -Wl,--export-dynamic -lgthread-2.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0  
-GLIB_MKENUMS = glib-mkenums
-GOBJECT_QUERY = gobject-query
-GREP = /bin/grep
-INSTALL_DATA = ${INSTALL} -m 644
-INSTALL_PROGRAM = ${INSTALL}
-INSTALL_SCRIPT = ${INSTALL}
-INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
-LDFLAGS = 
-LIBOBJS = 
-LIBOJBS = 
-LIBS = -lm  -Wl,--export-dynamic -pthread   -lxml2 -lgmodule-2.0 -ldl -lgthread-2.0 -lgobject-2.0 -lglib-2.0  
-LIBTOOL = $(SHELL) $(top_builddir)/libtool
-LN_S = ln -s
-LTLIBOBJS = 
-MAKEINFO = ${SHELL} /home/raj/netperf4_gobject/missing --run makeinfo
-NETSYS_SOURCE = linux
-OBJEXT = o
-PACKAGE = netperf
-PACKAGE_BUGREPORT = 
-PACKAGE_NAME = netperf
-PACKAGE_STRING = netperf 4.0.0rc2
-PACKAGE_TARNAME = netperf
-PACKAGE_VERSION = 4.0.0rc2
-PATH_SEPARATOR = :
-PKG_CONFIG = /usr/bin/pkg-config
-RANLIB = ranlib
-SET_MAKE = 
-SHELL = /bin/sh
-STRIP = strip
-VERSION = 4.0.0rc2
-WANT_DISK_FALSE = 
-WANT_DISK_TRUE = #
-WANT_DNS_FALSE = 
-WANT_DNS_TRUE = #
-WANT_MULTI_FALSE = 
-WANT_MULTI_TRUE = #
-WANT_VST_FALSE = 
-WANT_VST_TRUE = #
-ac_ct_CC = gcc
-ac_ct_CXX = g++
-ac_ct_F77 = 
-am__fastdepCC_FALSE = #
-am__fastdepCC_TRUE = 
-am__fastdepCXX_FALSE = #
-am__fastdepCXX_TRUE = 
-am__include = include
-am__leading_dot = .
-am__quote = 
-bindir = ${exec_prefix}/bin
-build = i686-pc-linux-gnu
-build_alias = 
-build_cpu = i686
-build_os = linux-gnu
-build_vendor = pc
-datadir = ${datarootdir}
-datarootdir = ${prefix}/share
-docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
-dvidir = ${docdir}
-exec_prefix = ${prefix}
-host = i686-pc-linux-gnu
-host_alias = 
-host_cpu = i686
-host_os = linux-gnu
-host_vendor = pc
-htmldir = ${docdir}
-includedir = ${prefix}/include
-infodir = ${datarootdir}/info
-install_sh = /home/raj/netperf4_gobject/install-sh
-libdir = ${exec_prefix}/lib
-libexecdir = ${exec_prefix}/libexec
-localedir = ${datarootdir}/locale
-localstatedir = ${prefix}/var
-mandir = ${datarootdir}/man
-oldincludedir = /usr/include
-pdfdir = ${docdir}
-prefix = /usr/local
-program_transform_name = s,x,x,
-psdir = ${docdir}
-sbindir = ${exec_prefix}/sbin
-sharedstatedir = ${prefix}/com
-sysconfdir = ${prefix}/etc
-target = i686-pc-linux-gnu
-target_alias = 
-target_cpu = i686
-target_os = linux-gnu
-target_vendor = pc
-AM_CPPFLAGS = -I$(top_srcdir)/include
-
-# in theory, the stuff below should deal with creating the requisite libs
-lib_LTLIBRARIES = nettest_multi.la
-
-nettest_multi_la_SOURCES = nettest_multi.c nettest_multi.h
-nettest_multi_la_LDFLAGS = -module
-subdir = suites/multi
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-LTLIBRARIES = $(lib_LTLIBRARIES)
-
-nettest_multi_la_LIBADD =
-am_nettest_multi_la_OBJECTS = nettest_multi.lo
-nettest_multi_la_OBJECTS = $(am_nettest_multi_la_OBJECTS)
-
-DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-DEP_FILES = ./$(DEPDIR)/nettest_multi.Plo
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
-	$(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-DIST_SOURCES = $(nettest_multi_la_SOURCES)
-DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
-SOURCES = $(nettest_multi_la_SOURCES)
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
-	cd $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu  suites/multi/Makefile
-Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
-	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
-libLTLIBRARIES_INSTALL = $(INSTALL)
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
-	@$(NORMAL_INSTALL)
-	$(mkinstalldirs) $(DESTDIR)$(libdir)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  if test -f $$p; then \
-	    f="`echo $$p | sed -e 's|^.*/||'`"; \
-	    echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
-	    $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
-	  else :; fi; \
-	done
-
-uninstall-libLTLIBRARIES:
-	@$(NORMAL_UNINSTALL)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	    p="`echo $$p | sed -e 's|^.*/||'`"; \
-	  echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
-	  $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
-	done
-
-clean-libLTLIBRARIES:
-	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
-	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
-	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
-	  test "$$dir" = "$$p" && dir=.; \
-	  echo "rm -f \"$${dir}/so_locations\""; \
-	  rm -f "$${dir}/so_locations"; \
-	done
-nettest_multi.la: $(nettest_multi_la_OBJECTS) $(nettest_multi_la_DEPENDENCIES) 
-	$(LINK) -rpath $(libdir) $(nettest_multi_la_LDFLAGS) $(nettest_multi_la_OBJECTS) $(nettest_multi_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT) core *.core
-
-distclean-compile:
-	-rm -f *.tab.c
-
-include ./$(DEPDIR)/nettest_multi.Plo
-
-.c.o:
-	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
-	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
-	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-	fi
-#	source='$<' object='$@' libtool=no \
-#	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
-#	$(CCDEPMODE) $(depcomp) \
-#	$(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
-
-.c.obj:
-	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-	  -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
-	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
-	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-	fi
-#	source='$<' object='$@' libtool=no \
-#	depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' \
-#	$(CCDEPMODE) $(depcomp) \
-#	$(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
-
-.c.lo:
-	if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
-	  -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
-	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
-	else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
-	fi
-#	source='$<' object='$@' libtool=yes \
-#	depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' \
-#	$(CCDEPMODE) $(depcomp) \
-#	$(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-distclean-libtool:
-	-rm -f libtool
-uninstall-info-am:
-
-ETAGS = etags
-ETAGSFLAGS =
-
-CTAGS = ctags
-CTAGSFLAGS =
-
-tags: TAGS
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	mkid -fID $$unique
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(ETAGS_ARGS)$$tags$$unique" \
-	  || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	     $$tags $$unique
-
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-		$(TAGS_FILES) $(LISP)
-	tags=; \
-	here=`pwd`; \
-	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-	unique=`for i in $$list; do \
-	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
-	test -z "$(CTAGS_ARGS)$$tags$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$tags $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && cd $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-
-top_distdir = ../..
-distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
-	list='$(DISTFILES)'; for file in $$list; do \
-	  case $$file in \
-	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
-	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
-	  esac; \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
-	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
-	    dir="/$$dir"; \
-	    $(mkinstalldirs) "$(distdir)$$dir"; \
-	  else \
-	    dir=''; \
-	  fi; \
-	  if test -d $$d/$$file; then \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-	    fi; \
-	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-	  else \
-	    test -f $(distdir)/$$file \
-	    || cp -p $$d/$$file $(distdir)/$$file \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-
-installdirs:
-	$(mkinstalldirs) $(DESTDIR)$(libdir)
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-exec-am: install-libLTLIBRARIES
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libLTLIBRARIES clean-libtool ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am info info-am install \
-	install-am install-data install-data-am install-exec \
-	install-exec-am install-info install-info-am \
-	install-libLTLIBRARIES install-man install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags uninstall uninstall-am uninstall-info-am \
-	uninstall-libLTLIBRARIES
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:



More information about the netperf-dev mailing list