aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES16
-rw-r--r--Makefile10
-rw-r--r--TODO7
-rw-r--r--cfg.c212
-rw-r--r--cmd-attach-session.c34
-rw-r--r--cmd-bind-key.c15
-rw-r--r--cmd-copy-mode.c22
-rw-r--r--cmd-detach-client.c24
-rw-r--r--cmd-generic.c175
-rw-r--r--cmd-has-session.c7
-rw-r--r--cmd-kill-session.c25
-rw-r--r--cmd-kill-window.c40
-rw-r--r--cmd-last-window.c26
-rw-r--r--cmd-link-window.c59
-rw-r--r--cmd-list-clients.c7
-rw-r--r--cmd-list-keys.c7
-rw-r--r--cmd-list-sessions.c4
-rw-r--r--cmd-list-windows.c21
-rw-r--r--cmd-new-session.c12
-rw-r--r--cmd-new-window.c40
-rw-r--r--cmd-next-window.c26
-rw-r--r--cmd-paste-buffer.c30
-rw-r--r--cmd-previous-window.c26
-rw-r--r--cmd-refresh-client.c22
-rw-r--r--cmd-rename-session.c34
-rw-r--r--cmd-rename-window.c37
-rw-r--r--cmd-scroll-mode.c24
-rw-r--r--cmd-select-window.c35
-rw-r--r--cmd-send-keys.c29
-rw-r--r--cmd-send-prefix.c22
-rw-r--r--cmd-set-option.c15
-rw-r--r--cmd-swap-window.c47
-rw-r--r--cmd-switch-client.c35
-rw-r--r--cmd-unbind-key.c15
-rw-r--r--cmd-unlink-window.c40
-rw-r--r--cmd.c91
-rw-r--r--key-bindings.c10
-rw-r--r--server-fn.c53
-rw-r--r--server-msg.c63
-rw-r--r--server.c12
-rw-r--r--tmux.c46
-rw-r--r--tmux.h48
42 files changed, 1086 insertions, 437 deletions
diff --git a/CHANGES b/CHANGES
index f284576e..93b3dafc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,17 @@
+02 June 2008
+
+* BIG CHANGE: -s and -c to specify session name and client name are now passed
+ after the command rather than before it. So, for example:
+
+ tmux -s0 neww
+
+ Becomes:
+
+ tmux neww -s0
+
+ This is to allow them to be used in the (forthcoming) configuration file
+ THIS WILL BREAK ANY CURRENT SCRIPTS OR ALIASES USING -s OR -c.
+
01 June 2008
* Bug fix: don't die if -k passed to link-window and the destination doesn't
@@ -316,4 +330,4 @@
(including mutt, emacs). No status bar yet and no key remapping or other
customisation.
-$Id: CHANGES,v 1.96 2008-06-01 20:32:41 nicm Exp $
+$Id: CHANGES,v 1.97 2008-06-02 18:08:16 nicm Exp $
diff --git a/Makefile b/Makefile
index 3301b558..c32e7201 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.53 2008-06-01 20:20:25 nicm Exp $
+# $Id: Makefile,v 1.54 2008-06-02 18:08:16 nicm Exp $
.SUFFIXES: .c .o .y .h
.PHONY: clean update-index.html upload-index.html
@@ -17,8 +17,8 @@ META?= \002 # C-b
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c input.c input-keys.c screen.c screen-display.c \
- window.c session.c log.c client.c client-msg.c client-fn.c \
- key-string.c key-bindings.c resize.c cmd.c cmd-new-session.c \
+ window.c session.c log.c client.c client-msg.c client-fn.c cfg.c \
+ key-string.c key-bindings.c resize.c cmd.c cmd-generic.c \
cmd-detach-client.c cmd-list-sessions.c cmd-new-window.c cmd-bind-key.c \
cmd-unbind-key.c cmd-previous-window.c cmd-last-window.c cmd-list-keys.c \
cmd-set-option.c cmd-rename-window.c cmd-select-window.c \
@@ -27,8 +27,8 @@ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
cmd-link-window.c cmd-unlink-window.c cmd-next-window.c cmd-send-keys.c \
cmd-swap-window.c cmd-rename-session.c cmd-kill-session.c \
cmd-switch-client.c cmd-has-session.c cmd-scroll-mode.c cmd-copy-mode.c \
- cmd-paste-buffer.c window-scroll.c window-more.c window-copy.c \
- tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
+ cmd-paste-buffer.c cmd-new-session.c window-scroll.c window-more.c \
+ window-copy.c tty.c tty-keys.c tty-write.c screen-write.c screen-redraw.c
CC?= cc
INCDIRS+= -I. -I- -I/usr/local/include
diff --git a/TODO b/TODO
index 6234eb0b..4fcdc6fc 100644
--- a/TODO
+++ b/TODO
@@ -70,6 +70,13 @@
- poll(2) is broken on OS X/Darwin, a workaround for this would be nice
- different screen model? layers perhaps? hmm
+---
+[18:20] *priteau* i found something in tmux that could be tweaked to be better
+[18:21] *priteau* in screen, when you type ^A-D, you can actually keep ctrl down
+ when typing the D
+[18:21] *priteau* in tmux, you have to release ctrl for the command to work
+---
+
-- For 0.3 --------------------------------------------------------------------
- chmod +x socket when any client is attached (upd in lost/accept)
- clear EOL etc CANNOT rely on term using the current colour/attr and probably
diff --git a/cfg.c b/cfg.c
new file mode 100644
index 00000000..4b4b2476
--- /dev/null
+++ b/cfg.c
@@ -0,0 +1,212 @@
+/* $Id: cfg.c,v 1.1 2008-06-02 18:08:16 nicm Exp $ */
+
+/*
+ * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "tmux.h"
+
+/*
+ * Config file parser. Pretty quick and simple, each line is parsed into a
+ * argv array and executed as a command.
+ */
+
+char *cfg_string(FILE *, char, int);
+void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
+void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
+
+void printflike2
+cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
+{
+}
+
+void printflike2
+cfg_error(struct cmd_ctx *ctx, const char *fmt, ...)
+{
+ va_list ap;
+ char *msg;
+
+ va_start(ap, fmt);
+ xvasprintf(&msg, fmt, ap);
+ va_end(ap);
+
+ *msg = toupper((u_char) *msg);
+ // XXX
+ log_warnx("%s", msg);
+ xfree(msg);
+}
+
+int
+load_cfg(const char *path, char **cause)
+{
+ FILE *f;
+ int ch, argc;
+ u_int line;
+ char **argv, *buf, *s;
+ size_t len;
+ struct cmd *cmd;
+ struct cmd_ctx ctx;
+
+ if ((f = fopen(path, "rb")) == NULL) {
+ xasprintf(cause, "%s: %s", path, strerror(errno));
+ return (1);
+ }
+
+ argv = NULL;
+ argc = 0;
+
+ buf = NULL;
+ len = 0;
+
+ line = 1;
+ while ((ch = getc(f)) != EOF) {
+ switch (ch) {
+ case '#':
+ /* Comment: discard until EOL. */
+ while ((ch = getc(f)) != '\n' && ch != EOF)
+ ;
+ line++;
+ break;
+ case '\'':
+ if ((s = cfg_string(f, '\'', 0)) == NULL)
+ goto error;
+ argv = xrealloc(argv, argc + 1, sizeof (char *));
+ argv[argc++] = s;
+ break;
+ case '"':
+ if ((s = cfg_string(f, '"', 1)) == NULL)
+ goto error;
+ argv = xrealloc(argv, argc + 1, sizeof (char *));
+ argv[argc++] = s;
+ break;
+ case '\n':
+ case EOF:
+ case ' ':
+ case '\t':
+ if (len == 0)
+ break;
+ buf[len] = '\0';
+
+ argv = xrealloc(argv, argc + 1, sizeof (char *));
+ argv[argc++] = buf;
+
+ buf = NULL;
+ len = 0;
+
+ if (ch != '\n' && ch != EOF)
+ break;
+ line++;
+
+ if ((cmd = cmd_parse(argc, argv, cause)) == NULL) {
+ if (*cause != NULL)
+ xfree(*cause); /* XXX */
+ goto error;
+ }
+
+ ctx.cursession = NULL;
+ ctx.curclient = NULL;
+
+ ctx.error = cfg_error;
+ ctx.print = cfg_print;
+
+ ctx.cmdclient = NULL;
+ ctx.flags = CMD_KEY;
+
+ cmd_exec(cmd, &ctx);
+
+ cmd_free(cmd);
+
+ while (--argc >= 0)
+ xfree(argv[argc]);
+ argc = 0;
+ break;
+ default:
+ if (len >= SIZE_MAX - 2)
+ goto error;
+
+ buf = xrealloc(buf, 1, len + 1);
+ buf[len++] = ch;
+ break;
+ }
+ }
+
+ fclose(f);
+
+ return (0);
+
+error:
+ while (--argc > 0)
+ xfree(argv[argc]);
+ xfree(argv);
+
+ if (buf != NULL)
+ xfree(buf);
+
+ xasprintf(cause, "%s: error at line %u", path, line);
+ return (1);
+}
+
+char *
+cfg_string(FILE *f, char endch, int esc)
+{
+ int ch;
+ char *buf;
+ size_t len;
+
+ buf = NULL;
+ len = 0;
+
+ while ((ch = getc(f)) != endch) {
+ switch (ch) {
+ case EOF:
+ xfree(buf);
+ return (NULL);
+ case '\\':
+ if (!esc)
+ break;
+ switch (ch = getc(f)) {
+ case EOF:
+ xfree(buf);
+ return (NULL);
+ case 'r':
+ ch = '\r';
+ break;
+ case 'n':
+ ch = '\n';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ }
+ break;
+ }
+
+ if (len >= SIZE_MAX - 2) {
+ xfree(buf);
+ return (NULL);
+ }
+ buf = xrealloc(buf, 1, len + 1);
+ buf[len++] = ch;
+ }
+
+ buf[len] = '\0';
+ return (buf);
+}
diff --git a/cmd-attach-session.c b/cmd-attach-session.c
index 1741b36e..e9c336df 100644
--- a/cmd-attach-session.c
+++ b/cmd-attach-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-attach-session.c,v 1.11 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-attach-session.c,v 1.12 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,19 +26,21 @@
* Attach existing session to the current terminal.
*/
-int cmd_attach_session_parse(void **, int, char **, char **);
+int cmd_attach_session_parse(struct cmd *, void **, int, char **, char **);
void cmd_attach_session_exec(void *, struct cmd_ctx *);
void cmd_attach_session_send(void *, struct buffer *);
void cmd_attach_session_recv(void **, struct buffer *);
void cmd_attach_session_free(void *);
struct cmd_attach_session_data {
+ char *sname;
int flag_detach;
};
const struct cmd_entry cmd_attach_session_entry = {
- "attach-session", "attach", "[-d]",
- CMD_CANTNEST|CMD_NOCLIENT,
+ "attach-session", "attach",
+ "[-d] [-s session-name]",
+ CMD_CANTNEST,
cmd_attach_session_parse,
cmd_attach_session_exec,
cmd_attach_session_send,
@@ -47,19 +49,24 @@ const struct cmd_entry cmd_attach_session_entry = {
};
int
-cmd_attach_session_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_attach_session_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_attach_session_data *data;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->flag_detach = 0;
- while ((opt = getopt(argc, argv, "dn:")) != EOF) {
+ while ((opt = getopt(argc, argv, "ds:")) != EOF) {
switch (opt) {
case 'd':
data->flag_detach = 1;
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -72,8 +79,7 @@ cmd_attach_session_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_attach_session_entry.name, cmd_attach_session_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_attach_session_free(data);
return (-1);
@@ -83,11 +89,15 @@ void
cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_attach_session_data *data = ptr;
+ struct session *s;
char *cause;
if (ctx->flags & CMD_KEY)
return;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if (!(ctx->cmdclient->flags & CLIENT_TERMINAL)) {
ctx->error(ctx, "not a terminal");
return;
@@ -100,8 +110,8 @@ cmd_attach_session_exec(void *ptr, struct cmd_ctx *ctx)
}
if (data->flag_detach)
- server_write_session(ctx->session, MSG_DETACH, NULL, 0);
- ctx->cmdclient->session = ctx->session;
+ server_write_session(s, MSG_DETACH, NULL, 0);
+ ctx->cmdclient->session = s;
server_write_client(ctx->cmdclient, MSG_READY, NULL, 0);
recalculate_sizes();
@@ -114,6 +124,7 @@ cmd_attach_session_send(void *ptr, struct buffer *b)
struct cmd_attach_session_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
}
void
@@ -123,6 +134,7 @@ cmd_attach_session_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
}
void
@@ -130,5 +142,7 @@ cmd_attach_session_free(void *ptr)
{
struct cmd_attach_session_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
xfree(data);
}
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 537a12f5..cff6c445 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-bind-key.c,v 1.8 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-bind-key.c,v 1.9 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,7 @@
* Bind a key to a command, this recurses through cmd_*.
*/
-int cmd_bind_key_parse(void **, int, char **, char **);
+int cmd_bind_key_parse(struct cmd *, void **, int, char **, char **);
void cmd_bind_key_exec(void *, struct cmd_ctx *);
void cmd_bind_key_send(void *, struct buffer *);
void cmd_bind_key_recv(void **, struct buffer *);
@@ -38,8 +38,9 @@ struct cmd_bind_key_data {
};
const struct cmd_entry cmd_bind_key_entry = {
- "bind-key", "bind", "key command [arguments]",
- CMD_NOCLIENT|CMD_NOSESSION,
+ "bind-key", "bind",
+ "key command [arguments]",
+ 0,
cmd_bind_key_parse,
cmd_bind_key_exec,
cmd_bind_key_send,
@@ -48,7 +49,8 @@ const struct cmd_entry cmd_bind_key_entry = {
};
int
-cmd_bind_key_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_bind_key_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_bind_key_data *data;
int opt;
@@ -80,8 +82,7 @@ cmd_bind_key_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_bind_key_entry.name, cmd_bind_key_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_bind_key_free(data);
diff --git a/cmd-copy-mode.c b/cmd-copy-mode.c
index e9b30022..84d5c748 100644
--- a/cmd-copy-mode.c
+++ b/cmd-copy-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-copy-mode.c,v 1.4 2007-12-06 10:04:42 nicm Exp $ */
+/* $Id: cmd-copy-mode.c,v 1.5 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,22 +30,26 @@
void cmd_copy_mode_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_copy_mode_entry = {
- "copy-mode", NULL, "",
- CMD_NOCLIENT,
- NULL,
+ "copy-mode", NULL,
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_copy_mode_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
cmd_copy_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
{
- struct window *w = ctx->session->curw->window;
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
if (ctx->flags & CMD_KEY)
- window_set_mode(w, &window_copy_mode);
+ window_set_mode(s->curw->window, &window_copy_mode);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-detach-client.c b/cmd-detach-client.c
index 64a31b85..fd0e5f55 100644
--- a/cmd-detach-client.c
+++ b/cmd-detach-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-detach-client.c,v 1.1 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-detach-client.c,v 1.2 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,19 +29,25 @@
void cmd_detach_client_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_detach_client_entry = {
- "detach-client", "detach", "",
- CMD_NOSESSION,
- NULL,
+ "detach-client", "detach",
+ CMD_CLIENTONLY_USAGE,
+ 0,
+ cmd_clientonly_parse,
cmd_detach_client_exec,
- NULL,
- NULL,
- NULL
+ cmd_clientonly_send,
+ cmd_clientonly_recv,
+ cmd_clientonly_free
};
void
-cmd_detach_client_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_detach_client_exec(void *ptr, struct cmd_ctx *ctx)
{
- server_write_client(ctx->client, MSG_DETACH, NULL, 0);
+ struct client *c;
+
+ if ((c = cmd_clientonly_get(ptr, ctx)) == NULL)
+ return;
+
+ server_write_client(c, MSG_DETACH, NULL, 0);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-generic.c b/cmd-generic.c
new file mode 100644
index 00000000..49d0f9a4
--- /dev/null
+++ b/cmd-generic.c
@@ -0,0 +1,175 @@
+/* $Id: cmd-generic.c,v 1.1 2008-06-02 18:08:16 nicm Exp $ */
+
+/*
+ * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <getopt.h>
+
+#include "tmux.h"
+
+struct cmd_clientonly_data {
+ char *cname;
+};
+
+struct cmd_sessiononly_data {
+ char *sname;
+};
+
+int
+cmd_clientonly_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
+{
+ struct cmd_clientonly_data *data;
+ int opt;
+
+ *ptr = data = xmalloc(sizeof *data);
+ data->cname = NULL;
+
+ while ((opt = getopt(argc, argv, "c:")) != EOF) {
+ switch (opt) {
+ case 'c':
+ data->cname = xstrdup(optarg);
+ break;
+ default:
+ goto usage;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 0)
+ goto usage;
+
+ return (0);
+
+usage:
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
+
+ self->entry->free(data);
+ return (-1);
+}
+
+void
+cmd_clientonly_send(void *ptr, struct buffer *b)
+{
+ struct cmd_clientonly_data *data = ptr;
+
+ buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->cname);
+}
+
+void
+cmd_clientonly_recv(void **ptr, struct buffer *b)
+{
+ struct cmd_clientonly_data *data;
+
+ *ptr = data = xmalloc(sizeof *data);
+ buffer_read(b, data, sizeof *data);
+ data->cname = cmd_recv_string(b);
+}
+
+void
+cmd_clientonly_free(void *ptr)
+{
+ struct cmd_clientonly_data *data = ptr;
+
+ if (data->cname != NULL)
+ xfree(data->cname);
+ xfree(data);
+}
+
+struct client *
+cmd_clientonly_get(void *ptr, struct cmd_ctx *ctx)
+{
+ struct cmd_clientonly_data *data = ptr;
+
+ if (data != NULL)
+ return (cmd_find_client(ctx, data->cname));
+ return (cmd_find_client(ctx, NULL));
+}
+
+int
+cmd_sessiononly_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
+{
+ struct cmd_sessiononly_data *data;
+ int opt;
+
+ *ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
+
+ while ((opt = getopt(argc, argv, "s:")) != EOF) {
+ switch (opt) {
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
+ default:
+ goto usage;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc != 0)
+ goto usage;
+
+ return (0);
+
+usage:
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
+
+ self->entry->free(data);
+ return (-1);
+}
+
+void
+cmd_sessiononly_send(void *ptr, struct buffer *b)
+{
+ struct cmd_sessiononly_data *data = ptr;
+
+ buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
+}
+
+void
+cmd_sessiononly_recv(void **ptr, struct buffer *b)
+{
+ struct cmd_sessiononly_data *data;
+
+ *ptr = data = xmalloc(sizeof *data);
+ buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
+}
+
+void
+cmd_sessiononly_free(void *ptr)
+{
+ struct cmd_sessiononly_data *data = ptr;
+
+ if (data->sname != NULL)
+ xfree(data->sname);
+ xfree(data);
+}
+
+struct session *
+cmd_sessiononly_get(void *ptr, struct cmd_ctx *ctx)
+{
+ struct cmd_sessiononly_data *data = ptr;
+
+ if (data != NULL)
+ return (cmd_find_session(ctx, data->sname));
+ return (cmd_find_session(ctx, NULL));
+}
diff --git a/cmd-has-session.c b/cmd-has-session.c
index b6d3fdf5..b7d14a48 100644
--- a/cmd-has-session.c
+++ b/cmd-has-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-has-session.c,v 1.3 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-has-session.c,v 1.4 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,8 +32,9 @@
void cmd_has_session_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_has_session_entry = {
- "has-session", "has", "",
- CMD_NOCLIENT,
+ "has-session", "has",
+ "",
+ 0,
NULL,
cmd_has_session_exec,
NULL,
diff --git a/cmd-kill-session.c b/cmd-kill-session.c
index 21cb6025..cb9bf33f 100644
--- a/cmd-kill-session.c
+++ b/cmd-kill-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-session.c,v 1.5 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-kill-session.c,v 1.6 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -33,30 +33,35 @@
void cmd_kill_session_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_kill_session_entry = {
- "kill-session", NULL, "",
- CMD_NOCLIENT,
- NULL,
+ "kill-session", NULL,
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_kill_session_exec,
- NULL,
- NULL,
- NULL,
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_kill_session_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_kill_session_exec(void *ptr, struct cmd_ctx *ctx)
{
+ struct session *s;
struct client *c;
u_int i;
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
- if (c->session == ctx->session) {
+ if (c->session == s) {
c->session = NULL;
server_write_client(c, MSG_EXIT, NULL, 0);
}
}
- session_destroy(ctx->session);
+ session_destroy(s);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-kill-window.c b/cmd-kill-window.c
index 13742e19..5370fdc3 100644
--- a/cmd-kill-window.c
+++ b/cmd-kill-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-kill-window.c,v 1.7 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-kill-window.c,v 1.8 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,19 +27,21 @@
* Destroy window.
*/
-int cmd_kill_window_parse(void **, int, char **, char **);
+int cmd_kill_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_kill_window_exec(void *, struct cmd_ctx *);
void cmd_kill_window_send(void *, struct buffer *);
void cmd_kill_window_recv(void **, struct buffer *);
void cmd_kill_window_free(void *);
struct cmd_kill_window_data {
+ char *sname;
int idx;
};
const struct cmd_entry cmd_kill_window_entry = {
- "kill-window", "killw", "[-i index]",
- CMD_NOCLIENT,
+ "kill-window", "killw",
+ "[-i index] [-s session-name]",
+ 0,
cmd_kill_window_parse,
cmd_kill_window_exec,
cmd_kill_window_send,
@@ -48,16 +50,18 @@ const struct cmd_entry cmd_kill_window_entry = {
};
int
-cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_kill_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_kill_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->idx = -1;
- while ((opt = getopt(argc, argv, "i:")) != EOF) {
+ while ((opt = getopt(argc, argv, "i:s:")) != EOF) {
switch (opt) {
case 'i':
data->idx = strtonum(optarg, 0, INT_MAX, &errstr);
@@ -66,6 +70,9 @@ cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause)
goto error;
}
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -78,8 +85,7 @@ cmd_kill_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_kill_window_entry.name, cmd_kill_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_kill_window_free(data);
@@ -89,9 +95,9 @@ error:
void
cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx)
{
- struct cmd_kill_window_data *data = ptr, std = { -1 };
+ struct cmd_kill_window_data *data = ptr, std = { NULL, -1 };
+ struct session *s;
struct client *c;
- struct winlinks *wwl = &ctx->session->windows;
struct winlink *wl;
u_int i;
int destroyed;
@@ -99,17 +105,20 @@ cmd_kill_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
data = &std;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if (data->idx == -1)
- wl = ctx->session->curw;
- else if ((wl = winlink_find_by_index(wwl, data->idx)) == NULL) {
+ wl = s->curw;
+ else if ((wl = winlink_find_by_index(&s->windows, data->idx)) == NULL) {
ctx->error(ctx, "no window %d", data->idx);
return;
}
- destroyed = session_detach(ctx->session, wl);
+ destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
- if (c == NULL || c->session != ctx->session)
+ if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
@@ -128,6 +137,7 @@ cmd_kill_window_send(void *ptr, struct buffer *b)
struct cmd_kill_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
}
void
@@ -144,5 +154,7 @@ cmd_kill_window_free(void *ptr)
{
struct cmd_kill_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
xfree(data);
}
diff --git a/cmd-last-window.c b/cmd-last-window.c
index e68289cd..88e0a538 100644
--- a/cmd-last-window.c
+++ b/cmd-last-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-last-window.c,v 1.6 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-last-window.c,v 1.7 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,20 +30,26 @@
void cmd_last_window_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_last_window_entry = {
- "last-window", "last", "",
- CMD_NOCLIENT,
- NULL,
+ "last-window", "last",
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_last_window_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_last_window_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_last_window_exec(void *ptr, struct cmd_ctx *ctx)
{
- if (session_last(ctx->session) == 0)
- server_redraw_session(ctx->session);
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
+ if (session_last(s) == 0)
+ server_redraw_session(s);
else
ctx->error(ctx, "no last window");
diff --git a/cmd-link-window.c b/cmd-link-window.c
index 45cb4876..72b2e03b 100644
--- a/cmd-link-window.c
+++ b/cmd-link-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-link-window.c,v 1.10 2008-06-01 20:32:41 nicm Exp $ */
+/* $Id: cmd-link-window.c,v 1.11 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,13 +27,14 @@
* Link a window into another session.
*/
-int cmd_link_window_parse(void **, int, char **, char **);
+int cmd_link_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_link_window_exec(void *, struct cmd_ctx *);
void cmd_link_window_send(void *, struct buffer *);
void cmd_link_window_recv(void **, struct buffer *);
void cmd_link_window_free(void *);
struct cmd_link_window_data {
+ char *sname;
int flag_detached;
int flag_kill;
int dstidx;
@@ -42,8 +43,9 @@ struct cmd_link_window_data {
};
const struct cmd_entry cmd_link_window_entry = {
- "link-window", "linkw", "[-dk] [-i index] name index",
- CMD_NOCLIENT,
+ "link-window", "linkw",
+ "[-dk] [-s session-name] [-i index] session-name index",
+ 0,
cmd_link_window_parse,
cmd_link_window_exec,
cmd_link_window_send,
@@ -52,21 +54,26 @@ const struct cmd_entry cmd_link_window_entry = {
};
int
-cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_link_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_link_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->flag_detached = 0;
data->flag_kill = 0;
data->dstidx = -1;
data->srcidx = -1;
data->srcname = NULL;
- while ((opt = getopt(argc, argv, "dki:")) != EOF) {
+ while ((opt = getopt(argc, argv, "di:ks:")) != EOF) {
switch (opt) {
+ case 'd':
+ data->flag_detached = 1;
+ break;
case 'i':
data->dstidx = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
@@ -74,12 +81,12 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause)
goto error;
}
break;
- case 'd':
- data->flag_detached = 1;
- break;
case 'k':
data->flag_kill = 1;
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -99,8 +106,7 @@ cmd_link_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_link_window_entry.name, cmd_link_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_link_window_free(data);
@@ -111,12 +117,15 @@ void
cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_link_window_data *data = ptr;
- struct session *dst = ctx->session, *src;
+ struct session *s, *src;
struct winlink *wl, *wl2;
if (data == NULL)
return;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if ((src = session_find(data->srcname)) == NULL) {
ctx->error(ctx, "session not found: %s", data->srcname);
return;
@@ -137,7 +146,7 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data->dstidx < 0)
data->dstidx = -1;
if (data->flag_kill && data->dstidx != -1) {
- wl2 = winlink_find_by_index(&dst->windows, data->dstidx);
+ wl2 = winlink_find_by_index(&s->windows, data->dstidx);
if (wl2 == NULL) {
ctx->error(ctx, "no window %d", data->dstidx);
return;
@@ -147,16 +156,16 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
* Can't use session_detach as it will destroy session if this
* makes it empty.
*/
- session_cancelbell(dst, wl2);
- winlink_remove(&dst->windows, wl2);
+ session_cancelbell(s, wl2);
+ winlink_remove(&s->windows, wl2);
/* Force select/redraw if current. */
- if (wl2 == dst->curw) {
+ if (wl2 == s->curw) {
data->flag_detached = 0;
- dst->curw = NULL;
+ s->curw = NULL;
}
- if (wl2 == dst->lastw)
- dst->lastw = NULL;
+ if (wl2 == s->lastw)
+ s->lastw = NULL;
/*
* Can't error out after this or there could be an empty
@@ -164,17 +173,17 @@ cmd_link_window_exec(void *ptr, struct cmd_ctx *ctx)
*/
}
- wl = session_attach(dst, wl->window, data->dstidx);
+ wl = session_attach(s, wl->window, data->dstidx);
if (wl == NULL) {
ctx->error(ctx, "index in use: %d", data->dstidx);
return;
}
if (!data->flag_detached) {
- session_select(dst, wl->idx);
- server_redraw_session(dst);
+ session_select(s, wl->idx);
+ server_redraw_session(s);
} else
- server_status_session(dst);
+ server_status_session(s);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -186,6 +195,7 @@ cmd_link_window_send(void *ptr, struct buffer *b)
struct cmd_link_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
cmd_send_string(b, data->srcname);
}
@@ -196,6 +206,7 @@ cmd_link_window_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
data->srcname = cmd_recv_string(b);
}
@@ -204,6 +215,8 @@ cmd_link_window_free(void *ptr)
{
struct cmd_link_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
if (data->srcname != NULL)
xfree(data->srcname);
xfree(data);
diff --git a/cmd-list-clients.c b/cmd-list-clients.c
index 54743c42..e3624b2f 100644
--- a/cmd-list-clients.c
+++ b/cmd-list-clients.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-clients.c,v 1.3 2007-11-27 19:23:33 nicm Exp $ */
+/* $Id: cmd-list-clients.c,v 1.4 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,8 +31,9 @@
void cmd_list_clients_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_list_clients_entry = {
- "list-clients", "lsc", "",
- CMD_NOCLIENT|CMD_NOSESSION,
+ "list-clients", "lsc",
+ "",
+ 0,
NULL,
cmd_list_clients_exec,
NULL,
diff --git a/cmd-list-keys.c b/cmd-list-keys.c
index f4bb6bf1..c5d622e9 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-keys.c,v 1.5 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-list-keys.c,v 1.6 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,8 +30,9 @@
void cmd_list_keys_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_list_keys_entry = {
- "list-keys", "lsk", "",
- CMD_NOCLIENT|CMD_NOSESSION,
+ "list-keys", "lsk",
+ "",
+ 0,
NULL,
cmd_list_keys_exec,
NULL,
diff --git a/cmd-list-sessions.c b/cmd-list-sessions.c
index 8b9fd201..2c86d7e5 100644
--- a/cmd-list-sessions.c
+++ b/cmd-list-sessions.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-sessions.c,v 1.9 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-list-sessions.c,v 1.10 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -32,7 +32,7 @@ void cmd_list_sessions_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_list_sessions_entry = {
"list-sessions", "ls", "",
- CMD_NOCLIENT|CMD_NOSESSION,
+ 0,
NULL,
cmd_list_sessions_exec,
NULL,
diff --git a/cmd-list-windows.c b/cmd-list-windows.c
index 056af295..55d5a92f 100644
--- a/cmd-list-windows.c
+++ b/cmd-list-windows.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-list-windows.c,v 1.15 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-list-windows.c,v 1.16 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,24 +30,29 @@
void cmd_list_windows_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_list_windows_entry = {
- "list-windows", "lsw", NULL,
- CMD_NOCLIENT,
- NULL,
+ "list-windows", "lsw",
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_list_windows_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
cmd_list_windows_exec(unused void *ptr, struct cmd_ctx *ctx)
{
+ struct session *s;
struct winlink *wl;
struct window *w;
u_int i;
unsigned long long size;
- RB_FOREACH(wl, winlinks, &ctx->session->windows) {
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
+ RB_FOREACH(wl, winlinks, &s->windows) {
w = wl->window;
size = 0;
diff --git a/cmd-new-session.c b/cmd-new-session.c
index aff19eab..02975173 100644
--- a/cmd-new-session.c
+++ b/cmd-new-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-session.c,v 1.19 2007-12-06 09:46:21 nicm Exp $ */
+/* $Id: cmd-new-session.c,v 1.20 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,7 @@
* Create a new session and attach to the current terminal unless -d is given.
*/
-int cmd_new_session_parse(void **, int, char **, char **);
+int cmd_new_session_parse(struct cmd *, void **, int, char **, char **);
void cmd_new_session_exec(void *, struct cmd_ctx *);
void cmd_new_session_send(void *, struct buffer *);
void cmd_new_session_recv(void **, struct buffer *);
@@ -42,7 +42,7 @@ struct cmd_new_session_data {
const struct cmd_entry cmd_new_session_entry = {
"new-session", "new",
"[-d] [-s session-name] [-n window-name] [command]",
- CMD_STARTSERVER|CMD_NOCLIENT|CMD_NOSESSION|CMD_CANTNEST,
+ CMD_STARTSERVER|CMD_CANTNEST,
cmd_new_session_parse,
cmd_new_session_exec,
cmd_new_session_send,
@@ -51,7 +51,8 @@ const struct cmd_entry cmd_new_session_entry = {
};
int
-cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_new_session_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_new_session_data *data;
int opt;
@@ -88,8 +89,7 @@ cmd_new_session_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_new_session_entry.name, cmd_new_session_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_new_session_free(data);
return (-1);
diff --git a/cmd-new-window.c b/cmd-new-window.c
index 71d922f3..3ee85c17 100644
--- a/cmd-new-window.c
+++ b/cmd-new-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-new-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-new-window.c,v 1.15 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,13 +27,14 @@
* Create a new window.
*/
-int cmd_new_window_parse(void **, int, char **, char **);
+int cmd_new_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_new_window_exec(void *, struct cmd_ctx *);
void cmd_new_window_send(void *, struct buffer *);
void cmd_new_window_recv(void **, struct buffer *);
void cmd_new_window_free(void *);
struct cmd_new_window_data {
+ char *sname;
char *name;
char *cmd;
int idx;
@@ -41,8 +42,9 @@ struct cmd_new_window_data {
};
const struct cmd_entry cmd_new_window_entry = {
- "new-window", "neww", "[-d] [-i index] [-n name] [command]",
- CMD_NOCLIENT,
+ "new-window", "neww",
+ "[-d] [-s session-name] [-i index] [-n name] [command]",
+ 0,
cmd_new_window_parse,
cmd_new_window_exec,
cmd_new_window_send,
@@ -51,19 +53,21 @@ const struct cmd_entry cmd_new_window_entry = {
};
int
-cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_new_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_new_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->idx = -1;
data->flag_detached = 0;
data->name = NULL;
data->cmd = NULL;
- while ((opt = getopt(argc, argv, "di:n:")) != EOF) {
+ while ((opt = getopt(argc, argv, "di:n:s:")) != EOF) {
switch (opt) {
case 'i':
data->idx = strtonum(optarg, 0, INT_MAX, &errstr);
@@ -78,6 +82,9 @@ cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause)
case 'd':
data->flag_detached = 1;
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -93,8 +100,7 @@ cmd_new_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_new_window_entry.name, cmd_new_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_new_window_free(data);
@@ -105,7 +111,8 @@ void
cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_new_window_data *data = ptr;
- struct cmd_new_window_data std = { NULL, NULL, -1, 0 };
+ struct cmd_new_window_data std = { NULL, NULL, NULL, -1, 0 };
+ struct session *s;
struct winlink *wl;
char *cmd;
@@ -116,18 +123,21 @@ cmd_new_window_exec(void *ptr, struct cmd_ctx *ctx)
if (cmd == NULL)
cmd = default_command;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if (data->idx < 0)
data->idx = -1;
- wl = session_new(ctx->session, data->name, cmd, data->idx);
+ wl = session_new(s, data->name, cmd, data->idx);
if (wl == NULL) {
ctx->error(ctx, "command failed: %s", cmd);
return;
}
if (!data->flag_detached) {
- session_select(ctx->session, wl->idx);
- server_redraw_session(ctx->session);
+ session_select(s, wl->idx);
+ server_redraw_session(s);
} else
- server_status_session(ctx->session);
+ server_status_session(s);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -139,6 +149,7 @@ cmd_new_window_send(void *ptr, struct buffer *b)
struct cmd_new_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
cmd_send_string(b, data->name);
cmd_send_string(b, data->cmd);
}
@@ -150,6 +161,7 @@ cmd_new_window_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
data->name = cmd_recv_string(b);
data->cmd = cmd_recv_string(b);
}
@@ -159,6 +171,8 @@ cmd_new_window_free(void *ptr)
{
struct cmd_new_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
if (data->name != NULL)
xfree(data->name);
if (data->cmd != NULL)
diff --git a/cmd-next-window.c b/cmd-next-window.c
index 4495558e..e07aaa0b 100644
--- a/cmd-next-window.c
+++ b/cmd-next-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-next-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-next-window.c,v 1.7 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,20 +30,26 @@
void cmd_next_window_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_next_window_entry = {
- "next-window", "next", "",
- CMD_NOCLIENT,
- NULL,
+ "next-window", "next",
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_next_window_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_next_window_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_next_window_exec(void *ptr, struct cmd_ctx *ctx)
{
- if (session_next(ctx->session) == 0)
- server_redraw_session(ctx->session);
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
+ if (session_next(s) == 0)
+ server_redraw_session(s);
else
ctx->error(ctx, "no next window");
diff --git a/cmd-paste-buffer.c b/cmd-paste-buffer.c
index 349feb48..30146ad4 100644
--- a/cmd-paste-buffer.c
+++ b/cmd-paste-buffer.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-paste-buffer.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-paste-buffer.c,v 1.3 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -31,25 +31,29 @@
void cmd_paste_buffer_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_paste_buffer_entry = {
- "paste-buffer", NULL, "paste",
- CMD_NOCLIENT,
- NULL,
+ "paste-buffer", "paste",
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_paste_buffer_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
cmd_paste_buffer_exec(unused void *ptr, struct cmd_ctx *ctx)
{
- struct window *w = ctx->session->curw->window;
+ struct session *s;
+ struct window *w;
- if (ctx->flags & CMD_KEY) {
- if (paste_buffer != NULL && *paste_buffer != '\0') {
- buffer_write(
- w->out, paste_buffer, strlen(paste_buffer));
- }
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+ w = s->curw->window;
+
+ if (ctx->flags & CMD_KEY &&
+ paste_buffer != NULL && *paste_buffer != '\0') {
+ buffer_write(w->out, paste_buffer, strlen(paste_buffer));
}
if (ctx->cmdclient != NULL)
diff --git a/cmd-previous-window.c b/cmd-previous-window.c
index d0423998..dd7560ce 100644
--- a/cmd-previous-window.c
+++ b/cmd-previous-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-previous-window.c,v 1.6 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-previous-window.c,v 1.7 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,20 +30,26 @@
void cmd_previous_window_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_previous_window_entry = {
- "previous-window", "prev", "",
- CMD_NOCLIENT,
- NULL,
+ "previous-window", "prev",
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_previous_window_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_previous_window_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_previous_window_exec(void *ptr, struct cmd_ctx *ctx)
{
- if (session_previous(ctx->session) == 0)
- server_redraw_session(ctx->session);
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
+
+ if (session_previous(s) == 0)
+ server_redraw_session(s);
else
ctx->error(ctx, "no previous window");
diff --git a/cmd-refresh-client.c b/cmd-refresh-client.c
index ba2ce5bf..4c1e6327 100644
--- a/cmd-refresh-client.c
+++ b/cmd-refresh-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-refresh-client.c,v 1.1 2007-11-16 21:12:31 nicm Exp $ */
+/* $Id: cmd-refresh-client.c,v 1.2 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -29,19 +29,25 @@
void cmd_refresh_client_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_refresh_client_entry = {
- "refresh-client", "refresh", "",
+ "refresh-client", "refresh",
+ CMD_CLIENTONLY_USAGE,
0,
- NULL,
+ cmd_clientonly_parse,
cmd_refresh_client_exec,
- NULL,
- NULL,
- NULL
+ cmd_clientonly_send,
+ cmd_clientonly_recv,
+ cmd_clientonly_free
};
void
-cmd_refresh_client_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_refresh_client_exec(void *ptr, struct cmd_ctx *ctx)
{
- server_redraw_client(ctx->client);
+ struct client *c;
+
+ if ((c = cmd_clientonly_get(ptr, ctx)) == NULL)
+ return;
+
+ server_redraw_client(c);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-rename-session.c b/cmd-rename-session.c
index 498bacd2..8a057543 100644
--- a/cmd-rename-session.c
+++ b/cmd-rename-session.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-session.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-rename-session.c,v 1.5 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,19 +27,21 @@
* Change session name.
*/
-int cmd_rename_session_parse(void **, int, char **, char **);
+int cmd_rename_session_parse(struct cmd *, void **, int, char **, char **);
void cmd_rename_session_exec(void *, struct cmd_ctx *);
void cmd_rename_session_send(void *, struct buffer *);
void cmd_rename_session_recv(void **, struct buffer *);
void cmd_rename_session_free(void *);
struct cmd_rename_session_data {
+ char *sname;
char *newname;
};
const struct cmd_entry cmd_rename_session_entry = {
- "rename-session", "rename", "new-name",
- CMD_NOCLIENT,
+ "rename-session", "rename",
+ "[-s session-name] new-name",
+ 0,
cmd_rename_session_parse,
cmd_rename_session_exec,
cmd_rename_session_send,
@@ -48,16 +50,21 @@ const struct cmd_entry cmd_rename_session_entry = {
};
int
-cmd_rename_session_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_rename_session_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_rename_session_data *data;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->newname = NULL;
- while ((opt = getopt(argc, argv, "")) != EOF) {
+ while ((opt = getopt(argc, argv, "s:")) != EOF) {
switch (opt) {
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -72,8 +79,7 @@ cmd_rename_session_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_rename_session_entry.name, cmd_rename_session_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_rename_session_free(data);
return (-1);
@@ -83,12 +89,16 @@ void
cmd_rename_session_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_rename_session_data *data = ptr;
+ struct session *s;
if (data == NULL)
return;
- xfree(ctx->session->name);
- ctx->session->name = xstrdup(data->newname);
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
+ xfree(s->name);
+ s->name = xstrdup(data->newname);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -100,6 +110,7 @@ cmd_rename_session_send(void *ptr, struct buffer *b)
struct cmd_rename_session_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
cmd_send_string(b, data->newname);
}
@@ -110,6 +121,7 @@ cmd_rename_session_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
data->newname = cmd_recv_string(b);
}
@@ -118,6 +130,8 @@ cmd_rename_session_free(void *ptr)
{
struct cmd_rename_session_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
if (data->newname != NULL)
xfree(data->newname);
xfree(data);
diff --git a/cmd-rename-window.c b/cmd-rename-window.c
index 5ed0c161..c0d20acf 100644
--- a/cmd-rename-window.c
+++ b/cmd-rename-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-rename-window.c,v 1.14 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-rename-window.c,v 1.15 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,20 +27,22 @@
* Rename window by index.
*/
-int cmd_rename_window_parse(void **, int, char **, char **);
+int cmd_rename_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_rename_window_exec(void *, struct cmd_ctx *);
void cmd_rename_window_send(void *, struct buffer *);
void cmd_rename_window_recv(void **, struct buffer *);
void cmd_rename_window_free(void *);
struct cmd_rename_window_data {
+ char *sname;
int idx;
char *newname;
};
const struct cmd_entry cmd_rename_window_entry = {
- "rename-window", "renamew", "[-i index] new-name",
- CMD_NOCLIENT,
+ "rename-window", "renamew",
+ "[-i index] [-s session-name] new-name",
+ 0,
cmd_rename_window_parse,
cmd_rename_window_exec,
cmd_rename_window_send,
@@ -49,17 +51,19 @@ const struct cmd_entry cmd_rename_window_entry = {
};
int
-cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_rename_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_rename_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->idx = -1;
data->newname = NULL;
- while ((opt = getopt(argc, argv, "i:")) != EOF) {
+ while ((opt = getopt(argc, argv, "i:s:")) != EOF) {
switch (opt) {
case 'i':
data->idx = strtonum(optarg, 0, INT_MAX, &errstr);
@@ -68,6 +72,9 @@ cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause)
goto error;
}
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -82,8 +89,7 @@ cmd_rename_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_rename_window_entry.name, cmd_rename_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_rename_window_free(data);
@@ -94,22 +100,25 @@ void
cmd_rename_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_rename_window_data *data = ptr;
- struct winlinks *wwl = &ctx->session->windows;
+ struct session *s;
struct winlink *wl;
if (data == NULL)
return;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if (data->idx == -1)
- wl = ctx->session->curw;
- else if ((wl = winlink_find_by_index(wwl, data->idx)) == NULL) {
+ wl = s->curw;
+ else if ((wl = winlink_find_by_index(&s->windows, data->idx)) == NULL) {
ctx->error(ctx, "no window %d", data->idx);
return;
}
xfree(wl->window->name);
wl->window->name = xstrdup(data->newname);
- server_status_session(ctx->session);
+ server_status_session(s);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -121,6 +130,7 @@ cmd_rename_window_send(void *ptr, struct buffer *b)
struct cmd_rename_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
cmd_send_string(b, data->newname);
}
@@ -131,6 +141,7 @@ cmd_rename_window_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
data->newname = cmd_recv_string(b);
}
@@ -139,6 +150,8 @@ cmd_rename_window_free(void *ptr)
{
struct cmd_rename_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
if (data->newname != NULL)
xfree(data->newname);
xfree(data);
diff --git a/cmd-scroll-mode.c b/cmd-scroll-mode.c
index 2d444a9a..a7252e8b 100644
--- a/cmd-scroll-mode.c
+++ b/cmd-scroll-mode.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-scroll-mode.c,v 1.6 2007-12-06 10:04:42 nicm Exp $ */
+/* $Id: cmd-scroll-mode.c,v 1.7 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,22 +30,26 @@
void cmd_scroll_mode_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_scroll_mode_entry = {
- "scroll-mode", NULL, "",
- CMD_NOCLIENT,
- NULL,
+ "scroll-mode", NULL,
+ CMD_SESSIONONLY_USAGE,
+ 0,
+ cmd_sessiononly_parse,
cmd_scroll_mode_exec,
- NULL,
- NULL,
- NULL
+ cmd_sessiononly_send,
+ cmd_sessiononly_recv,
+ cmd_sessiononly_free
};
void
-cmd_scroll_mode_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_scroll_mode_exec(void *ptr, struct cmd_ctx *ctx)
{
- struct window *w = ctx->session->curw->window;
+ struct session *s;
+
+ if ((s = cmd_sessiononly_get(ptr, ctx)) == NULL)
+ return;
if (ctx->flags & CMD_KEY)
- window_set_mode(w, &window_scroll_mode);
+ window_set_mode(s->curw->window, &window_scroll_mode);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-select-window.c b/cmd-select-window.c
index 896b18cb..c3eee8b9 100644
--- a/cmd-select-window.c
+++ b/cmd-select-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-select-window.c,v 1.11 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-select-window.c,v 1.12 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,19 +27,21 @@
* Select window by index.
*/
-int cmd_select_window_parse(void **, int, char **, char **);
+int cmd_select_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_select_window_exec(void *, struct cmd_ctx *);
void cmd_select_window_send(void *, struct buffer *);
void cmd_select_window_recv(void **, struct buffer *);
void cmd_select_window_free(void *);
struct cmd_select_window_data {
+ char *sname;
int idx;
};
const struct cmd_entry cmd_select_window_entry = {
- "select-window", "selectw", "index",
- CMD_NOCLIENT,
+ "select-window", "selectw",
+ "[-s session-name] index",
+ 0,
cmd_select_window_parse,
cmd_select_window_exec,
cmd_select_window_send,
@@ -58,20 +60,26 @@ cmd_select_window_default(void **ptr, int key)
struct cmd_select_window_data *data;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->idx = key - '0';
}
int
-cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_select_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_select_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
- while ((opt = getopt(argc, argv, "")) != EOF) {
+ while ((opt = getopt(argc, argv, "s:")) != EOF) {
switch (opt) {
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -90,8 +98,7 @@ cmd_select_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_select_window_entry.name, cmd_select_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_select_window_free(data);
@@ -102,13 +109,17 @@ void
cmd_select_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_select_window_data *data = ptr;
+ struct session *s;
if (data == NULL)
return;
- switch (session_select(ctx->session, data->idx)) {
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
+ switch (session_select(s, data->idx)) {
case 0:
- server_redraw_session(ctx->session);
+ server_redraw_session(s);
break;
case 1:
break;
@@ -127,6 +138,7 @@ cmd_select_window_send(void *ptr, struct buffer *b)
struct cmd_select_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
}
void
@@ -136,6 +148,7 @@ cmd_select_window_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
}
void
@@ -143,5 +156,7 @@ cmd_select_window_free(void *ptr)
{
struct cmd_select_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
xfree(data);
}
diff --git a/cmd-send-keys.c b/cmd-send-keys.c
index 25ee1c48..c4ffc366 100644
--- a/cmd-send-keys.c
+++ b/cmd-send-keys.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-keys.c,v 1.1 2008-06-01 20:20:25 nicm Exp $ */
+/* $Id: cmd-send-keys.c,v 1.2 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,19 +27,20 @@
* Change session name.
*/
-int cmd_send_keys_parse(void **, int, char **, char **);
+int cmd_send_keys_parse(struct cmd *, void **, int, char **, char **);
void cmd_send_keys_exec(void *, struct cmd_ctx *);
void cmd_send_keys_send(void *, struct buffer *);
void cmd_send_keys_recv(void **, struct buffer *);
void cmd_send_keys_free(void *);
struct cmd_send_keys_data {
+ char *cname;
u_int nkeys;
int *keys;
};
const struct cmd_entry cmd_send_keys_entry = {
- "send-keys", "send", "key ...",
+ "send-keys", "send", "[-c client-name] key ...",
0,
cmd_send_keys_parse,
cmd_send_keys_exec,
@@ -49,18 +50,23 @@ const struct cmd_entry cmd_send_keys_entry = {
};
int
-cmd_send_keys_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_send_keys_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_send_keys_data *data;
int opt, key;
char *s;
*ptr = data = xmalloc(sizeof *data);
+ data->cname = NULL;
data->nkeys = 0;
data->keys = NULL;
- while ((opt = getopt(argc, argv, "")) != EOF) {
+ while ((opt = getopt(argc, argv, "c:")) != EOF) {
switch (opt) {
+ case 'c':
+ data->cname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -89,8 +95,7 @@ cmd_send_keys_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_send_keys_entry.name, cmd_send_keys_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_send_keys_free(data);
return (-1);
@@ -100,13 +105,17 @@ void
cmd_send_keys_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_send_keys_data *data = ptr;
+ struct client *c;
u_int i;
if (data == NULL)
return;
+ if ((c = cmd_find_client(ctx, data->cname)) == NULL)
+ return;
+
for (i = 0; i < data->nkeys; i++)
- window_key(ctx->client->session->curw->window, data->keys[i]);
+ window_key(c->session->curw->window, data->keys[i]);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -118,6 +127,7 @@ cmd_send_keys_send(void *ptr, struct buffer *b)
struct cmd_send_keys_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->cname);
buffer_write(b, data->keys, data->nkeys * sizeof *data->keys);
}
@@ -128,6 +138,7 @@ cmd_send_keys_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->cname = cmd_recv_string(b);
data->keys = xcalloc(data->nkeys, sizeof *data->keys);
buffer_read(b, data->keys, data->nkeys * sizeof *data->keys);
}
@@ -137,6 +148,8 @@ cmd_send_keys_free(void *ptr)
{
struct cmd_send_keys_data *data = ptr;
+ if (data->cname != NULL)
+ xfree(data->cname);
if (data->keys != NULL)
xfree(data->keys);
xfree(data);
diff --git a/cmd-send-prefix.c b/cmd-send-prefix.c
index eb13b673..ce887dd7 100644
--- a/cmd-send-prefix.c
+++ b/cmd-send-prefix.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-send-prefix.c,v 1.7 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-send-prefix.c,v 1.8 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -30,19 +30,25 @@
void cmd_send_prefix_exec(void *, struct cmd_ctx *);
const struct cmd_entry cmd_send_prefix_entry = {
- "send-prefix", NULL, NULL,
+ "send-prefix", NULL,
+ CMD_CLIENTONLY_USAGE,
0,
- NULL,
+ cmd_clientonly_parse,
cmd_send_prefix_exec,
- NULL,
- NULL,
- NULL
+ cmd_clientonly_send,
+ cmd_clientonly_recv,
+ cmd_clientonly_free
};
void
-cmd_send_prefix_exec(unused void *ptr, struct cmd_ctx *ctx)
+cmd_send_prefix_exec(void *ptr, struct cmd_ctx *ctx)
{
- window_key(ctx->client->session->curw->window, prefix_key);
+ struct client *c;
+
+ if ((c = cmd_clientonly_get(ptr, ctx)) == NULL)
+ return;
+
+ window_key(c->session->curw->window, prefix_key);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
diff --git a/cmd-set-option.c b/cmd-set-option.c
index d0e86c89..b349b0eb 100644
--- a/cmd-set-option.c
+++ b/cmd-set-option.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-set-option.c,v 1.15 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-set-option.c,v 1.16 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,7 +28,7 @@
* Set an option.
*/
-int cmd_set_option_parse(void **, int, char **, char **);
+int cmd_set_option_parse(struct cmd *, void **, int, char **, char **);
void cmd_set_option_exec(void *, struct cmd_ctx *);
void cmd_set_option_send(void *, struct buffer *);
void cmd_set_option_recv(void **, struct buffer *);
@@ -40,8 +40,9 @@ struct cmd_set_option_data {
};
const struct cmd_entry cmd_set_option_entry = {
- "set-option", "set", "option value",
- CMD_NOCLIENT|CMD_NOSESSION,
+ "set-option", "set",
+ "option value",
+ 0,
cmd_set_option_parse,
cmd_set_option_exec,
cmd_set_option_send,
@@ -50,7 +51,8 @@ const struct cmd_entry cmd_set_option_entry = {
};
int
-cmd_set_option_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_set_option_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_set_option_data *data;
int opt;
@@ -77,8 +79,7 @@ cmd_set_option_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_set_option_entry.name, cmd_set_option_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_set_option_free(data);
return (-1);
diff --git a/cmd-swap-window.c b/cmd-swap-window.c
index 6c4cac0f..4044ad84 100644
--- a/cmd-swap-window.c
+++ b/cmd-swap-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-swap-window.c,v 1.4 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-swap-window.c,v 1.5 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,13 +27,14 @@
* Swap one window with another.
*/
-int cmd_swap_window_parse(void **, int, char **, char **);
+int cmd_swap_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_swap_window_exec(void *, struct cmd_ctx *);
void cmd_swap_window_send(void *, struct buffer *);
void cmd_swap_window_recv(void **, struct buffer *);
void cmd_swap_window_free(void *);
struct cmd_swap_window_data {
+ char *sname;
int dstidx;
int srcidx;
char *srcname;
@@ -41,8 +42,9 @@ struct cmd_swap_window_data {
};
const struct cmd_entry cmd_swap_window_entry = {
- "swap-window", "swapw", "[-i index] name index",
- CMD_NOCLIENT,
+ "swap-window", "swapw",
+ "[-i index] [-s session-name] session-name index",
+ 0,
cmd_swap_window_parse,
cmd_swap_window_exec,
cmd_swap_window_send,
@@ -51,20 +53,25 @@ const struct cmd_entry cmd_swap_window_entry = {
};
int
-cmd_swap_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_swap_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_swap_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->flag_detached = 0;
data->dstidx = -1;
data->srcidx = -1;
data->srcname = NULL;
- while ((opt = getopt(argc, argv, "di:")) != EOF) {
+ while ((opt = getopt(argc, argv, "di:s:")) != EOF) {
switch (opt) {
+ case 'd':
+ data->flag_detached = 1;
+ break;
case 'i':
data->dstidx = strtonum(optarg, 0, INT_MAX, &errstr);
if (errstr != NULL) {
@@ -72,8 +79,8 @@ cmd_swap_window_parse(void **ptr, int argc, char **argv, char **cause)
goto error;
}
break;
- case 'd':
- data->flag_detached = 1;
+ case 's':
+ data->sname = xstrdup(optarg);
break;
default:
goto usage;
@@ -94,8 +101,7 @@ cmd_swap_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_swap_window_entry.name, cmd_swap_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_swap_window_free(data);
@@ -106,13 +112,16 @@ void
cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_swap_window_data *data = ptr;
- struct session *dst = ctx->session, *src;
+ struct session *s, *src;
struct winlink *srcwl, *dstwl;
struct window *w;
if (data == NULL)
return;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if ((src = session_find(data->srcname)) == NULL) {
ctx->error(ctx, "session not found: %s", data->srcname);
return;
@@ -133,9 +142,9 @@ cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data->dstidx < 0)
data->dstidx = -1;
if (data->dstidx == -1)
- dstwl = dst->curw;
+ dstwl = s->curw;
else {
- dstwl = winlink_find_by_index(&dst->windows, data->dstidx);
+ dstwl = winlink_find_by_index(&s->windows, data->dstidx);
if (dstwl == NULL) {
ctx->error(ctx, "no window %d", data->dstidx);
return;
@@ -147,13 +156,13 @@ cmd_swap_window_exec(void *ptr, struct cmd_ctx *ctx)
srcwl->window = w;
if (!data->flag_detached) {
- session_select(dst, dstwl->idx);
- if (src != dst)
+ session_select(s, dstwl->idx);
+ if (src != s)
session_select(src, srcwl->idx);
}
server_redraw_session(src);
- if (src != dst)
- server_redraw_session(dst);
+ if (src != s)
+ server_redraw_session(s);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -165,6 +174,7 @@ cmd_swap_window_send(void *ptr, struct buffer *b)
struct cmd_swap_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
cmd_send_string(b, data->srcname);
}
@@ -175,6 +185,7 @@ cmd_swap_window_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->sname = cmd_recv_string(b);
data->srcname = cmd_recv_string(b);
}
@@ -183,6 +194,8 @@ cmd_swap_window_free(void *ptr)
{
struct cmd_swap_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
if (data->srcname != NULL)
xfree(data->srcname);
xfree(data);
diff --git a/cmd-switch-client.c b/cmd-switch-client.c
index ca122879..45373469 100644
--- a/cmd-switch-client.c
+++ b/cmd-switch-client.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-switch-client.c,v 1.2 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-switch-client.c,v 1.3 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -28,19 +28,21 @@
* Switch client to a different session.
*/
-int cmd_switch_client_parse(void **, int, char **, char **);
+int cmd_switch_client_parse(struct cmd *, void **, int, char **, char **);
void cmd_switch_client_exec(void *, struct cmd_ctx *);
void cmd_switch_client_send(void *, struct buffer *);
void cmd_switch_client_recv(void **, struct buffer *);
void cmd_switch_client_free(void *);
struct cmd_switch_client_data {
+ char *cname;
char *name;
};
const struct cmd_entry cmd_switch_client_entry = {
- "switch-client", "switchc", "session-name",
- CMD_NOSESSION,
+ "switch-client", "switchc",
+ "session-name",
+ 0,
cmd_switch_client_parse,
cmd_switch_client_exec,
cmd_switch_client_send,
@@ -49,16 +51,21 @@ const struct cmd_entry cmd_switch_client_entry = {
};
int
-cmd_switch_client_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_switch_client_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_switch_client_data *data;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->cname = NULL;
data->name = NULL;
- while ((opt = getopt(argc, argv, "")) != EOF) {
+ while ((opt = getopt(argc, argv, "c:")) != EOF) {
switch (opt) {
+ case 'c':
+ data->cname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -73,8 +80,7 @@ cmd_switch_client_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_switch_client_entry.name, cmd_switch_client_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
cmd_switch_client_free(data);
return (-1);
@@ -84,20 +90,23 @@ void
cmd_switch_client_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_switch_client_data *data = ptr;
+ struct client *c;
struct session *s;
if (data == NULL)
return;
+ if ((c = cmd_find_client(ctx, data->cname)) == NULL)
+ return;
+
if ((s = session_find(data->name)) == NULL) {
ctx->error(ctx, "session not found: %s", data->name);
return;
}
-
- ctx->client->session = s;
+ c->session = s;
recalculate_sizes();
- server_redraw_client(ctx->client);
+ server_redraw_client(c);
if (ctx->cmdclient != NULL)
server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
@@ -109,6 +118,7 @@ cmd_switch_client_send(void *ptr, struct buffer *b)
struct cmd_switch_client_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->cname);
cmd_send_string(b, data->name);
}
@@ -119,6 +129,7 @@ cmd_switch_client_recv(void **ptr, struct buffer *b)
*ptr = data = xmalloc(sizeof *data);
buffer_read(b, data, sizeof *data);
+ data->cname = cmd_recv_string(b);
data->name = cmd_recv_string(b);
}
@@ -127,6 +138,8 @@ cmd_switch_client_free(void *ptr)
{
struct cmd_switch_client_data *data = ptr;
+ if (data->cname != NULL)
+ xfree(data->cname);
if (data->name != NULL)
xfree(data->name);
xfree(data);
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index fd4e775f..68e61dec 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unbind-key.c,v 1.8 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-unbind-key.c,v 1.9 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -26,7 +26,7 @@
* Unbind key from command.
*/
-int cmd_unbind_key_parse(void **, int, char **, char **);
+int cmd_unbind_key_parse(struct cmd *, void **, int, char **, char **);
void cmd_unbind_key_exec(void *, struct cmd_ctx *);
void cmd_unbind_key_send(void *, struct buffer *);
void cmd_unbind_key_recv(void **, struct buffer *);
@@ -37,8 +37,9 @@ struct cmd_unbind_key_data {
};
const struct cmd_entry cmd_unbind_key_entry = {
- "unbind-key", "unbind", "key",
- CMD_NOCLIENT|CMD_NOSESSION,
+ "unbind-key", "unbind",
+ "key",
+ 0,
cmd_unbind_key_parse,
cmd_unbind_key_exec,
cmd_unbind_key_send,
@@ -47,7 +48,8 @@ const struct cmd_entry cmd_unbind_key_entry = {
};
int
-cmd_unbind_key_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_unbind_key_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_unbind_key_data *data;
int opt;
@@ -73,8 +75,7 @@ cmd_unbind_key_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_unbind_key_entry.name, cmd_unbind_key_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
xfree(data);
diff --git a/cmd-unlink-window.c b/cmd-unlink-window.c
index 577a2e2d..46f45035 100644
--- a/cmd-unlink-window.c
+++ b/cmd-unlink-window.c
@@ -1,4 +1,4 @@
-/* $Id: cmd-unlink-window.c,v 1.5 2007-12-06 09:46:22 nicm Exp $ */
+/* $Id: cmd-unlink-window.c,v 1.6 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -27,19 +27,21 @@
* Unlink a window, unless it would be destroyed by doing so (only one link).
*/
-int cmd_unlink_window_parse(void **, int, char **, char **);
+int cmd_unlink_window_parse(struct cmd *, void **, int, char **, char **);
void cmd_unlink_window_exec(void *, struct cmd_ctx *);
void cmd_unlink_window_send(void *, struct buffer *);
void cmd_unlink_window_recv(void **, struct buffer *);
void cmd_unlink_window_free(void *);
struct cmd_unlink_window_data {
- int idx;
+ char *sname;
+ int idx;
};
const struct cmd_entry cmd_unlink_window_entry = {
- "unlink-window", "unlinkw", "[-i index]",
- CMD_NOCLIENT,
+ "unlink-window", "unlinkw",
+ "[-i index] [-s session-name]",
+ 0,
cmd_unlink_window_parse,
cmd_unlink_window_exec,
cmd_unlink_window_send,
@@ -48,16 +50,18 @@ const struct cmd_entry cmd_unlink_window_entry = {
};
int
-cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause)
+cmd_unlink_window_parse(
+ struct cmd *self, void **ptr, int argc, char **argv, char **cause)
{
struct cmd_unlink_window_data *data;
const char *errstr;
int opt;
*ptr = data = xmalloc(sizeof *data);
+ data->sname = NULL;
data->idx = -1;
- while ((opt = getopt(argc, argv, "i:")) != EOF) {
+ while ((opt = getopt(argc, argv, "i:s:")) != EOF) {
switch (opt) {
case 'i':
data->idx = strtonum(optarg, 0, INT_MAX, &errstr);
@@ -66,6 +70,9 @@ cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause)
goto error;
}
break;
+ case 's':
+ data->sname = xstrdup(optarg);
+ break;
default:
goto usage;
}
@@ -78,8 +85,7 @@ cmd_unlink_window_parse(void **ptr, int argc, char **argv, char **cause)
return (0);
usage:
- usage(cause, "%s %s",
- cmd_unlink_window_entry.name, cmd_unlink_window_entry.usage);
+ usage(cause, "%s %s", self->entry->name, self->entry->usage);
error:
cmd_unlink_window_free(data);
@@ -90,8 +96,8 @@ void
cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx)
{
struct cmd_unlink_window_data *data = ptr;
+ struct session *s;
struct client *c;
- struct winlinks *wwl = &ctx->session->windows;
struct winlink *wl;
u_int i;
int destroyed;
@@ -99,12 +105,15 @@ cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx)
if (data == NULL)
return;
+ if ((s = cmd_find_session(ctx, data->sname)) == NULL)
+ return;
+
if (data->idx < 0)
data->idx = -1;
if (data->idx == -1)
- wl = ctx->session->curw;
+ wl = s->curw;
else {
- wl = winlink_find_by_index(wwl, data->idx);
+ wl = winlink_find_by_index(&s->windows, data->idx);
if (wl == NULL) {
ctx->error(ctx, "no window %d", data->idx);
return;
@@ -116,10 +125,10 @@ cmd_unlink_window_exec(void *ptr, struct cmd_ctx *ctx)
return;
}
- destroyed = session_detach(ctx->session, wl);
+ destroyed = session_detach(s, wl);
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
c = ARRAY_ITEM(&clients, i);
- if (c == NULL || c->session != ctx->session)
+ if (c == NULL || c->session != s)
continue;
if (destroyed) {
c->session = NULL;
@@ -138,6 +147,7 @@ cmd_unlink_window_send(void *ptr, struct buffer *b)
struct cmd_unlink_window_data *data = ptr;
buffer_write(b, data, sizeof *data);
+ cmd_send_string(b, data->sname);
}
void
@@ -154,5 +164,7 @@ cmd_unlink_window_free(void *ptr)
{
struct cmd_unlink_window_data *data = ptr;
+ if (data->sname != NULL)
+ xfree(data->sname);
xfree(data);
}
diff --git a/cmd.c b/cmd.c
index 52a2cf83..2232af16 100644
--- a/cmd.c
+++ b/cmd.c
@@ -1,4 +1,4 @@
-/* $Id: cmd.c,v 1.34 2008-06-01 20:20:25 nicm Exp $ */
+/* $Id: cmd.c,v 1.35 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -20,6 +20,7 @@
#include <getopt.h>
#include <string.h>
+#include <unistd.h>
#include "tmux.h"
@@ -105,7 +106,7 @@ cmd_parse(int argc, char **argv, char **cause)
cmd = xmalloc(sizeof *cmd);
cmd->entry = entry;
if (entry->parse != NULL) {
- if (entry->parse(&cmd->data, argc, argv, cause) != 0) {
+ if (entry->parse(cmd, &cmd->data, argc, argv, cause) != 0) {
xfree(cmd);
return (NULL);
}
@@ -226,3 +227,89 @@ cmd_recv_string(struct buffer *b)
return (s);
}
+
+/*
+ * Attempt to establish session. This looks first at the command-line argument
+ * if any, then sees if there is a session in the context, then finally tries
+ * the session data passed up from the client $TMUX variable.
+ */
+struct session *
+cmd_find_session(struct cmd_ctx *ctx, const char *arg)
+{
+ struct session *s;
+ struct msg_command_data *data = ctx->msgdata;
+ u_int i, n;
+
+ if (arg != NULL) {
+ if ((s = session_find(arg)) == NULL) {
+ ctx->error(ctx, "session not found: %s", arg);
+ return (NULL);
+ }
+ return (s);
+ }
+
+ if (ctx->cursession != NULL)
+ return (ctx->cursession);
+
+ if (data != NULL && data->pid != -1) {
+ if (data->pid != getpid()) {
+ ctx->error(ctx, "wrong server: %lld", data->pid);
+ return (NULL);
+ }
+ if (data->idx > ARRAY_LENGTH(&sessions)) {
+ ctx->error(ctx, "index out of range: %d", data->idx);
+ return (NULL);
+ }
+ if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) {
+ ctx->error(ctx, "session doesn't exist: %u", data->idx);
+ return (NULL);
+ }
+ return (s);
+ }
+
+ s = NULL;
+ n = 0;
+ for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
+ if (ARRAY_ITEM(&sessions, i) != NULL) {
+ s = ARRAY_ITEM(&sessions, i);
+ n++;
+ }
+ }
+ if (s == NULL) {
+ ctx->error(ctx, "no sessions found");
+ return (NULL);
+ }
+ if (n != 1) {
+ ctx->error(ctx, "multiple sessions and session not specified");
+ return (NULL);
+ }
+ return (s);
+}
+
+/*
+ * Figure out the client. Try the current client (if any) first, then try to
+ * figure it out from the argument.
+ */
+struct client *
+cmd_find_client(unused struct cmd_ctx *ctx, const char *arg)
+{
+ struct client *c;
+ u_int i;
+
+ if (ctx->curclient != NULL)
+ return (ctx->curclient);
+
+ if (arg == NULL) {
+ ctx->error(ctx, "must specify a client");
+ return (NULL);
+ }
+
+ for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
+ c = ARRAY_ITEM(&clients, i);
+ if (c != NULL && strcmp(arg, c->tty.path) == 0)
+ return (c);
+ }
+
+ ctx->error(ctx, "client not found: %s", arg);
+ return (NULL);
+}
diff --git a/key-bindings.c b/key-bindings.c
index 8acf71f1..96a220f2 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -1,4 +1,4 @@
-/* $Id: key-bindings.c,v 1.25 2007-12-06 21:42:00 nicm Exp $ */
+/* $Id: key-bindings.c,v 1.26 2008-06-02 18:08:16 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -155,14 +155,14 @@ key_bindings_error(struct cmd_ctx *ctx, const char *fmt, ...)
va_end(ap);
*msg = toupper((u_char) *msg);
- server_write_message(ctx->client, "%s", msg);
+ server_write_message(ctx->curclient, "%s", msg);
xfree(msg);
}
void printflike2
key_bindings_print(struct cmd_ctx *ctx, const char *fmt, ...)
{
- struct window *w = ctx->session->curw->window;
+ struct window *w = ctx->cursession->curw->window;
va_list ap;
window_set_mode(w, &window_more_mode);
@@ -188,8 +188,8 @@ key_bindings_dispatch(int key, struct client *c)
if (i == ARRAY_LENGTH(&key_bindings))
return;
- ctx.session = c->session;
- ctx.client = c;
+ ctx.cursession = c->session;
+ ctx.curclient = c;
ctx.error = key_bindings_error;
ctx.print = key_bindings_print;
diff --git a/server-fn.c b/server-fn.c
index 9da001f5..cf55e238 100644
--- a/server-fn.c
+++ b/server-fn.c
@@ -1,4 +1,4 @@
-/* $Id: server-fn.c,v 1.36 2007-12-06 09:46:23 nicm Exp $ */
+/* $Id: server-fn.c,v 1.37 2008-06-02 18:08:17 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -23,57 +23,6 @@
#include "tmux.h"
-/* Find session from command message. */
-struct session *
-server_extract_session(struct msg_command_data *data, char *name, char **cause)
-{
- struct session *s;
- u_int i, n;
-
- if (name != NULL) {
- if ((s = session_find(name)) == NULL) {
- xasprintf(cause, "session not found: %s", name);
- return (NULL);
- }
- return (s);
- }
-
- if (data->pid != -1) {
- if (data->pid != getpid()) {
- xasprintf(cause, "wrong server: %lld", data->pid);
- return (NULL);
- }
- if (data->idx > ARRAY_LENGTH(&sessions)) {
- xasprintf(cause, "index out of range: %d", data->idx);
- return (NULL);
- }
- if ((s = ARRAY_ITEM(&sessions, data->idx)) == NULL) {
- xasprintf(
- cause, "session doesn't exist: %u", data->idx);
- return (NULL);
- }
- return (s);
- }
-
- s = NULL;
- n = 0;
- for (i = 0; i < ARRAY_LENGTH(&sessions); i++) {
- if (ARRAY_ITEM(&sessions, i) != NULL) {
- s = ARRAY_ITEM(&sessions, i);
- n++;
- }
- }
- if (s == NULL) {
- xasprintf(cause, "no sessions found");
- return (NULL);
- }
- if (n != 1) {
- xasprintf(cause, "multiple sessions and session not specified");
- return (NULL);
- }
- return (s);
-}
-
void
server_write_client(
struct client *c, enum hdrtype type, const void *buf, size_t len)
diff --git a/server-msg.c b/server-msg.c
index d92aa3c1..ed8b86b6 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -1,4 +1,4 @@
-/* $Id: server-msg.c,v 1.43 2007-12-13 18:59:42 nicm Exp $ */
+/* $Id: server-msg.c,v 1.44 2008-06-02 18:08:17 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -111,16 +111,10 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
struct msg_command_data data;
struct cmd_ctx ctx;
struct cmd *cmd;
- char *name, *client, *cause;
- u_int i;
-
- /* XXX I hate this function. Split it? */
if (hdr->size < sizeof data)
fatalx("bad MSG_COMMAND size");
buffer_read(c->in, &data, sizeof data);
- name = cmd_recv_string(c->in);
- client = cmd_recv_string(c->in);
cmd = cmd_recv(c->in);
log_debug("got command %s from client %d", cmd->entry->name, c->fd);
@@ -128,64 +122,23 @@ server_msg_fn_command(struct hdr *hdr, struct client *c)
ctx.error = server_msg_fn_command_error;
ctx.print = server_msg_fn_command_print;
+ ctx.curclient = NULL;
+ ctx.cursession = NULL;
+ ctx.msgdata = &data;
+
ctx.cmdclient = c;
ctx.flags = 0;
+ /* XXX */
if (data.pid != -1 && (cmd->entry->flags & CMD_CANTNEST)) {
server_msg_fn_command_error(&ctx, "sessions "
"should be nested with care. unset $TMUX to force");
- goto out;
- }
-
- ctx.client = NULL;
- if (cmd->entry->flags & CMD_NOCLIENT) {
- if (client != NULL) {
- server_msg_fn_command_error(&ctx,
- "%s: cannot specify a client", cmd->entry->name);
- goto out;
- }
- } else {
- if (client == NULL) {
- server_msg_fn_command_error(&ctx,
- "%s: must specify a client", cmd->entry->name);
- goto out;
- }
- for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
- /* XXX fnmatch, multi clients etc */
- c = ARRAY_ITEM(&clients, i);
- if (c != NULL && strcmp(client, c->tty.path) == 0)
- ctx.client = c;
- }
- if (ctx.client == NULL) {
- server_msg_fn_command_error(&ctx, "%s: "
- "client not found: %s", cmd->entry->name, client);
- goto out;
- }
- }
-
- ctx.session = NULL;
- if (cmd->entry->flags & CMD_NOSESSION) {
- if (name != NULL) {
- server_msg_fn_command_error(&ctx,
- "%s: cannot specify a session", cmd->entry->name);
- goto out;
- }
- } else {
- ctx.session = server_extract_session(&data, name, &cause);
- if (ctx.session == NULL) {
- server_msg_fn_command_error(
- &ctx, "%s: %s", cmd->entry->name, cause);
- xfree(cause);
- goto out;
- }
+ cmd_free(cmd);
+ return (0);
}
cmd_exec(cmd, &ctx);
cmd_free(cmd);
-
-out:
- if (name != NULL)
- xfree(name);
return (0);
}
diff --git a/server.c b/server.c
index dcd115f3..8cfc607c 100644
--- a/server.c
+++ b/server.c
@@ -1,4 +1,4 @@
-/* $Id: server.c,v 1.45 2008-05-31 20:04:15 nicm Exp $ */
+/* $Id: server.c,v 1.46 2008-06-02 18:08:17 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -62,6 +62,7 @@ server_start(const char *path)
size_t size;
mode_t mask;
int n, fd, mode;
+ char *cause;
switch (fork()) {
case -1:
@@ -109,6 +110,13 @@ server_start(const char *path)
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
fatal("fcntl failed");
+ /* Load configuration. */
+ if (cfg_file != NULL && load_cfg(cfg_file, &cause) != 0) {
+ log_warnx("%s", cause);
+ xfree(cause);
+ exit(1);
+ }
+
if (daemon(1, 1) != 0)
fatal("daemon failed");
log_debug("server daemonised, pid now %ld", (long) getpid());
@@ -135,7 +143,7 @@ server_main(const char *srv_path, int srv_fd)
ARRAY_INIT(&sessions);
key_bindings_init();
-
+
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
diff --git a/tmux.c b/tmux.c
index c7ee8e49..89c7fca7 100644
--- a/tmux.c
+++ b/tmux.c
@@ -1,4 +1,4 @@
-/* $Id: tmux.c,v 1.46 2007-12-06 18:28:55 nicm Exp $ */
+/* $Id: tmux.c,v 1.47 2008-06-02 18:08:17 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -42,6 +42,7 @@ const char *_malloc_options = "AJX";
volatile sig_atomic_t sigwinch;
volatile sig_atomic_t sigterm;
+char *cfg_file;
char *default_command;
char *paste_buffer;
int bell_action;
@@ -59,8 +60,7 @@ usage(char **ptr, const char *fmt, ...)
char *msg;
va_list ap;
-#define USAGE \
- "usage: %s [-v] [-S socket-path] [-s session-name] [-c client-tty]"
+#define USAGE "usage: %s [-v] [-f file] [-S socket-path]"
if (fmt == NULL) {
xasprintf(ptr, USAGE " command [flags]", __progname);
} else {
@@ -182,22 +182,19 @@ main(int argc, char **argv)
struct hdr hdr;
const char *shell;
struct passwd *pw;
- char *client, *path, *name, *cause;
+ char *client, *path, *name, *cause, *home;
char rpath[MAXPATHLEN];
int n, opt;
client = path = name = NULL;
- while ((opt = getopt(argc, argv, "c:S:s:vV")) != EOF) {
+ while ((opt = getopt(argc, argv, "c:f:S:s:vV")) != EOF) {
switch (opt) {
- case 'c':
- client = xstrdup(optarg);
+ case 'f':
+ cfg_file = xstrdup(optarg);
break;
case 'S':
path = xstrdup(optarg);
break;
- case 's':
- name = xstrdup(optarg);
- break;
case 'v':
debug_level++;
break;
@@ -225,6 +222,26 @@ main(int argc, char **argv)
paste_buffer = NULL;
+ if (cfg_file == NULL) {
+ home = getenv("HOME");
+ if (home == NULL || *home == '\0') {
+ pw = getpwuid(getuid());
+ if (pw != NULL)
+ home = pw->pw_dir;
+ endpwent();
+ }
+ xasprintf(&cfg_file, "%s/%s", home, DEFAULT_CFG);
+ if (access(cfg_file, R_OK) != 0) {
+ xfree(cfg_file);
+ cfg_file = NULL;
+ }
+ } else {
+ if (access(cfg_file, R_OK) != 0) {
+ log_warn("%s", cfg_file);
+ exit(1);
+ }
+ }
+
if (path == NULL) {
xasprintf(&path,
"%s/%s-%lu", _PATH_TMP, __progname, (u_long) getuid());
@@ -265,14 +282,10 @@ main(int argc, char **argv)
}
memset(&cctx, 0, sizeof cctx);
- if (!(cmd->entry->flags & CMD_NOSESSION) ||
- (cmd->entry->flags & CMD_CANTNEST))
- client_fill_session(&data);
+ client_fill_session(&data);
if (client_init(rpath, &cctx, cmd->entry->flags & CMD_STARTSERVER) != 0)
exit(1);
b = buffer_create(BUFSIZ);
- cmd_send_string(b, name);
- cmd_send_string(b, client);
cmd_send(cmd, b);
cmd_free(cmd);
@@ -280,9 +293,6 @@ main(int argc, char **argv)
MSG_COMMAND, &data, sizeof data, BUFFER_OUT(b), BUFFER_USED(b));
buffer_destroy(b);
- if (name != NULL)
- xfree(name);
-
for (;;) {
pfd.fd = cctx.srv_fd;
pfd.events = POLLIN;
diff --git a/tmux.h b/tmux.h
index ff5dbb41..830e059b 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1,4 +1,4 @@
-/* $Id: tmux.h,v 1.116 2008-06-01 20:20:25 nicm Exp $ */
+/* $Id: tmux.h,v 1.117 2008-06-02 18:08:17 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -63,6 +63,9 @@ extern char *__progname;
#define TTY_NAME_MAX 32
#endif
+/* Default configuration file. */
+#define DEFAULT_CFG ".tmux.conf"
+
/* Fatal errors. */
#define fatal(msg) log_fatal("%s: %s", __func__, msg);
#define fatalx(msg) log_fatalx("%s: %s", __func__, msg);
@@ -621,8 +624,9 @@ struct client_ctx {
struct cmd_ctx {
struct client *cmdclient;
- struct client *client;
- struct session *session;
+ struct client *curclient;
+ struct session *cursession;
+ struct msg_command_data *msgdata;
void (*print)(struct cmd_ctx *, const char *, ...);
void (*error)(struct cmd_ctx *, const char *, ...);
@@ -631,29 +635,27 @@ struct cmd_ctx {
int flags;
};
+struct cmd {
+ const struct cmd_entry *entry;
+ void *data;
+};
+
struct cmd_entry {
const char *name;
const char *alias;
const char *usage;
#define CMD_STARTSERVER 0x1
-#define CMD_NOSESSION 0x2
-#define CMD_NOCLIENT 0x4
-#define CMD_CANTNEST 0x8
+#define CMD_CANTNEST 0x2
int flags;
- int (*parse)(void **, int, char **, char **);
+ int (*parse)(struct cmd *, void **, int, char **, char **);
void (*exec)(void *, struct cmd_ctx *);
void (*send)(void *, struct buffer *);
void (*recv)(void **, struct buffer *);
void (*free)(void *);
};
-struct cmd {
- const struct cmd_entry *entry;
- void *data;
-};
-
/* Key binding. */
struct binding {
int key;
@@ -683,6 +685,7 @@ extern volatile sig_atomic_t sigterm;
#define BELL_ANY 1
#define BELL_CURRENT 2
extern char *default_command;
+extern char *cfg_file;
extern char *paste_buffer;
extern int bell_action;
extern int debug_level;
@@ -695,6 +698,9 @@ void logfile(const char *);
void siginit(void);
void sigreset(void);
+/* cfg.c */
+int load_cfg(const char *, char **x);
+
/* tty.c */
void tty_init(struct tty *, char *, char *);
int tty_open(struct tty *, char **);
@@ -725,6 +731,8 @@ struct cmd *cmd_recv(struct buffer *);
void cmd_free(struct cmd *);
void cmd_send_string(struct buffer *, const char *);
char *cmd_recv_string(struct buffer *);
+struct session *cmd_find_session(struct cmd_ctx *, const char *);
+struct client *cmd_find_client(struct cmd_ctx *, const char *);
extern const struct cmd_entry cmd_attach_session_entry;
extern const struct cmd_entry cmd_bind_key_entry;
extern const struct cmd_entry cmd_copy_mode_entry;
@@ -757,6 +765,22 @@ extern const struct cmd_entry cmd_unbind_key_entry;
extern const struct cmd_entry cmd_unlink_window_entry;
void cmd_select_window_default(void **, int);
+/* cmd-generic.c */
+#define CMD_CLIENTONLY_USAGE "[-c client-name]"
+int cmd_clientonly_parse(struct cmd *, void **, int, char **, char **);
+void cmd_clientonly_exec(void *, struct cmd_ctx *);
+void cmd_clientonly_send(void *, struct buffer *);
+void cmd_clientonly_recv(void **, struct buffer *);
+void cmd_clientonly_free(void *);
+struct client *cmd_clientonly_get(void *, struct cmd_ctx *);
+#define CMD_SESSIONONLY_USAGE "[-s session-name]"
+int cmd_sessiononly_parse(struct cmd *, void **, int, char **, char **);
+void cmd_sessiononly_exec(void *, struct cmd_ctx *);
+void cmd_sessiononly_send(void *, struct buffer *);
+void cmd_sessiononly_recv(void **, struct buffer *);
+void cmd_sessiononly_free(void *);
+struct session *cmd_sessiononly_get(void *, struct cmd_ctx *);
+
/* client.c */
int client_init(const char *, struct client_ctx *, int);
int client_flush(struct client_ctx *);