'
our ($distro,$pkg, $d);
our ($dgitlive,$repos,$suites,$diverts,$policyhook,$repo);
sub checkdivert ($) {
my ($df) = @_;
if (!open DIV, '<', $df) {
$!==ENOENT or die $!;
return undef;
} else {
while () {
s/^\s+//; s/\s+$//;
next unless m/\S/;
next if m/^\#/;
my $divert;
if (s/\s+(\S+)$//) { $divert=$1; }
s/[^-+._0-9a-zA-Z*]/\\$&/g;
s/\*/.*/g;
printf DEBUG 'DISPATCH DIVERT ^%s$ %s'."\n",
$_, ($divert // '(undef)');
if ($pkg =~ m/^$_$/) { return $divert; }
}
DIV->error and die $!;
close DIV;
return undef;
}
}
sub finish () {
close STDOUT or die $!;
exit 0;
}
sub prl ($) {
print @_, "\n" or die $!;
}
sub selectpackage ($$;$) {
my $divertfn;
($distro,$pkg, $divertfn) = @_; # $distro,$pkg must have sane syntax
$d = "$dispatchdir/distro=$distro";
if (!stat $d) {
die $! unless $!==ENOENT;
die "unknown distro ($distro)\n";
}
$dgitlive= "$d/dgit-live";
$repos= "$d/repos";
$suites= "$d/suites";
$policyhook= "$d/policy-hook";
$authrune =~ s/\@/$d/g;
my $divert = checkdivert("$d/diverts");
if (defined $divert) {
$divertfn //= sub {
die "diverted to $divert incompletely or too late!\n";
};
$divertfn->($divert);
die;
}
$repo = "$repos/$pkg.git";
print DEBUG "DISPATCH DISTRO $distro PKG $pkg\n";
}
sub hasrepo () {
if (stat $repo) {
-d _ or die;
return 1;
} else {
$!==ENOENT or die $!;
return 0;
}
}
sub serve_up ($) {
my ($repo) = @_;
exec qw(git upload-pack --strict --timeout=1000), $repo;
die "exec git: $!";
}
sub dispatch () {
local ($_) = $ENV{'SSH_ORIGINAL_COMMAND'} // '';
if (m#^: dgit ($lre) git-check ($lre) ;#) {
selectpackage $1,$2, sub { prl "divert @_"; finish; };
prl hasrepo;
finish;
} elsif (
m#^${qre}git-([-a-z]+) ${qre}/dgit/($lre)/repos/($lre)\.git${qre}$#
) {
my $cmd=$1;
selectpackage $2,$3;
if ($cmd eq 'receive-pack') {
$ENV{'PERLLIB'} //= '';
$ENV{'PERLLIB'} =~ s#^(?=.)#:#;
$ENV{'PERLLIB'} =~ s#^# $ENV{DGIT_TEST_INTREE} // $dgitlive #e;
my $s = "$dgitlive/infra/dgit-repos-server";
$s = "dgit-repos-server" if !stat_exists $s;
exec $s, $distro, $d, $authrune, qw(--ssh);
die "exec $s: $!";
} elsif ($cmd eq 'upload-pack') {
$repo='$repos/_empty' unless hasrepo;
serve_up $repo;
} else {
die "unsupported git operation $cmd ($_)";
}
} elsif (
m#^${qre}git-upload-pack ${qre}/dgit/($lre)/(?:repos/)?_dgit-repos-server\.git${qre}$#
) {
my $distro= $1;
# if running installed packages, source code should come
# some other way
serve_up("$dispatchdir/distro=$1/dgit-live/.git");
} elsif (m#^${qre}git-upload-pack\s#) {
die "unknown repo to serve ($_). use dgit, or for server source ".
"git clone here:/dgit/DISTRO/repos/_dgit-repos-server.git";
} else {
die "unsupported operation ($_)";
}
}
dispatch;