1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <uv.h>
5
6uv_loop_t *loop;
7
8void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
9  buf->base = malloc(suggested_size);
10  buf->len = suggested_size;
11}
12
13void on_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
14    if (nread < 0) {
15        if (nread != UV_EOF)
16            fprintf(stderr, "Read error %s\n", uv_err_name(nread));
17        uv_close((uv_handle_t*) client, NULL);
18        free(buf->base);
19        free(client);
20        return;
21    }
22
23    char *data = (char*) malloc(sizeof(char) * (nread+1));
24    data[nread] = '\0';
25    strncpy(data, buf->base, nread);
26
27    fprintf(stderr, "%s", data);
28    free(data);
29    free(buf->base);
30}
31
32void on_connect(uv_connect_t *req, int status) {
33    if (status < 0) {
34        fprintf(stderr, "connect failed error %s\n", uv_err_name(status));
35        free(req);
36        return;
37    }
38
39    uv_read_start((uv_stream_t*) req->handle, alloc_buffer, on_read);
40    free(req);
41}
42
43void on_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) {
44    if (status < 0) {
45        fprintf(stderr, "getaddrinfo callback error %s\n", uv_err_name(status));
46        return;
47    }
48
49    char addr[17] = {'\0'};
50    uv_ip4_name((struct sockaddr_in*) res->ai_addr, addr, 16);
51    fprintf(stderr, "%s\n", addr);
52
53    uv_connect_t *connect_req = (uv_connect_t*) malloc(sizeof(uv_connect_t));
54    uv_tcp_t *socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t));
55    uv_tcp_init(loop, socket);
56
57    uv_tcp_connect(connect_req, socket, (const struct sockaddr*) res->ai_addr, on_connect);
58
59    uv_freeaddrinfo(res);
60}
61
62int main() {
63    loop = uv_default_loop();
64
65    struct addrinfo hints;
66    hints.ai_family = PF_INET;
67    hints.ai_socktype = SOCK_STREAM;
68    hints.ai_protocol = IPPROTO_TCP;
69    hints.ai_flags = 0;
70
71    uv_getaddrinfo_t resolver;
72    fprintf(stderr, "irc.libera.chat is... ");
73    int r = uv_getaddrinfo(loop, &resolver, on_resolved, "irc.libera.chat", "6667", &hints);
74
75    if (r) {
76        fprintf(stderr, "getaddrinfo call error %s\n", uv_err_name(r));
77        return 1;
78    }
79    return uv_run(loop, UV_RUN_DEFAULT);
80}
81