summaryrefslogtreecommitdiff
path: root/src/skaembutils/s6-ln.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/skaembutils/s6-ln.c')
-rw-r--r--src/skaembutils/s6-ln.c151
1 files changed, 0 insertions, 151 deletions
diff --git a/src/skaembutils/s6-ln.c b/src/skaembutils/s6-ln.c
deleted file mode 100644
index b33562f..0000000
--- a/src/skaembutils/s6-ln.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/sysdeps.h>
-
-#ifdef SKALIBS_HASLINKAT
-#include <skalibs/nonposix.h>
-#endif
-
-#include <string.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <skalibs/posixplz.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/skamisc.h>
-
-#define USAGE "s6-ln [ -n ] [ -s ] [ -f ] [ -L ] [ -P ] src... dest"
-#define SUFFIX ":s6-ln:XXXXXX"
-
-#ifdef SKALIBS_HASLINKAT
-
-static int linknoderef (char const *old, char const *new)
-{
- return linkat(AT_FDCWD, old, AT_FDCWD, new, 0) ;
-}
-
-static int linkderef (char const *old, char const *new)
-{
- return linkat(AT_FDCWD, old, AT_FDCWD, new, AT_SYMLINK_FOLLOW) ;
-}
-
-#else /* can't implement SUSv4, default to link */
-
-# define linknoderef link
-# define linkderef link
-
-#endif
-
-static int ln_doit (char const *old, char const *new, link_func_ref mylink, int force)
-{
- if ((*mylink)(old, new) == -1)
- {
- if (!force || errno != EEXIST)
- {
- strerr_warnwu5sys("make a link", " from ", new, " to ", old) ;
- return 1 ;
- }
- {
- size_t newlen = strlen(new) ;
- char fn[newlen + sizeof(SUFFIX)] ;
- memcpy(fn, new, newlen) ;
- memcpy(fn + newlen, SUFFIX, sizeof(SUFFIX)) ;
- if (mklinktemp(old, fn, mylink) == -1)
- {
- strerr_warnwu3sys("make a link", " to ", old) ;
- return 1 ;
- }
- if (rename(fn, new) == -1)
- {
- unlink_void(fn) ;
- strerr_warnwu2sys("atomically replace ", new) ;
- return 1 ;
- }
- /* if old == new, rename() didn't remove fn */
- unlink_void(fn) ;
- }
- }
- return 0 ;
-}
-
-int main (int argc, char const *const *argv)
-{
- link_func_ref mylink = &link ; /* default to system behaviour */
- int force = 0 ;
- int nodir = 0 ;
- PROG = "s6-ln" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "nsfLP", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'n' : nodir = 1 ; break ;
- case 's': mylink = &symlink ; break ;
- case 'f': force = 1 ; break ;
- case 'L': if (mylink != &symlink) mylink = &linkderef ; break ;
- case 'P': if (mylink != &symlink) mylink = &linknoderef ; break ;
- default : strerr_dieusage(100, USAGE) ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
- if (argc < 2) strerr_dieusage(100, USAGE) ;
- if (argc > 2)
- {
- stralloc sa = STRALLOC_ZERO ;
- unsigned int i = 0 ;
- int e = 0 ;
- size_t base ;
- if (!stralloc_cats(&sa, argv[argc-1]) || !stralloc_catb(&sa, "/", 1))
- strerr_diefu1sys(111, "stralloc_cats") ;
- base = sa.len ;
- for (; i < (unsigned int)(argc-1) ; i++)
- {
- sa.len = base ;
- if (!sabasename(&sa, argv[i], strlen(argv[i])))
- {
- strerr_warnwu1sys("sabasename") ;
- e++ ;
- continue ;
- }
- if (!stralloc_0(&sa))
- {
- strerr_warnwu1sys("stralloc_0") ;
- e++ ;
- continue ;
- }
- e += ln_doit(argv[i], sa.s, mylink, force) ;
- }
- return e ;
- }
-
- {
- struct stat st ;
- if (nodir ? lstat(argv[1], &st) : stat(argv[1], &st) < 0)
- {
- if (errno != ENOENT) strerr_diefu2sys(111, "stat ", argv[1]) ;
- return ln_doit(argv[0], argv[1], mylink, force) ;
- }
- if (!S_ISDIR(st.st_mode))
- return ln_doit(argv[0], argv[1], mylink, force) ;
- }
-
- {
- stralloc sa = STRALLOC_ZERO ;
- if (!stralloc_cats(&sa, argv[1])
- || !stralloc_catb(&sa, "/", 1)
- || !sabasename(&sa, argv[0], strlen(argv[0]))
- || !stralloc_0(&sa))
- strerr_diefu1sys(111, "stralloc_catb") ;
- return ln_doit(argv[0], sa.s, mylink, force) ;
- }
-}