[netperf-dev] netperf4 commit notice r212 - branches/gobject_migration/src

raj at netperf.org raj at netperf.org
Mon Mar 12 17:31:54 PST 2007


Author: raj
Date: 2007-03-12 17:31:53 -0800 (Mon, 12 Mar 2007)
New Revision: 212

Added:
   branches/gobject_migration/src/netperf4.c
Log:
don't forget our new mainprogram source

Added: branches/gobject_migration/src/netperf4.c
===================================================================
--- branches/gobject_migration/src/netperf4.c	2007-03-12 22:41:39 UTC (rev 211)
+++ branches/gobject_migration/src/netperf4.c	2007-03-13 01:31:53 UTC (rev 212)
@@ -0,0 +1,833 @@
+/*
+   netperf - network-oriented performance benchmarking
+
+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.
+
+*/
+
+#include <glib-object.h>
+
+#include <stdio.h>
+#include "netperf-netserver.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+# ifdef HAVE_GLIB_H
+#  include <glib.h>
+# endif 
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#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_STRING_H
+#include <string.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifndef HAVE_GETOPT_LONG
+#include "missing/getopt.h"
+#else
+#include <getopt.h>
+#endif
+
+/* #include "system.h" */
+
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include "netperf.h"
+#include "netlib.h"
+#include "netmsg.h"
+
+int debug = 0;
+FILE *where;
+
+typedef gboolean (*netperf_interactive_cmd_func_t)(gchar *arguments,gpointer data);
+
+static gboolean parse_interactive_new_command(char *arguments, gpointer data);
+static gboolean parse_interactive_set_command(char *arguments, gpointer data);
+static gboolean parse_interactive_read_command(char *arguments, gpointer data);
+static gboolean parse_interactive_show_command(char *arguments, gpointer data);
+static gboolean parse_interactive_load_command(char *arguments, gpointer data);
+static gboolean parse_interactive_measure_command(char *arguments, gpointer data);
+static gboolean parse_interactive_init_command(char *arguments, gpointer data);
+static gboolean parse_interactive_idle_command(char *arguments, gpointer data);
+static gboolean parse_interactive_stats_command(char *arguments, gpointer data);
+static gboolean parse_interactive_die_command(char *arguments, gpointer data);
+static gboolean unknown_interactive_command(char *arguments, gpointer data);
+
+struct netperf_interactive_cmds {
+  char *command_name;
+  netperf_interactive_cmd_func_t command_func;
+};
+
+struct netperf_interactive_cmds interactive_command_table[] = {
+  /* command_name         command_func */
+  { "set",                 parse_interactive_set_command},
+  { "show",                parse_interactive_show_command},
+  { "new",                 parse_interactive_new_command},
+  { "read",                parse_interactive_read_command},
+  { "load",                parse_interactive_load_command},
+  { "measure",             parse_interactive_measure_command},
+  { "init",                parse_interactive_init_command},
+  { "idle",                parse_interactive_idle_command},
+  { "stats",               parse_interactive_stats_command},
+  { "die",                 parse_interactive_die_command},
+  { NULL,                  unknown_interactive_command}
+};
+
+GHashTable *server_hash;
+GHashTable *test_hash;
+GHashTable *test_set_hash;
+
+xmlDocPtr config_doc = NULL;
+
+char *program_name;
+
+#define  GET_STATS        1
+#define  CLEAR_STATS      2
+
+/* getopt_long return codes */
+enum {DUMMY_CODE=129
+      ,BRIEF_CODE
+};
+
+/* Option flags and variables */
+
+char *oname = "stdout";         /* --output */
+FILE *ofile;
+char *iname = NULL;             /* --input */
+FILE *ifile;
+char *cname = NULL;             /* configuration file */
+int want_gui;                   /* should we try to launch the GUI? */
+int want_interactive;           /* does the user want an interactive session */
+int want_quiet;                 /* --quiet, --silent */
+int want_brief;                 /* --brief */
+int want_verbose;               /* --verbose */
+int want_batch = 0;             /* set when -i specified */
+
+
+static struct option const long_options[] =
+{
+  {"output", required_argument, 0, 'o'},
+  {"input", required_argument, 0, 'i'},
+  {"config", required_argument, 0, 'c'},
+  {"debug", no_argument, 0, 'd'},
+  {"quiet", no_argument, 0, 'q'},
+  {"silent", no_argument, 0, 'q'},
+  {"brief", no_argument, 0, BRIEF_CODE},
+  {"verbose", no_argument, 0, 'v'},
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'V'},
+  {NULL, 0, NULL, 0}
+};
+
+
+gboolean set_debug(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+  if (option_value) {
+    /* set to value */
+    debug = atoi(option_value);
+  }
+  else {
+    /* simple increment */
+    debug++;
+  }
+  return(TRUE);
+}
+
+
+
+gboolean set_verbose(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+  if (option_value) {
+    /* set to value */
+    want_verbose = atoi(option_value);
+  }
+  else {
+    /* simple increment */
+    want_verbose++;
+  }
+  return(TRUE);
+}
+  
+
+gboolean show_version(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+  g_printf("netserver: %s.%s.%s\n",
+	   NETPERF_VERSION,
+	   NETPERF_UPDATE,
+	   NETPERF_FIX);
+  exit(0);
+}
+
+gboolean set_output_destination(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+  oname = g_strdup(option_value);
+  ofile = fopen(oname, "w");
+  if (!ofile) {
+    g_fprintf(stderr,
+	    "%s: cannot open %s for writing\n",
+	    program_name,
+	    option_value);
+    exit(1);
+  }
+  return(TRUE);
+}
+
+gboolean set_input_source(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+
+  iname = g_strdup(option_value);
+  ifile = fopen(iname, "r");
+  if (!ifile) {
+    g_fprintf(where,
+	      "%s: cannot open %s for reading\n",
+	      program_name,
+	      option_value);
+    fflush(where);
+    exit(1);
+  } 
+  else {
+    want_batch = 1;
+    fclose(ifile);
+    ifile = NULL;
+  }
+
+  return(TRUE);
+}
+
+gboolean set_config_source(gchar *option_name, gchar *option_value, gpointer data, GError **error) {
+  cname = g_strdup(option_value);
+  return(TRUE);
+}
+
+
+static GOptionEntry netperf_entries[] = 
+  {
+    {"output",'o', 0, G_OPTION_ARG_CALLBACK, (void *)set_output_destination, "Specify where misc output should go", NULL},
+    {"input",'i',0, G_OPTION_ARG_CALLBACK, (void *)set_input_source, "Specify the command file", NULL},
+    {"config", 'c', 0, G_OPTION_ARG_CALLBACK, (void *)set_config_source, "Specify the configuration file", NULL},
+    {"debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, (void *)set_debug, "Set the level of debugging output", NULL},
+    {"version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, (void *)show_version, "Display the netserver version and exit", NULL},
+    {"verbose", 'v', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, (void *)set_verbose, "Set verbosity level for output", NULL},
+    {"brief", 'b', 0, G_OPTION_ARG_NONE, &want_brief, "Request brief output", NULL},
+    {"quiet", 'q', 0, G_OPTION_ARG_NONE, &want_quiet, "Display no test banners", NULL},
+    {"gui", 'g', 0, G_OPTION_ARG_NONE, &want_gui, "Enable the Graphical User Interface", NULL},
+    {"interactive", 'I', 0, G_OPTION_ARG_NONE, &want_interactive, "Enable the Graphical User Interface", NULL},
+    { NULL }
+  };
+
+
+static xmlNodePtr
+parse_xml_file(char *fname,const xmlChar *doctype, xmlDocPtr *document)
+{
+  xmlDocPtr  doc = NULL;
+  xmlNodePtr root = NULL;
+  xmlNsPtr   ns;
+  struct stat buf;
+
+  if (debug) {
+    if (fname) {
+      fprintf(where,"%s called with fname %s\n",__func__,fname);
+    }
+    else {
+      fprintf(where,"%s called with null fname\n",__func__);
+    }
+    fflush(where);
+  }
+  if (fname == NULL) {
+    if (!xmlStrcmp(doctype,(const xmlChar *)"netperf")) {
+      if (0 == g_stat("default_config.xml",&buf)) {
+	fname = "default_config.xml";
+      }
+      else if (0 == g_stat(NETPERFDIR G_DIR_SEPARATOR_S "default_config.xml",
+			 &buf)) {
+	fname = NETPERFDIR G_DIR_SEPARATOR_S "default_config.xml";
+      }
+      else {
+	fname = "missing config file";
+      }
+    }
+    if (!xmlStrcmp(doctype,(const xmlChar *)"commands")) {
+      if (0 == g_stat("default_commands.xml",&buf)) {
+	fname = "default_commands.xml";
+      }
+      else if (0 == g_stat(NETPERFDIR G_DIR_SEPARATOR_S "default_commands.xml",
+			 &buf)) {
+	fname = NETPERFDIR G_DIR_SEPARATOR_S "default_commands.xml";
+      }
+      else {
+	fname = "missing commands file";
+      }
+    }
+  }
+
+  if (debug) {
+    fprintf(where,"%s parsing file %s\n",__func__,fname);
+    fflush(where);
+  }
+  
+  if ((doc = xmlParseFile(fname)) != NULL) {
+    /* find the root element of the document */
+    if ((root = xmlDocGetRootElement(doc)) != NULL) {
+      /* now make sure that the netperf namespace is present */
+      ns = xmlSearchNsByHref(doc, root,
+                  (const xmlChar *)"http://www.netperf.org/ns/netperf");
+      if (ns != NULL) {
+        if (!xmlStrcmp(root->name,doctype)) {
+          /* happy day valid document */
+          *document = doc;
+        } else {
+          /* not a correct document type*/
+          fprintf(where,
+                  "file %s is of type \"%s\" not \"%s\"\n",
+                  fname,root->name,doctype);
+          fflush(where);
+          xmlFreeDoc(doc);
+          doc  = NULL;
+          root = NULL;
+        }
+      } else {
+        /* no namespace match */
+        fprintf(where,
+                "file %s does not reference a netperf namespace\n",fname);
+        fflush(where);
+        xmlFreeDoc(doc);
+        doc  = NULL;
+        root = NULL;
+      }
+    } else {
+      /* empty document */
+      fprintf(where,
+              "file %s contains no root element\n",fname);
+      xmlFreeDoc(doc);
+      fflush(where);
+      doc = NULL;
+    }
+  } else {
+    fprintf(where,
+            "file %s contained invalid XML\n",fname);
+    fflush(where);
+  }
+  return(root);
+}
+
+
+void print_netserver_hash_entry(gpointer key, gpointer value, gpointer user_data)
+{
+  NetperfNetserver *netserver;
+  guint state,req_state;
+  gchar *id;
+
+  g_print("key: %s, value %p, user_data %p\n",
+	  (char *)key,
+	  value,
+	  user_data);
+  /* the key :) thing to remember is that the pointer to the netserver
+     object is the value, not the key */
+  netserver = value;
+  g_object_get(netserver,
+	       "state", &state,
+	       "req-state", &req_state,
+	       "id", &id,
+	       NULL);
+  g_print("\tstate: %d res_state: %d id %s\n",state,req_state,id);
+
+}
+
+static void display_netserver_hash() {
+  /* try iterating through all the entries in the hash table */
+  g_hash_table_foreach(server_hash, print_netserver_hash_entry, NULL);
+
+}
+
+static void netperf_init() 
+{
+  /* the key for the server hash is the id string, so we use the
+     glib-provided g_str_hash as the hash function and g_str_equal for
+     the key equality test function */
+  server_hash = g_hash_table_new(g_str_hash,g_str_equal);
+
+  test_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+  test_set_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+}
+
+
+
+/* REVISIT - need to add test_set support */
+static void
+wait_for_test_to_enter_requested_state(gchar *testid, guint state) 
+{
+
+  NetperfTest *test;
+  guint test_state,test_req_state;
+
+  NETPERF_DEBUG_ENTRY(debug,where);
+
+  test = g_hash_table_lookup(test_set_hash, testid);
+
+  if (test) {
+    /* this was a test set */
+  }
+  else {
+    /* wasn't a test_set - is it a plain test? */
+    test = g_hash_table_lookup(test_hash,testid);
+    
+    if (test) {
+      do {
+	g_object_get(test,
+		     "state", &test_state,
+		     "req-state",&test_req_state,
+		     NULL);
+      } while ((test_state != test_req_state) && (test_state != TEST_ERROR));
+      if (TEST_ERROR == test_state) {
+	/* there is something wrong with the test, that is bad REVISIT */
+      }
+    }
+    else {
+      /* we didn't find a test, that is bad REVISIT */
+    }
+  }
+  NETPERF_DEBUG_EXIT(debug,where);
+
+}
+
+
+
+
+static SOCKET
+connect_netserver(xmlDocPtr doc, xmlNodePtr netserver, server_t *new_server)
+{
+  xmlChar   *remotehost;
+  xmlChar   *remoteport;
+  xmlChar   *localhost;
+  xmlChar   *localport;
+
+  int      localfamily;
+  int      remotefamily;
+  SOCKET      sock;
+
+  /* validation means that we know that the host informaion is in attributes
+     of the netserver element. The xml parser checked them and initialized
+     any optional attributes which where not present.  sgb 2003-10-11 */
+
+  /* pull the remote address family, service and host attributes */
+  remotefamily = strtofam(xmlGetProp(netserver,(const xmlChar *)"family"));
+  remoteport   = xmlGetProp(netserver,(const xmlChar *)"remote_service");
+  remotehost   = xmlGetProp(netserver,(const xmlChar *)"remote_host");
+
+  /* for the time being, the netserver element definition provides only
+     one family attribute - this means no mixed family stuff, which should
+     not be a problem for the moment.  since getaddrinfo() takes a servname
+     parm as an ASCII string we will just pass the string. sgb 2003-10-11 */
+
+  /* now pull the local address family, service and host attributes */
+  localfamily  = strtofam(xmlGetProp(netserver,(const xmlChar *)"family"));
+  localport    = xmlGetProp(netserver,(const xmlChar *)"local_service");
+  localhost    = xmlGetProp(netserver,(const xmlChar *)"local_host");
+
+  /* and now call establish_control */
+  sock = establish_control(remotehost, remoteport, remotefamily,
+                           localhost,  localport,  localfamily);
+  return(sock);
+}
+
+static gboolean periodic_callback(gpointer data)
+{
+  static int i = 1;
+  g_print("Hello there again for the %d",i);
+  if (i > 3) g_print("th time\n");
+  else if (i > 1) g_print("nd time\n");
+  else g_print("st time\n");
+  i++;
+
+  return TRUE;
+}
+
+static gboolean parse_interactive_new_command(char *arguments,
+					      gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the NEW command were %s\n",
+	  arguments);
+
+  return return_value;
+}
+
+static gboolean unknown_interactive_command(char *arguments,
+					    gpointer data) {
+  g_print("The command you entered %s is presently unknown\n",
+	  arguments);
+
+  return TRUE;
+}
+
+static gboolean parse_interactive_set_command(char *arguments,
+					      gpointer data)
+{
+  gboolean return_value = TRUE;
+
+  g_print("the arguments to the SET command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_show_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the SHOW command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_read_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the READ command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_load_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the LOAD command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_measure_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the MEASURE command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_init_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the INIT command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_idle_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the IDLE command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_stats_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the stats command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+static gboolean parse_interactive_die_command(char *arguments,
+					       gpointer data)
+{
+  gboolean return_value = TRUE;
+  g_print("the arguments to the DIE command were %s\n",
+	  arguments);
+  return return_value;
+}
+
+
+/* this is _really_ brain dead parsing, but it should be good enough
+   to get us going.  I would be _MORE_ than happy to have something a
+   bit more sophisticated if warranted. also, the return should
+   probably become a bit more sophisticated one of these days to deal
+   with fatal vs non-fatal errors */
+static gboolean parse_interactive_command_line(gchar *command_line,
+					       gpointer data)
+{
+  struct netperf_interactive_cmds *command_table_entry;
+
+  gchar **split;
+  gboolean return_value = TRUE;
+  command_table_entry = interactive_command_table;
+
+  split = g_strsplit(command_line,
+		     " ", /* space, the final delimiter */
+		     2);  /* yes, splitting to a magic constant number
+			     of tokens, naughty naughty */
+
+  /* a very simplistic parsing of the split. split[0] should be our
+     command, the rest of it the arguments to the command which will
+     be parsed by the command-specific parser. the g_strcasecmp
+     documentation suggests that this is not a good thing to use, but
+     it was also difficult to follow what to use to replace it. for
+     the time being, we aren't worried about localization though, so I
+     _think_ I'm OK - famous last words. perhaps one of these days
+     we'll use one of those tables like used for the command message
+     parsing... */
+  while (command_table_entry->command_name != NULL) {
+    if (g_strcasecmp(command_table_entry->command_name,split[0]) == 0){
+      return_value = (command_table_entry->command_func)(split[1],data);
+      break;
+    }
+    command_table_entry++;
+  }
+
+  if (NULL == command_table_entry->command_name) {
+    g_print("command %s with arguments %s is presently unknown\n",
+	    split[0],
+	    split[1]);
+    return_value = TRUE;
+  }
+  g_strfreev(split);
+
+  return return_value;
+}  
+
+static gboolean read_from_terminal(GIOChannel *source,
+				   GIOCondition condition,
+				   gpointer data) {
+
+  GIOStatus ret;
+  gchar *command_line;
+  gsize length;
+  gsize terminator_pos;
+  GError *error = NULL;
+  gboolean return_value = TRUE;
+
+  NETPERF_DEBUG_ENTRY(debug,where);
+
+  ret = g_io_channel_read_line(source,
+			       &command_line,
+			       &length,
+			       &terminator_pos,
+			       &error);
+
+  switch (ret)     {
+  case G_IO_STATUS_NORMAL:
+    
+    g_print("There were %d bytes to read from the terminal\n",
+	  length);
+    g_print("and it was %s\n",command_line);
+    g_print("with the terminator position being %d\n",terminator_pos);
+    return_value = parse_interactive_command_line(command_line,data);
+    g_free(command_line);
+    break;
+  case G_IO_STATUS_EOF:
+    g_print("the user tried to ask for end of file on the terminal\n");
+    return_value = FALSE; /* time to remove the watch */
+    break;
+
+  case G_IO_STATUS_ERROR:
+    g_print("Knuth only knows what went wrong, we have G_IO_STATUS_ERROR\n");
+    break;
+
+  case G_IO_STATUS_AGAIN:
+    g_print("It was deceiving us, we have G_IO_STATUS_AGAIN\n");
+    break;
+  }
+
+  NETPERF_DEBUG_EXIT(debug,where);
+
+  return return_value;
+}
+int main(int argc, char **argv) 
+{
+
+  NetperfNetserver *netserver = NULL;
+
+  GIOChannel *input_channel;
+  guint       input_watch_id;
+
+  GOptionContext *option_context;
+  gboolean ret;
+  GError *error=NULL;
+  
+  GMainLoop *loop;
+
+  g_type_init();
+
+#ifdef G_OS_WIN32
+  WSADATA	wsa_data ;
+
+#endif
+
+  /* should this be a g_strdup() call instead of an assignment of the
+     pointer? */
+  program_name = argv[0];
+
+  g_thread_init(NULL);
+
+  where = stderr;
+
+#ifdef G_OS_WIN32
+  /* Initialize the winsock lib ( version 2.2 ) */
+  if ( WSAStartup(MAKEWORD(2,2), &wsa_data) == SOCKET_ERROR ){
+    g_fprintf(where,"WSAStartup() failed : %d\n", GetLastError()) ;
+    return 1 ;
+  }
+#endif
+
+  option_context = g_option_context_new(" - netperf4 netperf options");
+  g_option_context_add_main_entries(option_context,netperf_entries, NULL);
+  ret = g_option_context_parse(option_context, &argc, &argv, &error);
+  if (error) {
+    /* it sure would be nice to know how to trigger the help output */
+    g_error("%s g_option_context_parse %s %d %s\nUse netserver --help for help\n",
+	      __func__,
+	      g_quark_to_string(error->domain),
+	      error->code,
+	      error->message);
+    g_clear_error(&error);
+  }
+
+  xmlInitParser();
+  xmlKeepBlanksDefault(0);
+
+  xmlDoValidityCheckingDefaultValue = 1;
+  xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
+
+  /* OK, all the "non-test" initialization is complete.  Now we have
+     to decide if we are going to run a batch command file, or start
+     trying to take commands from the user in an interactive
+     manner. */
+
+  parse_xml_file(cname, (const xmlChar *)"netperf", &config_doc);
+
+  netperf_init();
+
+  loop = g_main_loop_new(NULL, FALSE);
+
+  if (want_interactive) {
+    g_print("Yo, the user wants an interactive session\n");
+  }
+  else {
+    g_print("Hey, the user wants a batch session\n");
+  }
+
+  /* ass-u-me-ing that fd0 is stdin is probably a bad thing to do */
+  input_channel = g_io_channel_unix_new(0);
+  input_watch_id = g_io_add_watch(input_channel,
+				  G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
+				  read_from_terminal,
+				  NULL);
+
+  g_timeout_add(10000,
+		(GSourceFunc)periodic_callback,
+		NULL);
+
+  g_main_loop_run(loop);
+
+#ifdef notdef
+  netserver = g_object_new(TYPE_NETPERF_NETSERVER,
+			   "req-state", NSRV_CONNECTED,
+			   "id", "george",
+			   NULL);
+  g_print("netserver george is at %p\n",netserver);
+
+  g_hash_table_replace(server_hash,
+		       g_strdup("george"),
+		       netserver);
+
+  netserver = g_object_new(TYPE_NETPERF_NETSERVER,
+			   "req-state", NSRV_CONNECTED,
+			   "id", "fred",
+			   NULL);
+  g_print("netserver fred is at %p\n",netserver);
+
+  g_hash_table_replace(server_hash,
+		       g_strdup("fred"),
+		       netserver);
+
+  netserver = g_hash_table_lookup(server_hash,"fred");
+  g_print("netserver fred is %p from the hash table\n",
+	  netserver);
+
+  /* try iterating through all the entries in the hash table */
+  g_hash_table_foreach(server_hash, print_netserver_hash_entry, NULL);
+#endif
+
+  return 0;
+
+}



More information about the netperf-dev mailing list