| 49 | #define MAX_INTERACTIVE_COMMAND (4*1024*1024) |
| 50 | |
| 51 | static void run_shell(void) |
| 52 | { |
| 53 | int done = 0; |
| 54 | struct child_process help_cmd = CHILD_PROCESS_INIT; |
| 55 | |
| 56 | if (!access(NOLOGIN_COMMAND, F_OK)) { |
| 57 | /* Interactive login disabled. */ |
| 58 | struct child_process nologin_cmd = CHILD_PROCESS_INIT; |
| 59 | int status; |
| 60 | |
| 61 | strvec_push(&nologin_cmd.args, NOLOGIN_COMMAND); |
| 62 | status = run_command(&nologin_cmd); |
| 63 | if (status < 0) |
| 64 | exit(127); |
| 65 | exit(status); |
| 66 | } |
| 67 | |
| 68 | /* Print help if enabled */ |
| 69 | help_cmd.silent_exec_failure = 1; |
| 70 | strvec_push(&help_cmd.args, HELP_COMMAND); |
| 71 | run_command(&help_cmd); |
| 72 | |
| 73 | do { |
| 74 | const char *prog; |
| 75 | char *full_cmd; |
| 76 | char *rawargs; |
| 77 | size_t len; |
| 78 | char *split_args; |
| 79 | const char **argv; |
| 80 | int code; |
| 81 | int count; |
| 82 | |
| 83 | fprintf(stderr, "git> "); |
| 84 | |
| 85 | /* |
| 86 | * Avoid using a strbuf or git_read_line_interactively() here. |
| 87 | * We don't want to allocate arbitrary amounts of memory on |
| 88 | * behalf of a possibly untrusted client, and we're subject to |
| 89 | * OS limits on command length anyway. |
| 90 | */ |
| 91 | fflush(stdout); |
| 92 | rawargs = xmalloc(MAX_INTERACTIVE_COMMAND); |
| 93 | if (!fgets(rawargs, MAX_INTERACTIVE_COMMAND, stdin)) { |
| 94 | fprintf(stderr, "\n"); |
| 95 | free(rawargs); |
| 96 | break; |
| 97 | } |
| 98 | len = strlen(rawargs); |
| 99 | |
| 100 | /* |
| 101 | * If we truncated due to our input buffer size, reject the |
| 102 | * command. That's better than running bogus input, and |
| 103 | * there's a good chance it's just malicious garbage anyway. |
| 104 | */ |
| 105 | if (len >= MAX_INTERACTIVE_COMMAND - 1) |
| 106 | die("invalid command format: input too long"); |
| 107 | |
| 108 | if (len > 0 && rawargs[len - 1] == '\n') { |
no test coverage detected