shell.c 2.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2
#include "cache.h"
#include "quote.h"
3
#include "exec_cmd.h"
J
Johannes Schindelin 已提交
4
#include "strbuf.h"
L
Linus Torvalds 已提交
5 6 7 8 9

static int do_generic_cmd(const char *me, char *arg)
{
	const char *my_argv[4];

10
	setup_path();
11
	if (!arg || !(arg = sq_dequote(arg)))
L
Linus Torvalds 已提交
12
		die("bad argument");
13
	if (prefixcmp(me, "git-"))
14
		die("bad command");
L
Linus Torvalds 已提交
15

16
	my_argv[0] = me + 4;
L
Linus Torvalds 已提交
17 18 19
	my_argv[1] = arg;
	my_argv[2] = NULL;

J
Junio C Hamano 已提交
20
	return execv_git_cmd(my_argv);
L
Linus Torvalds 已提交
21 22
}

J
Johannes Schindelin 已提交
23 24 25 26 27 28 29 30 31
static int do_cvs_cmd(const char *me, char *arg)
{
	const char *cvsserver_argv[3] = {
		"cvsserver", "server", NULL
	};

	if (!arg || strcmp(arg, "server"))
		die("git-cvsserver only handles server: %s", arg);

32
	setup_path();
J
Johannes Schindelin 已提交
33 34 35 36
	return execv_git_cmd(cvsserver_argv);
}


L
Linus Torvalds 已提交
37 38 39 40 41 42
static struct commands {
	const char *name;
	int (*exec)(const char *me, char *arg);
} cmd_list[] = {
	{ "git-receive-pack", do_generic_cmd },
	{ "git-upload-pack", do_generic_cmd },
43
	{ "git-upload-archive", do_generic_cmd },
J
Johannes Schindelin 已提交
44
	{ "cvs", do_cvs_cmd },
L
Linus Torvalds 已提交
45 46 47
	{ NULL },
};

J
Junio C Hamano 已提交
48
int main(int argc, char **argv)
L
Linus Torvalds 已提交
49 50 51
{
	char *prog;
	struct commands *cmd;
52 53 54 55 56 57 58 59 60 61 62 63 64
	int devnull_fd;

	/*
	 * Always open file descriptors 0/1/2 to avoid clobbering files
	 * in die().  It also avoids not messing up when the pipes are
	 * dup'ed onto stdin/stdout/stderr in the child processes we spawn.
	 */
	devnull_fd = open("/dev/null", O_RDWR);
	while (devnull_fd >= 0 && devnull_fd <= 2)
		devnull_fd = dup(devnull_fd);
	if (devnull_fd == -1)
		die("opening /dev/null failed (%s)", strerror(errno));
	close (devnull_fd);
L
Linus Torvalds 已提交
65

66 67 68
	/*
	 * Special hack to pretend to be a CVS server
	 */
J
Johannes Schindelin 已提交
69 70
	if (argc == 2 && !strcmp(argv[1], "cvs server"))
		argv--;
71 72 73 74 75

	/*
	 * We do not accept anything but "-c" followed by "cmd arg",
	 * where "cmd" is a very limited subset of git commands.
	 */
J
Johannes Schindelin 已提交
76
	else if (argc != 3 || strcmp(argv[1], "-c"))
L
Linus Torvalds 已提交
77 78
		die("What do you think I am? A shell?");

J
Junio C Hamano 已提交
79
	prog = argv[2];
80 81 82 83
	if (!strncmp(prog, "git", 3) && isspace(prog[3]))
		/* Accept "git foo" as if the caller said "git-foo". */
		prog[3] = '-';

L
Linus Torvalds 已提交
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	for (cmd = cmd_list ; cmd->name ; cmd++) {
		int len = strlen(cmd->name);
		char *arg;
		if (strncmp(cmd->name, prog, len))
			continue;
		arg = NULL;
		switch (prog[len]) {
		case '\0':
			arg = NULL;
			break;
		case ' ':
			arg = prog + len + 1;
			break;
		default:
			continue;
		}
		exit(cmd->exec(cmd->name, arg));
	}
	die("unrecognized command '%s'", prog);
}