#include <string.h>
#include <sys/stat.h>
#include <arpa/inet.h>
+#include <signal.h>
#include "luci2.h"
static struct blob_buf buf;
static struct uci_context *cursor;
+enum {
+ RPC_S_PID,
+ RPC_S_SIGNAL,
+ __RPC_S_MAX,
+};
+
+static const struct blobmsg_policy rpc_signal_policy[__RPC_S_MAX] = {
+ [RPC_S_PID] = { .name = "pid", .type = BLOBMSG_TYPE_INT32 },
+ [RPC_S_SIGNAL] = { .name = "signal", .type = BLOBMSG_TYPE_INT32 },
+};
+
static int
rpc_errno_status(void)
return 0;
}
+static int
+rpc_luci2_process_list(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ FILE *top;
+ void *c, *d;
+ char line[1024];
+ char *pid, *ppid, *user, *stat, *vsz, *pvsz, *pcpu, *cmd;
+
+ if (!(top = popen("/bin/busybox top -bn1", "r")))
+ return rpc_errno_status();
+
+ blob_buf_init(&buf, 0);
+ c = blobmsg_open_array(&buf, "processes");
+
+ while (fgets(line, sizeof(line) - 1, top))
+ {
+ pid = strtok(line, " ");
+
+ if (*pid < '0' || *pid > '9')
+ continue;
+
+ ppid = strtok(NULL, " ");
+ user = strtok(NULL, " ");
+ stat = strtok(NULL, " ");
+
+ if (!stat)
+ continue;
+
+ if (!*(stat + 1))
+ *(stat + 1) = ' ';
+
+ if (!*(stat + 2))
+ *(stat + 2) = ' ';
+
+ *(stat + 3) = 0;
+
+ vsz = strtok(stat + 4, " ");
+ pvsz = strtok(NULL, " ");
+ pcpu = strtok(NULL, " ");
+ cmd = strtok(NULL, "\n");
+
+ if (!cmd)
+ continue;
+
+ d = blobmsg_open_table(&buf, NULL);
+
+ blobmsg_add_u32(&buf, "pid", atoi(pid));
+ blobmsg_add_u32(&buf, "ppid", atoi(ppid));
+ blobmsg_add_string(&buf, "user", user);
+ blobmsg_add_string(&buf, "stat", stat);
+ blobmsg_add_u32(&buf, "vsize", atoi(vsz) * 1024);
+ blobmsg_add_u32(&buf, "vsize_percent", atoi(pvsz));
+ blobmsg_add_u32(&buf, "cpu_percent", atoi(pcpu));
+ blobmsg_add_string(&buf, "command", cmd);
+
+ blobmsg_close_table(&buf, d);
+ }
+
+ fclose(top);
+ blobmsg_close_array(&buf, c);
+
+ ubus_send_reply(ctx, req, buf.head);
+ return 0;
+}
+
+static int
+rpc_luci2_process_signal(struct ubus_context *ctx, struct ubus_object *obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ int pid, sig;
+ struct blob_attr *tb[__RPC_S_MAX];
+
+ blobmsg_parse(rpc_signal_policy, __RPC_S_MAX, tb,
+ blob_data(msg), blob_len(msg));
+
+ if (!tb[RPC_S_SIGNAL] || !tb[RPC_S_PID])
+ {
+ errno = EINVAL;
+ return rpc_errno_status();
+ }
+
+ pid = blobmsg_get_u32(tb[RPC_S_PID]);
+ sig = blobmsg_get_u32(tb[RPC_S_SIGNAL]);
+
+ if (kill(pid, sig))
+ return rpc_errno_status();
+
+ return 0;
+}
+
static FILE *
dnsmasq_leasefile(void)
int rv = 0;
static const struct ubus_method luci2_system_methods[] = {
- UBUS_METHOD_NOARG("syslog", rpc_luci2_system_log),
- UBUS_METHOD_NOARG("dmesg", rpc_luci2_system_dmesg),
+ UBUS_METHOD_NOARG("syslog", rpc_luci2_system_log),
+ UBUS_METHOD_NOARG("dmesg", rpc_luci2_system_dmesg),
+ UBUS_METHOD_NOARG("process_list", rpc_luci2_process_list),
+ UBUS_METHOD("process_signal", rpc_luci2_process_signal,
+ rpc_signal_policy),
};
static struct ubus_object_type luci2_system_type =