Index: trunk/zoo-project/zoo-services/utils/hpc/Makefile
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/Makefile	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/Makefile	(revision 917)
@@ -0,0 +1,14 @@
+ZRPATH=../../..
+include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
+CFLAGS=-I${INST_INCLUDE} ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+
+cgi-env/wps_hpc.zo: service.c service2.c
+	g++ ${CFLAGS} -shared -fpic -o cgi-env/wps_hpc.zo service.c service2.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} ${FCGI_LDFLAGS} -L${ZRPATH}/zoo-kernel/ -lzoo_service ${ZRPATH}/zoo-kernel/sshapi.o ${HPCLDFLAGS}
+
+install:
+	install -d ${CGI_DIR}
+	install cgi-env/*.zcfg ${CGI_DIR}/
+	install cgi-env/*.zo ${CGI_DIR}/
+
+clean:
+	rm -f cgi-env/wps_hpc.zo
Index: trunk/zoo-project/zoo-services/utils/hpc/cgi-env/DeleteData.zcfg
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/cgi-env/DeleteData.zcfg	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/cgi-env/DeleteData.zcfg	(revision 917)
@@ -0,0 +1,50 @@
+[DeleteData]
+ Title = Delete the data associated with an input or an output
+ Abstract = Delete the data associated with an input or an output
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_hpc.zo
+ serviceType = C
+ <DataInputs>
+  [jobid]
+   Title = the image
+   Abstract = The image to process
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+  [filename]
+   Title = the image
+   Abstract = The image to process
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+  [ioname]
+   Title = the input / output name
+   Abstract = the input / output name
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting string
+   Abstract = The resulting message string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC.zcfg
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC.zcfg	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC.zcfg	(revision 917)
@@ -0,0 +1,30 @@
+[FinalizeHPC]
+ Title = Start phase 3 of HPC execution
+ Abstract = Unblock the ZOO-Kernel awaiting for a remote job execution 
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_hpc.zo
+ serviceType = C
+ <DataInputs>
+  [JobId]
+   Title = the image
+   Abstract = The image to process
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The hello string
+   Abstract = The Hello message string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC1.zcfg
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC1.zcfg	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/cgi-env/FinalizeHPC1.zcfg	(revision 917)
@@ -0,0 +1,30 @@
+[FinalizeHPC1]
+ Title = Start phase 3 of HPC execution
+ Abstract = Unblock the ZOO-Kernel awaiting for a remote job execution 
+ processVersion = 1
+ storeSupported = true
+ statusSupported = true
+ serviceProvider = wps_hpc.zo
+ serviceType = C
+ <DataInputs>
+  [JobId]
+   Title = the image
+   Abstract = The image to process
+   minOccurs = 1
+   maxOccurs = 1
+   <LiteralData>
+    dataType = string
+    <Default>
+    </Default>
+   </LiteralData>
+ </DataInputs>
+ <DataOutputs>
+  [Result]
+   Title = The resulting string
+   Abstract = The message returned by the service execution as a string.
+   <LiteralOutput>
+    DataType = string
+    <Default>
+    </Default>
+   </LiteralOutput>
+ </DataOutputs>  
Index: trunk/zoo-project/zoo-services/utils/hpc/service.c
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/service.c	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/service.c	(revision 917)
@@ -0,0 +1,363 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2017 GeoLabs SARL. All rights reserved.
+ *
+ * This work was supported by public funds received in the framework of GEOSUD,
+ * a project (ANR-10-EQPX-20) of the program "Investissements d'Avenir" managed
+ * by the French National Research Agency
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "service.h"
+#include "service_internal.h"
+#include "sshapi.h"
+#include "server_internal.h"
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+
+#include <dirent.h>
+extern "C" {
+
+  /**
+   * FinalizeHPC ZOO Service :
+   * This service is used to inform a ZOO-Kernel waiting for the end of the
+   * execution of a HPC service
+   */
+  ZOO_DLL_EXPORT int FinalizeHPC(maps*& conf,maps*& inputs,maps*& outputs){
+    // Retrieve the jobid corresponding to the identifier generated by SLURM
+    // by reading the file generated when running the SBATCH file
+    map* jobid=getMapFromMaps(inputs,"jobid","value");
+    struct sockaddr_un addr;
+    char buf[100]="3";
+    int fd,rc=NULL;
+    int i=0;
+    map* usid=getMapFromMaps(conf,"lenv","usid");
+    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
+
+    char *flenv =
+      (char *) malloc ((strlen (tmpPath->value) + 
+			strlen (jobid->value) + 12) * sizeof (char));
+    sprintf (flenv, "%s/%s_lenv.cfg", tmpPath->value, jobid->value);
+    maps* m = (maps *) malloc (MAPS_SIZE);
+    m->child=NULL;
+    m->next=NULL;
+    map* configId=NULL;
+
+    
+    if(conf_read(flenv, m) != 2){
+      configId=getMapFromMaps(m,"lenv","configId");
+      setMapInMaps(conf,"lenv","configId",configId->value);
+    }else{
+      setMapInMaps(conf,"lenv","message",_("Unable to read the lenv section file of the requested jobid"));
+      return SERVICE_FAILED;
+    }
+    
+    SSHCON *test=ssh_connect(conf);
+    /*if(test==NULL){
+      setMapInMaps(conf,"lenv","message",_("Unable to connect using ssh."));
+      return SERVICE_FAILED;
+      }*/
+
+    char *logPath=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+12)*sizeof(char));
+    sprintf(logPath,"%s/exec_out_%s",tmpPath->value,jobid->value);
+    struct stat f_status;
+    int ts=stat(logPath, &f_status);
+    char* fcontent = NULL;
+    if(ts==0) {
+      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+      FILE* f=fopen(logPath,"rb");
+      fread(fcontent,f_status.st_size,1,f);
+      int fsize=f_status.st_size;
+      fcontent[fsize]=0;
+      fclose(f);
+    }else{
+      setMapInMaps(conf,"lenv","message",_("No service with this jobid can be found"));
+      return SERVICE_FAILED;
+    }
+    free(logPath);
+    // Run scontrol to check if the service execution ended.
+    // Store all the informations returned by scontrol command as a cfg file to
+    // be parsed back by the ZOO-Kernel waiting for the execution of the remote
+    // service
+    maps* tmpMaps=createMaps("henv");
+    char* command=(char*)malloc((126)*sizeof(char));
+    sprintf(command,"scontrol show jobid | grep -A24 JobId=%s",fcontent);    
+    if(ssh_exec(conf,command,ssh_get_cnt(conf))==0){
+      free(command);
+      setMapInMaps(conf,"lenv","message",_("Failed to run scontrol remotely"));
+      // TODO: check status in db and if available continue in other case return SERVICE_FAILED
+      return SERVICE_FAILED;
+    }else{
+      free(command);
+      logPath=(char*)malloc((strlen(tmpPath->value)+strlen(usid->value)+11)*sizeof(char));
+      sprintf(logPath,"%s/exec_out_%s",tmpPath->value,usid->value);
+      int ts=stat(logPath, &f_status);
+      if(ts==0) {
+	fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+	FILE* f=fopen(logPath,"rb");
+	fread(fcontent,f_status.st_size,1,f);
+	int fsize=f_status.st_size;
+	fcontent[fsize]=0;
+	fclose(f);
+	free(logPath);
+	char *token, *saveptr;
+	token = strtok_r (fcontent, " ", &saveptr);
+	while (token != NULL)
+	  {
+	    char *token1, *saveptr1;
+	    char *tmpToken=strdup(token);
+	    token1 = strtok_r (tmpToken, "=", &saveptr1);
+	    int isNext=-1;
+	    int hasTwoElements=0;
+	    char *name=NULL;
+	    while (token1 != NULL)
+	      {
+		if(hasTwoElements==0)
+		  name=strdup(token1);
+		if(hasTwoElements<1)
+		  hasTwoElements+=1;
+		else{
+		  char *value=strdup(token1);
+		  if(value[strlen(value)-1]=='\n')
+		    value[strlen(value)-1]=0;
+		  if(strlen(name)>0 && strlen(value)>0){
+		    if(tmpMaps->content==NULL)
+		      tmpMaps->content=createMap(name,value);
+		    else
+		      addToMap(tmpMaps->content,name,value);
+		    free(value);
+		  }
+		  free(name);
+		  hasTwoElements=0;
+		}
+		token1 = strtok_r (NULL, "=", &saveptr1);
+	      }
+	    free(tmpToken);
+	    token = strtok_r (NULL, " ", &saveptr);
+	  }
+      }else{
+	setMapInMaps(conf,"lenv","message",_("Unable to access the downloaded execution log file"));
+	return SERVICE_FAILED;
+      }
+    }
+    logPath=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+15)*sizeof(char));
+    sprintf(logPath,"%s/exec_status_%s",tmpPath->value,jobid->value);
+    dumpMapsToFile(tmpMaps,logPath,0);
+    char *sname=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+21));
+    sprintf(sname,"%s/.wait_socket_%s.sock",tmpPath->value,jobid->value);
+    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+      perror("socket error");
+      setMapInMaps(conf,"lenv","message",_("Socket error"));
+      return SERVICE_FAILED;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, sname, sizeof(addr.sun_path)-1);
+    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
+      perror("connect error");
+      setMapInMaps(conf,"lenv","message",_("Unable to connect"));
+      return SERVICE_FAILED;
+    }
+    if (write(fd, "3", 1) != rc) {
+      if (rc < 0) {
+	perror("write error");
+	setMapInMaps(conf,"lenv","message",_("Unable to announce the successful execution of the HPC service"));
+	close(fd);
+	return SERVICE_FAILED;
+      }
+    }
+    close(fd);
+    setOutputValue(outputs,"Result",(char*)"\"FinalizeHPC run successfully\"",32);
+    unlink(flenv);
+    free(flenv);
+
+    return SERVICE_SUCCEEDED;
+  }
+
+
+  /**
+   * FinalizeHPC1 ZOO Service :
+   * This service is used to inform a ZOO-Kernel waiting for the end of the
+   * execution of a HPC service
+   *
+   * format="AllocCPUS"; for i in $(sacct -e) ; do format="$format,$i"; done; format="$(echo $format | sed "s:AllocCPUS,::")" ; echo $format; sacct --format=$format -p | grep "997f-11e8-9f78-0050569320d2" 
+   *
+   * AllocCPUS,AllocGRES,AllocNodes,AllocTRES,Account,AssocID,AveCPU,AveCPUFreq,AveDiskRead,AveDiskWrite,AvePages,AveRSS,AveVMSize,BlockID,Cluster,Comment,ConsumedEnergy,ConsumedEnergyRaw,CPUTime,CPUTimeRAW,DerivedExitCode,Elapsed,Eligible,End,ExitCode,GID,Group,JobID,JobIDRaw,JobName,Layout,MaxDiskRead,MaxDiskReadNode,MaxDiskReadTask,MaxDiskWrite,MaxDiskWriteNode,MaxDiskWriteTask,MaxPages,MaxPagesNode,MaxPagesTask,MaxRSS,MaxRSSNode,MaxRSSTask,MaxVMSize,MaxVMSizeNode,MaxVMSizeTask,MinCPU,MinCPUNode,MinCPUTask,NCPUS,NNodes,NodeList,NTasks,Priority,Partition,QOS,QOSRAW,ReqCPUFreq,ReqCPUFreqMin,ReqCPUFreqMax,ReqCPUFreqGov,ReqCPUS,ReqGRES,ReqMem,ReqNodes,ReqTRES,Reservation,ReservationId,Reserved,ResvCPU,ResvCPURAW,Start,State,Submit,Suspended,SystemCPU,Timelimit,TotalCPU,UID,User,UserCPU,WCKey,WCKeyID
+   * 28||1|cpu=28,node=1|geosud|258|||||||||cluster||||00:00:56|56|0:0|00:00:02|2018-08-06T15:48:13|2018-08-06T15:48:16|0:0|1019|geosud|883299|883299|ZOO-Project_5bd1c32b-997f-11e8-9f78-0050569320d2_GSDBandMath_6_2_005||||||||||||||||||||28|1|muse044||4294360886|defq|qos_geosud|20|Unknown|Unknown|Unknown|Unknown|1||0n|1|cpu=1,node=1|||00:00:01|00:00:01|1|2018-08-06T15:48:14|COMPLETED|2018-08-06T15:48:13|00:00:00||UNLIMITED|00:00:00|1229|geosudwps|||0|
+   * 
+   */
+  ZOO_DLL_EXPORT int FinalizeHPC1(maps*& conf,maps*& inputs,maps*& outputs){
+    // Retrieve the jobid corresponding to the identifier generated by SLURM
+    // by reading the file generated when running the SBATCH file
+    map* jobid=getMapFromMaps(inputs,"jobid","value");
+    struct sockaddr_un addr;
+    char buf[100]="3";
+    int fd,rc=NULL;
+    int i=0;
+    map* usid=getMapFromMaps(conf,"lenv","usid");
+    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
+
+    char *flenv =
+      (char *) malloc ((strlen (tmpPath->value) + 
+			strlen (jobid->value) + 12) * sizeof (char));
+    sprintf (flenv, "%s/%s_lenv.cfg", tmpPath->value, jobid->value);
+    maps* m = (maps *) malloc (MAPS_SIZE);
+    m->child=NULL;
+    m->next=NULL;
+    map* configId=NULL;
+
+    
+    if(conf_read(flenv, m) != 2){
+      configId=getMapFromMaps(m,"lenv","configId");
+      setMapInMaps(conf,"lenv","configId",configId->value);
+    }else{
+      setMapInMaps(conf,"lenv","message",_("Unable to read the lenv section file of the requested jobid"));
+      return SERVICE_FAILED;
+    }
+
+    SSHCON *test=ssh_connect(conf);
+    /*if(test==NULL){
+      setMapInMaps(conf,"lenv","message",_("Unable to connect using ssh."));
+      return SERVICE_FAILED;
+      }*/
+
+    char *logPath=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+12)*sizeof(char));
+    sprintf(logPath,"%s/exec_out_%s",tmpPath->value,jobid->value);
+    struct stat f_status;
+    int ts=stat(logPath, &f_status);
+    char* fcontent = NULL;
+    if(ts==0) {
+      fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+      FILE* f=fopen(logPath,"rb");
+      fread(fcontent,f_status.st_size,1,f);
+      int fsize=f_status.st_size;
+      fcontent[fsize]=0;
+      fclose(f);
+    }else{
+      setMapInMaps(conf,"lenv","message",_("No service with this jobid can be found"));
+      return SERVICE_FAILED;
+    }
+    free(logPath);
+    // Run sacct to check if the service execution ended.
+    // Store all the informations returned by scontrol command as a cfg file to
+    // be parsed back by the ZOO-Kernel waiting for the execution of the remote
+    // service
+    maps* tmpMaps=createMaps("henv");
+    
+    map* tmpMap=getMapFromMaps(conf,configId->value,"remote_command_opt");
+    char* command=(char*)malloc((126+strlen(tmpMap->value))*sizeof(char));
+    sprintf(command,"sacct --format=%s -p | grep \"%s\" | sed \"s:||:|None|:g;s:||:|None|:g\"",tmpMap->value,jobid->value);    
+    if(ssh_exec(conf,command,ssh_get_cnt(conf))==0){
+      free(command);
+      setMapInMaps(conf,"lenv","message",_("Failed to run sacct remotely"));
+      // TODO: check status in db and if available continue in other case return SERVICE_FAILED
+      return SERVICE_FAILED;
+    }else{
+      free(command);
+      logPath=(char*)malloc((strlen(tmpPath->value)+strlen(usid->value)+11)*sizeof(char));
+      sprintf(logPath,"%s/exec_out_%s",tmpPath->value,usid->value);
+      int ts=stat(logPath, &f_status);
+      if(ts==0) {
+	fcontent=(char*)malloc(sizeof(char)*(f_status.st_size+1));
+	FILE* f=fopen(logPath,"rb");
+	fread(fcontent,f_status.st_size,1,f);
+	int fsize=f_status.st_size;
+	fcontent[fsize]=0;
+	fclose(f);
+	free(logPath);
+	char *token, *saveptr;
+	char *token1, *saveptr1;
+	token = strtok_r (tmpMap->value, ",", &saveptr);
+	token1 = strtok_r (fcontent, "|", &saveptr1);
+	while (token != NULL) {
+	  fprintf(stderr,"%s %d %s \n",__FILE__,__LINE__,token);
+	  fflush(stderr);
+	  fprintf(stderr,"%s %d %s %s \n",__FILE__,__LINE__,token,token1);
+	  fflush(stderr);
+	  if(token1 != NULL){
+	    if(tmpMaps->content==NULL)
+	      tmpMaps->content=createMap(token,token1);
+	    else
+	      addToMap(tmpMaps->content,token,token1);
+	  }
+	  token = strtok_r (NULL, ",", &saveptr);
+	  token1 = strtok_r (NULL, "|", &saveptr1);
+	}
+      }else{
+	free(logPath);
+	setMapInMaps(conf,"lenv","message",_("Unable to access the downloaded execution log file"));
+	return SERVICE_FAILED;
+      }
+    }
+    tmpMap=getMapFromMaps(tmpMaps,"henv","JobId");
+    if(tmpMap!=NULL){
+      char* tmpStr=(char*)malloc((32)*sizeof(char));
+      sprintf(tmpStr,"slurm-%s.out",tmpMap->value);
+      addToMap(tmpMaps->content,"StdErr",tmpStr); 
+      free(tmpStr);
+    }
+    logPath=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+15)*sizeof(char));
+    sprintf(logPath,"%s/exec_status_%s",tmpPath->value,jobid->value);
+    dumpMapsToFile(tmpMaps,logPath,0);
+    char *sname=(char*)malloc((strlen(tmpPath->value)+strlen(jobid->value)+21));
+    sprintf(sname,"%s/.wait_socket_%s.sock",tmpPath->value,jobid->value);
+    if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+      perror("socket error");
+      setMapInMaps(conf,"lenv","message",_("Socket error"));
+      return SERVICE_FAILED;
+    }
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, sname, sizeof(addr.sun_path)-1);
+    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
+      perror("connect error");
+      setMapInMaps(conf,"lenv","message",_("Unable to connect"));
+      return SERVICE_FAILED;
+    }
+    if (write(fd, "3", 1) != rc) {
+      if (rc < 0) {
+	perror("write error");
+	setMapInMaps(conf,"lenv","message",_("Unable to announce the successful execution of the HPC service"));
+	close(fd);
+	return SERVICE_FAILED;
+      }
+    }
+    close(fd);
+    unlink(flenv);
+    free(flenv);
+    setOutputValue(outputs,"Result",(char*)"\"FinalizeHPC run successfully\"",32);
+
+    return SERVICE_SUCCEEDED;
+  }
+  
+}
Index: trunk/zoo-project/zoo-services/utils/hpc/service2.c
===================================================================
--- trunk/zoo-project/zoo-services/utils/hpc/service2.c	(revision 917)
+++ trunk/zoo-project/zoo-services/utils/hpc/service2.c	(revision 917)
@@ -0,0 +1,270 @@
+/**
+ * Author : Gérald FENOY
+ *
+ * Copyright 2017 GeoLabs SARL. All rights reserved.
+ *
+ * This work was supported by public funds received in the framework of GEOSUD,
+ * a project (ANR-10-EQPX-20) of the program "Investissements d'Avenir" managed
+ * by the French National Research Agency
+ *
+ * This work was supported by public funds received in the framework of GEOSUD,
+ * a project (ANR-10-EQPX-20) of the program "Investissements d'Avenir" managed
+ * by the French National Research Agency
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "service.h"
+#include "service_internal.h"
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
+
+#include <dirent.h>
+#include <string.h>
+#include <cerrno>
+
+extern "C" {
+
+  /** 
+   * Retrieve the error message which occured when trying to remove a file
+   * (return values can be EACCES, EBUSY, EFAULT, EIO, EISDIR, ELOOP, 
+   * ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EPERM, EROFS, UNKNOWN).
+   *
+   * @param errn
+   * @result a string corresponding to the error number 
+   */ 
+  char* fetchErrno(int errn){
+   switch(errn){
+    case EACCES:
+	return "EACCES";
+    case EBUSY:
+	return "EBUSY";
+    case EFAULT:
+	return "EFAULT";
+    case EIO:
+	return "EIO";
+    case EISDIR:
+	return "EISDIR";
+    case ELOOP:
+	return "ELOOP";
+    case ENAMETOOLONG:
+	return "ENAMETOOLONG";
+    case ENOENT:
+	return "ENOENT";
+    case ENOMEM:
+	return "ENOMEM";
+    case ENOTDIR:
+	return "ENOTDIR";
+    case EPERM:
+	return "EPERM";
+    case EROFS:
+	return "EROFS";
+    default:
+	return "UNKNOWN";
+   }
+  }
+
+  /**
+   * Try to delete a cache file.
+   * 
+   * @param storage the full path to store the file
+   * @param filename the filename to store
+   * @param ext the extention of the file
+   * @return 0 in case of success
+   */
+  int tryDeleteCacheFile(const char* storage,const char* filename,const char* ext){
+    char *filename_noext=(char*)malloc((strlen(filename)-3)*sizeof(char));
+    snprintf(filename_noext,strlen(filename)-4,"%s",filename);
+    char* filename_full=(char*)malloc((strlen(filename)+1)*sizeof(char));
+    sprintf(filename_full,"%s.%s",filename_noext,ext);
+    char* fullpath=(char*)malloc((strlen(storage)+strlen(filename_full)+2)*sizeof(char));
+    sprintf(fullpath,"%s/%s",storage,filename_full);
+    if(unlink(fullpath)==0){
+      // TODO store the filename_full in the deletedfiles
+      fprintf(stderr,"#### DeleteData #### %s %d %s has been successfully deleted\n",__FILE__,__LINE__,filename_full);
+    }else{
+      fprintf(stderr,"#### DeleteData #### unable to delete %s \n",fullpath);
+    }
+    free(fullpath);
+    free(filename_full);
+    return 0;
+  }  
+
+  /**
+   * Try to delete a data file.
+   * 
+   * @param storage the full path to store the file
+   * @param filename the filename to store
+   * @return 0 in case of success
+   */
+  int tryDeleteDataFile(const char* storage,const char* filename){
+    char* fullpath=NULL;
+    if(filename!=NULL){
+      fullpath=(char*)malloc((strlen(storage)+strlen(filename)+2)*sizeof(char));
+      sprintf(fullpath,"%s/%s",storage,filename);
+    }
+    else
+      fullpath=zStrdup(storage);
+    if(unlink(fullpath)==0){
+      // TODO store the filename_full in the deletedfiles
+      fprintf(stderr,"#### DeleteData #### %s %d %s has been successfully deleted\n",__FILE__,__LINE__,(filename!=NULL && strlen(filename)>0?filename:fullpath));
+    }else{
+      fprintf(stderr,"#### DeleteData #### unable to delete %s %s \n",fullpath,fetchErrno(errno));
+    }
+    free(fullpath);
+    return 0;
+  }  
+  
+  
+  /**
+   * DeleteData ZOO-Service :
+   * This service is used in the ZOO-Project to delete the data file
+   * associated with input or output.
+   */
+  ZOO_DLL_EXPORT int DeleteData(maps*& conf,maps*& inputs,maps*& outputs){
+    map* dataPath=getMapFromMaps(conf,"main","dataPath");
+    map* tmpPath=getMapFromMaps(conf,"main","tmpPath");
+    map* cacheDir=getMapFromMaps(conf,"main","cacheDir");
+    map* jobid=getMapFromMaps(inputs,"jobid","value");
+    map* filename=getMapFromMaps(inputs,"filename","value");
+    map* ioname=getMapFromMaps(inputs,"ioname","value");
+    char tmp0[4];
+    sprintf(tmp0,"%c%c%c",filename->value[strlen(filename->value)-3],filename->value[strlen(filename->value)-2],filename->value[strlen(filename->value)-1]);
+    char *cfilename=NULL;
+    if(strcasecmp(tmp0,"zca")==0){
+      cfilename=(char*) malloc((strlen(filename->value)+strlen(cacheDir->value)+2)*sizeof(char));
+      sprintf(cfilename,"%s/%s",cacheDir->value,filename->value);
+    }
+    else{
+      cfilename=(char*) malloc((strlen(filename->value)+strlen(tmpPath->value)+2)*sizeof(char));
+      sprintf(cfilename,"%s/%s",tmpPath->value,filename->value);
+    }
+    zooLock* lck=lockFile(conf,cfilename,'w');
+    char** deletedfiles;
+    if(lck!=NULL){
+      if(strcasecmp(tmp0,"zca")==0){
+	// Read the zcp file to verify if it comes from a shared source
+	char *filename_noext=(char*)malloc((strlen(filename->value)-3)*sizeof(char));
+	snprintf(filename_noext,strlen(filename->value)-4,"%s",filename->value);
+	char* filename_full=(char*)malloc((strlen(filename->value)+1)*sizeof(char));
+	sprintf(filename_full,"%s.zcp",filename_noext);
+	char* fullpath=(char*)malloc((strlen(cacheDir->value)+strlen(filename_full)+2)*sizeof(char));
+	sprintf(fullpath,"%s/%s",cacheDir->value,filename_full);
+	FILE* f0=fopen(fullpath,"rb");
+	char *fcontent=NULL;
+	if(f0!=NULL){
+	  long flen;
+	  fseek (f0, 0, SEEK_END);
+	  flen = ftell (f0);
+	  fseek (f0, 0, SEEK_SET);
+	  fcontent = (char *) malloc ((flen + 1) * sizeof (char));
+	  fread(fcontent,flen,1,f0);
+	  fcontent[flen]=0;
+	  fclose(f0);
+	}
+	if(fcontent!=NULL && strcasecmp(fcontent,"SHARED")!=0){
+	  // Delete associated zcm, zcp and maps files
+	  tryDeleteCacheFile(cacheDir->value,filename->value,"zca");
+	  tryDeleteCacheFile(cacheDir->value,filename->value,"zcm");
+	  tryDeleteCacheFile(cacheDir->value,filename->value,"zcp");
+	  tryDeleteCacheFile(tmpPath->value,filename->value,"maps");
+	  // Delete <input>_<sid>.map
+	  char* datafile=(char*)malloc((strlen(jobid->value)+strlen(ioname->value)+19)*sizeof(char));
+	  sprintf(datafile,"%s_%s.map",ioname->value,jobid->value);
+	  tryDeleteDataFile(dataPath->value,datafile);
+	  free(datafile);
+	}else{
+	  setMapInMaps(conf,"lenv","message",_ss("The file you try to delete is a shared ressource and cannot be deleted by nature."));
+	  unlockFile(conf,lck);
+	  return SERVICE_FAILED;
+	}
+	setMapInMaps(outputs,"Result","value",_ss("The input data has been correclty removed"));
+      }else{
+	char tmp1[8];
+	snprintf(tmp1,7,"%s",filename->value);
+	if(strcasecmp(tmp1,"output")==0 || strstr(filename->value,".zca")!=NULL || strcasecmp(tmp1,"input_")==0){
+	  tryDeleteDataFile(tmpPath->value,filename->value);
+          char *tmp=zStrdup(filename->value);
+	  tmp[strlen(tmp)-strlen(strrchr(tmp,'.'))]=0;
+	  char *mapsfile=(char*)malloc((strlen(tmp)+6)*sizeof(char));
+	  sprintf(mapsfile,"%s.maps",tmp);
+          char* mapPath=(char*)malloc((strlen(tmpPath->value)+strlen(mapsfile)+2)*sizeof(char));
+          sprintf(mapPath,"%s/%s",tmpPath->value,mapsfile);
+	  FILE* myMapsfile=fopen(mapPath,"r");
+          if(myMapsfile!=NULL){
+	    char *buffer=(char*)malloc(1024*sizeof(char));
+	    while(fgets(buffer, 1024, myMapsfile) != NULL){
+	      buffer[strlen(buffer)-1]=0;
+	      tryDeleteDataFile(buffer,NULL);
+	    }
+	    free(buffer);
+	    fclose(myMapsfile);
+          }
+          tryDeleteDataFile(mapPath,NULL);
+          free(mapPath);
+          free(mapsfile);
+	  // Delete ZOO_DATA_<output>_<sid>.data and <output>_<sid>.map
+	  char* datafile=(char*)malloc((strlen(jobid->value)+strlen(ioname->value)+19)*sizeof(char));
+	  sprintf(datafile,"ZOO_DATA_%s_%s.data",ioname->value,jobid->value);
+	  tryDeleteDataFile(dataPath->value,datafile);
+	  free(datafile);
+	  datafile=(char*)malloc((strlen(jobid->value)+strlen(ioname->value)+19)*sizeof(char));
+	  sprintf(datafile,"%s_%s.map",ioname->value,jobid->value);
+	  tryDeleteDataFile(dataPath->value,datafile);
+	  free(datafile);
+	  char* webServices[3]={"wms","wfs","wcs"};
+	  int i=0;
+	  // Delete ZOO_DATA_<ws>_link_<sid>.data and <ws>_link_<sid>.map
+	  // with <ws> is the corresponding OGC web service (wms,wfs,wcs)
+	  for(i=0;i<3;i++){
+	    datafile=(char*)malloc((strlen(jobid->value)+24)*sizeof(char));
+	    sprintf(datafile,"ZOO_DATA_%s_link_%s.data",webServices[i],jobid->value);
+	    tryDeleteDataFile(dataPath->value,datafile);
+	    free(datafile);
+	    datafile=(char*)malloc((strlen(jobid->value)+14)*sizeof(char));
+	    sprintf(datafile,"%s_link_%s.map",webServices[i],jobid->value);
+	    tryDeleteDataFile(dataPath->value,datafile);
+	    free(datafile);
+	  }
+	  setMapInMaps(outputs,"Result","value",_ss("The output data has been correclty removed"));
+	}else{
+	  setMapInMaps(conf,"lenv","message",_ss("The file you try to delete is nor an input, nor an output."));
+	  unlockFile(conf,lck);
+	  return SERVICE_FAILED;
+	}
+      }
+      unlockFile(conf,lck);
+    }
+    else{
+      setMapInMaps(conf,"lenv","message",_ss("Failed to acquire lock for deletion, please try again later."));
+      return SERVICE_FAILED;
+    }
+    return SERVICE_SUCCEEDED;
+  }
+
+}
Index: trunk/zoo-project/zoo-services/utils/registry/Makefile
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/Makefile	(revision 811)
+++ trunk/zoo-project/zoo-services/utils/registry/Makefile	(revision 917)
@@ -1,5 +1,5 @@
 ZRPATH=../../..
 include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
-CFLAGS=${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+ZCFLAGS=-I${ZRPATH}/zoo-kernel/ ${CFLAGS} ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
 
 YAML_FILES=""
@@ -16,5 +16,5 @@
 
 cgi-env/wps_registry.zo: service.c
-	g++ ${CFLAGS} -shared -fpic -o cgi-env/wps_registry.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} -lfcgi -L${ZRPATH}/zoo-kernel/ -lzoo_service ${ZRPATH}/zoo-kernel/server_internal.o ${ZRPATH}/zoo-kernel/lex.cr.o ${ZRPATH}/zoo-kernel/lex.sr.o ${ZRPATH}/zoo-kernel/service_conf.tab.o ${ZRPATH}/zoo-kernel/main_conf_read.tab.o ${ZRPATH}/zoo-kernel/response_print.o ${YAML_FILES} ${MS_FILES} ${MS_LDFLAGS} ${YAML_LDFLAGS}
+	g++ ${ZCFLAGS} -shared -fpic -o cgi-env/wps_registry.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} -lfcgi -L${ZRPATH}/zoo-kernel/ -lzoo_service ${ZRPATH}/zoo-kernel/server_internal.o ${ZRPATH}/zoo-kernel/lex.cr.o ${ZRPATH}/zoo-kernel/lex.sr.o ${ZRPATH}/zoo-kernel/service_conf.tab.o ${ZRPATH}/zoo-kernel/main_conf_read.tab.o ${ZRPATH}/zoo-kernel/response_print.o ${YAML_FILES} ${MS_FILES} ${MS_LDFLAGS} ${YAML_LDFLAGS}
 
 install:
Index: trunk/zoo-project/zoo-services/utils/registry/service.c
===================================================================
--- trunk/zoo-project/zoo-services/utils/registry/service.c	(revision 811)
+++ trunk/zoo-project/zoo-services/utils/registry/service.c	(revision 917)
@@ -80,5 +80,5 @@
 				    root_nodes[1][1],"2.0.0",1);
       setMapInMaps(conf,"main","rversion","2.0.0");
-      printDescribeProcessForProcess(zooRegistry,conf,n,inherited);
+      printDescribeProcessForProcess(zooRegistry,conf,doc,n,inherited);
       setMapInMaps(conf,"main","rversion","1.0.0");
 
Index: trunk/zoo-project/zoo-services/utils/status/Makefile
===================================================================
--- trunk/zoo-project/zoo-services/utils/status/Makefile	(revision 811)
+++ trunk/zoo-project/zoo-services/utils/status/Makefile	(revision 917)
@@ -1,8 +1,8 @@
 ZRPATH=../../..
 include ${ZRPATH}/zoo-kernel/ZOOMakefile.opts
-CFLAGS=-I${INST_INCLUDE} ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
+CFLAGS1=${CFLAGS} -I${INST_INCLUDE} ${ZOO_CFLAGS} ${XML2CFLAGS} ${GDAL_CFLAGS} ${PYTHONCFLAGS} -DLINUX_FREE_ISSUE #-DDEBUG
 
 cgi-env/wps_status.zo: service.c
-	g++ ${CFLAGS} -shared -fpic -o cgi-env/wps_status.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} ${FCGI_LDFLAGS} -L${ZRPATH}/zoo-kernel/ -lzoo_service
+	g++ ${CFLAGS1} -shared -fpic -o cgi-env/wps_status.zo ./service.c ${GDAL_LIBS} ${XML2LDFLAGS} ${MACOS_LD_FLAGS} ${ZOO_LDFLAGS} ${MACOS_LD_NET_FLAGS} ${XSLT_LDFLAGS} ${FCGI_LDFLAGS} -L${ZRPATH}/zoo-kernel/ -lzoo_service
 
 install:
Index: trunk/zoo-project/zoo-services/utils/status/service.c
===================================================================
--- trunk/zoo-project/zoo-services/utils/status/service.c	(revision 811)
+++ trunk/zoo-project/zoo-services/utils/status/service.c	(revision 917)
@@ -72,4 +72,7 @@
       return SERVICE_FAILED;
     }
+    map* tmpMap1=getMapFromMaps(conf,"lenv","semaphore");
+    if(tmpMap1!=NULL && strcasecmp(tmpMap1->value,"Created")==0)
+      removeShmLock(conf,1);
     sprintf(xslFileName,"%s/updateStatus.xsl",tmpMmap->value);
     xmlSubstituteEntitiesDefault(1);
@@ -85,7 +88,7 @@
        */
       char *tmpStr=_getStatus(conf,tmpMap->value);
-#ifdef DEBUG
+      //#ifdef DEBUG
       fprintf(stderr,"DEBUG: %s \n",tmpStr);
-#endif
+      //#endif
       if(tmpStr!=NULL && strncmp(tmpStr,"-1",2)!=0){
 	char *tmpStr1=strdup(tmpStr);
@@ -140,4 +143,6 @@
       char message[10];
       sprintf(message,"Step %d",i);
+      fprintf (stderr, "RUN IN BACKGROUND MODE %s %d \n",__FILE__,__LINE__);
+      fflush(stderr);
       updateStatus(conf,i,message);
 #ifndef WIN32
