1 /* 2 * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org> 3 * 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 7 * 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. 12 */ 13 14 #include "ubusd.h" 15 16 static struct ubus_object *monitor_obj; 17 static LIST_HEAD(monitors); 18 19 struct ubus_monitor { 20 struct list_head list; 21 struct ubus_client *cl; 22 uint32_t seq; 23 }; 24 25 static void 26 ubusd_monitor_free(struct ubus_monitor *m) 27 { 28 list_del(&m->list); 29 free(m); 30 } 31 32 static bool 33 ubusd_monitor_connect(struct ubus_client *cl, struct ubus_msg_buf *ub) 34 { 35 struct ubus_monitor *m; 36 37 ubusd_monitor_disconnect(cl); 38 39 m = calloc(1, sizeof(*m)); 40 if (!m) 41 return false; 42 43 m->cl = cl; 44 list_add_tail(&m->list, &monitors); 45 46 return true; 47 } 48 49 static struct ubus_monitor* 50 ubusd_monitor_find(struct ubus_client *cl) 51 { 52 struct ubus_monitor *m, *tmp; 53 54 list_for_each_entry_safe(m, tmp, &monitors, list) { 55 if (m->cl != cl) 56 continue; 57 58 return m; 59 } 60 61 return NULL; 62 } 63 64 void 65 ubusd_monitor_disconnect(struct ubus_client *cl) 66 { 67 struct ubus_monitor *m; 68 69 m = ubusd_monitor_find(cl); 70 if (!m) 71 return; 72 73 ubusd_monitor_free(m); 74 } 75 76 void 77 ubusd_monitor_message(struct ubus_client *cl, struct ubus_msg_buf *ub, bool send) 78 { 79 static struct blob_buf mb; 80 struct ubus_monitor *m; 81 82 if (list_empty(&monitors)) 83 return; 84 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)); 92 93 ub = ubus_msg_new(mb.head, blob_raw_len(mb.head), true); 94 ub->hdr.type = UBUS_MSG_MONITOR; 95 96 list_for_each_entry(m, &monitors, list) { 97 ub->hdr.seq = ++m->seq; 98 ubus_msg_send(m->cl, ub); 99 } 100 101 ubus_msg_free(ub); 102 } 103 104 static int 105 ubusd_monitor_recv(struct ubus_client *cl, struct ubus_msg_buf *ub, 106 const char *method, struct blob_attr *msg) 107 { 108 /* Only root is allowed for now */ 109 if (cl->uid != 0 || cl->gid != 0) 110 return UBUS_STATUS_PERMISSION_DENIED; 111 112 if (!strcmp(method, "add")) { 113 if (!ubusd_monitor_connect(cl, ub)) 114 return UBUS_STATUS_UNKNOWN_ERROR; 115 116 return UBUS_STATUS_OK; 117 } 118 119 if (!strcmp(method, "remove")) { 120 ubusd_monitor_disconnect(cl); 121 return UBUS_STATUS_OK; 122 } 123 124 return UBUS_STATUS_METHOD_NOT_FOUND; 125 } 126 127 void 128 ubusd_monitor_init(void) 129 { 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; 133 } 134
This page was automatically generated by LXR 0.3.1. • OpenWrt