Markdown.pm: make Markdown module available to use
[girocco.git] / install.sh
blob35abb48f936e8ba36726bed694711909519d4826
1 #!/bin/sh
2 # The Girocco installation script
3 # We will OVERWRITE basedir!
5 set -e
7 echol() { printf '%s\n' "$*"; }
8 warn() { printf >&2 '%s\n' "$*"; }
9 die() { warn "$@"; exit 1; }
11 # Include custom configuration, if any
12 [ ! -e config.sh ] || [ ! -f config.sh ] || [ ! -r config.sh ] || . ./config.sh
14 [ -n "$MAKE" ] || MAKE="$(MAKEFLAGS= make -s gnu_make_command_name | grep '^gnu_make_command_name=' | sed 's/^[^=]*=//')"
15 if [ -z "$MAKE" ]; then
16 echo "ERROR: cannot determine name of the GNU make command" >&2
17 echo "Please set MAKE to the name of the GNU make executable" >&2
18 exit 1
21 # Run perl module checker
22 if ! [ -f toolbox/check-perl-modules.pl ] || ! [ -x toolbox/check-perl-modules.pl ]; then
23 echo "ERROR: missing toolbox/check-perl-modules.pl!" >&2
24 exit 1
27 getconfbin="$(command -v getconf 2>/dev/null)" && [ -n "$getconfbin" ] ||
28 die "ERROR: missing getconf utility"
29 [ "$getconfbin" != "getconf" ] || die "ERROR: cannot handle a built-in getconf"
30 getconfpath="$("$getconfbin" PATH 2>/dev/null)" || die 'ERROR: `getconf PATH` failed'
31 [ -n "$getconfpath" ] || die 'ERROR: `getconf PATH` returned empty string'
33 # What Config should we use?
34 [ -n "$GIROCCO_CONF" ] || GIROCCO_CONF=Girocco::Config
35 export GIROCCO_CONF
36 echo "*** Initializing using $GIROCCO_CONF..."
38 # First run Girocco::Config consistency checks
39 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -e ''
41 . ./shlib.sh
42 umask 0022
44 # Check available perl modules
45 "$var_perl_bin" toolbox/check-perl-modules.pl
47 # Check for a tainted PATH configuration
48 perlprog="$(PATHCHECK="$cfg_path" "$var_perl_bin" -e '
49 print "delete \@ENV{qw(IFS CDPATH ENV BASH_ENV)}; ";
50 print "\$ENV{PATH} = \"".quotemeta($ENV{PATHCHECK})."\"; ";
51 print "my \$v = qx(\"\\\$GETCONFBIN\" PATH); defined(\$v) and chomp(\$v); ";
52 print "defined(\$v) && \$v ne \"\" or exit 1; exit 0;";')"
53 GETCONFBIN="$getconfbin" "$var_perl_bin" -T -e "$perlprog" || {
54 warn "ERROR: configured PATH failed Perl taint checks:"
55 warn " $cfg_path"
56 warn "(that means at least one of the directories in the path is writable by 'other')"
57 die "(or that at least one of the directories in the path is not an absolute path)"
60 # Config.pm already checked $cfg_reporoot to require an absolute path, but
61 # we also require it does not contain a : or ; that would cause problems when
62 # used in GIT_ALTERNATE_OBJECT_DIRECTORIES
63 probch=':;'
64 case "$cfg_reporoot" in *[$probch]*)
65 echo "fatal: \$Girocco::Config::reporoot may not contain ':' or ';' characters" >&2
66 exit 1
67 esac
69 # Either we must run as root (but preferably not if disable_jailsetup is true)
70 # or the mirror_user (preferred choice for disable_jailsetup).
71 isroot=
72 [ "$(id -u)" -ne 0 ] || isroot=1
73 if [ -n "$isroot" ]; then
74 if [ "${cfg_disable_jailsetup:-0}" != "0" ]; then
75 cat <<'EOT'
77 ***
78 *** WARNING: $Girocco::Config::disable_jailsetup has been enabled
79 *** WARNING: but installation is being performed as the superuser
80 ***
82 You appear to have disabled jailsetup which is perfectly fine for installations
83 that will not be using an ssh jail. However, in that case, running the install
84 process as the superuser is highly discouraged.
86 Instead, running it as the configured $Girocco::Config::mirror_user is much
87 preferred.
89 The install process will now pause for 10 seconds to give you a chance to abort
90 it before continuing to install a disable_jailsetup config as the superuser.
92 EOT
93 sleep 10 || die "install aborted"
95 else
96 [ -n "$cfg_mirror_user" ] || die 'Girocco::Config.pm $mirror_user must be set'
97 curuname="$(id -un)"
98 [ -n "$curuname" ] || die "Cannot determine name of current user"
99 if [ "$cfg_mirror_user" != "$curuname" ]; then
100 warn "ERROR: install must run as superuser or Config.pm's \$mirror_user ($cfg_mirror_user)"
101 die "ERROR: install is currently running as $curuname"
105 # $1 must exist and be a dir
106 # $2 may exist but must be a dir
107 # $3 must not exist
108 # After call $2 will be renamed to $3 (if $2 existed)
109 # And $1 will be renamed to $2
110 quick_move() {
111 [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] || { echo "fatal: quick_move: bad args: '$1' '$2' '$3'" >&2; exit 1; }
112 ! [ -e "$3" ] || { echo "fatal: quick_move: already exists: $3" >&2; exit 1; }
113 [ -d "$1" ] || { echo "fatal: quick_move: no such dir: $1" >&2; exit 1; }
114 ! [ -e "$2" ] || [ -d "$2" ] || { echo "fatal: quick_move: not a dir: $2" >&2; exit 1; }
115 perl -e 'my @a; $ARGV[0] =~ m|^(/.+)$| and $a[0] = $1; $ARGV[1] =~ m|^(/.+)$| and $a[1] = $1;
116 $ARGV[2] =~ m|^(/.+)$| and $a[2] = $1; defined($a[0]) && defined($a[1]) && defined($a[2])
117 or die "bad arguments -- three absolute paths required";
118 rename($a[1], $a[2]) or die "rename failed: $!\n" if -d $a[1];
119 rename($a[0], $a[1]) or die "rename failed: $!\n"; exit 0;' "$1" "$2" "$3" || {
120 echo "fatal: quick_move: rename failed" >&2
121 exit 1
123 ! [ -d "$1" ] && [ -d "$2" ] || {
124 echo "fatal: quick_move: rename failed" >&2
125 exit 1
129 check_sh_builtin() (
130 "unset" -f command
131 "command" "$var_sh_bin" -c '{ "unset" -f unalias command "$1" || :; "unalias" "$1" || :; } >/dev/null 2>&1; "command" -v "$1"' "$var_sh_bin" "$1"
132 ) 2>/dev/null
134 owngroup=
135 [ -z "$cfg_owning_group" ] || owngroup=":$cfg_owning_group"
136 if [ -n "$cfg_httpspushurl" ] && [ -z "$cfg_certsdir" ]; then
137 echo "ERROR: \$httpspushurl is set but \$certsdir is not!" >&2
138 echo "ERROR: perhaps you have an incorrect Config.pm?" >&2
139 exit 1
143 # Check for extra required tools
144 if [ "${cfg_xmllint_readme:-0}" != "0" ] && ! command -v xmllint >/dev/null; then
145 echo "ERROR: \$xmllint_readme set but xmllint not in \$PATH!" >&2
146 exit 1
150 echo "*** Checking for compiled utilities..."
151 if ! [ -f src/can_user_push ] || ! [ -x src/can_user_push ]; then
152 echo "ERROR: src/can_user_push is not built! Did you _REALLY_ read INSTALL?" >&2
153 echo "ERROR: perhaps you forgot to run make?" >&2
154 exit 1
156 if ! [ -f src/can_user_push_http ] || ! [ -x src/can_user_push_http ]; then
157 echo "ERROR: src/can_user_push_http is not built! Did you _REALLY_ read INSTALL?" >&2
158 echo "ERROR: perhaps you forgot to run make?" >&2
159 exit 1
161 if ! [ -f src/getent ] || ! [ -x src/getent ]; then
162 echo "ERROR: src/getent is not built! Did you _REALLY_ read INSTALL?" >&2
163 echo "ERROR: perhaps you forgot to run make?" >&2
164 exit 1
166 if ! [ -f src/get_sun_path_len ] || ! [ -x src/get_sun_path_len ]; then
167 echo "ERROR: src/get_sun_path_len is not built! Did you _REALLY_ read INSTALL?" >&2
168 echo "ERROR: perhaps you forgot to run make?" >&2
169 exit 1
171 if ! [ -f src/get_user_uuid ] || ! [ -x src/get_user_uuid ]; then
172 echo "ERROR: src/get_user_uuid is not built! Did you _REALLY_ read INSTALL?" >&2
173 echo "ERROR: perhaps you forgot to run make?" >&2
174 exit 1
176 if ! [ -f src/list_packs ] || ! [ -x src/list_packs ]; then
177 echo "ERROR: src/list_packs is not built! Did you _REALLY_ read INSTALL?" >&2
178 echo "ERROR: perhaps you forgot to run make?" >&2
179 exit 1
181 if ! [ -f src/peek_packet ] || ! [ -x src/peek_packet ]; then
182 echo "ERROR: src/peek_packet is not built! Did you _REALLY_ read INSTALL?" >&2
183 echo "ERROR: perhaps you forgot to run make?" >&2
184 exit 1
186 if ! [ -f src/rangecgi ] || ! [ -x src/rangecgi ]; then
187 echo "ERROR: src/rangecgi is not built! Did you _REALLY_ read INSTALL?" >&2
188 echo "ERROR: perhaps you forgot to run make?" >&2
189 exit 1
191 if ! [ -f src/readlink ] || ! [ -x src/readlink ]; then
192 echo "ERROR: src/readlink is not built! Did you _REALLY_ read INSTALL?" >&2
193 echo "ERROR: perhaps you forgot to run make?" >&2
194 exit 1
196 if ! [ -f src/strftime ] || ! [ -x src/strftime ]; then
197 echo "ERROR: src/strftime is not built! Did you _REALLY_ read INSTALL?" >&2
198 echo "ERROR: perhaps you forgot to run make?" >&2
199 exit 1
201 if ! [ -f src/throttle ] || ! [ -x src/throttle ]; then
202 echo "ERROR: src/throttle is not built! Did you _REALLY_ read INSTALL?" >&2
203 echo "ERROR: perhaps you forgot to run make?" >&2
204 exit 1
206 if ! [ -f src/ulimit512 ] || ! [ -x src/ulimit512 ]; then
207 echo "ERROR: src/ulimit512 is not built! Did you _REALLY_ read INSTALL?" >&2
208 echo "ERROR: perhaps you forgot to run make?" >&2
209 exit 1
211 ebin="/bin/echo"
212 if [ ! -x "$ebin" ] && [ -x "/usr/bin/echo" ]; then
213 ebin="/usr/bin/echo"
215 if [ ! -x "$ebin" ]; then
216 echo "ERROR: neither /bin/echo nor /usr/bin/echo found" >&2
217 echo "ERROR: at least one must be present for testing during install" >&2
218 exit 1
220 ec=999
221 tmpfile="$(mktemp "/tmp/ul512-$$-XXXXXX")"
222 { src/ulimit512 -f 0 "$ebin" test >"$tmpfile" || ec=$?; } >/dev/null 2>&1
223 rm -f "$tmpfile"
224 if [ "$ec" = "999" ] || [ "$ec" = "0" ]; then
225 echo "ERROR: src/ulimit512 is built, but broken!" >&2
226 echo "ERROR: exceeding file size limit did not fail!" >&2
227 exit 1
229 if ! [ -f src/ltsha256 ] || ! [ -x src/ltsha256 ]; then
230 echo "ERROR: src/ltsha256 is not built! Did you _REALLY_ read INSTALL?" >&2
231 echo "ERROR: perhaps you forgot to run make?" >&2
232 exit 1
234 sha256check="15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"
235 sha256result="$(printf '%s' '123456789' | src/ltsha256)"
236 if [ "$sha256check" != "$sha256result" ]; then
237 echo "ERROR: src/ltsha256 is built, but broken!" >&2
238 echo "ERROR: verifying sha256 hash of '123456789' failed!" >&2
239 exit 1
241 if ! [ -f src/ltsha1 ] || ! [ -x src/ltsha1 ]; then
242 echo "ERROR: src/ltsha1 is not built! Did you _REALLY_ read INSTALL?" >&2
243 echo "ERROR: perhaps you forgot to run make?" >&2
244 exit 1
246 sha1check="f7c3bc1d808e04732adf679965ccc34ca7ae3441"
247 sha1result="$(printf '%s' '123456789' | src/ltsha1)"
248 if [ "$sha1check" != "$sha1result" ]; then
249 echo "ERROR: src/ltsha1 is built, but broken!" >&2
250 echo "ERROR: verifying sha1 hash of '123456789' failed!" >&2
251 exit 1
253 var_sun_path_len="$(src/get_sun_path_len 2>/dev/null)" || :
255 [ -z "$var_sun_path_len" ] ||
256 [ "${var_sun_path_len#*[!0-9]}" != "$var_sun_path_len" ] ||
257 [ "$var_sun_path_len" -lt 80 ] || [ "$var_sun_path_len" -gt 4096 ]
258 then
259 echol "ERROR: src/get_sun_path_len is built, but bogus!" >&2
260 echol "ERROR: reports sizeof(struct sockaddr_un.sun_path) is '$var_sun_path_len'" >&2
261 exit 1
263 taskdsockpath="$cfg_chroot/etc/taskd.socket@" # "@" stands in for the NUL byte
264 if [ "${#taskdsockpath}" -gt "$var_sun_path_len" ]; then
265 echol "ERROR: maximum length of sockaddr_un.sun_path is $var_sun_path_len" >&2
266 echol "ERROR: the configured taskd.socket path has length ${#taskdsockpath}" >&2
267 echol "ERROR: reduce the length of \$Girocco::Config::chroot to shorten" >&2
268 echol "ERROR: '${taskdsockpath%?}'" >&2
269 echol "ERROR: to fit (including the final '\\0' byte)" >&2
270 exit 1
274 echo "*** Checking for ezcert..."
275 if ! [ -f ezcert.git/CACreateCert ] || ! [ -x ezcert.git/CACreateCert ]; then
276 echo "ERROR: ezcert.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
277 exit 1
281 echo "*** Checking for git..."
282 case "$cfg_git_bin" in /*) :;; *)
283 echo 'ERROR: $Girocco::Config::git_bin must be set to an absolute path' >&2
284 exit 1
285 esac
286 if ! [ -f "$cfg_git_bin" ] || ! [ -x "$cfg_git_bin" ]; then
287 echo "ERROR: $cfg_git_bin does not exist or is not executable" >&2
288 exit 1
290 if ! git_version="$("$cfg_git_bin" version)" || [ -z "$git_version" ]; then
291 echo "ERROR: $cfg_git_bin version failed" >&2
292 exit 1
294 case "$git_version" in
295 [Gg]"it version "*) :;;
297 echo "ERROR: '$cfg_git_bin version' output does not start with 'git version '" >&2
298 exit 1
299 esac
300 echo "Found $cfg_git_bin $git_version"
301 git_vernum="$(echo "$git_version" | sed -ne 's/^[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/p')"
302 echo "*** Checking Git $git_vernum for compatibility..."
303 if [ "$(vcmp "$git_vernum" 1.6.6)" -lt 0 ]; then
304 echo 'ERROR: $Girocco::Config::git_bin must be at least Git version 1.6.6'
305 exit 1
307 if [ "$(vcmp "$git_vernum" 1.6.6.3)" -lt 0 ]; then
308 echo 'WARNING: $Girocco::Config::git_bin version < 1.6.6.3, clients will not see useful error messages'
310 if [ "$(vcmp "$git_vernum" 1.7.3)" -lt 0 ]; then
311 cat <<'EOT'
314 *** SEVERE WARNING: $Girocco::Config::git_bin is set to a version of Git before 1.7.3
317 Some Girocco functionality will be gracefully disabled and other things will
318 just not work at all such as race condition protection against simultaneous
319 client pushes and server garbage collections.
323 if [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 1.7.5)" -lt 0 ]; then
324 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.5 and mirroring enabled, some sources can cause an infinite fetch loop'
326 if [ "$(vcmp "$git_vernum" 1.7.6.6)" -lt 0 ]; then
327 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.6.6, performance may be degraded'
329 if [ "$(uname -m 2>/dev/null)" = "x86_64" ] && [ "$(vcmp "$git_vernum" 1.7.11)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.0)" -lt 0 ]; then
330 echo 'WARNING: $Girocco::Config::git_bin version >= 1.7.11 and < 2.12.0 and x86_64, make sure Git built WITHOUT XDL_FAST_HASH'
331 echo 'WARNING: See https://lore.kernel.org/git/20141222041944.GA441@peff.net/ for details'
333 if [ "$(vcmp "$git_vernum" 1.8.4.2)" -ge 0 ] && [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 2)" -lt 0 ]; then
334 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, git-daemon needs write access for shallow clones'
335 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, shallow clones will leave repository turds'
337 if [ "$(vcmp "$git_vernum" 1.8.4.3)" -lt 0 ]; then
338 echo 'WARNING: $Girocco::Config::git_bin version < 1.8.4.3, clients will not receive symref=HEAD:refs/heads/...'
340 if [ "$(vcmp "$git_vernum" 2.1)" -lt 0 ]; then
341 echo 'WARNING: $Girocco::Config::git_bin version < 2.1.0, pack bitmaps will not be available'
343 if [ "$(vcmp "$git_vernum" 2.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.1.3)" -lt 0 ]; then
344 echo 'WARNING: $Girocco::Config::git_bin version >= 2.1.0 and < 2.1.3, pack bitmaps may not be reliable, please upgrade to at least Git version 2.1.3'
346 if [ "$(vcmp "$git_vernum" 2.2)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.3.2)" -lt 0 ]; then
347 cat <<'EOT'
350 *** ERROR: $Girocco::Config::git_bin is set to an incompatible version of Git
353 Git versions starting with 2.2.0 and continuing up through 2.3.1 are incompatible
354 with Girocco due to various unresolved issues. Please either downgrade to 2.1.4
355 or earlier or, more preferred, upgrade to 2.3.2 (ideally 2.4.11) or later.
357 In order to bypass this check you will have to modify install.sh in which case
358 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
361 exit 1
363 if [ "$(vcmp "$git_vernum" 2.3.3)" -lt 0 ]; then
364 echo 'WARNING: $Girocco::Config::git_bin version < 2.3.3, performance will be sub-optimal'
366 if [ "$(vcmp "$git_vernum" 2.4.4)" -lt 0 ]; then
367 echo 'WARNING: $Girocco::Config::git_bin version < 2.4.4, many refs smart HTTP fetches can deadlock'
369 if [ "$(vcmp "$git_vernum" 2.10.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.3)" -lt 0 ]; then
370 echo 'WARNING: $Girocco::Config::git_bin version >= 2.10.1 and < 2.12.3, --pickaxe-regex can segfault'
371 echo 'WARNING: If gitweb pickaxe regular expression searches are enabled, --pickaxe-regex will be used'
372 echo 'WARNING: See the fix at http://repo.or.cz/git.git/f53c5de29cec68e3 for details'
373 echo 'WARNING: The fix is trivial and easily cherry-picked into a custom 2.10.1 - 2.12.2 build'
374 echo 'WARNING: Leaving the gitweb/gitweb_config.perl "regexp" feature off as recommended avoids the issue'
376 secmsg=
377 if [ "$(vcmp "$git_vernum" 2.4.11)" -lt 0 ]; then
378 secmsg='prior to 2.4.11'
380 if [ "$(vcmp "$git_vernum" 2.5)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.5.5)" -lt 0 ]; then
381 secmsg='2.5.x prior to 2.5.5'
383 if [ "$(vcmp "$git_vernum" 2.6)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.6.6)" -lt 0 ]; then
384 secmsg='2.6.x prior to 2.6.6'
386 if [ "$(vcmp "$git_vernum" 2.7)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.7.4)" -lt 0 ]; then
387 secmsg='2.7.x prior to 2.7.4'
389 if [ -n "$secmsg" ]; then
390 cat <<EOT
393 *** SEVERE WARNING: \$Girocco::Config::git_bin is set to a version of Git $secmsg
396 Security issues exist in Git versions prior to 2.4.11, 2.5.x prior to 2.5.5,
397 2.6.x prior to 2.6.6 and 2.7.x prior to 2.7.4.
399 Besides the security fixes included in later versions, versions prior to
400 2.2.0 may accidentally prune unreachable loose objects earlier than
401 intended. Since Git version 2.4.11 is the minimum version to include all
402 security fixes to date, it should be considered the absolute minimum
403 version of Git to use when running Girocco.
405 This is not enforced, but Git is easy to build from the git.git submodule
406 and upgrading to GIT VERSION 2.4.11 OR LATER IS HIGHLY RECOMMENDED.
408 We will now pause for a moment so you can reflect on this warning.
411 sleep 60
413 if [ -n "$cfg_mirror" ] && [ "$cfg_mirror" != 0 ] && LC_ALL=C grep -a -q ns_parserr "$cfg_git_bin"; then
414 cat <<'EOT'
417 *** WARNING: $Girocco::Config::git_bin is set to a questionable Git binary
420 You appear to have enabled mirroring and the Git binary you have selected
421 appears to contain an experimental patch that cannot be disabled. This
422 patch can generate invalid network DNS traffic and/or cause long delays
423 when fetching using the "git:" protocol when no port number is specified.
424 It may also end up retrieving repsitory contents from a host other than
425 the one specified in the "git:" URL when the port is omitted.
427 You are advised to either build your own version of Git (the problem patch
428 is not part of the official Git repository) or disable mirroring (via the
429 $Girocco::Config:mirror setting) to avoid these potential problems.
431 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
434 sleep 5
437 test_nc_U() {
438 [ -n "$1" ] || return 1
439 _cmdnc="$(command -v "$1" 2>/dev/null)" || :
440 [ -n "$_cmdnc" ] && [ -f "$_cmdnc" ] && [ -x "$_cmdnc" ] || return 1
441 _tmpdir="$(mktemp -d /tmp/nc-u-XXXXXX)"
442 [ -n "$_tmpdir" ] && [ -d "$_tmpdir" ] || return 1
443 >"$_tmpdir/output"
444 (sleep 3 | "$_cmdnc" -l -U "$_tmpdir/socket" 2>/dev/null >"$_tmpdir/output" || >"$_tmpdir/failed")&
445 _bgpid="$!"
446 sleep 1
447 echo "testing" | "$_cmdnc" -w 1 -U "$_tmpdir/socket" >/dev/null 2>&1 || >"$_tmpdir/failed"
448 sleep 1
449 kill "$_bgpid" >/dev/null 2>&1 || :
450 read -r _result <"$_tmpdir/output" || :
451 _bad=
452 ! [ -e "$_tmpdir/failed" ] || _bad=1
453 rm -rf "$_tmpdir"
454 [ -z "$_bad" ] && [ "$_result" = "testing" ]
455 } >/dev/null 2>&1
457 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
458 test_nc_U "$var_nc_openbsd_bin" || {
459 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
460 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
461 uname_s="$(uname -s 2>/dev/null | tr A-Z a-z 2>/dev/null)" || :
462 case "$uname_s" in
463 *dragonfly*)
464 echo "ERROR: see the src/dragonfly/README file for a solution" >&2;;
465 *kfreebsd*|*linux*)
466 echo "ERROR: try installing the package named 'netcat-openbsd'" >&2;;
467 esac
468 exit 1
471 echo "*** Verifying selected POSIX sh is sane..."
472 shbin="$var_sh_bin"
473 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
474 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
475 exit 1
477 [ "$(check_sh_builtin command)" = "command" ] || {
478 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
479 exit 1
481 sh_not_builtin=
482 sh_extra_chroot_installs=
483 badsh=
484 for sbi in cd pwd read umask unset unalias; do
485 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
486 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
487 badsh=1
489 done
490 [ -z "$badsh" ] || exit 1
491 for sbi in '[' echo printf test; do
492 if ! extra="$(check_sh_builtin "$sbi")"; then
493 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
494 badsh=1
495 continue
497 if [ "$extra" != "$sbi" ]; then
498 case "$extra" in /*) :;; *)
499 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
500 badsh=1
501 continue
502 esac
503 withspc=
504 case "$extra" in *" "*) withspc=1; esac
505 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
506 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
507 badsh=1
508 continue
510 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
511 sh_not_builtin="$sh_not_builtin $sbi"
512 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
514 done
515 [ -z "$badsh" ] || exit 1
516 [ -z "$sh_extra_chroot_installs" ] || {
517 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
518 echo "WARNING: as a result it will run slower than necessary" >&2
519 echo "WARNING: consider building and switching to dash which can be found at:" >&2
520 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
521 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
522 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
523 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
526 echo "*** Verifying xargs is sane..."
527 _xargsr="$(</dev/null command xargs printf %s -r)" || :
528 xtest1="$(</dev/null command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
529 xtest2="$(printf '%s\n' one two | command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
530 [ -z "$xtest1" ] && [ "$xtest2" = "test one test two " ] || {
531 echo 'ERROR: xargs is unusable' >&2
532 echo 'ERROR: either `test -z "$(</dev/null xargs echo test 2>/dev/null)"`' >&2
533 echo 'ERROR: or `test -z "$(</dev/null xargs -r echo test 2>/dev/null)"`' >&2
534 echo 'ERROR: must be true, but neither is' >&2
535 exit 1
538 echo "*** Verifying selected perl is sane..."
539 perlbin="$var_perl_bin"
540 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
541 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
542 exit 1
545 echo "*** Verifying selected gzip is sane..."
546 gzipbin="$var_gzip_bin"
547 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
548 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
549 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
550 exit 1
553 echo "*** Verifying basedir, webroot, webreporoot and cgiroot paths..."
554 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
555 case "$cfg_basedir" in /*) :;; *)
556 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
557 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
558 exit 1
559 esac
560 case "$cfg_webroot" in /*) :;; *)
561 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
562 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
563 exit 1
564 esac
565 if [ -n "$cfg_webreporoot" ]; then
566 case "$cfg_webreporoot" in /*) :;; *)
567 echo "ERROR: invalid Girocco::Config::webreporoot setting" >&2
568 echo "ERROR: \"$cfg_webreporoot\" must be an absolute path (start with '/') or undef" >&2
569 exit 1
570 esac
572 case "$cfg_cgiroot" in /*) :;; *)
573 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
574 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
575 exit 1
576 esac
578 # return the input with trailing slashes stripped but return "/" for all "/"s
579 striptrsl() {
580 [ -n "$1" ] || return 0
581 _s="${1##*[!/]}"
582 [ "$_s" != "$1" ] || _s="${_s#?}"
583 printf "%s\n" "${1%$_s}"
586 # a combination of realpath + dirname where the realpath of the deepest existing
587 # directory is returned with the rest of the non-existing components appended
588 # and trailing slashes and multiple slashes are removed
589 realdir() {
590 _d="$(striptrsl "$1")"
591 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
592 echo "$_d"
593 return 0
595 _c=""
596 while ! [ -d "$_d" ]; do
597 _c="/$(basename "$_d")$_c"
598 _d="$(dirname "$_d")"
599 [ "$_d" != "/" ] || _c="${_c#/}"
600 done
601 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
604 # Use basedir, webroot and cgiroot for easier control of filesystem locations
605 # Wherever we are writing/copying/installing files we use these, but where we
606 # are editing, adding config settings or printing advice we always stick to the
607 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
608 # Only the file system directories that could be asynchronously accessed (by
609 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
610 # The chroot is handled specially and does not need one of these.
611 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
612 # case the prior contents of cgiroot and/or webroot are discarded.
613 rbasedir="$(realdir "$cfg_basedir")"
614 rwebroot="$(realdir "$cfg_webroot")"
615 rwebreporoot=
616 [ -z "$cfg_webreporoot" ] || {
617 # avoid resolving a pre-existing symlink from a previous install
618 rwebreporoot="$(realdir "${cfg_webreporoot%/}_NOSUCHDIR")"
619 rwebreporoot="${rwebreporoot%_NOSUCHDIR}"
621 rcgiroot="$(realdir "$cfg_cgiroot")"
622 case "$rbasedir" in "$rwebroot"/?*)
623 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
624 exit 1
625 esac
626 case "$rbasedir" in "$rcgiroot"/?*)
627 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
628 exit 1
629 esac
630 if [ "$rwebroot" = "$rcgiroot" ]; then
631 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
632 exit 1
634 case "$rcgiroot" in "$rwebroot"/?*)
635 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
636 exit 1
637 esac
638 case "$rwebroot" in "$rcgiroot"/?*)
639 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
640 exit 1
641 esac
642 if [ -n "$rwebreporoot" ]; then
643 if [ "$rwebreporoot" = "$rwebroot" ]; then
644 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::webreporoot settings; must not be the same" >&2
645 exit 1
647 case "$rwebreporoot" in "$rwebroot"/?*);;*)
648 echo "ERROR: invalid Girocco::Config::webreporoot setting; must be under webroot or undef" >&2
649 exit 1
650 esac
652 basedir="$rbasedir-new"
653 case "$rwebroot" in
654 "$rbasedir"/?*)
655 webroot="$basedir${rwebroot#$rbasedir}"
656 webrootsub=1
659 webroot="$rwebroot-new"
660 webrootsub=
662 esac
663 webreporoot=
664 [ -z "$rwebreporoot" ] || webreporoot="$webroot${rwebreporoot#$rwebroot}"
665 case "$rcgiroot" in
666 "$rbasedir"/?*)
667 cgiroot="$basedir${rcgiroot#$rbasedir}"
668 cgirootsub=1
671 cgiroot="$rcgiroot-new"
672 cgirootsub=
674 esac
676 echo "*** Setting up basedir..."
678 chown_make() {
679 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
680 find -H "$@" -user root -exec chown "$SUDO_USER:$(id -gn "$SUDO_USER")" '{}' + 2>/dev/null || :
681 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
682 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
686 "$MAKE" --no-print-directory --silent apache.conf
687 chown_make apache.conf
688 "$MAKE" --no-print-directory --silent -C src
689 chown_make src
690 rm -fr "$basedir"
691 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
692 # make the mtlinesfile with 1000 empty lines
693 yes '' | dd bs=1000 count=1 2>/dev/null >"$basedir/mtlinesfile"
694 chmod a+r "$basedir/mtlinesfile"
695 cp cgi/*.cgi "$basedir/cgi"
696 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
697 rm -f "$basedir/Girocco/Dumper.pm" # Dumper.pm is only for the install.sh process
698 rm -f "$basedir/Girocco/Validator.pm" # Validator.pm is only for the install.sh process
699 find -H "$basedir" -type l -exec rm -f '{}' +
700 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
701 src/rangecgi src/readlink src/strftime src/throttle src/ulimit512 src/ltsha256 \
702 ezcert.git/CACreateCert cgi/authrequired.cgi cgi/snapshot.cgi \
703 "$basedir/bin"
704 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
705 if [ -n "$cfg_httpspushurl" ]; then
706 [ -z "$cfg_pretrustedroot" ] || rm -f "$basedir"/html/rootcert.html
707 else
708 rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
710 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
712 # Put the frozen Config in place
713 VARLIST="$(get_girocco_config_var_list varonly)" && export VARLIST
714 perl -I"$PWD" -MGirocco::Dumper=FreezeConfig -MScalar::Util=looks_like_number -e '
715 my $usemod = $ARGV[0];
716 my $f = sub { return () unless $_[0] =~ /^(var_[^=\s]+)=(.*)$/;
717 my ($k,$v) = ($1,$2);
718 $v =~ s/([\@\%])/\\$1/gos;
719 $v = "\"".$v."\"" unless substr($v,0,1) eq "\"" || looks_like_number($v);
720 my $e = eval $v;
721 [$k, $e] };
722 my @vars = map({&$f($_)} split(/\n+/, $ENV{VARLIST}));
723 my $s = sub { my $conf = shift;
724 foreach (@vars) {
725 my ($k,$v) = @{$_};
726 eval "\$${conf}::$k=\$v";
729 print FreezeConfig([$usemod,"Girocco::Validator"], undef, $s);
730 ' -- "$GIROCCO_CONF" >"$basedir/Girocco/Config.pm"
731 unset VARLIST
733 # Create symbolic links to selected binaries
734 ln -s "$cfg_git_bin" "$basedir/bin/git"
735 ln -s "$shbin" "$basedir/bin/sh"
736 ln -s "$perlbin" "$basedir/bin/perl"
737 ln -s "$gzipbin" "$basedir/bin/gzip"
738 [ -z "$var_openssl_bin" ] || ln -s "$var_openssl_bin" "$basedir/bin/openssl"
740 echo "*** Preprocessing scripts..."
741 SHBIN="$shbin" && export SHBIN
742 PERLBIN="$perlbin" && export PERLBIN
743 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
744 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
745 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
746 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
747 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
748 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
749 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
750 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
751 -e 's/\@cgiroot\@/"$Girocco::Config::cgiroot"/g;' \
752 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
753 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
754 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
755 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
756 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
757 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
758 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
759 -e 's/\@autogchack\@/"$Girocco::Config::autogchack"/g;' \
760 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
761 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
762 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
763 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
764 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
765 -e 's/\@fetch_stash_refs\@/"$Girocco::Config::fetch_stash_refs"/g;' \
766 -e 's/\@suppress_git_ssh_logging\@/"$Girocco::Config::suppress_git_ssh_logging"/g;' \
767 -e 's/\@max_file_size512\@/"$Girocco::Config::max_file_size512"/g;' \
768 -e 'close ARGV if eof;' \
769 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
770 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
771 "$basedir"/shlib.sh "$basedir"/hooks/* \
772 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
773 "$basedir"/toolbox/reports/*.sh \
774 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
775 "$basedir"/bin/create-* "$basedir"/bin/update-* \
776 "$basedir"/bin/*.cgi "$basedir"/screen/*
777 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
778 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
779 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
780 "$basedir"/cgi/*.cgi "$basedir"/gitweb/*.perl \
781 "$basedir"/jobd/*.pl "$basedir"/taskd/*.pl
782 perl -i -p \
783 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
784 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
785 -e 'close ARGV if eof;' \
786 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
787 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
788 perl -i -p \
789 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
790 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
791 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
792 -e 'close ARGV if eof;' \
793 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
794 unset PERLBIN
795 unset SHBIN
797 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
798 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
800 if [ "${cfg_mirror_darcs:-0}" != "0" ]; then
801 echo "*** Setting up darcs-fast-export from girocco-darcs-fast-export.git..."
802 if ! [ -f girocco-darcs-fast-export.git/darcs-fast-export ] ||
803 ! [ -x girocco-darcs-fast-export.git/darcs-fast-export ]; then
804 echo "ERROR: girocco-darcs-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
805 exit 1
807 mkdir -p "$basedir"/bin
808 cp girocco-darcs-fast-export.git/darcs-fast-export "$basedir"/bin
811 if [ "${cfg_mirror_hg:-0}" != "0" ]; then
812 echo "*** Setting up hg-fast-export from girocco-hg-fast-export.git..."
813 if ! [ -f girocco-hg-fast-export.git/hg-fast-export.py ] || ! [ -f girocco-hg-fast-export.git/hg2git.py ]; then
814 echo "ERROR: girocco-hg-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
815 exit 1
817 mkdir -p "$basedir"/bin
818 cp girocco-hg-fast-export.git/hg-fast-export.py girocco-hg-fast-export.git/hg2git.py "$basedir"/bin
821 echo "*** Setting up markdown from markdown.git..."
822 if ! [ -f markdown.git/Markdown.pl ]; then
823 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
824 exit 1
826 mkdir -p "$basedir"/bin
827 (PERLBIN="$perlbin" && export PERLBIN &&
828 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
829 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
830 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
831 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
832 test $? -eq 0
833 (umask 0133 && ln -s -f -n bin/Markdown.pl "$basedir"/Markdown.pm)
834 test $? -eq 0
836 # Some permission sanity on basedir/bin just in case
837 find -H "$basedir"/bin -type f -exec chmod go-w '{}' +
838 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
840 if [ -n "$cfg_mirror" ]; then
841 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
843 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.pl, or add this"
844 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
845 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.pl -q --all-once"
848 echo "*** Setting up repository root..."
849 [ -d "$cfg_reporoot" ] || {
850 mkdir -p "$cfg_reporoot"
851 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot" ||
852 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot"
854 [ -z "$cfg_owning_group" ] ||
855 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
856 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
857 mkdir -p "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty"
858 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" ||
859 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot/{_recyclebin,_global} properly"
860 if [ "$cfg_owning_group" ]; then
861 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
862 chgrp -R "$cfg_owning_group" "$cfg_reporoot/_global" || echo "WARNING: Cannot chgrp -R $cfg_owning_group $cfg_reporoot/_global"
864 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
865 chmod 00755 "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" || echo "WARNING: Cannot chmod $cfg_reporoot/_global properly"
868 usejail=
869 [ "${cfg_disable_jailsetup:-0}" != "0" ] || [ "${cfg_chrooted:-0}" = "0" ] || usejail=1
870 if [ -n "$usejail" ]; then
871 echo "*** Setting up chroot jail for pushing..."
872 if [ -n "$isroot" ]; then
873 # jailsetup may install things from $cfg_basedir/bin into the
874 # chroot so we do a mini-update of just that portion now
875 mkdir -p "$cfg_basedir"
876 rm -rf "$cfg_basedir/bin-new"
877 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
878 rm -rf "$cfg_basedir/bin-old"
879 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
880 rm -rf "$cfg_basedir/bin-old"
881 if [ -n "$sh_extra_chroot_installs" ]; then
882 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
883 export GIROCCO_CHROOT_EXTRA_INSTALLS
885 ./jailsetup.sh
886 unset GIROCCO_CHROOT_EXTRA_INSTALLS
887 else
888 echo "WARNING: Skipping jail setup, not root"
893 echo "*** Setting up jail configuration (project database)..."
894 [ -n "$usejail" ] && [ -n "$isroot" ] || ./jailsetup.sh dbonly
895 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
896 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
897 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
898 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
899 if [ -n "$usejail" ]; then
900 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
901 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
902 else
903 # If a chroot jail is not in use, sudo privileges are neither expected nor required
904 # which means it will not be possible to change the owner of the passwd and group
905 # files if it differs from the mirror user. And that's okay, provided the group
906 # can still be set correctly to the owning group. But, just in case we're running
907 # as root, go ahead and set the owner to the mirror user.
908 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
909 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup the etc/passwd and/or etc/group files"
911 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
912 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
913 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
916 echo "*** Setting up global hook scripts..."
917 # It is absolutely CRUCIAL that hook script replacements are done atomically!
918 # Otherwise an incoming push might slip in and fail to run the hook script!
919 # The underlying rename(2) function call provides this and mv will use it.
920 # First add hook scripts
921 hooks="pre-auto-gc pre-receive post-commit post-receive update"
922 for hook in $hooks; do
923 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
924 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
925 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
926 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
927 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
928 done
929 # Then remove any hook scripts that do not belong
930 for hook in "$cfg_reporoot/_global/hooks"/*; do
931 hook="${hook##*/}"
932 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
933 case " $hooks " in *" $hook "*);;*)
934 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
935 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
936 esac
937 done
940 echo "*** Setting up gitweb from git.git..."
941 if ! [ -f git.git/Makefile ]; then
942 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
943 exit 1
946 # We do not wholesale replace either webroot or cgiroot unless they are under
947 # basedir so if they exist and are not we make a copy to start working on them.
948 # We make a copy using -p which can result in some warnings so we suppress
949 # error output as it's of no consequence in this case.
950 rm -rf "$webroot" "$cgiroot"
951 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
952 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
953 mkdir -p "$webroot" "$cgiroot"
956 cd git.git &&
957 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
958 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
959 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
960 chown_make gitweb &&
961 PERLBIN="$perlbin" && export PERLBIN &&
962 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
963 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
964 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
965 chown_make "$cgiroot"/gitweb.cgi.$$ &&
966 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
967 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
969 test $? -eq 0
972 echo "*** Setting up git-browser from git-browser.git..."
973 if ! [ -f git-browser.git/git-browser.cgi ]; then
974 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
975 exit 1
977 mkdir -p "$webroot"/git-browser "$cgiroot"
979 cd git-browser.git &&
980 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
981 PERLBIN="$perlbin" && export PERLBIN && perl -p \
982 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
983 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
984 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
985 chown_make "$cgiroot"/git-browser.cgi.$$ &&
986 perl -p \
987 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
988 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
989 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
990 chown_make "$cgiroot"/git-diff.cgi.$$ &&
991 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
992 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
993 for h in *.html; do
994 [ "$h" != "index.html" ] || continue
995 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
996 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
997 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
998 >"$webroot/git-browser/$h.$$" &&
999 chmod a+r "$webroot/git-browser/$h.$$" &&
1000 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
1001 else
1002 cp -p "$h" "$webroot/git-browser/"
1004 done
1005 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
1006 cp -pR JSON "$cgiroot/"
1008 test $? -eq 0
1009 gitwebabs="$cfg_gitweburl"
1010 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
1011 gitwebabs="${gitwebabs#*://}"
1012 case "$gitwebabs" in
1013 *"/"*) gitwebabs="/${gitwebabs#*/}";;
1014 *) gitwebabs="";;
1015 esac
1016 esac
1017 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
1018 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
1019 gitbin: $cfg_git_bin
1020 gitweb: $gitwebabs
1021 warehouse: $cfg_reporoot
1022 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
1024 chown_make "$basedir/gitweb"/git-browser.conf.$$
1025 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
1026 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
1027 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
1028 cfg_gitweb_url="$cfg_gitweburl/"
1029 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
1030 cfg_home_url="$cfg_gitweburl/%n"
1031 cfg_home_text="summary"
1032 cfg_bycommit_title="$esctitle - %n/graphiclog1"
1033 cfg_bydate_title="$esctitle - %n/graphiclog2"
1035 chown_make "$webroot"/git-browser/GitConfig.js.$$
1036 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
1039 echo "*** Setting up our part of the website..."
1040 mkdir -p "$webroot" "$cgiroot"
1041 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
1042 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
1043 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
1044 cp "$basedir/cgi"/*.cgi "$cgiroot"
1045 rm -rf "$basedir/cgi"
1046 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
1047 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
1048 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
1049 else
1050 cp gitweb/indextext.html "$basedir/gitweb"
1052 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
1053 cp mootools.js "$webroot"
1054 cp htaccess "$webroot/.htaccess"
1055 cp cgi/htaccess "$cgiroot/.htaccess"
1056 cp git-favicon.ico "$webroot/favicon.ico"
1057 cp robots.txt "$webroot"
1058 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
1061 echo "*** Setting up token keys..."
1062 mkdir -p "$cfg_certsdir/tokenkeys"
1063 "$var_perl_bin" -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -MGirocco::Util -MGirocco::TimedToken -e '
1064 my $basedir; $Girocco::Config::certsdir =~ /^(.+)$/ and $basedir = "$1/tokenkeys";
1065 -d "$basedir" && -w _ or die "no such writable directory: \"$basedir\"\n";
1066 foreach (qw(projedit)) {
1067 my $tk = get_token_key($_);
1068 if (!defined($tk)) {
1069 my $tf = "$basedir/$_.tky";
1070 $tk = create_token_secret();
1071 my $fh;
1072 open $fh, ">", "$tf" or
1073 die "unable to open \"$tf\" for writing: $!\n";
1074 printf $fh "%s\n", $tk;
1075 close $fh or die "error closing \"$tf\": $!\n";
1076 printf "%s\n", "Created new $_ token secret";
1082 if [ -n "$cfg_httpspushurl" ]; then
1083 echo "*** Setting up SSL certificates..."
1084 openssl="${var_openssl_bin:-openssl}"
1085 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
1086 bits=2048
1087 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
1088 bits="$cfg_rsakeylength"
1090 mkdir -p "$cfg_certsdir"
1091 [ -d "$cfg_certsdir" ]
1092 wwwcertcn=
1093 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
1094 wwwcertcn="$(
1095 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
1096 sed -e 's,[^/]*,,'
1099 wwwcertdns=
1100 if [ -n "$cfg_wwwcertaltnames" ]; then
1101 for dnsopt in $cfg_wwwcertaltnames; do
1102 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
1103 done
1105 wwwcertdnsfile=
1106 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
1107 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1109 needroot=
1110 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1111 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1112 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1113 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1114 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1115 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1116 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1117 umask 0077
1118 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1119 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1120 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1121 umask 0022
1122 echo "Created new root key"
1124 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1125 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1126 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1127 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem" \
1128 "$cfg_certsdir/girocco_www_fullchain.pem"
1129 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1130 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1131 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1132 echo "Created new root certificate"
1134 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1135 umask 0077
1136 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1137 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1138 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1139 umask 0022
1140 echo "Created new www key"
1142 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1143 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1144 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1145 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1146 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1147 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1148 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1149 rm -f "$cfg_certsdir/girocco_www_fullchain.pem"
1150 echo "Created www certificate"
1152 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1153 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1154 echo "Created www certificate chain file"
1156 if ! [ -e "$cfg_certsdir/girocco_www_fullchain.pem" ]; then
1157 cat "$cfg_certsdir/girocco_www_crt.pem" >"$cfg_certsdir/girocco_www_fullchain.pem"
1158 cat "$cfg_certsdir/girocco_www_chain.pem" >>"$cfg_certsdir/girocco_www_fullchain.pem"
1159 echo "Created www certificate full chain file"
1161 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1162 umask 0037
1163 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1164 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1165 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1166 umask 0022
1167 echo "Created new client key"
1169 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1170 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1171 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1172 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1173 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1174 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1175 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1176 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1177 echo "Created client certificate"
1179 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1180 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1181 echo "Created client certificate suffix file"
1183 if [ -z "$cfg_pretrustedroot" ]; then
1184 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1185 else
1186 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1188 if [ -n "$cfg_mob" ]; then
1189 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1190 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1191 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1192 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1193 echo "Created new mob user key"
1195 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1196 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1197 createcert --client --key "$cfg_clientkey" \
1198 --cert "$cfg_clientcert" \
1199 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1200 echo "Created mob user client certificate"
1202 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1203 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1204 else
1205 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1207 else
1208 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1209 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1213 echo "*** Processing website html templates..."
1214 rm -f "$cgiroot/html.cgi"
1215 rm -rf "$cgiroot/html"
1216 mkdir -p "$cgiroot/html"
1217 for tf in "$basedir/html"/*.html; do
1218 tfb="${tf##*/}"
1219 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1220 rm -f "$tf"
1221 done
1223 echo "*** Formatting markdown documentation..."
1224 mkdir -p "$cgiroot/html/gfm"
1225 for d in basics.md syntax.md; do
1227 cat <<-HEADER
1228 <!DOCTYPE html>
1229 <html xmlns="http://www.w3.org/1999/xhtml">
1230 <head>
1231 <meta charset="utf-8" />
1232 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1233 <title>$d</title>
1234 </head>
1235 <body><pre>
1236 HEADER
1237 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1238 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1239 -e 's/ by adding `.md` to the URL//' \
1240 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1241 cat <<-FOOTER
1242 </pre></body>
1243 </html>
1244 FOOTER
1245 } >"$cgiroot/html/gfm/$d.html"
1247 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1248 gwfpath="$cfg_gitwebfiles"
1249 case "$gwfpath" in *"//"*)
1250 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1251 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1252 esac
1253 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1254 gwfpath="${gwfpath%/}"
1255 cat <<-HEADER
1256 <!DOCTYPE html>
1257 <html xmlns="http://www.w3.org/1999/xhtml">
1258 <head>
1259 <meta charset="utf-8" />
1260 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1261 <title>$title</title>
1262 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1263 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1264 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1265 </head>
1266 <body style="text-align:center">
1267 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1268 HEADER
1269 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1270 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1271 -e 's/ by adding `.md` to the URL//' |
1272 "$perlbin" "markdown.git/Markdown.pl"
1273 cat <<-FOOTER
1274 </div>
1275 </body>
1276 </html>
1277 FOOTER
1278 } >"$cgiroot/html/gfm/${d%.md}.html"
1279 done
1282 echo "*** Finalizing permissions and moving into place..."
1283 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1284 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1286 # This should always be the very last thing install.sh does
1287 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1288 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1289 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1290 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1291 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1292 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1293 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1294 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1295 touch "$cfg_chroot/etc/taskd.restart"
1296 chown_make "$cfg_chroot/etc/taskd.restart"
1297 trap ':' PIPE
1298 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1299 trap - PIPE