~stacyharper/bonsai

ref: 7392eea86ac92c92203ec05b83e32387acfa59e3 bonsai/cmd/bonsaid/cmd.ha -rw-r--r-- 2.6 KiB
7392eea8Stacy Harper Fix some log priority 2 months ago
                                                                                
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use bufio;
use errors;
use fmt;
use fs;
use getopt;
use io;
use log;
use os::exec;
use shlex;
use strings;
use unix::poll::{event};
use bonsai;

type servererror = !(io::error | fs::error | exec::error);
type cmderror = servererror;

fn strerror(err: cmderror) const str = {
	match (err) {
	case let err: io::error =>
		return io::strerror(err);
	case let err: fs::error =>
		return fs::strerror(err);
	case let err: exec::error =>
		return exec::strerror(err);
	};
};

fn exec(serv: *server, client: *client, cmd: str) (void | servererror) = {
	log::printfln("received command: '{}'", cmd);
	const args = match (shlex::split(cmd)) {
	case shlex::syntaxerr =>
		log::println("error invalid command syntax", cmd);
		writefmt(client, "error Invalid command syntax");
		return;
	case let items: []str =>
		yield items;
	};
	defer strings::freeall(args);
	if (len(args) == 0) {
		log::println("error invalid command syntax");
		writefmt(client, "error Invalid command syntax");
		return;
	};

	const cmd = switch (args[0]) {
	case "event" =>
		yield &exec_event;
	case "context" =>
		yield &exec_context;
	case "quit" =>
		yield &exec_quit;
	case =>
		log::println("error unknown command");
		writefmt(client, "error unknown command");
		return;
	};

	match (cmd(serv, client, args[1..])) {
	case let err: servererror =>
		log::println("error internal error:", strerror(err));
		writefmt(client, "error internal error");
		return err;
	case void => yield;
	};
};

fn exec_event(serv: *server, client: *client, args: []str) (void | cmderror) = {
	log::println("executing event command");
	bonsai::state_forward(
		&serv.state,
		bonsai::action_event_received {
			event_name = args[0]
		}
	);

	let buf = bufio::dynamic(io::mode::WRITE);

	fmt::fprint(&buf, "end\n")?;
	writebuf(client, bufio::buffer(&buf));
};

fn exec_context(serv: *server, client: *client, args: []str) (void | cmderror) = {
	log::println("executing context command");
	let context_elements: []bonsai::context_element = [];
	for (let i = 0z; i < len(args); i += 1) {
		append(
			context_elements,
			bonsai::context_element_str(args[i])
		);
	};

	bonsai::state_forward(
		&serv.state,
		bonsai::action_context_changed {
			context_elements = context_elements
		}
	);

	let buf = bufio::dynamic(io::mode::WRITE);

	fmt::fprint(&buf, "end\n")?;
	writebuf(client, bufio::buffer(&buf));
};

fn exec_quit(serv: *server, client: *client, args: []str) (void | cmderror) = {
	log::println("executing quit command");
	if (!serv.daemonized) {
		writefmt(client, "error Server is not damonized, use a service manager");
		return;
	};
	serv.terminate = true;
};