1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/* ISC license. */
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <skalibs/bytestr.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr2.h>
#include <skalibs/stralloc.h>
#include <skalibs/djbunix.h>
#include <skalibs/skamisc.h>
#include <s6/s6-supervise.h>
#include <s6-rc/s6rc-constants.h>
#define USAGE "s6-rc-update [ -l live ]"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "build string") ;
static char const *live = S6RC_LIVE_BASE ;
static int safe_servicedir_update (char const *dst, char const *src, int h)
{
unsigned int dstlen = str_len(dst) ;
unsigned int srclen = str_len(src) ;
int fd ;
int hasdata = 1, hasenv = 1, ok = 1 ;
char dstfn[dstlen + 15 + sizeof(S6_SUPERVISE_CTLDIR)] ;
char srcfn[srclen + 17] ;
char tmpfn[dstlen + 21] ;
byte_copy(dstfn, dstlen, dst) ;
byte_copy(srcfn, srclen, src) ;
byte_copy(dstfn + dstlen, 6, "/down") ;
fd = open_trunc(dstfn) ;
if (fd < 0) strerr_warnwu2sys("touch ", dstfn) ;
else close(fd) ;
byte_copy(dstfn + dstlen + 1, 5, "data") ;
byte_copy(tmpfn, dstlen + 5, dstfn) ;
byte_copy(tmpfn + dstlen + 5, 5, ".old") ;
if (rename(dstfn, tmpfn) < 0)
{
if (errno == ENOENT) hasdata = 0 ;
else goto err ;
}
byte_copy(dstfn + dstlen + 1, 4, "env") ;
byte_copy(tmpfn + dstlen + 1, 8, "env.old") ;
if (rename(dstfn, tmpfn) < 0)
{
if (errno == ENOENT) hasenv = 0 ;
else goto err ;
}
byte_copy(dstfn + dstlen + 1, 9, "nosetsid") ;
if (unlink(dstfn) < 0 && errno != ENOENT) goto err ;
byte_copy(dstfn + dstlen + 3, 14, "tification-fd") ;
if (unlink(dstfn) < 0 && errno != ENOENT) goto err ;
byte_copy(srcfn + srclen, 17, "/notification-fd") ;
hiercopy(srcfn, dstfn) ;
byte_copy(srcfn + srclen + 3, 7, "setsid") ;
byte_copy(dstfn + dstlen + 3, 7, "setsid") ;
hiercopy(srcfn, dstfn) ;
byte_copy(srcfn + srclen + 1, 5, "data") ;
byte_copy(dstfn + dstlen + 1, 5, "data") ;
hiercopy(srcfn, dstfn) ;
byte_copy(srcfn + srclen + 1, 4, "env") ;
byte_copy(dstfn + dstlen + 1, 4, "env") ;
hiercopy(srcfn, dstfn) ;
byte_copy(srcfn + srclen + 1, 4, "run") ;
byte_copy(dstfn + dstlen + 1, 4, "run") ;
if (!hiercopy(srcfn, dstfn)) goto err ;
byte_copy(srcfn + srclen + 1, 4, "run") ;
byte_copy(dstfn + dstlen + 1, 4, "finish") ;
hiercopy(srcfn, dstfn) ;
if (h)
{
byte_copy(dstfn + dstlen + 1, 5, "down") ;
if (unlink(dstfn) < 0)
{
strerr_warnwu2sys("unlink ", dstfn) ;
ok = 0 ;
}
byte_copy(dstfn + dstlen + 1, 8 + sizeof(S6_SUPERVISE_CTLDIR), S6_SUPERVISE_CTLDIR "/control") ;
s6_svc_write(dstfn, "u", 1) ;
}
byte_copy(dstfn + dstlen + 1, 9, "data.old") ;
if (rm_rf(dstfn) < 0) strerr_warnwu2sys("remove ", dstfn) ;
byte_copy(dstfn + dstlen + 1, 8, "env.old") ;
if (rm_rf(dstfn) < 0) strerr_warnwu2sys("remove ", dstfn) ;
return 1 ;
err:
if (h)
{
int e = errno ;
byte_copy(dstfn + dstlen + 1, 5, "down") ;
unlink(dstfn) ;
errno = e ;
}
return 0 ;
}
static int servicedir_name_change (char const *live, char const *oldname, char const *newname)
{
unsigned int livelen = str_len(live) ;
unsigned int oldlen = str_len(oldname) ;
unsigned int newlen = str_len(oldname) ;
char oldfn[livelen + oldlen + 2] ;
char newfn[livelen + newlen + 2] ;
byte_copy(oldfn, livelen, live) ;
oldfn[livelen] = '/' ;
byte_copy(oldfn + livelen + 1, oldlen + 1, oldname) ;
byte_copy(newfn, livelen + 1, oldfn) ;
byte_copy(newfn + livelen + 1, newlen + 1, newname) ;
if (rename(oldfn, newfn) < 0) return 0 ;
return 1 ;
}
int main (int argc, char const *const *argv)
{
PROG = "s6-rc-update" ;
strerr_dief1x(100, "this utility has not been written yet.") ;
}
|