commit 5e5da8c4bcc83f7737a115b8da52fc3935fe3a6b from: Stefan Sperling date: Sun Sep 05 20:51:29 2021 UTC rename got_fetch_parse_uri() to got_dial_parse_uri() This function is now being used by both 'got fetch' and 'got send' so its former name was misleading. commit - 77d7d3bb1aabafae6c020c8a07a6e9f4f7885c9b commit + 5e5da8c4bcc83f7737a115b8da52fc3935fe3a6b blob - a907f12b2708cbb1ea36221531d27fbd95446daf blob + 5f3984d14029304bc35fa0a2ae1caeff8de74a69 --- got/got.c +++ got/got.c @@ -1544,7 +1544,7 @@ cmd_clone(int argc, char *argv[]) else usage_clone(); - error = got_fetch_parse_uri(&proto, &host, &port, &server_path, + error = got_dial_parse_uri(&proto, &host, &port, &server_path, &repo_name, uri); if (error) goto done; @@ -2379,7 +2379,7 @@ cmd_fetch(int argc, char *argv[]) } } - error = got_fetch_parse_uri(&proto, &host, &port, &server_path, + error = got_dial_parse_uri(&proto, &host, &port, &server_path, &repo_name, remote->fetch_url); if (error) goto done; @@ -7694,7 +7694,7 @@ cmd_send(int argc, char *argv[]) goto done; } - error = got_fetch_parse_uri(&proto, &host, &port, &server_path, + error = got_dial_parse_uri(&proto, &host, &port, &server_path, &repo_name, remote->send_url); if (error) goto done; blob - b213aadb14e213dfe28a280f089b6efff3e384f8 blob + 2a50bd2101d46a788ed418f19afeafc8958b08d1 --- include/got_dial.h +++ include/got_dial.h @@ -15,3 +15,5 @@ */ const struct got_error *got_dial_apply_unveil(const char *proto); +const struct got_error *got_dial_parse_uri(char **proto, char **host, + char **port, char **server_path, char **repo_name, const char *uri); blob - 43fd6d170ab25f2d04f322214d7b0ee370c4d9f5 blob + 1220c48e7f2ace97395c12e5a3af43b9c0bdc410 --- lib/dial.c +++ lib/dial.c @@ -15,6 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include @@ -26,6 +27,7 @@ #include #include "got_error.h" +#include "got_path.h" #include "got_lib_dial.h" @@ -58,7 +60,133 @@ got_dial_apply_unveil(const char *proto) return NULL; } +static int +hassuffix(char *base, char *suf) +{ + int nb, ns; + + nb = strlen(base); + ns = strlen(suf); + if (ns <= nb && strcmp(base + (nb - ns), suf) == 0) + return 1; + return 0; +} + const struct got_error * +got_dial_parse_uri(char **proto, char **host, char **port, + char **server_path, char **repo_name, const char *uri) +{ + const struct got_error *err = NULL; + char *s, *p, *q; + int n; + + *proto = *host = *port = *server_path = *repo_name = NULL; + + p = strstr(uri, "://"); + if (!p) { + /* Try parsing Git's "scp" style URL syntax. */ + *proto = strdup("ssh"); + if (proto == 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; + } + p = q + 1; + } else { + *proto = strndup(uri, p - uri); + if (proto == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + 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; + } + } + } + + while (p[0] == '/' && p[1] == '/') + p++; + *server_path = strdup(p); + if (*server_path == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } + got_path_strip_trailing_slashes(*server_path); + + 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); + if (*repo_name == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } +done: + if (err) { + free(*proto); + *proto = NULL; + free(*host); + *host = NULL; + free(*port); + *port = NULL; + free(*server_path); + *server_path = NULL; + free(*repo_name); + *repo_name = NULL; + } + return err; +} + +const struct got_error * got_dial_ssh(pid_t *newpid, int *newfd, const char *host, const char *port, const char *path, const char *direction, int verbosity) { blob - 6392c7ed06f631433155ab4dbd754e9d3ad6f32c blob + 5206b456ca799c99ae1e3454f99d30f377a63361 --- lib/fetch.c +++ lib/fetch.c @@ -75,18 +75,6 @@ #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) #endif -static int -hassuffix(char *base, char *suf) -{ - int nb, ns; - - nb = strlen(base); - ns = strlen(suf); - if (ns <= nb && strcmp(base + (nb - ns), suf) == 0) - return 1; - return 0; -} - const struct got_error * got_fetch_connect(pid_t *fetchpid, int *fetchfd, const char *proto, const char *host, const char *port, const char *server_path, int verbosity) @@ -106,120 +94,6 @@ got_fetch_connect(pid_t *fetchpid, int *fetchfd, const err = got_error_path(proto, GOT_ERR_NOT_IMPL); else err = got_error_path(proto, GOT_ERR_BAD_PROTO); - return err; -} - -const struct got_error * -got_fetch_parse_uri(char **proto, char **host, char **port, - char **server_path, char **repo_name, const char *uri) -{ - const struct got_error *err = NULL; - char *s, *p, *q; - int n; - - *proto = *host = *port = *server_path = *repo_name = NULL; - - p = strstr(uri, "://"); - if (!p) { - /* Try parsing Git's "scp" style URL syntax. */ - *proto = strdup("ssh"); - if (proto == 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; - } - p = q + 1; - } else { - *proto = strndup(uri, p - uri); - if (proto == NULL) { - err = got_error_from_errno("strndup"); - goto done; - } - 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; - } - } - } - - while (p[0] == '/' && p[1] == '/') - p++; - *server_path = strdup(p); - if (*server_path == NULL) { - err = got_error_from_errno("strdup"); - goto done; - } - got_path_strip_trailing_slashes(*server_path); - - 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); - if (*repo_name == NULL) { - err = got_error_from_errno("strndup"); - goto done; - } -done: - if (err) { - free(*proto); - *proto = NULL; - free(*host); - *host = NULL; - free(*port); - *port = NULL; - free(*server_path); - *server_path = NULL; - free(*repo_name); - *repo_name = NULL; - } return err; }