* Extract protocol and relevant parts from the specified connection URL. * The caller must free() the returned strings. */
| 1052 | * The caller must free() the returned strings. |
| 1053 | */ |
| 1054 | static enum url_scheme parse_connect_url(const char *url_orig, char **ret_host, |
| 1055 | char **ret_path) |
| 1056 | { |
| 1057 | char *url; |
| 1058 | char *host, *path; |
| 1059 | char *end; |
| 1060 | int separator = '/'; |
| 1061 | enum url_scheme scheme = URL_SCHEME_LOCAL; |
| 1062 | |
| 1063 | if (is_url(url_orig)) |
| 1064 | url = url_decode(url_orig); |
| 1065 | else |
| 1066 | url = xstrdup(url_orig); |
| 1067 | |
| 1068 | host = strstr(url, "://"); |
| 1069 | if (host) { |
| 1070 | *host = '\0'; |
| 1071 | scheme = url_get_scheme(url); |
| 1072 | if (scheme == URL_SCHEME_UNKNOWN) |
| 1073 | die(_("protocol '%s' is not supported"), url); |
| 1074 | host += 3; |
| 1075 | } else { |
| 1076 | host = url; |
| 1077 | if (!url_is_local_not_ssh(url)) { |
| 1078 | scheme = URL_SCHEME_SSH; |
| 1079 | separator = ':'; |
| 1080 | } |
| 1081 | } |
| 1082 | |
| 1083 | /* |
| 1084 | * Don't do destructive transforms as protocol code does |
| 1085 | * '[]' unwrapping in get_host_and_port() |
| 1086 | */ |
| 1087 | end = host_end(&host, 0); |
| 1088 | |
| 1089 | if (scheme == URL_SCHEME_LOCAL) |
| 1090 | path = end; |
| 1091 | else if (scheme == URL_SCHEME_FILE && *host != '/' && |
| 1092 | !has_dos_drive_prefix(host) && |
| 1093 | offset_1st_component(host - 2) > 1) |
| 1094 | path = host - 2; /* include the leading "//" */ |
| 1095 | else if (scheme == URL_SCHEME_FILE && has_dos_drive_prefix(end)) |
| 1096 | path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */ |
| 1097 | else |
| 1098 | path = strchr(end, separator); |
| 1099 | |
| 1100 | if (!path || !*path) |
| 1101 | die(_("no path specified; see 'git help pull' for valid url syntax")); |
| 1102 | |
| 1103 | /* |
| 1104 | * null-terminate hostname and point path to ~ for URL's like this: |
| 1105 | * ssh://host.xz/~user/repo |
| 1106 | */ |
| 1107 | |
| 1108 | end = path; /* Need to \0 terminate host here */ |
| 1109 | if (separator == ':') |
| 1110 | path++; /* path starts after ':' */ |
| 1111 | if (scheme == URL_SCHEME_GIT || scheme == URL_SCHEME_SSH) { |
no test coverage detected