Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2006 Franck Bui-Huu |
| 3 | * Copyright (c) 2006 Rene Scharfe |
| 4 | */ |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 5 | #include "cache.h" |
| 6 | #include "builtin.h" |
| 7 | #include "archive.h" |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 8 | #include "pkt-line.h" |
Junio C Hamano | 23d6d11 | 2006-09-10 03:33:34 -0700 | [diff] [blame] | 9 | #include "sideband.h" |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 10 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 11 | static int run_remote_archiver(const char *remote, int argc, |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 12 | const char **argv) |
| 13 | { |
Junio C Hamano | 23d6d11 | 2006-09-10 03:33:34 -0700 | [diff] [blame] | 14 | char *url, buf[LARGE_PACKET_MAX]; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 15 | int fd[2], i, len, rv; |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 16 | struct child_process *conn; |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 17 | const char *exec = "git-upload-archive"; |
Rene Scharfe | 819b2b5 | 2008-07-25 12:41:25 +0200 | [diff] [blame] | 18 | int exec_at = 0, exec_value_at = 0; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 19 | |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 20 | for (i = 1; i < argc; i++) { |
| 21 | const char *arg = argv[i]; |
Junio C Hamano | 599065a | 2007-02-20 01:54:00 -0800 | [diff] [blame] | 22 | if (!prefixcmp(arg, "--exec=")) { |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 23 | if (exec_at) |
| 24 | die("multiple --exec specified"); |
| 25 | exec = arg + 7; |
| 26 | exec_at = i; |
Rene Scharfe | 819b2b5 | 2008-07-25 12:41:25 +0200 | [diff] [blame] | 27 | } else if (!strcmp(arg, "--exec")) { |
| 28 | if (exec_at) |
| 29 | die("multiple --exec specified"); |
| 30 | if (i + 1 >= argc) |
| 31 | die("option --exec requires a value"); |
| 32 | exec = argv[i + 1]; |
| 33 | exec_at = i; |
| 34 | exec_value_at = ++i; |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 35 | } |
| 36 | } |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 37 | |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 38 | url = xstrdup(remote); |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 39 | conn = git_connect(fd, url, exec, 0); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 40 | |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 41 | for (i = 1; i < argc; i++) { |
Rene Scharfe | 819b2b5 | 2008-07-25 12:41:25 +0200 | [diff] [blame] | 42 | if (i == exec_at || i == exec_value_at) |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 43 | continue; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 44 | packet_write(fd[1], "argument %s\n", argv[i]); |
Junio C Hamano | fe5ab76 | 2006-09-10 04:02:57 -0700 | [diff] [blame] | 45 | } |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 46 | packet_flush(fd[1]); |
| 47 | |
| 48 | len = packet_read_line(fd[0], buf, sizeof(buf)); |
| 49 | if (!len) |
Heikki Orsila | 34baebc | 2008-08-30 14:12:53 +0300 | [diff] [blame] | 50 | die("git archive: expected ACK/NAK, got EOF"); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 51 | if (buf[len-1] == '\n') |
| 52 | buf[--len] = 0; |
| 53 | if (strcmp(buf, "ACK")) { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 54 | if (len > 5 && !prefixcmp(buf, "NACK ")) |
Heikki Orsila | 34baebc | 2008-08-30 14:12:53 +0300 | [diff] [blame] | 55 | die("git archive: NACK %s", buf + 5); |
| 56 | die("git archive: protocol error"); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | len = packet_read_line(fd[0], buf, sizeof(buf)); |
| 60 | if (len) |
Heikki Orsila | 34baebc | 2008-08-30 14:12:53 +0300 | [diff] [blame] | 61 | die("git archive: expected a flush"); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 62 | |
| 63 | /* Now, start reading from fd[0] and spit it out to stdout */ |
Nicolas Pitre | 9ac13ec | 2006-10-11 11:49:15 -0400 | [diff] [blame] | 64 | rv = recv_sideband("archive", fd[0], 1, 2); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 65 | close(fd[0]); |
Junio C Hamano | ec587fd | 2007-01-21 17:10:51 -0800 | [diff] [blame] | 66 | close(fd[1]); |
Johannes Sixt | 98158e9 | 2007-10-19 21:47:53 +0200 | [diff] [blame] | 67 | rv |= finish_connect(conn); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 68 | |
| 69 | return !!rv; |
| 70 | } |
| 71 | |
Junio C Hamano | d751864 | 2006-09-12 22:42:31 -0700 | [diff] [blame] | 72 | static const char *extract_remote_arg(int *ac, const char **av) |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 73 | { |
| 74 | int ix, iy, cnt = *ac; |
| 75 | int no_more_options = 0; |
| 76 | const char *remote = NULL; |
| 77 | |
| 78 | for (ix = iy = 1; ix < cnt; ix++) { |
| 79 | const char *arg = av[ix]; |
| 80 | if (!strcmp(arg, "--")) |
| 81 | no_more_options = 1; |
| 82 | if (!no_more_options) { |
Junio C Hamano | cc44c76 | 2007-02-20 01:53:29 -0800 | [diff] [blame] | 83 | if (!prefixcmp(arg, "--remote=")) { |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 84 | if (remote) |
| 85 | die("Multiple --remote specified"); |
| 86 | remote = arg + 9; |
| 87 | continue; |
Rene Scharfe | 819b2b5 | 2008-07-25 12:41:25 +0200 | [diff] [blame] | 88 | } else if (!strcmp(arg, "--remote")) { |
| 89 | if (remote) |
| 90 | die("Multiple --remote specified"); |
| 91 | if (++ix >= cnt) |
| 92 | die("option --remote requires a value"); |
| 93 | remote = av[ix]; |
| 94 | continue; |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 95 | } |
| 96 | if (arg[0] != '-') |
| 97 | no_more_options = 1; |
| 98 | } |
| 99 | if (ix != iy) |
| 100 | av[iy] = arg; |
| 101 | iy++; |
| 102 | } |
| 103 | if (remote) { |
| 104 | av[--cnt] = NULL; |
| 105 | *ac = cnt; |
| 106 | } |
| 107 | return remote; |
| 108 | } |
| 109 | |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 110 | int cmd_archive(int argc, const char **argv, const char *prefix) |
| 111 | { |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 112 | const char *remote = NULL; |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 113 | |
Junio C Hamano | d751864 | 2006-09-12 22:42:31 -0700 | [diff] [blame] | 114 | remote = extract_remote_arg(&argc, argv); |
Junio C Hamano | 37f9443 | 2006-09-09 23:48:03 -0700 | [diff] [blame] | 115 | if (remote) |
| 116 | return run_remote_archiver(remote, argc, argv); |
| 117 | |
Michal Rokos | aa90986 | 2006-11-21 23:19:28 +0100 | [diff] [blame] | 118 | setvbuf(stderr, NULL, _IOLBF, BUFSIZ); |
Junio C Hamano | 8142f60 | 2006-09-10 04:16:39 -0700 | [diff] [blame] | 119 | |
Rene Scharfe | 6e94e68 | 2008-07-25 12:41:21 +0200 | [diff] [blame] | 120 | return write_archive(argc, argv, prefix, 1); |
Franck Bui-Huu | 4df096a | 2006-09-07 15:12:02 +0200 | [diff] [blame] | 121 | } |