diff --git a/src/66/66-parser.c b/src/66/66-parser.c
index 1d1869152a13781920fd5805a7cd8ca681c2f6c9..a8f98bacc4248fd71064cfb56042db7111aec803 100644
--- a/src/66/66-parser.c
+++ b/src/66/66-parser.c
@@ -55,12 +55,15 @@ static int check_dir(char const *dir,int force)
 	r = scan_mode(dir,S_IFDIR) ;
 	if (r < 0) return 0 ;
 	
-	if ((r && force) || !r)
+	if (r && force)
 	{
 		if (rm_rf(dir) < 0) return 0 ;
-		r = dir_create(dir, 0755) ;
 		if (!r)	return 0 ;
+		r = 0 ;
 	}
+	else if (r && !force) return -1 ;
+	if (!r)
+		if (!dir_create(dir, 0755)) return 0 ;
 	return 1 ;
 }
 
@@ -112,14 +115,17 @@ int main(int argc, char const *const *argv,char const *const *envp)
 	if (dir[0] != '/') strerr_dief3x(110, "directory: ",dir," must be an absolute path") ;
 	if (sv[0] != '/') strerr_dief3x(110, "service: ",sv," must be an absolute path") ;
 	if (!setname(name,sv)) strerr_diefu1x(111,"parse service name") ;
-	if (!check_dir(dir,force)) strerr_diefu2sys(111,"sanitize directory: ",dir) ;
+	r = check_dir(dir,force) ;
+	if (r < 1) strerr_dief3x(111,"destination: ",dir," already exist") ;
+	else if (!r) strerr_diefu2sys(111,"sanitize directory: ",dir) ;
 	filesize=file_get_size(sv) ;
 	r = openreadfileclose(sv,&src,filesize) ;
 	if (!r) strerr_dief2sys(111,"open: ",sv) ;
 	if (!stralloc_cats(&src,"\n")) retstralloc(111,"main") ;
 	if (!stralloc_0(&src)) retstralloc(111,"main") ;
+	VERBO1 strerr_warni2x("Parsing service file: ", sv) ;
 	if (!parser(&service,&src,sv)) strerr_diefu2x(111,"parse service file: ",sv) ;
-
+	VERBO1 strerr_warni4x("Write service file: ", sv," at: ",dir) ;
 	type = service.cname.itype ;
 	switch(type)
 	{
diff --git a/src/extra-tools/66-envfile.c b/src/extra-tools/66-envfile.c
index df5d9e0d9f7c56cbbdef7f68bdd7f8a0ea722437..76b87c1ce0eafab9dfde26642bf1b8abf7d39841 100644
--- a/src/extra-tools/66-envfile.c
+++ b/src/extra-tools/66-envfile.c
@@ -11,252 +11,18 @@
  * This file may not be copied, modified, propagated, or distributed
  * except according to the terms contained in the LICENSE file./
  */
-#include <string.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
 
-#include <oblibs/string.h>
-#include <oblibs/stralist.h>
-#include <oblibs/error2.h>
-#include <oblibs/obgetopt.h>
-#include <oblibs/directory.h>
-#include <oblibs/files.h>
-
-#include <skalibs/bytestr.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/env.h>
 #include <skalibs/djbunix.h>
-#include <skalibs/diuint32.h>
-#include <skalibs/env.h>
-#include <skalibs/sgetopt.h>
-
-#include <execline/execline.h>
-
-#include <66/parser.h>
-
-unsigned int VERBOSITY = 1 ;
-static stralloc senv = STRALLOC_ZERO ;
-static genalloc gaenv = GENALLOC_ZERO ; //diuint32, pos in senv
-static int MAXVAR = 50 ;
-static int MAXFILE = 500 ;
-
-#define USAGE "66-envfile [ -h help ] [ -f file ] [ -l ] dir prog"
-
-typedef struct exlsn_s exlsn_t, *exlsn_t_ref ;
-struct exlsn_s
-{
-  stralloc vars ;
-  stralloc values ;
-  genalloc data ; // array of elsubst
-  stralloc modifs ;
-} ;
-
-#define EXLSN_ZERO { .vars = STRALLOC_ZERO, .values = STRALLOC_ZERO, .data = GENALLOC_ZERO, .modifs = STRALLOC_ZERO }
-
-static inline void info_help (void)
-{
-  static char const *help =
-"66-envfile <options> dir prog\n"
-"\n"
-"options :\n"
-"	-h: print this help\n" 
-"	-f: file to parse\n"
-"	-l: loose\n"
-;
-
- if (buffer_putsflush(buffer_1, help) < 0)
-    strerr_diefu1sys(111, "write to stdout") ;
-}
-
-static int env_substitute(char const *key, char const *val,exlsn_t *info, char const *const *envp,int unexport)
-{
-	char const *defaultval = "" ;
-	char const *x ;
-	int insist = 0 ;
-		
-	eltransforminfo_t si = ELTRANSFORMINFO_ZERO ;
-	elsubst_t blah ;
-	
-	blah.var = info->vars.len ;
-	blah.value = info->values.len ;
-	
-	if (el_vardupl(key, info->vars.s, info->vars.len)) strerr_dief1x(111, "bad substitution key") ;
-	if (!stralloc_catb(&info->vars,key, strlen(key) + 1)) retstralloc(111,"env_substitute") ;
-	
-	x = env_get2(envp, key) ;
-	if (!x)
-	{
-		if (insist) strerr_dief2x(111, val,": is not set") ;
-		x = defaultval ;
-	}
-	else if (unexport)
-	{
-		if (!stralloc_catb(&info->modifs, key, strlen(key) + 1)) goto err ;
-	}
-	if (!x) blah.n = 0 ;
-	else
-	{
-		int r ;
-		if (!stralloc_cats(&info->values, x)) goto err ;
-		r = el_transform(&info->values, blah.value, &si) ;
-		if (r < 0) goto err ;
-		blah.n = r ;
-	}
-	
-	if (!genalloc_append(elsubst_t, &info->data, &blah)) goto err ;
-		
-	return 1 ;
-	
-	err:
-		info->vars.len = blah.var ;
-		info->values.len = blah.value ;
-		strerr_diefu1x(111,"complete environment substition") ;
-}
-
-int new_env(char const *path,char const *file,stralloc *modifs)
-{
-	int nbline = 0, i = 0 ;
-	
-	stralloc sa = STRALLOC_ZERO ;
-	genalloc gatmp = GENALLOC_ZERO ;//stralist
-	
-	if (!file_readputsa(&sa,path,file)) strerr_diefu4sys(111,"read file: ",path,"/",file) ;
-	if (!parse_env(&sa)) strerr_dief2x(111,"parse file: ", file) ;
-	
-	nbline = get_nbline_ga(sa.s,sa.len,&gatmp) ;
-	
-	for (i = 0;i < nbline;i++)
-		if (!add_env(gaistr(&gatmp,i),&gaenv,&senv)) strerr_diefu2x(111,"append genalloc with: ",gaistr(&gatmp,i)) ;
-
-	for (i = 0 ; i < genalloc_len(diuint32,&gaenv) ; i++)
-	{
-		if (i > MAXVAR) strerr_dief4x(111,"to many variable in file: ",path,"/",file) ;
-		int key = genalloc_s(diuint32,&gaenv)[i].left ;
-		int val = genalloc_s(diuint32,&gaenv)[i].right ;
-		if ((senv.s+key)[0] == '!')
-			key++;
-		if (!env_addmodif(modifs,senv.s + key,senv.s + val)) strerr_diefu1x(111,"add environment") ;
-	}
-	
-	genalloc_deepfree(stralist,&gatmp,stra_free) ;
-	
-	return 1 ;
-}
+#include <skalibs/strerr2.h>
 
 int main (int argc, char const *const *argv, char const *const *envp)
 {
-	int r, i, one, unexport  ;
-	int insist = 1 ;
-	
-	char const *path = 0 ;
-	char const *file = 0 ;
-	
-	stralloc modifs = STRALLOC_ZERO ;
-	stralloc dst = STRALLOC_ZERO ;
-	genalloc toparse = GENALLOC_ZERO ; //stralist
-	
-	exlsn_t info = EXLSN_ZERO ;
-	
-	r = i = one = unexport = 0 ;
-	insist = 1 ;
-	
 	PROG = "66-envfile" ;
-	{
-		subgetopt_t l = SUBGETOPT_ZERO ;
-
-		for (;;)
-		{
-			int opt = subgetopt_r(argc,argv, ">hlf:", &l) ;
-			if (opt == -1) break ;
-			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
-			switch (opt)
-			{
-				case 'h' : 	info_help(); return 0 ;
-				case 'f' :  file = l.arg ; one = 1 ; break ;
-				case 'l' : 	insist = 0 ; break ;
-				default : exitusage(USAGE) ; 
-			}
-		}
-		argc -= l.ind ; argv += l.ind ;
-	}
-	
-	if (argc < 2) exitusage(USAGE) ;
-	
-	path = *argv ;
-	
-	if (path[0] != '/') strerr_dief3x(111,"directory: ",path," must be an absolute path") ;
-	
-	r = dir_get(&toparse,path,"",S_IFREG) ;
-	if (!r && insist) strerr_diefu2sys(111,"get file from: ",path) ;
-	else if ((!r && !insist) || !genalloc_len(stralist,&toparse))
-	{
-		argv++;
-		argc--;
-		xpathexec_run(argv[0],argv,envp) ;
-	}
-	
-	if (one)
-	{
-		r = stra_findidx(&toparse,file) ;
-		if (r < 0) 
-		{
-			if (insist) strerr_diefu2x(111,"find: ",file) ;
-			else
-			{
-				argv++;
-				argc--;
-				xpathexec_run(argv[0],argv,envp) ;
-			}
-		}
-		new_env(path,file,&modifs) ;
-	}
-	else
-	{
-		for (i = 0 ; i < genalloc_len(stralist,&toparse) ; i++)
-		{
-			if (i > MAXFILE) strerr_dief2x(111,"to many file to parse in: ",path) ;
-			new_env(path,gaistr(&toparse,i),&modifs) ;
-		}
-	}
-	genalloc_deepfree(stralist,&toparse,stra_free) ;
-	
-	size_t n = env_len(envp) + 1 + byte_count(modifs.s,modifs.len,'\0') ;
-	char const *newenv[n] ;
-	if (!env_merge (newenv, n ,envp,env_len(envp),modifs.s, modifs.len)) strerr_diefu1sys(111,"build environment") ;
-	
-	modifs.len = 0 ;
-	
-	for (i = 0 ; i < genalloc_len(diuint32,&gaenv) ; i++)
-	{
-			unexport = 0 ;
-			int key = genalloc_s(diuint32,&gaenv)[i].left ;
-			int val = genalloc_s(diuint32,&gaenv)[i].right ;
-			if ((senv.s+key)[0] == '!')
-			{
-				key++ ;
-				unexport = 1 ;
-			}
-			env_substitute(senv.s + key,senv.s + val,&info,newenv,unexport) ;
-	}
-	genalloc_free(diuint32,&gaenv) ;
-	stralloc_free(&senv) ;
-	
-	argv++;
-	argc--;
-
-	if (!env_string (&modifs, argv, (unsigned int) argc)) strerr_diefu1x(111,"make environment string") ;
-	r = el_substitute (&dst, modifs.s, modifs.len, info.vars.s, info.values.s,
-		genalloc_s (elsubst_t const, &info.data),genalloc_len (elsubst_t const, &info.data)) ;
-	if (r < 0) strerr_diefu1sys(111,"el_substitute") ;
-	else if (!r) _exit(0) ;
-
-	stralloc_free(&modifs) ;
-	{
-		char const *v[r + 1] ;
-		if (!env_make (v, r ,dst.s, dst.len)) strerr_diefu1sys(111,"make environment") ;
-		v[r] = 0 ;
-		pathexec_r (v, newenv, env_len(newenv),info.modifs.s,info.modifs.len) ;
-	}
+	int i = 1 ;
+	strerr_warnw1x("the 66-envfile is obsolescent, please use execl-envfile instead") ;
+	char const *cmd[argc] ;
+	cmd[0] = "execl-envfile" ;
+	for(; i < argc ;i++)
+		cmd[i] = argv[i] ;
+	pathexec_run(cmd[0],cmd,envp) ;
 }
diff --git a/src/extra-tools/deps-exe/execl-envfile b/src/extra-tools/deps-exe/execl-envfile
new file mode 100644
index 0000000000000000000000000000000000000000..77b1d97fdc3b7efce73a9a3efb7a8691bb92c0ea
--- /dev/null
+++ b/src/extra-tools/deps-exe/execl-envfile
@@ -0,0 +1,5 @@
+${LIB66}
+-lexecline
+-loblibs
+-lskarnet
+${LIBEXECLINE}
diff --git a/src/extra-tools/execl-envfile.c b/src/extra-tools/execl-envfile.c
new file mode 100644
index 0000000000000000000000000000000000000000..013b720e7bde5442d32de1b46a281ff4270d07d8
--- /dev/null
+++ b/src/extra-tools/execl-envfile.c
@@ -0,0 +1,242 @@
+/* 
+ * execl-envfile.c
+ * 
+ * Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
+ * 
+ * All rights reserved.
+ * 
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <oblibs/string.h>
+#include <oblibs/stralist.h>
+#include <oblibs/error2.h>
+#include <oblibs/obgetopt.h>
+#include <oblibs/directory.h>
+#include <oblibs/files.h>
+
+#include <skalibs/bytestr.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/env.h>
+#include <skalibs/djbunix.h>
+#include <skalibs/diuint32.h>
+#include <skalibs/env.h>
+#include <skalibs/sgetopt.h>
+
+#include <execline/execline.h>
+
+#include <66/parser.h>
+#include <66/environ.h>
+
+unsigned int VERBOSITY = 1 ;
+static stralloc SAENV = STRALLOC_ZERO ;
+static genalloc GAENV = GENALLOC_ZERO ; //diuint32, pos in senv
+static int MAXVAR = 50 ;
+static int MAXFILE = 500 ;
+static int MAXENV = 4096 ;
+
+#define USAGE "execl-envfile [ -h help ] [ -f file ] [ -l ] dir prog"
+
+typedef struct exlsn_s exlsn_t, *exlsn_t_ref ;
+struct exlsn_s
+{
+  stralloc vars ;
+  stralloc values ;
+  genalloc data ; // array of elsubst
+  stralloc modifs ;
+} ;
+
+#define EXLSN_ZERO { .vars = STRALLOC_ZERO, .values = STRALLOC_ZERO, .data = GENALLOC_ZERO, .modifs = STRALLOC_ZERO }
+
+static inline void info_help (void)
+{
+  static char const *help =
+"execl-envfile <options> dir prog\n"
+"\n"
+"options :\n"
+"	-h: print this help\n" 
+"	-f: file to parse\n"
+"	-l: loose\n"
+;
+
+ if (buffer_putsflush(buffer_1, help) < 0)
+    strerr_diefu1sys(111, "write to stdout") ;
+}
+
+static int env_substitute(char const *key, char const *val,exlsn_t *info, char const *const *envp,int unexport)
+{
+	char const *defaultval = "" ;
+	char const *x ;
+	int insist = 0 ;
+		
+	eltransforminfo_t si = ELTRANSFORMINFO_ZERO ;
+	elsubst_t blah ;
+	
+	blah.var = info->vars.len ;
+	blah.value = info->values.len ;
+	
+	if (el_vardupl(key, info->vars.s, info->vars.len)) strerr_dief1x(111, "bad substitution key") ;
+	if (!stralloc_catb(&info->vars,key, strlen(key) + 1)) retstralloc(111,"env_substitute") ;
+	
+	x = env_get2(envp, key) ;
+	if (!x)
+	{
+		if (insist) strerr_dief2x(111, val,": is not set") ;
+		x = defaultval ;
+	}
+	else if (unexport)
+	{
+		if (!stralloc_catb(&info->modifs, key, strlen(key) + 1)) goto err ;
+	}
+	if (!x) blah.n = 0 ;
+	else
+	{
+		int r ;
+		if (!stralloc_cats(&info->values, x)) goto err ;
+		r = el_transform(&info->values, blah.value, &si) ;
+		if (r < 0) goto err ;
+		blah.n = r ;
+	}
+	
+	if (!genalloc_append(elsubst_t, &info->data, &blah)) goto err ;
+		
+	return 1 ;
+	
+	err:
+		info->vars.len = blah.var ;
+		info->values.len = blah.value ;
+		return 0 ;
+}
+
+int main (int argc, char const *const *argv, char const *const *envp)
+{
+	int r, i, one, unexport  ;
+	int insist = 1 ;
+	
+	char const *path = 0 ;
+	char const *file = 0 ;
+	
+	stralloc src = STRALLOC_ZERO ;
+	stralloc modifs = STRALLOC_ZERO ;
+	stralloc dst = STRALLOC_ZERO ;
+	genalloc toparse = GENALLOC_ZERO ; //stralist
+	
+	exlsn_t info = EXLSN_ZERO ;
+	
+	r = i = one = unexport = 0 ;
+	insist = 1 ;
+	
+	PROG = "execl-envfile" ;
+	{
+		subgetopt_t l = SUBGETOPT_ZERO ;
+
+		for (;;)
+		{
+			int opt = subgetopt_r(argc,argv, ">hlf:", &l) ;
+			if (opt == -1) break ;
+			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
+			switch (opt)
+			{
+				case 'h' : 	info_help(); return 0 ;
+				case 'f' :  file = l.arg ; one = 1 ; break ;
+				case 'l' : 	insist = 0 ; break ;
+				default : exitusage(USAGE) ; 
+			}
+		}
+		argc -= l.ind ; argv += l.ind ;
+	}
+	
+	if (argc < 2) exitusage(USAGE) ;
+	
+	path = *argv ;
+	
+	if (path[0] != '/') strerr_dief3x(111,"directory: ",path," must be an absolute path") ;
+	
+	r = dir_get(&toparse,path,"",S_IFREG) ;
+	if (!r && insist) strerr_diefu2sys(111,"get file from: ",path) ;
+	else if ((!r && !insist) || !genalloc_len(stralist,&toparse))
+	{
+		argv++;
+		argc--;
+		xpathexec_run(argv[0],argv,envp) ;
+	}
+	
+	if (one)
+	{
+		r = stra_findidx(&toparse,file) ;
+		if (r < 0) 
+		{
+			if (insist) strerr_diefu2x(111,"find: ",file) ;
+			else
+			{
+				argv++;
+				argc--;
+				xpathexec_run(argv[0],argv,envp) ;
+			}
+		}
+		if (!file_readputsa(&src,path,file)) strerr_diefu4sys(111,"read file: ",path,"/",file) ;
+		if (!env_parsenclean(&modifs,&src)) strerr_diefu4x(111,"parse and clean environment of: ",path,"/",file)  ;
+		if (!env_split(&GAENV,&SAENV,&src)) strerr_diefu4x(111,"split environment of: ",path,"/",file) ;
+	}
+	else
+	{
+		for (i = 0 ; i < genalloc_len(stralist,&toparse) ; i++)
+		{
+			src.len = 0 ;
+			if (i > MAXFILE) strerr_dief2x(111,"to many file to parse in: ",path) ;
+			if (!file_readputsa(&src,path,gaistr(&toparse,i))) strerr_diefu4sys(111,"read file: ",path,"/",gaistr(&toparse,i)) ;
+			if (!env_parsenclean(&modifs,&src)) strerr_diefu4x(111,"parse and clean environment of: ",path,"/",gaistr(&toparse,i)) ;
+			if (!env_split(&GAENV,&SAENV,&src)) strerr_diefu4x(111,"split environment of: ",path,"/",gaistr(&toparse,i)) ;
+		}
+	}
+	genalloc_deepfree(stralist,&toparse,stra_free) ;
+	stralloc_free(&src) ;
+	
+	size_t n = env_len(envp) + 1 + byte_count(modifs.s,modifs.len,'\0') ;
+	if (n > MAXENV) strerr_dief1x(111,"environment string too long") ;
+	char const *newenv[n] ;
+	if (!env_merge (newenv, n ,envp,env_len(envp),modifs.s, modifs.len)) strerr_diefu1sys(111,"build environment") ;
+
+	for (i = 0 ; i < genalloc_len(diuint32,&GAENV) ; i++)
+	{
+			if (i > MAXVAR) strerr_dief1x(111,"to many variables") ;
+			unexport = 0 ;
+			int key = genalloc_s(diuint32,&GAENV)[i].left ;
+			int val = genalloc_s(diuint32,&GAENV)[i].right ;
+			if ((SAENV.s+key)[0] == '!')
+			{
+				key++ ;
+				unexport = 1 ;
+			}
+			env_substitute(SAENV.s + key,SAENV.s + val,&info,newenv,unexport) ;
+	}
+	genalloc_free(diuint32,&GAENV) ;
+	stralloc_free(&SAENV) ;
+	
+	argv++;
+	argc--;
+
+	modifs.len = 0 ;
+	if (!env_string (&modifs, argv, (unsigned int) argc)) strerr_diefu1x(111,"make environment string") ;
+	r = el_substitute (&dst, modifs.s, modifs.len, info.vars.s, info.values.s,
+		genalloc_s (elsubst_t const, &info.data),genalloc_len (elsubst_t const, &info.data)) ;
+	if (r < 0) strerr_diefu1sys(111,"el_substitute") ;
+	else if (!r) _exit(0) ;
+
+	stralloc_free(&modifs) ;
+	{
+		char const *v[r + 1] ;
+		if (!env_make (v, r ,dst.s, dst.len)) strerr_diefu1sys(111,"make environment") ;
+		v[r] = 0 ;
+		pathexec_r (v, newenv, env_len(newenv),info.modifs.s,info.modifs.len) ;
+	}
+}
diff --git a/src/include/66/parser.h b/src/include/66/parser.h
index 6c605315ca59fddab1e54f2022dd6db6287a97c1..6a888f3d6ef347774849eae4868091ca593d46de 100644
--- a/src/include/66/parser.h
+++ b/src/include/66/parser.h
@@ -310,7 +310,6 @@ extern int section_skip(char const *s,size_t pos,int nline) ;
 extern int section_valid(int id, uint32_t nline, size_t pos,stralloc *src, char const *file) ;
 extern int clean_value(stralloc *sa) ;
 extern void parse_err(int ierr,int idsec,int idkey) ;
-extern int add_env(char *line,genalloc *ga,stralloc *sa) ;
 extern int add_pipe(sv_alltype *sv, stralloc *sa) ;
 
 /** enable phase */
@@ -330,6 +329,6 @@ extern int write_uint(char const *dst, char const *name, uint32_t ui) ;
 extern int write_logger(sv_alltype *sv, sv_execlog *log,char const *name, char const *dst, int mode, unsigned int force) ;
 extern int write_consprod(sv_alltype *sv,char const *prodname,char const *consname,char const *proddst,char const *consdst) ;
 extern int write_dependencies(sv_name_t *cname,char const *dst,char const *filename, genalloc *ga, unsigned int force) ;
-extern int write_env(char const *name, genalloc *env,stralloc *sa,char const *dst) ;
+extern int write_env(char const *name,stralloc *sa,char const *dst) ;
 
 #endif
diff --git a/src/lib66/parser.c b/src/lib66/parser.c
index c788ed80bdde236b7f7865546756f90db13a3f10..ef5c70116b6b593c085ac6a9e7e5ec4368805173 100644
--- a/src/lib66/parser.c
+++ b/src/lib66/parser.c
@@ -86,7 +86,10 @@ inline char next(stralloc *s,size_t *pos)
 	(*pos) += 1 ;
 	return c ;
 }
-
+/** @Return 1 on sucess
+ * @Return 0 on fail
+ * @Return 2 for end of file
+ * @Return -1 if close was not found */  
 inline int parse_config(parse_mill_t *p,char const *file, stralloc *src, stralloc *kp,size_t *pos)
 {
 	uint8_t what = 0 ;
@@ -147,15 +150,13 @@ inline int parse_config(parse_mill_t *p,char const *file, stralloc *src, strallo
 		strerr_warnw6x("umatched ",(p->inner.nopen > p->inner.nclose) ? sepopen : sepclose," in: ",file," at line: ",fmt) ;
 		return 0 ;
 	}
-	/** make a return distinction for a end of string*/
-	if (end) return -1 ;
+	if (!p->inner.nclose) return -1 ;
+	if (end) return 2 ;
 	return 1 ;
 }
 
 int parser(sv_alltype *service,stralloc *src,char const *file)
 {
-	VERBO2 strerr_warni2x("Parsing service file: ", file) ;
-	
 	int r ;
 	int svtype = -1 ;
 	section_t sasection = SECTION_ZERO ;
diff --git a/src/lib66/parser_utils.c b/src/lib66/parser_utils.c
index 24fff18b8664c0276069382b63d2360a9c966356..f0d6dfbbba4d760e9a659c1a1efe350194acf109 100644
--- a/src/lib66/parser_utils.c
+++ b/src/lib66/parser_utils.c
@@ -38,6 +38,7 @@
 #include <66/constants.h>
 #include <66/enum.h>
 #include <66/utils.h>//MYUID
+#include <66/environ.h>//MYUID
 
 stralloc keep = STRALLOC_ZERO ;//sv_alltype data
 stralloc deps = STRALLOC_ZERO ;//sv_name depends
@@ -203,32 +204,18 @@ int parse_env(stralloc *src)
 							.forceskip = 0, .force = 1, \
 							.inner = PARSE_MILL_INNER_ZERO } ;
 	
-	size_t blen = src->len, n = 0, len = 0 ;
-	if (!stralloc_inserts(src,1,"@")) goto err ;
+	size_t blen = src->len, n = 0 ;
+	if (!stralloc_inserts(src,0,"@")) goto err ;
 	while(pos < (blen+n))
 	{
 		line.inner.nopen = line.inner.nclose = 0 ;
 		if (!parse_config(&line,file,src,&kp,&pos)) goto err ;
-		if (!stralloc_0(&kp)) goto err ;
+		if (!stralloc_cats(&kp,"\n")) goto err ;
 		if (!stralloc_inserts(src,pos,"@")) goto err ;
 		n++;
 	}
 	if (!stralloc_0(&kp)) goto err ;
-	
-	len = kp.len ;
-	char *p = kp.s ;
-	for (uint32_t i = 0 ;i < line.inner.nline;i++)
-	{
-		n = strlen(p) + 1 ;
-		if (n > len) return (errno = EINVAL, 0) ;
-		if (n > 1)
-		{
-			if (!stralloc_cats(&tmp,p) ||
-			!stralloc_0(&tmp)) goto err ;
-		}
-		p += n ; len -= n ;
-	}
-	if (!stralloc_copy(src,&tmp)) goto err ;
+	if (!stralloc_copy(src,&kp)) goto err ;
 	
 	stralloc_free(&kp) ;
 	stralloc_free(&tmp) ;
@@ -650,6 +637,7 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype)
 	int r, nbline ;
 	unsigned int i ;
 	genalloc gatmp = GENALLOC_ZERO ;
+	stralloc satmp = STRALLOC_ZERO ;
 	r = i = 0 ;
 
 	switch(nocheck->idkey){
@@ -892,9 +880,29 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype)
 			nbline = get_nbline_ga(nocheck->val.s,nocheck->val.len,&gatmp) ;
 			for (i = 0;i < nbline;i++)
 			{
-				if (!add_env(gaistr(&gatmp,i),&service->env,&saenv))
+				satmp.len = 0 ;
+				if (!stralloc_cats(&satmp,gaistr(&gatmp,i)) ||
+				!stralloc_0(&satmp)) 
 				{
-					VERBO3 strerr_warnwu2x("add environment value: ",gaistr(&gatmp,i)) ;
+					VERBO3 strerr_warnwu2x("append environment value: ",gaistr(&gatmp,i)) ;
+					stralloc_free(&satmp) ;
+					return 0 ;
+				}
+				r = env_clean(&satmp) ;
+				if (r > 0)
+				{
+					if (!stralloc_cats(&saenv,satmp.s) ||
+					!stralloc_cats(&saenv,"\n"))
+					{
+						VERBO3 strerr_warnwu2x("store environment value: ",gaistr(&gatmp,i)) ;
+						stralloc_free(&satmp) ;
+						return 0 ;
+					}
+				}
+				else if (!r)
+				{
+					VERBO3 strerr_warnwu2x("clean environment value: ",gaistr(&gatmp,i)) ;
+					stralloc_free(&satmp) ;
 					return 0 ;
 				}
 			}
@@ -917,7 +925,7 @@ int keep_common(sv_alltype *service,keynocheck *nocheck,int svtype)
 	}
 	
 	genalloc_deepfree(stralist,&gatmp,stra_free) ;
-	
+	stralloc_free(&satmp) ;
 	return 1 ;
 }
 
@@ -1236,62 +1244,6 @@ void parse_err(int ierr,int idsec,int idkey)
 	}
 }
 
-int add_env(char *line,genalloc *ga,stralloc *sa)
-{
-	unsigned int i = 0, err = 1 ;
-	
-	char *k = 0 ;
-	char *v = 0 ;
-	
-	genalloc gatmp = GENALLOC_ZERO ;
-	stralloc satmp = STRALLOC_ZERO ;
-	diuint32 tmp = DIUINT32_ZERO ;
-	
-	if (!get_wasted_line(line)) goto freed ;
-	k = line ;
-	v = line ;
-	obstr_sep(&v,"=") ;
-	if (v == NULL) { err = 0 ; goto freed ; }
-	
-	if (!clean_val(&gatmp,k)) { err = 0 ; goto freed ; }
-	for (i = 0 ; i < genalloc_len(stralist,&gatmp) ; i++)
-	{
-		if ((i+1) < genalloc_len(stralist,&gatmp))
-		{
-			if (!stralloc_cats(&satmp,gaistr(&gatmp,i))) { err = 0 ; goto freed ; }
-			if (!stralloc_cats(&satmp," ")) { err = 0 ; goto freed ; }
-		}
-		else if (!stralloc_catb(&satmp,gaistr(&gatmp,i),gaistrlen(&gatmp,i)+1)) { err = 0 ; goto freed ; }
-	}
-	tmp.left = sa->len ;
-	if(!stralloc_catb(sa,satmp.s,satmp.len+1)) { err = 0 ; goto freed ; }
-	
-	if (!obstr_trim(v,'\n')) { err = 0 ; goto freed ; }
-	satmp.len = 0 ;
-	genalloc_deepfree(stralist,&gatmp,stra_free) ;
-	
-	if (!clean_val(&gatmp,v)) { err = 0 ; goto freed ; }
-	for (i = 0 ; i < genalloc_len(stralist,&gatmp) ; i++)
-	{
-		if ((i+1) < genalloc_len(stralist,&gatmp))
-		{
-			if (!stralloc_cats(&satmp,gaistr(&gatmp,i))) { err = 0 ; goto freed ; }
-			if (!stralloc_cats(&satmp," ")) { err = 0 ; goto freed ; }
-		}
-		else if (!stralloc_catb(&satmp,gaistr(&gatmp,i),gaistrlen(&gatmp,i)+1)) { err = 0 ; goto freed ; }
-	}
-	tmp.right = sa->len ;
-	if(!stralloc_catb(sa,satmp.s,satmp.len+1)) { err = 0 ; goto freed ; }
-	
-	if (!genalloc_append(diuint32,ga,&tmp)) err = 0 ;
-		
-	freed:
-		stralloc_free(&satmp) ;
-		genalloc_deepfree(stralist,&gatmp,stra_free) ;
-	
-	return err ;
-}
-
 int add_pipe(sv_alltype *sv, stralloc *sa)
 {
 	char *prodname = keep.s+sv->cname.name ;
diff --git a/src/lib66/parser_write.c b/src/lib66/parser_write.c
index b8459c5eb1e05b44c63a063ed485e062597d7d1d..208fb797114f1800b9d7818d0c1dcab12aca2d23 100644
--- a/src/lib66/parser_write.c
+++ b/src/lib66/parser_write.c
@@ -684,7 +684,8 @@ int write_common(sv_alltype *sv, char const *dst)
 			
 		char *name = keep.s + sv->cname.name ;
 				
-		if (!write_env(name,&sv->env,&saenv,dst))
+		//if (!write_env(name,&sv->env,&saenv,dst))
+		if (!write_env(name,&saenv,dst))
 		{
 			VERBO3 strerr_warnwu1x("write environment") ;
 			return 0 ;
@@ -884,43 +885,27 @@ int write_uint(char const *dst, char const *name, uint32_t ui)
 	return 1 ;
 }
 
-int write_env(char const *name, genalloc *env,stralloc *sa,char const *dst)
+int write_env(char const *name, stralloc *sa,char const *dst)
 {
 	int r ;
-	stralloc tmp = STRALLOC_ZERO ;
-	if (genalloc_len(diuint32,env))
-	{
-		char *key = 0 ;
-		char *val = 0 ;
-		r = scan_mode(dst,S_IFDIR) ;
-		if (r < 0)
-		{
-			VERBO3 strerr_warnw2sys(" invalid environment directory: ",dst) ;
-			return 0 ;
-		}
-		if (!r)
-		{
-			VERBO3 strerr_warnw2sys(dst," service environment directory doesn't exist") ;
-			return 0 ;
-		}
-		for (unsigned int i = 0 ; i < genalloc_len(diuint32,env) ; i++)
-		{
-			key = sa->s + genalloc_s(diuint32,env)[i].left ;
-			val = sa->s + genalloc_s(diuint32,env)[i].right ;
 			
-			if (!stralloc_cats(&tmp,key)) retstralloc(0,"write_env") ;
-			if (!stralloc_cats(&tmp,"=")) retstralloc(0,"write_env") ;
-			if (!stralloc_cats(&tmp,val)) retstralloc(0,"write_env") ;
-			if (!stralloc_cats(&tmp,"\n")) retstralloc(0,"write_env") ;
-		}
+	r = scan_mode(dst,S_IFDIR) ;
+	if (r < 0)
+	{
+		VERBO3 strerr_warnw2sys(" invalid environment directory: ",dst) ;
+		return 0 ;
+	}
+	else if (!r)
+	{
+		VERBO3 strerr_warnw2sys(dst," service environment directory doesn't exist") ;
+		return 0 ;
 	}
-	if (!file_write_unsafe(dst,name,tmp.s,tmp.len))
+	if (!file_write_unsafe(dst,name,sa->s,sa->len))
 	{
 		VERBO3 strerr_warnwu4sys("create file: ",dst,"/",name) ;
 		return 0 ;
 	}
-	
-	stralloc_free(&tmp) ;
-	
+		
 	return 1 ;
 }
+