X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/a3a841073e6e3d5a560c072c8bc7bbd770740235..d8d36af4521e77ed284f7be91f95d53d972914b4:/socket.c diff --git a/socket.c b/socket.c index fc01edf9..93f05a98 100644 --- a/socket.c +++ b/socket.c @@ -48,11 +48,11 @@ static int establish_proxy_connection(int fd, char *host, int port, int len; if (proxy_user && proxy_pass) { - snprintf(buffer, sizeof buffer, "%s:%s", - proxy_user, proxy_pass); + stringjoin(buffer, sizeof buffer, + proxy_user, ":", proxy_pass, NULL); len = strlen(buffer); - if ((len*8 + 5) / 6 - 2 >= (int)sizeof authbuf) { + if ((len*8 + 5) / 6 >= (int)sizeof authbuf) { rprintf(FERROR, "authentication information is too long\n"); return -1; @@ -299,9 +299,14 @@ int open_socket_out(char *host, int port, const char *bind_address, int open_socket_out_wrapped(char *host, int port, const char *bind_address, int af_hint) { - char *prog; + char *prog = getenv("RSYNC_CONNECT_PROG"); - if ((prog = getenv("RSYNC_CONNECT_PROG")) != NULL) + if (verbose >= 2) { + rprintf(FINFO, "%sopening tcp connection to %s port %d\n", + prog ? "Using RSYNC_CONNECT_PROG instead of " : "", + host, port); + } + if (prog) return sock_exec(prog); return open_socket_out(host, port, bind_address, af_hint); } @@ -313,15 +318,11 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_address, * * Try to be better about handling the results of getaddrinfo(): when * opening an inbound socket, we might get several address results, - * e.g. for the machine's ipv4 and ipv6 name. - * - * If binding a wildcard, then any one of them should do. If an address - * was specified but it's insufficiently specific then that's not our - * fault. + * e.g. for the machine's IPv4 and IPv6 name. * - * However, some of the advertized addresses may not work because e.g. we - * don't have IPv6 support in the kernel. In that case go on and try all - * addresses until one succeeds. + * We return an array of socket file-descriptors, with the length of + * the array stored as the first element of the list. This allows + * the caller to listen on all of them. * * @param bind_address Local address to bind, or NULL to allow it to * default. @@ -374,8 +375,11 @@ static int *open_socket_in(int type, int port, const char *bind_address, #ifdef IPV6_V6ONLY if (resp->ai_family == AF_INET6) { - setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, - (char *)&one, sizeof one); + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, + (char *)&one, sizeof one) < 0) { + close(s); + continue; + } } #endif @@ -431,17 +435,17 @@ int is_a_socket(int fd) static RETSIGTYPE sigchld_handler(UNUSED(int val)) { - signal(SIGCHLD, sigchld_handler); #ifdef WNOHANG while (waitpid(-1, NULL, WNOHANG) > 0) {} #endif + signal(SIGCHLD, sigchld_handler); } void start_accept_loop(int port, int (*fn)(int, int)) { fd_set deffds; - int *sp, maxfd, i, j; + int *sp, maxfd, i; extern char *bind_address; extern int default_af_hint; @@ -455,9 +459,6 @@ void start_accept_loop(int port, int (*fn)(int, int)) maxfd = -1; for (i = 1; i <= *sp; i++) { if (listen(sp[i], 5) == -1) { - for (j = 1; j <= i; j++) - close(sp[j]); - free(sp); exit_cleanup(RERR_SOCKETIO); } FD_SET(sp[i], &deffds); @@ -698,7 +699,7 @@ static int socketpair_tcp(int fd[2]) goto failed; memset(&sock2, 0, sizeof sock2); -#ifdef HAVE_SOCKADDR_LEN +#if HAVE_SOCKADDR_IN_LEN sock2.sin_len = sizeof sock2; #endif sock2.sin_family = PF_INET; @@ -769,18 +770,14 @@ int sock_exec(const char *prog) strerror(errno)); return -1; } + if (verbose >= 2) + rprintf(FINFO, "Running socket program: \"%s\"\n", prog); if (fork() == 0) { close(fd[0]); close(0); close(1); dup(fd[1]); dup(fd[1]); - if (verbose > 3) { - /* Can't use rprintf because we've forked. */ - fprintf(stderr, - RSYNC_NAME ": execute socket program \"%s\"\n", - prog); - } exit(system(prog)); } close(fd[1]);