diff --git a/builtin-archive.c b/builtin-archive.c index 12351e9dd5..d34b3fd028 100644 --- a/builtin-archive.c +++ b/builtin-archive.c @@ -5,6 +5,7 @@ #include "cache.h" #include "builtin.h" #include "archive.h" +#include "transport.h" #include "parse-options.h" #include "pkt-line.h" #include "sideband.h" @@ -25,12 +26,16 @@ static void create_output_file(const char *output_file) static int run_remote_archiver(int argc, const char **argv, const char *remote, const char *exec) { - char *url, buf[LARGE_PACKET_MAX]; + char buf[LARGE_PACKET_MAX]; int fd[2], i, len, rv; - struct child_process *conn; + struct transport *transport; + struct remote *_remote; - url = xstrdup(remote); - conn = git_connect(fd, url, exec, 0); + _remote = remote_get(remote); + if (!_remote->url[0]) + die("git archive: Remote with no URL"); + transport = transport_get(_remote, _remote->url[0]); + transport_connect(transport, "git-upload-archive", exec, fd); for (i = 1; i < argc; i++) packet_write(fd[1], "argument %s\n", argv[i]); @@ -53,9 +58,7 @@ static int run_remote_archiver(int argc, const char **argv, /* Now, start reading from fd[0] and spit it out to stdout */ rv = recv_sideband("archive", fd[0], 1); - close(fd[0]); - close(fd[1]); - rv |= finish_connect(conn); + rv |= transport_disconnect(transport); return !!rv; } diff --git a/transport-helper.c b/transport-helper.c index 50b3bac0c4..6ece0d9875 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -467,6 +467,24 @@ static int process_connect(struct transport *transport, return process_connect_service(transport, name, exec); } +static int connect_helper(struct transport *transport, const char *name, + const char *exec, int fd[2]) +{ + struct helper_data *data = transport->data; + + /* Get_helper so connect is inited. */ + get_helper(transport); + if (!data->connect) + die("Operation not supported by protocol."); + + if (!process_connect_service(transport, name, exec)) + die("Can't connect to subservice %s.", name); + + fd[0] = data->helper->out; + fd[1] = data->helper->in; + return 0; +} + static int fetch(struct transport *transport, int nr_heads, struct ref **to_fetch) { @@ -711,6 +729,7 @@ int transport_helper_init(struct transport *transport, const char *name) transport->fetch = fetch; transport->push_refs = push_refs; transport->disconnect = release_helper; + transport->connect = connect_helper; transport->smart_options = &(data->transport_options); return 0; } diff --git a/transport.c b/transport.c index ad25b98ae1..a7d67eba83 100644 --- a/transport.c +++ b/transport.c @@ -756,6 +756,17 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re return ret; } +static int connect_git(struct transport *transport, const char *name, + const char *executable, int fd[2]) +{ + struct git_transport_data *data = transport->data; + data->conn = git_connect(data->fd, transport->url, + executable, 0); + fd[0] = data->fd[0]; + fd[1] = data->fd[1]; + return 0; +} + static int disconnect_git(struct transport *transport) { struct git_transport_data *data = transport->data; @@ -901,6 +912,7 @@ struct transport *transport_get(struct remote *remote, const char *url) ret->get_refs_list = get_refs_via_connect; ret->fetch = fetch_refs_via_pack; ret->push_refs = git_transport_push; + ret->connect = connect_git; ret->disconnect = disconnect_git; ret->smart_options = &(data->options); @@ -1061,6 +1073,15 @@ void transport_unlock_pack(struct transport *transport) } } +int transport_connect(struct transport *transport, const char *name, + const char *exec, int fd[2]) +{ + if (transport->connect) + return transport->connect(transport, name, exec, fd); + else + die("Operation not supported by protocol"); +} + int transport_disconnect(struct transport *transport) { int ret = 0; diff --git a/transport.h b/transport.h index 781db2ec82..97ba2519dd 100644 --- a/transport.h +++ b/transport.h @@ -64,6 +64,8 @@ struct transport { **/ int (*push_refs)(struct transport *transport, struct ref *refs, int flags); int (*push)(struct transport *connection, int refspec_nr, const char **refspec, int flags); + int (*connect)(struct transport *connection, const char *name, + const char *executable, int fd[2]); /** get_refs_list(), fetch(), and push_refs() can keep * resources (such as a connection) reserved for futher @@ -133,6 +135,9 @@ char *transport_anonymize_url(const char *url); void transport_take_over(struct transport *transport, struct child_process *child); +int transport_connect(struct transport *transport, const char *name, + const char *exec, int fd[2]); + /* Transport methods defined outside transport.c */ int transport_helper_init(struct transport *transport, const char *name);