2 * Copyright (C) the libgit2 contributors. All rights reserved.
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 git_smart_subtransport_definition http_subtransport_definition
= { git_smart_subtransport_http
, 1 };
22 static git_smart_subtransport_definition git_subtransport_definition
= { git_smart_subtransport_git
, 0 };
24 static git_smart_subtransport_definition ssh_subtransport_definition
= { git_smart_subtransport_ssh
, 0 };
27 static transport_definition local_transport_definition
= { "file://", 1, git_transport_local
, NULL
};
29 static transport_definition ssh_transport_definition
= { "ssh://", 1, git_transport_smart
, &ssh_subtransport_definition
};
31 static transport_definition dummy_transport_definition
= { NULL
, 1, git_transport_dummy
, NULL
};
34 static transport_definition transports
[] = {
35 {"git://", 1, git_transport_smart
, &git_subtransport_definition
},
36 {"http://", 1, git_transport_smart
, &http_subtransport_definition
},
37 {"https://", 1, git_transport_smart
, &http_subtransport_definition
},
38 {"file://", 1, git_transport_local
, NULL
},
40 {"ssh://", 1, git_transport_smart
, &ssh_subtransport_definition
},
45 #define GIT_TRANSPORT_COUNT (sizeof(transports)/sizeof(transports[0])) - 1
47 static int transport_find_fn(const char *url
, git_transport_cb
*callback
, void **param
)
50 unsigned priority
= 0;
51 transport_definition
*definition
= NULL
, *definition_iter
;
53 // First, check to see if it's an obvious URL, which a URL scheme
54 for (i
= 0; i
< GIT_TRANSPORT_COUNT
; ++i
) {
55 definition_iter
= &transports
[i
];
57 if (strncasecmp(url
, definition_iter
->prefix
, strlen(definition_iter
->prefix
)))
60 if (definition_iter
->priority
> priority
)
61 definition
= definition_iter
;
65 /* On Windows, it might not be possible to discern between absolute local
66 * and ssh paths - first check if this is a valid local path that points
67 * to a directory and if so assume local path, else assume SSH */
69 /* Check to see if the path points to a file on the local file system */
70 if (!definition
&& git_path_exists(url
) && git_path_isdir(url
))
71 definition
= &local_transport_definition
;
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 /* For other systems, perform the SSH check first, to avoid going to the
79 * filesystem if it is not necessary */
81 /* It could be a SSH remote path. Check to see if there's a :
82 * SSH is an unsupported transport mechanism in this version of libgit2 */
83 if (!definition
&& strrchr(url
, ':'))
85 definition
= &ssh_transport_definition
;
87 definition
= &dummy_transport_definition
;
90 /* Check to see if the path points to a file on the local file system */
91 if (!definition
&& git_path_exists(url
) && git_path_isdir(url
))
92 definition
= &local_transport_definition
;
98 *callback
= definition
->fn
;
99 *param
= definition
->param
;
108 int git_transport_dummy(git_transport
**transport
, git_remote
*owner
, void *param
)
110 GIT_UNUSED(transport
);
113 giterr_set(GITERR_NET
, "This transport isn't implemented. Sorry");
117 int git_transport_new(git_transport
**out
, git_remote
*owner
, const char *url
)
120 git_transport
*transport
;
124 if (transport_find_fn(url
, &fn
, ¶m
) < 0) {
125 giterr_set(GITERR_NET
, "Unsupported URL protocol");
129 error
= fn(&transport
, owner
, param
);
139 int git_remote_valid_url(const char *url
)
144 return !transport_find_fn(url
, &fn
, ¶m
);
147 int git_remote_supported_url(const char* url
)
152 if (transport_find_fn(url
, &fn
, ¶m
) < 0)
155 return fn
!= &git_transport_dummy
;