projtool.pl: do not attempt to check unset error codes
[girocco.git] / install.sh
blob842a36111e2ea3b3a73c3466c8c8ddbd3a5507aa
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 echo "*** Checking for compiled utilities..."
144 if ! [ -f src/can_user_push ] || ! [ -x src/can_user_push ]; then
145 echo "ERROR: src/can_user_push is not built! Did you _REALLY_ read INSTALL?" >&2
146 echo "ERROR: perhaps you forgot to run make?" >&2
147 exit 1
149 if ! [ -f src/can_user_push_http ] || ! [ -x src/can_user_push_http ]; then
150 echo "ERROR: src/can_user_push_http is not built! Did you _REALLY_ read INSTALL?" >&2
151 echo "ERROR: perhaps you forgot to run make?" >&2
152 exit 1
154 if ! [ -f src/getent ] || ! [ -x src/getent ]; then
155 echo "ERROR: src/getent is not built! Did you _REALLY_ read INSTALL?" >&2
156 echo "ERROR: perhaps you forgot to run make?" >&2
157 exit 1
159 if ! [ -f src/get_sun_path_len ] || ! [ -x src/get_sun_path_len ]; then
160 echo "ERROR: src/get_sun_path_len is not built! Did you _REALLY_ read INSTALL?" >&2
161 echo "ERROR: perhaps you forgot to run make?" >&2
162 exit 1
164 if ! [ -f src/get_user_uuid ] || ! [ -x src/get_user_uuid ]; then
165 echo "ERROR: src/get_user_uuid is not built! Did you _REALLY_ read INSTALL?" >&2
166 echo "ERROR: perhaps you forgot to run make?" >&2
167 exit 1
169 if ! [ -f src/list_packs ] || ! [ -x src/list_packs ]; then
170 echo "ERROR: src/list_packs is not built! Did you _REALLY_ read INSTALL?" >&2
171 echo "ERROR: perhaps you forgot to run make?" >&2
172 exit 1
174 if ! [ -f src/peek_packet ] || ! [ -x src/peek_packet ]; then
175 echo "ERROR: src/peek_packet is not built! Did you _REALLY_ read INSTALL?" >&2
176 echo "ERROR: perhaps you forgot to run make?" >&2
177 exit 1
179 if ! [ -f src/rangecgi ] || ! [ -x src/rangecgi ]; then
180 echo "ERROR: src/rangecgi is not built! Did you _REALLY_ read INSTALL?" >&2
181 echo "ERROR: perhaps you forgot to run make?" >&2
182 exit 1
184 if ! [ -f src/readlink ] || ! [ -x src/readlink ]; then
185 echo "ERROR: src/readlink is not built! Did you _REALLY_ read INSTALL?" >&2
186 echo "ERROR: perhaps you forgot to run make?" >&2
187 exit 1
189 if ! [ -f src/strftime ] || ! [ -x src/strftime ]; then
190 echo "ERROR: src/strftime is not built! Did you _REALLY_ read INSTALL?" >&2
191 echo "ERROR: perhaps you forgot to run make?" >&2
192 exit 1
194 if ! [ -f src/throttle ] || ! [ -x src/throttle ]; then
195 echo "ERROR: src/throttle is not built! Did you _REALLY_ read INSTALL?" >&2
196 echo "ERROR: perhaps you forgot to run make?" >&2
197 exit 1
199 if ! [ -f src/ulimit512 ] || ! [ -x src/ulimit512 ]; then
200 echo "ERROR: src/ulimit512 is not built! Did you _REALLY_ read INSTALL?" >&2
201 echo "ERROR: perhaps you forgot to run make?" >&2
202 exit 1
204 ebin="/bin/echo"
205 if [ ! -x "$ebin" ] && [ -x "/usr/bin/echo" ]; then
206 ebin="/usr/bin/echo"
208 if [ ! -x "$ebin" ]; then
209 echo "ERROR: neither /bin/echo nor /usr/bin/echo found" >&2
210 echo "ERROR: at least one must be present for testing during install" >&2
211 exit 1
213 ec=999
214 tmpfile="$(mktemp "/tmp/ul512-$$-XXXXXX")"
215 { src/ulimit512 -f 0 "$ebin" test >"$tmpfile" || ec=$?; } >/dev/null 2>&1
216 rm -f "$tmpfile"
217 if [ "$ec" = "999" ] || [ "$ec" = "0" ]; then
218 echo "ERROR: src/ulimit512 is built, but broken!" >&2
219 echo "ERROR: exceeding file size limit did not fail!" >&2
220 exit 1
222 if ! [ -f src/ltsha256 ] || ! [ -x src/ltsha256 ]; then
223 echo "ERROR: src/ltsha256 is not built! Did you _REALLY_ read INSTALL?" >&2
224 echo "ERROR: perhaps you forgot to run make?" >&2
225 exit 1
227 sha256check="15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"
228 sha256result="$(printf '%s' '123456789' | src/ltsha256)"
229 if [ "$sha256check" != "$sha256result" ]; then
230 echo "ERROR: src/ltsha256 is built, but broken!" >&2
231 echo "ERROR: verifying sha256 hash of '123456789' failed!" >&2
232 exit 1
234 if ! [ -f src/ltsha1 ] || ! [ -x src/ltsha1 ]; then
235 echo "ERROR: src/ltsha1 is not built! Did you _REALLY_ read INSTALL?" >&2
236 echo "ERROR: perhaps you forgot to run make?" >&2
237 exit 1
239 sha1check="f7c3bc1d808e04732adf679965ccc34ca7ae3441"
240 sha1result="$(printf '%s' '123456789' | src/ltsha1)"
241 if [ "$sha1check" != "$sha1result" ]; then
242 echo "ERROR: src/ltsha1 is built, but broken!" >&2
243 echo "ERROR: verifying sha1 hash of '123456789' failed!" >&2
244 exit 1
246 var_sun_path_len="$(src/get_sun_path_len 2>/dev/null)" || :
248 [ -z "$var_sun_path_len" ] ||
249 [ "${var_sun_path_len#*[!0-9]}" != "$var_sun_path_len" ] ||
250 [ "$var_sun_path_len" -lt 80 ] || [ "$var_sun_path_len" -gt 4096 ]
251 then
252 echol "ERROR: src/get_sun_path_len is built, but bogus!" >&2
253 echol "ERROR: reports sizeof(struct sockaddr_un.sun_path) is '$var_sun_path_len'" >&2
254 exit 1
256 taskdsockpath="$cfg_chroot/etc/taskd.socket@" # "@" stands in for the NUL byte
257 if [ "${#taskdsockpath}" -gt "$var_sun_path_len" ]; then
258 echol "ERROR: maximum length of sockaddr_un.sun_path is $var_sun_path_len" >&2
259 echol "ERROR: the configured taskd.socket path has length ${#taskdsockpath}" >&2
260 echol "ERROR: reduce the length of \$Girocco::Config::chroot to shorten" >&2
261 echol "ERROR: '${taskdsockpath%?}'" >&2
262 echol "ERROR: to fit (including the final '\\0' byte)" >&2
263 exit 1
267 echo "*** Checking for ezcert..."
268 if ! [ -f ezcert.git/CACreateCert ] || ! [ -x ezcert.git/CACreateCert ]; then
269 echo "ERROR: ezcert.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
270 exit 1
274 echo "*** Checking for git..."
275 case "$cfg_git_bin" in /*) :;; *)
276 echo 'ERROR: $Girocco::Config::git_bin must be set to an absolute path' >&2
277 exit 1
278 esac
279 if ! [ -f "$cfg_git_bin" ] || ! [ -x "$cfg_git_bin" ]; then
280 echo "ERROR: $cfg_git_bin does not exist or is not executable" >&2
281 exit 1
283 if ! git_version="$("$cfg_git_bin" version)" || [ -z "$git_version" ]; then
284 echo "ERROR: $cfg_git_bin version failed" >&2
285 exit 1
287 case "$git_version" in
288 [Gg]"it version "*) :;;
290 echo "ERROR: '$cfg_git_bin version' output does not start with 'git version '" >&2
291 exit 1
292 esac
293 echo "Found $cfg_git_bin $git_version"
294 git_vernum="$(echo "$git_version" | sed -ne 's/^[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/p')"
295 echo "*** Checking Git $git_vernum for compatibility..."
296 if [ "$(vcmp "$git_vernum" 1.6.6)" -lt 0 ]; then
297 echo 'ERROR: $Girocco::Config::git_bin must be at least Git version 1.6.6'
298 exit 1
300 if [ "$(vcmp "$git_vernum" 1.6.6.3)" -lt 0 ]; then
301 echo 'WARNING: $Girocco::Config::git_bin version < 1.6.6.3, clients will not see useful error messages'
303 if [ "$(vcmp "$git_vernum" 1.7.3)" -lt 0 ]; then
304 cat <<'EOT'
307 *** SEVERE WARNING: $Girocco::Config::git_bin is set to a version of Git before 1.7.3
310 Some Girocco functionality will be gracefully disabled and other things will
311 just not work at all such as race condition protection against simultaneous
312 client pushes and server garbage collections.
316 if [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 1.7.5)" -lt 0 ]; then
317 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.5 and mirroring enabled, some sources can cause an infinite fetch loop'
319 if [ "$(vcmp "$git_vernum" 1.7.6.6)" -lt 0 ]; then
320 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.6.6, performance may be degraded'
322 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
323 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'
324 echo 'WARNING: See https://lore.kernel.org/git/20141222041944.GA441@peff.net/ for details'
326 if [ "$(vcmp "$git_vernum" 1.8.4.2)" -ge 0 ] && [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 2)" -lt 0 ]; then
327 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, git-daemon needs write access for shallow clones'
328 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, shallow clones will leave repository turds'
330 if [ "$(vcmp "$git_vernum" 1.8.4.3)" -lt 0 ]; then
331 echo 'WARNING: $Girocco::Config::git_bin version < 1.8.4.3, clients will not receive symref=HEAD:refs/heads/...'
333 if [ "$(vcmp "$git_vernum" 2.1)" -lt 0 ]; then
334 echo 'WARNING: $Girocco::Config::git_bin version < 2.1.0, pack bitmaps will not be available'
336 if [ "$(vcmp "$git_vernum" 2.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.1.3)" -lt 0 ]; then
337 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'
339 if [ "$(vcmp "$git_vernum" 2.2)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.3.2)" -lt 0 ]; then
340 cat <<'EOT'
343 *** ERROR: $Girocco::Config::git_bin is set to an incompatible version of Git
346 Git versions starting with 2.2.0 and continuing up through 2.3.1 are incompatible
347 with Girocco due to various unresolved issues. Please either downgrade to 2.1.4
348 or earlier or, more preferred, upgrade to 2.3.2 (ideally 2.4.11) or later.
350 In order to bypass this check you will have to modify install.sh in which case
351 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
354 exit 1
356 if [ "$(vcmp "$git_vernum" 2.3.3)" -lt 0 ]; then
357 echo 'WARNING: $Girocco::Config::git_bin version < 2.3.3, performance will be sub-optimal'
359 if [ "$(vcmp "$git_vernum" 2.4.4)" -lt 0 ]; then
360 echo 'WARNING: $Girocco::Config::git_bin version < 2.4.4, many refs smart HTTP fetches can deadlock'
362 if [ "$(vcmp "$git_vernum" 2.10.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.3)" -lt 0 ]; then
363 echo 'WARNING: $Girocco::Config::git_bin version >= 2.10.1 and < 2.12.3, --pickaxe-regex can segfault'
364 echo 'WARNING: If gitweb pickaxe regular expression searches are enabled, --pickaxe-regex will be used'
365 echo 'WARNING: See the fix at http://repo.or.cz/git.git/f53c5de29cec68e3 for details'
366 echo 'WARNING: The fix is trivial and easily cherry-picked into a custom 2.10.1 - 2.12.2 build'
367 echo 'WARNING: Leaving the gitweb/gitweb_config.perl "regexp" feature off as recommended avoids the issue'
369 secmsg=
370 if [ "$(vcmp "$git_vernum" 2.4.11)" -lt 0 ]; then
371 secmsg='prior to 2.4.11'
373 if [ "$(vcmp "$git_vernum" 2.5)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.5.5)" -lt 0 ]; then
374 secmsg='2.5.x prior to 2.5.5'
376 if [ "$(vcmp "$git_vernum" 2.6)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.6.6)" -lt 0 ]; then
377 secmsg='2.6.x prior to 2.6.6'
379 if [ "$(vcmp "$git_vernum" 2.7)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.7.4)" -lt 0 ]; then
380 secmsg='2.7.x prior to 2.7.4'
382 if [ -n "$secmsg" ]; then
383 cat <<EOT
386 *** SEVERE WARNING: \$Girocco::Config::git_bin is set to a version of Git $secmsg
389 Security issues exist in Git versions prior to 2.4.11, 2.5.x prior to 2.5.5,
390 2.6.x prior to 2.6.6 and 2.7.x prior to 2.7.4.
392 Besides the security fixes included in later versions, versions prior to
393 2.2.0 may accidentally prune unreachable loose objects earlier than
394 intended. Since Git version 2.4.11 is the minimum version to include all
395 security fixes to date, it should be considered the absolute minimum
396 version of Git to use when running Girocco.
398 This is not enforced, but Git is easy to build from the git.git submodule
399 and upgrading to GIT VERSION 2.4.11 OR LATER IS HIGHLY RECOMMENDED.
401 We will now pause for a moment so you can reflect on this warning.
404 sleep 60
406 if [ -n "$cfg_mirror" ] && [ "$cfg_mirror" != 0 ] && LC_ALL=C grep -a -q ns_parserr "$cfg_git_bin"; then
407 cat <<'EOT'
410 *** WARNING: $Girocco::Config::git_bin is set to a questionable Git binary
413 You appear to have enabled mirroring and the Git binary you have selected
414 appears to contain an experimental patch that cannot be disabled. This
415 patch can generate invalid network DNS traffic and/or cause long delays
416 when fetching using the "git:" protocol when no port number is specified.
417 It may also end up retrieving repsitory contents from a host other than
418 the one specified in the "git:" URL when the port is omitted.
420 You are advised to either build your own version of Git (the problem patch
421 is not part of the official Git repository) or disable mirroring (via the
422 $Girocco::Config:mirror setting) to avoid these potential problems.
424 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
427 sleep 5
430 test_nc_U() {
431 [ -n "$1" ] || return 1
432 _cmdnc="$(command -v "$1" 2>/dev/null)" || :
433 [ -n "$_cmdnc" ] && [ -f "$_cmdnc" ] && [ -x "$_cmdnc" ] || return 1
434 _tmpdir="$(mktemp -d /tmp/nc-u-XXXXXX)"
435 [ -n "$_tmpdir" ] && [ -d "$_tmpdir" ] || return 1
436 >"$_tmpdir/output"
437 (sleep 3 | "$_cmdnc" -l -U "$_tmpdir/socket" 2>/dev/null >"$_tmpdir/output" || >"$_tmpdir/failed")&
438 sleep 1
439 _bgpid="$!"
440 echo "testing" | "$_cmdnc" -w 1 -U "$_tmpdir/socket" >/dev/null 2>&1 || >"$_tmpdir/failed"
441 sleep 1
442 kill "$_bgpid" >/dev/null 2>&1 || :
443 sleep 1
444 read -r _result <"$_tmpdir/output" || :
445 _bad=
446 ! [ -e "$_tmpdir/failed" ] || _bad=1
447 rm -rf "$_tmpdir"
448 [ -z "$_bad" ] && [ "$_result" = "testing" ]
449 } >/dev/null 2>&1
451 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
452 test_nc_U "$var_nc_openbsd_bin" || {
453 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
454 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
455 uname_s="$(uname -s 2>/dev/null | tr A-Z a-z 2>/dev/null)" || :
456 case "$uname_s" in
457 *dragonfly*)
458 echo "ERROR: see the src/dragonfly/README file for a solution" >&2;;
459 *kfreebsd*|*linux*)
460 echo "ERROR: try installing the package named 'netcat-openbsd'" >&2;;
461 esac
462 exit 1
465 echo "*** Verifying selected POSIX sh is sane..."
466 shbin="$var_sh_bin"
467 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
468 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
469 exit 1
471 [ "$(check_sh_builtin command)" = "command" ] || {
472 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
473 exit 1
475 sh_not_builtin=
476 sh_extra_chroot_installs=
477 badsh=
478 for sbi in cd pwd read umask unset unalias; do
479 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
480 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
481 badsh=1
483 done
484 [ -z "$badsh" ] || exit 1
485 for sbi in '[' echo printf test; do
486 if ! extra="$(check_sh_builtin "$sbi")"; then
487 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
488 badsh=1
489 continue
491 if [ "$extra" != "$sbi" ]; then
492 case "$extra" in /*) :;; *)
493 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
494 badsh=1
495 continue
496 esac
497 withspc=
498 case "$extra" in *" "*) withspc=1; esac
499 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
500 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
501 badsh=1
502 continue
504 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
505 sh_not_builtin="$sh_not_builtin $sbi"
506 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
508 done
509 [ -z "$badsh" ] || exit 1
510 [ -z "$sh_extra_chroot_installs" ] || {
511 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
512 echo "WARNING: as a result it will run slower than necessary" >&2
513 echo "WARNING: consider building and switching to dash which can be found at:" >&2
514 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
515 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
516 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
517 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
520 echo "*** Verifying xargs is sane..."
521 _xargsr="$(</dev/null command xargs printf %s -r)" || :
522 xtest1="$(</dev/null command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
523 xtest2="$(printf '%s\n' one two | command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
524 [ -z "$xtest1" ] && [ "$xtest2" = "test one test two " ] || {
525 echo 'ERROR: xargs is unusable' >&2
526 echo 'ERROR: either `test -z "$(</dev/null xargs echo test 2>/dev/null)"`' >&2
527 echo 'ERROR: or `test -z "$(</dev/null xargs -r echo test 2>/dev/null)"`' >&2
528 echo 'ERROR: must be true, but neither is' >&2
529 exit 1
532 echo "*** Verifying selected perl is sane..."
533 perlbin="$var_perl_bin"
534 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
535 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
536 exit 1
539 echo "*** Verifying selected gzip is sane..."
540 gzipbin="$var_gzip_bin"
541 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
542 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
543 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
544 exit 1
547 echo "*** Verifying basedir, webroot, webreporoot and cgiroot paths..."
548 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
549 case "$cfg_basedir" in /*) :;; *)
550 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
551 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
552 exit 1
553 esac
554 case "$cfg_webroot" in /*) :;; *)
555 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
556 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
557 exit 1
558 esac
559 if [ -n "$cfg_webreporoot" ]; then
560 case "$cfg_webreporoot" in /*) :;; *)
561 echo "ERROR: invalid Girocco::Config::webreporoot setting" >&2
562 echo "ERROR: \"$cfg_webreporoot\" must be an absolute path (start with '/') or undef" >&2
563 exit 1
564 esac
566 case "$cfg_cgiroot" in /*) :;; *)
567 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
568 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
569 exit 1
570 esac
572 echo "*** Verifying installation preconditions..."
574 # Make sure Markdown.pm is present and use'able
576 ! [ -e Markdown.pm ] || ! [ -f Markdown.pm ] || ! [ -s Markdown.pm ] ||
577 ! mdoutput="$("$perlbin" 2>/dev/null -I"$PWD" -MMarkdown=Markdown,ProcessRaw -e \
578 'use strict; use warnings; print Markdown("_test_ **this**"); exit 0;')"
579 then
580 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
581 exit 1
583 # And that it at least appears to function properly
584 if [ "$mdoutput" != '<p><em>test</em> <strong>this</strong></p>' ]; then
585 echo "ERROR: markdown.git verification test failed -- Markdown function does not work" >&2
586 exit 1
589 # return the input with trailing slashes stripped but return "/" for all "/"s
590 striptrsl() {
591 [ -n "$1" ] || return 0
592 _s="${1##*[!/]}"
593 [ "$_s" != "$1" ] || _s="${_s#?}"
594 printf "%s\n" "${1%$_s}"
597 # a combination of realpath + dirname where the realpath of the deepest existing
598 # directory is returned with the rest of the non-existing components appended
599 # and trailing slashes and multiple slashes are removed
600 realdir() {
601 _d="$(striptrsl "$1")"
602 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
603 echo "$_d"
604 return 0
606 _c=""
607 while ! [ -d "$_d" ]; do
608 _c="/$(basename "$_d")$_c"
609 _d="$(dirname "$_d")"
610 [ "$_d" != "/" ] || _c="${_c#/}"
611 done
612 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
615 # Use basedir, webroot and cgiroot for easier control of filesystem locations
616 # Wherever we are writing/copying/installing files we use these, but where we
617 # are editing, adding config settings or printing advice we always stick to the
618 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
619 # Only the file system directories that could be asynchronously accessed (by
620 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
621 # The chroot is handled specially and does not need one of these.
622 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
623 # case the prior contents of cgiroot and/or webroot are discarded.
624 rbasedir="$(realdir "$cfg_basedir")"
625 rwebroot="$(realdir "$cfg_webroot")"
626 rwebreporoot=
627 [ -z "$cfg_webreporoot" ] || {
628 # avoid resolving a pre-existing symlink from a previous install
629 rwebreporoot="$(realdir "${cfg_webreporoot%/}_NOSUCHDIR")"
630 rwebreporoot="${rwebreporoot%_NOSUCHDIR}"
632 rcgiroot="$(realdir "$cfg_cgiroot")"
633 case "$rbasedir" in "$rwebroot"/?*)
634 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
635 exit 1
636 esac
637 case "$rbasedir" in "$rcgiroot"/?*)
638 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
639 exit 1
640 esac
641 if [ "$rwebroot" = "$rcgiroot" ]; then
642 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
643 exit 1
645 case "$rcgiroot" in "$rwebroot"/?*)
646 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
647 exit 1
648 esac
649 case "$rwebroot" in "$rcgiroot"/?*)
650 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
651 exit 1
652 esac
653 if [ -n "$rwebreporoot" ]; then
654 if [ "$rwebreporoot" = "$rwebroot" ]; then
655 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::webreporoot settings; must not be the same" >&2
656 exit 1
658 case "$rwebreporoot" in "$rwebroot"/?*);;*)
659 echo "ERROR: invalid Girocco::Config::webreporoot setting; must be under webroot or undef" >&2
660 exit 1
661 esac
663 basedir="$rbasedir-new"
664 case "$rwebroot" in
665 "$rbasedir"/?*)
666 webroot="$basedir${rwebroot#$rbasedir}"
667 webrootsub=1
670 webroot="$rwebroot-new"
671 webrootsub=
673 esac
674 webreporoot=
675 [ -z "$rwebreporoot" ] || webreporoot="$webroot${rwebreporoot#$rwebroot}"
676 case "$rcgiroot" in
677 "$rbasedir"/?*)
678 cgiroot="$basedir${rcgiroot#$rbasedir}"
679 cgirootsub=1
682 cgiroot="$rcgiroot-new"
683 cgirootsub=
685 esac
687 echo "*** Setting up basedir..."
689 chown_make() {
690 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
691 find -H "$@" -user root -exec chown "$SUDO_USER:$(id -gn "$SUDO_USER")" '{}' + 2>/dev/null || :
692 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
693 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
697 "$MAKE" --no-print-directory --silent apache.conf
698 chown_make apache.conf
699 "$MAKE" --no-print-directory --silent -C src
700 chown_make src
701 rm -fr "$basedir"
702 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
703 # make the mtlinesfile with 1000 empty lines
704 yes '' | dd bs=1000 count=1 2>/dev/null >"$basedir/mtlinesfile"
705 chmod a+r "$basedir/mtlinesfile"
706 cp cgi/*.cgi "$basedir/cgi"
707 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
708 rm -f "$basedir/Girocco/Dumper.pm" # Dumper.pm is only for the install.sh process
709 rm -f "$basedir/Girocco/Validator.pm" # Validator.pm is only for the install.sh process
710 find -H "$basedir" -type l -exec rm -f '{}' +
711 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
712 src/rangecgi src/readlink src/strftime src/throttle src/ulimit512 src/ltsha256 \
713 ezcert.git/CACreateCert cgi/authrequired.cgi cgi/snapshot.cgi \
714 "$basedir/bin"
715 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
716 if [ -n "$cfg_httpspushurl" ]; then
717 [ -z "$cfg_pretrustedroot" ] || rm -f "$basedir"/html/rootcert.html
718 else
719 rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
721 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
723 # Put the frozen Config in place
724 VARLIST="$(get_girocco_config_var_list varonly)" && export VARLIST
725 perl -I"$PWD" -MGirocco::Dumper=FreezeConfig -MScalar::Util=looks_like_number -e '
726 my $usemod = $ARGV[0];
727 my $f = sub { return () unless $_[0] =~ /^(var_[^=\s]+)=(.*)$/;
728 my ($k,$v) = ($1,$2);
729 $v =~ s/([\@\%])/\\$1/gos;
730 $v = "\"".$v."\"" unless substr($v,0,1) eq "\"" || looks_like_number($v);
731 my $e = eval $v;
732 [$k, $e] };
733 my @vars = map({&$f($_)} split(/\n+/, $ENV{VARLIST}));
734 my $s = sub { my $conf = shift;
735 foreach (@vars) {
736 my ($k,$v) = @{$_};
737 eval "\$${conf}::$k=\$v";
740 print FreezeConfig([$usemod,"Girocco::Validator"], undef, $s);
741 ' -- "$GIROCCO_CONF" >"$basedir/Girocco/Config.pm"
742 unset VARLIST
744 # Create symbolic links to selected binaries
745 ln -s "$cfg_git_bin" "$basedir/bin/git"
746 ln -s "$shbin" "$basedir/bin/sh"
747 ln -s "$perlbin" "$basedir/bin/perl"
748 ln -s "$gzipbin" "$basedir/bin/gzip"
749 [ -z "$var_openssl_bin" ] || ln -s "$var_openssl_bin" "$basedir/bin/openssl"
751 echo "*** Preprocessing scripts..."
752 SHBIN="$shbin" && export SHBIN
753 PERLBIN="$perlbin" && export PERLBIN
754 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
755 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
756 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
757 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
758 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
759 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
760 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
761 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
762 -e 's/\@cgiroot\@/"$Girocco::Config::cgiroot"/g;' \
763 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
764 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
765 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
766 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
767 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
768 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
769 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
770 -e 's/\@autogchack\@/"$Girocco::Config::autogchack"/g;' \
771 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
772 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
773 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
774 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
775 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
776 -e 's/\@fetch_stash_refs\@/"$Girocco::Config::fetch_stash_refs"/g;' \
777 -e 's/\@suppress_git_ssh_logging\@/"$Girocco::Config::suppress_git_ssh_logging"/g;' \
778 -e 's/\@max_file_size512\@/"$Girocco::Config::max_file_size512"/g;' \
779 -e 's/\@cfg_name\@/"$Girocco::Config::name"/g;' \
780 -e 'close ARGV if eof;' \
781 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
782 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
783 "$basedir"/shlib.sh "$basedir"/hooks/* \
784 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
785 "$basedir"/toolbox/reports/*.sh \
786 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
787 "$basedir"/bin/create-* "$basedir"/bin/update-* \
788 "$basedir"/bin/*.cgi "$basedir"/screen/*
789 perl -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -i -p \
790 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
791 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
792 "$basedir"/cgi/*.cgi "$basedir"/gitweb/*.perl \
793 "$basedir"/jobd/*.pl "$basedir"/taskd/*.pl
794 perl -i -p \
795 -e 'BEGIN {my @a; m|^(/.+)$| && push(@a, $1) or die "bad path: $_" for @ARGV; @ARGV=@a}' \
796 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
797 -e 'close ARGV if eof;' \
798 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
799 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
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 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
804 -e 'close ARGV if eof;' \
805 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
806 unset PERLBIN
807 unset SHBIN
809 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
810 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
812 if [ "${cfg_mirror_darcs:-0}" != "0" ]; then
813 echo "*** Setting up darcs-fast-export from girocco-darcs-fast-export.git..."
814 if ! [ -f girocco-darcs-fast-export.git/darcs-fast-export ] ||
815 ! [ -x girocco-darcs-fast-export.git/darcs-fast-export ]; then
816 echo "ERROR: girocco-darcs-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
817 exit 1
819 mkdir -p "$basedir"/bin
820 cp girocco-darcs-fast-export.git/darcs-fast-export "$basedir"/bin
823 if [ "${cfg_mirror_hg:-0}" != "0" ]; then
824 echo "*** Setting up hg-fast-export from girocco-hg-fast-export.git..."
825 if ! [ -f girocco-hg-fast-export.git/hg-fast-export.py ] || ! [ -f girocco-hg-fast-export.git/hg2git.py ]; then
826 echo "ERROR: girocco-hg-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
827 exit 1
829 mkdir -p "$basedir"/bin
830 cp girocco-hg-fast-export.git/hg-fast-export.py girocco-hg-fast-export.git/hg2git.py "$basedir"/bin
833 echo "*** Setting up markdown from markdown.git..."
834 if ! [ -f markdown.git/Markdown.pl ]; then
835 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
836 exit 1
838 mkdir -p "$basedir"/bin
839 (PERLBIN="$perlbin" && export PERLBIN &&
840 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
841 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
842 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
843 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
844 test $? -eq 0
845 (umask 0133 && ln -s -f -n bin/Markdown.pl "$basedir"/Markdown.pm)
846 test $? -eq 0
848 # Some permission sanity on basedir/bin just in case
849 find -H "$basedir"/bin -type f -exec chmod go-w '{}' +
850 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
852 if [ -n "$cfg_mirror" ]; then
853 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
855 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.pl, or add this"
856 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
857 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.pl -q --all-once"
860 echo "*** Setting up repository root..."
861 [ -d "$cfg_reporoot" ] || {
862 mkdir -p "$cfg_reporoot"
863 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot" ||
864 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot"
866 [ -z "$cfg_owning_group" ] ||
867 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
868 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
869 mkdir -p "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty"
870 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" ||
871 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot/{_recyclebin,_global} properly"
872 if [ "$cfg_owning_group" ]; then
873 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
874 chgrp -R "$cfg_owning_group" "$cfg_reporoot/_global" || echo "WARNING: Cannot chgrp -R $cfg_owning_group $cfg_reporoot/_global"
876 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
877 chmod 00755 "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" || echo "WARNING: Cannot chmod $cfg_reporoot/_global properly"
880 usejail=
881 [ "${cfg_disable_jailsetup:-0}" != "0" ] || [ "${cfg_chrooted:-0}" = "0" ] || usejail=1
882 if [ -n "$usejail" ]; then
883 echo "*** Setting up chroot jail for pushing..."
884 if [ -n "$isroot" ]; then
885 # jailsetup may install things from $cfg_basedir/bin into the
886 # chroot so we do a mini-update of just that portion now
887 mkdir -p "$cfg_basedir"
888 rm -rf "$cfg_basedir/bin-new"
889 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
890 rm -rf "$cfg_basedir/bin-old"
891 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
892 rm -rf "$cfg_basedir/bin-old"
893 if [ -n "$sh_extra_chroot_installs" ]; then
894 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
895 export GIROCCO_CHROOT_EXTRA_INSTALLS
897 ./jailsetup.sh
898 unset GIROCCO_CHROOT_EXTRA_INSTALLS
899 else
900 echo "WARNING: Skipping jail setup, not root"
905 echo "*** Setting up jail configuration (project database)..."
906 [ -n "$usejail" ] && [ -n "$isroot" ] || ./jailsetup.sh dbonly
907 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
908 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
909 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
910 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
911 if [ -n "$usejail" ]; then
912 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
913 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
914 else
915 # If a chroot jail is not in use, sudo privileges are neither expected nor required
916 # which means it will not be possible to change the owner of the passwd and group
917 # files if it differs from the mirror user. And that's okay, provided the group
918 # can still be set correctly to the owning group. But, just in case we're running
919 # as root, go ahead and set the owner to the mirror user.
920 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
921 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup the etc/passwd and/or etc/group files"
923 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
924 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
925 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
928 echo "*** Setting up global hook scripts..."
929 # It is absolutely CRUCIAL that hook script replacements are done atomically!
930 # Otherwise an incoming push might slip in and fail to run the hook script!
931 # The underlying rename(2) function call provides this and mv will use it.
932 # First add hook scripts
933 hooks="pre-auto-gc pre-receive post-commit post-receive update"
934 for hook in $hooks; do
935 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
936 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
937 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
938 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
939 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
940 done
941 # Then remove any hook scripts that do not belong
942 for hook in "$cfg_reporoot/_global/hooks"/*; do
943 hook="${hook##*/}"
944 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
945 case " $hooks " in *" $hook "*);;*)
946 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
947 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
948 esac
949 done
952 echo "*** Setting up gitweb from git.git..."
953 if ! [ -f git.git/Makefile ]; then
954 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
955 exit 1
958 # We do not wholesale replace either webroot or cgiroot unless they are under
959 # basedir so if they exist and are not we make a copy to start working on them.
960 # We make a copy using -p which can result in some warnings so we suppress
961 # error output as it's of no consequence in this case.
962 rm -rf "$webroot" "$cgiroot"
963 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
964 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
965 mkdir -p "$webroot" "$cgiroot"
968 cd git.git &&
969 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
970 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
971 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
972 chown_make gitweb &&
973 PERLBIN="$perlbin" && export PERLBIN &&
974 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
975 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
976 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
977 chown_make "$cgiroot"/gitweb.cgi.$$ &&
978 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
979 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
981 test $? -eq 0
984 echo "*** Setting up git-browser from git-browser.git..."
985 if ! [ -f git-browser.git/git-browser.cgi ]; then
986 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
987 exit 1
989 mkdir -p "$webroot"/git-browser "$cgiroot"
991 cd git-browser.git &&
992 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
993 PERLBIN="$perlbin" && export PERLBIN && perl -p \
994 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
995 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
996 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
997 chown_make "$cgiroot"/git-browser.cgi.$$ &&
998 perl -p \
999 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
1000 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
1001 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
1002 chown_make "$cgiroot"/git-diff.cgi.$$ &&
1003 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
1004 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
1005 for h in *.html; do
1006 [ "$h" != "index.html" ] || continue
1007 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
1008 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
1009 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
1010 >"$webroot/git-browser/$h.$$" &&
1011 chmod a+r "$webroot/git-browser/$h.$$" &&
1012 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
1013 else
1014 cp -p "$h" "$webroot/git-browser/"
1016 done
1017 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
1018 cp -pR JSON "$cgiroot/"
1020 test $? -eq 0
1021 gitwebabs="$cfg_gitweburl"
1022 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
1023 gitwebabs="${gitwebabs#*://}"
1024 case "$gitwebabs" in
1025 *"/"*) gitwebabs="/${gitwebabs#*/}";;
1026 *) gitwebabs="";;
1027 esac
1028 esac
1029 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
1030 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
1031 gitbin: $cfg_git_bin
1032 gitweb: $gitwebabs
1033 warehouse: $cfg_reporoot
1034 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
1036 chown_make "$basedir/gitweb"/git-browser.conf.$$
1037 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
1038 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
1039 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
1040 cfg_gitweb_url="$cfg_gitweburl/"
1041 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
1042 cfg_home_url="$cfg_gitweburl/%n"
1043 cfg_home_text="summary"
1044 cfg_bycommit_title="$esctitle - %n/graphiclog1"
1045 cfg_bydate_title="$esctitle - %n/graphiclog2"
1047 chown_make "$webroot"/git-browser/GitConfig.js.$$
1048 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
1051 echo "*** Setting up our part of the website..."
1052 mkdir -p "$webroot" "$cgiroot"
1053 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
1054 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
1055 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
1056 cp "$basedir/cgi"/*.cgi "$cgiroot"
1057 rm -rf "$basedir/cgi"
1058 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
1059 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
1060 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
1061 if [ -f gitweb/indextext_readonly.html ]; then
1062 grep -v 'rootcert[.]html' gitweb/indextext_readonly.html \
1063 >"$basedir/gitweb/indextext_readonly.html"
1065 else
1066 cp gitweb/indextext.html "$basedir/gitweb"
1067 if [ -f gitweb/indextext_readonly.html ]; then
1068 cp gitweb/indextext_readonly.html "$basedir/gitweb"
1071 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
1072 cp mootools.js "$webroot"
1073 cp htaccess "$webroot/.htaccess"
1074 cp cgi/htaccess "$cgiroot/.htaccess"
1075 cp git-favicon.ico "$webroot/favicon.ico"
1076 cp robots.txt "$webroot"
1077 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
1080 echo "*** Setting up token keys..."
1081 mkdir -p "$cfg_certsdir/tokenkeys"
1082 "$var_perl_bin" -I"$PWD" -M$GIROCCO_CONF -MGirocco::Validator -MGirocco::Util -MGirocco::TimedToken -e '
1083 my $basedir; $Girocco::Config::certsdir =~ /^(.+)$/ and $basedir = "$1/tokenkeys";
1084 -d "$basedir" && -w _ or die "no such writable directory: \"$basedir\"\n";
1085 foreach (qw(projedit)) {
1086 my $tk = get_token_key($_);
1087 if (!defined($tk)) {
1088 my $tf = "$basedir/$_.tky";
1089 $tk = create_token_secret();
1090 my $fh;
1091 open $fh, ">", "$tf" or
1092 die "unable to open \"$tf\" for writing: $!\n";
1093 printf $fh "%s\n", $tk;
1094 close $fh or die "error closing \"$tf\": $!\n";
1095 printf "%s\n", "Created new $_ token secret";
1101 if [ -n "$cfg_httpspushurl" ]; then
1102 echo "*** Setting up SSL certificates..."
1103 openssl="${var_openssl_bin:-openssl}"
1104 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
1105 bits=2048
1106 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
1107 bits="$cfg_rsakeylength"
1109 mkdir -p "$cfg_certsdir"
1110 [ -d "$cfg_certsdir" ]
1111 wwwcertcn=
1112 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
1113 wwwcertcn="$(
1114 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
1115 tr '\t' ' ' | sed -e 's/^ *subject=//;s/^ *//;s/ *$//;s,^/,,;s,^,/,;s/ *= */=/g;'
1118 wwwcertdns=
1119 if [ -n "$cfg_wwwcertaltnames" ]; then
1120 for dnsopt in $cfg_wwwcertaltnames; do
1121 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
1122 done
1124 wwwcertdnsfile=
1125 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
1126 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1128 needroot=
1129 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1130 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1131 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1132 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1133 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1134 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1135 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1136 umask 0077
1137 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1138 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1139 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1140 umask 0022
1141 echo "Created new root key"
1143 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1144 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1145 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1146 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem" \
1147 "$cfg_certsdir/girocco_www_fullchain.pem"
1148 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1149 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1150 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1151 echo "Created new root certificate"
1153 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1154 umask 0077
1155 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1156 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1157 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1158 umask 0022
1159 echo "Created new www key"
1161 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1162 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1163 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1164 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1165 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1166 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1167 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1168 rm -f "$cfg_certsdir/girocco_www_fullchain.pem"
1169 echo "Created www certificate"
1171 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1172 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1173 echo "Created www certificate chain file"
1175 if ! [ -e "$cfg_certsdir/girocco_www_fullchain.pem" ]; then
1176 cat "$cfg_certsdir/girocco_www_crt.pem" >"$cfg_certsdir/girocco_www_fullchain.pem"
1177 cat "$cfg_certsdir/girocco_www_chain.pem" >>"$cfg_certsdir/girocco_www_fullchain.pem"
1178 echo "Created www certificate full chain file"
1180 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1181 umask 0037
1182 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1183 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1184 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1185 umask 0022
1186 echo "Created new client key"
1188 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1189 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1190 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1191 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1192 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1193 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1194 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1195 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1196 echo "Created client certificate"
1198 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1199 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1200 echo "Created client certificate suffix file"
1202 if [ -z "$cfg_pretrustedroot" ]; then
1203 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1204 else
1205 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1207 if [ -n "$cfg_mob" ]; then
1208 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1209 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1210 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1211 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1212 echo "Created new mob user key"
1214 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1215 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1216 createcert --client --key "$cfg_clientkey" \
1217 --cert "$cfg_clientcert" \
1218 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1219 echo "Created mob user client certificate"
1221 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1222 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1223 else
1224 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1226 else
1227 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1228 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1232 echo "*** Processing website html templates..."
1233 rm -f "$cgiroot/html.cgi"
1234 rm -rf "$cgiroot/html"
1235 mkdir -p "$cgiroot/html"
1236 for tf in "$basedir/html"/*.html; do
1237 tfb="${tf##*/}"
1238 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1239 rm -f "$tf"
1240 done
1242 echo "*** Formatting markdown documentation..."
1243 mkdir -p "$cgiroot/html/gfm"
1244 for d in basics.md syntax.md; do
1246 cat <<-HEADER
1247 <!DOCTYPE html>
1248 <html xmlns="http://www.w3.org/1999/xhtml">
1249 <head>
1250 <meta charset="utf-8" />
1251 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1252 <title>$d</title>
1253 </head>
1254 <body><pre>
1255 HEADER
1256 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1257 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1258 -e 's/ by adding `.md` to the URL//' \
1259 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1260 cat <<-FOOTER
1261 </pre></body>
1262 </html>
1263 FOOTER
1264 } >"$cgiroot/html/gfm/$d.html"
1266 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1267 gwfpath="$cfg_gitwebfiles"
1268 case "$gwfpath" in *"//"*)
1269 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1270 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1271 esac
1272 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1273 gwfpath="${gwfpath%/}"
1274 cat <<-HEADER
1275 <!DOCTYPE html>
1276 <html xmlns="http://www.w3.org/1999/xhtml">
1277 <head>
1278 <meta charset="utf-8" />
1279 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1280 <title>$title</title>
1281 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1282 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1283 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1284 </head>
1285 <body style="text-align:center">
1286 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1287 HEADER
1288 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1289 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1290 -e 's/ by adding `.md` to the URL//' |
1291 "$perlbin" "markdown.git/Markdown.pl"
1292 cat <<-FOOTER
1293 </div>
1294 </body>
1295 </html>
1296 FOOTER
1297 } >"$cgiroot/html/gfm/${d%.md}.html"
1298 done
1301 echo "*** Finalizing permissions and moving into place..."
1302 chmod -R a+r "$basedir" "$webroot" "$cgiroot" >/dev/null 2>&1 || :
1303 find "$basedir" "$webroot" "$cgiroot" -type f -perm -u=x -exec chmod a+x '{}' + >/dev/null 2>&1 || :
1304 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1305 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1307 # This should always be the very last thing install.sh does
1308 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1309 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1310 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1311 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1312 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1313 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1314 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1315 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1316 touch "$cfg_chroot/etc/taskd.restart"
1317 chown_make "$cfg_chroot/etc/taskd.restart"
1318 trap ':' PIPE
1319 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1320 trap - PIPE