-
Notifications
You must be signed in to change notification settings - Fork 3
/
cmd.c
96 lines (82 loc) · 2.11 KB
/
cmd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* SPDX-License-Identifier: BSD-3-Clause */
#include "ucentral.h"
enum {
CMD_COMMAND,
CMD_TIMEOUT,
CMD_DELAY,
__CMD_MAX,
};
static const struct blobmsg_policy cmd_policy[__CMD_MAX] = {
[CMD_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_STRING },
[CMD_TIMEOUT] = { .name = "timeout", .type = BLOBMSG_TYPE_INT32 },
[CMD_DELAY] = { .name = "delay", .type = BLOBMSG_TYPE_INT32 },
};
static void
cmd_run_cb(time_t uuid, uint32_t _id)
{
char str[128];
char id[32];
ULOG_INFO("running command task\n");
sprintf(str, "/tmp/ucentral.cmd.%010" PRIu64, uuid);
snprintf(id, sizeof(id), "%d", _id);
execlp("/usr/share/ucentral/cmd.uc", "/usr/share/ucentral/cmd.uc", str, id, NULL);
exit(1);
}
static void
cmd_complete_cb(struct task *t, time_t uuid, uint32_t id, int ret)
{
char str[128];
sprintf(str, "/tmp/ucentral.cmd.%010" PRIu64, uuid);
unlink(str);
if (t->cancelled)
result_send_error(1, "command timed out and was aborted", -1, id);
else if (ret)
result_send_error(1, "command returned an error code", ret, id);
}
int
cmd_run(struct blob_attr *attr, uint32_t id, int admin)
{
static struct blob_attr *tb[__CMD_MAX];
char *json = NULL;
FILE *fp = NULL;
char path[128];
int ret = -1;
time_t t = id;
blobmsg_parse(cmd_policy, __CMD_MAX, tb, blobmsg_data(attr), blobmsg_data_len(attr));
if (!tb[CMD_COMMAND]) {
ULOG_ERR("cmd has invalid parameters\n");
goto out;
}
json = blobmsg_format_json(attr, true);
if (!json) {
ULOG_ERR("failed to format cmd json\n");
goto out;
}
snprintf(path, sizeof(path), "/tmp/ucentral.cmd.%010" PRIu64, t);
fp = fopen(path, "w+");
if (!fp) {
ULOG_ERR("failed to open %s\n", path);
goto out;
}
if (fwrite(json, strlen(json), 1, fp) == 1) {
struct task *task = calloc(1, sizeof(*task));
if (tb[CMD_TIMEOUT])
task->run_time = blobmsg_get_u32(tb[CMD_TIMEOUT]);
else
task->run_time = 60;
if (tb[CMD_DELAY])
task->delay = blobmsg_get_u32(tb[CMD_DELAY]);
task->run = cmd_run_cb;
task->complete = cmd_complete_cb;
fclose(fp);
fp = NULL;
task_run(task, t, id, admin);
ret = 0;
}
out:
if (json)
free(json);
if (fp)
fclose(fp);
return ret;
}