| /* |
| * Copyright (C) 2009-2012 the libgit2 contributors |
| * |
| * This file is part of libgit2, distributed under the GNU GPL v2 with |
| * a Linking Exception. For full terms see the included COPYING file. |
| */ |
| #include "common.h" |
| #include "git2/types.h" |
| #include "git2/remote.h" |
| #include "git2/net.h" |
| #include "transport.h" |
| #include "path.h" |
| |
| static struct { |
| char *prefix; |
| git_transport_cb fn; |
| } transports[] = { |
| {"git://", git_transport_git}, |
| {"http://", git_transport_http}, |
| {"https://", git_transport_https}, |
| {"file://", git_transport_local}, |
| {"git+ssh://", git_transport_dummy}, |
| {"ssh+git://", git_transport_dummy}, |
| {NULL, 0} |
| }; |
| |
| #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1 |
| |
| static git_transport_cb transport_find_fn(const char *url) |
| { |
| size_t i = 0; |
| |
| // First, check to see if it's an obvious URL, which a URL scheme |
| for (i = 0; i < GIT_TRANSPORT_COUNT; ++i) { |
| if (!strncasecmp(url, transports[i].prefix, strlen(transports[i].prefix))) |
| return transports[i].fn; |
| } |
| |
| /* still here? Check to see if the path points to a file on the local file system */ |
| if ((git_path_exists(url) == 0) && git_path_isdir(url)) |
| return &git_transport_local; |
| |
| /* It could be a SSH remote path. Check to see if there's a : */ |
| if (strrchr(url, ':')) |
| return &git_transport_dummy; /* SSH is an unsupported transport mechanism in this version of libgit2 */ |
| |
| return NULL; |
| } |
| |
| /************** |
| * Public API * |
| **************/ |
| |
| int git_transport_dummy(git_transport **transport) |
| { |
| GIT_UNUSED(transport); |
| giterr_set(GITERR_NET, "This transport isn't implemented. Sorry"); |
| return -1; |
| } |
| |
| int git_transport_new(git_transport **out, const char *url) |
| { |
| git_transport_cb fn; |
| git_transport *transport; |
| int error; |
| |
| fn = transport_find_fn(url); |
| |
| if (fn == NULL) { |
| giterr_set(GITERR_NET, "Unsupported URL protocol"); |
| return -1; |
| } |
| |
| error = fn(&transport); |
| if (error < 0) |
| return error; |
| |
| transport->url = git__strdup(url); |
| GITERR_CHECK_ALLOC(transport->url); |
| |
| *out = transport; |
| |
| return 0; |
| } |
| |
| /* from remote.h */ |
| int git_remote_valid_url(const char *url) |
| { |
| return transport_find_fn(url) != NULL; |
| } |
| |
| int git_remote_supported_url(const char* url) |
| { |
| git_transport_cb transport_fn = transport_find_fn(url); |
| |
| return ((transport_fn != NULL) && (transport_fn != &git_transport_dummy)); |
| } |