summaryrefslogtreecommitdiffstats
path: root/server-msg.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2007-10-03 21:31:07 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2007-10-03 21:31:07 +0000
commitdf716ecc8fadc9ffd6b8c9ee33d062b58895a47b (patch)
treed9ba914e38d207a7ed1ee330cdc48bc681b220fe /server-msg.c
parenta5a17b40ee9cd25eae3c3d177abf4e4faa2dc4d8 (diff)
Rewrite command handling to be more generic. Not finished!
Diffstat (limited to 'server-msg.c')
-rw-r--r--server-msg.c402
1 files changed, 92 insertions, 310 deletions
diff --git a/server-msg.c b/server-msg.c
index 6de3d34c..89d57b0f 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -1,4 +1,4 @@
-/* $Id: server-msg.c,v 1.19 2007-10-03 13:07:42 nicm Exp $ */
+/* $Id: server-msg.c,v 1.20 2007-10-03 21:31:07 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -24,16 +24,13 @@
#include "tmux.h"
-int server_msg_fn_attach(struct hdr *, struct client *);
-int server_msg_fn_bindkey(struct hdr *, struct client *);
+int server_msg_fn_command(struct hdr *, struct client *);
+int server_msg_fn_identify(struct hdr *, struct client *);
int server_msg_fn_keys(struct hdr *, struct client *);
-int server_msg_fn_new(struct hdr *, struct client *);
-int server_msg_fn_rename(struct hdr *, struct client *);
-int server_msg_fn_sessions(struct hdr *, struct client *);
-int server_msg_fn_size(struct hdr *, struct client *);
-int server_msg_fn_unbindkey(struct hdr *, struct client *);
-int server_msg_fn_windowlist(struct hdr *, struct client *);
-int server_msg_fn_windows(struct hdr *, struct client *);
+int server_msg_fn_resize(struct hdr *, struct client *);
+
+void server_msg_fn_command_error(struct cmd_ctx *, const char *, ...);
+void server_msg_fn_command_print(struct cmd_ctx *, const char *, ...);
struct server_msg {
enum hdrtype type;
@@ -41,16 +38,10 @@ struct server_msg {
int (*fn)(struct hdr *, struct client *);
};
const struct server_msg server_msg_table[] = {
- { MSG_ATTACH, server_msg_fn_attach },
- { MSG_BINDKEY, server_msg_fn_bindkey },
+ { MSG_IDENTIFY, server_msg_fn_identify },
+ { MSG_COMMAND, server_msg_fn_command },
+ { MSG_RESIZE, server_msg_fn_resize },
{ MSG_KEYS, server_msg_fn_keys },
- { MSG_NEW, server_msg_fn_new },
- { MSG_RENAME, server_msg_fn_rename },
- { MSG_SESSIONS, server_msg_fn_sessions },
- { MSG_SIZE, server_msg_fn_size },
- { MSG_UNBINDKEY, server_msg_fn_unbindkey },
- { MSG_WINDOWLIST, server_msg_fn_windowlist },
- { MSG_WINDOWS, server_msg_fn_windows },
};
#define NSERVERMSG (sizeof server_msg_table / sizeof server_msg_table[0])
@@ -83,89 +74,98 @@ server_msg_dispatch(struct client *c)
}
}
-/* New message from client. */
+void
+server_msg_fn_command_error(struct cmd_ctx *ctx, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ server_write_client(ctx->client, MSG_ERROR, msg, strlen(msg));
+ xfree(msg);
+}
+
+void
+server_msg_fn_command_print(struct cmd_ctx *ctx, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ server_write_client(ctx->client, MSG_PRINT, msg, strlen(msg));
+ xfree(msg);
+}
+
int
-server_msg_fn_new(struct hdr *hdr, struct client *c)
+server_msg_fn_command(struct hdr *hdr, struct client *c)
{
- struct new_data data;
- char *msg;
-
- if (c->session != NULL)
- return (0);
- if (hdr->size != sizeof data)
- fatalx("bad MSG_NEW size");
+ struct msg_command_data data;
+ struct cmd_ctx ctx;
+ struct cmd *cmd;
+ char *cause;
+
+ if (hdr->size < sizeof data)
+ fatalx("bad MSG_COMMAND size");
buffer_read(c->in, &data, sizeof data);
- c->sx = data.sx;
- if (c->sx == 0)
- c->sx = 80;
- c->sy = data.sy;
- if (c->sy == 0)
- c->sy = 25;
+ cmd = cmd_recv(c->in);
+ log_debug("got command %u %s from client %d",
+ cmd->entry->type, cmd->entry->name, c->fd);
- if (c->sy >= status_lines)
- c->sy -= status_lines;
+ if (cmd->entry->flags & CMD_NOSESSION)
+ ctx.session = NULL;
+ else {
+ ctx.session = server_find_sessid(&data.sid, &cause);
+ if (ctx.session == NULL) {
+ server_write_error(c, "%s", cause);
+ xfree(cause);
+ return (0);
+ }
+ }
- data.name[(sizeof data.name) - 1] = '\0';
- if (*data.name != '\0' && session_find(data.name) != NULL) {
- xasprintf(&msg, "duplicate session: %s", data.name);
- server_write_client(c, MSG_ERROR, msg, strlen(msg));
- xfree(msg);
- return (0);
- }
+ ctx.error = server_msg_fn_command_error;
+ ctx.print = server_msg_fn_command_print;
- c->session = session_create(data.name, default_command, c->sx, c->sy);
- if (c->session == NULL)
- fatalx("session_create failed");
+ ctx.client = c;
+ ctx.flags = 0;
- server_write_client(c, MSG_OKAY, NULL, 0);
- server_draw_client(c, 0, c->sy - 1);
+ cmd_exec(cmd, &ctx);
+ cmd_free(cmd);
return (0);
}
-/* Attach message from client. */
int
-server_msg_fn_attach(struct hdr *hdr, struct client *c)
+server_msg_fn_identify(struct hdr *hdr, struct client *c)
{
- struct attach_data data;
- char *cause;
-
- if (c->session != NULL)
- return (0);
- if (hdr->size != sizeof data)
- fatalx("bad MSG_ATTACH size");
+ struct msg_identify_data data;
+
+ if (hdr->size < sizeof data)
+ fatalx("bad MSG_IDENTIFY size");
buffer_read(c->in, &data, sizeof data);
+ log_debug("got identify msg from client: %u,%u", data.sx, data.sy);
+
c->sx = data.sx;
- if (c->sx == 0)
- c->sx = 80;
c->sy = data.sy;
- if (c->sy == 0)
- c->sy = 25;
-
- if (c->sy >= status_lines)
- c->sy -= status_lines;
-
- if ((c->session = server_find_sessid(&data.sid, &cause)) == NULL) {
- server_write_error(c, "%s", cause);
- xfree(cause);
- return (0);
- }
- server_draw_client(c, 0, c->sy - 1);
+ c->flags |= CLIENT_TERMINAL;
return (0);
}
-/* Size message from client. */
int
-server_msg_fn_size(struct hdr *hdr, struct client *c)
+server_msg_fn_resize(struct hdr *hdr, struct client *c)
{
- struct size_data data;
+ struct msg_resize_data data;
+ u_int sy;
- if (c->session == NULL)
- return (0);
if (hdr->size != sizeof data)
fatalx("bad MSG_SIZE size");
buffer_read(c->in, &data, sizeof data);
@@ -177,265 +177,47 @@ server_msg_fn_size(struct hdr *hdr, struct client *c)
if (c->sy == 0)
c->sy = 25;
- if (c->sy >= status_lines)
- c->sy -= status_lines;
+ sy = c->sy;
+ if (sy < status_lines)
+ sy = status_lines + 1;
+ sy -= status_lines;
- if (window_resize(c->session->window, c->sx, c->sy) != 0)
- server_draw_client(c, 0, c->sy - 1);
+ if (window_resize(c->session->window, c->sx, sy) != 0)
+ server_draw_client(c);
return (0);
}
-/* Keys message from client. */
int
server_msg_fn_keys(struct hdr *hdr, struct client *c)
{
int key;
size_t size;
- if (c->session == NULL)
- return (0);
if (hdr->size & 0x1)
fatalx("bad MSG_KEYS size");
+ if (c->flags & CLIENT_HOLD) {
+ server_draw_client(c);
+ c->flags &= ~CLIENT_HOLD;
+ }
+
size = hdr->size;
while (size != 0) {
key = (int16_t) input_extract16(c->in);
size -= 2;
- if (c->prefix) {
- cmd_dispatch(c, key);
- c->prefix = 0;
+ if (c->flags & CLIENT_PREFIX) {
+ key_bindings_dispatch(key, c);
+ c->flags &= ~CLIENT_PREFIX;
continue;
}
- if (key == cmd_prefix)
- c->prefix = 1;
+ if (key == prefix_key)
+ c->flags |= CLIENT_PREFIX;
else
window_key(c->session->window, key);
}
return (0);
}
-
-/* Sessions message from client. */
-int
-server_msg_fn_sessions(struct hdr *hdr, struct client *c)
-{
- struct sessions_data data;
- struct sessions_entry entry;
- struct session *s;
- u_int i, j;
-
- if (hdr->size != sizeof data)
- fatalx("bad MSG_SESSIONS size");
- buffer_read(c->in, &data, sizeof data);
-
- data.sessions = 0;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if (ARRAY_ITEM(&sessions, i) != NULL)
- data.sessions++;
- }
- server_write_client2(c, MSG_SESSIONS,
- &data, sizeof data, NULL, data.sessions * sizeof entry);
-
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- s = ARRAY_ITEM(&sessions, i);
- if (s == NULL)
- continue;
- strlcpy(entry.name, s->name, sizeof entry.name);
- entry.tim = s->tim;
- entry.windows = 0;
- for (j = 0; j < ARRAY_LENGTH(&s->windows); j++) {
- if (ARRAY_ITEM(&s->windows, j) != NULL)
- entry.windows++;
- }
- buffer_write(c->out, &entry, sizeof entry);
- }
-
- return (0);
-}
-
-/* Windows message from client. */
-int
-server_msg_fn_windows(struct hdr *hdr, struct client *c)
-{
- struct windows_data data;
- struct windows_entry entry;
- struct session *s;
- struct window *w;
- u_int i;
- char *cause;
-
- if (hdr->size != sizeof data)
- fatalx("bad MSG_WINDOWS size");
- buffer_read(c->in, &data, sizeof data);
-
- if ((s = server_find_sessid(&data.sid, &cause)) == NULL) {
- server_write_error(c, "%s", cause);
- xfree(cause);
- return (0);
- }
-
- data.windows = 0;
- for (i = 0; i < ARRAY_LENGTH(&s->windows); i++) {
- if (ARRAY_ITEM(&s->windows, i) != NULL)
- data.windows++;
- }
- server_write_client2(c, MSG_WINDOWS,
- &data, sizeof data, NULL, data.windows * sizeof entry);
-
- for (i = 0; i < ARRAY_LENGTH(&s->windows); i++) {
- w = ARRAY_ITEM(&s->windows, i);
- if (w == NULL)
- continue;
- entry.idx = i;
- strlcpy(entry.name, w->name, sizeof entry.name);
- strlcpy(entry.title, w->screen.title, sizeof entry.title);
- if (ttyname_r(w->fd, entry.tty, sizeof entry.tty) != 0)
- *entry.tty = '\0';
- buffer_write(c->out, &entry, sizeof entry);
- }
-
- return (0);
-}
-
-/* Rename message from client. */
-int
-server_msg_fn_rename(struct hdr *hdr, struct client *c)
-{
- struct rename_data data;
- char *cause;
- struct window *w;
- struct session *s;
- u_int i;
-
- if (hdr->size != sizeof data)
- fatalx("bad MSG_RENAME size");
- buffer_read(c->in, &data, sizeof data);
-
- data.newname[(sizeof data.newname) - 1] = '\0';
- if ((s = server_find_sessid(&data.sid, &cause)) == NULL) {
- server_write_error(c, "%s", cause);
- xfree(cause);
- return (0);
- }
-
- if (data.idx == -1)
- w = s->window;
- else {
- if (data.idx < 0)
- fatalx("bad window index");
- w = window_at(&s->windows, data.idx);
- if (w == NULL) {
- server_write_error(c, "window not found: %d", data.idx);
- return (0);
- }
- }
-
- strlcpy(w->name, data.newname, sizeof w->name);
-
- server_write_client(c, MSG_OKAY, NULL, 0);
- for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
- c = ARRAY_ITEM(&clients, i);
- if (c != NULL && c->session != NULL) {
- if (session_has(c->session, w))
- server_draw_status(c);
- }
- }
-
- return (0);
-}
-
-/* Window list message from client */
-int
-server_msg_fn_windowlist(struct hdr *hdr, struct client *c)
-{
- struct window *w;
- char *buf;
- size_t len, off;
- u_int i;
-
- if (c->session == NULL)
- return (0);
- if (hdr->size != 0)
- fatalx("bad MSG_WINDOWLIST size");
-
- len = c->sx + 1;
- buf = xmalloc(len);
- off = 0;
-
- *buf = '\0';
- for (i = 0; i < ARRAY_LENGTH(&c->session->windows); i++) {
- w = ARRAY_ITEM(&c->session->windows, i);
- if (w == NULL)
- continue;
- off += xsnprintf(buf + off, len - off, "%u:%s%s ", i, w->name,
- w == c->session->window ? "*" : "");
- if (off >= len)
- break;
- }
-
- server_write_message(c, "%s", buf);
- xfree(buf);
-
- return (0);
-}
-
-/* Bind key message from client */
-int
-server_msg_fn_bindkey(struct hdr *hdr, struct client *c)
-{
- struct bind_data data;
- const struct bind *bind;
- char *str;
-
- if (hdr->size < sizeof data)
- fatalx("bad MSG_BINDKEY size");
- buffer_read(c->in, &data, sizeof data);
-
- str = NULL;
- if (data.flags & BIND_STRING) {
- hdr->size -= sizeof data;
-
- str = xmemstrdup(BUFFER_OUT(c->in), hdr->size);
- if (hdr->size > 0)
- buffer_remove(c->in, hdr->size);
- }
-
- data.cmd[(sizeof data.cmd) - 1] = '\0';
- if ((bind = cmd_lookup_bind(data.cmd)) == NULL)
- fatalx("unknown command");
- if (!(bind->flags & BIND_USER) &&
- (data.flags & (BIND_NUMBER|BIND_STRING)) != 0)
- fatalx("argument missing");
- if ((bind->flags & BIND_USER) &&
- (data.flags & (BIND_NUMBER|BIND_STRING)) == 0)
- fatalx("argument required");
-
- cmd_add_bind(data.key, data.num, str, bind);
- if (str != NULL)
- xfree(str);
-
- server_write_client(c, MSG_OKAY, NULL, 0);
-
- return (0);
-}
-
-/* Unbind key message from client */
-int
-server_msg_fn_unbindkey(struct hdr *hdr, struct client *c)
-{
- struct bind_data data;
-
- if (hdr->size != sizeof data)
- fatalx("bad MSG_UNBINDKEY size");
-
- buffer_read(c->in, &data, hdr->size);
-
- cmd_remove_bind(data.key);
-
- server_write_client(c, MSG_OKAY, NULL, 0);
-
- return (0);
-}