use the json to blobmsg library
[project/ubus.git] / cli.c
1 #include <libubox/blobmsg_json.h>
2 #include "libubus.h"
3
4 static struct blob_buf b;
5
6 static void receive_lookup(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv)
7 {
8         struct blob_attr *cur;
9         char *s;
10         int rem;
11
12         fprintf(stderr, "'%s' @%08x\n", obj->path, obj->id);
13
14         if (!obj->signature)
15                 return;
16
17         blob_for_each_attr(cur, obj->signature, rem) {
18                 s = blobmsg_format_json(cur, false);
19                 fprintf(stderr, "\t%s\n", s);
20                 free(s);
21         }
22 }
23
24 static void receive_data(struct ubus_request *req, int type, struct blob_attr *msg)
25 {
26         char *str;
27         if (!msg)
28                 return;
29
30         str = blobmsg_format_json(msg, true);
31         fprintf(stderr, "%s\n", str);
32         free(str);
33 }
34
35
36 static int usage(char *prog)
37 {
38         fprintf(stderr,
39                 "Usage: %s <command> [arguments...]\n"
40                 "Commands:\n"
41                 " - list [<path>]                       List objects\n"
42                 " - call <path> <method> [<message>]    Call an object method\n"
43                 " - listen [<path>...]                  Listen for events\n"
44                 "\n", prog);
45         return 1;
46 }
47
48 static void receive_event(struct ubus_context *ctx, struct ubus_event_handler *ev,
49                           const char *type, struct blob_attr *msg)
50 {
51         char *str;
52
53         if (msg)
54                 str = blobmsg_format_json(msg, true);
55         else
56                 str = "";
57
58         fprintf(stderr, "\"%s\":{ %s }\n", type, str);
59         free(str);
60 }
61
62 static int ubus_cli_listen(struct ubus_context *ctx, int argc, char **argv)
63 {
64         static struct ubus_event_handler listener;
65         const char *event;
66         int ret = 0;
67
68         memset(&listener, 0, sizeof(listener));
69         listener.cb = receive_event;
70
71         if (!argc) {
72                 event = "*";
73                 ret = ubus_register_event_handler(ctx, &listener, NULL);
74         }
75
76         for (;argc;argv++, argc--) {
77                 event = argv[0];
78                 ret = ubus_register_event_handler(ctx, &listener, argv[0]);
79                 if (ret)
80                         break;
81         }
82
83         if (ret) {
84                 fprintf(stderr, "Error while registering for event '%s': %s\n",
85                         event, ubus_strerror(ret));
86         }
87
88         uloop_init();
89         ubus_add_uloop(ctx);
90         uloop_run();
91         uloop_done();
92
93         return 0;
94 }
95
96 int main(int argc, char **argv)
97 {
98         static struct ubus_context *ctx;
99         char *cmd;
100         int ret = 0;
101
102         ctx = ubus_connect(NULL);
103         if (!ctx) {
104                 fprintf(stderr, "Failed to connect to ubus\n");
105                 return -1;
106         }
107
108         cmd = argv[1];
109         if (argc < 2)
110                 return usage(argv[0]);
111
112         if (!strcmp(cmd, "list")) {
113                 const char *path = NULL;
114
115                 if (argc == 3)
116                         path = argv[2];
117
118                 ret = ubus_lookup(ctx, path, receive_lookup, NULL);
119         } else if (!strcmp(cmd, "call")) {
120                 uint32_t id;
121
122                 if (argc < 4 || argc > 5)
123                         return usage(argv[0]);
124
125                 blob_buf_init(&b, 0);
126                 if (argc == 5 && !blobmsg_add_json_from_string(&b, argv[4])) {
127                         fprintf(stderr, "Failed to parse message data\n");
128                         goto out;
129                 }
130
131                 ret = ubus_lookup_id(ctx, argv[2], &id);
132                 if (!ret)
133                         ret = ubus_invoke(ctx, id, argv[3], b.head, receive_data, NULL);
134         } else if (!strcmp(cmd, "listen")) {
135                 ret = ubus_cli_listen(ctx, argc - 2, argv + 2);
136         } else {
137                 return usage(argv[0]);
138         }
139
140         if (ret)
141                 fprintf(stderr, "Failed: %s\n", ubus_strerror(ret));
142
143 out:
144         ubus_free(ctx);
145         return ret;
146 }