Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 1 | #include "cache.h" |
| 2 | #include "quote.h" |
Michal Ostrowski | 77cb17e | 2006-01-10 21:12:17 -0500 | [diff] [blame] | 3 | #include "exec_cmd.h" |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 4 | #include "strbuf.h" |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 5 | |
| 6 | static int do_generic_cmd(const char *me, char *arg) |
| 7 | { |
| 8 | const char *my_argv[4]; |
| 9 | |
Johannes Sixt | e1464ca | 2008-07-21 21:19:52 +0200 | [diff] [blame] | 10 | setup_path(); |
Junio C Hamano | ab5f862 | 2005-11-25 20:57:02 -0800 | [diff] [blame] | 11 | if (!arg || !(arg = sq_dequote(arg))) |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 12 | die("bad argument"); |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 13 | if (prefixcmp(me, "git-")) |
Michal Ostrowski | 77cb17e | 2006-01-10 21:12:17 -0500 | [diff] [blame] | 14 | die("bad command"); |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 15 | |
Michal Ostrowski | 77cb17e | 2006-01-10 21:12:17 -0500 | [diff] [blame] | 16 | my_argv[0] = me + 4; |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 17 | my_argv[1] = arg; |
| 18 | my_argv[2] = NULL; |
| 19 | |
Junio C Hamano | 9201c70 | 2006-03-05 02:47:29 -0800 | [diff] [blame] | 20 | return execv_git_cmd(my_argv); |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 21 | } |
| 22 | |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 23 | static int do_cvs_cmd(const char *me, char *arg) |
| 24 | { |
| 25 | const char *cvsserver_argv[3] = { |
| 26 | "cvsserver", "server", NULL |
| 27 | }; |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 28 | |
| 29 | if (!arg || strcmp(arg, "server")) |
| 30 | die("git-cvsserver only handles server: %s", arg); |
| 31 | |
Johannes Sixt | e1464ca | 2008-07-21 21:19:52 +0200 | [diff] [blame] | 32 | setup_path(); |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 33 | return execv_git_cmd(cvsserver_argv); |
| 34 | } |
| 35 | |
| 36 | |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 37 | static struct commands { |
| 38 | const char *name; |
| 39 | int (*exec)(const char *me, char *arg); |
| 40 | } cmd_list[] = { |
| 41 | { "git-receive-pack", do_generic_cmd }, |
| 42 | { "git-upload-pack", do_generic_cmd }, |
Erik Broes | 79f72b9 | 2009-04-09 21:58:52 +0200 | [diff] [blame] | 43 | { "git-upload-archive", do_generic_cmd }, |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 44 | { "cvs", do_cvs_cmd }, |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 45 | { NULL }, |
| 46 | }; |
| 47 | |
Junio C Hamano | 1e7abc5 | 2008-08-25 22:39:17 -0700 | [diff] [blame] | 48 | int main(int argc, char **argv) |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 49 | { |
| 50 | char *prog; |
| 51 | struct commands *cmd; |
Paolo Bonzini | 0cfeed2 | 2008-08-27 17:20:35 +0200 | [diff] [blame] | 52 | int devnull_fd; |
| 53 | |
| 54 | /* |
| 55 | * Always open file descriptors 0/1/2 to avoid clobbering files |
| 56 | * in die(). It also avoids not messing up when the pipes are |
| 57 | * dup'ed onto stdin/stdout/stderr in the child processes we spawn. |
| 58 | */ |
| 59 | devnull_fd = open("/dev/null", O_RDWR); |
| 60 | while (devnull_fd >= 0 && devnull_fd <= 2) |
| 61 | devnull_fd = dup(devnull_fd); |
| 62 | if (devnull_fd == -1) |
Thomas Rast | d824cbb | 2009-06-27 17:58:46 +0200 | [diff] [blame] | 63 | die_errno("opening /dev/null failed"); |
Paolo Bonzini | 0cfeed2 | 2008-08-27 17:20:35 +0200 | [diff] [blame] | 64 | close (devnull_fd); |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 65 | |
Junio C Hamano | bc7c73e | 2007-12-01 22:16:19 -0800 | [diff] [blame] | 66 | /* |
| 67 | * Special hack to pretend to be a CVS server |
| 68 | */ |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 69 | if (argc == 2 && !strcmp(argv[1], "cvs server")) |
| 70 | argv--; |
Junio C Hamano | bc7c73e | 2007-12-01 22:16:19 -0800 | [diff] [blame] | 71 | |
| 72 | /* |
| 73 | * We do not accept anything but "-c" followed by "cmd arg", |
| 74 | * where "cmd" is a very limited subset of git commands. |
| 75 | */ |
Johannes Schindelin | 0c696fe | 2007-10-09 15:33:25 +0100 | [diff] [blame] | 76 | else if (argc != 3 || strcmp(argv[1], "-c")) |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 77 | die("What do you think I am? A shell?"); |
| 78 | |
Junio C Hamano | 1e7abc5 | 2008-08-25 22:39:17 -0700 | [diff] [blame] | 79 | prog = argv[2]; |
Junio C Hamano | bc7c73e | 2007-12-01 22:16:19 -0800 | [diff] [blame] | 80 | if (!strncmp(prog, "git", 3) && isspace(prog[3])) |
| 81 | /* Accept "git foo" as if the caller said "git-foo". */ |
| 82 | prog[3] = '-'; |
| 83 | |
Linus Torvalds | 35eb2d3 | 2005-10-23 14:30:45 -0700 | [diff] [blame] | 84 | for (cmd = cmd_list ; cmd->name ; cmd++) { |
| 85 | int len = strlen(cmd->name); |
| 86 | char *arg; |
| 87 | if (strncmp(cmd->name, prog, len)) |
| 88 | continue; |
| 89 | arg = NULL; |
| 90 | switch (prog[len]) { |
| 91 | case '\0': |
| 92 | arg = NULL; |
| 93 | break; |
| 94 | case ' ': |
| 95 | arg = prog + len + 1; |
| 96 | break; |
| 97 | default: |
| 98 | continue; |
| 99 | } |
| 100 | exit(cmd->exec(cmd->name, arg)); |
| 101 | } |
| 102 | die("unrecognized command '%s'", prog); |
| 103 | } |