commit d65a88a2f0db40d2c2ac34ee34e8aff8ac629d52 from: Stefan Sperling date: Sun Sep 05 20:19:14 2021 UTC move duplicated dial_ssh() and dial_git() functions into a common file These functions are used by 'got send' and 'got fetch' in order to open network connections to a server. Move them into new file lib/dial.c and declare relevant functions in got_dial.h and lib/got_lib_dial.h. No functional change. commit - abc59930d57a2d46c310e1b0c758c948554bc1af commit + d65a88a2f0db40d2c2ac34ee34e8aff8ac629d52 blob - 14f769b331dbbbc7a4e4a948191670b97122457d blob + a53d25848b09acd89ddfa729b2104f4145517095 --- got/Makefile +++ got/Makefile @@ -12,7 +12,7 @@ SRCS= got.c blame.c commit_graph.c delta.c diff.c \ gotconfig.c diff_main.c diff_atomize_text.c \ diff_myers.c diff_output.c diff_output_plain.c \ diff_output_unidiff.c diff_output_edscript.c \ - diff_patience.c send.c deltify.c pack_create.c + diff_patience.c send.c deltify.c pack_create.c dial.c MAN = ${PROG}.1 got-worktree.5 git-repository.5 got.conf.5 blob - e7638e1bfc66827e100c0706e810805be3fa972e blob + a907f12b2708cbb1ea36221531d27fbd95446daf --- got/got.c +++ got/got.c @@ -55,6 +55,7 @@ #include "got_privsep.h" #include "got_opentemp.h" #include "got_gotconfig.h" +#include "got_dial.h" #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) @@ -1598,13 +1599,10 @@ cmd_clone(int argc, char *argv[]) } } - if (strcmp(proto, "git+ssh") == 0 || strcmp(proto, "ssh") == 0) { - if (unveil(GOT_FETCH_PATH_SSH, "x") != 0) { - error = got_error_from_errno2("unveil", - GOT_FETCH_PATH_SSH); - goto done; - } - } + error = got_dial_apply_unveil(proto); + if (error) + goto done; + error = apply_unveil(repo_path, 0, NULL); if (error) goto done; @@ -2408,13 +2406,10 @@ cmd_fetch(int argc, char *argv[]) goto done; } - if (strcmp(proto, "git+ssh") == 0 || strcmp(proto, "ssh") == 0) { - if (unveil(GOT_FETCH_PATH_SSH, "x") != 0) { - error = got_error_from_errno2("unveil", - GOT_FETCH_PATH_SSH); - goto done; - } - } + error = got_dial_apply_unveil(proto); + if (error) + goto done; + error = apply_unveil(got_repo_get_path(repo), 0, NULL); if (error) goto done; @@ -7726,13 +7721,10 @@ cmd_send(int argc, char *argv[]) goto done; } - if (strcmp(proto, "git+ssh") == 0 || strcmp(proto, "ssh") == 0) { - if (unveil(GOT_FETCH_PATH_SSH, "x") != 0) { - error = got_error_from_errno2("unveil", - GOT_FETCH_PATH_SSH); - goto done; - } - } + error = got_dial_apply_unveil(proto); + if (error) + goto done; + error = apply_unveil(got_repo_get_path(repo), 0, NULL); if (error) goto done; blob - /dev/null blob + b213aadb14e213dfe28a280f089b6efff3e384f8 (mode 644) --- /dev/null +++ include/got_dial.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2021 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +const struct got_error *got_dial_apply_unveil(const char *proto); blob - ec4d2dc496a45f2a0804737eeb32ad4991f4c8ba blob + 0678325a656296d677ef121766f0c17a0ea3c6cf --- include/got_fetch.h +++ include/got_fetch.h @@ -14,14 +14,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* IANA assigned */ -#define GOT_DEFAULT_GIT_PORT 9418 -#define GOT_DEFAULT_GIT_PORT_STR "9418" - -#ifndef GOT_FETCH_PATH_SSH -#define GOT_FETCH_PATH_SSH "/usr/bin/ssh" -#endif - #define GOT_FETCH_DEFAULT_REMOTE_NAME "origin" #define GOT_FETCH_PKTMAX 65536 blob - 2f0388ea400f048c63027a0b901c892f672248bc blob + a805a93b43a7bd5f89c592a6da5982f41dd96ae6 --- include/got_send.h +++ include/got_send.h @@ -15,14 +15,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* IANA assigned */ -#define GOT_DEFAULT_GIT_PORT 9418 -#define GOT_DEFAULT_GIT_PORT_STR "9418" - -#ifndef GOT_SEND_PATH_SSH -#define GOT_SEND_PATH_SSH "/usr/bin/ssh" -#endif - #define GOT_SEND_DEFAULT_REMOTE_NAME "origin" #define GOT_SEND_PKTMAX 65536 blob - /dev/null blob + 43fd6d170ab25f2d04f322214d7b0ee370c4d9f5 (mode 644) --- /dev/null +++ lib/dial.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2018, 2019 Ori Bernstein + * Copyright (c) 2021 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "got_error.h" + +#include "got_lib_dial.h" + +#ifndef ssizeof +#define ssizeof(_x) ((ssize_t)(sizeof(_x))) +#endif + +#ifndef MIN +#define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) +#endif + +#ifndef GOT_DIAL_PATH_SSH +#define GOT_DIAL_PATH_SSH "/usr/bin/ssh" +#endif + +/* IANA assigned */ +#define GOT_DEFAULT_GIT_PORT 9418 +#define GOT_DEFAULT_GIT_PORT_STR "9418" + +const struct got_error * +got_dial_apply_unveil(const char *proto) +{ + if (strcmp(proto, "git+ssh") == 0 || strcmp(proto, "ssh") == 0) { + if (unveil(GOT_DIAL_PATH_SSH, "x") != 0) { + return got_error_from_errno2("unveil", + GOT_DIAL_PATH_SSH); + } + } + + return NULL; +} + +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) +{ + const struct got_error *error = NULL; + int pid, pfd[2]; + char cmd[64]; + char *argv[11]; + int i = 0, j; + + *newpid = -1; + *newfd = -1; + + argv[i++] = GOT_DIAL_PATH_SSH; + if (port != NULL) { + argv[i++] = "-p"; + argv[i++] = (char *)port; + } + if (verbosity == -1) { + argv[i++] = "-q"; + } else { + /* ssh(1) allows up to 3 "-v" options. */ + for (j = 0; j < MIN(3, verbosity); j++) + argv[i++] = "-v"; + } + argv[i++] = "--"; + argv[i++] = (char *)host; + argv[i++] = (char *)cmd; + argv[i++] = (char *)path; + argv[i++] = NULL; + + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pfd) == -1) + return got_error_from_errno("socketpair"); + + pid = fork(); + if (pid == -1) { + error = got_error_from_errno("fork"); + close(pfd[0]); + close(pfd[1]); + return error; + } else if (pid == 0) { + int n; + if (close(pfd[1]) == -1) + err(1, "close"); + if (dup2(pfd[0], 0) == -1) + err(1, "dup2"); + if (dup2(pfd[0], 1) == -1) + err(1, "dup2"); + n = snprintf(cmd, sizeof(cmd), "git-%s-pack", direction); + if (n < 0 || n >= ssizeof(cmd)) + err(1, "snprintf"); + if (execv(GOT_DIAL_PATH_SSH, argv) == -1) + err(1, "execv"); + abort(); /* not reached */ + } else { + if (close(pfd[0]) == -1) + return got_error_from_errno("close"); + *newpid = pid; + *newfd = pfd[1]; + return NULL; + } +} + +const struct got_error * +got_dial_git(int *newfd, const char *host, const char *port, + const char *path, const char *direction) +{ + const struct got_error *err = NULL; + struct addrinfo hints, *servinfo, *p; + char *cmd = NULL; + int fd = -1, len, r, eaicode; + + *newfd = -1; + + if (port == NULL) + port = GOT_DEFAULT_GIT_PORT_STR; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + eaicode = getaddrinfo(host, port, &hints, &servinfo); + if (eaicode) { + char msg[512]; + snprintf(msg, sizeof(msg), "%s: %s", host, + gai_strerror(eaicode)); + return got_error_msg(GOT_ERR_ADDRINFO, msg); + } + + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((fd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) + continue; + if (connect(fd, p->ai_addr, p->ai_addrlen) == 0) { + err = NULL; + break; + } + err = got_error_from_errno("connect"); + close(fd); + } + if (p == NULL) + goto done; + + if (asprintf(&cmd, "git-%s-pack %s", direction, path) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + len = 4 + strlen(cmd) + 1 + strlen("host=") + strlen(host) + 1; + r = dprintf(fd, "%04x%s%chost=%s%c", len, cmd, '\0', host, '\0'); + if (r < 0) + err = got_error_from_errno("dprintf"); +done: + free(cmd); + if (err) { + if (fd != -1) + close(fd); + } else + *newfd = fd; + return err; +} blob - 798e728b740269a24d6c9570992490578f0ce78c blob + 58ebe83cb10ef337c7ed983de51d61cc5f631253 --- lib/fetch.c +++ lib/fetch.c @@ -39,8 +39,6 @@ #include #include #include -#include -#include #include "got_error.h" #include "got_reference.h" @@ -62,6 +60,7 @@ #include "got_lib_privsep.h" #include "got_lib_object_cache.h" #include "got_lib_repository.h" +#include "got_lib_dial.h" #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) @@ -85,126 +84,6 @@ hassuffix(char *base, char *suf) if (ns <= nb && strcmp(base + (nb - ns), suf) == 0) return 1; return 0; -} - -static const struct got_error * -dial_ssh(pid_t *fetchpid, int *fetchfd, const char *host, const char *port, - const char *path, const char *direction, int verbosity) -{ - const struct got_error *error = NULL; - int pid, pfd[2]; - char cmd[64]; - char *argv[11]; - int i = 0, j; - - *fetchpid = -1; - *fetchfd = -1; - - argv[i++] = GOT_FETCH_PATH_SSH; - if (port != NULL) { - argv[i++] = "-p"; - argv[i++] = (char *)port; - } - if (verbosity == -1) { - argv[i++] = "-q"; - } else { - /* ssh(1) allows up to 3 "-v" options. */ - for (j = 0; j < MIN(3, verbosity); j++) - argv[i++] = "-v"; - } - argv[i++] = "--"; - argv[i++] = (char *)host; - argv[i++] = (char *)cmd; - argv[i++] = (char *)path; - argv[i++] = NULL; - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pfd) == -1) - return got_error_from_errno("socketpair"); - - pid = fork(); - if (pid == -1) { - error = got_error_from_errno("fork"); - close(pfd[0]); - close(pfd[1]); - return error; - } else if (pid == 0) { - int n; - if (close(pfd[1]) == -1) - err(1, "close"); - if (dup2(pfd[0], 0) == -1) - err(1, "dup2"); - if (dup2(pfd[0], 1) == -1) - err(1, "dup2"); - n = snprintf(cmd, sizeof(cmd), "git-%s-pack", direction); - if (n < 0 || n >= ssizeof(cmd)) - err(1, "snprintf"); - if (execv(GOT_FETCH_PATH_SSH, argv) == -1) - err(1, "execv"); - abort(); /* not reached */ - } else { - if (close(pfd[0]) == -1) - return got_error_from_errno("close"); - *fetchpid = pid; - *fetchfd = pfd[1]; - return NULL; - } -} - -static const struct got_error * -dial_git(int *fetchfd, const char *host, const char *port, const char *path, - const char *direction) -{ - const struct got_error *err = NULL; - struct addrinfo hints, *servinfo, *p; - char *cmd = NULL; - int fd = -1, len, r, eaicode; - - *fetchfd = -1; - - if (port == NULL) - port = GOT_DEFAULT_GIT_PORT_STR; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - eaicode = getaddrinfo(host, port, &hints, &servinfo); - if (eaicode) { - char msg[512]; - snprintf(msg, sizeof(msg), "%s: %s", host, - gai_strerror(eaicode)); - return got_error_msg(GOT_ERR_ADDRINFO, msg); - } - - for (p = servinfo; p != NULL; p = p->ai_next) { - if ((fd = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) - continue; - if (connect(fd, p->ai_addr, p->ai_addrlen) == 0) { - err = NULL; - break; - } - err = got_error_from_errno("connect"); - close(fd); - } - if (p == NULL) - goto done; - - if (asprintf(&cmd, "git-%s-pack %s", direction, path) == -1) { - err = got_error_from_errno("asprintf"); - goto done; - } - len = 4 + strlen(cmd) + 1 + strlen("host=") + strlen(host) + 1; - r = dprintf(fd, "%04x%s%chost=%s%c", len, cmd, '\0', host, '\0'); - if (r < 0) - err = got_error_from_errno("dprintf"); -done: - free(cmd); - if (err) { - if (fd != -1) - close(fd); - } else - *fetchfd = fd; - return err; } const struct got_error * @@ -217,10 +96,11 @@ got_fetch_connect(pid_t *fetchpid, int *fetchfd, const *fetchfd = -1; if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0) - err = dial_ssh(fetchpid, fetchfd, host, port, server_path, - "upload", verbosity); + err = got_dial_ssh(fetchpid, fetchfd, host, port, + server_path, GOT_DIAL_DIRECTION_FETCH, verbosity); else if (strcmp(proto, "git") == 0) - err = dial_git(fetchfd, host, port, server_path, "upload"); + err = got_dial_git(fetchfd, host, port, server_path, + GOT_DIAL_DIRECTION_FETCH); else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0) err = got_error_path(proto, GOT_ERR_NOT_IMPL); else blob - /dev/null blob + cbaf4ea224445b13ae795d7ec9ddb72fda40ab52 (mode 644) --- /dev/null +++ lib/got_lib_dial.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019 Ori Bernstein + * Copyright (c) 2021 Stefan Sperling + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define GOT_DIAL_DIRECTION_SEND "receive" +#define GOT_DIAL_DIRECTION_FETCH "upload" + +const struct got_error *got_dial_git(int *newfd, const char *host, + const char *port, const char *path, const char *direction); + +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 - 6c977a92f5e574ca78d050e9d534527d8b10d122 blob + 389638ce5e6ef123646ace201dde42a8e1706e20 --- lib/send.c +++ lib/send.c @@ -40,8 +40,6 @@ #include #include #include -#include -#include #include "got_error.h" #include "got_reference.h" @@ -66,6 +64,7 @@ #include "got_lib_object_cache.h" #include "got_lib_repository.h" #include "got_lib_pack_create.h" +#include "got_lib_dial.h" #ifndef nitems #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) @@ -78,127 +77,7 @@ #ifndef MIN #define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b)) #endif - -static const struct got_error * -dial_ssh(pid_t *sendpid, int *sendfd, const char *host, const char *port, - const char *path, const char *direction, int verbosity) -{ - const struct got_error *error = NULL; - int pid, pfd[2]; - char cmd[64]; - char *argv[11]; - int i = 0, j; - - *sendpid = -1; - *sendfd = -1; - - argv[i++] = GOT_SEND_PATH_SSH; - if (port != NULL) { - argv[i++] = "-p"; - argv[i++] = (char *)port; - } - if (verbosity == -1) { - argv[i++] = "-q"; - } else { - /* ssh(1) allows up to 3 "-v" options. */ - for (j = 0; j < MIN(3, verbosity); j++) - argv[i++] = "-v"; - } - argv[i++] = "--"; - argv[i++] = (char *)host; - argv[i++] = (char *)cmd; - argv[i++] = (char *)path; - argv[i++] = NULL; - - if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pfd) == -1) - return got_error_from_errno("socketpair"); - - pid = fork(); - if (pid == -1) { - error = got_error_from_errno("fork"); - close(pfd[0]); - close(pfd[1]); - return error; - } else if (pid == 0) { - int n; - if (close(pfd[1]) == -1) - err(1, "close"); - if (dup2(pfd[0], 0) == -1) - err(1, "dup2"); - if (dup2(pfd[0], 1) == -1) - err(1, "dup2"); - n = snprintf(cmd, sizeof(cmd), "git-%s-pack", direction); - if (n < 0 || n >= ssizeof(cmd)) - err(1, "snprintf"); - if (execv(GOT_SEND_PATH_SSH, argv) == -1) - err(1, "execv"); - abort(); /* not reached */ - } else { - if (close(pfd[0]) == -1) - return got_error_from_errno("close"); - *sendpid = pid; - *sendfd = pfd[1]; - return NULL; - } -} - -static const struct got_error * -dial_git(int *sendfd, const char *host, const char *port, const char *path, - const char *direction) -{ - const struct got_error *err = NULL; - struct addrinfo hints, *servinfo, *p; - char *cmd = NULL; - int fd = -1, len, r, eaicode; - *sendfd = -1; - - if (port == NULL) - port = GOT_DEFAULT_GIT_PORT_STR; - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - eaicode = getaddrinfo(host, port, &hints, &servinfo); - if (eaicode) { - char msg[512]; - snprintf(msg, sizeof(msg), "%s: %s", host, - gai_strerror(eaicode)); - return got_error_msg(GOT_ERR_ADDRINFO, msg); - } - - for (p = servinfo; p != NULL; p = p->ai_next) { - if ((fd = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) - continue; - if (connect(fd, p->ai_addr, p->ai_addrlen) == 0) { - err = NULL; - break; - } - err = got_error_from_errno("connect"); - close(fd); - } - if (p == NULL) - goto done; - - if (asprintf(&cmd, "git-%s-pack %s", direction, path) == -1) { - err = got_error_from_errno("asprintf"); - goto done; - } - len = 4 + strlen(cmd) + 1 + strlen("host=") + strlen(host) + 1; - r = dprintf(fd, "%04x%s%chost=%s%c", len, cmd, '\0', host, '\0'); - if (r < 0) - err = got_error_from_errno("dprintf"); -done: - free(cmd); - if (err) { - if (fd != -1) - close(fd); - } else - *sendfd = fd; - return err; -} - const struct got_error * got_send_connect(pid_t *sendpid, int *sendfd, const char *proto, const char *host, const char *port, const char *server_path, int verbosity) @@ -209,10 +88,11 @@ got_send_connect(pid_t *sendpid, int *sendfd, const ch *sendfd = -1; if (strcmp(proto, "ssh") == 0 || strcmp(proto, "git+ssh") == 0) - err = dial_ssh(sendpid, sendfd, host, port, server_path, - "receive", verbosity); + err = got_dial_ssh(sendpid, sendfd, host, port, server_path, + GOT_DIAL_DIRECTION_SEND, verbosity); else if (strcmp(proto, "git") == 0) - err = dial_git(sendfd, host, port, server_path, "receive"); + err = got_dial_git(sendfd, host, port, server_path, + GOT_DIAL_DIRECTION_SEND); else if (strcmp(proto, "http") == 0 || strcmp(proto, "git+http") == 0) err = got_error_path(proto, GOT_ERR_NOT_IMPL); else