diff options
Diffstat (limited to 'src/transport.c')
-rw-r--r-- | src/transport.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/src/transport.c b/src/transport.c index 37c244c97..ff926b1be 100644 --- a/src/transport.c +++ b/src/transport.c @@ -42,6 +42,8 @@ static transport_definition transports[] = { {NULL, 0, 0} }; +static git_vector additional_transports = GIT_VECTOR_INIT; + #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1 static int transport_find_fn(const char *url, git_transport_cb *callback, void **param) @@ -61,6 +63,14 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void * definition = definition_iter; } + git_vector_foreach(&additional_transports, i, definition_iter) { + if (strncasecmp(url, definition_iter->prefix, strlen(definition_iter->prefix))) + continue; + + if (definition_iter->priority > priority) + definition = definition_iter; + } + #ifdef GIT_WIN32 /* On Windows, it might not be possible to discern between absolute local * and ssh paths - first check if this is a valid local path that points @@ -73,7 +83,7 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void * /* It could be a SSH remote path. Check to see if there's a : * SSH is an unsupported transport mechanism in this version of libgit2 */ if (!definition && strrchr(url, ':')) - definition = &dummy_transport_definition; + definition = &dummy_transport_definition; #else /* For other systems, perform the SSH check first, to avoid going to the * filesystem if it is not necessary */ @@ -97,7 +107,7 @@ static int transport_find_fn(const char *url, git_transport_cb *callback, void * *callback = definition->fn; *param = definition->param; - + return 0; } @@ -135,6 +145,62 @@ int git_transport_new(git_transport **out, git_remote *owner, const char *url) return 0; } +int git_transport_register( + const char *prefix, + unsigned priority, + git_transport_cb cb, + void *param) +{ + transport_definition *d; + + d = git__calloc(sizeof(transport_definition), 1); + GITERR_CHECK_ALLOC(d); + + d->prefix = git__strdup(prefix); + + if (!d->prefix) + goto on_error; + + d->priority = priority; + d->fn = cb; + d->param = param; + + if (git_vector_insert(&additional_transports, d) < 0) + goto on_error; + + return 0; + +on_error: + git__free(d->prefix); + git__free(d); + return -1; +} + +int git_transport_unregister( + const char *prefix, + unsigned priority) +{ + transport_definition *d; + unsigned i; + + git_vector_foreach(&additional_transports, i, d) { + if (d->priority == priority && !strcasecmp(d->prefix, prefix)) { + if (git_vector_remove(&additional_transports, i) < 0) + return -1; + + git__free(d->prefix); + git__free(d); + + if (!additional_transports.length) + git_vector_free(&additional_transports); + + return 0; + } + } + + return GIT_ENOTFOUND; +} + /* from remote.h */ int git_remote_valid_url(const char *url) { |