-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinfo.c
103 lines (86 loc) · 1.96 KB
/
info.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
92
93
94
95
96
97
98
99
100
101
102
103
#include "info.h"
#include "contact.h"
#include "client.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <libubox/uloop.h>
#include <libubox/blobmsg.h>
#include <libubox/blobmsg_json.h>
#define UNIX_PATH "/tmp/ecchatd.socket"
extern struct contacts *contacts;
static char * gen_info()
{
struct blob_buf b = {0};
struct contact *c;
char *str;
blob_buf_init(&b, 0);
avl_for_each_element(&contacts->tree, c, node) {
void *t = blobmsg_open_table(&b, ecchat_idstr(&c->id));
struct client *client = c->priv;
blobmsg_add_u32(&b, "mbox", c->mbox.cnt);
blobmsg_add_u32(&b, "version", c->latest_client_version);
if (client) {
blobmsg_add_string(&b, "remote", ss_ntoa(&client->ss));
blobmsg_add_u32(&b, "txq", client->txq.cnt);
}
blobmsg_close_table(&b, t);
}
str = blobmsg_format_json_indent(b.head, true, 0);
blob_buf_free(&b);
return str;
}
static void unix_fd_cb(struct uloop_fd *fd, unsigned events)
{
struct sockaddr_un un;
socklen_t slen = sizeof(un);
char buf[32];
char *info_str;
ssize_t rc;
if (!(events & ULOOP_READ))
return;
rc = recvfrom(fd->fd, buf, sizeof(buf), 0,
(struct sockaddr *)&un, &slen);
if (rc == -1)
err_errno("read");
info_str = gen_info();
if (info_str) {
rc = sendto(fd->fd, info_str, strlen(info_str), 0,
(struct sockaddr *)&un, slen);
if (rc == -1)
err_errno("write");
free(info_str);
}
}
static struct uloop_fd unix_fd = {
.fd = -1,
.cb = unix_fd_cb
};
void info_init()
{
struct sockaddr_un un = {0};
int sk;
sk = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sk == -1) {
err_errno("socket");
return;
}
un.sun_family = AF_UNIX;
strcpy(un.sun_path, UNIX_PATH);
unlink(UNIX_PATH);
if (bind(sk, (struct sockaddr *)&un, sizeof(un)) == -1) {
err_errno("bind %s", UNIX_PATH);
close(sk);
return;
}
unix_fd.fd = sk;
uloop_fd_add(&unix_fd, ULOOP_READ);
}
void info_deinit()
{
if (unix_fd.fd != -1) {
uloop_fd_delete(&unix_fd);
close(unix_fd.fd);
unlink(UNIX_PATH);
}
}