diff --git a/src/include/66/parse.h b/src/include/66/parse.h
index de23ecb5295ac67d2f9866c82288b2bd67fa3932..5860ed29ed94c90b6fa5fd7b4e8869a10cdfb232 100644
--- a/src/include/66/parse.h
+++ b/src/include/66/parse.h
@@ -42,6 +42,7 @@ extern parse_mill_t MILL_GET_VALUE ;
 
 /** freed and cleanup*/
 extern void ssexec_enable_cleanup(void) ;
+extern void parse_cleanup(resolve_service_t *res, char const *tmpdir, uint8_t force) ;
 
 /** main */
 extern void start_parser(char const *sv, ssexec_t *info, uint8_t disable_module, char const *directory_forced) ;
diff --git a/src/include/66/sanitize.h b/src/include/66/sanitize.h
index 121c96dee1f0dddfcc459b97ba174694f95526ea..a166e8f22ca61d8262b9766c085552b13359c237 100644
--- a/src/include/66/sanitize.h
+++ b/src/include/66/sanitize.h
@@ -28,6 +28,9 @@ extern void sanitize_livestate(resolve_service_t *res) ;
 extern void sanitize_scandir(resolve_service_t *res) ;
 extern void sanitize_init(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen) ;
 extern void sanitize_graph(ssexec_t *info) ;
-extern void sanitize_write(resolve_service_t *res, uint8_t force) ;
+/** @Return 0 the service is already written
+ * @Return 1 the service will be overwritten
+ * die on system error */
+extern int sanitize_write(resolve_service_t *res, uint8_t force) ;
 
 #endif
diff --git a/src/include/66/write.h b/src/include/66/write.h
index e20b3cf9c2b8cd6d84b1ab7026d0c6b6ddbe53b3..cca7812b14593d2b2fbee4dfb634b95e3c9a922a 100644
--- a/src/include/66/write.h
+++ b/src/include/66/write.h
@@ -18,13 +18,16 @@
 #include <stdint.h>
 #include <66/service.h>
 
-extern void write_services(resolve_service_t *res, char const *workdir) ;
-extern void write_classic(resolve_service_t *res, char const *dst) ;
-extern void write_common(resolve_service_t *res, char const *dst) ;
-extern void write_environ(char const *name, char const *contents, char const *dst) ;
-extern void write_execute_scripts(char const *file, char const *contents, char const *dst) ;
-extern void write_logger(resolve_service_t *res, char const *destination) ;
-extern void write_oneshot(resolve_service_t *res, char const *dst) ;
-extern void write_uint(char const *dst, char const *name, uint32_t ui) ;
+extern void write_services(resolve_service_t *res, char const *dst, uint8_t force) ;
+extern void write_classic(resolve_service_t *res, char const *dst, uint8_t force) ;
+extern void write_oneshot(resolve_service_t *res, char const *dst, uint8_t force) ;
+extern void write_logger(resolve_service_t *res, char const *dst, uint8_t force) ;
+
+extern int write_common(resolve_service_t *res, char const *dst) ;
+extern int write_execute_scripts(char const *file, char const *contents, char const *dst) ;
+extern int write_uint(char const *dst, char const *name, uint32_t ui) ;
+extern int write_environ(char const *name, char const *contents, char const *dst) ;
+
+extern void write_make_symlink(resolve_service_t *res) ;
 
 #endif
diff --git a/src/lib66/parse/parse_service.c b/src/lib66/parse/parse_service.c
index 18536647b5a2391f890b9cf7e49280187794d35c..d1d21bad66eab2875ba1c70c85d73e8eeca8ce46 100644
--- a/src/lib66/parse/parse_service.c
+++ b/src/lib66/parse/parse_service.c
@@ -14,16 +14,15 @@
 
 #include <string.h>
 #include <stdint.h>
-#include <stdint.h>
-
-#include <stddef.h>
+#include <stdlib.h>
 
 #include <oblibs/log.h>
 #include <oblibs/string.h>
 #include <oblibs/sastr.h>
 #include <oblibs/types.h>
+#include <oblibs/directory.h>
 
-#include <skalibs/genalloc.h>
+#include <skalibs/djbunix.h>
 
 #include <66/enum.h>
 #include <66/constants.h>
@@ -58,14 +57,120 @@ parse_mill_t MILL_GET_VALUE = \
     .skip = " \t\r", .skiplen = 3, .forceskip = 1, \
     .inner.debug = "get_value" } ;
 
+void parse_cleanup(resolve_service_t *res, char const *tmpdir, uint8_t force)
+{
+    log_flow() ;
+
+    size_t namelen = strlen(res->sa.s + res->name), homelen = strlen(res->sa.s + res->path.home) ;
+    char dir[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
+
+    if (!dir_rm_rf(tmpdir))
+        log_warnu("remove temporary directory: ", tmpdir) ;
+
+    if (!force) {
+
+        auto_strings(dir, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", res->sa.s + res->name) ;
+
+        if (!dir_rm_rf(dir))
+            log_warnu("remove service directory: ", dir) ;
+    }
+}
+
+static void parse_copy_online(char const *dst, char const *src, resolve_service_t *res, uint8_t force)
+{
+    log_flow() ;
+
+    size_t pos = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+    size_t srclen = strlen(src) ;
+
+    if (!access(dst, F_OK)) {
+
+        char const *exclude[6] = { SS_EVENTDIR + 1, SS_SUPERVISEDIR + 1, SS_SCANDIR, SS_STATE + 1, SS_RESOLVE + 1, 0 } ;
+        if (!sastr_dir_get_recursive(&sa, dst, exclude, S_IFDIR|S_IFREG, 1)) {
+            parse_cleanup(res, src, force) ;
+            stralloc_free(&sa) ;
+            log_dieusys(LOG_EXIT_SYS, "get file list of: ", dst) ;
+        }
+
+        FOREACH_SASTR(&sa, pos) {
+
+            char base[strlen(sa.s + pos) + 1] ;
+            if (!ob_basename(base, sa.s + pos)) {
+                parse_cleanup(res, src, force) ;
+                stralloc_free(&sa) ;
+                log_dieusys(LOG_EXIT_SYS, "basename of: ", sa.s + pos) ;
+            }
+
+            char element[srclen + 1 + strlen(base) + 1] ;
+
+            auto_strings(element, src, "/", base) ;
+
+            if (access(element, F_OK) < 0) {
+                log_trace("remove element: ", sa.s + pos) ;
+                if (!dir_rm_rf(sa.s + pos)) {
+                    parse_cleanup(res, src, force) ;
+                    stralloc_free(&sa) ;
+                    log_dieusys(LOG_EXIT_SYS, "remove element: ", sa.s + pos) ;
+                }
+            }
+        }
+    }
+
+    stralloc_free(&sa) ;
+
+    if (access(dst, F_OK) < 0) {
+
+        log_trace("create directory: ", dst) ;
+        if (!dir_create_parent(dst, 0755)) {
+            parse_cleanup(res, src, force) ;
+            stralloc_free(&sa) ;
+            log_dieusys(LOG_EXIT_SYS, "create directory: ", dst) ;
+        }
+    }
+
+    log_trace("copy:", src, " to: ", dst) ;
+    if (!hiercopy(src, dst)) {
+        parse_cleanup(res, src, force) ;
+        stralloc_free(&sa) ;
+        log_dieusys(LOG_EXIT_SYS, "copy: ", src, " to: ", dst) ;
+    }
+}
+
+static void parse_write_state(resolve_service_t *res, char const *dst, uint8_t force)
+{
+    log_flow() ;
+    ss_state_t sta = STATE_ZERO ;
+
+    if (state_check(res)) {
+
+        if (!state_read(&sta, res)) {
+            parse_cleanup(res, dst, force) ;
+            log_dieu(LOG_EXIT_SYS, "read state file of: ", res->sa.s + res->name) ;
+        }
+    }
+
+    state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_TRUE) ;
+    state_set_flag(&sta, STATE_FLAGS_TOPARSE, STATE_FLAGS_FALSE) ;
+    state_set_flag(&sta, STATE_FLAGS_ISPARSED, STATE_FLAGS_TRUE) ;
+    state_set_flag(&sta, STATE_FLAGS_ISEARLIER, res->earlier ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
+    state_set_flag(&sta, STATE_FLAGS_ISDOWNFILE, res->execute.down ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
+
+    if (!state_write_tmp(&sta, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write state file of: ", res->sa.s + res->name) ;
+    }
+}
+
 void parse_service(char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
 {
     log_flow();
 
     int r ;
     unsigned int areslen = 0, count = 0, pos = 0 ;
+    uint8_t rforce = 0 ;
     resolve_service_t ares[SS_MAX_SERVICE] ;
-    ss_state_t sta = STATE_ZERO ;
+    stralloc sa = STRALLOC_ZERO ;
 
     char main[strlen(sv) + 1] ;
     if (!ob_basename(main, sv))
@@ -84,29 +189,44 @@ void parse_service(char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
 
     for (pos = 0 ; pos < areslen ; pos++) {
 
-        sanitize_write(&ares[pos], force) ;
+        sa.len = 0 ;
+        /** be paranoid */
+        rforce = 0 ;
+        size_t namelen = strlen(ares[pos].sa.s + ares[pos].name), homelen = strlen(ares[pos].sa.s + ares[pos].path.home) ;
 
-        write_services(&ares[pos], ares[pos].sa.s + ares[pos].path.servicedir) ;
+        char servicedir[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
 
-        if (state_check(&ares[pos])) {
+        auto_strings(servicedir, ares[pos].sa.s + ares[pos].path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", ares[pos].sa.s + ares[pos].name) ;
 
-            if (!state_read(&sta, &ares[pos]))
-                log_dieu(LOG_EXIT_SYS, "read state file of: ", ares[pos].sa.s + ares[pos].name) ;
-        }
+        if (sanitize_write(&ares[pos], force))
+            rforce = 1 ;
 
-        state_set_flag(&sta, STATE_FLAGS_TOINIT, STATE_FLAGS_TRUE) ;
-        state_set_flag(&sta, STATE_FLAGS_TOPARSE, STATE_FLAGS_FALSE) ;
-        state_set_flag(&sta, STATE_FLAGS_ISPARSED, STATE_FLAGS_TRUE) ;
-        state_set_flag(&sta, STATE_FLAGS_ISEARLIER, ares[pos].earlier ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
-        state_set_flag(&sta, STATE_FLAGS_ISDOWNFILE, ares[pos].execute.down ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
+        if (!auto_stra(&sa, "/tmp/", ares[pos].sa.s + ares[pos].name, ":XXXXXX"))
+            log_die_nomem("stralloc") ;
 
-        if (!state_write(&sta, &ares[pos]))
-            log_dieu(LOG_EXIT_SYS, "write state file of: ", ares[pos].sa.s + ares[pos].name) ;
+        if (!mkdtemp(sa.s))
+            log_dieusys(LOG_EXIT_SYS, "create temporary directory") ;
+
+        write_services(&ares[pos], sa.s, rforce) ;
+
+        parse_write_state(&ares[pos], sa.s, rforce) ;
+
+        service_resolve_write_tmp(&ares[pos], sa.s, rforce) ;
+
+        parse_copy_online(servicedir, sa.s, &ares[pos], rforce) ;
+
+        /** do not die here, just warn the user */
+        log_trace("remove temporary directory: ", sa.s) ;
+        if (!dir_rm_rf(sa.s))
+            log_warnu("remove temporary directory: ", sa.s) ;
 
         tree_service_add(info->base.s, ares[pos].sa.s + ares[pos].treename, ares[pos].sa.s + ares[pos].name) ;
 
+        write_make_symlink(&ares[pos]) ;
+
         log_info("Parsed successfully: ", ares[pos].sa.s + ares[pos].name, " at tree: ", ares[pos].sa.s + ares[pos].treename) ;
     }
 
     service_resolve_array_free(ares, areslen) ;
+    stralloc_free(&sa) ;
 }
diff --git a/src/lib66/sanitize/sanitize_write.c b/src/lib66/sanitize/sanitize_write.c
index 4f685511acf15622b96041df2ca118e7499353e5..857851999d230b9242e43489cee8d6debd8de11a 100644
--- a/src/lib66/sanitize/sanitize_write.c
+++ b/src/lib66/sanitize/sanitize_write.c
@@ -35,25 +35,6 @@
 #include <66/state.h>
 #include <66/svc.h>
 
-static void remove_dir(char const *path, char const *name)
-{
-    size_t pos = 0 ;
-    stralloc sa = STRALLOC_ZERO ;
-
-    char const *exclude[5] = { "event", "supervise", "scandir", 0 } ;
-    if (!sastr_dir_get_recursive(&sa, path, exclude, S_IFDIR|S_IFREG, 1))
-        log_dieusys(LOG_EXIT_SYS, "get list of running services") ;
-
-    FOREACH_SASTR(&sa, pos) {
-        log_trace("remove element: ", sa.s + pos, " from: ", name, " service directory") ;
-
-        if (!dir_rm_rf(sa.s + pos))
-            log_dieusys(LOG_EXIT_SYS, "remove: ", sa.s + pos) ;
-    }
-
-    stralloc_free(&sa) ;
-}
-
 static void resolve_compare(resolve_service_t *res)
 {
     log_flow() ;
@@ -86,11 +67,11 @@ static void resolve_compare(resolve_service_t *res)
     resolve_free(wres) ;
 }
 
-static int delete(resolve_service_t *res, uint8_t force)
+static int preserve(resolve_service_t *res, uint8_t force)
 {
     log_flow() ;
 
-    int r ;
+    int r = 0 ;
 
     char dir[strlen(res->sa.s + res->path.servicedir) + 1] ;
 
@@ -98,96 +79,31 @@ static int delete(resolve_service_t *res, uint8_t force)
 
     r = scan_mode(dir, S_IFDIR) ;
     if (r < 0)
-        log_die(LOG_EXIT_SYS, "unvalid source: ", dir) ;
+        log_diesys(LOG_EXIT_SYS, "unvalid source: ", dir) ;
 
     if (r) {
 
         if (force) {
 
-            stralloc sa = STRALLOC_ZERO ;
-            ss_state_t sta = STATE_ZERO ;
-
-            /** Keep the current symlink target. */
-            if (sareadlink(&sa, dir) < 0 ||
-                !stralloc_0(&sa))
-                    log_dieusys(LOG_EXIT_SYS, "readlink: ", dir) ;
-
             resolve_compare(res) ;
 
-            if (state_check(res)) {
-
-                if (!state_read(&sta, res))
-                    log_dieu(LOG_EXIT_SYS, "read state file of: ", res->sa.s + res->name) ;
-            }
-
-            remove_dir(sa.s, res->sa.s + res->name) ;
-
-            if (!state_write(&sta, res))
-                log_dieu(LOG_EXIT_SYS, "write state file of: ", res->sa.s + res->name) ;
-
-            stralloc_free(&sa) ;
-
         } else
             /** This info should never be executed as long as the parse_frontend
              * check already verifies the service and prevents reaching this point if !force. */
-            log_info_return(2, "Ignoring: ", res->sa.s + res->name, " -- service already written") ;
+            log_info_return(0, "Ignoring: ", res->sa.s + res->name, " -- service already written") ;
     }
 
-    return 1 ;
+    return r ;
 }
 
-static void make_servicedir(resolve_service_t *res)
+int sanitize_write(resolve_service_t *res, uint8_t force)
 {
     log_flow() ;
 
     int r ;
-    char *name = res->sa.s + res->name ;
-    size_t namelen = strlen(name), homelen = strlen(res->sa.s + res->path.home) ;
-    char sym[homelen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1 + namelen + 1] ;
-    char dst[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + SS_RESOLVE_LEN + 1 + namelen + 1] ;
-
-    auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", name) ;
-
-    auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
-
-    struct stat st ;
-    r = lstat(sym, &st) ;
-    if (r < 0) {
-
-        if (errno != ENOENT) {
-
-            log_dieusys(LOG_EXIT_SYS, "lstat: ", sym) ;
-
-        } else {
-
-            log_trace("symlink: ", sym, " to: ", dst) ;
-            r = symlink(dst, sym) ;
-            if (r < 0 && errno != EEXIST)
-                log_dieusys(LOG_EXIT_SYS, "point symlink: ", sym, " to: ", dst) ;
-        }
-    }
-
-    auto_strings(dst + homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen, SS_RESOLVE) ;
-
-    r = scan_mode(dst, S_IFDIR) ;
-    if (r < 0)
-        log_die(LOG_EXIT_SYS, "unvalid source: ", dst) ;
-
-    log_trace("create directory: ", dst) ;
-    if (!dir_create_parent(dst, 0755))
-        log_dieusys(LOG_EXIT_SYS, "create directory: ", dst) ;
-}
-
-void sanitize_write(resolve_service_t *res, uint8_t force)
-{
-    log_flow() ;
-
-    if (delete(res, force) > 1)
-        return ;
 
-    make_servicedir(res) ;
+    r = preserve(res, force) ;
 
-    if (!service_resolve_write(res))
-        log_dieu(LOG_EXIT_SYS, "write resolve file of service: ", res->sa.s + res->name) ;
+    return r ;
 }
 
diff --git a/src/lib66/write/deps-lib/deps b/src/lib66/write/deps-lib/deps
index d07d1f64466ea03a219318abadb3e78242d979e9..8c3cc1baec909e0c322fe12a5e86817a2d9eecc7 100644
--- a/src/lib66/write/deps-lib/deps
+++ b/src/lib66/write/deps-lib/deps
@@ -3,6 +3,7 @@ write_common.o
 write_environ.o
 write_execute_scripts.o
 write_logger.o
+write_make_symlink.o
 write_oneshot.o
 write_service.o
 write_uint.o
diff --git a/src/lib66/write/write_classic.c b/src/lib66/write/write_classic.c
index 84e32b0c4e43933b5c19f041615b87e3485909a4..f0de0219dced9574f5c6935fd26751c5762d5745 100644
--- a/src/lib66/write/write_classic.c
+++ b/src/lib66/write/write_classic.c
@@ -19,27 +19,45 @@
 
 #include <66/service.h>
 #include <66/write.h>
+#include <66/parse.h>
 
 /* dst e.g. /var/lib/66/system/service/svc/<name> */
 
-void write_classic(resolve_service_t *res, char const *dst)
+void write_classic(resolve_service_t *res, char const *dst, uint8_t force)
 {
     log_flow() ;
 
     /**notification,timeout, ... */
-    write_common(res, dst) ;
+    if (!write_common(res, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write common file of: ", res->sa.s + res->name) ;
+    }
 
     /** run file */
-    write_execute_scripts("run", res->sa.s + res->execute.run.run, dst) ;
+    if (!write_execute_scripts("run", res->sa.s + res->execute.run.run, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+    }
 
     /** finish file */
-    if (res->execute.finish.run_user)
-        write_execute_scripts("finish", res->sa.s + res->execute.finish.run, dst) ;
+    if (res->execute.finish.run_user) {
+        if (!write_execute_scripts("finish", res->sa.s + res->execute.finish.run, dst)) {
+            parse_cleanup(res, dst, force) ;
+            log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+        }
+    }
 
     /** run.user file */
-    write_execute_scripts( "run.user", res->sa.s + res->execute.run.run_user, dst) ;
+    if (!write_execute_scripts( "run.user", res->sa.s + res->execute.run.run_user, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+    }
 
     /** finish.user file */
-    if (res->execute.finish.run_user)
-        write_execute_scripts("finish.user", res->sa.s + res->execute.finish.run_user, dst) ;
+    if (res->execute.finish.run_user) {
+        if (!write_execute_scripts("finish.user", res->sa.s + res->execute.finish.run_user, dst)) {
+            parse_cleanup(res, dst, force) ;
+            log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+        }
+    }
 }
diff --git a/src/lib66/write/write_common.c b/src/lib66/write/write_common.c
index 12f760a99435ef7d465cbe14469c63acaaeb3436..ee2c8c3dc8ae033eb546bebd83b49a392cad9ba5 100644
--- a/src/lib66/write/write_common.c
+++ b/src/lib66/write/write_common.c
@@ -14,6 +14,7 @@
 
 
 #include <string.h>
+#include <stdlib.h>
 #include <errno.h>
 
 #include <oblibs/log.h>
@@ -32,7 +33,7 @@
 #include <66/environ.h>
 #include <66/enum.h>
 
-void write_common(resolve_service_t *res, char const *dst)
+int write_common(resolve_service_t *res, char const *dst)
 {
     log_flow() ;
 
@@ -40,34 +41,38 @@ void write_common(resolve_service_t *res, char const *dst)
     if (res->execute.down) {
         log_trace("create file: ", dst, "/down") ;
         if (!file_create_empty(dst, "down", 0644))
-            log_dieusys(LOG_EXIT_SYS, "create down file") ;
+            log_warnusys_return(LOG_EXIT_ZERO, "create down file") ;
     }
 
     /** notification-fd */
     if (res->notify)
-        write_uint(dst, SS_NOTIFICATION, res->notify) ;
+        if (!write_uint(dst, SS_NOTIFICATION, res->notify))
+            log_warnusys_return(LOG_EXIT_ZERO, "write uint file", SS_NOTIFICATION) ;
 
     /** timeout family
      *
      * Only write timeout file for classic service.
-     * All others services are read directly through
-     * the resolve file at start process. */
+     * S6-supervise need it otherwise it's read directly
+     * from the resolve file at start process. */
     if (res->execute.timeout.kill)
-        write_uint(dst, "timeout-kill", res->execute.timeout.kill) ;
+        if (!write_uint(dst, "timeout-kill", res->execute.timeout.kill))
+            log_warnusys_return(LOG_EXIT_ZERO, "write uint file timeout-kill") ;
 
     if (res->execute.timeout.finish)
-        write_uint(dst, "timeout-finish", res->execute.timeout.finish) ;
+        if (!write_uint(dst, "timeout-finish", res->execute.timeout.finish))
+            log_warnusys_return(LOG_EXIT_ZERO, "write uint file timeout-finish") ;
 
     /** max-death-tally */
     if (res->maxdeath)
-        write_uint(dst, SS_MAXDEATHTALLY, res->maxdeath) ;
+        if (!write_uint(dst, SS_MAXDEATHTALLY, res->maxdeath))
+            log_warnusys_return(LOG_EXIT_ZERO, "write uint file", SS_MAXDEATHTALLY) ;
 
     /** down-signal */
     if (res->execute.downsignal)
-        write_uint(dst, "down-signal", res->execute.downsignal) ;
+        if (!write_uint(dst, "down-signal", res->execute.downsignal))
+            log_warnusys_return(LOG_EXIT_ZERO, "write uint file down-signal") ;
 
-    /** environment
-     * environment for module is already written by the parse_module() function */
+    /** environment for module is already written by the parse_module() function */
     if (res->environ.env && res->type != TYPE_MODULE) {
 
         stralloc dst = STRALLOC_ZERO ;
@@ -76,9 +81,10 @@ void write_common(resolve_service_t *res, char const *dst)
         auto_strings(name, ".", res->sa.s + res->name) ;
 
         if (!env_prepare_for_write(&dst, &contents, res))
-            log_dieu(LOG_EXIT_SYS, "prepare environment for: ", res->sa.s + res->name) ;
+            log_warnusys_return(LOG_EXIT_ZERO, "prepare environment for: ", res->sa.s + res->name) ;
 
-        write_environ(name, contents.s, dst.s) ;
+        if (!write_environ(name, contents.s, dst.s))
+            log_warnusys_return(LOG_EXIT_ZERO, "write environment for: ", res->sa.s + res->name) ;
 
         stralloc_free(&dst) ;
         stralloc_free(&contents) ;
@@ -91,28 +97,71 @@ void write_common(resolve_service_t *res, char const *dst)
         size_t pos = 0 ;
         stralloc sa = STRALLOC_ZERO ;
         char *src = res->sa.s + res->path.frontend ;
-        size_t srclen = strlen(src) ;
+        size_t srclen = strlen(src), dstlen = strlen(dst) ;
+        char basedir[srclen + 1] ;
+
+        if (!ob_dirname(basedir, src))
+            log_warnusys_return(LOG_EXIT_ZERO, "get dirname of: ", src) ;
+
 
         if (!sastr_clean_string(&sa, res->sa.s + res->hiercopy))
-            log_dieu(LOG_EXIT_SYS, "clean string") ;
+            log_warnusys_return(LOG_EXIT_ZERO, "clean string") ;
 
         FOREACH_SASTR(&sa, pos) {
 
             char *what = sa.s + pos ;
+            int fd ;
+            size_t wlen = strlen(what) ;
             char tmp[SS_MAX_PATH_LEN + 1] ;
-            char basedir[srclen + 1] ;
+            char dest[dstlen + 1 + wlen + 1];
+            char basename[SS_MAX_PATH_LEN + 1] ;
+
+            if (what [0] == '/' ) {
+
+                auto_strings(tmp, what) ;
+
+                if (!ob_basename(basename, what))
+                    log_warnusys_return(LOG_EXIT_ZERO, "get basename of: ", what) ;
 
-            if (!ob_dirname(basedir, src))
-                log_dieu(LOG_EXIT_SYS, "get dirname of: ", src) ;
+                what = basename ;
 
-            if (what[0] == '.') {
+            } else if (what[0] == '.' && ((what[1] == '/') || (what[1] == '.' && what[2] == '/'))) {
+               /** distinction between .file and ./ ../ directory */
+                char b[strlen(src) + 1]  ;
 
-                if (!dir_beabsolute(tmp, src))
-                    log_dieusys(LOG_EXIT_SYS, "find absolute path of: ", what) ;
+                if (!ob_dirname(b, src))
+                    log_warnusys_return(LOG_EXIT_ZERO, "get dirname of: ", src) ;
+
+                fd = open_read(".") ;
+                if (fd < 0)
+                    log_warnusys_return(LOG_EXIT_ZERO, "open current directory") ;
+
+                if (chdir(b) < 0) {
+                    fd_close(fd) ;
+                    log_warnusys_return(LOG_EXIT_ZERO, "change directory") ;
+                }
+
+                char *p = realpath(what, tmp) ;
+                if (!p) {
+                    fd_close(fd) ;
+                    log_warnusys_return(LOG_EXIT_ZERO, "get absolute path of: ", what) ;
+                }
+
+                if (fd_chdir(fd) < 0) {
+                    fd_close(fd) ;
+                    log_warnusys_return(LOG_EXIT_ZERO, "change directory") ;
+                }
+
+                fd_close(fd) ;
+
+                if (!ob_basename(basename, what))
+                    log_warnusys_return(LOG_EXIT_ZERO, "get basename of: ", what) ;
+
+                what = basename ;
 
             } else {
 
-                auto_strings(tmp, what) ;
+                auto_strings(tmp, basedir, what) ;
             }
 
             r = scan_mode(tmp, S_IFDIR) ;
@@ -120,16 +169,23 @@ void write_common(resolve_service_t *res, char const *dst)
 
                 r = scan_mode(tmp, S_IFREG) ;
                 if (!r)
-                    log_dieusys(LOG_EXIT_SYS, "find: ", tmp) ;
-                if (r < 0) {
+                    log_warnusys_return(LOG_EXIT_ZERO, "find: ", tmp) ;
+                else if (r < 0) {
                     errno = ENOTSUP ;
-                    log_diesys(LOG_EXIT_SYS, "invalid format of: ", tmp) ;
+                    log_warnusys_return(LOG_EXIT_ZERO, "invalid format of: ", tmp) ;
                 }
             }
 
-            log_trace("copy: ", tmp, " to: ", dst) ;
-            if (!hiercopy(tmp, dst))
-                log_dieusys(LOG_EXIT_SYS, "copy: ", tmp, " to: ", dst) ;
+            auto_strings(dest, dst, "/", what) ;
+
+            log_trace("copy: ", tmp, " to: ", dest) ;
+            if (!hiercopy(tmp, dest))
+                log_warnusys_return(LOG_EXIT_ZERO, "copy: ", tmp, " to: ", dest) ;
         }
+        stralloc_free(&sa) ;
     }
+
+
+
+    return 1 ;
 }
diff --git a/src/lib66/write/write_environ.c b/src/lib66/write/write_environ.c
index 46482ef33e3ce9a85c8c7ff4bde66de6148ba397..34d285767dccda2e513b0ed94dd44c98b87b1819 100644
--- a/src/lib66/write/write_environ.c
+++ b/src/lib66/write/write_environ.c
@@ -18,7 +18,7 @@
 #include <oblibs/files.h>
 #include <oblibs/types.h>
 
-void write_environ(char const *name, char const *contents, char const *dst)
+int write_environ(char const *name, char const *contents, char const *dst)
 {
     log_flow() ;
 
@@ -27,10 +27,12 @@ void write_environ(char const *name, char const *contents, char const *dst)
 
     r = scan_mode(dst,S_IFDIR) ;
     if (r < 0)
-        log_die(LOG_EXIT_SYS, "conflicting format of the environment directory: ", dst) ;
+        log_warn_return(LOG_EXIT_ZERO, "conflicting format of the environment directory: ", dst) ;
     else if (!r)
-        log_dieusys(LOG_EXIT_SYS, "find environment directory: ", dst) ;
+        log_warnusys_return(LOG_EXIT_ZERO, "find environment directory: ", dst) ;
 
     if (!file_write_unsafe(dst, name, contents, len))
-        log_dieusys(LOG_EXIT_SYS, "create file: ", dst, "/", name) ;
+        log_warnusys_return(LOG_EXIT_ZERO, "create file: ", dst, "/", name) ;
+
+    return 1 ;
 }
diff --git a/src/lib66/write/write_execute_scripts.c b/src/lib66/write/write_execute_scripts.c
index ffac88a1486a4d68cc49987b6b23a377a61b78f3..78c5d7b0e45fa7c26a123cf9c03b03e3ca1da61e 100644
--- a/src/lib66/write/write_execute_scripts.c
+++ b/src/lib66/write/write_execute_scripts.c
@@ -23,7 +23,7 @@
 #define FAKELEN strlen(run)
 #endif
 
-void write_execute_scripts(char const *file, char const *contents, char const *dst)
+int write_execute_scripts(char const *file, char const *contents, char const *dst)
 {
 
     log_flow() ;
@@ -37,8 +37,10 @@ void write_execute_scripts(char const *file, char const *contents, char const *d
 
     log_trace("create file: ", dst, "/", file) ;
     if (!file_write_unsafe(dst, file, run, FAKELEN))
-        log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", file) ;
+        log_warnusys_return(LOG_EXIT_ZERO, "write: ", dst, "/", file) ;
 
     if (chmod(write, 0755) < 0)
-        log_dieusys(LOG_EXIT_SYS, "chmod", write) ;
+        log_warnusys_return(LOG_EXIT_ZERO, "chmod", write) ;
+
+    return 1 ;
 }
diff --git a/src/lib66/write/write_execute_scripts_user.c b/src/lib66/write/write_execute_scripts_user.c
deleted file mode 100644
index 7ddd99a8928b069f368399fc35b12251272f7c30..0000000000000000000000000000000000000000
--- a/src/lib66/write/write_execute_scripts_user.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * write_execute_scripts_user.c
- *
- * Copyright (c) 2018-2021 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 <sys/stat.h>
-
-#include <oblibs/log.h>
-#include <oblibs/string.h>
-#include <oblibs/files.h>
-
-#include <66/service.h>
-#include <66/config.h>
-#include <66/enum.h>
-
-#ifndef FAKELEN
-#define FAKELEN strlen(run)
-#endif
-
-void write_execute_scripts_user(resolve_service_t *res, resolve_service_addon_scripts_t *scripts, char const *file, char const *dst)
-{
-    log_flow() ;
-
-    char *shebang = scripts->shebang ? res->sa.s + scripts->shebang : SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
-    size_t shebanglen = strlen(shebang) ;
-    size_t scriptlen = strlen(res->sa.s + scripts->run_user) ;
-    char run[shebanglen + scriptlen + 4 + 1] ;
-    int build = !strcmp(res->sa.s + scripts->build, "custom") ? 1 : 0 ;
-    char write[strlen(dst) + 1 + strlen(file) + 1] ;
-
-    auto_strings(write, dst, "/", file) ;
-
-    auto_strings(run, "#!") ;
-
-    if (build && scripts->shebang)
-        auto_strings(run + FAKELEN, res->sa.s + scripts->shebang, "\n") ;
-    else
-        auto_strings(run + FAKELEN, shebang, "\n") ;
-
-    auto_strings(run + FAKELEN, res->sa.s + scripts->run_user, "\n") ;
-
-    if (!file_write_unsafe(dst, file, run, FAKELEN))
-        log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", file) ;
-
-    if (chmod(write, 0755) < 0)
-        log_dieusys(LOG_EXIT_SYS, "chmod", write) ;
-
-}
diff --git a/src/lib66/write/write_logger.c b/src/lib66/write/write_logger.c
index f56e14bdf68df9ba076d2583d6898aa6f754a18b..d175fa217ae423f0716a4fe58298ee2170d02c91 100644
--- a/src/lib66/write/write_logger.c
+++ b/src/lib66/write/write_logger.c
@@ -31,6 +31,7 @@
 #include <66/utils.h>
 #include <s6/config.h>
 #include <66/constants.h>
+#include <66/parse.h>
 
 #include <s6/config.h>
 
@@ -40,7 +41,7 @@
 
 /** @destination -> /var/lib/66/system/service/svc/<name> */
 
-void write_logger(resolve_service_t *res, char const *destination)
+void write_logger(resolve_service_t *res, char const *destination, uint8_t force)
 {
     log_flow() ;
 
@@ -50,48 +51,72 @@ void write_logger(resolve_service_t *res, char const *destination)
 
     char *logrunner = res->execute.run.runas ? res->sa.s + res->execute.run.runas : SS_LOGGER_RUNNER ;
 
-    if (res->execute.timeout.kill)
-        write_uint(destination, "timeout-kill", res->execute.timeout.kill) ;
+    if (res->execute.timeout.kill) {
+        if (!write_uint(destination, "timeout-kill", res->execute.timeout.kill)) {
+            parse_cleanup(res, destination, force) ;
+            log_dieusys(LOG_EXIT_SYS, "write uint file timeout-kill") ;
+        }
+    }
 
-    if (res->execute.timeout.finish)
-        write_uint(destination, "timeout-finish", res->execute.timeout.finish) ;
+    if (res->execute.timeout.finish) {
+        if (!write_uint(destination, "timeout-finish", res->execute.timeout.finish)) {
+            parse_cleanup(res, destination, force) ;
+            log_dieusys(LOG_EXIT_SYS, "write uint file timeout-finish") ;
+        }
+    }
 
     /** notification */
-    write_uint(destination, "notification-fd", 3) ;
+    if (!write_uint(destination, SS_NOTIFICATION, 3)) {
+        parse_cleanup(res, destination, force) ;
+        log_dieusys(LOG_EXIT_SYS, "write uint file ", SS_NOTIFICATION) ;
+    }
 
     /** log destination */
     log_trace("create directory: ", res->sa.s + res->logger.destination) ;
-    if (!dir_create_parent(res->sa.s + res->logger.destination, 0755))
+    if (!dir_create_parent(res->sa.s + res->logger.destination, 0755)) {
+        parse_cleanup(res, destination, force) ;
         log_dieusys(LOG_EXIT_SYS, "create directory: ", res->sa.s + res->logger.destination) ;
+    }
 
     if (!owner && ((res->execute.run.build == BUILD_AUTO) || (!res->execute.run.build))) {
 
-        if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid))
+        if (!youruid(&log_uid, logrunner) || !yourgid(&log_gid, log_uid)) {
+            parse_cleanup(res, destination, force) ;
             log_dieusys(LOG_EXIT_SYS, "get uid and gid of: ", logrunner) ;
-
-        if (chown(res->sa.s + res->logger.destination, log_uid, log_gid) == -1)
+        }
+        if (chown(res->sa.s + res->logger.destination, log_uid, log_gid) == -1) {
+            parse_cleanup(res, destination, force) ;
             log_dieusys(LOG_EXIT_SYS, "chown: ", res->sa.s + res->logger.destination) ;
+        }
     }
 
     char write[strlen(destination) + 10] ;
 
     /** run script */
     log_trace("create file: ", destination, "/run") ;
-    if (!file_write_unsafe(destination, "run", res->sa.s + res->execute.run.run, strlen(res->sa.s + res->execute.run.run)))
+    if (!file_write_unsafe(destination, "run", res->sa.s + res->execute.run.run, strlen(res->sa.s + res->execute.run.run))) {
+        parse_cleanup(res, destination, force) ;
         log_dieusys(LOG_EXIT_SYS, "write: ", destination, "/run.user") ;
+    }
 
     auto_strings(write, destination, "/run") ;
 
-    if (chmod(write, 0755) < 0)
+    if (chmod(write, 0755) < 0) {
+        parse_cleanup(res, destination, force) ;
         log_dieusys(LOG_EXIT_SYS, "chmod", write) ;
+    }
 
     /** run.user script */
-log_trace("create file: ", destination, "/run.user") ;
-    if (!file_write_unsafe(destination, "run.user", res->sa.s + res->execute.run.run_user, strlen(res->sa.s + res->execute.run.run_user)))
+    log_trace("create file: ", destination, "/run.user") ;
+    if (!file_write_unsafe(destination, "run.user", res->sa.s + res->execute.run.run_user, strlen(res->sa.s + res->execute.run.run_user))) {
+        parse_cleanup(res, destination, force) ;
         log_dieusys(LOG_EXIT_SYS, "write: ", destination, "/run.user") ;
+    }
 
     auto_strings(write, destination, "/run.user") ;
 
-    if (chmod(write, 0755) < 0)
+    if (chmod(write, 0755) < 0) {
+        parse_cleanup(res, destination, force) ;
         log_dieusys(LOG_EXIT_SYS, "chmod", write) ;
+    }
 }
diff --git a/src/lib66/write/write_oneshot.c b/src/lib66/write/write_oneshot.c
index 071f50adb2c9ef6d28c35eaa3ac860dd8d4bad9d..d5789684db2ffc3a28e7ff1b13b5a327ca33e345 100644
--- a/src/lib66/write/write_oneshot.c
+++ b/src/lib66/write/write_oneshot.c
@@ -16,26 +16,43 @@
 
 #include <66/service.h>
 #include <66/write.h>
+#include <66/parse.h>
 
-void write_oneshot(resolve_service_t *res, char const *dst)
+void write_oneshot(resolve_service_t *res, char const *dst, uint8_t force)
 {
     log_flow() ;
 
     /**notification,timeout, ... */
-    write_common(res, dst) ;
+    if (!write_common(res, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write common file of: ", res->sa.s + res->name) ;
+    }
 
     /** run file */
-    write_execute_scripts("up", res->sa.s + res->execute.run.run, dst) ;
+    if (!write_execute_scripts("up", res->sa.s + res->execute.run.run, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+    }
 
     /** finish file */
-    if (res->execute.finish.run_user)
-        write_execute_scripts("down", res->sa.s + res->execute.finish.run, dst) ;
+    if (res->execute.finish.run_user) {
+        if (!write_execute_scripts("down", res->sa.s + res->execute.finish.run, dst)) {
+            parse_cleanup(res, dst, force) ;
+            log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+        }
+    }
 
     /** run.user file */
-    write_execute_scripts("up.user", res->sa.s + res->execute.run.run_user, dst) ;
+    if (!write_execute_scripts("up.user", res->sa.s + res->execute.run.run_user, dst)) {
+        parse_cleanup(res, dst, force) ;
+        log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+    }
 
     /** finish.user file */
-    if (res->execute.finish.run_user)
-        write_execute_scripts("down.user", res->sa.s + res->execute.finish.run_user, dst) ;
-
+    if (res->execute.finish.run_user) {
+        if (!write_execute_scripts("down.user", res->sa.s + res->execute.finish.run_user, dst)) {
+            parse_cleanup(res, dst, force) ;
+            log_dieu(LOG_EXIT_SYS, "write execute script of: ", res->sa.s + res->name) ;
+        }
+    }
 }
diff --git a/src/lib66/write/write_service.c b/src/lib66/write/write_service.c
index e80dfcaf27ac9b7241dee31f8565509b5908c7cb..c42c474d0fc98da6b32663ea6afdbd6e6049e669 100644
--- a/src/lib66/write/write_service.c
+++ b/src/lib66/write/write_service.c
@@ -28,6 +28,7 @@
 #include <66/write.h>
 #include <66/constants.h>
 #include <66/sanitize.h>
+#include <66/parse.h>
 
 /** @Return 0 on fail
  * @Return 1 on success
@@ -35,7 +36,7 @@
  *
  * @workdir -> /var/lib/66/system/<tree>/servicedirs/
  * */
-void write_services(resolve_service_t *res, char const *workdir)
+void write_services(resolve_service_t *res, char const *workdir, uint8_t force)
 {
     log_flow() ;
 
@@ -43,9 +44,9 @@ void write_services(resolve_service_t *res, char const *workdir)
     uint32_t type = res->type ;
     char logname = get_rstrlen_until(name, SS_LOG_SUFFIX) ;
     if (logname > 0)
-        type = 4 ;
+        type = 10 ;
 
-    log_trace("write service ", name) ;
+    log_trace("write service: ", name) ;
 
     switch(type) {
 
@@ -55,20 +56,21 @@ void write_services(resolve_service_t *res, char const *workdir)
 
         case TYPE_CLASSIC:
 
-            write_classic(res, workdir) ;
+            write_classic(res, workdir, force) ;
             break ;
 
         case TYPE_ONESHOT:
 
-            write_oneshot(res, workdir) ;
+            write_oneshot(res, workdir, force) ;
             break ;
 
-        case 4:
+        case 10:
 
-            write_logger(res, workdir) ;
+            write_logger(res, workdir, force) ;
             break ;
 
         default:
+            parse_cleanup(res, workdir, force) ;
             log_die(LOG_EXIT_SYS, "unkown type: ", get_key_by_enum(ENUM_TYPE, type)) ;
     }
 
diff --git a/src/lib66/write/write_uint.c b/src/lib66/write/write_uint.c
index 4224fe6c86c04a00460129dbb1b5d351c7765e81..85e13d5130a1dc7a6671b07dc0f53bcc539582a8 100644
--- a/src/lib66/write/write_uint.c
+++ b/src/lib66/write/write_uint.c
@@ -20,7 +20,7 @@
 
 #include <skalibs/types.h>
 
-void write_uint(char const *dst, char const *name, uint32_t ui)
+int write_uint(char const *dst, char const *name, uint32_t ui)
 {
     log_flow() ;
 
@@ -28,5 +28,7 @@ void write_uint(char const *dst, char const *name, uint32_t ui)
 
     log_trace("write file: ", dst, "/", name) ;
     if (!file_write_unsafe(dst, name, number, uint32_fmt(number,ui)))
-        log_dieusys(LOG_EXIT_SYS, "write: ", dst, "/", name) ;
+        log_warnusys_return(LOG_EXIT_ZERO, "write: ", dst, "/", name) ;
+
+    return 1 ;
 }