aboutsummaryrefslogtreecommitdiff
path: root/libbb/xconnect.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/xconnect.c')
-rw-r--r--libbb/xconnect.c38
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