summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2008-06-02 18:08:17 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2008-06-02 18:08:17 +0000
commitc7243b73cb3baaf6993d8a9dfb16c054c3978040 (patch)
tree1d67ee4c5cf764dc83245c79d27da52857b4a89d
parent11ee55e755af67dc9155e956b4569c8fdeb11848 (diff)
Move -s and -c down a level so handling them is the responsibility of the command (with some helper functions), rather than the top-level. This changes the action command syntax so that -s and -c must be after the command rather than before.
-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_win