git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 3/4] Add init-serve, the remote side of "git init --remote=host:path"
Date: Sat, 28 Feb 2009 16:03:41 -0800	[thread overview]
Message-ID: <1235865822-14625-3-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1235865822-14625-2-git-send-email-gitster@pobox.com>

This still has a few NEEDSWORK, but should be good enough to start
developing and testing the requesting side of the protocol pair.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Makefile             |    1 +
 builtin-init-serve.c |  139 ++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin.h            |    1 +
 git.c                |    1 +
 4 files changed, 142 insertions(+), 0 deletions(-)
 create mode 100644 builtin-init-serve.c

diff --git a/Makefile b/Makefile
index 0675c43..c0d0cfd 100644
--- a/Makefile
+++ b/Makefile
@@ -544,6 +544,7 @@ BUILTIN_OBJS += builtin-gc.o
 BUILTIN_OBJS += builtin-grep.o
 BUILTIN_OBJS += builtin-help.o
 BUILTIN_OBJS += builtin-init-db.o
+BUILTIN_OBJS += builtin-init-serve.o
 BUILTIN_OBJS += builtin-log.o
 BUILTIN_OBJS += builtin-ls-files.o
 BUILTIN_OBJS += builtin-ls-remote.o
diff --git a/builtin-init-serve.c b/builtin-init-serve.c
new file mode 100644
index 0000000..2a06631
--- /dev/null
+++ b/builtin-init-serve.c
@@ -0,0 +1,139 @@
+#include "cache.h"
+#include "builtin.h"
+#include "pkt-line.h"
+#include "run-command.h"
+#include "strbuf.h"
+
+/*
+ * Notice any command line argument that we may not want to invoke
+ * "git init" with when we are doing this remotely, and reject the
+ * request.
+ */
+static int forbidden_arg(const char *arg)
+{
+	if (!prefixcmp(arg, "--shared=") ||
+	    !strcmp(arg, "--shared") ||
+	    !strcmp(arg, "--bare"))
+		return 0;
+	return 1;
+}
+
+/*
+ * The other end gives the command line arguments to "git init" one by
+ * one over pkt-line protocol, and then expects a message back.
+ *
+ * We need to read them all, even when we know we will reject the
+ * request before responding.
+ */
+static int serve(const char *errmsg)
+{
+	int argc = 0;
+	const char *argv[64];
+
+	argv[argc++] = "git";
+	argv[argc++] = "init";
+	for (;;) {
+		static char err[1000];
+		char line[1000];
+		int len;
+
+		len = packet_read_line(0, line, sizeof(line));
+		if (!len)
+			break;
+		if (*errmsg)
+			continue; /* just read and discard */
+
+		if (line[len - 1] == '\n')
+			line[--len] = '\0';
+
+		if (!prefixcmp(line, "arg ")) {
+			const char *cmd = line + 4;
+			if (forbidden_arg(cmd)) {
+				snprintf(err, sizeof(err),
+					 "forbidden option to 'git init': '%s'",
+					 cmd);
+				errmsg = err;
+			} else if (argc + 1 < ARRAY_SIZE(argv))
+				argv[argc++] = xstrdup(cmd);
+			else
+				errmsg = "arg list too long";
+			continue;
+		}
+
+		/* Possible protocol extensions here... */
+		snprintf(err, sizeof(err),
+			 "unrecognized protocol extension: %s", line);
+		errmsg = err;
+
+		/* Do not break out of the loop here */
+	}
+
+	if (!*errmsg) {
+		struct child_process child;
+
+		argv[argc] = NULL;
+		memset(&child, 0, sizeof(child));
+		child.argv = argv;
+		child.env = sanitize_git_env;
+
+		/*
+		 * NEEDSWORK: I do not currently think it is worth it,
+		 * but this might want to set up and use the sideband
+		 * to capture and send output from the child back to
+		 * the requestor.  At least this comment needs to be removed
+		 * once we make the decision.
+		 */
+		child.stdout_to_stderr = 1;
+
+		/*
+		 * NEEDSWORK: we might want to distinguish various
+		 * error codes from run_command() and return different
+		 * messages back.  I am too lazy to be bothered.
+		 */
+		if (run_command(&child))
+			errmsg = "bad";
+	}
+
+	if (*errmsg)
+		packet_write(1, "ng init %s\n", errmsg);
+	else
+		packet_write(1, "ok init\n");
+
+	return !!*errmsg;
+}
+
+int cmd_init_serve(int argc, const char **argv, const char *prefix)
+{
+	const char *dir;
+	struct strbuf errmsg = STRBUF_INIT;
+	char here[PATH_MAX];
+	int must_rmdir = 0;
+
+	if (argc != 2)
+		return serve("usage: init /p/a/th");
+	dir = argv[1];
+
+	if (!getcwd(here, sizeof(here)))
+		return serve("init cannot determine the $cwd");
+
+	/*
+	 * Perhaps lift avoid_alias() from daemon.c and check
+	 * dir with it, as programs like gitosis may
+	 * want to restrict the arguments to this service.
+	 */
+	if (mkdir(dir, 0777))
+		strbuf_addf(&errmsg,
+			    "cannot mkdir('%s'): %s", dir, strerror(errno));
+	else {
+		must_rmdir = 1;
+		if (chdir(dir))
+			strbuf_addf(&errmsg,
+				    "cannot chdir('%s'): %s", dir, strerror(errno));
+	}
+	if (serve(errmsg.buf)) {
+		if (must_rmdir && !chdir(here))
+			rmdir(dir);
+		return 1;
+	}
+	return 0;
+}
diff --git a/builtin.h b/builtin.h
index 1495cf6..e9f9ffb 100644
--- a/builtin.h
+++ b/builtin.h
@@ -59,6 +59,7 @@ extern int cmd_grep(int argc, const char **argv, const char *prefix);
 extern int cmd_help(int argc, const char **argv, const char *prefix);
 extern int cmd_http_fetch(int argc, const char **argv, const char *prefix);
 extern int cmd_init_db(int argc, const char **argv, const char *prefix);
+extern int cmd_init_serve(int argc, const char **argv, const char *prefix);
 extern int cmd_log(int argc, const char **argv, const char *prefix);
 extern int cmd_log_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index c2b181e..1df8584 100644
--- a/git.c
+++ b/git.c
@@ -311,6 +311,7 @@ static void handle_internal_command(int argc, const char **argv)
 #endif
 		{ "init", cmd_init_db },
 		{ "init-db", cmd_init_db },
+		{ "init-serve", cmd_init_serve },
 		{ "log", cmd_log, RUN_SETUP | USE_PAGER },
 		{ "ls-files", cmd_ls_files, RUN_SETUP },
 		{ "ls-tree", cmd_ls_tree, RUN_SETUP },
-- 
1.6.2.rc2.99.g9f3bb

  reply	other threads:[~2009-03-01  0:05 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-01  0:03 [PATCH 1/4] Refactor list of environment variables to be sanitized Junio C Hamano
2009-03-01  0:03 ` [PATCH 2/4] git-init: inject some sanity to the option parser Junio C Hamano
2009-03-01  0:03   ` Junio C Hamano [this message]
2009-03-01  0:03     ` [PATCH 4/4] "git init --remote=host:path" Junio C Hamano
2009-03-01  3:16     ` [PATCH 3/4] Add init-serve, the remote side of " Jeff King
2009-03-01  5:54       ` Junio C Hamano
2009-03-01 10:00         ` Jeff King
2009-03-01 17:04           ` Shawn O. Pearce
2009-03-03  6:50             ` Subject: [PATCH] Push to create Junio C Hamano
2009-03-03  7:09               ` Jay Soffian
2009-03-03  7:09               ` Jeff King
2009-03-03  7:37                 ` Jay Soffian
2009-03-03  7:39                   ` Jay Soffian
2009-03-03  7:56                   ` Junio C Hamano
2009-03-03  8:02                     ` Jay Soffian
2009-03-03  8:04                       ` Junio C Hamano
2009-03-03  8:04                       ` Junio C Hamano
2009-03-03  8:16                         ` Jay Soffian
2009-03-03  8:23                     ` Jeff King
2009-03-03 19:57                       ` Jay Soffian
2009-03-04  5:42                         ` Jeff King
2009-03-04  6:35                           ` Junio C Hamano
2009-03-04 13:06                           ` Jay Soffian
2009-03-03  7:55                 ` Junio C Hamano
2009-03-03  8:06                   ` Jeff King
2009-03-03  8:22                     ` Junio C Hamano
2009-03-03  8:27                       ` Jeff King
2009-03-03  8:30                         ` Junio C Hamano
2009-03-03  8:41                           ` Jay Soffian
2009-03-03  9:23                           ` Theodore Tso
2009-03-03 10:39                             ` Johannes Schindelin
2009-03-04 17:58                               ` Theodore Tso
2009-03-06  1:37                                 ` Miles Bader
2009-03-03 18:41                             ` Shawn O. Pearce
2009-03-04  8:32                               ` [RFC/PATCH 1/2] improve missing repository error message Jeff King
2009-03-04  9:19                                 ` Matthieu Moy
2009-03-04 10:35                                   ` Jeff King
2009-03-04 18:57                                 ` Shawn O. Pearce
2009-03-05 10:36                                   ` Jeff King
2009-03-04  8:42                               ` [RFC/PATCH 2/2] make remote hangup warnings more friendly Jeff King
2009-03-04 19:04                                 ` Shawn O. Pearce
2009-03-05 10:45                                   ` Jeff King
2009-03-03 21:08                   ` Subject: [PATCH] Push to create Daniel Barkalow

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=1235865822-14625-3-git-send-email-gitster@pobox.com \
    --to=gitster@pobox.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).