commit - f68a789010192e18ab34908cd5fde2d531c35fdc
commit + 9a682fbe2c64ce71685dc332f7d2758ede442224
blob - c82af734662e46f71c8f251dae7e1932a3a1ce57
blob + 0d45d173276f8ac93d898c2c552e2430bdbb95eb
--- lib/fetch.c
+++ lib/fetch.c
{
const struct got_error *err = NULL;
char *s, *p, *q;
- int n, hasport;
+ int n;
*proto = *host = *port = *server_path = *repo_name = NULL;
p = strstr(uri, "://");
if (!p) {
- return got_error(GOT_ERR_PARSE_URI);
- }
- *proto = strndup(uri, p - uri);
- if (proto == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
-
- hasport = (strcmp(*proto, "git") == 0 ||
- strstr(*proto, "http") == *proto);
- s = p + 3;
- p = NULL;
- if (!hasport) {
- p = strstr(s, ":");
- if (p != NULL)
- p++;
- }
- if (p == NULL)
- p = strstr(s, "/");
- if (p == NULL || strlen(p) == 1) {
- err = got_error(GOT_ERR_PARSE_URI);
- goto done;
- }
-
- q = memchr(s, ':', p - s);
- if (q) {
+ /* Try parsing Git's "scp" style URL syntax. */
+ *proto = strdup("ssh");
+ if (proto == NULL) {
+ err = got_error_from_errno("strdup");
+ goto done;
+ }
+ *port = strdup("22");
+ if (*port == NULL) {
+ err = got_error_from_errno("strdup");
+ goto done;
+ }
+ s = (char *)uri;
+ q = strchr(s, ':');
+ if (q == NULL) {
+ err = got_error(GOT_ERR_PARSE_URI);
+ goto done;
+ }
+ /* No slashes allowed before first colon. */
+ p = strchr(s, '/');
+ if (p && q > p) {
+ err = got_error(GOT_ERR_PARSE_URI);
+ goto done;
+ }
*host = strndup(s, q - s);
if (*host == NULL) {
err = got_error_from_errno("strndup");
goto done;
}
- *port = strndup(q + 1, p - (q + 1));
- if (*port == NULL) {
- err = got_error_from_errno("strndup");
- goto done;
- }
+ p = q + 1;
} else {
- *host = strndup(s, p - s);
- if (*host == NULL) {
+ *proto = strndup(uri, p - uri);
+ if (proto == NULL) {
err = got_error_from_errno("strndup");
goto done;
}
- if (asprintf(port, "%u", GOT_DEFAULT_GIT_PORT) == -1) {
- err = got_error_from_errno("asprintf");
+ s = p + 3;
+
+ p = strstr(s, "/");
+ if (p == NULL || strlen(p) == 1) {
+ err = got_error(GOT_ERR_PARSE_URI);
goto done;
}
+
+ q = memchr(s, ':', p - s);
+ if (q) {
+ *host = strndup(s, q - s);
+ if (*host == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ *port = strndup(q + 1, p - (q + 1));
+ if (*port == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ } else {
+ *host = strndup(s, p - s);
+ if (*host == NULL) {
+ err = got_error_from_errno("strndup");
+ goto done;
+ }
+ if (asprintf(port, "%u", GOT_DEFAULT_GIT_PORT) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ }
}
*server_path = strdup(p);
goto done;
}
- p = strrchr(p, '/') + 1;
- if (!p || strlen(p) == 0) {
- //werrstr("missing repository in uri");
+ p = strrchr(p, '/');
+ if (!p || strlen(p) <= 1) {
err = got_error(GOT_ERR_PARSE_URI);
goto done;
}
+ p++;
n = strlen(p);
+ if (n == 0) {
+ err = got_error(GOT_ERR_PARSE_URI);
+ goto done;
+ }
if (hassuffix(p, ".git"))
n -= 4;
*repo_name = strndup(p, (p + n) - p);
blob - a43ae11cedd1948f4e7325fa76ffe35512c88ebc
blob + ff64378ee31865853d76973f1ac1ecf6f4c31698
--- regress/fetch/fetch_test.c
+++ regress/fetch/fetch_test.c
NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
{ "git:///127.0.0.1/git/",
NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
+ { "/127.0.0.1:/git/",
+ NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
{ "git://127.0.0.1/git/myrepo",
"git", "localhost", GOT_DEFAULT_GIT_PORT_STR, "git",
"https", "localhost", GOT_DEFAULT_GIT_PORT_STR,
"git/repos/foo/../bar", "myrepo", GOT_ERR_OK },
+ { "git+ssh://127.0.0.1:22/git/myrepo",
+ "git+ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK },
+ { "ssh://127.0.0.1:22/git/myrepo",
+ "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK },
+ { "127.0.0.1:git/myrepo",
+ "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK },
+ { "127.0.0.1:/git/myrepo",
+ "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK },
+ { "127.0.0.1:22/git/myrepo",
+ "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK },
};
int i;