+ struct cli_wait_data *data = priv;
+
+ wait_check_object(data, obj->path);
+}
+
+
+static void wait_timeout(struct uloop_timeout *timeout)
+{
+ uloop_end();
+}
+
+static int ubus_cli_wait_for(struct ubus_context *ctx, int argc, char **argv)
+{
+ struct cli_wait_data data = {
+ .timeout.cb = wait_timeout,
+ .ev.cb = wait_event_cb,
+ .pending = argv,
+ .n_pending = argc,
+ };
+ int ret;
+
+ if (argc < 1)
+ return -2;
+
+ uloop_init();
+ ubus_add_uloop(ctx);
+
+ ret = ubus_register_event_handler(ctx, &data.ev, "ubus.object.add");
+ if (ret)
+ return ret;
+
+ if (!data.n_pending)
+ return ret;
+
+ ret = ubus_lookup(ctx, NULL, wait_list_cb, &data);
+ if (ret)
+ return ret;
+
+ if (!data.n_pending)
+ return ret;
+
+ uloop_timeout_set(&data.timeout, timeout * 1000);
+ uloop_run();
+ uloop_done();
+
+ if (data.n_pending)
+ return UBUS_STATUS_TIMEOUT;
+
+ return ret;
+}
+
+static const char *
+ubus_cli_msg_type(uint32_t type)
+{
+ const char *ret = NULL;
+ static char unk_type[16];
+
+
+ if (type < ARRAY_SIZE(monitor_types))
+ ret = monitor_types[type];
+
+ if (!ret) {
+ snprintf(unk_type, sizeof(unk_type), "%d", type);
+ ret = unk_type;
+ }
+
+ return ret;
+}
+
+static char *
+ubus_cli_get_monitor_data(struct blob_attr *data)
+{
+ static const struct blob_attr_info policy[UBUS_ATTR_MAX] = {
+ [UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
+ [UBUS_ATTR_OBJPATH] = { .type = BLOB_ATTR_STRING },
+ [UBUS_ATTR_OBJID] = { .type = BLOB_ATTR_INT32 },
+ [UBUS_ATTR_METHOD] = { .type = BLOB_ATTR_STRING },
+ [UBUS_ATTR_OBJTYPE] = { .type = BLOB_ATTR_INT32 },
+ [UBUS_ATTR_SIGNATURE] = { .type = BLOB_ATTR_NESTED },
+ [UBUS_ATTR_DATA] = { .type = BLOB_ATTR_NESTED },
+ [UBUS_ATTR_ACTIVE] = { .type = BLOB_ATTR_INT8 },
+ [UBUS_ATTR_NO_REPLY] = { .type = BLOB_ATTR_INT8 },
+ [UBUS_ATTR_USER] = { .type = BLOB_ATTR_STRING },
+ [UBUS_ATTR_GROUP] = { .type = BLOB_ATTR_STRING },
+ };
+ static const char * const names[UBUS_ATTR_MAX] = {
+ [UBUS_ATTR_STATUS] = "status",
+ [UBUS_ATTR_OBJPATH] = "objpath",
+ [UBUS_ATTR_OBJID] = "objid",
+ [UBUS_ATTR_METHOD] = "method",
+ [UBUS_ATTR_OBJTYPE] = "objtype",
+ [UBUS_ATTR_SIGNATURE] = "signature",
+ [UBUS_ATTR_DATA] = "data",
+ [UBUS_ATTR_ACTIVE] = "active",
+ [UBUS_ATTR_NO_REPLY] = "no_reply",
+ [UBUS_ATTR_USER] = "user",
+ [UBUS_ATTR_GROUP] = "group",
+ };
+ struct blob_attr *tb[UBUS_ATTR_MAX];
+ int i;