/* Extra slots needed for storing canonical name */
#define EXTRA ((256+sizeof(struct aibuf)-1)/sizeof(struct aibuf))
-int getaddrinfo(const char *host, const char *serv, const struct addrinfo *hint, struct addrinfo **res)
+int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
{
int flags = hint ? hint->ai_flags : 0;
int family = hint ? hint->ai_family : AF_UNSPEC;
union sa sa = {{0}};
unsigned char reply[1024];
int i, j;
- //char hostbuf[256];
char line[512];
FILE *f, _f;
- unsigned char _buf[64];
+ unsigned char _buf[1024];
char *z;
int result;
int cnt;
type = proto==IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
if (serv) {
- port = strtoul(serv, &z, 0);
- if (!*z && port > 65535) return EAI_SERVICE;
- if (!port) {
+ if (!*serv) return EAI_SERVICE;
+ port = strtoul(serv, &z, 10);
+ if (*z) {
+ size_t servlen = strlen(serv);
+ char *end = line;
+
if (flags & AI_NUMERICSERV) return EAI_SERVICE;
- //f = fopen("/etc/services", "rb");
- return EAI_SERVICE;
+ f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
+ if (!f) return EAI_SERVICE;
+ while (fgets(line, sizeof line, f)) {
+ if (strncmp(line, serv, servlen) || !isspace(line[servlen]))
+ continue;
+ port = strtoul(line+servlen, &end, 10);
+ if (strncmp(end, proto==IPPROTO_UDP ? "/udp" : "/tcp", 4))
+ continue;
+ break;
+ }
+ __fclose_ca(f);
+ if (feof(f)) return EAI_SERVICE;
}
+ if (port > 65535) return EAI_SERVICE;
port = htons(port);
}
return 0;
}
+ if (!*host) return EAI_NONAME;
+
/* Try as a numeric address */
if (__ipparse(&sa, family, host) >= 0) {
buf = calloc(sizeof *buf, 1+EXTRA);
buf->ai.ai_addr = (void *)&buf->sa;
buf->ai.ai_addrlen = family==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
buf->ai.ai_family = family;
+ buf->ai.ai_canonname = (char *)host;
buf->sa = sa;
buf->sa.sin.sin_port = port;
*res = &buf->ai;
while (j--) buf[i++].sa.sin.sin_family = AF_INET6;
}
- if (__dns_get_rr((void *)&buf[cnt], 0, 256, 1, reply, RR_CNAME, 1) < 0)
+ if (__dns_get_rr((void *)&buf[cnt], 0, 256, 1, reply, RR_CNAME, 1) <= 0)
strcpy((void *)&buf[cnt], host);
for (i=0; i<cnt; i++) {