From f07d94c8ecd336457764e0a003466ad00d8d92d3 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Wed, 18 Sep 2019 23:40:07 +1100
Subject: [PATCH] less memory allocation and be more efficient

---
 src/lib66/backup_cmd_switcher.c  |  23 ++---
 src/lib66/db_compile.c           |  50 +++++------
 src/lib66/instance.c             |  29 ++++--
 src/lib66/rc_init.c              |  30 +++----
 src/lib66/resolve.c              |  99 ++++++++++-----------
 src/lib66/resolve_graph.c        |  35 ++++----
 src/lib66/ssexec_enable.c        |  28 +++---
 src/lib66/tree_cmd_state.c       | 146 ++++++++++++++-----------------
 src/lib66/tree_get_permissions.c |  16 ++--
 9 files changed, 219 insertions(+), 237 deletions(-)

diff --git a/src/lib66/backup_cmd_switcher.c b/src/lib66/backup_cmd_switcher.c
index af12b33b..a918cd5d 100644
--- a/src/lib66/backup_cmd_switcher.c
+++ b/src/lib66/backup_cmd_switcher.c
@@ -20,10 +20,9 @@
 #include <oblibs/error2.h>
 #include <oblibs/string.h>
 #include <oblibs/types.h>
-#include <oblibs/stralist.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/stralloc.h>
-#include <skalibs/genalloc.h>
 #include <skalibs/types.h>
 #include <skalibs/djbunix.h>
 
@@ -79,8 +78,7 @@ int backup_switcher(int argc, char const *const *argv,ssexec_t *info)
 	}
 	tree = *argv ;
 	size_t treelen = strlen(tree) ;
-	
-	
+
 	/** $HOME/66/system/tree/servicedirs */
 	//base.len-- ;
 	size_t psymlen ;
@@ -172,8 +170,6 @@ int backup_switcher(int argc, char const *const *argv,ssexec_t *info)
 		memcpy(dstback + info->base.len + SS_SYSTEM_LEN + SS_BACKUP_LEN + 1, tree, treelen) ;
 		memcpy(dstback + info->base.len + SS_SYSTEM_LEN + SS_BACKUP_LEN + 1 + treelen, pback,pbacklen) ;
 		dstback[info->base.len + SS_SYSTEM_LEN + SS_BACKUP_LEN + 1 + treelen + pbacklen] = 0 ;
-				
-		
 		
 		if (what >= 0)
 		{
@@ -183,7 +179,6 @@ int backup_switcher(int argc, char const *const *argv,ssexec_t *info)
 				return -1 ;
 			}
 		}
-		
 		if (what)
 		{
 			
@@ -209,15 +204,15 @@ int backup_switcher(int argc, char const *const *argv,ssexec_t *info)
 int backup_cmd_switcher(unsigned int verbosity,char const *cmd,ssexec_t *info)
 {	
 	int r ;
+	size_t pos = 0 ;
+	stralloc opts = STRALLOC_ZERO ;
 	
-	genalloc opts = GENALLOC_ZERO ;
-	
-	if (!clean_val(&opts,cmd))
+	if (!sastr_clean_string(&opts,cmd))
 	{
 		VERBO3 strerr_warnwu2x("clean: ",cmd) ;
 		return -1 ;
 	}
-	int newopts = 5 + genalloc_len(stralist,&opts) ;
+	int newopts = 5 + sastr_len(&opts) ;
 	char const *newargv[newopts] ;
 	unsigned int m = 0 ;
 	char fmt[UINT_FMT] ;
@@ -227,15 +222,15 @@ int backup_cmd_switcher(unsigned int verbosity,char const *cmd,ssexec_t *info)
 	newargv[m++] = "-v" ;
 	newargv[m++] = fmt ;
 	
-	for (unsigned int i = 0; i < genalloc_len(stralist,&opts); i++)
-		newargv[m++] = gaistr(&opts,i) ;
+	for (;pos < opts.len; pos += strlen(opts.s + pos) + 1)
+		newargv[m++] = opts.s + pos ;
 		
 	newargv[m++] = info->treename.s ;
 	newargv[m++] = 0 ;
 	
 	r = backup_switcher(newopts,newargv,info) ;
 
-	genalloc_deepfree(stralist,&opts,stra_free) ;
+	stralloc_free(&opts) ;
 	
 	return r ;
 }
diff --git a/src/lib66/db_compile.c b/src/lib66/db_compile.c
index f58cf353..2f64cde6 100644
--- a/src/lib66/db_compile.c
+++ b/src/lib66/db_compile.c
@@ -18,48 +18,47 @@
 
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 
 #include <oblibs/string.h>
 #include <oblibs/error2.h>
-#include <oblibs/directory.h>
+#include <oblibs/types.h>
 
-#include <skalibs/stralloc.h>
 #include <skalibs/types.h>
 #include <skalibs/djbunix.h>
 
 #include <66/utils.h>
 #include <66/constants.h>
-#include <66/ssexec.h>
 
-#include <stdio.h>
 int db_compile(char const *workdir, char const *tree, char const *treename, char const *const *envp)
 {
 	int wstat, r ;
 	pid_t pid ;
+	size_t wlen = strlen(workdir), treelen = strlen(treename) ;
 	
-	stralloc source = STRALLOC_ZERO ;
-	stralloc destination = STRALLOC_ZERO ;
-		
-	if (!stralloc_cats(&destination,workdir)) retstralloc(0,"compile_db") ;
-	if (!stralloc_cats(&destination,SS_DB)) retstralloc(0,"compile_db") ;
-	if (!stralloc_0(&destination)) retstralloc(0,"compile_db") ;
-	r = dir_search(destination.s,treename,S_IFDIR) ;//+1 to remove the '/'
-	destination.len--;
-	if (!stralloc_cats(&destination,"/")) retstralloc(0,"compile_db") ;
-	if (!stralloc_cats(&destination,treename)) retstralloc(0,"compile_db") ;
-	if (!stralloc_0(&destination)) retstralloc(0,"compile_db") ;
+	char dest[wlen + SS_DB_LEN + 1 + treelen + 1] ;
+	memcpy(dest,workdir,wlen) ;
+	memcpy(dest + wlen,SS_DB,SS_DB_LEN) ;
+	dest[wlen + SS_DB_LEN] = '/' ;
+	memcpy(dest + wlen + SS_DB_LEN + 1,treename,treelen) ;
+	dest[wlen + SS_DB_LEN + 1 + treelen] = 0 ;
+	
+	char src[wlen + SS_DB_LEN + SS_SRC_LEN + 1] ;
+	memcpy(src,workdir,wlen) ;
+	memcpy(src + wlen,SS_DB,SS_DB_LEN) ;
+	memcpy(src + wlen + SS_DB_LEN,SS_SRC,SS_SRC_LEN) ;
+	src[wlen + SS_DB_LEN + SS_SRC_LEN] = 0 ;
+	
+	r = scan_mode(dest,S_IFDIR) ;
 	if (r)
 	{
-		if (rm_rf(destination.s) < 0)
+		if (rm_rf(dest) < 0)
 		{
-			VERBO3 strerr_warnwu2sys("remove ", destination.s) ;
+			VERBO3 strerr_warnwu2sys("remove ", dest) ;
 			return 0 ;
 		}
 	}
-	if (!stralloc_cats(&source,workdir)) retstralloc(0,"compile_db") ;
-	if (!stralloc_cats(&source,SS_DB SS_SRC)) retstralloc(0,"compile_db") ;
-	if (!stralloc_0(&source)) retstralloc(0,"compile_db") ;
-			
+				
 	char const *newargv[7] ;
 	unsigned int m = 0 ;
 	char fmt[UINT_FMT] ;
@@ -69,8 +68,8 @@ int db_compile(char const *workdir, char const *tree, char const *treename, char
 	newargv[m++] = "-v" ;
 	newargv[m++] = fmt ;
 	newargv[m++] = "--" ;
-	newargv[m++] = destination.s ;
-	newargv[m++] = source.s ;
+	newargv[m++] = dest ;
+	newargv[m++] = src ;
 	newargv[m++] = 0 ;
 	
 	pid = child_spawn0(newargv[0],newargv,envp) ;
@@ -81,12 +80,9 @@ int db_compile(char const *workdir, char const *tree, char const *treename, char
 	}
 	if (wstat)
 	{
-		VERBO3 strerr_warnwu2x("compile: ",destination.s) ;
+		VERBO3 strerr_warnwu2x("compile: ",dest) ;
 		return 0 ;
 	}
 	
-	stralloc_free(&source) ;
-	stralloc_free(&destination) ;
-	
 	return 1 ;
 }
diff --git a/src/lib66/instance.c b/src/lib66/instance.c
index 37c83b01..ad9ebc56 100644
--- a/src/lib66/instance.c
+++ b/src/lib66/instance.c
@@ -19,7 +19,6 @@
 #include <oblibs/error2.h>
 #include <oblibs/files.h>
 #include <oblibs/string.h>
-#include <oblibs/stralist.h>
 #include <oblibs/directory.h>
 #include <oblibs/environ.h>
 #include <oblibs/sastr.h>
@@ -52,10 +51,14 @@ int instance_splitname(stralloc *sa,char const *name,int len,int what)
 	
 	copy = name + tlen ;
 	
+	sa->len = 0 ;
 	if (!what)
-		return stralloc_obreplace(sa,template) ;
+		if (!stralloc_cats(sa,template) ||
+		!stralloc_0(sa)) return 0 ;
 	else
-		return stralloc_obreplace(sa,copy) ;
+		if (!stralloc_catb(sa,copy,strlen(copy)) ||
+		!stralloc_0(sa)) return 0 ;
+	return 1 ;
 }
 
 int instance_create(stralloc *sasv,char const *svname, char const *regex, char const *src, int len)
@@ -126,8 +129,10 @@ int insta_replace(stralloc *sa,char const *src,char const *cpy)
 			
 	}
 	result[curr] = 0 ;
-	
-	return stralloc_obreplace(sa,result) ;
+	sa->len = 0 ;
+	if (!stralloc_cats(sa,result) ||
+	!stralloc_0(sa)) return 0 ;
+	return 1 ;
 }
 
 /** instance -> 0, copy -> 1 */
@@ -142,10 +147,14 @@ int insta_splitname(stralloc *sa,char const *name,int len,int what)
 	
 	copy = name + tlen ;
 	
+	sa->len = 0 ;
 	if (!what)
-		return stralloc_obreplace(sa,template) ;
+		if (!stralloc_cats(sa,template) ||
+		!stralloc_0(sa)) return 0 ;
 	else
-		return stralloc_obreplace(sa,copy) ;
+		if (!stralloc_catb(sa,copy,strlen(copy)) ||
+		!stralloc_0(sa)) return 0 ;
+	return 1 ;
 }
 
 int insta_create(stralloc *sasv,stralloc *sv, char const *src, int len)
@@ -196,8 +205,10 @@ int insta_create(stralloc *sasv,stralloc *sv, char const *src, int len)
 	
 	stralloc_free(&sa) ;
 	stralloc_free(&tmp) ;
-	
-	return stralloc_obreplace(sv,copy) ;
+	sv->len = 0 ;
+	if (!stralloc_catb(sv,copy,strlen(copy)) ||
+	!stralloc_0(sv)) return 0 ;
+	return 1 ;
 }
 
 int insta_check(char const *svname)
diff --git a/src/lib66/rc_init.c b/src/lib66/rc_init.c
index dca07901..6f6c3b2e 100644
--- a/src/lib66/rc_init.c
+++ b/src/lib66/rc_init.c
@@ -16,14 +16,17 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include <sys/types.h>
 
 #include <oblibs/error2.h>
 #include <oblibs/string.h>
 #include <oblibs/types.h>
 #include <oblibs/directory.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/genalloc.h>
 #include <skalibs/djbunix.h>
+#include <skalibs/types.h>
 
 #include <66/resolve.h>
 #include <66/ssexec.h>
@@ -40,11 +43,12 @@ int rc_init(ssexec_t *info, char const *const *envp)
 {
 	int r, wstat, empty = 0 ;
 	pid_t pid ;
+	size_t pos = 0 ;
 	
 	ss_state_t sta = STATE_ZERO ;
 	stralloc sares = STRALLOC_ZERO ;
 	ss_resolve_t res = RESOLVE_ZERO ;
-	genalloc gasvc = GENALLOC_ZERO ; //stralist type
+	stralloc sasvc = STRALLOC_ZERO ;
 	genalloc gares = GENALLOC_ZERO ; //ss_resolve_t type
 	
 	char svdir[info->tree.len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + info->treename.len + 1] ;
@@ -120,23 +124,23 @@ int rc_init(ssexec_t *info, char const *const *envp)
 				
 	if (wstat) { VERBO1 strerr_warnwu2x("init db of tree: ",info->treename.s) ; goto err ; }
 	
-	if (!clean_val(&gasvc,res.sa.s + res.deps)) { VERBO1 strerr_warnwu1sys("clean dependencies of inner bundle") ; goto err ; }
+	if (!sastr_clean_string(&sasvc,res.sa.s + res.deps)) { VERBO1 strerr_warnwu1sys("clean dependencies of inner bundle") ; goto err ; }
 	
-	for (unsigned int i = 0 ; i < genalloc_len(stralist,&gasvc) ; i++)
+	for (; pos < sasvc.len ; pos += strlen(sasvc.s + pos) +1)
 	{
-		char *name = gaistr(&gasvc,i) ;
+		char *name = sasvc.s + pos ;
 		ss_resolve_t tmp = RESOLVE_ZERO ;
 		if (!ss_resolve_check(sares.s,name)){ VERBO1 strerr_warnw2sys("unknown service: ",name) ; goto err ; }
 		if (!ss_resolve_read(&tmp,sares.s,name)) { VERBO1 strerr_warnwu2sys("read resolve file of: ",name) ; goto err ; }
 		if (!ss_resolve_add_deps(&gares,&tmp,sares.s)) { VERBO1 strerr_warnwu2sys("resolve dependencies of: ",name) ; goto err ; }
 		ss_resolve_free(&tmp) ;
 	}
-	
-	for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_t,&gares) ; i++)
+
+	for (pos = 0 ; pos < genalloc_len(ss_resolve_t,&gares) ; pos++)
 	{
-		char const *string = genalloc_s(ss_resolve_t,&gares)[i].sa.s ;
-		char const *name = string + genalloc_s(ss_resolve_t,&gares)[i].name  ;
-		char const *state = string + genalloc_s(ss_resolve_t,&gares)[i].state  ;
+		char const *string = genalloc_s(ss_resolve_t,&gares)[pos].sa.s ;
+		char const *name = string + genalloc_s(ss_resolve_t,&gares)[pos].name  ;
+		char const *state = string + genalloc_s(ss_resolve_t,&gares)[pos].state  ;
 		
 		VERBO2 strerr_warni2x("Write state file of: ",name) ;
 		if (!ss_state_write(&sta,state,name))
@@ -147,20 +151,16 @@ int rc_init(ssexec_t *info, char const *const *envp)
 		VERBO1 strerr_warni2x("Initialized successfully: ",name) ;
 	}
 	
-	/*
-	VERBO2 strerr_warnt2x("reload scandir: ",info->scandir.s) ;
-	if (scandir_send_signal(info->scandir.s,"an") <= 0) goto err ;
-	*/
 	end:
 	genalloc_deepfree(ss_resolve_t,&gares,ss_resolve_free) ;
-	genalloc_deepfree(stralist,&gasvc,stra_free) ;
+	stralloc_free(&sasvc) ;
 	ss_resolve_free(&res) ;
 	stralloc_free(&sares) ;
 	return empty ? 2 : 1 ;
 	
 	err:
 		genalloc_deepfree(ss_resolve_t,&gares,ss_resolve_free) ;
-		genalloc_deepfree(stralist,&gasvc,stra_free) ;
+		stralloc_free(&sasvc) ;
 		ss_resolve_free(&res) ;
 		stralloc_free(&sares) ;
 		return 0 ;
diff --git a/src/lib66/resolve.c b/src/lib66/resolve.c
index ac59b5e5..a8a98e1c 100644
--- a/src/lib66/resolve.c
+++ b/src/lib66/resolve.c
@@ -24,7 +24,6 @@
 #include <oblibs/directory.h>
 #include <oblibs/files.h>
 #include <oblibs/string.h>
-#include <oblibs/stralist.h>
 #include <oblibs/sastr.h>
 
 #include <skalibs/stralloc.h>
@@ -104,7 +103,7 @@ int ss_resolve_pointo(stralloc *sa,ssexec_t *info,unsigned int type, unsigned in
 		else if (!stralloc_cats(&tmp,SS_DB)) goto err ;
 	}
 	if (!stralloc_0(&tmp) ||
-	!stralloc_obreplace(sa,tmp.s)) goto err ;
+	!stralloc_copy(sa,&tmp)) goto err ;
 	
 	stralloc_free(&tmp) ;
 	return 1 ;
@@ -657,13 +656,6 @@ int ss_resolve_setnwrite(sv_alltype *services, ssexec_t *info, char const *dst)
 			if (!stralloc_catb(&final,deps.s + id,strlen(deps.s + id)) ||
 			!stralloc_catb(&final," ",1)) retstralloc(0,"write_dependencies") ;
 		}
-		/*for (unsigned int i = 0; i < res.ndeps; i++)
-		{
-			if (!stralloc_obreplace(&namedeps,deps.s+genalloc_s(unsigned int,&gadeps)[services->cname.idga+i])) goto err ;
-			namedeps.len--;
-			if (!stralloc_catb(&final,namedeps.s,namedeps.len)) { VERBO1 warnstralloc("ss_resolve_setnwrite") ; goto err ; }
-			if (!stralloc_catb(&final," ",1)) {VERBO1  warnstralloc("ss_resolve_setnwrite") ; goto err ; }
-		}*/
 		final.len-- ;
 		if (!stralloc_0(&final)){ VERBO1 warnstralloc("ss_resolve_setnwrite") ; goto err ; } 
 		res.deps = ss_resolve_add_string(&res,final.s) ;
@@ -794,8 +786,8 @@ int ss_resolve_append(genalloc *ga,ss_resolve_t *res)
 
 int ss_resolve_add_deps(genalloc *tokeep,ss_resolve_t *res, char const *src)
 {
-	unsigned int i = 0 ;
-	genalloc tmp = GENALLOC_ZERO ;
+	size_t pos = 0 ;
+	stralloc tmp = STRALLOC_ZERO ;
 	
 	char *name = res->sa.s + res->name ;
 	char *deps = res->sa.s + res->deps ;
@@ -804,39 +796,40 @@ int ss_resolve_add_deps(genalloc *tokeep,ss_resolve_t *res, char const *src)
 		
 	if (res->ndeps)
 	{
-		if (!clean_val(&tmp,deps)) return 0 ;
-		for (;i < genalloc_len(stralist,&tmp) ; i++)
+		if (!sastr_clean_string(&tmp,deps)) return 0 ;
+		for (;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1)
 		{
 			ss_resolve_t dres = RESOLVE_ZERO ;
-			if (!ss_resolve_check(src,gaistr(&tmp,i))) goto err ;
-			if (!ss_resolve_read(&dres,src,gaistr(&tmp,i))) goto err ;
-			if (dres.ndeps && !ss_resolve_cmp(tokeep,gaistr(&tmp,i)))
+			char *dname = tmp.s + pos ;
+			if (!ss_resolve_check(src,dname)) goto err ;
+			if (!ss_resolve_read(&dres,src,dname)) goto err ;
+			if (dres.ndeps && !ss_resolve_cmp(tokeep,dname))
 			{
 				if (!ss_resolve_add_deps(tokeep,&dres,src)) goto err ;
 			}
-			if (!ss_resolve_cmp(tokeep,gaistr(&tmp,i)))
+			if (!ss_resolve_cmp(tokeep,dname))
 			{
 				if (!ss_resolve_append(tokeep,&dres)) goto err ;
 			}
 			ss_resolve_free(&dres) ;
 		}
 	}
-	genalloc_deepfree(stralist,&tmp,stra_free) ;
+	stralloc_free(&tmp) ;
 	return 1 ;
 	err:
-		genalloc_deepfree(stralist,&tmp,stra_free) ;
+		stralloc_free(&tmp) ;
 		return 0 ;
 }
 
 int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 {
 	int type ;
-	genalloc tmp = GENALLOC_ZERO ;
-	genalloc nsv = GENALLOC_ZERO ;
+	stralloc tmp = STRALLOC_ZERO ;
+	stralloc nsv = STRALLOC_ZERO ;
 	ss_state_t sta = STATE_ZERO ;
 	
 	char *name = res->sa.s + res->name ;
-	size_t srclen = strlen(src) ;
+	size_t srclen = strlen(src), a = 0, b = 0, c = 0 ;
 	char s[srclen + SS_RESOLVE_LEN + 1] ;
 	memcpy(s,src,srclen) ;
 	memcpy(s + srclen,SS_RESOLVE,SS_RESOLVE_LEN) ;
@@ -845,7 +838,7 @@ int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 	if (res->type == CLASSIC) type = 0 ;
 	else type = 1 ;
 	
-	if (!dir_get(&nsv,s,SS_MASTER+1,S_IFREG)) goto err ;
+	if (!sastr_dir_get(&nsv,s,SS_MASTER+1,S_IFREG)) goto err ;
 	
 	if (!ss_resolve_cmp(tokeep,name) && (!obstr_equal(name,SS_MASTER+1)))
 	{
@@ -853,13 +846,14 @@ int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 	}
 	if (res->type == BUNDLE && res->ndeps)
 	{
-		if (!clean_val(&tmp,res->sa.s + res->deps)) goto err ;
+		if (!sastr_clean_string(&tmp,res->sa.s + res->deps)) goto err ;
 		ss_resolve_t dres = RESOLVE_ZERO ;
-		for (unsigned int i = 0 ; i < genalloc_len(stralist,&tmp) ; i++)
+		for (; a < tmp.len ; a += strlen(tmp.s + a) + 1)
 		{	
-			if (!ss_resolve_check(src,gaistr(&tmp,i))) goto err ; 
-			if (!ss_resolve_read(&dres,src,gaistr(&tmp,i))) goto err ;
-			if (!ss_resolve_cmp(tokeep,gaistr(&tmp,i)))
+			char *name = tmp.s + a ;
+			if (!ss_resolve_check(src,name)) goto err ; 
+			if (!ss_resolve_read(&dres,src,name)) goto err ;
+			if (!ss_resolve_cmp(tokeep,name))
 			{
 				if (!ss_resolve_append(tokeep,&dres)) goto err ;
 				if (!ss_resolve_add_rdeps(tokeep,&dres,src)) goto err ;
@@ -867,12 +861,12 @@ int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 			ss_resolve_free(&dres) ;
 		}
 	}
-	for (unsigned int i = 0 ; i < genalloc_len(stralist,&nsv) ; i++)
+	for (; b < nsv.len ; b += strlen(nsv.s + b) +1)
 	{
 		int dtype = 0 ;
-		genalloc_deepfree(stralist,&tmp,stra_free) ;
+		tmp.len = 0 ;
 		ss_resolve_t dres = RESOLVE_ZERO ;
-		char *dname = gaistr(&nsv,i) ;
+		char *dname = nsv.s + b ;
 		if (obstr_equal(name,dname)) { ss_resolve_free(&dres) ; continue ; }
 		if (!ss_resolve_check(src,dname)) goto err ;
 		
@@ -892,10 +886,10 @@ int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 		{
 			if (dres.ndeps)// || (dres.type == BUNDLE && dres.ndeps) || )
 			{
-				if (!clean_val(&tmp,dres.sa.s + dres.deps)) goto err ;
-				for (unsigned int j = 0 ; j < genalloc_len(stralist,&tmp) ; j++)
+				if (!sastr_clean_string(&tmp,dres.sa.s + dres.deps)) goto err ;
+				for (c = 0 ; c < tmp.len ; c += strlen(tmp.s + c) + 1)
 				{
-					if (obstr_equal(name,gaistr(&tmp,j)))
+					if (obstr_equal(name,tmp.s + c))
 					{
 						if (!ss_resolve_append(tokeep,&dres)) goto err ;
 						if (!ss_resolve_add_rdeps(tokeep,&dres,src)) goto err ;
@@ -909,20 +903,21 @@ int ss_resolve_add_rdeps(genalloc *tokeep, ss_resolve_t *res, char const *src)
 		ss_resolve_free(&dres) ;
 	}
 	
-	genalloc_deepfree(stralist,&tmp,stra_free) ;
-	genalloc_deepfree(stralist,&nsv,stra_free) ;
+	stralloc_free(&nsv) ;
+	stralloc_free(&tmp) ;
 	return 1 ;
 	err:
-		genalloc_deepfree(stralist,&tmp,stra_free) ;
-		genalloc_deepfree(stralist,&nsv,stra_free) ;
+		stralloc_free(&nsv) ;
+		stralloc_free(&tmp) ;
 		return 0 ;
 }
 
 int ss_resolve_add_logger(genalloc *ga,char const *src)
 {
+	size_t i = 0 ;
 	genalloc gatmp = GENALLOC_ZERO ;
-
-	for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_t,ga) ; i++) 
+	
+	for (; i < genalloc_len(ss_resolve_t,ga) ; i++) 
 	{
 		ss_resolve_t res = RESOLVE_ZERO ;
 		ss_resolve_t dres = RESOLVE_ZERO ;
@@ -1022,15 +1017,14 @@ int ss_resolve_search(genalloc *ga,char const *name)
 int ss_resolve_write_master(ssexec_t *info,ss_resolve_graph_t *graph,char const *dir, unsigned int reverse)
 {
 	int r ;
-	
+	size_t i = 0 ;
 	char ownerstr[UID_FMT] ;
 	size_t ownerlen = uid_fmt(ownerstr,info->owner) ;
 	ownerstr[ownerlen] = 0 ;
 	
 	stralloc in = STRALLOC_ZERO ;
 	stralloc inres = STRALLOC_ZERO ;
-	stralloc already = STRALLOC_ZERO ;
-	genalloc gain = GENALLOC_ZERO ;
+	stralloc gain = STRALLOC_ZERO ;
 	ss_resolve_t res = RESOLVE_ZERO ;
 	
 	size_t dirlen = strlen(dir) ;
@@ -1070,21 +1064,20 @@ int ss_resolve_write_master(ssexec_t *info,ss_resolve_graph_t *graph,char const
 		file[dstlen + 1 + SS_CONTENTS_LEN] = 0 ;
 		size_t filesize=file_get_size(file) ;
 		
-		r = openreadfileclose(file,&already,filesize) ;
+		r = openreadfileclose(file,&gain,filesize) ;
 		if(!r) goto err ;
 		/** ensure that we have an empty line at the end of the string*/
-		if (!stralloc_cats(&already,"\n")) goto err ;
-		if (!stralloc_0(&already)) goto err ;
-		if (!clean_val(&gain,already.s))	goto err ;
-		stralloc_free(&already) ;
+		if (!stralloc_cats(&gain,"\n")) goto err ;
+		if (!stralloc_0(&gain)) goto err ;
+		if (!sastr_clean_element(&gain)) goto err ;
 	}
 	
-	for (unsigned int i = 0 ; i < genalloc_len(ss_resolve_t,&graph->sorted); i++)
+	for (; i < genalloc_len(ss_resolve_t,&graph->sorted); i++)
 	{
 		char *string = genalloc_s(ss_resolve_t,&graph->sorted)[i].sa.s ;
 		char *name = string + genalloc_s(ss_resolve_t,&graph->sorted)[i].name ;
 		if (reverse)
-			if (!stra_cmp(&gain,name)) continue ;
+			if (sastr_cmp(&gain,name) == -1) continue ;
 		
 		if (!stralloc_cats(&in,name)) goto err ;
 		if (!stralloc_cats(&in,"\n")) goto err ;
@@ -1120,15 +1113,13 @@ int ss_resolve_write_master(ssexec_t *info,ss_resolve_graph_t *graph,char const
 	stralloc_free(&in) ;
 	stralloc_free(&inres) ;
 	ss_resolve_free(&res) ;
-	stralloc_free(&already) ;
-	genalloc_deepfree(stralist,&gain,stra_free) ;
+	stralloc_free(&gain) ;
 	return 1 ;
 	
 	err:
 		ss_resolve_free(&res) ;
 		stralloc_free(&in) ;
 		stralloc_free(&inres) ;
-		stralloc_free(&already) ;
-		genalloc_deepfree(stralist,&gain,stra_free) ;
+		stralloc_free(&gain) ;
 		return 0 ;
 }
diff --git a/src/lib66/resolve_graph.c b/src/lib66/resolve_graph.c
index 03e74a8b..5fa9d2a6 100644
--- a/src/lib66/resolve_graph.c
+++ b/src/lib66/resolve_graph.c
@@ -17,6 +17,7 @@
 #include <oblibs/string.h>
 #include <oblibs/directory.h>
 #include <oblibs/error2.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/genalloc.h>
 
@@ -105,20 +106,21 @@ int ss_resolve_graph_sort(ss_resolve_graph_t *graph)
 int ss_resolve_graph_publish(ss_resolve_graph_t *graph,unsigned int reverse)
 {
 	int ret = 0 ;
-	genalloc gatmp = GENALLOC_ZERO ;
+	size_t a = 0 , b = 0 ;
+	stralloc sa = STRALLOC_ZERO ;
 
-	for (unsigned int a = 0 ; a < genalloc_len(ss_resolve_t,&graph->name) ; a++)
+	for (; a < genalloc_len(ss_resolve_t,&graph->name) ; a++)
 	{
 		ss_resolve_graph_ndeps_t rescp = RESOLVE_GRAPH_NDEPS_ZERO ;
 		rescp.idx = a ;
 		
 		if (genalloc_s(ss_resolve_t,&graph->name)[a].ndeps)
 		{
-			genalloc_deepfree(stralist,&gatmp,stra_free) ;
-			if (!clean_val(&gatmp, genalloc_s(ss_resolve_t,&graph->name)[a].sa.s +  genalloc_s(ss_resolve_t,&graph->name)[a].deps)) goto err ;
-			for (unsigned int b = 0 ; b < genalloc_len(stralist,&gatmp) ; b++)
+			sa.len = 0 ;
+			if (!sastr_clean_string(&sa, genalloc_s(ss_resolve_t,&graph->name)[a].sa.s +  genalloc_s(ss_resolve_t,&graph->name)[a].deps)) goto err ;
+			for (; b < sa.len ; b += strlen(sa.s + b) +1)
 			{
-				char *deps = gaistr(&gatmp,b) ;
+				char *deps = sa.s + b ;
 				int r = ss_resolve_search(&graph->name,deps) ;
 				if (r >= 0)
 				{
@@ -132,10 +134,10 @@ int ss_resolve_graph_publish(ss_resolve_graph_t *graph,unsigned int reverse)
 	if (ss_resolve_graph_sort(graph) < 0) { ret = -1 ; goto err ; }
 	if (!reverse) genalloc_reverse(ss_resolve_t,&graph->sorted) ;
 	
-	genalloc_deepfree(stralist,&gatmp,stra_free) ;
+	stralloc_free(&sa) ;
 	return 1 ;
 	err:
-		genalloc_deepfree(stralist,&gatmp,stra_free) ;
+		stralloc_free(&sa) ;
 		return ret ;
 }
 
@@ -171,9 +173,9 @@ int ss_resolve_graph_build(ss_resolve_graph_t *graph,ss_resolve_t *res,char cons
  * @Return 0 on fail*/
 int ss_resolve_graph_src(ss_resolve_graph_t *graph, char const *dir, unsigned int reverse, unsigned int what)
 {
-	genalloc gatmp = GENALLOC_ZERO ;
+	stralloc sa = STRALLOC_ZERO ;
 	ss_resolve_t res = RESOLVE_ZERO ;
-	size_t dirlen = strlen(dir) ;
+	size_t dirlen = strlen(dir), pos = 0 ;
 	
 	char solve[dirlen + SS_DB_LEN + SS_SRC_LEN + 1] ;
 	memcpy(solve,dir,dirlen) ;
@@ -182,29 +184,28 @@ int ss_resolve_graph_src(ss_resolve_graph_t *graph, char const *dir, unsigned in
 	{
 		memcpy(solve + dirlen, SS_SVC, SS_SVC_LEN) ;
 		solve[dirlen + SS_SVC_LEN] = 0 ;
-		if (!dir_get(&gatmp,solve,"",S_IFDIR)) goto err ;
+		if (!sastr_dir_get(&sa,solve,"",S_IFDIR)) goto err ;
 	}
 	if (what)
 	{
 		memcpy(solve + dirlen, SS_DB, SS_DB_LEN) ;
 		memcpy(solve + dirlen + SS_DB_LEN, SS_SRC, SS_SRC_LEN) ;
 		solve[dirlen + SS_DB_LEN + SS_SRC_LEN] = 0 ;
-		if (!dir_get(&gatmp,solve,SS_MASTER + 1,S_IFDIR)) goto err ;
+		if (!sastr_dir_get(&sa,solve,SS_MASTER + 1,S_IFDIR)) goto err ;
 	}
-	
-	for(unsigned int i = 0 ; i < genalloc_len(stralist,&gatmp) ; i++)
+	for (;pos < sa.len; pos += strlen(sa.s + pos) + 1)
 	{
-		char *name = gaistr(&gatmp,i) ;
+		char *name = sa.s + pos ;
 		if (!ss_resolve_check(dir,name)) goto err ;
 		if (!ss_resolve_read(&res,dir,name)) goto err ;
 		if (!ss_resolve_graph_build(graph,&res,dir,reverse)) goto err ;
 	}
 	
-	genalloc_deepfree(stralist,&gatmp,stra_free) ;
+	stralloc_free(&sa) ;
 	ss_resolve_free(&res) ;
 	return 1 ;
 	err:
-		genalloc_deepfree(stralist,&gatmp,stra_free) ;
+		stralloc_free(&sa) ;
 		ss_resolve_free(&res) ;
 		return 0 ;
 }
diff --git a/src/lib66/ssexec_enable.c b/src/lib66/ssexec_enable.c
index c395ea69..56ec9ec9 100644
--- a/src/lib66/ssexec_enable.c
+++ b/src/lib66/ssexec_enable.c
@@ -15,17 +15,16 @@
 #include <string.h>
 #include <stdint.h>
 #include <errno.h>
-#include <stdio.h>
+//#include <stdio.h>
 
 #include <oblibs/obgetopt.h>
 #include <oblibs/error2.h>
-#include <oblibs/stralist.h>
 #include <oblibs/string.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/stralloc.h>
 #include <skalibs/genalloc.h>
 #include <skalibs/djbunix.h>
-#include <skalibs/diuint32.h>
 
 #include <66/constants.h>
 #include <66/utils.h>
@@ -87,12 +86,13 @@ int ssexec_enable(int argc, char const *const *argv,char const *const *envp,ssex
 	CONF = 0 ;
 	
 	int r ;
+	size_t pos = 0 ;
 	unsigned int nbsv, nlongrun, nclassic, start ;
 
 	stralloc home = STRALLOC_ZERO ;
 	stralloc workdir = STRALLOC_ZERO ;
 	stralloc sasrc = STRALLOC_ZERO ;
-	genalloc tostart = GENALLOC_ZERO ; // type stralist
+	stralloc tostart = STRALLOC_ZERO ;
 	
 	r = nbsv = nclassic = nlongrun = start = 0 ;
 	
@@ -150,11 +150,11 @@ int ssexec_enable(int argc, char const *const *argv,char const *const *envp,ssex
 			strerr_diefu2x(111,"write revolve file for: ",name) ;
 		}
 		VERBO2 strerr_warni2x("Service written successfully: ", name) ;
-		if (!stra_cmp(&tostart,name))
+		if (sastr_cmp(&tostart,name) == -1)
 		{
 			if (sv->cname.itype == CLASSIC) nclassic++ ;
 			else nlongrun++ ;
-			if (!stra_add(&tostart,name))
+			if (!sastr_add_string(&tostart,name))
 			{
 				cleanup(workdir.s) ;
 				retstralloc(111,"main") ;
@@ -222,30 +222,30 @@ int ssexec_enable(int argc, char const *const *argv,char const *const *envp,ssex
 	stralloc_free(&workdir) ;
 	stralloc_free(&sasrc) ;
 		
-	for (unsigned int i = 0 ; i < genalloc_len(stralist,&tostart); i++)
-		VERBO1 strerr_warni2x("Enabled successfully: ", gaistr(&tostart,i)) ;
+	for (; pos < tostart.len; pos += strlen(tostart.s + pos) + 1)
+		VERBO1 strerr_warni2x("Enabled successfully: ", tostart.s + pos) ;
 	
-	if (start && genalloc_len(stralist,&tostart))
+	if (start && tostart.len)
 	{
-		int nargc = 2 + genalloc_len(stralist,&tostart) ;
+		int nargc = 2 + sastr_len(&tostart) ;
 		char const *newargv[nargc] ;
 		unsigned int m = 0 ;
 		
 		newargv[m++] = "fake_name" ;
 		
-		for (unsigned int i = 0 ; i < genalloc_len(stralist,&tostart); i++)
-			newargv[m++] = gaistr(&tostart,i) ;
+		for (pos = 0 ; pos < tostart.len; pos += strlen(tostart.s + pos) + 1)
+			newargv[m++] = tostart.s + pos ;
 		
 		newargv[m++] = 0 ;
 		
 		if (ssexec_start(nargc,newargv,envp,info))
 		{
-			genalloc_deepfree(stralist,&tostart,stra_free) ;
+			stralloc_free(&tostart) ;
 			return 111 ;
 		}
 	}
 	
-	genalloc_deepfree(stralist,&tostart,stra_free) ;
+	stralloc_free(&tostart) ;
 		
 	return 0 ;
 }
diff --git a/src/lib66/tree_cmd_state.c b/src/lib66/tree_cmd_state.c
index ab2a5a12..e3e6c257 100644
--- a/src/lib66/tree_cmd_state.c
+++ b/src/lib66/tree_cmd_state.c
@@ -20,12 +20,10 @@
 #include <oblibs/error2.h>
 #include <oblibs/string.h>
 #include <oblibs/types.h>
-#include <oblibs/directory.h>
 #include <oblibs/files.h>
-#include <oblibs/stralist.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/stralloc.h>
-#include <skalibs/genalloc.h>
 #include <skalibs/types.h>
 #include <skalibs/djbunix.h>
 
@@ -36,23 +34,14 @@
 
 int tree_state(int argc, char const *const *argv)
 {
-	int r, fd, err ;
-	unsigned int add, del, sch, verbosity ;
-	size_t statesize ;
-	size_t treelen ;
-	size_t statelen ;
-	
-	char const *tree = NULL ;
-	
-	stralloc base = STRALLOC_ZERO ;
-	stralloc contents = STRALLOC_ZERO ; 
-	genalloc in = GENALLOC_ZERO ; //type stralist
-	
-	verbosity = err = 1 ;
-	
+	int r, fd,skip = -1 ;
+	unsigned int add, del, sch, verbosity, err ;
+	size_t statesize = 0, treelen, statelen, pos = 0 ;
 	uid_t owner = MYUID ;
-	
-	add = del = sch =  0 ;
+	char const *tree = 0 ;
+
+	verbosity = 1 ;
+	add = del = sch = err = 0 ;
 	{
 		subgetopt_t l = SUBGETOPT_ZERO ;
 
@@ -60,33 +49,35 @@ int tree_state(int argc, char const *const *argv)
 		{
 			int opt = getopt_args(argc,argv, "v:sad", &l) ;
 			if (opt == -1) break ;
-			if (opt == -2){ strerr_warnw1x("options must be set first") ; return -1 ; }
+			if (opt == -2){ strerr_warnw1x("options must be set first") ; return 0 ; }
 			switch (opt)
 			{
-				case 'v' :  if (!uint0_scan(l.arg, &verbosity)) return -1 ;  break ;
-				case 'a' : 	add = 1 ; if (del) return -1 ; break ;
-				case 'd' : 	del = 1 ;  if (add) return -1 ; break ;
+				case 'v' :  if (!uint0_scan(l.arg, &verbosity)) return 0 ;  break ;
+				case 'a' : 	add = 1 ; if (del) return 0 ; break ;
+				case 'd' : 	del = 1 ; if (add) return 0 ; break ;
 				case 's' : 	sch = 1 ; break ;
-				default : 	return -1 ; 
+				default : 	return 0 ; 
 			}
 		}
 		argc -= l.ind ; argv += l.ind ;
 	}
 
-	if (argc < 1) return -1 ;
-
+	if (argc < 1) return 0 ;
+	
+	stralloc base = STRALLOC_ZERO ;
+	stralloc contents = STRALLOC_ZERO ;
+	
 	tree = *argv ;
 	treelen = strlen(tree) ;
 	
 	if (!set_ownersysdir(&base,owner))
 	{
 		VERBO3 strerr_warnwu1sys("set owner directory") ;
-		return -1 ;
+		stralloc_free(&base) ;
+		stralloc_free(&contents) ;
+		return 0 ;
 	}
-
 	/** /system/state */
-	//base.len-- ;
-	
 	char state[base.len + SS_SYSTEM_LEN + SS_STATE_LEN + 1] ;
 	memcpy(state,base.s,base.len) ;
 	memcpy(state + base.len,SS_SYSTEM,SS_SYSTEM_LEN) ;
@@ -95,41 +86,35 @@ int tree_state(int argc, char const *const *argv)
 	state[statelen] = 0 ;
 
 	r = scan_mode(state,S_IFREG) ;
-	if (r < 0) { errno = EEXIST ;  err = -1 ; goto out ; }
+	if (r == -1) { errno = EEXIST ; goto out ; }
 	if (!r)
 	{
 		VERBO3 strerr_warnwu2sys("find: ",state) ;
-		{ err = -1 ; goto out ; }
+		goto out ;
 	}
 	
 	statesize = file_get_size(state) ;
-
 	r = openreadfileclose(state,&contents,statesize) ;
 	if(!r)
 	{
 		VERBO3 strerr_warnwu2sys("open: ", state) ;
-		{ err = -1 ; goto out ; }
+		goto out ;
 	}
-	/** ensure that we have an empty line at the end of the string*/
-	if (!stralloc_cats(&contents,"\n")) retstralloc(-1,"tree_registrer") ;
-	if (!stralloc_0(&contents)) retstralloc(-1,"tree_registrer") ;
 	
-	if (!clean_val(&in,contents.s))
+	if (contents.len)
 	{
-		VERBO3 strerr_warnwu2x("clean: ",contents.s) ;
-		{ err = -1 ; goto out ; }
+		if (!sastr_split_string_in_nline(&contents)) goto out ;
 	}
-
 	
 	if (add)
 	{
-		if (!stra_cmp(&in,tree))
+		if (sastr_cmp(&contents,tree) == -1)
 		{
 			fd = open_append(state) ;
 			if (fd < 0)
 			{
 				VERBO3 strerr_warnwu2sys("open: ",state) ;
-				{ err = -1 ; goto out ; }
+				goto out ;
 			}
 			r = write(fd, tree,treelen);
 			r = write(fd, "\n",1);
@@ -137,91 +122,92 @@ int tree_state(int argc, char const *const *argv)
 			{
 				VERBO3 strerr_warnwu5sys("write: ",state," with ", tree," as content") ;
 				fd_close(fd) ;
-				{ err = -1 ; goto out ; }
+				goto out ;
 			}
 			fd_close(fd) ;
 		}
+		else
+		{
+			err = 2 ;
+			goto out ;
+		}
 	}
 		
 	if (del)
 	{
-		
-		if (stra_cmp(&in,tree))
+		skip = sastr_cmp(&contents,tree) ;
+		if (skip >= 0)
 		{
-			if (!stra_remove(&in,tree))
-			{
-				VERBO3 strerr_warnwu4x("to remove: ",tree," in: ",state) ;
-				{ err = -1 ; goto out ; }
-			}
 			fd = open_trunc(state) ;
 			if (fd < 0)
 			{
 				VERBO3 strerr_warnwu2sys("open_trunc ", state) ;
-				{ err = -1 ; goto out ; }
-			}/*
-			fd = open_append(state) ;
-			if (fd < 0)
-			{
-				VERBO3 strerr_warnwu2sys("open: ",state) ;
-				{ err = -1 ; goto out ; }
-			}*/
-			
+				goto out ;
+			}
+	
 			/*** replace it by write_file_unsafe*/
-			for (unsigned int i = 0 ; i < genalloc_len(stralist,&in) ; i++)
+			for (;pos < contents.len ; pos += strlen(contents.s + pos) + 1)
 			{
-				r = write(fd, gaistr(&in,i),gaistrlen(&in,i));
+				if (pos == (size_t)skip) continue ;
+				char *name = contents.s + pos ;
+				size_t namelen = strlen(contents.s + pos) ;
+				r = write(fd, name,namelen);
 				if (r < 0)
 				{
-					VERBO3 strerr_warnwu5sys("write: ",state," with ", gaistr(&in,i)," as content") ;
+					VERBO3 strerr_warnwu5sys("write: ",state," with ", name," as content") ;
 					fd_close(fd) ;
-					{ err = -1 ; goto out ; }
+					goto out ;
 				}
 				r = write(fd, "\n",1);
 				if (r < 0)
 				{
-					VERBO3 strerr_warnwu5sys("write: ",state," with ", gaistr(&in,i)," as content") ;
+					VERBO3 strerr_warnwu5sys("write: ",state," with ", name," as content") ;
 					fd_close(fd) ;
-					{ err = -1 ; goto out ; }
+					goto out ;
 				}
 			}
 			fd_close(fd) ;
 		}
+		else
+		{
+			err = 2 ;
+			goto out ;
+		}
 	}
 	if (sch)
 	{
-		if (stra_cmp(&in,tree))
+		if (sastr_cmp(&contents,tree) >= 0)
 		{
 			err = 1 ;
 			goto out ;
 		}
 		else 
 		{
-			err = 0 ;
+			err = 2 ;
 			goto out ;
 		}
 	}
-	
+	err = 1 ;
 	out:
 	stralloc_free(&base) ;
 	stralloc_free(&contents) ; 
-	genalloc_deepfree(stralist,&in,stra_free) ;
 	
 	return err ;
-
 }
 	
 int tree_cmd_state(unsigned int verbosity,char const *cmd, char const *tree)
 {
 	int r ;
+	size_t pos = 0 ;
+	stralloc opts = STRALLOC_ZERO ;
 	
-	genalloc opts = GENALLOC_ZERO ;
-	
-	if (!clean_val(&opts,cmd))
+	if (!sastr_clean_string(&opts,cmd))
 	{
 		VERBO3 strerr_warnwu2x("clean: ",cmd) ;
-		return -1 ;
+		stralloc_free(&opts) ;
+		return 0 ;
 	}
-	int newopts = 5 + genalloc_len(stralist,&opts) ;
+	int newopts = 5 + sastr_len(&opts) ;
 	char const *newargv[newopts] ;
 	unsigned int m = 0 ;
 	char fmt[UINT_FMT] ;
@@ -231,15 +217,15 @@ int tree_cmd_state(unsigned int verbosity,char const *cmd, char const *tree)
 	newargv[m++] = "-v" ;
 	newargv[m++] = fmt ;
 	
-	for (unsigned int i = 0; i < genalloc_len(stralist,&opts); i++)
-		newargv[m++] = gaistr(&opts,i) ;
-		
+	for (;pos < opts.len; pos += strlen(opts.s + pos) + 1)
+		newargv[m++] = opts.s + pos ;
+
 	newargv[m++] = tree ;
 	newargv[m++] = 0 ;
 	
 	r = tree_state(newopts,newargv) ;
 
-	genalloc_deepfree(stralist,&opts,stra_free) ;
+	stralloc_free(&opts) ;
 	
 	return r ;
 }
diff --git a/src/lib66/tree_get_permissions.c b/src/lib66/tree_get_permissions.c
index 2cd08d2a..e0275272 100644
--- a/src/lib66/tree_get_permissions.c
+++ b/src/lib66/tree_get_permissions.c
@@ -18,7 +18,6 @@
 #include <sys/stat.h>
 
 #include <oblibs/error2.h>
-#include <oblibs/directory.h>
 #include <oblibs/types.h>
 
 #include <skalibs/stralloc.h>
@@ -32,16 +31,19 @@ int tree_get_permissions(char const *tree,uid_t owner)
 	ssize_t r ;
 	size_t treelen = strlen(tree) ;
 	char pack[UID_FMT] ;
-	char tmp[treelen + SS_RULES_LEN + 1] ;
-	
 	uint32_pack(pack,owner) ;
-	pack[uint_fmt(pack,owner)] = 0 ;
+	size_t packlen = uint_fmt(pack,owner) ;
+	pack[packlen] = 0 ;
+	
+	char tmp[treelen + SS_RULES_LEN + 1 + packlen + 1] ;
 	
 	memcpy(tmp,tree,treelen) ;
 	memcpy(tmp + treelen,SS_RULES,SS_RULES_LEN) ;
-	tmp[treelen + SS_RULES_LEN] = 0 ;
-		
-	r = dir_search(tmp,pack,S_IFREG) ;
+	tmp[treelen + SS_RULES_LEN] = '/' ;
+	memcpy(tmp + treelen + SS_RULES_LEN + 1, pack,packlen) ;
+	tmp[treelen + SS_RULES_LEN + 1 + packlen] = 0 ;
+	
+	r = scan_mode(tmp,S_IFREG) ;
 	if (r != 1)	return 0 ;
 	
 	return 1 ;
-- 
GitLab