summaryrefslogtreecommitdiff
path: root/git-daemon
diff options
context:
space:
mode:
authorIan Jackson <ian@chiark.greenend.org.uk>2010-05-22 19:13:43 +0100
committerIan Jackson <ian@chiark.greenend.org.uk>2010-05-22 19:13:43 +0100
commit70b9d2e0dbecb8fe1e2045a1752465cd35885bb0 (patch)
treed975be3e56a711a6cac087abe6939af9a4226d2c /git-daemon
parentd36c5f7baf4f11c7d6765afac2f5fb9449b0e0a7 (diff)
downloaduserv-utils-70b9d2e0dbecb8fe1e2045a1752465cd35885bb0.tar.gz
Changes to make it appear to work on chiark
Diffstat (limited to 'git-daemon')
-rw-r--r--git-daemon/Makefile14
-rw-r--r--git-daemon/README30
-rw-r--r--git-daemon/chiark-urlmap5
-rwxr-xr-xgit-daemon/git-daemon.in33
-rwxr-xr-xgit-daemon/git-service.in23
-rw-r--r--git-daemon/git-urlmap35
-rw-r--r--git-daemon/inetd.conf.in2
-rw-r--r--git-daemon/read-urlmap60
8 files changed, 124 insertions, 78 deletions
diff --git a/git-daemon/Makefile b/git-daemon/Makefile
index 2d24274..1a18f66 100644
--- a/git-daemon/Makefile
+++ b/git-daemon/Makefile
@@ -9,14 +9,14 @@ include ../settings.make
TARGETS= git-upload-pack inetd.conf git-daemon git-service
-SUBSTVARS= libuserv etcuserv
+SUBSTVARS= libuserv etcuserv varlog
all: $(TARGETS)
-sedscript: Makefile
+sedscript: Makefile read-urlmap
echo >$@.new '$(foreach f, $(SUBSTVARS), s,@$f@,$($f),g; )'
echo >>$@.new '/@@READ_URLMAP@@/c\'
- perl >>$@.new -pe 's/$$/\\/' <read-urlmap
+ perl >>$@.new -pe 's/\\/\\\\/g; s/$$/\\/' <read-urlmap
mv -f $@.new $@
%: %.in sedscript
@@ -28,8 +28,12 @@ sedscript: Makefile
install: all
mkdir -p $(libuserv) $(etcuserv) $(services)
cp git-daemon git-service $(libuserv)
- cp git-upload-pack $(services)
- cp git-urlmap $(etcuserv)
+ cp git-upload-pack $(services)/git-upload-pack:new
+ cp git-urlmap $(etcuserv)/git-urlmap:new
+ set -e; cd $(services); test -f git-upload-pack \
+ || mv git-upload-pack:new git-upload-pack
+ set -e; cd $(etcuserv); test -f git-urlmap \
+ || mv git-urlmap:new git-urlmap
clean:
rm -f $(TARGETS)
diff --git a/git-daemon/README b/git-daemon/README
index 116a6b3..76d9946 100644
--- a/git-daemon/README
+++ b/git-daemon/README
@@ -59,35 +59,7 @@ service, which is simply the git program with the same name.
Configuration:
--------------
-See "chiark-urlmap" for an example.
-
-Each line is one of:
-
- single-user <vhost>[/<subpath>] <user> [<directory>]
- matching requests will be handled by <user>
- and unless overridden by <user> handled by
- serving subdirectories of <directory>
-
- multi-user <vhost>[/<subpath>] <directory>
- matching requests are only those those next
- path element starts with ~<user>. The
- request will be handled by <user> and unless
- overridden by <user> will be handled by
- serving subdirectories of <directory>
- (<directory> must be a relative path)
-
- repo-regexp <regexp>
- For per-user service. Subrepos must match this
- regexp, which must contain a single matching
- group which is the filesystem pathname inside
- the <directory>. The default is (Tcl syntax):
- repo-regexp {^(\w[-+._0-9A-Za-z]*)$}
-
- [no-]require-git-daemon-export-ok
- For per-user service. Default is no-.
-
-Last match, or last setting, wins.
-<subpath>s may start with ~
+See "git-urlmap" for syntax description and an example.
----------------------------------------------
diff --git a/git-daemon/chiark-urlmap b/git-daemon/chiark-urlmap
deleted file mode 100644
index 09e2a11..0000000
--- a/git-daemon/chiark-urlmap
+++ /dev/null
@@ -1,5 +0,0 @@
-
-single-user dotat.at fanf dotat-git
-multi-user git.chiark.greenend.org.uk public-git
-multi-user cabal.greenend.org.uk cabal-git
-single-user git.chiark.greenend.org.uk webmaster /u2/git-repos
diff --git a/git-daemon/git-daemon.in b/git-daemon/git-daemon.in
index 8fe8ca1..1b1b540 100755
--- a/git-daemon/git-daemon.in
+++ b/git-daemon/git-daemon.in
@@ -13,6 +13,13 @@ use POSIX;
use Socket;
use Sys::Syslog;
+BEGIN {
+ if ($ARGV[0] =~ s/^-L//) {
+ my $logfile= shift @ARGV;
+ open STDERR, ">> $logfile" or die $!;
+ }
+}
+
sub ntoa {
my $sockaddr = shift;
return ('(local)') unless defined $sockaddr;
@@ -24,6 +31,9 @@ our ($client,$client_addr,$client_port) = ntoa getpeername STDIN;
our ($server,$server_addr,$server_port) = ntoa getsockname STDIN;
our ($service,$specpath,$spechost);
+printf STDERR "%s [$$] %s %s\n",
+ strftime("%Y-%m-%d %H:%M:%S %Z", localtime), $server, $client;
+
openlog 'userv-git-daemon', 'pid', 'daemon';
sub fail { syslog 'err', "$client @_"; exit }
@@ -52,20 +62,25 @@ unless (($service,$specpath,$spechost) = $line =~
@@READ_URLMAP@@
-fail "No mapping for $uri" unless defined $serve_user;
-syslog 'notice', "$client $service $serve_user $uri";
+fail "No global mapping for $uri" unless defined $serve_user;
-my ($hn,$ha,$at,$naddrs,@addrs) = gethostbyname $host;
-die "hostname/address mismatch ($spechost $server_addr)" unless grep {
+my ($hn,$ha,$at,$naddrs,@addrs) = gethostbyname $spechost;
+fail "hostname/address mismatch ($spechost $server_addr)" unless grep {
$server_addr eq inet_ntoa $_
} @addrs;
-my @opts = map "-D$_=${$::{$_}}",
- qw(service path host
- client client_addr client_port
- server server_addr server_port);
+our @opts;
+
+push @opts, "-D$_=${$::{$_}}"
+ for qw(service specpath spechost
+ client client_addr client_port
+ server server_addr server_port);
+
+fail "no user $serve_user" unless getpwnam($serve_user);
+
+syslog 'notice', "$client $service $uri $serve_user";
-my @cmd = ('userv', '-t300', @opts, $user, $service);
+my @cmd = ('userv', '-t300', @opts, $serve_user, $service);
no warnings; # suppress errors to stderr
exec @cmd or fail "exec userv: $!";
diff --git a/git-daemon/git-service.in b/git-daemon/git-service.in
index 43ff340..75e64d5 100755
--- a/git-daemon/git-service.in
+++ b/git-daemon/git-service.in
@@ -9,30 +9,33 @@
use strict;
use warnings;
+use POSIX;
use Sys::Syslog;
our ($client,$service,$specpath,$spechost,@opts);
${$::{$_}} = $ENV{"USERV_U_$_"}
- for qw(service path host)
+ for qw(service specpath spechost client);
-openlog "userv-$service", 'pid', 'daemon';
+openlog "userv-$service:$ENV{USER}", 'pid', 'daemon';
sub fail { syslog 'err', "$client @_"; exit }
@@READ_URLMAP@@
-fail "No mapping for $uri ($ENV{USERV_USER})" unless defined $serve_user;
+fail "No user $ENV{USER} mapping for $uri" unless defined $serve_user;
-$1 = undef;
-fail "Bad subdirectory $serve_dir" unless $serve_dir =~ m/$repo_regexp/o;
-our $dir = $1;
+$serve_dir = "$ENV{HOME}/$serve_dir" unless $serve_dir =~ m|^/|;
-$dir = "$ENV{HOME}/$dir" unless $dir =~ m|^/|;
+fail "Bad subdirectory $serve_repo" unless $serve_repo =~ m/$repo_regexp/o;
+fail "bad config - repo-regexp does not capture" unless defined $1;
+my $sani_repo= $1;
-$dir = "$dir/$repo" if defined $repo;
-$path = $check_export ? "$dir/git-daemon-export-ok" : $dir;
+my $dir = $serve_dir.(length $sani_repo ? "/$sani_repo" : '');
+
+my $path = $check_export ? "$dir/git-daemon-export-ok" : $dir;
fail "$! $path" unless -e $path;
-syslog 'notice', "$client $dir";
+
+syslog 'notice', "$client $uri $dir";
@opts = qw( --strict )
if @opts == 0 and $service eq 'git-upload-pack';
diff --git a/git-daemon/git-urlmap b/git-daemon/git-urlmap
new file mode 100644
index 0000000..10aaed2
--- /dev/null
+++ b/git-daemon/git-urlmap
@@ -0,0 +1,35 @@
+# Each line is one of:
+#
+# single-user <vhost>[/<vsubpath>] <user> [<directory>]
+# matching requests will be handled by <user>
+# and unless overridden by <user> handled by
+# serving subdirectories of <directory>
+#
+# multi-user <vhost>[/<vsubpath>] <directory>
+# matching requests are only those those next
+# path element starts with ~<user>. The
+# request will be handled by <user> and unless
+# overridden by <user> will be handled by
+# serving subdirectories of <directory>
+# (<directory> must be a relative path)
+#
+# repo-regexp <regexp>
+# For per-user service. Subrepos must match this
+# regexp, which must contain a single matching
+# group which is the filesystem pathname inside
+# the <directory>. The default is (Tcl syntax):
+# repo-regexp {^(\w[-+._0-9A-Za-z]*)$}
+#
+# [no-]require-git-daemon-export-ok
+# For per-user service. Default is no-.
+#
+# Last match, or last setting, wins.
+# <vsubpath>s may start with ~
+
+# here is an example, taken from chiark:
+#
+# single-user dotat.at fanf dotat-git
+# single-user git.chiark.greenend.org.uk webmaster /u2/git-repos
+#
+# multi-user cabal.greenend.org.uk cabal-git
+# multi-user git.chiark.greenend.org.uk public-git
diff --git a/git-daemon/inetd.conf.in b/git-daemon/inetd.conf.in
index a40382d..11bf717 100644
--- a/git-daemon/inetd.conf.in
+++ b/git-daemon/inetd.conf.in
@@ -1,2 +1,2 @@
# Example inetd.conf line for the userv git daemon.
-git stream tcp nowait git @libuserv@/git-daemon git-daemon @etcuserv@/git-urlmap
+git stream tcp nowait git /usr/sbin/tcpd @libuserv@/git-daemon -L@varlog@/git/userv-git-daemon.log @etcuserv@/git-urlmap
diff --git a/git-daemon/read-urlmap b/git-daemon/read-urlmap
index 6ae3237..0fd760f 100644
--- a/git-daemon/read-urlmap
+++ b/git-daemon/read-urlmap
@@ -18,51 +18,73 @@
# $repo_regexp
# $require_exportok
-die "no config" unless @ARGV;
-
sub remain_path ($) {
# return value matches {( / [^/]+ )+}x
- my ($p) = @_;
- return "/$specpath" if !defined $p;
- return "" if $p eq $specpath;
- return substr($specpath,length($p))
- if substr($specpath,0,length($p)+1) eq "$p/";
+ my ($vsubpath) = @_;
+ syslog 'debug', sprintf "DEBUG remain_path %s $specpath",
+ (defined $vsubpath ? $vsubpath : '<undef>');
+ return "/$specpath" if !defined $vsubpath;
+ return "" if $vsubpath eq $specpath;
+ return substr($specpath,length($vsubpath))
+ if substr($specpath,0,length($vsubpath)+1) eq "$vsubpath/";
return undef;
}
-die unless length $specpath;
+fail "no config ??" unless @ARGV;
+fail "no specpath ??" unless length $specpath;
our $uri = "git://$spechost/$specpath";
-our $repo_regexp= '^/*(\\w[-+._0-9A-Za-z]*)$';
+our $repo_regexp= '^/*(\\w[-+._0-9A-Za-z]*)$'; # stupid emacs ';
our $check_export= 0;
+our ($serve_user, $serve_dir, $serve_repo);
+
+sub fexists ($) {
+ my ($f) = @_;
+ if (stat $f) {
+ -f _ or fail "bad config $_ - not a file";
+ return 1;
+ } else {
+ $!==&ENOENT or fail "bad config $_ - could not stat: $!";
+ return 0;
+ }
+}
+
+@ARGV = grep { fexists($_) } @ARGV;
+
while (<>) {
+
s/^\s*//;
s/\s+$//;
next unless m/\S/;
next if m/^\#/;
if (m{^ single-user \s+ (\S+?) (/\S*)? \s+ (\S+) (?: \s+ (\S+) )? $ }x) {
- my ($h,$p,$u,$d) = ($1,$2,$3,$4);
- next unless $h ne $host;
- $serve_repo= remain_path($p);
+ my ($h,$v,$u,$d) = ($1,$2,$3,$4);
+ next unless $h eq $spechost;
+ $serve_repo= remain_path($v);
next unless defined $serve_repo;
$serve_user= $u;
$serve_dir= $d;
+ syslog 'debug', "DEBUG $ARGV:$. match".
+ " $serve_user $serve_dir $serve_repo";
} elsif (m{^ multi-user \s+ (\S+?) (/\S*)? \s+ (\S+) $ }x) {
- my ($h,$p,$d) = ($1,$2,$3);
- next unless $1 ne $host;
- $serve_repo= remain_path($p);
- next unless defined $serv_repo;
- next unless $serve_repo =~ s{ ^/\~( [a-z][-+_0-9a-z] )/$ }{ / }xi;
- $serve_user= $u;
+ my ($h,$v,$d) = ($1,$2,$3);
+ next unless $1 eq $spechost;
+ $serve_repo= remain_path($v);
+ next unless defined $serve_repo;
+ syslog 'debug', "DEBUG $ARGV:$. perhaps $serve_repo";
+ next unless $serve_repo =~ s{ ^/\~( [a-z][-+_0-9a-z]* )/ }{/}xi;
+ $serve_user= $1;
$serve_dir= $d;
+ syslog 'debug', "DEBUG $ARGV:$. match".
+ " $serve_user $serve_dir $serve_repo";
} elsif (m{^ repo-regexp \s+ (\S.*) $ }x) {
$repo_regexp= $1;
} elsif (m{^ (no-)?require-git-daemon-export-ok $ }x) {
$check_export= !defined $1;
} else {
- die "bad config";
+ fail "config syntax error at $ARGV:$.";
}
}