All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Johan Sørensen" <johan@johansorensen.com>
To: git@vger.kernel.org
Cc: "Johan Sørensen" <johan@johansorensen.com>
Subject: [PATCH] Introduce a filter-path argument to git-daemon, for doing custom path transformations
Date: Thu, 12 Mar 2009 16:48:34 +0100	[thread overview]
Message-ID: <1236872914-43327-1-git-send-email-johan@johansorensen.com> (raw)
In-Reply-To: <alpine.DEB.1.00.0903121218000.10279@pacific.mpi-cbg.de>

The parameter for filter-path is an executable that will receive the service
name, the client hostname and path to the repos the client requests as as
arguments. It is then the responsibility of the script to return a zero
terminated string on its stdout with the real path of the target repository.

Signed-off-by: Johan Sørensen <johan@johansorensen.com>
---
 Documentation/git-daemon.txt |   15 +++++++++++
 daemon.c                     |   54 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt
index 36f00ae..bf8d31f 100644
--- a/Documentation/git-daemon.txt
+++ b/Documentation/git-daemon.txt
@@ -13,6 +13,7 @@ SYNOPSIS
 	     [--strict-paths] [--base-path=path] [--base-path-relaxed]
 	     [--user-path | --user-path=path]
 	     [--interpolated-path=pathtemplate]
+	     [--path-filter=executable]
 	     [--reuseaddr] [--detach] [--pid-file=file]
 	     [--enable=service] [--disable=service]
 	     [--allow-override=service] [--forbid-override=service]
@@ -71,6 +72,20 @@ OPTIONS
 	After interpolation, the path is validated against the directory
 	whitelist.
 
+--path-filter=executable::
+	To support a more flexible directory layout a path filter script
+	can be used. The executable will receive the service name (upload-pack,
+	upload-archive or receive-pack), the client hostname and the request git
+	directory as arguments. The executable must return a zero-terminated
+	string on stdout which is the real path 'git-daemon' should serve. This
+	is useful when --interpolated-path doesn't buy you enough flexibility.
+	You could for instance keep support for old clone urls if you rename your
+	repository, or fetch a custom url-mapping from a third-party repo manager
+	application, or	map deeply nested repository directories to a more
+	sensible layout for the outside world.
+	Please be aware that the executable spawned will have the same privileges
+	as the user you are running the git-daemon under.
+
 --export-all::
 	Allow pulling from all directories that look like GIT repositories
 	(have the 'objects' and 'refs' subdirectories), even if they
diff --git a/daemon.c b/daemon.c
index d93cf96..e865e78 100644
--- a/daemon.c
+++ b/daemon.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "pkt-line.h"
 #include "exec_cmd.h"
+#include "run-command.h"
 
 #include <syslog.h>
 
@@ -22,6 +23,7 @@ static const char daemon_usage[] =
 "           [--strict-paths] [--base-path=path] [--base-path-relaxed]\n"
 "           [--user-path | --user-path=path]\n"
 "           [--interpolated-path=path]\n"
+"           [--path-filter=path]\n"
 "           [--reuseaddr] [--detach] [--pid-file=file]\n"
 "           [--[enable|disable|allow-override|forbid-override]=service]\n"
 "           [--inetd | [--listen=host_or_ipaddr] [--port=n]\n"
@@ -58,6 +60,11 @@ static char *canon_hostname;
 static char *ip_address;
 static char *tcp_port;
 
+/* if defined, the script will be executed with the service name, hostname,
+ * and requested path on stdin and _must_ return with a successful exitcode
+ * and the new path on stdout */
+static char *path_filter_script;
+
 static void logreport(int priority, const char *err, va_list params)
 {
 	if (log_syslog) {
@@ -287,6 +294,42 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
 	return 0;
 }
 
+static char *run_path_filter_script(struct daemon_service *s, char *host,
+			    char *dir) {
+	struct strbuf result_buf = STRBUF_INIT;
+	struct child_process filter_cmd;
+	const char *args[] = { path_filter_script, s->name, host, dir, NULL };
+
+	loginfo("Executing path filter script: '%s %s %s %s'",
+					path_filter_script, s->name, host, dir);
+	memset(&filter_cmd, 0, sizeof(filter_cmd));
+	filter_cmd.argv = args;
+	filter_cmd.out = -1;
+
+	if (start_command(&filter_cmd)) {
+		logerror("path filter: unable to fork path_filter_script");
+		return dir;
+	}
+
+	if (strbuf_read(&result_buf, filter_cmd.out, PATH_MAX) < 0) {
+		strbuf_release(&result_buf);
+		close(filter_cmd.out);
+		logerror("path filter: script read returned %s", strerror(errno));
+		return dir;
+	}
+
+	close(filter_cmd.out);
+	if (finish_command(&filter_cmd)) {
+		logerror("path filter script died with strange error");
+		return dir;
+	}
+
+	if (result_buf.len > 0)
+		dir = strbuf_detach(&result_buf, NULL);
+
+	return dir;
+}
+
 static int run_service(char *dir, struct daemon_service *service)
 {
 	const char *path;
@@ -557,7 +600,12 @@ static int execute(struct sockaddr *addr)
 			 * Note: The directory here is probably context sensitive,
 			 * and might depend on the actual service being performed.
 			 */
-			return run_service(line + namelen + 5, s);
+			if (path_filter_script) {
+				return run_service(run_path_filter_script(s, hostname,
+				                   line + namelen + 5), s);
+			} else {
+				return run_service(line + namelen + 5, s);
+			}
 		}
 	}
 
@@ -1018,6 +1066,10 @@ int main(int argc, char **argv)
 			pid_file = arg + 11;
 			continue;
 		}
+		if (!prefixcmp(arg, "--path-filter=")) {
+			path_filter_script = arg + 14;
+			continue;
+		}
 		if (!strcmp(arg, "--detach")) {
 			detach = 1;
 			log_syslog = 1;
-- 
1.6.1

  reply	other threads:[~2009-03-12 15:50 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-11 15:17 [PATCH] Introduce a filter-path argument to git-daemon, for doing custom path transformations Johan Sørensen
2009-03-11 15:58 ` Johannes Sixt
2009-03-12 10:13   ` Johan Sørensen
2009-03-12 11:29     ` Johannes Schindelin
2009-03-12 15:48       ` Johan Sørensen [this message]
2009-03-12 16:50         ` Johannes Schindelin
2009-03-12 19:06       ` Johan Sørensen
2009-03-14  6:58         ` Junio C Hamano
2009-03-14 14:39           ` Johan Sørensen
2009-03-14 18:23             ` Junio C Hamano
2009-03-19  0:15               ` Johannes Schindelin
2009-03-19 13:02                 ` Johan Sørensen
2009-03-20 22:27                   ` Johannes Schindelin
2009-03-12 10:26   ` Johan Sørensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1236872914-43327-1-git-send-email-johan@johansorensen.com \
    --to=johan@johansorensen.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.