1/* $OpenBSD$ */
2
3/*
4 * Copyright (c) 2012 Nicholas Marriott <[email protected]>
5 * Copyright (c) 2012 George Nachman <[email protected]>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21
22#include <event.h>
23#include <stdlib.h>
24#include <string.h>
25#include <time.h>
26
27#include "tmux.h"
28
29/* Write a line. */
30void
31control_write(struct client *c, const char *fmt, ...)
32{
33 va_list ap;
34
35 va_start(ap, fmt);
36 file_vprint(c, fmt, ap);
37 file_print(c, "\n");
38 va_end(ap);
39}
40
41/* Control error callback. */
42static enum cmd_retval
43control_error(struct cmdq_item *item, void *data)
44{
45 struct client *c = item->client;
46 char *error = data;
47
48 cmdq_guard(item, "begin", 1);
49 control_write(c, "parse error: %s", error);
50 cmdq_guard(item, "error", 1);
51
52 free(error);
53 return (CMD_RETURN_NORMAL);
54}
55
56/* Control input callback. Read lines and fire commands. */
57static void
58control_callback(__unused struct client *c, __unused const char *path,
59 int error, int closed, struct evbuffer *buffer, __unused void *data)
60{
61 char *line;
62 struct cmdq_item *item;
63 struct cmd_parse_result *pr;
64
65 if (closed || error != 0)
66 c->flags |= CLIENT_EXIT;
67
68 for (;;) {
69 line = evbuffer_readln(buffer, NULL, EVBUFFER_EOL_LF);
70 if (line == NULL)
71 break;
72 log_debug("%s: %s", __func__, line);
73 if (*line == '\0') { /* empty line exit */
74 free(line);
75 c->flags |= CLIENT_EXIT;
76 break;
77 }
78
79 pr = cmd_parse_from_string(line, NULL);
80 switch (pr->status) {
81 case CMD_PARSE_EMPTY:
82 break;
83 case CMD_PARSE_ERROR:
84 item = cmdq_get_callback(control_error, pr->error);
85 cmdq_append(c, item);
86 break;
87 case CMD_PARSE_SUCCESS:
88 item = cmdq_get_command(pr->cmdlist, NULL, NULL, 0);
89 item->shared->flags |= CMDQ_SHARED_CONTROL;
90 cmdq_append(c, item);
91 cmd_list_free(pr->cmdlist);
92 break;
93 }
94
95 free(line);
96 }
97}
98
99void
100control_start(struct client *c)
101{
102 file_read(c, "-", control_callback, c);
103
104 if (c->flags & CLIENT_CONTROLCONTROL)
105 file_print(c, "\033P1000p");
106}
107