2 * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2.1
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
16 static struct ubus_object
*monitor_obj
;
17 static LIST_HEAD(monitors
);
20 struct list_head list
;
21 struct ubus_client
*cl
;
26 ubusd_monitor_free(struct ubus_monitor
*m
)
33 ubusd_monitor_connect(struct ubus_client
*cl
, struct ubus_msg_buf
*ub
)
35 struct ubus_monitor
*m
;
37 ubusd_monitor_disconnect(cl
);
39 m
= calloc(1, sizeof(*m
));
41 list_add(&m
->list
, &monitors
);
45 ubusd_monitor_disconnect(struct ubus_client
*cl
)
47 struct ubus_monitor
*m
;
49 list_for_each_entry(m
, &monitors
, list
) {
53 ubusd_monitor_free(m
);
59 ubusd_monitor_message(struct ubus_client
*cl
, struct ubus_msg_buf
*ub
, bool send
)
61 static struct blob_buf mb
;
62 struct ubus_monitor
*m
;
64 if (list_empty(&monitors
))
67 blob_buf_init(&mb
, 0);
68 blob_put_int32(&mb
, UBUS_MONITOR_CLIENT
, cl
->id
.id
);
69 blob_put_int32(&mb
, UBUS_MONITOR_PEER
, ub
->hdr
.peer
);
70 blob_put_int32(&mb
, UBUS_MONITOR_SEQ
, ub
->hdr
.seq
);
71 blob_put_int32(&mb
, UBUS_MONITOR_TYPE
, ub
->hdr
.type
);
72 blob_put_int8(&mb
, UBUS_MONITOR_SEND
, send
);
73 blob_put(&mb
, UBUS_MONITOR_DATA
, blob_data(ub
->data
), blob_len(ub
->data
));
75 list_for_each_entry(m
, &monitors
, list
) {
76 ub
= ubus_msg_new(mb
.head
, blob_raw_len(mb
.head
), true);
77 ub
->hdr
.type
= UBUS_MSG_MONITOR
;
78 ub
->hdr
.seq
= ++m
->seq
;
79 ubus_msg_send(m
->cl
, ub
, true);
84 ubusd_monitor_recv(struct ubus_client
*cl
, struct ubus_msg_buf
*ub
,
85 const char *method
, struct blob_attr
*msg
)
87 /* Only root is allowed for now */
88 if (cl
->uid
!= 0 || cl
->gid
!= 0)
89 return UBUS_STATUS_PERMISSION_DENIED
;
91 if (!strcmp(method
, "add")) {
92 ubusd_monitor_connect(cl
, ub
);
96 if (!strcmp(method
, "remove")) {
97 ubusd_monitor_disconnect(cl
);
101 return UBUS_STATUS_METHOD_NOT_FOUND
;
105 ubusd_monitor_init(void)
107 monitor_obj
= ubusd_create_object_internal(NULL
, UBUS_SYSTEM_OBJECT_MONITOR
);
108 if (monitor_obj
!= NULL
)
109 monitor_obj
->recv_msg
= ubusd_monitor_recv
;