diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-08-25 23:14:00 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-08-25 23:14:00 +0000 |
| commit | 4fb4eaecb937e3eddd8804c85ce20c80cc753480 (patch) | |
| tree | a0f530151558a3c721f0aaf9b0e4e28f183de8c0 /src/libs6rc/s6rc_servicedir_copy_online.c | |
| parent | fc91cc6cd1384a315a1f33bc83e6d6e9926fc791 (diff) | |
| download | s6-rc-4fb4eaecb937e3eddd8804c85ce20c80cc753480.tar.gz | |
Some refactor + add servicedir copy functions in libs6rc
Diffstat (limited to 'src/libs6rc/s6rc_servicedir_copy_online.c')
| -rw-r--r-- | src/libs6rc/s6rc_servicedir_copy_online.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/libs6rc/s6rc_servicedir_copy_online.c b/src/libs6rc/s6rc_servicedir_copy_online.c new file mode 100644 index 0000000..6e14844 --- /dev/null +++ b/src/libs6rc/s6rc_servicedir_copy_online.c @@ -0,0 +1,74 @@ +/* ISC license. */ + +#include <errno.h> +#include <unistd.h> +#include <stdio.h> +#include <skalibs/bytestr.h> +#include <skalibs/djbunix.h> +#include <s6-rc/s6rc-utils.h> +#include "s6rc-servicedir-internal.h" +#include <s6-rc/s6rc-servicedir.h> + +int s6rc_servicedir_copy_online (char const *src, char const *dst) +{ + unsigned int srclen = str_len(src) ; + unsigned int dstlen = str_len(dst) ; + unsigned int n ; + unsigned int i = 0 ; + int wantup = 0 ; + int e ; + char srcfn[srclen + s6rc_servicedir_file_maxlen + 6] ; + char dstfn[dstlen + s6rc_servicedir_file_maxlen + 6] ; + char oldfn[dstlen + s6rc_servicedir_file_maxlen + 6] ; + byte_copy(srcfn, srclen, src) ; + srcfn[srclen] = '/' ; + byte_copy(dstfn, dstlen + 1, dst) ; + byte_copy(oldfn, dstlen, dst) ; + byte_copy(oldfn + dstlen, 5, "/old") ; + if (rm_rf(oldfn) < 0 && errno != ENOENT) return 0 ; + if (mkdir(oldfn, 0755) < 0) return 0 ; + dstfn[dstlen] = '/' ; + oldfn[dstlen + 4] = '/' ; + wantup = s6rc_servicedir_block(dst) ; + if (wantup < 0) { e = errno ; goto errdir ; } + + for (; s6rc_servicedir_file_list[i].name ; i++) + { + str_copy(dstfn + dstlen + 1, s6rc_servicedir_file_list[i].name) ; + str_copy(oldfn + dstlen + 5, s6rc_servicedir_file_list[i].name) ; + if (rename(dstfn, oldfn) < 0) { e = errno ; goto errrename ; } + } + n = i ; + while (i--) + { + if (!s6rc_servicedir_copy_one(src, dst, s6rc_servicedir_file_list + i)) + { + e = errno ; + goto errremove ; + } + } + oldfn[dstlen + 4] = 0 ; + rm_rf(oldfn) ; + s6rc_servicedir_unblock(dst, wantup) ; + return 1 ; + + errremove: + for (; i < n ; i++) + { + str_copy(dstfn + dstlen + 1, s6rc_servicedir_file_list[i].name) ; + rm_rf(dstfn) ; + } + i = n ; + errrename: + while (i--) + { + str_copy(dstfn + dstlen + 1, s6rc_servicedir_file_list[i].name) ; + str_copy(oldfn + dstlen + 5, s6rc_servicedir_file_list[i].name) ; + rename(oldfn, dstfn) ; + } + errdir: + oldfn[dstlen + 4] = 0 ; + rmdir(oldfn) ; + errno = e ; + return 0 ; +} |
