2 * Copyright (C) 2009-2012 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "git2/types.h"
9 #include "git2/remote.h"
11 #include "git2/transport.h"
14 typedef struct transport_definition
{
19 } transport_definition
;
21 static transport_definition local_transport_definition
= { "file://", 1, git_transport_local
, NULL
};
22 static transport_definition dummy_transport_definition
= { NULL
, 1, git_transport_dummy
, NULL
};
24 static git_smart_subtransport_definition http_subtransport_definition
= { git_smart_subtransport_http
, 1 };
25 static git_smart_subtransport_definition git_subtransport_definition
= { git_smart_subtransport_git
, 0 };
27 static transport_definition transports
[] = {
28 {"git://", 1, git_transport_smart
, &git_subtransport_definition
},
29 {"http://", 1, git_transport_smart
, &http_subtransport_definition
},
30 {"https://", 1, git_transport_smart
, &http_subtransport_definition
},
31 {"file://", 1, git_transport_local
, NULL
},
32 {"git+ssh://", 1, git_transport_dummy
, NULL
},
33 {"ssh+git://", 1, git_transport_dummy
, NULL
},
37 #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
39 static int transport_find_fn(const char *url
, git_transport_cb
*callback
, void **param
)
42 unsigned priority
= 0;
43 transport_definition
*definition
= NULL
, *definition_iter
;
45 // First, check to see if it's an obvious URL, which a URL scheme
46 for (i
= 0; i
< GIT_TRANSPORT_COUNT
; ++i
) {
47 definition_iter
= &transports
[i
];
49 if (strncasecmp(url
, definition_iter
->prefix
, strlen(definition_iter
->prefix
)))
52 if (definition_iter
->priority
> priority
)
53 definition
= definition_iter
;
57 /* On Windows, it might not be possible to discern between absolute local
58 * and ssh paths - first check if this is a valid local path that points
59 * to a directory and if so assume local path, else assume SSH */
61 /* Check to see if the path points to a file on the local file system */
62 if (!definition
&& git_path_exists(url
) && git_path_isdir(url
))
63 definition
= &local_transport_definition
;
65 /* It could be a SSH remote path. Check to see if there's a :
66 * SSH is an unsupported transport mechanism in this version of libgit2 */
67 if (!definition
&& strrchr(url
, ':'))
68 definition
= &dummy_transport_definition
;
70 /* For other systems, perform the SSH check first, to avoid going to the
71 * filesystem if it is not necessary */
73 /* It could be a SSH remote path. Check to see if there's a :
74 * SSH is an unsupported transport mechanism in this version of libgit2 */
75 if (!definition
&& strrchr(url
, ':'))
76 definition
= &dummy_transport_definition
;
78 /* Check to see if the path points to a file on the local file system */
79 if (!definition
&& git_path_exists(url
) && git_path_isdir(url
))
80 definition
= &local_transport_definition
;
86 *callback
= definition
->fn
;
87 *param
= definition
->param
;
96 int git_transport_dummy(git_transport
**transport
, git_remote
*owner
, void *param
)
98 GIT_UNUSED(transport
);
101 giterr_set(GITERR_NET
, "This transport isn't implemented. Sorry");
105 int git_transport_new(git_transport
**out
, git_remote
*owner
, const char *url
)
108 git_transport
*transport
;
112 if (transport_find_fn(url
, &fn
, ¶m
) < 0) {
113 giterr_set(GITERR_NET
, "Unsupported URL protocol");
117 error
= fn(&transport
, owner
, param
);
127 int git_remote_valid_url(const char *url
)
132 return !transport_find_fn(url
, &fn
, ¶m
);
135 int git_remote_supported_url(const char* url
)
140 if (transport_find_fn(url
, &fn
, ¶m
) < 0)
143 return fn
!= &git_transport_dummy
;