install.sh: eliminate spurious test_nc_U "Terminated" messages
[girocco.git] / install.sh
blob5be264b4f57d9f5ba933e549326cdb0270d02359
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 sleep 1
446 _bgpid="$!"
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 sleep 1
451 read -r _result <"$_tmpdir/output" || :
452 _bad=
453 ! [ -e "$_tmpdir/failed" ] || _bad=1
454 rm -rf "$_tmpdir"
455 [ -z "$_bad" ] && [ "$_result" = "testing" ]
456 } >/dev/null 2>&1
458 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
459 test_nc_U "$var_nc_openbsd_bin" || {
460 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
461 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
462 uname_s="$(uname -s 2>/dev/null | tr A-Z a-z 2>/dev/null)" || :
463 case "$uname_s" in
464 *dragonfly*)
465 echo "ERROR: see the src/dragonfly/README file for a solution" >&2;;
466 *kfreebsd*|*linux*)
467 echo "ERROR: try installing the package named 'netcat-openbsd'" >&2;;
468 esac
469 exit 1
472 echo "*** Verifying selected POSIX sh is sane..."
473 shbin="$var_sh_bin"
474 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
475 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
476 exit 1
478 [ "$(check_sh_builtin command)" = "command" ] || {
479 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
480 exit 1
482 sh_not_builtin=
483 sh_extra_chroot_installs=
484 badsh=
485 for sbi in cd pwd read umask unset unalias; do
486 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
487 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
488 badsh=1
490 done
491 [ -z "$badsh" ] || exit 1
492 for sbi in '[' echo printf test; do
493 if ! extra="$(check_sh_builtin "$sbi")"; then
494 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
495 badsh=1
496 continue
498 if [ "$extra" != "$sbi" ]; then
499 case "$extra" in /*) :;; *)
500 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
501 badsh=1
502 continue
503 esac
504 withspc=
505 case "$extra" in *" "*) withspc=1; esac
506 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
507 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
508 badsh=1
509 continue
511 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
512 sh_not_builtin="$sh_not_builtin $sbi"
513 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
515 done
516 [ -z "$badsh" ] || exit 1
517 [ -z "$sh_extra_chroot_installs" ] || {
518 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
519 echo "WARNING: as a result it will run slower than necessary" >&2
520 echo "WARNING: consider building and switching to dash which can be found at:" >&2
521 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
522 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
523 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
524 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
527 echo "*** Verifying xargs is sane..."
528 _xargsr="$(</dev/null command xargs printf %s -r)" || :
529 xtest1="$(</dev/null command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
530 xtest2="$(printf '%s\n' one two | command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
531 [ -z "$xtest1" ] && [ "$xtest2" = "test one test two " ] || {
532 echo 'ERROR: xargs is unusable' >&2
533 echo 'ERROR: either `test -z "$(</dev/null xargs echo test 2>/dev/null)"`' >&2
534 echo 'ERROR: or `test -z "$(</dev/null xargs -r echo test 2>/dev/null)"`' >&2
535 echo 'ERROR: must be true, but neither is' >&2
536 exit 1
539 echo "*** Verifying selected perl is sane..."
540 perlbin="$var_perl_bin"
541 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
542 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
543 exit 1
546 echo "*** Verifying selected gzip is sane..."
547 gzipbin="$var_gzip_bin"
548 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
549 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
550 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
551 exit 1
554 echo "*** Verifying basedir, webroot, webreporoot and cgiroot paths..."
555 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
556 case "$cfg_basedir" in /*) :;; *)
557 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
558 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
559 exit 1
560 esac
561 case "$cfg_webroot" in /*) :;; *)
562 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
563 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
564 exit 1
565 esac
566 if [ -n "$cfg_webreporoot" ]; then
567 case "$cfg_webreporoot" in /*) :;; *)
568 echo "ERROR: invalid Girocco::Config::webreporoot setting" >&2
569 echo "ERROR: \"$cfg_webreporoot\" must be an absolute path (start with '/') or undef" >&2
570 exit 1
571 esac
573 case "$cfg_cgiroot" in /*) :;; *)
574 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
575 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
576 exit 1
577 esac
579 echo "*** Verifying installation preconditions..."
581 # Make sure Markdown.pm is present and use'able
583 ! [ -e Markdown.pm ] || ! [ -f Markdown.pm ] || ! [ -s Markdown.pm ] ||
584 ! mdoutput="$("$perlbin" 2>/dev/null -I"$PWD" -MMarkdown=Markdown,ProcessRaw -e \
585 'use strict; use warnings; print Markdown("_test_ **this**"); exit 0;')"
586 then
587 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
588 exit 1
590 # And that it at least appears to function properly
591 if [ "$mdoutput" != '<p><em>test</em> <strong>this</strong></p>' ]; then
592 echo "ERROR: markdown.git verification test failed -- Markdown function does not work" >&2
593 exit 1
596 # return the input with trailing slashes stripped but return "/" for all "/"s
597 striptrsl() {
598 [ -n "$1" ] || return 0
599 _s="${1##*[!/]}"
600 [ "$_s" != "$1" ] || _s="${_s#?}"
601 printf "%s\n" "${1%$_s}"
604 # a combination of realpath + dirname where the realpath of the deepest existing
605 # directory is returned with the rest of the non-existing components appended
606 # and trailing slashes and multiple slashes are removed
607 realdir() {
608 _d="$(striptrsl "$1")"
609 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
610 echo "$_d"
611 return 0
613 _c=""
614 while ! [ -d "$_d" ]; do
615 _c="/$(basename "$_d")$_c"
616 _d="$(dirname "$_d")"
617 [ "$_d" != "/" ] || _c="${_c#/}"
618 done
619 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
622 # Use basedir, webroot and cgiroot for easier control of filesystem locations
623 # Wherever we are writing/copying/installing files we use these, but where we
624 # are editing, adding config settings or printing advice we always stick to the
625 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
626 # Only the file system directories that could be asynchronously accessed (by
627 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
628 # The chroot is handled specially and does not need one of these.
629 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
630 # case the prior contents of cgiroot and/or webroot are discarded.
631 rbasedir="$(realdir "$cfg_basedir")"
632 rwebroot="$(realdir "$cfg_webroot")"
633 rwebreporoot=
634 [ -z "$cfg_webreporoot" ] || {
635 # avoid resolving a pre-existing symlink from a previous install
636 rwebreporoot="$(realdir "${cfg_webreporoot%/}_NOSUCHDIR")"
637 rwebreporoot="${rwebreporoot%_NOSUCHDIR}"
639 rcgiroot="$(realdir "$cfg_cgiroot")"
640 case "$rbasedir" in "$rwebroot"/?*)
641 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
642 exit 1
643 esac
644 case "$rbasedir" in "$rcgiroot"/?*)
645 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
646 exit 1
647 esac
648 if [ "$rwebroot" = "$rcgiroot" ]; then
649 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
650 exit 1
652 case "$rcgiroot" in "$rwebroot"/?*)
653 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
654 exit 1
655 esac
656 case "$rwebroot" in "$rcgiroot"/?*)
657 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
658 exit 1
659 esac
660 if [ -n "$rwebreporoot" ]; then
661 if [ "$rwebreporoot" = "$rwebroot" ]; then
662 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::webreporoot settings; must not be the same" >&2
663 exit 1
665 case "$rwebreporoot" in "$rwebroot"/?*);;*)
666 echo "ERROR: invalid Girocco::Config::webreporoot setting; must be under webroot or undef" >&2
667 exit 1
668 esac
670 basedir="$rbasedir-new"
671 case "$rwebroot" in
672 "$rbasedir"/?*)
673 webroot="$basedir${rwebroot#$rbasedir}"
674 webrootsub=1
677 webroot="$rwebroot-new"
678 webrootsub=
680 esac
681 webreporoot=
682 [ -z "$rwebreporoot" ] || webreporoot="$webroot${rwebreporoot#$rwebroot}"
683 case "$rcgiroot" in
684 "$rbasedir"/?*)
685 cgiroot="$basedir${rcgiroot#$rbasedir}"
686 cgirootsub=1
689 cgiroot="$rcgiroot-new"
690 cgirootsub=
692 esac
694 echo "*** Setting up basedir..."
696 chown_make() {
697 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
698 find -H "$@" -user root -exec chown "$SUDO_USER:$(id -gn "$SUDO_USER")" '{}' + 2>/dev/null || :
699 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
700 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
704 "$MAKE" --no-print-directory --silent apache.conf
705 chown_make apache.conf
706 "$MAKE" --no-print-directory --silent -C src
707 chown_make src
708 rm -fr "$basedir"
709 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
710 # make the mtlinesfile with 1000 empty lines
711 yes '' | dd bs=1000 count=1 2>/dev/null >"$basedir/mtlinesfile"
712 chmod a+r "$basedir/mtlinesfile"
713 cp cgi/*.cgi "$basedir/cgi"
714 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
715 rm -f "$basedir/Girocco/Dumper.pm" # Dumper.pm is only for the install.sh process
716 rm -f "$basedir/Girocco/Validator.pm" # Validator.pm is only for the install.sh process
717 find -H "$basedir" -type l -exec rm -f '{}' +
718 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
719 src/rangecgi src/readlink src/strftime src/throttle src/ulimit512 src/ltsha256 \
720 ezcert.git/CACreateCert cgi/authrequired.cgi cgi/snapshot.cgi \
721 "$basedir/bin"
722 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
723 if [ -n "$cfg_httpspushurl" ]; then
724 [ -z "$cfg_pretrustedroot" ] || rm -f "$basedir"/html/rootcert.html
725 else
726 rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
728 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
730 # Put the frozen Config in place
731 VARLIST="$(get_girocco_config_var_list varonly)" && export VARLIST
732 perl -I"$PWD" -MGirocco::Dumper=FreezeConfig -MScalar::Util=looks_like_number -e '
733 my $usemod = $ARGV[0];
734 my $f = sub { return () unless $_[0] =~ /^(var_[^=\s]+)=(.*)$/;
735 my ($k,$v) = ($1,$2);
736 $v =~ s/([\@\%])/\\$1/gos;
737 $v = "\"".$v."\"" unless substr($v,0,1) eq "\"" || looks_like_number($v);
738 my $e = eval $v;
739 [$k, $e] };
740 my @vars = map({&$f($_)} split(/\n+/, $ENV{VARLIST}));
741 my $s = sub { my $conf = shift;
742 foreach (@vars) {
743 my ($k,$v) = @{$_};
744 eval "\$${conf}::$k=\$v";
747 print FreezeConfig([$usemod,"Girocco::Validator"], undef, $s);
748 ' -- "$GIROCCO_CONF" >"$basedir/Girocco/Config.pm"
749 unset VARLIST
751 # Create symbolic links to selected binaries
752 ln -s "$cfg_git_bin" "$basedir/bin/git"
753 ln -s "$shbin" "$basedir/bin/sh"
754 ln -s "$perlbin" "$basedir/bin/perl"
755 ln -s "$gzipbin" "$basedir/bin/gzip"
756 [ -z "$var_openssl_bin" ] || ln -s "$var_openssl_bin" "$basedir/bin/openssl"
758 echo "*** Preprocessing scripts..."
759 SHBIN="$shbin" && export SHBIN
760 PERLBIN="$perlbin" && export PERLBIN
761 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
762 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
763 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
764 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
765 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
766 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
767 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
768 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
769 -e 's/\@cgiroot\@/"$Girocco::Config::cgiroot"/g;' \
770 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
771 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
772 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
773 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
774 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
775 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
776 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
777 -e 's/\@autogchack\@/"$Girocco::Config::autogchack"/g;' \
778 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
779 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
780 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
781 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
782 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
783 -e 's/\@fetch_stash_refs\@/"$Girocco::Config::fetch_stash_refs"/g;' \
784 -e 's/\@suppress_git_ssh_logging\@/"$Girocco::Config::suppress_git_ssh_logging"/g;' \
785 -e 's/\@max_file_size512\@/"$Girocco::Config::max_file_size512"/g;' \
786 -e 'close ARGV if eof;' \
787 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
788 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
789 "$basedir"/shlib.sh "$basedir"/hooks/* \
790 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
791 "$basedir"/toolbox/reports/*.sh \
792 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
793 "$basedir"/bin/create-* "$basedir"/bin/update-* \
794 "$basedir"/bin/*.cgi "$basedir"/screen/*
795 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
796 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
797 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
798 "$basedir"/cgi/*.cgi "$basedir"/gitweb/*.perl \
799 "$basedir"/jobd/*.pl "$basedir"/taskd/*.pl
800 perl -i -p \
801 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
802 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
803 -e 'close ARGV if eof;' \
804 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
805 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
806 perl -i -p \
807 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
808 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
809 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
810 -e 'close ARGV if eof;' \
811 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
812 unset PERLBIN
813 unset SHBIN
815 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
816 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
818 if [ "${cfg_mirror_darcs:-0}" != "0" ]; then
819 echo "*** Setting up darcs-fast-export from girocco-darcs-fast-export.git..."
820 if ! [ -f girocco-darcs-fast-export.git/darcs-fast-export ] ||
821 ! [ -x girocco-darcs-fast-export.git/darcs-fast-export ]; then
822 echo "ERROR: girocco-darcs-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
823 exit 1
825 mkdir -p "$basedir"/bin
826 cp girocco-darcs-fast-export.git/darcs-fast-export "$basedir"/bin
829 if [ "${cfg_mirror_hg:-0}" != "0" ]; then
830 echo "*** Setting up hg-fast-export from girocco-hg-fast-export.git..."
831 if ! [ -f girocco-hg-fast-export.git/hg-fast-export.py ] || ! [ -f girocco-hg-fast-export.git/hg2git.py ]; then
832 echo "ERROR: girocco-hg-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
833 exit 1
835 mkdir -p "$basedir"/bin
836 cp girocco-hg-fast-export.git/hg-fast-export.py girocco-hg-fast-export.git/hg2git.py "$basedir"/bin
839 echo "*** Setting up markdown from markdown.git..."
840 if ! [ -f markdown.git/Markdown.pl ]; then
841 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
842 exit 1
844 mkdir -p "$basedir"/bin
845 (PERLBIN="$perlbin" && export PERLBIN &&
846 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
847 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
848 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
849 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
850 test $? -eq 0
851 (umask 0133 && ln -s -f -n bin/Markdown.pl "$basedir"/Markdown.pm)
852 test $? -eq 0
854 # Some permission sanity on basedir/bin just in case
855 find -H "$basedir"/bin -type f -exec chmod go-w '{}' +
856 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
858 if [ -n "$cfg_mirror" ]; then
859 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
861 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.pl, or add this"
862 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
863 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.pl -q --all-once"
866 echo "*** Setting up repository root..."
867 [ -d "$cfg_reporoot" ] || {
868 mkdir -p "$cfg_reporoot"
869 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot" ||
870 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot"
872 [ -z "$cfg_owning_group" ] ||
873 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
874 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
875 mkdir -p "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty"
876 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" ||
877 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot/{_recyclebin,_global} properly"
878 if [ "$cfg_owning_group" ]; then
879 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
880 chgrp -R "$cfg_owning_group" "$cfg_reporoot/_global" || echo "WARNING: Cannot chgrp -R $cfg_owning_group $cfg_reporoot/_global"
882 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
883 chmod 00755 "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" || echo "WARNING: Cannot chmod $cfg_reporoot/_global properly"
886 usejail=
887 [ "${cfg_disable_jailsetup:-0}" != "0" ] || [ "${cfg_chrooted:-0}" = "0" ] || usejail=1
888 if [ -n "$usejail" ]; then
889 echo "*** Setting up chroot jail for pushing..."
890 if [ -n "$isroot" ]; then
891 # jailsetup may install things from $cfg_basedir/bin into the
892 # chroot so we do a mini-update of just that portion now
893 mkdir -p "$cfg_basedir"
894 rm -rf "$cfg_basedir/bin-new"
895 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
896 rm -rf "$cfg_basedir/bin-old"
897 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
898 rm -rf "$cfg_basedir/bin-old"
899 if [ -n "$sh_extra_chroot_installs" ]; then
900 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
901 export GIROCCO_CHROOT_EXTRA_INSTALLS
903 ./jailsetup.sh
904 unset GIROCCO_CHROOT_EXTRA_INSTALLS
905 else
906 echo "WARNING: Skipping jail setup, not root"
911 echo "*** Setting up jail configuration (project database)..."
912 [ -n "$usejail" ] && [ -n "$isroot" ] || ./jailsetup.sh dbonly
913 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
914 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
915 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
916 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
917 if [ -n "$usejail" ]; then
918 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
919 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
920 else
921 # If a chroot jail is not in use, sudo privileges are neither expected nor required
922 # which means it will not be possible to change the owner of the passwd and group
923 # files if it differs from the mirror user. And that's okay, provided the group
924 # can still be set correctly to the owning group. But, just in case we're running
925 # as root, go ahead and set the owner to the mirror user.
926 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
927 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup the etc/passwd and/or etc/group files"
929 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
930 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
931 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
934 echo "*** Setting up global hook scripts..."
935 # It is absolutely CRUCIAL that hook script replacements are done atomically!
936 # Otherwise an incoming push might slip in and fail to run the hook script!
937 # The underlying rename(2) function call provides this and mv will use it.
938 # First add hook scripts
939 hooks="pre-auto-gc pre-receive post-commit post-receive update"
940 for hook in $hooks; do
941 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
942 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
943 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
944 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
945 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
946 done
947 # Then remove any hook scripts that do not belong
948 for hook in "$cfg_reporoot/_global/hooks"/*; do
949 hook="${hook##*/}"
950 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
951 case " $hooks " in *" $hook "*);;*)
952 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
953 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
954 esac
955 done
958 echo "*** Setting up gitweb from git.git..."
959 if ! [ -f git.git/Makefile ]; then
960 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
961 exit 1
964 # We do not wholesale replace either webroot or cgiroot unless they are under
965 # basedir so if they exist and are not we make a copy to start working on them.
966 # We make a copy using -p which can result in some warnings so we suppress
967 # error output as it's of no consequence in this case.
968 rm -rf "$webroot" "$cgiroot"
969 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
970 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
971 mkdir -p "$webroot" "$cgiroot"
974 cd git.git &&
975 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
976 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
977 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
978 chown_make gitweb &&
979 PERLBIN="$perlbin" && export PERLBIN &&
980 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
981 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
982 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
983 chown_make "$cgiroot"/gitweb.cgi.$$ &&
984 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
985 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
987 test $? -eq 0
990 echo "*** Setting up git-browser from git-browser.git..."
991 if ! [ -f git-browser.git/git-browser.cgi ]; then
992 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
993 exit 1
995 mkdir -p "$webroot"/git-browser "$cgiroot"
997 cd git-browser.git &&
998 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
999 PERLBIN="$perlbin" && export PERLBIN && perl -p \
1000 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
1001 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
1002 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
1003 chown_make "$cgiroot"/git-browser.cgi.$$ &&
1004 perl -p \
1005 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
1006 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
1007 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
1008 chown_make "$cgiroot"/git-diff.cgi.$$ &&
1009 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
1010 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
1011 for h in *.html; do
1012 [ "$h" != "index.html" ] || continue
1013 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
1014 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
1015 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
1016 >"$webroot/git-browser/$h.$$" &&
1017 chmod a+r "$webroot/git-browser/$h.$$" &&
1018 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
1019 else
1020 cp -p "$h" "$webroot/git-browser/"
1022 done
1023 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
1024 cp -pR JSON "$cgiroot/"
1026 test $? -eq 0
1027 gitwebabs="$cfg_gitweburl"
1028 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
1029 gitwebabs="${gitwebabs#*://}"
1030 case "$gitwebabs" in
1031 *"/"*) gitwebabs="/${gitwebabs#*/}";;
1032 *) gitwebabs="";;
1033 esac
1034 esac
1035 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
1036 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
1037 gitbin: $cfg_git_bin
1038 gitweb: $gitwebabs
1039 warehouse: $cfg_reporoot
1040 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
1042 chown_make "$basedir/gitweb"/git-browser.conf.$$
1043 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
1044 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
1045 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
1046 cfg_gitweb_url="$cfg_gitweburl/"
1047 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
1048 cfg_home_url="$cfg_gitweburl/%n"
1049 cfg_home_text="summary"
1050 cfg_bycommit_title="$esctitle - %n/graphiclog1"
1051 cfg_bydate_title="$esctitle - %n/graphiclog2"
1053 chown_make "$webroot"/git-browser/GitConfig.js.$$
1054 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
1057 echo "*** Setting up our part of the website..."
1058 mkdir -p "$webroot" "$cgiroot"
1059 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
1060 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
1061 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
1062 cp "$basedir/cgi"/*.cgi "$cgiroot"
1063 rm -rf "$basedir/cgi"
1064 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
1065 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
1066 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
1067 else
1068 cp gitweb/indextext.html "$basedir/gitweb"
1070 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
1071 cp mootools.js "$webroot"
1072 cp htaccess "$webroot/.htaccess"
1073 cp cgi/htaccess "$cgiroot/.htaccess"
1074 cp git-favicon.ico "$webroot/favicon.ico"
1075 cp robots.txt "$webroot"
1076 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
1079 echo "*** Setting up token keys..."
1080 mkdir -p "$cfg_certsdir/tokenkeys"
1081 "$var_perl_bin" -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -MGirocco::Util -MGirocco::TimedToken -e '
1082 my $basedir; $Girocco::Config::certsdir =~ /^(.+)$/ and $basedir = "$1/tokenkeys";
1083 -d "$basedir" && -w _ or die "no such writable directory: \"$basedir\"\n";
1084 foreach (qw(projedit)) {
1085 my $tk = get_token_key($_);
1086 if (!defined($tk)) {
1087 my $tf = "$basedir/$_.tky";
1088 $tk = create_token_secret();
1089 my $fh;
1090 open $fh, ">", "$tf" or
1091 die "unable to open \"$tf\" for writing: $!\n";
1092 printf $fh "%s\n", $tk;
1093 close $fh or die "error closing \"$tf\": $!\n";
1094 printf "%s\n", "Created new $_ token secret";
1100 if [ -n "$cfg_httpspushurl" ]; then
1101 echo "*** Setting up SSL certificates..."
1102 openssl="${var_openssl_bin:-openssl}"
1103 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
1104 bits=2048
1105 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
1106 bits="$cfg_rsakeylength"
1108 mkdir -p "$cfg_certsdir"
1109 [ -d "$cfg_certsdir" ]
1110 wwwcertcn=
1111 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
1112 wwwcertcn="$(
1113 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
1114 sed -e 's,[^/]*,,'
1117 wwwcertdns=
1118 if [ -n "$cfg_wwwcertaltnames" ]; then
1119 for dnsopt in $cfg_wwwcertaltnames; do
1120 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
1121 done
1123 wwwcertdnsfile=
1124 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
1125 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1127 needroot=
1128 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1129 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1130 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1131 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1132 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1133 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1134 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1135 umask 0077
1136 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1137 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1138 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1139 umask 0022
1140 echo "Created new root key"
1142 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1143 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1144 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1145 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem" \
1146 "$cfg_certsdir/girocco_www_fullchain.pem"
1147 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1148 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1149 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1150 echo "Created new root certificate"
1152 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1153 umask 0077
1154 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1155 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1156 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1157 umask 0022
1158 echo "Created new www key"
1160 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1161 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1162 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1163 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1164 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1165 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1166 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1167 rm -f "$cfg_certsdir/girocco_www_fullchain.pem"
1168 echo "Created www certificate"
1170 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1171 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1172 echo "Created www certificate chain file"
1174 if ! [ -e "$cfg_certsdir/girocco_www_fullchain.pem" ]; then
1175 cat "$cfg_certsdir/girocco_www_crt.pem" >"$cfg_certsdir/girocco_www_fullchain.pem"
1176 cat "$cfg_certsdir/girocco_www_chain.pem" >>"$cfg_certsdir/girocco_www_fullchain.pem"
1177 echo "Created www certificate full chain file"
1179 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1180 umask 0037
1181 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1182 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1183 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1184 umask 0022
1185 echo "Created new client key"
1187 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1188 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1189 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1190 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1191 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1192 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1193 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1194 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1195 echo "Created client certificate"
1197 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1198 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1199 echo "Created client certificate suffix file"
1201 if [ -z "$cfg_pretrustedroot" ]; then
1202 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1203 else
1204 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1206 if [ -n "$cfg_mob" ]; then
1207 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1208 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1209 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1210 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1211 echo "Created new mob user key"
1213 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1214 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1215 createcert --client --key "$cfg_clientkey" \
1216 --cert "$cfg_clientcert" \
1217 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1218 echo "Created mob user client certificate"
1220 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1221 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1222 else
1223 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1225 else
1226 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1227 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1231 echo "*** Processing website html templates..."
1232 rm -f "$cgiroot/html.cgi"
1233 rm -rf "$cgiroot/html"
1234 mkdir -p "$cgiroot/html"
1235 for tf in "$basedir/html"/*.html; do
1236 tfb="${tf##*/}"
1237 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1238 rm -f "$tf"
1239 done
1241 echo "*** Formatting markdown documentation..."
1242 mkdir -p "$cgiroot/html/gfm"
1243 for d in basics.md syntax.md; do
1245 cat <<-HEADER
1246 <!DOCTYPE html>
1247 <html xmlns="http://www.w3.org/1999/xhtml">
1248 <head>
1249 <meta charset="utf-8" />
1250 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1251 <title>$d</title>
1252 </head>
1253 <body><pre>
1254 HEADER
1255 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1256 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1257 -e 's/ by adding `.md` to the URL//' \
1258 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1259 cat <<-FOOTER
1260 </pre></body>
1261 </html>
1262 FOOTER
1263 } >"$cgiroot/html/gfm/$d.html"
1265 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1266 gwfpath="$cfg_gitwebfiles"
1267 case "$gwfpath" in *"//"*)
1268 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1269 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1270 esac
1271 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1272 gwfpath="${gwfpath%/}"
1273 cat <<-HEADER
1274 <!DOCTYPE html>
1275 <html xmlns="http://www.w3.org/1999/xhtml">
1276 <head>
1277 <meta charset="utf-8" />
1278 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1279 <title>$title</title>
1280 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1281 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1282 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1283 </head>
1284 <body style="text-align:center">
1285 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1286 HEADER
1287 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1288 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1289 -e 's/ by adding `.md` to the URL//' |
1290 "$perlbin" "markdown.git/Markdown.pl"
1291 cat <<-FOOTER
1292 </div>
1293 </body>
1294 </html>
1295 FOOTER
1296 } >"$cgiroot/html/gfm/${d%.md}.html"
1297 done
1300 echo "*** Finalizing permissions and moving into place..."
1301 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1302 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1304 # This should always be the very last thing install.sh does
1305 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1306 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1307 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1308 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1309 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1310 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1311 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1312 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1313 touch "$cfg_chroot/etc/taskd.restart"
1314 chown_make "$cfg_chroot/etc/taskd.restart"
1315 trap ':' PIPE
1316 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1317 trap - PIPE