chiark / gitweb /
Changes to make it appear to work on chiark
authorIan Jackson <ian@chiark.greenend.org.uk>
Sat, 22 May 2010 18:13:43 +0000 (19:13 +0100)
committerIan Jackson <ian@chiark.greenend.org.uk>
Sat, 22 May 2010 18:13:43 +0000 (19:13 +0100)
git-daemon/Makefile
git-daemon/README
git-daemon/chiark-urlmap [deleted file]
git-daemon/git-daemon.in
git-daemon/git-service.in
git-daemon/git-urlmap [new file with mode: 0644]
git-daemon/inetd.conf.in
git-daemon/read-urlmap
settings.make

index 2d24274af9ae26b2346b7fbffe1b18281938b1b8..1a18f66dbafa9faceba604a2b646df0f4c9622b8 100644 (file)
@@ -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)
index 116a6b35cec0d090efd1ae4dd2e4a765db6443a3..76d9946e38d47757ae62472819f1f400ef9a7d85 100644 (file)
@@ -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 (file)
index 09e2a11..0000000
+++ /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
index 8fe8ca116ab17762260c521a7adf9a611854bf0b..1b1b5402afa6656c2baa226d3638f9193f278ecb 100755 (executable)
@@ -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: $!";
 
index 43ff340a70f58335f17ab65c9e48dd8c7d480d49..75e64d57a2ed142cf670e67277cf0fd2d40c210f 100755 (executable)
@@ -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 (file)
index 0000000..10aaed2
--- /dev/null
@@ -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
index a40382d4bcfa2cd1af952dc384bb48b7f23153a7..11bf71759113bdf9e57f480750e4f4cb03d88cd8 100644 (file)
@@ -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
index 6ae3237bdbb957b012e8e9a2172d999665c0054f..0fd760f8c2c95b91756507c5ad528351ea2bf1b7 100644 (file)
 #     $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:$.";
     }
 }
 
index bd9313c6d56526c282b77589c08b6d15bd9ecbcf..c74afc2fe6c604ed2f03b2d4ef4a22be40ec0b2b 100644 (file)
@@ -30,6 +30,7 @@ docdir=               $(sharedir)/doc
 
 libuserv=      $(libdir)/userv
 shareuserv=    $(sharedir)/userv
+varlog=                $(vardir)/log
 varlib=                $(vardir)/lib
 varlibuserv=   $(varlib)/userv