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