1 /* $OpenBSD: control.c,v 1.3 2012/09/03 09:32:38 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2012 Nicholas Marriott <nicm@users.sourceforge.net> 5 * Copyright (c) 2012 George Nachman <tmux@georgester.com> 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 26 #include "tmux.h" 27 28 void printflike2 control_msg_error(struct cmd_ctx *, const char *, ...); 29 void printflike2 control_msg_print(struct cmd_ctx *, const char *, ...); 30 void printflike2 control_msg_info(struct cmd_ctx *, const char *, ...); 31 32 /* Command error callback. */ 33 void printflike2 34 control_msg_error(struct cmd_ctx *ctx, const char *fmt, ...) 35 { 36 struct client *c = ctx->curclient; 37 va_list ap; 38 39 va_start(ap, fmt); 40 evbuffer_add_vprintf(c->stdout_data, fmt, ap); 41 va_end(ap); 42 43 evbuffer_add(c->stdout_data, "\n", 1); 44 server_push_stdout(c); 45 } 46 47 /* Command print callback. */ 48 void printflike2 49 control_msg_print(struct cmd_ctx *ctx, const char *fmt, ...) 50 { 51 struct client *c = ctx->curclient; 52 va_list ap; 53 54 va_start(ap, fmt); 55 evbuffer_add_vprintf(c->stdout_data, fmt, ap); 56 va_end(ap); 57 58 evbuffer_add(c->stdout_data, "\n", 1); 59 server_push_stdout(c); 60 } 61 62 /* Command info callback. */ 63 void printflike2 64 control_msg_info(unused struct cmd_ctx *ctx, unused const char *fmt, ...) 65 { 66 } 67 68 /* Write a line. */ 69 void printflike2 70 control_write(struct client *c, const char *fmt, ...) 71 { 72 va_list ap; 73 74 va_start(ap, fmt); 75 evbuffer_add_vprintf(c->stdout_data, fmt, ap); 76 va_end(ap); 77 78 evbuffer_add(c->stdout_data, "\n", 1); 79 server_push_stdout(c); 80 } 81 82 /* Control input callback. Read lines and fire commands. */ 83 void 84 control_callback(struct client *c, int closed, unused void *data) 85 { 86 char *line, *cause; 87 struct cmd_ctx ctx; 88 struct cmd_list *cmdlist; 89 90 if (closed) 91 c->flags |= CLIENT_EXIT; 92 93 for (;;) { 94 line = evbuffer_readln(c->stdin_data, NULL, EVBUFFER_EOL_LF); 95 if (line == NULL) 96 break; 97 if (*line == '\0') { /* empty line exit */ 98 c->flags |= CLIENT_EXIT; 99 break; 100 } 101 102 ctx.msgdata = NULL; 103 ctx.cmdclient = NULL; 104 ctx.curclient = c; 105 106 ctx.error = control_msg_error; 107 ctx.print = control_msg_print; 108 ctx.info = control_msg_info; 109 110 if (cmd_string_parse(line, &cmdlist, &cause) != 0) { 111 control_write(c, "%%error in line \"%s\": %s", line, 112 cause); 113 free(cause); 114 } else { 115 cmd_list_exec(cmdlist, &ctx); 116 cmd_list_free(cmdlist); 117 } 118 119 free(line); 120 } 121 } 122