Add getservbyname and getservbyport (#204)

For every call of getservbyname/getservbyport the lookup of
/etc/services is done by opening the file and parsing each line
one-by-one. This is slow, but the implementation is simple.

This change also adds fixes for the gethostbyname function.
This commit is contained in:
Gautham 2021-07-05 05:01:42 +05:30 committed by GitHub
parent cfbd2afc19
commit 0ea2907730
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 412 additions and 25 deletions

View file

@ -27,26 +27,28 @@
*/
#include "libc/dns/ent.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/af.h"
struct hostent *gethostbyname(const char *name) {
static struct hostent *ptr0, he0;
static char h_name[DNS_NAME_MAX + 1];
static char *h_aliases[1];
static char *h_addr_list[2];
static char h_addr_list0[4];
struct addrinfo *result = NULL;
if (!ptr0) {
he0.h_name = NULL;
he0.h_name = h_name;
he0.h_aliases = (char **)malloc(sizeof(char *) * 1);
if (!he0.h_aliases) return NULL;
he0.h_aliases = h_aliases;
he0.h_aliases[0] = NULL;
he0.h_addrtype = AF_INET;
he0.h_length = 4;
he0.h_addr_list = (char **)malloc(sizeof(char *) * 2);
if (!he0.h_addr_list) return NULL;
he0.h_addr_list = h_addr_list;
he0.h_addr_list[0] = (char *)malloc(sizeof(uint32_t));
if (!he0.h_addr_list[0]) return NULL;
he0.h_addr_list[0] = h_addr_list0;
he0.h_addr_list[1] = NULL;
ptr0 = &he0;
@ -54,12 +56,12 @@ struct hostent *gethostbyname(const char *name) {
if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) return NULL;
if (ptr0->h_name) free(ptr0->h_name);
if (result->ai_canonname) {
ptr0->h_name = strdup(result->ai_canonname);
} else {
ptr0->h_name = strdup(name);
}
/* if getaddrinfo is successful, result->ai_canonname is non-NULL,
* (see newaddrinfo) but the string can still be empty */
if (result->ai_canonname[0])
memccpy(ptr0->h_name, result->ai_canonname, '\0', DNS_NAME_MAX);
else
memccpy(ptr0->h_name, name, '\0', DNS_NAME_MAX);
*((uint32_t *)ptr0->h_addr_list[0]) = (result->ai_addr4->sin_addr.s_addr);
/* TODO: if result has ai_next, fit multiple entries for h_addr_list */