From 8d51c52de261da7451fcff9819eba482809d2cea Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Mon, 30 Oct 2023 20:18:09 +1100
Subject: [PATCH] add symlink familly function

---
 src/include/66/66.h                 |  1 +
 src/include/66/symlink.h            | 28 +++++++++++++++
 src/lib66/symlink/deps-lib/deps     |  7 ++++
 src/lib66/symlink/symlink_make.c    | 55 ++++++++++++++++++++++++++++
 src/lib66/symlink/symlink_pointto.c | 55 ++++++++++++++++++++++++++++
 src/lib66/symlink/symlink_switch.c  | 56 +++++++++++++++++++++++++++++
 6 files changed, 202 insertions(+)
 create mode 100644 src/include/66/symlink.h
 create mode 100644 src/lib66/symlink/deps-lib/deps
 create mode 100644 src/lib66/symlink/symlink_make.c
 create mode 100644 src/lib66/symlink/symlink_pointto.c
 create mode 100644 src/lib66/symlink/symlink_switch.c

diff --git a/src/include/66/66.h b/src/include/66/66.h
index c2ab9888..b32a1566 100644
--- a/src/include/66/66.h
+++ b/src/include/66/66.h
@@ -29,6 +29,7 @@
 #include <66/ssexec.h>
 #include <66/state.h>
 #include <66/svc.h>
+#include <66/symlink.h>
 #include <66/tree.h>
 #include <66/utils.h>
 #include <66/write.h>
diff --git a/src/include/66/symlink.h b/src/include/66/symlink.h
new file mode 100644
index 00000000..e6da8a39
--- /dev/null
+++ b/src/include/66/symlink.h
@@ -0,0 +1,28 @@
+/*
+ * symlink.h
+ *
+ * Copyright (c) 2018-2023 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./
+ */
+
+#ifndef SS_SYMLINK_H
+#define SS_SYMLINK_H
+
+#define SYMLINK_SOURCE 0
+#define SYMLINK_LIVE 1
+
+#include <stdint.h>
+#include <66/service.h>
+
+extern int symlink_switch(resolve_service_t *res, uint8_t flag) ;
+extern int symlink_make(resolve_service_t *res) ;
+extern int symlink_pointto(resolve_service_t *res) ;
+
+#endif
diff --git a/src/lib66/symlink/deps-lib/deps b/src/lib66/symlink/deps-lib/deps
new file mode 100644
index 00000000..62133c0b
--- /dev/null
+++ b/src/lib66/symlink/deps-lib/deps
@@ -0,0 +1,7 @@
+symlink_make.o
+symlink_switch.o
+symlink_pointto.o
+-ls6
+-loblibs
+-lskarnet
+
diff --git a/src/lib66/symlink/symlink_make.c b/src/lib66/symlink/symlink_make.c
new file mode 100644
index 00000000..c570a72e
--- /dev/null
+++ b/src/lib66/symlink/symlink_make.c
@@ -0,0 +1,55 @@
+/*
+ * symlink_make.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 <sys/errno.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <66/service.h>
+#include <66/constants.h>
+
+int symlink_make(resolve_service_t *res)
+{
+    log_flow() ;
+
+    int r ;
+    struct stat st ;
+    char *name = res->sa.s + res->name ;
+    size_t namelen = strlen(name), homelen = strlen(res->sa.s + res->path.home) ;
+    char *dst = res->sa.s + res->path.servicedir ;
+    char sym[homelen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1 + namelen + 1] ;
+
+    auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", name) ;
+
+    r = lstat(sym, &st) ;
+    if (r < 0) {
+
+        if (errno != ENOENT) {
+
+            log_warnusys_return(LOG_EXIT_ZERO, "lstat: ", sym) ;
+
+        } else {
+
+            log_trace("symlink: ", sym, " to: ", dst) ;
+            r = symlink(dst, sym) ;
+            if (r < 0 && errno != EEXIST)
+                log_warnusys_return(LOG_EXIT_ZERO, "point symlink: ", sym, " to: ", dst) ;
+        }
+    }
+
+    return 1 ;
+}
\ No newline at end of file
diff --git a/src/lib66/symlink/symlink_pointto.c b/src/lib66/symlink/symlink_pointto.c
new file mode 100644
index 00000000..782130f4
--- /dev/null
+++ b/src/lib66/symlink/symlink_pointto.c
@@ -0,0 +1,55 @@
+/*
+ * symkink_pointto.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 <stdint.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <66/symlink.h>
+#include <66/resolve.h>
+#include <66/config.h>
+#include <66/constants.h>
+
+/**
+ * Return SYMLINK_SOURCE is symlink point to source
+ * Return SYMLINK_LIVE is symlink point to live
+ * Return -1 on error
+ **/
+int symlink_pointto(resolve_service_t *res)
+{
+    log_flow() ;
+
+    size_t homelen = strlen(res->sa.s + res->path.home), namelen = strlen(res->sa.s + res->name) ;
+    char sym[homelen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1 + namelen + 1] ;
+    char realsym[SS_MAX_PATH_LEN + 1] ;
+    int size = 0 ;
+
+    auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", res->sa.s + res->name) ;
+
+    size = readlink(sym, realsym, SS_MAX_PATH_LEN) ;
+    if (size >= SS_MAX_PATH_LEN) {
+        errno = ENAMETOOLONG ;
+        log_warnusys_return(LOG_EXIT_LESSONE, "readlink") ;
+    }
+
+    realsym[size] = 0 ;
+
+    if (str_start_with(realsym, res->sa.s + res->path.home))
+        return SYMLINK_SOURCE ;
+    else
+        return SYMLINK_LIVE ;
+}
\ No newline at end of file
diff --git a/src/lib66/symlink/symlink_switch.c b/src/lib66/symlink/symlink_switch.c
new file mode 100644
index 00000000..39f4c7b6
--- /dev/null
+++ b/src/lib66/symlink/symlink_switch.c
@@ -0,0 +1,56 @@
+/*
+ * symlink_switch.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 <stdint.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/unix-transactional.h>//atomic_symlink
+
+#include <66/resolve.h>
+#include <66/sanitize.h>
+#include <66/constants.h>
+
+
+int symlink_switch(resolve_service_t *res, uint8_t flag)
+{
+    log_flow() ;
+
+    char *name = res->sa.s + res->name ;
+    size_t namelen = strlen(res->sa.s + res->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[SS_MAX_PATH_LEN + 1] ;
+
+    auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", name) ;
+
+    if (!flag) {
+
+        auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
+
+    } else {
+
+        auto_strings(dst, res->sa.s + res->live.servicedir) ;
+    }
+
+    log_trace("symlink: ", sym, " to: ", dst) ;
+    if (!atomic_symlink(dst, sym, "symlink_switch"))
+        log_warnusys_return(LOG_EXIT_ZERO, "point symlink: ", sym, " to: ", dst) ;
+
+    return 1 ;
+}
\ No newline at end of file
-- 
GitLab