config: allow specific openssl binary to be used
[girocco.git] / install.sh
blob11f43454a29cff23a9022e96f483905f0a3e358b
1 #!/bin/sh
2 # The Girocco installation script
3 # We will OVERWRITE basedir!
5 set -e
7 [ -n "$MAKE" ] || MAKE="$(MAKEFLAGS= make -s gnu_make_command_name | grep '^gnu_make_command_name=' | sed 's/^[^=]*=//')"
8 if [ -z "$MAKE" ]; then
9 echo "ERROR: cannot determine name of the GNU make command" >&2
10 echo "Please set MAKE to the name of the GNU make executable" >&2
11 exit 1
14 # Run perl module checker
15 if ! [ -f toolbox/check-perl-modules.pl ] || ! [ -x toolbox/check-perl-modules.pl ]; then
16 echo "ERROR: missing toolbox/check-perl-modules.pl!" >&2
17 exit 1
20 # What Config should we use?
21 [ -n "$GIROCCO_CONF" ] || GIROCCO_CONF=Girocco::Config
22 echo "*** Initializing using $GIROCCO_CONF..."
24 # First run Girocco::Config consistency checks
25 perl -I"$PWD" -M$GIROCCO_CONF -e ''
27 . ./shlib.sh
28 umask 0022
29 "$var_perl_bin" toolbox/check-perl-modules.pl
31 # Config.pm already checked $cfg_reporoot to require an absolute path, but
32 # we also require it does not contain a : or ; that would cause problems when
33 # used in GIT_ALTERNATE_OBJECT_DIRECTORIES
34 probch=':;'
35 case "$cfg_reporoot" in *[$probch]*)
36 echo "fatal: \$Girocco::Config::reporoot may not contain ':' or ';' characters" >&2
37 exit 1
38 esac
40 warn() { printf >&2 '%s\n' "$*"; }
41 die() { warn "$@"; exit 1; }
43 # Either we must run as root (but preferably not if disable_jailsetup is true)
44 # or the mirror_user (preferred choice for disable_jailsetup).
45 if [ "$(id -u)" -eq 0 ]; then
46 if [ "${cfg_disable_jailsetup:-0}" != "0" ]; then
47 cat <<'EOT'
49 ***
50 *** WARNING: $Girocco::Config::disable_jailsetup has been enabled
51 *** WARNING: but installation is being performed as the superuser
52 ***
54 You appear to have disabled jailsetup which is perfectly fine for installations
55 that will not be using an ssh jail. However, in that case, running the install
56 process as the superuser is highly discouraged.
58 Instead, running it as the configured $Girocco::Config::mirror_user is much
59 preferred.
61 The install process will now pause for 10 seconds to give you a chance to abort
62 it before continuing to install a disable_jailsetup config as the superuser.
64 EOT
65 sleep 10 || die "install aborted"
67 else
68 [ -n "$cfg_mirror_user" ] || die 'Girocco::Config.pm $mirror_user must be set'
69 curuname="$(id -un)"
70 [ -n "$curuname" ] || die "Cannot determine name of current user"
71 if [ "$cfg_mirror_user" != "$curuname" ]; then
72 warn "ERROR: install must run as superuser or Config.pm's \$mirror_user ($cfg_mirror_user)"
73 die "ERROR: install is currently running as $curuname"
77 # $1 must exist and be a dir
78 # $2 may exist but must be a dir
79 # $3 must not exist
80 # After call $2 will be renamed to $3 (if $2 existed)
81 # And $1 will be renamed to $2
82 quick_move() {
83 [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] || { echo "fatal: quick_move: bad args: '$1' '$2' '$3'" >&2; exit 1; }
84 ! [ -e "$3" ] || { echo "fatal: quick_move: already exists: $3" >&2; exit 1; }
85 [ -d "$1" ] || { echo "fatal: quick_move: no such dir: $1" >&2; exit 1; }
86 ! [ -e "$2" ] || [ -d "$2" ] || { echo "fatal: quick_move: not a dir: $2" >&2; exit 1; }
87 perl -e 'rename($ARGV[1], $ARGV[2]) or die "rename failed: $!\n" if -d $ARGV[1];
88 rename($ARGV[0], $ARGV[1]) or die "rename failed: $!\n"; exit 0;' "$1" "$2" "$3" || {
89 echo "fatal: quick_move: rename failed" >&2
90 exit 1
92 ! [ -d "$1" ] && [ -d "$2" ] || {
93 echo "fatal: quick_move: rename failed" >&2
94 exit 1
98 check_sh_builtin() (
99 "unset" -f command
100 "command" "$var_sh_bin" -c '{ "unset" -f unalias command "$1" || :; "unalias" "$1" || :; } >/dev/null 2>&1; "command" -v "$1"' "$var_sh_bin" "$1"
101 ) 2>/dev/null
103 owngroup=
104 [ -z "$cfg_owning_group" ] || owngroup=":$cfg_owning_group"
105 if [ -n "$cfg_httpspushurl" ] && [ -z "$cfg_certsdir" ]; then
106 echo "ERROR: \$httpspushurl is set but \$certsdir is not!" >&2
107 echo "ERROR: perhaps you have an incorrect Config.pm?" >&2
108 exit 1
112 # Check for extra required tools
113 if [ "${cfg_xmllint_readme:-0}" != "0" ] && ! command -v xmllint >/dev/null; then
114 echo "ERROR: \$xmllint_readme set but xmllint not in \$PATH!" >&2
115 exit 1
119 echo "*** Checking for compiled utilities..."
120 if ! [ -f src/can_user_push ] || ! [ -x src/can_user_push ]; then
121 echo "ERROR: src/can_user_push is not built! Did you _REALLY_ read INSTALL?" >&2
122 echo "ERROR: perhaps you forgot to run make?" >&2
123 exit 1
125 if ! [ -f src/can_user_push_http ] || ! [ -x src/can_user_push_http ]; then
126 echo "ERROR: src/can_user_push_http is not built! Did you _REALLY_ read INSTALL?" >&2
127 echo "ERROR: perhaps you forgot to run make?" >&2
128 exit 1
130 if ! [ -f src/getent ] || ! [ -x src/getent ]; then
131 echo "ERROR: src/getent is not built! Did you _REALLY_ read INSTALL?" >&2
132 echo "ERROR: perhaps you forgot to run make?" >&2
133 exit 1
135 if ! [ -f src/get_user_uuid ] || ! [ -x src/get_user_uuid ]; then
136 echo "ERROR: src/get_user_uuid is not built! Did you _REALLY_ read INSTALL?" >&2
137 echo "ERROR: perhaps you forgot to run make?" >&2
138 exit 1
140 if ! [ -f src/list_packs ] || ! [ -x src/list_packs ]; then
141 echo "ERROR: src/list_packs is not built! Did you _REALLY_ read INSTALL?" >&2
142 echo "ERROR: perhaps you forgot to run make?" >&2
143 exit 1
145 if ! [ -f src/peek_packet ] || ! [ -x src/peek_packet ]; then
146 echo "ERROR: src/peek_packet is not built! Did you _REALLY_ read INSTALL?" >&2
147 echo "ERROR: perhaps you forgot to run make?" >&2
148 exit 1
150 if ! [ -f src/rangecgi ] || ! [ -x src/rangecgi ]; then
151 echo "ERROR: src/rangecgi is not built! Did you _REALLY_ read INSTALL?" >&2
152 echo "ERROR: perhaps you forgot to run make?" >&2
153 exit 1
155 if ! [ -f src/readlink ] || ! [ -x src/readlink ]; then
156 echo "ERROR: src/readlink is not built! Did you _REALLY_ read INSTALL?" >&2
157 echo "ERROR: perhaps you forgot to run make?" >&2
158 exit 1
160 if ! [ -f src/strftime ] || ! [ -x src/strftime ]; then
161 echo "ERROR: src/strftime is not built! Did you _REALLY_ read INSTALL?" >&2
162 echo "ERROR: perhaps you forgot to run make?" >&2
163 exit 1
165 if ! [ -f src/throttle ] || ! [ -x src/throttle ]; then
166 echo "ERROR: src/throttle is not built! Did you _REALLY_ read INSTALL?" >&2
167 echo "ERROR: perhaps you forgot to run make?" >&2
168 exit 1
170 if ! [ -f src/ulimit512 ] || ! [ -x src/ulimit512 ]; then
171 echo "ERROR: src/ulimit512 is not built! Did you _REALLY_ read INSTALL?" >&2
172 echo "ERROR: perhaps you forgot to run make?" >&2
173 exit 1
175 ebin="/bin/echo"
176 if [ ! -x "$ebin" ] && [ -x "/usr/bin/echo" ]; then
177 ebin="/usr/bin/echo"
179 if [ ! -x "$ebin" ]; then
180 echo "ERROR: neither /bin/echo nor /usr/bin/echo found" >&2
181 echo "ERROR: at least one must be present for testing during install" >&2
182 exit 1
184 ec=999
185 tmpfile="$(mktemp "/tmp/ul512-$$-XXXXXX")"
186 { src/ulimit512 -f 0 "$ebin" test >"$tmpfile" || ec=$?; } >/dev/null 2>&1
187 rm -f "$tmpfile"
188 if [ "$ec" = "999" ] || [ "$ec" = "0" ]; then
189 echo "ERROR: src/ulimit512 is built, but broken!" >&2
190 echo "ERROR: exceeding file size limit did not fail!" >&2
191 exit 1
193 if ! [ -f src/ltsha256 ] || ! [ -x src/ltsha256 ]; then
194 echo "ERROR: src/ltsha256 is not built! Did you _REALLY_ read INSTALL?" >&2
195 echo "ERROR: perhaps you forgot to run make?" >&2
196 exit 1
198 sha256check="15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"
199 sha256result="$(printf '%s' '123456789' | src/ltsha256)"
200 if [ "$sha256check" != "$sha256result" ]; then
201 echo "ERROR: src/ltsha256 is built, but broken!" >&2
202 echo "ERROR: verifying sha256 hash of '123456789' failed!" >&2
203 exit 1
207 echo "*** Checking for ezcert..."
208 if ! [ -f ezcert.git/CACreateCert ] || ! [ -x ezcert.git/CACreateCert ]; then
209 echo "ERROR: ezcert.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
210 exit 1
214 echo "*** Checking for git..."
215 case "$cfg_git_bin" in /*) :;; *)
216 echo 'ERROR: $Girocco::Config::git_bin must be set to an absolute path' >&2
217 exit 1
218 esac
219 if ! [ -f "$cfg_git_bin" ] || ! [ -x "$cfg_git_bin" ]; then
220 echo "ERROR: $cfg_git_bin does not exist or is not executable" >&2
221 exit 1
223 if ! git_version="$("$cfg_git_bin" version)" || [ -z "$git_version" ]; then
224 echo "ERROR: $cfg_git_bin version failed" >&2
225 exit 1
227 case "$git_version" in
228 [Gg]"it version "*) :;;
230 echo "ERROR: '$cfg_git_bin version' output does not start with 'git version '" >&2
231 exit 1
232 esac
233 echo "Found $cfg_git_bin $git_version"
234 git_vernum="$(echo "$git_version" | sed -ne 's/^[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/p')"
235 echo "*** Checking Git $git_vernum for compatibility..."
236 if [ "$(vcmp "$git_vernum" 1.6.6)" -lt 0 ]; then
237 echo 'ERROR: $Girocco::Config::git_bin must be at least Git version 1.6.6'
238 exit 1
240 if [ "$(vcmp "$git_vernum" 1.6.6.3)" -lt 0 ]; then
241 echo 'WARNING: $Girocco::Config::git_bin version < 1.6.6.3, clients will not see useful error messages'
243 if [ "$(vcmp "$git_vernum" 1.7.3)" -lt 0 ]; then
244 cat <<'EOT'
247 *** SEVERE WARNING: $Girocco::Config::git_bin is set to a version of Git before 1.7.3
250 Some Girocco functionality will be gracefully disabled and other things will
251 just not work at all such as race condition protection against simultaneous
252 client pushes and server garbage collections.
256 if [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 1.7.5)" -lt 0 ]; then
257 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.5 and mirroring enabled, some sources can cause an infinite fetch loop'
259 if [ "$(vcmp "$git_vernum" 1.7.6.6)" -lt 0 ]; then
260 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.6.6, performance may be degraded'
262 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
263 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'
264 echo 'WARNING: See https://lore.kernel.org/git/20141222041944.GA441@peff.net/ for details'
266 if [ "$(vcmp "$git_vernum" 1.8.4.2)" -ge 0 ] && [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 2)" -lt 0 ]; then
267 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, git-daemon needs write access for shallow clones'
268 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, shallow clones will leave repository turds'
270 if [ "$(vcmp "$git_vernum" 1.8.4.3)" -lt 0 ]; then
271 echo 'WARNING: $Girocco::Config::git_bin version < 1.8.4.3, clients will not receive symref=HEAD:refs/heads/...'
273 if [ "$(vcmp "$git_vernum" 2.1)" -lt 0 ]; then
274 echo 'WARNING: $Girocco::Config::git_bin version < 2.1.0, pack bitmaps will not be available'
276 if [ "$(vcmp "$git_vernum" 2.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.1.3)" -lt 0 ]; then
277 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'
279 if [ "$(vcmp "$git_vernum" 2.2)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.3.2)" -lt 0 ]; then
280 cat <<'EOT'
283 *** ERROR: $Girocco::Config::git_bin is set to an incompatible version of Git
286 Git versions starting with 2.2.0 and continuing up through 2.3.1 are incompatible
287 with Girocco due to various unresolved issues. Please either downgrade to 2.1.4
288 or earlier or, more preferred, upgrade to 2.3.2 (ideally 2.4.11) or later.
290 In order to bypass this check you will have to modify install.sh in which case
291 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
294 exit 1
296 if [ "$(vcmp "$git_vernum" 2.3.3)" -lt 0 ]; then
297 echo 'WARNING: $Girocco::Config::git_bin version < 2.3.3, performance will be sub-optimal'
299 if [ "$(vcmp "$git_vernum" 2.4.4)" -lt 0 ]; then
300 echo 'WARNING: $Girocco::Config::git_bin version < 2.4.4, many refs smart HTTP fetches can deadlock'
302 if [ "$(vcmp "$git_vernum" 2.10.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.3)" -lt 0 ]; then
303 echo 'WARNING: $Girocco::Config::git_bin version >= 2.10.1 and < 2.12.3, --pickaxe-regex can segfault'
304 echo 'WARNING: If gitweb pickaxe regular expression searches are enabled, --pickaxe-regex will be used'
305 echo 'WARNING: See the fix at http://repo.or.cz/git.git/f53c5de29cec68e3 for details'
306 echo 'WARNING: The fix is trivial and easily cherry-picked into a custom 2.10.1 - 2.12.2 build'
307 echo 'WARNING: Leaving the gitweb/gitweb_config.perl "regexp" feature off as recommended avoids the issue'
309 secmsg=
310 if [ "$(vcmp "$git_vernum" 2.4.11)" -lt 0 ]; then
311 secmsg='prior to 2.4.11'
313 if [ "$(vcmp "$git_vernum" 2.5)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.5.5)" -lt 0 ]; then
314 secmsg='2.5.x prior to 2.5.5'
316 if [ "$(vcmp "$git_vernum" 2.6)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.6.6)" -lt 0 ]; then
317 secmsg='2.6.x prior to 2.6.6'
319 if [ "$(vcmp "$git_vernum" 2.7)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.7.4)" -lt 0 ]; then
320 secmsg='2.7.x prior to 2.7.4'
322 if [ -n "$secmsg" ]; then
323 cat <<EOT
326 *** SEVERE WARNING: \$Girocco::Config::git_bin is set to a version of Git $secmsg
329 Security issues exist in Git versions prior to 2.4.11, 2.5.x prior to 2.5.5,
330 2.6.x prior to 2.6.6 and 2.7.x prior to 2.7.4.
332 Besides the security fixes included in later versions, versions prior to
333 2.2.0 may accidentally prune unreachable loose objects earlier than
334 intended. Since Git version 2.4.11 is the minimum version to include all
335 security fixes to date, it should be considered the absolute minimum
336 version of Git to use when running Girocco.
338 This is not enforced, but Git is easy to build from the git.git submodule
339 and upgrading to GIT VERSION 2.4.11 OR LATER IS HIGHLY RECOMMENDED.
341 We will now pause for a moment so you can reflect on this warning.
344 sleep 60
346 if [ -n "$cfg_mirror" ] && [ "$cfg_mirror" != 0 ] && grep -q ns_parserr "$cfg_git_bin"; then
347 cat <<'EOT'
350 *** WARNING: $Girocco::Config::git_bin is set to a questionable Git binary
353 You appear to have enabled mirroring and the Git binary you have selected
354 appears to contain an experimental patch that cannot be disabled. This
355 patch can generate invalid network DNS traffic and/or cause long delays
356 when fetching using the "git:" protocol when no port number is specified.
357 It may also end up retrieving repsitory contents from a host other than
358 the one specified in the "git:" URL when the port is omitted.
360 You are advised to either build your own version of Git (the problem patch
361 is not part of the official Git repository) or disable mirroring (via the
362 $Girocco::Config:mirror setting) to avoid these potential problems.
364 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
367 sleep 5
370 test_nc_U() {
371 [ -n "$1" ] || return 1
372 _cmdnc="$(command -v "$1" 2>/dev/null)" || :
373 [ -n "$_cmdnc" ] && [ -f "$_cmdnc" ] && [ -x "$_cmdnc" ] || return 1
374 _tmpdir="$(mktemp -d /tmp/nc-u-XXXXXX)"
375 [ -n "$_tmpdir" ] && [ -d "$_tmpdir" ] || return 1
376 >"$_tmpdir/output"
377 (sleep 3 | "$_cmdnc" -l -U "$_tmpdir/socket" 2>/dev/null >"$_tmpdir/output" || >"$_tmpdir/failed")&
378 _bgpid="$!"
379 sleep 1
380 echo "testing" | "$_cmdnc" -w 1 -U "$_tmpdir/socket" >/dev/null 2>&1 || >"$_tmpdir/failed"
381 sleep 1
382 kill "$_bgpid" >/dev/null 2>&1 || :
383 read -r _result <"$_tmpdir/output" || :
384 _bad=
385 ! [ -e "$_tmpdir/failed" ] || _bad=1
386 rm -rf "$_tmpdir"
387 [ -z "$_bad" ] && [ "$_result" = "testing" ]
388 } >/dev/null 2>&1
390 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
391 test_nc_U "$var_nc_openbsd_bin" || {
392 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
393 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
394 uname_s="$(uname -s 2>/dev/null | tr A-Z a-z 2>/dev/null)" || :
395 case "$uname_s" in
396 *dragonfly*)
397 echo "ERROR: see the src/dragonfly/README file for a solution" >&2;;
398 *kfreebsd*|*linux*)
399 echo "ERROR: try installing the package named 'netcat-openbsd'" >&2;;
400 esac
401 exit 1
404 echo "*** Verifying selected POSIX sh is sane..."
405 shbin="$var_sh_bin"
406 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
407 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
408 exit 1
410 [ "$(check_sh_builtin command)" = "command" ] || {
411 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
412 exit 1
414 sh_not_builtin=
415 sh_extra_chroot_installs=
416 badsh=
417 for sbi in cd pwd read umask unset unalias; do
418 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
419 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
420 badsh=1
422 done
423 [ -z "$badsh" ] || exit 1
424 for sbi in '[' echo printf test; do
425 if ! extra="$(check_sh_builtin "$sbi")"; then
426 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
427 badsh=1
428 continue
430 if [ "$extra" != "$sbi" ]; then
431 case "$extra" in /*) :;; *)
432 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
433 badsh=1
434 continue
435 esac
436 withspc=
437 case "$extra" in *" "*) withspc=1; esac
438 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
439 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
440 badsh=1
441 continue
443 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
444 sh_not_builtin="$sh_not_builtin $sbi"
445 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
447 done
448 [ -z "$badsh" ] || exit 1
449 [ -z "$sh_extra_chroot_installs" ] || {
450 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
451 echo "WARNING: as a result it will run slower than necessary" >&2
452 echo "WARNING: consider building and switching to dash which can be found at:" >&2
453 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
454 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
455 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
456 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
459 echo "*** Verifying xargs is sane..."
460 _xargsr="$(</dev/null command xargs printf %s -r)" || :
461 xtest1="$(</dev/null command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
462 xtest2="$(printf '%s\n' one two | command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
463 [ -z "$xtest1" ] && [ "$xtest2" = "test one test two " ] || {
464 echo 'ERROR: xargs is unusable' >&2
465 echo 'ERROR: either `test -z "$(</dev/null xargs echo test 2>/dev/null)"`' >&2
466 echo 'ERROR: or `test -z "$(</dev/null xargs -r echo test 2>/dev/null)"`' >&2
467 echo 'ERROR: must be true, but neither is' >&2
468 exit 1
471 echo "*** Verifying selected perl is sane..."
472 perlbin="$var_perl_bin"
473 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
474 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
475 exit 1
478 echo "*** Verifying selected gzip is sane..."
479 gzipbin="$var_gzip_bin"
480 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
481 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
482 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
483 exit 1
486 echo "*** Verifying basedir, webroot, webreporoot and cgiroot paths..."
487 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
488 case "$cfg_basedir" in /*) :;; *)
489 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
490 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
491 exit 1
492 esac
493 case "$cfg_webroot" in /*) :;; *)
494 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
495 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
496 exit 1
497 esac
498 if [ -n "$cfg_webreporoot" ]; then
499 case "$cfg_webreporoot" in /*) :;; *)
500 echo "ERROR: invalid Girocco::Config::webreporoot setting" >&2
501 echo "ERROR: \"$cfg_webreporoot\" must be an absolute path (start with '/') or undef" >&2
502 exit 1
503 esac
505 case "$cfg_cgiroot" in /*) :;; *)
506 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
507 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
508 exit 1
509 esac
511 # return the input with trailing slashes stripped but return "/" for all "/"s
512 striptrsl() {
513 [ -n "$1" ] || return 0
514 _s="${1##*[!/]}"
515 [ "$_s" != "$1" ] || _s="${_s#?}"
516 printf "%s\n" "${1%$_s}"
519 # a combination of realpath + dirname where the realpath of the deepest existing
520 # directory is returned with the rest of the non-existing components appended
521 # and trailing slashes and multiple slashes are removed
522 realdir() {
523 _d="$(striptrsl "$1")"
524 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
525 echo "$_d"
526 return 0
528 _c=""
529 while ! [ -d "$_d" ]; do
530 _c="/$(basename "$_d")$_c"
531 _d="$(dirname "$_d")"
532 [ "$_d" != "/" ] || _c="${_c#/}"
533 done
534 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
537 # Use basedir, webroot and cgiroot for easier control of filesystem locations
538 # Wherever we are writing/copying/installing files we use these, but where we
539 # are editing, adding config settings or printing advice we always stick to the
540 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
541 # Only the file system directories that could be asynchronously accessed (by
542 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
543 # The chroot is handled specially and does not need one of these.
544 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
545 # case the prior contents of cgiroot and/or webroot are discarded.
546 rbasedir="$(realdir "$cfg_basedir")"
547 rwebroot="$(realdir "$cfg_webroot")"
548 rwebreporoot=
549 [ -z "$cfg_webreporoot" ] || {
550 # avoid resolving a pre-existing symlink from a previous install
551 rwebreporoot="$(realdir "${cfg_webreporoot%/}_NOSUCHDIR")"
552 rwebreporoot="${rwebreporoot%_NOSUCHDIR}"
554 rcgiroot="$(realdir "$cfg_cgiroot")"
555 case "$rbasedir" in "$rwebroot"/?*)
556 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
557 exit 1
558 esac
559 case "$rbasedir" in "$rcgiroot"/?*)
560 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
561 exit 1
562 esac
563 if [ "$rwebroot" = "$rcgiroot" ]; then
564 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
565 exit 1
567 case "$rcgiroot" in "$rwebroot"/?*)
568 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
569 exit 1
570 esac
571 case "$rwebroot" in "$rcgiroot"/?*)
572 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
573 exit 1
574 esac
575 if [ -n "$rwebreporoot" ]; then
576 if [ "$rwebreporoot" = "$rwebroot" ]; then
577 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::webreporoot settings; must not be the same" >&2
578 exit 1
580 case "$rwebreporoot" in "$rwebroot"/?*);;*)
581 echo "ERROR: invalid Girocco::Config::webreporoot setting; must be under webroot or undef" >&2
582 exit 1
583 esac
585 basedir="$rbasedir-new"
586 case "$rwebroot" in
587 "$rbasedir"/?*)
588 webroot="$basedir${rwebroot#$rbasedir}"
589 webrootsub=1
592 webroot="$rwebroot-new"
593 webrootsub=
595 esac
596 webreporoot=
597 [ -z "$rwebreporoot" ] || webreporoot="$webroot${rwebreporoot#$rwebroot}"
598 case "$rcgiroot" in
599 "$rbasedir"/?*)
600 cgiroot="$basedir${rcgiroot#$rbasedir}"
601 cgirootsub=1
604 cgiroot="$rcgiroot-new"
605 cgirootsub=
607 esac
609 echo "*** Setting up basedir..."
611 chown_make() {
612 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
613 find -H "$@" -user root -exec chown "$SUDO_USER:$(id -gn "$SUDO_USER")" '{}' + 2>/dev/null || :
614 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
615 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
619 "$MAKE" --no-print-directory --silent apache.conf
620 chown_make apache.conf
621 "$MAKE" --no-print-directory --silent -C src
622 chown_make src
623 rm -fr "$basedir"
624 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
625 # make the mtlinesfile with 1000 empty lines
626 yes '' | dd bs=1000 count=1 2>/dev/null >"$basedir/mtlinesfile"
627 chmod a+r "$basedir/mtlinesfile"
628 cp cgi/*.cgi "$basedir/cgi"
629 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
630 rm -f "$basedir/Girocco/Dumper.pm" # Dumper.pm is only for the install.sh process
631 find -H "$basedir" -type l -exec rm -f '{}' +
632 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
633 src/rangecgi src/readlink src/strftime src/throttle src/ulimit512 src/ltsha256 \
634 ezcert.git/CACreateCert cgi/authrequired.cgi cgi/snapshot.cgi \
635 "$basedir/bin"
636 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
637 if [ -n "$cfg_httpspushurl" ]; then
638 [ -z "$cfg_pretrustedroot" ] || rm -f "$basedir"/html/rootcert.html
639 else
640 rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
642 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
644 # Put the frozen Config in place
645 VARLIST="$(get_girocco_config_var_list varonly)" && export VARLIST
646 perl -I"$PWD" -MGirocco::Dumper=FreezeConfig -MScalar::Util=looks_like_number -e '
647 my $usemod = $ARGV[0];
648 my $f = sub { return () unless $_[0] =~ /^(var_[^=\s]+)=(.*)$/;
649 my ($k,$v) = ($1,$2);
650 $v =~ s/([\@\%])/\\$1/gos;
651 $v = "\"".$v."\"" unless substr($v,0,1) eq "\"" || looks_like_number($v);
652 my $e = eval $v;
653 [$k, $e] };
654 my @vars = map({&$f($_)} split(/\n+/, $ENV{VARLIST}));
655 my $s = sub { my $conf = shift;
656 foreach (@vars) {
657 my ($k,$v) = @{$_};
658 eval "\$${conf}::$k=\$v";
661 print FreezeConfig($usemod, undef, $s);
662 ' -- "$GIROCCO_CONF" >"$basedir/Girocco/Config.pm"
663 unset VARLIST
665 # Create symbolic links to selected binaries
666 ln -s "$cfg_git_bin" "$basedir/bin/git"
667 ln -s "$shbin" "$basedir/bin/sh"
668 ln -s "$perlbin" "$basedir/bin/perl"
669 ln -s "$gzipbin" "$basedir/bin/gzip"
670 [ -z "$var_openssl_bin" ] || ln -s "$var_openssl_bin" "$basedir/bin/openssl"
672 echo "*** Preprocessing scripts..."
673 SHBIN="$shbin" && export SHBIN
674 PERLBIN="$perlbin" && export PERLBIN
675 perl -I"$PWD" -M$GIROCCO_CONF -i -p \
676 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
677 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
678 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
679 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
680 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
681 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
682 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
683 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
684 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
685 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
686 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
687 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
688 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
689 -e 's/\@autogchack\@/"$Girocco::Config::autogchack"/g;' \
690 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
691 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
692 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
693 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
694 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
695 -e 's/\@fetch_stash_refs\@/"$Girocco::Config::fetch_stash_refs"/g;' \
696 -e 's/\@suppress_git_ssh_logging\@/"$Girocco::Config::suppress_git_ssh_logging"/g;' \
697 -e 's/\@max_file_size512\@/"$Girocco::Config::max_file_size512"/g;' \
698 -e 'close ARGV if eof;' \
699 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
700 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
701 "$basedir"/shlib.sh "$basedir"/hooks/* \
702 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
703 "$basedir"/toolbox/reports/*.sh \
704 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
705 "$basedir"/bin/create-* "$basedir"/bin/update-* \
706 "$basedir"/bin/*.cgi "$basedir"/screen/*
707 perl -I"$PWD" -M$GIROCCO_CONF -i -p \
708 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
709 "$basedir"/cgi/*.cgi "$basedir"/gitweb/*.perl \
710 "$basedir"/jobd/*.pl "$basedir"/taskd/*.pl
711 perl -i -p \
712 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
713 -e 'close ARGV if eof;' \
714 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
715 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
716 perl -i -p \
717 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
718 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
719 -e 'close ARGV if eof;' \
720 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
721 unset PERLBIN
722 unset SHBIN
724 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
725 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
727 if [ "${cfg_mirror_darcs:-0}" != "0" ]; then
728 echo "*** Setting up darcs-fast-export from girocco-darcs-fast-export.git..."
729 if ! [ -f girocco-darcs-fast-export.git/darcs-fast-export ] ||
730 ! [ -x girocco-darcs-fast-export.git/darcs-fast-export ]; then
731 echo "ERROR: girocco-darcs-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
732 exit 1
734 mkdir -p "$basedir"/bin
735 cp girocco-darcs-fast-export.git/darcs-fast-export "$basedir"/bin
738 if [ "${cfg_mirror_hg:-0}" != "0" ]; then
739 echo "*** Setting up hg-fast-export from girocco-hg-fast-export.git..."
740 if ! [ -f girocco-hg-fast-export.git/hg-fast-export.py ] || ! [ -f girocco-hg-fast-export.git/hg2git.py ]; then
741 echo "ERROR: girocco-hg-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
742 exit 1
744 mkdir -p "$basedir"/bin
745 cp girocco-hg-fast-export.git/hg-fast-export.py girocco-hg-fast-export.git/hg2git.py "$basedir"/bin
748 echo "*** Setting up markdown from markdown.git..."
749 if ! [ -f markdown.git/Markdown.pl ]; then
750 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
751 exit 1
753 mkdir -p "$basedir"/bin
754 (PERLBIN="$perlbin" && export PERLBIN &&
755 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
756 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
757 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
758 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
759 test $? -eq 0
761 # Some permission sanity on basedir/bin just in case
762 find -H "$basedir"/bin -type f -exec chmod go-w '{}' +
763 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
765 if [ -n "$cfg_mirror" ]; then
766 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
768 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.pl, or add this"
769 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
770 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.pl -q --all-once"
773 echo "*** Setting up repository root..."
774 [ -d "$cfg_reporoot" ] || {
775 mkdir -p "$cfg_reporoot"
776 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot" ||
777 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot"
779 [ -z "$cfg_owning_group" ] ||
780 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
781 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
782 mkdir -p "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty"
783 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" ||
784 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot/{_recyclebin,_global} properly"
785 if [ "$cfg_owning_group" ]; then
786 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
787 chgrp -R "$cfg_owning_group" "$cfg_reporoot/_global" || echo "WARNING: Cannot chgrp -R $cfg_owning_group $cfg_reporoot/_global"
789 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
790 chmod 00755 "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" || echo "WARNING: Cannot chmod $cfg_reporoot/_global properly"
793 if [ "${cfg_disable_jailsetup:-0}" = "0" ] && [ -n "$cfg_chrooted" ]; then
794 echo "*** Setting up chroot jail for pushing..."
795 if [ "$(id -u)" -eq 0 ]; then
796 # jailsetup may install things from $cfg_basedir/bin into the
797 # chroot so we do a mini-update of just that portion now
798 mkdir -p "$cfg_basedir"
799 rm -rf "$cfg_basedir/bin-new"
800 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
801 rm -rf "$cfg_basedir/bin-old"
802 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
803 rm -rf "$cfg_basedir/bin-old"
804 if [ -n "$sh_extra_chroot_installs" ]; then
805 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
806 export GIROCCO_CHROOT_EXTRA_INSTALLS
808 ./jailsetup.sh
809 unset GIROCCO_CHROOT_EXTRA_INSTALLS
810 else
811 echo "WARNING: Skipping jail setup, not root"
816 echo "*** Setting up jail configuration (project database)..."
817 [ "$(id -u)" -eq 0 ] || ./jailsetup.sh dbonly
818 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
819 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
820 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
821 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
822 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
823 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
824 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
825 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
826 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
829 echo "*** Setting up global hook scripts..."
830 # It is absolutely CRUCIAL that hook script replacements are done atomically!
831 # Otherwise an incoming push might slip in and fail to run the hook script!
832 # The underlying rename(2) function call provides this and mv will use it.
833 # First add hook scripts
834 hooks="pre-auto-gc pre-receive post-commit post-receive update"
835 for hook in $hooks; do
836 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
837 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
838 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
839 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
840 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
841 done
842 # Then remove any hook scripts that do not belong
843 for hook in "$cfg_reporoot/_global/hooks"/*; do
844 hook="${hook##*/}"
845 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
846 case " $hooks " in *" $hook "*);;*)
847 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
848 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
849 esac
850 done
853 echo "*** Setting up gitweb from git.git..."
854 if ! [ -f git.git/Makefile ]; then
855 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
856 exit 1
859 # We do not wholesale replace either webroot or cgiroot unless they are under
860 # basedir so if they exist and are not we make a copy to start working on them.
861 # We make a copy using -p which can result in some warnings so we suppress
862 # error output as it's of no consequence in this case.
863 rm -rf "$webroot" "$cgiroot"
864 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
865 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
866 mkdir -p "$webroot" "$cgiroot"
869 cd git.git &&
870 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
871 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
872 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
873 chown_make gitweb &&
874 PERLBIN="$perlbin" && export PERLBIN &&
875 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
876 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
877 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
878 chown_make "$cgiroot"/gitweb.cgi.$$ &&
879 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
880 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
882 test $? -eq 0
885 echo "*** Setting up git-browser from git-browser.git..."
886 if ! [ -f git-browser.git/git-browser.cgi ]; then
887 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
888 exit 1
890 mkdir -p "$webroot"/git-browser "$cgiroot"
892 cd git-browser.git &&
893 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
894 PERLBIN="$perlbin" && export PERLBIN && perl -p \
895 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
896 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
897 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
898 chown_make "$cgiroot"/git-browser.cgi.$$ &&
899 perl -p \
900 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
901 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
902 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
903 chown_make "$cgiroot"/git-diff.cgi.$$ &&
904 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
905 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
906 for h in *.html; do
907 [ "$h" != "index.html" ] || continue
908 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
909 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
910 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
911 >"$webroot/git-browser/$h.$$" &&
912 chmod a+r "$webroot/git-browser/$h.$$" &&
913 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
914 else
915 cp -p "$h" "$webroot/git-browser/"
917 done
918 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
919 cp -pR JSON "$cgiroot/"
921 test $? -eq 0
922 gitwebabs="$cfg_gitweburl"
923 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
924 gitwebabs="${gitwebabs#*://}"
925 case "$gitwebabs" in
926 *"/"*) gitwebabs="/${gitwebabs#*/}";;
927 *) gitwebabs="";;
928 esac
929 esac
930 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
931 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
932 gitbin: $cfg_git_bin
933 gitweb: $gitwebabs
934 warehouse: $cfg_reporoot
935 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
937 chown_make "$basedir/gitweb"/git-browser.conf.$$
938 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
939 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
940 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
941 cfg_gitweb_url="$cfg_gitweburl/"
942 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
943 cfg_home_url="$cfg_gitweburl/%n"
944 cfg_home_text="summary"
945 cfg_bycommit_title="$esctitle - %n/graphiclog1"
946 cfg_bydate_title="$esctitle - %n/graphiclog2"
948 chown_make "$webroot"/git-browser/GitConfig.js.$$
949 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
952 echo "*** Setting up our part of the website..."
953 mkdir -p "$webroot" "$cgiroot"
954 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
955 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
956 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
957 cp "$basedir/cgi"/*.cgi "$cgiroot"
958 rm -rf "$basedir/cgi"
959 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
960 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
961 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
962 else
963 cp gitweb/indextext.html "$basedir/gitweb"
965 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
966 cp mootools.js "$webroot"
967 cp htaccess "$webroot/.htaccess"
968 cp cgi/htaccess "$cgiroot/.htaccess"
969 cp git-favicon.ico "$webroot/favicon.ico"
970 cp robots.txt "$webroot"
971 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
974 if [ -n "$cfg_httpspushurl" ]; then
975 echo "*** Setting up SSL certificates..."
976 openssl="${var_openssl_bin:-openssl}"
977 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
978 bits=2048
979 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
980 bits="$cfg_rsakeylength"
982 mkdir -p "$cfg_certsdir"
983 [ -d "$cfg_certsdir" ]
984 wwwcertcn=
985 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
986 wwwcertcn="$(
987 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
988 sed -e 's,[^/]*,,'
991 wwwcertdns=
992 if [ -n "$cfg_wwwcertaltnames" ]; then
993 for dnsopt in $cfg_wwwcertaltnames; do
994 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
995 done
997 wwwcertdnsfile=
998 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
999 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1001 needroot=
1002 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1003 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1004 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1005 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1006 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1007 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1008 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1009 umask 0077
1010 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1011 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1012 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1013 umask 0022
1014 echo "Created new root key"
1016 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1017 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1018 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1019 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem"
1020 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1021 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1022 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1023 echo "Created new root certificate"
1025 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1026 umask 0077
1027 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1028 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1029 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1030 umask 0022
1031 echo "Created new www key"
1033 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1034 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1035 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1036 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1037 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1038 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1039 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1040 echo "Created www certificate"
1042 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1043 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1044 echo "Created www certificate chain file"
1046 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1047 umask 0037
1048 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1049 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1050 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1051 umask 0022
1052 echo "Created new client key"
1054 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1055 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1056 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1057 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1058 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1059 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1060 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1061 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1062 echo "Created client certificate"
1064 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1065 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1066 echo "Created client certificate suffix file"
1068 if [ -z "$cfg_pretrustedroot" ]; then
1069 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1070 else
1071 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1073 if [ -n "$cfg_mob" ]; then
1074 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1075 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1076 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1077 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1078 echo "Created new mob user key"
1080 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1081 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1082 createcert --client --key "$cfg_clientkey" \
1083 --cert "$cfg_clientcert" \
1084 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1085 echo "Created mob user client certificate"
1087 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1088 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1089 else
1090 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1092 else
1093 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1094 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1098 echo "*** Processing website html templates..."
1099 rm -f "$cgiroot/html.cgi"
1100 rm -rf "$cgiroot/html"
1101 mkdir -p "$cgiroot/html"
1102 for tf in "$basedir/html"/*.html; do
1103 tfb="${tf##*/}"
1104 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1105 rm -f "$tf"
1106 done
1108 echo "*** Formatting markdown documentation..."
1109 mkdir -p "$cgiroot/html/gfm"
1110 for d in basics.md syntax.md; do
1112 cat <<-HEADER
1113 <!DOCTYPE html>
1114 <html xmlns="http://www.w3.org/1999/xhtml">
1115 <head>
1116 <meta charset="utf-8" />
1117 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1118 <title>$d</title>
1119 </head>
1120 <body><pre>
1121 HEADER
1122 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1123 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1124 -e 's/ by adding `.md` to the URL//' \
1125 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1126 cat <<-FOOTER
1127 </pre></body>
1128 </html>
1129 FOOTER
1130 } >"$cgiroot/html/gfm/$d.html"
1132 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1133 gwfpath="$cfg_gitwebfiles"
1134 case "$gwfpath" in *"//"*)
1135 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1136 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1137 esac
1138 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1139 gwfpath="${gwfpath%/}"
1140 cat <<-HEADER
1141 <!DOCTYPE html>
1142 <html xmlns="http://www.w3.org/1999/xhtml">
1143 <head>
1144 <meta charset="utf-8" />
1145 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1146 <title>$title</title>
1147 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1148 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1149 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1150 </head>
1151 <body style="text-align:center">
1152 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1153 HEADER
1154 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1155 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1156 -e 's/ by adding `.md` to the URL//' |
1157 "$perlbin" "markdown.git/Markdown.pl"
1158 cat <<-FOOTER
1159 </div>
1160 </body>
1161 </html>
1162 FOOTER
1163 } >"$cgiroot/html/gfm/${d%.md}.html"
1164 done
1167 echo "*** Finalizing permissions and moving into place..."
1168 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1169 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1171 # This should always be the very last thing install.sh does
1172 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1173 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1174 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1175 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1176 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1177 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1178 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1179 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1180 touch "$cfg_chroot/etc/taskd.restart"
1181 chown_make "$cfg_chroot/etc/taskd.restart"
1182 trap ':' PIPE
1183 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1184 trap - PIPE