shell.c 2.1 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 10 11 12 13
/* Stubs for functions that make no sense for git-shell. These stubs
 * are provided here to avoid linking in external redundant modules.
 */
void release_pack_memory(size_t need, int fd){}
void trace_argv_printf(const char **argv, const char *fmt, ...){}
void trace_printf(const char *fmt, ...){}


L
Linus Torvalds 已提交
14 15 16 17
static int do_generic_cmd(const char *me, char *arg)
{
	const char *my_argv[4];

18
	setup_path(NULL);
19
	if (!arg || !(arg = sq_dequote(arg)))
L
Linus Torvalds 已提交
20
		die("bad argument");
21
	if (prefixcmp(me, "git-"))
22
		die("bad command");
L
Linus Torvalds 已提交
23

24
	my_argv[0] = me + 4;
L
Linus Torvalds 已提交
25 26 27
	my_argv[1] = arg;
	my_argv[2] = NULL;

J
Junio C Hamano 已提交
28
	return execv_git_cmd(my_argv);
L
Linus Torvalds 已提交
29 30
}

J
Johannes Schindelin 已提交
31 32 33 34 35 36 37 38 39
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);

40
	setup_path(NULL);
J
Johannes Schindelin 已提交
41 42 43 44
	return execv_git_cmd(cvsserver_argv);
}


L
Linus Torvalds 已提交
45 46 47 48 49 50
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 },
J
Johannes Schindelin 已提交
51
	{ "cvs", do_cvs_cmd },
L
Linus Torvalds 已提交
52 53 54 55 56 57 58 59
	{ NULL },
};

int main(int argc, char **argv)
{
	char *prog;
	struct commands *cmd;

60 61 62
	/*
	 * Special hack to pretend to be a CVS server
	 */
J
Johannes Schindelin 已提交
63 64
	if (argc == 2 && !strcmp(argv[1], "cvs server"))
		argv--;
65 66 67 68 69

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

	prog = argv[2];
74 75 76 77
	if (!strncmp(prog, "git", 3) && isspace(prog[3]))
		/* Accept "git foo" as if the caller said "git-foo". */
		prog[3] = '-';

L
Linus Torvalds 已提交
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
	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);
}