#include "libubus.h"
static struct blob_buf b;
+static int listen_timeout;
static int timeout = 30;
static bool simple_output = false;
static int verbose = 0;
[BLOBMSG_TYPE_TABLE] = "\"Table\"",
};
const char *type = NULL;
- int typeid;
+ size_t typeid;
if (blob_id(attr) != BLOBMSG_TYPE_INT32)
return NULL;
{
struct blob_attr *cur;
char *s;
- int rem;
+ size_t rem;
if (simple_output || !verbose) {
printf("%s\n", obj->path);
print_event(type, msg);
}
+static int ubus_cli_error(char *cmd, int argc, char **argv, int err)
+{
+ int i;
+
+ if (!simple_output && !isatty(fileno(stderr))) {
+ fprintf(stderr, "Command failed: ubus %s ", cmd);
+ for (i = 0; i < argc; i++) {
+ fprintf(stderr, "%s ", argv[i]);
+ }
+ fprintf(stderr, "(%s)\n", ubus_strerror(err));
+
+ return -err;
+ }
+
+ return err;
+}
+
static int ubus_cli_list(struct ubus_context *ctx, int argc, char **argv)
{
const char *path = NULL;
blob_buf_init(&b, 0);
if (argc == 3 && !blobmsg_add_json_from_string(&b, argv[2])) {
- if (!simple_output)
- fprintf(stderr, "Failed to parse message data\n");
- return -1;
+ return ubus_cli_error("call", argc, argv, UBUS_STATUS_PARSE_ERROR);
}
ret = ubus_lookup_id(ctx, argv[0], &id);
if (ret)
return ret;
- return ubus_invoke(ctx, id, argv[1], b.head, receive_call_result_data, NULL, timeout * 1000);
+ ret = ubus_invoke(ctx, id, argv[1], b.head, receive_call_result_data, NULL, timeout * 1000);
+ if (ret)
+ return ubus_cli_error("call", argc, argv, ret);
+
+ return ret;
}
struct cli_listen_data {
bool timed_out;
};
-static void listen_timeout(struct uloop_timeout *timeout)
+static void ubus_cli_listen_timeout(struct uloop_timeout *timeout)
{
struct cli_listen_data *data = container_of(timeout, struct cli_listen_data, timeout);
data->timed_out = true;
static void do_listen(struct ubus_context *ctx, struct cli_listen_data *data)
{
memset(data, 0, sizeof(*data));
- data->timeout.cb = listen_timeout;
+ data->timeout.cb = ubus_cli_listen_timeout;
uloop_init();
ubus_add_uloop(ctx);
- uloop_timeout_set(&data->timeout, timeout * 1000);
+ if (listen_timeout)
+ uloop_timeout_set(&data->timeout, listen_timeout * 1000);
uloop_run();
uloop_done();
}
blob_buf_init(&b, 0);
if (argc == 2 && !blobmsg_add_json_from_string(&b, argv[1])) {
- if (!simple_output)
- fprintf(stderr, "Failed to parse message data\n");
- return -1;
+ return UBUS_STATUS_PARSE_ERROR;
}
return ubus_send_event(ctx, argv[0], b.head);
bool send;
char *data;
- blob_parse(msg, tb, policy, UBUS_MONITOR_MAX);
+ blob_parse_untrusted(msg, blob_raw_len(msg), tb, policy, UBUS_MONITOR_MAX);
if (!tb[UBUS_MONITOR_CLIENT] ||
!tb[UBUS_MONITOR_PEER] ||
static int add_monitor_type(const char *type)
{
- int i;
+ size_t i;
for (i = 0; i < ARRAY_SIZE(monitor_types); i++) {
if (!monitor_types[i] || strcmp(monitor_types[i], type) != 0)
"Commands:\n"
" - list [<path>] List objects\n"
" - call <path> <method> [<message>] Call an object method\n"
+ " - subscribe <path> [<path>...] Subscribe to object(s) notifications\n"
" - listen [<path>...] Listen for events\n"
" - send <type> [<message>] Send an event\n"
" - wait_for <object> [<object>...] Wait for multiple objects to appear on ubus\n"
{
const char *progname, *ubus_socket = NULL;
struct ubus_context *ctx;
- char *cmd;
int ret = 0;
- int i, ch;
+ char *cmd;
+ size_t i;
+ int ch;
progname = argv[0];
ubus_socket = optarg;
break;
case 't':
+ listen_timeout = atoi(optarg);
timeout = atoi(optarg);
break;
case 'S':