From b013cdbe70ee4c781c5444e2f1e1042b1f3bea7b Mon Sep 17 00:00:00 2001
From: mh17 <mh17>
Date: Thu, 3 Dec 2009 15:03:08 +0000
Subject: [PATCH] added code for pipeServer

---
 src/include/ZMap/zmapView.h                |   6 +-
 src/zmapApp/zmapApp_P.h                    |   7 +-
 src/zmapServer/pipe/pipeServer.c           | 138 ++++++++++++++++-----
 src/zmapServer/pipe/pipeServer_P.h         |  12 +-
 src/zmapServer/zmapServerProtocolHandler.c |   4 +-
 src/zmapServer/zmapServerPrototype.h       |   6 +-
 src/zmapView/zmapViewUtils.c               |  20 ++-
 7 files changed, 150 insertions(+), 43 deletions(-)

diff --git a/src/include/ZMap/zmapView.h b/src/include/ZMap/zmapView.h
index fb1349e15..32a78266d 100755
--- a/src/include/ZMap/zmapView.h
+++ b/src/include/ZMap/zmapView.h
@@ -31,7 +31,7 @@
  * HISTORY:
  * Last edited: Jun 12 14:36 2009 (edgrif)
  * Created: Thu May 13 14:59:14 2004 (edgrif)
- * CVS info:   $Id: zmapView.h,v 1.53 2009-06-12 13:58:16 edgrif Exp $
+ * CVS info:   $Id: zmapView.h,v 1.54 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef ZMAPVIEW_H
@@ -162,6 +162,10 @@ typedef struct
     struct {
       char *path ;
     } file ;
+    struct {
+      char *path ;
+      char *query ;
+    } pipe ;
   } scheme_data ;
 
 } ZMapViewSessionServerStruct, *ZMapViewSessionServer ;
diff --git a/src/zmapApp/zmapApp_P.h b/src/zmapApp/zmapApp_P.h
index 76ffef03a..1292dae6e 100755
--- a/src/zmapApp/zmapApp_P.h
+++ b/src/zmapApp/zmapApp_P.h
@@ -27,7 +27,7 @@
  * HISTORY:
  * Last edited: Dec 19 09:12 2008 (edgrif)
  * Created: Thu Jul 24 14:35:41 2003 (edgrif)
- * CVS info:   $Id: zmapApp_P.h,v 1.26 2008-12-19 10:00:04 edgrif Exp $
+ * CVS info:   $Id: zmapApp_P.h,v 1.27 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef ZMAP_APP_PRIV_H
@@ -101,6 +101,11 @@ typedef struct _ZMapAppContextStruct
 
   char *locale;
   gboolean sent_finalised ;
+  
+  char *script_dir;		/* where scripts are kept for the pipeServer module
+  					 * can be set in [ZMap] or defaults to run-time directory
+  					 */
+  
 } ZMapAppContextStruct, *ZMapAppContext ;
 
 
diff --git a/src/zmapServer/pipe/pipeServer.c b/src/zmapServer/pipe/pipeServer.c
index 552bcdb81..81307a24c 100755
--- a/src/zmapServer/pipe/pipeServer.c
+++ b/src/zmapServer/pipe/pipeServer.c
@@ -1,6 +1,6 @@
 /*  File: pipeServer.c
  *  Author: Malcolm Hinsley (mh17@sanger.ac.uk)
- *      derived from pipeServer.c by Ed Griffiths (edgrif@sanger.ac.uk)
+ *      derived from fileServer.c by Ed Griffiths (edgrif@sanger.ac.uk)
  *  Copyright (c) 2009: Genome Research Ltd.
  *-------------------------------------------------------------------
  * ZMap is free software; you can redistribute it and/or
@@ -34,7 +34,7 @@
  * HISTORY:
  * Last edited: Nov 30 09:18 2009 (edgrif)
  * Created: 2009-11-26 12:02:40 (mh17)
- * CVS info:   $Id: pipeServer.c,v 1.3 2009-11-30 10:50:01 edgrif Exp $
+ * CVS info:   $Id: pipeServer.c,v 1.4 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -51,7 +51,7 @@
 #include <ZMap/zmapGFF.h>
 #include <zmapServerPrototype.h>
 #include <pipeServer_P.h>
-
+#include <ZMap/zmapConfigLoader.h>
 
 /* Used to control getting features in all alignments in all blocks... */
 typedef struct
@@ -70,6 +70,7 @@ static gboolean createConnection(void **server_out,
 				 ZMapURL url, char *format, 
                                  char *version_str, int timeout) ;
 
+static gboolean pipe_server_spawn(PipeServer server,GError **error);
 static ZMapServerResponseType openConnection(void *server) ;
 static ZMapServerResponseType getInfo(void *server, ZMapServerInfo info) ;
 static ZMapServerResponseType getFeatureSetNames(void *server,
@@ -142,9 +143,37 @@ static gboolean globalInit(void)
 }
 
 
-/* spawn a new process to run our script ans open a pipe for read to get the output
- *
- *
+
+/* Read ZMap application defaults. */
+static gboolean getConfiguration(PipeServer server)
+{
+  gboolean result = FALSE ;
+  ZMapConfigIniContext context;
+
+  if((context = zMapConfigIniContextProvide()))
+    {
+      char *tmp_string  = NULL;
+
+      /* script directory to use */
+      if(zMapConfigIniContextGetString(context, ZMAPSTANZA_APP_CONFIG, ZMAPSTANZA_APP_CONFIG, 
+				       ZMAPSTANZA_APP_SCRIPTS, &tmp_string))
+	{
+	  server->script_dir = tmp_string;
+        result = TRUE;
+	}
+      zMapConfigIniContextDestroy(context);
+    }
+  if(!result)
+    server->script_dir = g_get_current_dir();
+  return result ;
+}
+
+
+
+/* spawn a new process to run our script and open a pipe for read to get the output
+ * global config of the default scripts directory is via '[ZMap] scripts-dir=there'
+ * to get absolute path you need 4 slashes eg for pipe://<host>/<path>
+ * where <host> is null and <path> begins with a /
  * For now we will assume that "host" contains the script name and then we just ignore the other
  * parameters....
  * 
@@ -162,18 +191,19 @@ static gboolean createConnection(void **server_out,
   server = (PipeServer)g_new0(PipeServerStruct, 1) ;
   *server_out = (void *)server ;
 
+  getConfiguration(server);	// get scripts directory
 
   /* We could check both format and version here if we wanted to..... */
 
 
   /* This code is a hack to get round the fact that the url code we use in zmapView.c to parse
-   * urls from our config firle will chop the leading "/" off the path....which causes the
+   * urls from our config file will chop the leading "/" off the path....which causes the
    * zMapGetPath() call below to construct an incorrect path.... */
   {
     char *tmp_path = url->path ;
 
     if (*(url->path) != '/')
-      tmp_path = g_strdup_printf("/%s", url->path) ;
+      tmp_path = g_strdup_printf("%s/%s", server->script_dir,url->path) ;
 
     server->script_path = zMapGetPath(tmp_path) ;
 
@@ -181,11 +211,50 @@ static gboolean createConnection(void **server_out,
       g_free(tmp_path) ;
   }
 
+  server->query = url->query;
 
   return result ;
 }
 
 
+
+
+/* 
+ * fork and exec the script and read teh output via a pipe
+ * no data sent to STDIN and STDERR ignored
+ * in case of errors or hangups eevntually we will time out and an error popped up.
+ * downside is limited to not having the data, whcih is what happens anyway
+ */
+static gboolean pipe_server_spawn(PipeServer server,GError **error)
+{
+  gboolean result = FALSE;
+  gchar **argv;
+  gint pipe_fd;
+  GError *pipe_error = NULL;;
+
+  argv = (gchar **) g_malloc (sizeof(gchar *) * (PIPE_MAX_ARGS + 4));
+    /* initially we have one arg which is the query string
+     * but implement flexible arg handling anyway
+     */
+
+  argv[0] = server->script_path; // scripts can get exec'd, as long as they start w/ #!
+  argv[1] = server->query;       // may be NULL
+  argv[2]= NULL;
+
+  result = g_spawn_async_with_pipes(server->script_dir,argv,NULL,G_SPAWN_STDERR_TO_DEV_NULL,
+                                    NULL,NULL,&server->child_pid,NULL,&pipe_fd,NULL,&pipe_error);
+  if(result)
+  {
+    server->gff_pipe = g_io_channel_unix_new(pipe_fd);
+  }
+
+  g_free(argv);
+  if(error)
+    *error = pipe_error;
+  return(result);
+}
+
+
 static ZMapServerResponseType openConnection(void *server_in)
 {
   ZMapServerResponseType result = ZMAP_SERVERRESPONSE_REQFAIL ;
@@ -200,19 +269,17 @@ static ZMapServerResponseType openConnection(void *server_in)
     {
       GError *gff_pipe_err = NULL ;
 
-      if ((server->gff_pipe = g_io_channel_new_file(server->script_path, "r", &gff_pipe_err)))
-	{
-	  result = ZMAP_SERVERRESPONSE_OK ;
-	}
-      else
-	{
-	  setLastErrorMsg(server, &gff_pipe_err) ;
-
-	  result = ZMAP_SERVERRESPONSE_REQFAIL ;
-	}
+      if(pipe_server_spawn(server,&gff_pipe_err))
+	    {
+	      result = ZMAP_SERVERRESPONSE_OK ;
+	    }
+	    else
+	    {
+	      setLastErrorMsg(server, &gff_pipe_err) ;
+	      result = ZMAP_SERVERRESPONSE_REQFAIL ;
+	    }
     }
 
-
   return result ;
 }
 
@@ -230,7 +297,7 @@ static ZMapServerResponseType getInfo(void *server_in, ZMapServerInfo info)
   else
     {
       result = ZMAP_SERVERRESPONSE_REQFAIL ;
-      ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,
+      ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,server->query,
 		     "Could not get server info because: %s", server->last_err_msg) ;
     }
 
@@ -256,7 +323,7 @@ static ZMapServerResponseType getFeatureSetNames(void *server_in,
   zMapAssert(server) ;
 
   setErrMsg(server, g_strdup("Feature Sets cannot be read from GFF stream.")) ;
-  ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,
+  ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,server->query,
 		 "%s", server->last_err_msg) ;
 
   result = ZMAP_SERVERRESPONSE_UNSUPPORTED ;
@@ -279,7 +346,7 @@ static ZMapServerResponseType getStyles(void *server_in, GData **styles_out)
   zMapAssert(server) ;
 
   setErrMsg(server, g_strdup("Reading styles from a GFF stream is not supported.")) ;
-  ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,
+  ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path, server->query,
 		 "%s", server->last_err_msg) ;
 
   result = ZMAP_SERVERRESPONSE_UNSUPPORTED ;
@@ -358,7 +425,7 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 
 
 
-  get_features.result = ZMAP_SERVERRESPONSE_OK ;
+  get_features.result = ZMAP_SERVERRESPONSE_REQFAIL ;  // to catch empty file
   get_features.server = (PipeServer)server_in ;
 
   get_features.parser = zMapGFFCreateParser() ;
@@ -376,6 +443,7 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 						 &gff_pipe_err)) == G_IO_STATUS_NORMAL)
     {
       gboolean done_header = FALSE ;
+      get_features.result = ZMAP_SERVERRESPONSE_OK;   // now we have data default is 'OK'
 
       *(get_features.gff_line->str + terminator_pos) = '\0' ; /* Remove terminating newline. */
 
@@ -399,7 +467,7 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 		  setErrMsg(server, 
 			    g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
 					    zMapGFFGetLineNumber(get_features.parser), get_features.gff_line->str)) ;
-		  ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+		  ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				 "%s", server->last_err_msg) ;
 		}
 	      else
@@ -417,7 +485,7 @@ static ZMapServerResponseType getFeatures(void *server_in, GData *styles, ZMapFe
 				g_strdup_printf("zMapGFFParseHeader() failed for line %d: %s",
 						zMapGFFGetLineNumber(get_features.parser),
 						get_features.gff_line->str)) ;
-		      ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+		      ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				     "%s", server->last_err_msg) ;
 		    }
 		}
@@ -479,8 +547,8 @@ static void eachBlockSequence(gpointer key, gpointer data, gpointer user_data)
 	  setErrMsg(get_features->server,
 		    g_strdup_printf("zMapGFFGetSequence() failed, error=%s",
 				    error->message));
-	  ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, 
-			 get_features->server->script_path,
+	  ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, 
+			 get_features->server->script_path,get_features->server->query,
 			 "%s", get_features->server->last_err_msg);
 	}
       else
@@ -593,7 +661,7 @@ static ZMapServerResponseType getContextSequence(void *server_in, GData *styles,
 		  setErrMsg(server, 
 			    g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
 					    zMapGFFGetLineNumber(get_features.parser), get_features.gff_line->str)) ;
-		  ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+		  ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				 "%s", server->last_err_msg) ;
 		}
 	      else
@@ -604,7 +672,7 @@ static ZMapServerResponseType getContextSequence(void *server_in, GData *styles,
 		    {
 		      get_features.result = ZMAP_SERVERRESPONSE_REQFAIL ;
 		      setErrMsg(server, g_strdup_printf("GFFTerminated! %s", error->message)) ;
-		      ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+		      ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				     "%s", server->last_err_msg) ;		    }
 		  else
 		    {
@@ -612,7 +680,7 @@ static ZMapServerResponseType getContextSequence(void *server_in, GData *styles,
 				g_strdup_printf("zMapGFFParseHeader() failed for line %d: %s",
 						zMapGFFGetLineNumber(get_features.parser),
 						get_features.gff_line->str)) ;
-		      ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+		      ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				     "%s", server->last_err_msg) ;
 		    }
 		}
@@ -663,6 +731,9 @@ static ZMapServerResponseType closeConnection(void *server_in)
   PipeServer server = (PipeServer)server_in ;
   GError *gff_pipe_err = NULL ;
 
+  if(server->child_pid)
+    g_spawn_close_pid(server->child_pid);
+
   if (server->gff_pipe && g_io_channel_shutdown(server->gff_pipe, FALSE, &gff_pipe_err) != G_IO_STATUS_NORMAL)
     {
       zMapLogCritical("Could not close feature pipe \"%s\"", server->script_path) ;
@@ -784,7 +855,8 @@ static void eachBlock(gpointer key, gpointer data, gpointer user_data)
       if (!sequenceRequest(get_features->server, get_features->parser,
 			   get_features->gff_line, feature_block))
 	{
-	  ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, get_features->server->script_path,
+	  ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, get_features->server->script_path,
+                  get_features->server->query,
 			 "Could not map %s because: %s",
 			 g_quark_to_string(get_features->server->req_context->sequence_name),
 			 get_features->server->last_err_msg) ;
@@ -833,7 +905,7 @@ static gboolean sequenceRequest(PipeServer server, ZMapGFFParser parser, GString
 	      server->last_err_msg =
 		g_strdup_printf("zMapGFFParseLine() failed with no GError for line %d: %s",
 				zMapGFFGetLineNumber(parser), gff_line->str) ;
-	      ZMAPSERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,
+	      ZMAPPIPESERVER_LOG(Critical, PIPE_PROTOCOL_STR, server->script_path,server->query,
 			     "%s", server->last_err_msg) ;
 
 	      result = FALSE ;
@@ -849,7 +921,7 @@ static gboolean sequenceRequest(PipeServer server, ZMapGFFParser parser, GString
 		}
 	      else
 		{
-		  ZMAPSERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,
+		  ZMAPPIPESERVER_LOG(Warning, PIPE_PROTOCOL_STR, server->script_path,server->query,
 				 "%s", error->message) ;
 		}
 	    }
diff --git a/src/zmapServer/pipe/pipeServer_P.h b/src/zmapServer/pipe/pipeServer_P.h
index 36075c415..9360665f6 100755
--- a/src/zmapServer/pipe/pipeServer_P.h
+++ b/src/zmapServer/pipe/pipeServer_P.h
@@ -28,7 +28,7 @@
  *              
  * HISTORY:
  * Created: Thu Nov 26 10:30:21 2009 (mh17)
- * CVS info:   $Id: pipeServer_P.h,v 1.1 2009-11-26 12:18:47 mh17 Exp $
+ * CVS info:   $Id: pipeServer_P.h,v 1.2 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef PIPE_SERVER_P_H
@@ -37,14 +37,20 @@
 
 #define PIPE_PROTOCOL_STR "GFF Pipe"			    /* For error messages. */
 
+#define PIPE_MAX_ARGS	2	// extra args we add on to the query
+#define PIPE_ARG_ZMAP_START	"zmap_start"
+#define PIPE_ARG_ZMAP_END	"zmap_end"
 
 
 
 /* Holds all the state we need to create and access the script output. */
 typedef struct _PipeServerStruct
 {
-  gchar *script_path ;		// where our configured script is
-  GIOChannel* gff_pipe ;	// the pipe we read the script's output from
+  gchar *script_dir;		// default location for relative paths
+  gchar *script_path ;	// where our configured script is, includign script-dir
+  gchar *query;		    	// from query string
+  GIOChannel *gff_pipe ;// the pipe we read the script's output from
+  GPid child_pid;
 
   char *styles_file ;
 
diff --git a/src/zmapServer/zmapServerProtocolHandler.c b/src/zmapServer/zmapServerProtocolHandler.c
index 34ef84d98..787d1a264 100755
--- a/src/zmapServer/zmapServerProtocolHandler.c
+++ b/src/zmapServer/zmapServerProtocolHandler.c
@@ -27,7 +27,7 @@
  * HISTORY:
  * Last edited: Nov 26 08:26 2009 (edgrif)
  * Created: Thu Jan 27 13:17:43 2005 (edgrif)
- * CVS info:   $Id: zmapServerProtocolHandler.c,v 1.47 2009-11-30 10:52:50 edgrif Exp $
+ * CVS info:   $Id: zmapServerProtocolHandler.c,v 1.48 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -314,7 +314,6 @@ ZMapThreadReturnCode zMapServerRequestHandler(void **slave_data,
   ZMapServer server = NULL ;
   void *global_init_data ;
 
-
   /* Slightly opaque here, if *slave_data is NULL this implies that we are not set up yet
    * so the request should be to start a connection and we should have been passed in
    * a load of connection stuff.... */
@@ -501,7 +500,6 @@ ZMapThreadReturnCode zMapServerRequestHandler(void **slave_data,
       break ;
     }
 
-
   /* Return server. */
   *slave_data = (void *)server ;
 
diff --git a/src/zmapServer/zmapServerPrototype.h b/src/zmapServer/zmapServerPrototype.h
index f1c194218..9ab8e4189 100755
--- a/src/zmapServer/zmapServerPrototype.h
+++ b/src/zmapServer/zmapServerPrototype.h
@@ -30,7 +30,7 @@
  * HISTORY:
  * Last edited: Oct  2 08:09 2009 (edgrif)
  * Created: Wed Aug  6 15:48:47 2003 (edgrif)
- * CVS info:   $Id: zmapServerPrototype.h,v 1.29 2009-11-26 15:40:18 mh17 Exp $
+ * CVS info:   $Id: zmapServerPrototype.h,v 1.30 2009-12-03 15:03:08 mh17 Exp $
  *-------------------------------------------------------------------
  */
 #ifndef ZMAP_SERVER_PROTOTYPEP_H
@@ -130,11 +130,15 @@ void pipeGetServerFuncs(ZMapServerFuncs pipe_funcs) ;
 
 /* Try to give consistent messages/logging.... */
 #define ZMAP_SERVER_MSGPREFIX "Server %s:%s - "
+#define ZMAP_PIPESERVER_MSGPREFIX "Server %s:%s(%s) - "
 
 /* LOGTYPE just be one of the zMapLogXXXX types, i.e. Message, Warning, Critical or Fatal */
 #define ZMAPSERVER_LOG(LOGTYPE, PROTOCOL, HOST, FORMAT, ...) \
 zMapLog##LOGTYPE(ZMAP_SERVER_MSGPREFIX FORMAT, PROTOCOL, HOST, __VA_ARGS__)
 
+#define ZMAPPIPESERVER_LOG(LOGTYPE, PROTOCOL, HOST, ARG, FORMAT, ...) \
+zMapLog##LOGTYPE(ZMAP_PIPESERVER_MSGPREFIX FORMAT, PROTOCOL, HOST, ARG, __VA_ARGS__)
+
 
 #define ZMAPSERVER_MAKEMESSAGE(PROTOCOL, HOST, FORMAT, ...) \
 g_strdup_printf(ZMAP_SERVER_MSGPREFIX FORMAT, PROTOCOL, HOST, __VA_ARGS__)
diff --git a/src/zmapView/zmapViewUtils.c b/src/zmapView/zmapViewUtils.c
index 745ea09bb..f0051d43c 100755
--- a/src/zmapView/zmapViewUtils.c
+++ b/src/zmapView/zmapViewUtils.c
@@ -29,7 +29,7 @@
  * HISTORY:
  * Last edited: Oct  1 15:42 2009 (edgrif)
  * Created: Mon Sep 20 10:29:15 2004 (edgrif)
- * CVS info:   $Id: zmapViewUtils.c,v 1.14 2009-10-02 09:19:32 edgrif Exp $
+ * CVS info:   $Id: zmapViewUtils.c,v 1.15 2009-12-03 15:06:40 mh17 Exp $
  *-------------------------------------------------------------------
  */
 
@@ -600,6 +600,13 @@ void zmapViewSessionAddServer(ZMapViewSession session_data, ZMapURL url, char *f
 	server_data->scheme_data.acedb.database = g_strdup(url->path) ;
 	break ;
       }
+    case SCHEME_PIPE:
+      {
+	server_data->scheme_data.pipe.path = g_strdup(url->path) ;
+	server_data->scheme_data.pipe.query = g_strdup(url->query) ;
+	break ;
+      }
+    
     case SCHEME_FILE:
       {
 	server_data->scheme_data.file.path = g_strdup(url->path) ;
@@ -637,6 +644,11 @@ void zmapViewSessionAddServerInfo(ZMapViewSession session_data, char *database_p
 
 	break ;
       }
+    case SCHEME_PIPE:
+      {
+
+	break ;
+      }
     default:
       {
 
@@ -670,6 +682,12 @@ void zmapViewSessionFreeServer(gpointer data, gpointer user_data_unused)
 	g_free(server_data->scheme_data.file.path) ;
 	break ;
       }
+    case SCHEME_PIPE:
+      {
+	g_free(server_data->scheme_data.pipe.path) ;
+	g_free(server_data->scheme_data.pipe.query) ;
+	break ;
+      }
     default:
       {
 	/* no action currently. */
-- 
GitLab