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