-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathai.c
91 lines (73 loc) · 2.1 KB
/
ai.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include "ai.h"
/**
* Special handling for EAI_AGAIN and EAI_SYSTEM.
*/
int xgetai(const char *const host,
const char *const port,
const int family,
const int socktype,
const int flags,
AddrInfo **result) {
assert(port != NULL);
assert(result != NULL);
const struct addrinfo hints = {
.ai_family = family,
.ai_socktype = socktype,
.ai_flags = flags
};
int ret = getaddrinfo(host, port, &hints, result);
assert(ret != EAI_BADFLAGS);
assert(ret != EAI_SOCKTYPE);
return (ret);
}
void ai_free(AddrInfo **const ai) {
assert(ai != NULL);
if (*ai != NULL)
freeaddrinfo(*ai);
}
void ai_print(const char *const prefix,
const int family,
SockAddr *const addr,
const char *const port,
const bool handle_errno) {
assert(prefix != NULL);
assert(addr != NULL);
assert(port != NULL);
void (*warn_func)(const char *format, ...)
attr((format(printf, 1, 2)))
= handle_errno ? warn : warnx;
int _errno = errno;
if (family == AF_INET) {
char ip[INET_ADDRSTRLEN];
struct sockaddr_in sa;
(void) memcpy(&sa, addr, sizeof(struct sockaddr_in));
if (inet_ntop(AF_INET, &sa.sin_addr, ip, INET_ADDRSTRLEN) == NULL) {
assert(errno != EAFNOSUPPORT);
assert(errno != ENOSPC);
}
errno = _errno;
warn_func("%s IPv4:%.*s:%s", prefix, INET_ADDRSTRLEN, ip, port);
} else if (family == AF_INET6) {
char ip[INET6_ADDRSTRLEN];
struct sockaddr_in6 sa;
(void) memcpy(&sa, addr, sizeof(struct sockaddr_in6));
if (inet_ntop(AF_INET6, &sa.sin6_addr, ip, INET6_ADDRSTRLEN) == NULL) {
assert(errno != EAFNOSUPPORT);
assert(errno != ENOSPC);
}
errno = _errno;
warn_func("%s IPv6:%.*s:%s", prefix, INET6_ADDRSTRLEN, ip, port);
} else {
assert(family == AF_INET || family == AF_INET6);
}
/* just in case this function implementation changes, we restore
* errno here
*/
errno = _errno;
}