commit 20eb36d0c1c6656066cb9febb9e6988c1eac5c2a from: Stefan Sperling date: Wed Mar 18 16:11:27 2020 UTC attempt to connect to a server before creating a local repo commit - 66cba96f002a13482c34efaaf5ace08a33f45ec4 commit + 20eb36d0c1c6656066cb9febb9e6988c1eac5c2a blob - c3c32e39f4990b11e465475f5888368aaaac553f blob + 14911d3169374e71dc20c2e4255fbe01f188b729 --- got/got.c +++ got/got.c @@ -980,7 +980,7 @@ cmd_clone(int argc, char *argv[]) struct got_pathlist_head refs, symrefs; struct got_pathlist_entry *pe; struct got_object_id *pack_hash = NULL; - int ch; + int ch, fetchfd = -1; TAILQ_INIT(&refs); TAILQ_INIT(&symrefs); @@ -1007,6 +1007,10 @@ cmd_clone(int argc, char *argv[]) err = got_fetch_parse_uri(&proto, &host, &port, &server_path, &repo_name, argv[0]); + if (err) + goto done; + + err = got_fetch_connect(&fetchfd, proto, host, port, server_path); if (err) goto done; @@ -1031,7 +1035,7 @@ cmd_clone(int argc, char *argv[]) if (err) goto done; - err = got_fetch(&pack_hash, &refs, &symrefs, + err = got_fetch(&pack_hash, &refs, &symrefs, fetchfd, proto, host, port, server_path, repo_name, branch_filter, repo); if (err) goto done; @@ -1096,6 +1100,8 @@ cmd_clone(int argc, char *argv[]) } done: + if (fetchfd != -1 && close(fetchfd) == -1 && err == NULL) + err = got_error_from_errno("close"); if (repo) got_repo_close(repo); TAILQ_FOREACH(pe, &refs, entry) { blob - 7b366507306fb9ce4b3c3a9d29e4d2b1044d2f19 blob + 600d8380690a460eb5dc3bc7b0bf1af363c1aaa5 --- include/got_fetch.h +++ include/got_fetch.h @@ -21,7 +21,10 @@ const struct got_error *got_fetch_parse_uri(char **, char **, char **, char **, char **, const char *); +const struct got_error *got_fetch_connect(int *, const char *, const char *, + const char *, const char *); + const struct got_error *got_fetch(struct got_object_id **, - struct got_pathlist_head *, struct got_pathlist_head *, + struct got_pathlist_head *, struct got_pathlist_head *, int, const char *, const char *, const char *, const char *, const char *, const char *, struct got_repository *); blob - 93751d15f248e33311d9591c8be94427dd8279f6 blob + 617c092b660b823d34b1543c2e24debb60a4f138 --- lib/fetch.c +++ lib/fetch.c @@ -179,6 +179,25 @@ done: close(fd); } else *fetchfd = fd; + return err; +} + +const struct got_error * +got_fetch_connect(int *fetchfd, const char *proto, const char *host, + const char *port, const char *server_path) +{ + const struct got_error *err = NULL; + + *fetchfd = -1; + + if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0) + err = dial_ssh(fetchfd, host, port, server_path, "upload"); + else if (strcmp(proto, "git") == 0) + err = dial_git(fetchfd, host, port, server_path, "upload"); + else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0) + err = got_error_path(proto, GOT_ERR_NOT_IMPL); + else + err = got_error_path(proto, GOT_ERR_BAD_PROTO); return err; } @@ -280,12 +299,12 @@ done: const struct got_error* got_fetch(struct got_object_id **pack_hash, struct got_pathlist_head *refs, - struct got_pathlist_head *symrefs, const char *proto, const char *host, - const char *port, const char *server_path, const char *repo_name, - const char *branch_filter, struct got_repository *repo) + struct got_pathlist_head *symrefs, int fetchfd, const char *proto, + const char *host, const char *port, const char *server_path, + const char *repo_name, const char *branch_filter, struct got_repository *repo) { - int imsg_fetchfds[2], imsg_idxfds[2], fetchfd = -1; - int packfd = -1, npackfd = -1, idxfd = -1, nidxfd = -1; + int imsg_fetchfds[2], imsg_idxfds[2]; + int packfd = -1, npackfd = -1, idxfd = -1, nidxfd = -1, nfetchfd = -1; int status, done = 0; const struct got_error *err; struct imsgbuf ibuf; @@ -298,8 +317,6 @@ got_fetch(struct got_object_id **pack_hash, struct got *pack_hash = NULL; - fetchfd = -1; - if (asprintf(&path, "%s/%s/fetching.pack", repo_path, GOT_OBJECTS_PACK_DIR) == -1) { err = got_error_from_errno("asprintf"); @@ -329,17 +346,6 @@ got_fetch(struct got_object_id **pack_hash, struct got goto done; } - if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0) - err = dial_ssh(&fetchfd, host, port, server_path, "upload"); - else if (strcmp(proto, "git") == 0) - err = dial_git(&fetchfd, host, port, server_path, "upload"); - else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0) - err = got_error(GOT_ERR_BAD_PROTO); - else - err = got_error(GOT_ERR_BAD_PROTO); - if (err) - goto done; - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, imsg_fetchfds) == -1) { err = got_error_from_errno("socketpair"); goto done; @@ -359,10 +365,15 @@ got_fetch(struct got_object_id **pack_hash, struct got goto done; } imsg_init(&ibuf, imsg_fetchfds[0]); - err = got_privsep_send_fetch_req(&ibuf, fetchfd); + nfetchfd = dup(fetchfd); + if (nfetchfd == -1) { + err = got_error_from_errno("dup"); + goto done; + } + err = got_privsep_send_fetch_req(&ibuf, nfetchfd); if (err != NULL) goto done; - fetchfd = -1; + nfetchfd = -1; err = got_privsep_send_tmpfd(&ibuf, npackfd); if (err != NULL) goto done; @@ -457,7 +468,7 @@ got_fetch(struct got_object_id **pack_hash, struct got } done: - if (fetchfd != -1 && close(fetchfd) == -1 && err == NULL) + if (nfetchfd != -1 && close(nfetchfd) == -1 && err == NULL) err = got_error_from_errno("close"); if (npackfd != -1 && close(npackfd) == -1 && err == NULL) err = got_error_from_errno("close");