diff options
Diffstat (limited to 'libbb/xconnect.c')
-rw-r--r-- | libbb/xconnect.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 27c7424..f313655 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -32,6 +32,24 @@ int FAST_FUNC setsockopt_bindtodevice(int fd, const char *iface) return r; } +len_and_sockaddr* FAST_FUNC get_sock_lsa(int fd) +{ + len_and_sockaddr lsa; + len_and_sockaddr *lsa_ptr; + + lsa.len = LSA_SIZEOF_SA; + if (getsockname(fd, &lsa.u.sa, &lsa.len) != 0) + return NULL; + + lsa_ptr = xzalloc(LSA_LEN_SIZE + lsa.len); + if (lsa.len > LSA_SIZEOF_SA) { /* rarely (if ever) happens */ + lsa_ptr->len = lsa.len; + getsockname(fd, &lsa_ptr->u.sa, &lsa_ptr->len); + } else { + memcpy(lsa_ptr, &lsa, LSA_LEN_SIZE + lsa.len); + } + return lsa_ptr; +} void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) { @@ -46,6 +64,26 @@ void FAST_FUNC xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) } } +void FAST_FUNC xrconnect(int s, + const struct sockaddr *s_addr, socklen_t addrlen, + void (*reportf)(int err)) +{ + if (connect(s, s_addr, addrlen) < 0) { + if (reportf) { + int t_errno= errno; + reportf(t_errno); + errno= t_errno; + } + if (ENABLE_FEATURE_CLEAN_UP) + close(s); + if (s_addr->sa_family == AF_INET) + bb_perror_msg_and_die("%s (%s)", + "cannot connect to remote host", + inet_ntoa(((struct sockaddr_in *)s_addr)->sin_addr)); + bb_perror_msg_and_die("cannot connect to remote host"); + } +} + /* Return port number for a service. * If "port" is a number use it as the port. * If "port" is a name it is looked up in /etc/services, if it isnt found return |