14 #include <sys/types.h>
21 #include <linux/types.h>
23 #include <libubox/uloop.h>
24 #include <libubox/blobmsg.h>
25 #include <libubox/list.h>
26 #include <libubox/ustream.h>
27 #include <libubox/utils.h>
33 static struct blob_buf
b;
34 static struct ubus_auto_conn
conn;
35 static struct udebug_ubus
udebug;
46 [
READ_LINES] = { .name =
"lines", .type = BLOBMSG_TYPE_INT32 },
47 [
READ_STREAM] = { .name =
"stream", .type = BLOBMSG_TYPE_BOOL },
48 [
READ_ONESHOT] = { .name =
"oneshot", .type = BLOBMSG_TYPE_BOOL },
52 { .name =
"event", .type = BLOBMSG_TYPE_STRING };
55 struct list_head
list;
79 if (ustream_pending_data(
s,
true))
88 blobmsg_add_string(
b,
"msg", l->
data);
89 blobmsg_add_u32(
b,
"id", l->
id);
90 blobmsg_add_u32(
b,
"priority", l->
priority);
91 blobmsg_add_u32(
b,
"source", l->
source);
92 blobmsg_add_u64(
b,
"time", (((__u64) l->
ts.tv_sec) * 1000) + (l->
ts.tv_nsec / 1000000));
97 struct ubus_request_data *req,
const char *method,
98 struct blob_attr *msg)
107 bool oneshot =
false;
125 if (pipe(fds) == -1) {
126 fprintf(stderr,
"logd: failed to create pipe: %m\n");
130 ubus_request_set_fd(
ctx, req, fds[0]);
131 cl = calloc(1,
sizeof(*cl));
134 ustream_fd_init(&cl->
s, cl->
fd);
135 list_add(&cl->
list, &clients);
137 blob_buf_init(&
b, 0);
140 ret = ustream_write(&cl->
s.stream, (
void *)
b.head, blob_len(
b.head) +
sizeof(
struct blob_attr),
false);
150 blob_buf_init(&
b, 0);
151 c = blobmsg_open_array(&
b,
"log");
153 e = blobmsg_open_table(&
b, NULL);
155 blobmsg_close_table(&
b, e);
158 blobmsg_close_array(&
b, c);
159 ubus_send_reply(
ctx, req,
b.head);
167 struct ubus_request_data *req,
const char *method,
168 struct blob_attr *msg)
170 struct blob_attr *tb;
176 blobmsg_parse(&
write_policy, 1, &tb, blob_data(msg), blob_len(msg));
178 event = blobmsg_get_string(tb);
179 len = strlen(event) + 1;
212 if (list_empty(&clients) && !
log_object.has_subscribers)
215 blob_buf_init(&
b, 0);
216 blobmsg_add_string(&
b,
"msg", l->
data);
217 blobmsg_add_u32(&
b,
"id", l->
id);
218 blobmsg_add_u32(&
b,
"priority", l->
priority);
219 blobmsg_add_u32(&
b,
"source", l->
source);
220 blobmsg_add_u64(&
b,
"time", (((__u64) l->
ts.tv_sec) * 1000) + (l->
ts.tv_nsec / 1000000));
225 list_for_each_entry(c, &clients,
list)
226 ustream_write(&c->
s.stream, (
void *)
b.head, blob_len(
b.head) +
sizeof(
struct blob_attr),
false);
238 fprintf(stderr,
"Failed to add object: %s\n", ubus_strerror(ret));
241 fprintf(stderr,
"log: connected to ubus\n");
248 struct passwd *p = NULL;
250 signal(SIGPIPE, SIG_IGN);
251 while ((ch = getopt(argc, argv,
"S:")) != -1) {
265 ubus_auto_connect(&
conn);
267 p = getpwnam(
"logd");
269 if (setgid(p->pw_gid) < 0) {
270 fprintf(stderr,
"setgid() failed: %s\n", strerror(errno));
274 if (setuid(p->pw_uid) < 0) {
275 fprintf(stderr,
"setuid() failed: %s\n", strerror(errno));
280 udebug_ubus_free(&
udebug);
283 ubus_auto_shutdown(&
conn);
static const struct blobmsg_policy write_policy
void ubus_notify_log(struct log_head *l)
int main(int argc, char **argv)
static void ubus_connect_handler(struct ubus_context *ctx)
static struct udebug_ubus udebug
static struct ubus_object_type log_object_type
static LIST_HEAD(clients)
static int write_log(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
static void client_close(struct ustream *s)
static int read_log(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
static void client_notify_state(struct ustream *s)
static struct ubus_auto_conn conn
static struct ubus_object log_object
static void client_notify_write(struct ustream *s, int bytes)
static const struct ubus_method log_methods[]
static const struct blobmsg_policy read_policy[__READ_MAX]
static void log_fill_msg(struct blob_buf *b, struct log_head *l)
static struct ubus_context * ctx
struct log_head * log_list(int count, struct log_head *h)
void log_add(char *buf, int size, int source)
void log_init(int _log_size)
void log_udebug_config(struct udebug_ubus *ctx, struct blob_attr *data, bool enabled)