diff options
Diffstat (limited to 'src/skaembutils/s6-ln.c')
-rw-r--r-- | src/skaembutils/s6-ln.c | 151 |
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) ; - } -} |