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
));
44 list_add_tail(&m
->list
, &monitors
);
49 static struct ubus_monitor
*
50 ubusd_monitor_find(struct ubus_client
*cl
)
52 struct ubus_monitor
*m
, *tmp
;
54 list_for_each_entry_safe(m
, tmp
, &monitors
, list
) {
65 ubusd_monitor_disconnect(struct ubus_client
*cl
)
67 struct ubus_monitor
*m
;
69 m
= ubusd_monitor_find(cl
);
73 ubusd_monitor_free(m
);
77 ubusd_monitor_message(struct ubus_client
*cl
, struct ubus_msg_buf
*ub
, bool send
)
79 static struct blob_buf mb
;
80 struct ubus_monitor
*m
;
82 if (list_empty(&monitors
))
85 blob_buf_init(&mb
, 0);
86 blob_put_int32(&mb
, UBUS_MONITOR_CLIENT
, cl
->id
.id
);
87 blob_put_int32(&mb
, UBUS_MONITOR_PEER
, ub
->hdr
.peer
);
88 blob_put_int32(&mb
, UBUS_MONITOR_SEQ
, ub
->hdr
.seq
);
89 blob_put_int32(&mb
, UBUS_MONITOR_TYPE
, ub
->hdr
.type
);
90 blob_put_int8(&mb
, UBUS_MONITOR_SEND
, send
);
91 blob_put(&mb
, UBUS_MONITOR_DATA
, blob_data(ub
->data
), blob_len(ub
->data
));
93 ub
= ubus_msg_new(mb
.head
, blob_raw_len(mb
.head
), true);
94 ub
->hdr
.type
= UBUS_MSG_MONITOR
;
96 list_for_each_entry(m
, &monitors
, list
) {
97 ub
->hdr
.seq
= ++m
->seq
;
98 ubus_msg_send(m
->cl
, ub
);
105 ubusd_monitor_recv(struct ubus_client
*cl
, struct ubus_msg_buf
*ub
,
106 const char *method
, struct blob_attr
*msg
)
108 /* Only root is allowed for now */
109 if (cl
->uid
!= 0 || cl
->gid
!= 0)
110 return UBUS_STATUS_PERMISSION_DENIED
;
112 if (!strcmp(method
, "add")) {
113 if (!ubusd_monitor_connect(cl
, ub
))
114 return UBUS_STATUS_UNKNOWN_ERROR
;
116 return UBUS_STATUS_OK
;
119 if (!strcmp(method
, "remove")) {
120 ubusd_monitor_disconnect(cl
);
121 return UBUS_STATUS_OK
;
124 return UBUS_STATUS_METHOD_NOT_FOUND
;
128 ubusd_monitor_init(void)
130 monitor_obj
= ubusd_create_object_internal(NULL
, UBUS_SYSTEM_OBJECT_MONITOR
);
131 if (monitor_obj
!= NULL
)
132 monitor_obj
->recv_msg
= ubusd_monitor_recv
;