efd4983eb1
- Applied Joel Coltoff's xconnect patch: On both my host system and with mipsel-linux for my embedded systems the function getservbyname() gives the port number already in host order. In fact, this is how it was used by rdate in version 0.60.3. The snapshot I have of the development tree from July 12, 2002 takes the port number and stuffs it into htons() before it uses it. This causes bugs in rdate, telnet and wget. This patch fixes that.
80 lines
1.7 KiB
C
80 lines
1.7 KiB
C
/* vi: set sw=4 ts=4: */
|
|
/*
|
|
* Utility routines.
|
|
*
|
|
* Connect to host at port using address resolusion from getaddrinfo
|
|
*
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include "libbb.h"
|
|
|
|
int xconnect(const char *host, const char *port)
|
|
{
|
|
#if CONFIG_FEATURE_IPV6
|
|
struct addrinfo hints;
|
|
struct addrinfo *res;
|
|
struct addrinfo *addr_info;
|
|
int error;
|
|
int s;
|
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
/* set-up hints structure */
|
|
hints.ai_family = PF_UNSPEC;
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
error = getaddrinfo(host, port, &hints, &res);
|
|
if (error||!res)
|
|
perror_msg_and_die(gai_strerror(error));
|
|
addr_info=res;
|
|
while (res) {
|
|
s=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
|
if (s<0)
|
|
{
|
|
error=s;
|
|
res=res->ai_next;
|
|
continue;
|
|
}
|
|
/* try to connect() to res->ai_addr */
|
|
error = connect(s, res->ai_addr, res->ai_addrlen);
|
|
if (error >= 0)
|
|
break;
|
|
close(s);
|
|
res=res->ai_next;
|
|
}
|
|
freeaddrinfo(addr_info);
|
|
if (error < 0)
|
|
{
|
|
perror_msg_and_die("Unable to connect to remote host (%s)", host);
|
|
}
|
|
return s;
|
|
#else
|
|
struct sockaddr_in s_addr;
|
|
int s = socket(AF_INET, SOCK_STREAM, 0);
|
|
struct servent *tserv;
|
|
int port_nr=htons(atoi(port));
|
|
struct hostent * he;
|
|
|
|
if (port_nr==0 && (tserv = getservbyname(port, "tcp")) != NULL)
|
|
port_nr = tserv->s_port;
|
|
|
|
memset(&s_addr, 0, sizeof(struct sockaddr_in));
|
|
s_addr.sin_family = AF_INET;
|
|
s_addr.sin_port = port_nr;
|
|
|
|
he = xgethostbyname(host);
|
|
memcpy(&s_addr.sin_addr, he->h_addr, sizeof s_addr.sin_addr);
|
|
|
|
if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
|
|
{
|
|
perror_msg_and_die("Unable to connect to remote host (%s)", host);
|
|
}
|
|
return s;
|
|
#endif
|
|
}
|