From 7d049d488416dcd7192b5d3ee0ebef840a50b451 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Fri, 19 Jun 2020 19:38:03 +1100
Subject: [PATCH] use cdb format if available

---
 src/66/66-update.c | 101 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 81 insertions(+), 20 deletions(-)

diff --git a/src/66/66-update.c b/src/66/66-update.c
index 86f412e9..eea9d7bd 100644
--- a/src/66/66-update.c
+++ b/src/66/66-update.c
@@ -28,6 +28,7 @@
 #include <skalibs/sgetopt.h>
 #include <skalibs/djbunix.h>
 #include <skalibs/unix-transactional.h>
+#include <skalibs/cdb.h>
 
 #include <66/ssexec.h>
 #include <66/constants.h>
@@ -121,31 +122,92 @@ void tree_allowed(stralloc *list,char const *base, char const *treename)
 	stralloc_free(&sa) ;
 }
 
-void tree_contents(stralloc *list,char const *tree,ssexec_t *info)
+static uint8_t tree_contents_format(char const *tree)
 {
-	stralloc sa = STRALLOC_ZERO ;
-	size_t treelen = strlen(tree), pos, newlen ;
-	char solve[treelen + SS_SVDIRS_LEN + SS_DB_LEN + SS_SRC_LEN + 1] ;
-	newlen = treelen + SS_SVDIRS_LEN ;
-	auto_strings(solve,tree,SS_SVDIRS,SS_SVC) ;
+	/** even on empty tree Master bundle is always present.
+	 * Check its format. Cdb format allow to retrieve all information
+	 * of the service whatever the 66 version whereas ss_resolve_src_path
+	 * may cause troubles with module if multiple same module was enabled. 
+	 * So, check the validity of the cdb format and use it if we can.*/
+	int r = 1, e = errno, fd ;
+	size_t treelen = strlen(tree) ;
+	cdb_t c = CDB_ZERO ;
+	char d[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN + SS_MASTER_LEN + 1] ;
+	auto_strings(d,tree,SS_SVDIRS,SS_RESOLVE,SS_MASTER) ;
 	
-	if (!sastr_dir_get(&sa,solve,"",S_IFDIR))
-		log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get source svc service file of: ",tree) ;
+	fd = open_readb(d) ;
+	if (fd < 0)
+		log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"open: ",d) ;
+
+	if (!cdb_init_map(&c, fd, 1))
+		log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"cdb_init: ", d) ;
 
-	auto_string_from(solve,newlen,SS_DB,SS_SRC) ;
+	errno = 0 ;
+	r = cdb_find(&c, "name", 4) ;
+	if (r == -1 && errno == EPROTO) r == 0 ;
+	else r = 1 ;
 
-	if (!sastr_dir_get(&sa,solve,SS_MASTER + 1,S_IFDIR))
-		log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get source of atomic service file of: ",tree) ;
+	fd_close(fd) ;
+	cdb_free(&c) ;
+	errno = e ;
+	return (uint8_t)r ;
+}
+
+void tree_contents(stralloc *list,char const *tree,ssexec_t *info)
+{
+	uint8_t format = tree_contents_format(tree) ;
 	
-	for (pos = 0 ;pos < sa.len; pos += strlen(sa.s + pos) + 1)
+	size_t treelen = strlen(tree), pos, newlen ;
+	stralloc sa = STRALLOC_ZERO ;
+	char solve[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN + SS_DB_LEN + SS_SRC_LEN + 1] ;
+
+	if (format)
 	{
-		char *name = sa.s + pos ;
-		int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ;
-		if (logname > 0) continue ;
-		log_trace(DRYRUN ? drun : "","tree: ",info->treename.s," contain service: ",name) ;
-		if (ss_resolve_src_path(list,name,info->owner,0) < 1)
-			log_dieu_nclean(LOG_EXIT_SYS,&cleanup,"resolve source path of: ",name) ;
-	
+		ss_resolve_t res = RESOLVE_ZERO ;
+		auto_strings(solve,tree,SS_SVDIRS,SS_RESOLVE) ;
+		if (!sastr_dir_get(&sa,solve,SS_MASTER + 1,S_IFREG))
+			log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get the service resolve files of: ",tree) ;
+		
+		auto_strings(solve,tree,SS_SVDIRS) ;
+		
+		for (pos = 0 ;pos < sa.len; pos += strlen(sa.s + pos) + 1)
+		{
+			char *name = sa.s + pos ;
+			int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ;
+			if (logname > 0) continue ;
+
+			if (!ss_resolve_read(&res,solve,name))
+				log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read resolve file of: ",solve,"/",name) ;
+
+			if (!stralloc_catb(list,res.sa.s + res.src,strlen(res.sa.s + res.src) + 1))
+				log_diesys_nclean(LOG_EXIT_SYS,&cleanup,"stralloc") ;
+
+			log_trace(DRYRUN ? drun : "","tree: ",info->treename.s," contain service: ",res.sa.s + res.src) ;
+		}
+	}
+	else
+	{
+		newlen = treelen + SS_SVDIRS_LEN ;
+		auto_strings(solve,tree,SS_SVDIRS,SS_SVC) ;
+
+		if (!sastr_dir_get(&sa,solve,"",S_IFDIR))
+			log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get the source svc service files of: ",tree) ;
+
+		auto_string_from(solve,newlen,SS_DB,SS_SRC) ;
+
+		if (!sastr_dir_get(&sa,solve,SS_MASTER + 1,S_IFDIR))
+			log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get source of atomic service files of: ",tree) ;
+
+		for (pos = 0 ;pos < sa.len; pos += strlen(sa.s + pos) + 1)
+		{
+			char *name = sa.s + pos ;
+			int logname = get_rstrlen_until(name,SS_LOG_SUFFIX) ;
+			if (logname > 0) continue ;
+			log_trace(DRYRUN ? drun : "","tree: ",info->treename.s," contain service: ",name) ;
+			if (ss_resolve_src_path(list,name,info->owner,0) < 1)
+				log_dieu_nclean(LOG_EXIT_SYS,&cleanup,"resolve source path of: ",name) ;
+		
+		}
 	}
 	stralloc_free(&sa) ;
 }
@@ -175,7 +237,6 @@ static int run_cmdline(char const *prog,char const **add,int len,char const *con
 	return 1 ;
 }
 
-
 int main(int argc, char const *const *argv,char const *const *envp)
 {
 	int r ;
-- 
GitLab