forked from Bananymous/banan-os
LibC: Implement gethostbyname()
This is not a POSIX function, but curl seems to depend on it. It is even deprecated on linux...
This commit is contained in:
parent
b98bb9eb27
commit
78bcb85679
|
@ -10,6 +10,7 @@ set(LIBC_SOURCES
|
|||
fcntl.cpp
|
||||
grp.cpp
|
||||
malloc.cpp
|
||||
netdb.cpp
|
||||
printf_impl.cpp
|
||||
pwd.cpp
|
||||
scanf_impl.cpp
|
||||
|
|
|
@ -90,6 +90,7 @@ void endservent(void);
|
|||
void freeaddrinfo(struct addrinfo* ai);
|
||||
const char* gai_strerror(int ecode);
|
||||
int getaddrinfo(const char* __restrict nodename, const char* __restrict servname, const struct addrinfo* __restrict hints, struct addrinfo** __restrict res);
|
||||
struct hostent* gethostbyname(const char* name);
|
||||
struct hostent* gethostent(void);
|
||||
int getnameinfo(const struct sockaddr* __restrict sa, socklen_t salen, char* __restrict node, socklen_t nodelen, char* __restrict service, socklen_t servicelen, int flags);
|
||||
struct netent* getnetbyaddr(uint32_t net, int type);
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
#include <BAN/Bitcast.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct hostent* gethostbyname(const char* name)
|
||||
{
|
||||
static char name_buffer[HOST_NAME_MAX + 1];
|
||||
static in_addr_t addr_buffer;
|
||||
static in_addr_t* addr_ptrs[2];
|
||||
static struct hostent hostent;
|
||||
|
||||
if (strlen(name) > HOST_NAME_MAX)
|
||||
return nullptr;
|
||||
strcpy(name_buffer, name);
|
||||
hostent.h_name = name_buffer;
|
||||
|
||||
hostent.h_aliases = nullptr;
|
||||
|
||||
hostent.h_addrtype = AF_INET;
|
||||
hostent.h_length = sizeof(in_addr_t);
|
||||
|
||||
addr_ptrs[0] = &addr_buffer;
|
||||
addr_ptrs[1] = nullptr;
|
||||
hostent.h_addr_list = reinterpret_cast<char**>(addr_ptrs);
|
||||
|
||||
int socket = -1;
|
||||
|
||||
if (in_addr_t ipv4 = inet_addr(name); ipv4 != (in_addr_t)(-1))
|
||||
addr_buffer = ipv4;
|
||||
else
|
||||
{
|
||||
int socket = ::socket(AF_UNIX, SOCK_SEQPACKET, 0);
|
||||
if (socket == -1)
|
||||
return nullptr;
|
||||
|
||||
sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, "/tmp/resolver.sock");
|
||||
if (connect(socket, (sockaddr*)&addr, sizeof(addr)) == -1)
|
||||
goto error_close_socket;
|
||||
|
||||
if (send(socket, name, strlen(name), 0) == -1)
|
||||
goto error_close_socket;
|
||||
|
||||
sockaddr_storage storage;
|
||||
if (recv(socket, &storage, sizeof(storage), 0) == -1)
|
||||
goto error_close_socket;
|
||||
|
||||
close(socket);
|
||||
|
||||
if (storage.ss_family != AF_INET)
|
||||
return nullptr;
|
||||
|
||||
addr_buffer = *reinterpret_cast<in_addr_t*>(storage.ss_storage);
|
||||
}
|
||||
|
||||
return &hostent;
|
||||
|
||||
error_close_socket:
|
||||
close(socket);
|
||||
return nullptr;
|
||||
}
|
Loading…
Reference in New Issue