mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	String/number arguments..
This commit is contained in:
		
							
								
								
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | |||||||
| 03 October 2007 | 03 October 2007 | ||||||
|  |  | ||||||
|  | * (nicm) String number arguments. So you can do: tmux bind ^Q create "blah". | ||||||
| * (nicm) Key binding. tmux bind key command [argument] and tmux unbind key. | * (nicm) Key binding. tmux bind key command [argument] and tmux unbind key. | ||||||
|   Key names are in a table in key-string.c, plus A is A, ^A is ctrl-A. |   Key names are in a table in key-string.c, plus A is A, ^A is ctrl-A. | ||||||
|   Possible commands are in cmd.c (look at cmd_bind_table). |   Possible commands are in cmd.c (look at cmd_bind_table). | ||||||
| @@ -98,5 +99,5 @@ | |||||||
|   (including mutt, emacs). No status bar yet and no key remapping or other |   (including mutt, emacs). No status bar yet and no key remapping or other | ||||||
|   customisation. |   customisation. | ||||||
|  |  | ||||||
| $Id: CHANGES,v 1.24 2007-10-03 11:26:33 nicm Exp $ | $Id: CHANGES,v 1.25 2007-10-03 12:34:16 nicm Exp $ | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							| @@ -34,6 +34,7 @@ | |||||||
| 	packet... hrm. already scanning output for \e, could add an extra | 	packet... hrm. already scanning output for \e, could add an extra | ||||||
| 	byte to it for message | 	byte to it for message | ||||||
| - could use bsearch all over the place | - could use bsearch all over the place | ||||||
|  | - better errors when creating new windows/sessions (how?) | ||||||
|  |  | ||||||
| -- For 0.1 -------------------------------------------------------------------- | -- For 0.1 -------------------------------------------------------------------- | ||||||
| - man page | - man page | ||||||
| @@ -49,6 +50,7 @@ | |||||||
| 	set status on/off | 	set status on/off | ||||||
| 	set meta | 	set meta | ||||||
| 	set shell | 	set shell | ||||||
|  | 	list-keys (list key bindings) | ||||||
| - fix resize (width problems with multiple clients?) | - fix resize (width problems with multiple clients?) | ||||||
| - handle tmux in tmux (check $TMUX and abort) | - handle tmux in tmux (check $TMUX and abort) | ||||||
| - check for some reqd terminfo caps on startup | - check for some reqd terminfo caps on startup | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								client-fn.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								client-fn.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: client-fn.c,v 1.1 2007-10-03 10:18:31 nicm Exp $ */ | /* $Id: client-fn.c,v 1.2 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -62,6 +62,23 @@ client_write_server( | |||||||
| 	hdr.type = type; | 	hdr.type = type; | ||||||
| 	hdr.size = len; | 	hdr.size = len; | ||||||
| 	buffer_write(cctx->srv_out, &hdr, sizeof hdr); | 	buffer_write(cctx->srv_out, &hdr, sizeof hdr); | ||||||
| 	if (len > 0) |  | ||||||
|  | 	if (buf != NULL) | ||||||
| 		buffer_write(cctx->srv_out, buf, len); | 		buffer_write(cctx->srv_out, buf, len); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | client_write_server2(struct client_ctx *cctx, | ||||||
|  |     enum hdrtype type, void *buf1, size_t len1, void *buf2, size_t len2) | ||||||
|  | { | ||||||
|  | 	struct hdr	hdr; | ||||||
|  |  | ||||||
|  | 	hdr.type = type; | ||||||
|  | 	hdr.size = len1 + len2; | ||||||
|  | 	buffer_write(cctx->srv_out, &hdr, sizeof hdr); | ||||||
|  |  | ||||||
|  | 	if (buf1 != NULL) | ||||||
|  | 		buffer_write(cctx->srv_out, buf1, len1); | ||||||
|  | 	if (buf2 != NULL) | ||||||
|  | 		buffer_write(cctx->srv_out, buf2, len2); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										135
									
								
								cmd.c
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								cmd.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: cmd.c,v 1.2 2007-10-03 11:26:34 nicm Exp $ */ | /* $Id: cmd.c,v 1.3 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -25,54 +25,49 @@ | |||||||
|  |  | ||||||
| int	cmd_prefix = META; | int	cmd_prefix = META; | ||||||
|  |  | ||||||
| void	cmd_fn_create(struct client *, int); | void	cmd_fn_create(struct client *, struct cmd *); | ||||||
| void	cmd_fn_detach(struct client *, int); | void	cmd_fn_detach(struct client *, struct cmd *); | ||||||
| void	cmd_fn_last(struct client *, int); | void	cmd_fn_last(struct client *, struct cmd *); | ||||||
| void	cmd_fn_meta(struct client *, int); | void	cmd_fn_meta(struct client *, struct cmd *); | ||||||
| void	cmd_fn_next(struct client *, int); | void	cmd_fn_next(struct client *, struct cmd *); | ||||||
| void	cmd_fn_previous(struct client *, int); | void	cmd_fn_previous(struct client *, struct cmd *); | ||||||
| void	cmd_fn_refresh(struct client *, int); | void	cmd_fn_refresh(struct client *, struct cmd *); | ||||||
| void	cmd_fn_select(struct client *, int); | void	cmd_fn_select(struct client *, struct cmd *); | ||||||
| void	cmd_fn_windowinfo(struct client *, int); | void	cmd_fn_windowinfo(struct client *, struct cmd *); | ||||||
|  |  | ||||||
| struct cmd { |  | ||||||
| 	int	key; |  | ||||||
| 	void	(*fn)(struct client *, int); |  | ||||||
| 	int	arg; |  | ||||||
| }; |  | ||||||
| const struct cmd cmd_default[] = { | const struct cmd cmd_default[] = { | ||||||
| 	{ '0', cmd_fn_select, 0 }, | 	{ '0', cmd_fn_select, 0, NULL }, | ||||||
| 	{ '1', cmd_fn_select, 1 }, | 	{ '1', cmd_fn_select, 1, NULL }, | ||||||
| 	{ '2', cmd_fn_select, 2 }, | 	{ '2', cmd_fn_select, 2, NULL }, | ||||||
| 	{ '3', cmd_fn_select, 3 }, | 	{ '3', cmd_fn_select, 3, NULL }, | ||||||
| 	{ '4', cmd_fn_select, 4 }, | 	{ '4', cmd_fn_select, 4, NULL }, | ||||||
| 	{ '5', cmd_fn_select, 5 }, | 	{ '5', cmd_fn_select, 5, NULL }, | ||||||
| 	{ '6', cmd_fn_select, 6 }, | 	{ '6', cmd_fn_select, 6, NULL }, | ||||||
| 	{ '7', cmd_fn_select, 7 }, | 	{ '7', cmd_fn_select, 7, NULL }, | ||||||
| 	{ '8', cmd_fn_select, 8 }, | 	{ '8', cmd_fn_select, 8, NULL }, | ||||||
| 	{ '9', cmd_fn_select, 9 }, | 	{ '9', cmd_fn_select, 9, NULL }, | ||||||
| 	{ 'C', cmd_fn_create, 0 }, | 	{ 'C', cmd_fn_create, 0, NULL }, | ||||||
| 	{ 'c', cmd_fn_create, 0 }, | 	{ 'c', cmd_fn_create, 0, NULL }, | ||||||
| 	{ 'D', cmd_fn_detach, 0 }, | 	{ 'D', cmd_fn_detach, 0, NULL }, | ||||||
| 	{ 'd', cmd_fn_detach, 0 }, | 	{ 'd', cmd_fn_detach, 0, NULL }, | ||||||
| 	{ 'N', cmd_fn_next, 0 }, | 	{ 'N', cmd_fn_next, 0, NULL }, | ||||||
| 	{ 'n', cmd_fn_next, 0 }, | 	{ 'n', cmd_fn_next, 0, NULL }, | ||||||
| 	{ 'P', cmd_fn_previous, 0 }, | 	{ 'P', cmd_fn_previous, 0, NULL }, | ||||||
| 	{ 'p', cmd_fn_previous, 0 }, | 	{ 'p', cmd_fn_previous, 0, NULL }, | ||||||
| 	{ 'R', cmd_fn_refresh, 0 }, | 	{ 'R', cmd_fn_refresh, 0, NULL }, | ||||||
| 	{ 'r', cmd_fn_refresh, 0 }, | 	{ 'r', cmd_fn_refresh, 0, NULL }, | ||||||
| 	{ 'L', cmd_fn_last, 0 }, | 	{ 'L', cmd_fn_last, 0, NULL }, | ||||||
| 	{ 'l', cmd_fn_last, 0 }, | 	{ 'l', cmd_fn_last, 0, NULL }, | ||||||
| 	{ 'I', cmd_fn_windowinfo, 0 }, | 	{ 'I', cmd_fn_windowinfo, 0, NULL }, | ||||||
| 	{ 'i', cmd_fn_windowinfo, 0 }, | 	{ 'i', cmd_fn_windowinfo, 0, NULL }, | ||||||
| 	{ META, cmd_fn_meta, 0 }, | 	{ META, cmd_fn_meta, 0, NULL }, | ||||||
| }; | }; | ||||||
| u_int	cmd_count = (sizeof cmd_default / sizeof cmd_default[0]); | u_int	cmd_count = (sizeof cmd_default / sizeof cmd_default[0]); | ||||||
| struct cmd *cmd_table; | struct cmd *cmd_table; | ||||||
|  |  | ||||||
| const struct bind cmd_bind_table[] = { | const struct bind cmd_bind_table[] = { | ||||||
| 	{ "select", 	cmd_fn_select, -1 }, | 	{ "select", 	cmd_fn_select, BIND_NUMBER|BIND_USER }, | ||||||
| 	{ "create", 	cmd_fn_create, 0 }, | 	{ "create", 	cmd_fn_create, BIND_STRING|BIND_USER }, | ||||||
| 	{ "detach", 	cmd_fn_detach, 0 }, | 	{ "detach", 	cmd_fn_detach, 0 }, | ||||||
| 	{ "next",	cmd_fn_next, 0 }, | 	{ "next",	cmd_fn_next, 0 }, | ||||||
| 	{ "previous", 	cmd_fn_previous, 0 }, | 	{ "previous", 	cmd_fn_previous, 0 }, | ||||||
| @@ -98,7 +93,7 @@ cmd_lookup_bind(const char *name) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_add_bind(int key, int arg, const struct bind *bind) | cmd_add_bind(int key, u_int num, char *str, const struct bind *bind) | ||||||
| { | { | ||||||
| 	struct cmd	*cmd = NULL; | 	struct cmd	*cmd = NULL; | ||||||
| 	u_int		 i; | 	u_int		 i; | ||||||
| @@ -124,10 +119,12 @@ cmd_add_bind(int key, int arg, const struct bind *bind) | |||||||
|  |  | ||||||
| 	cmd->key = key; | 	cmd->key = key; | ||||||
| 	cmd->fn = bind->fn; | 	cmd->fn = bind->fn; | ||||||
| 	if (bind->arg != -1) | 	if (bind->flags & BIND_USER) { | ||||||
| 		cmd->arg = bind->arg; | 		if (bind->flags & BIND_STRING) | ||||||
| 	else | 			cmd->str = xstrdup(str); | ||||||
| 		cmd->arg = arg; | 		if (bind->flags & BIND_NUMBER) | ||||||
|  | 			cmd->num = num; | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| @@ -155,6 +152,7 @@ cmd_init(void) | |||||||
| void | void | ||||||
| cmd_free(void) | cmd_free(void) | ||||||
| { | { | ||||||
|  | 	/* XXX free strings */ | ||||||
| 	xfree(cmd_table); | 	xfree(cmd_table); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -167,35 +165,32 @@ cmd_dispatch(struct client *c, int key) | |||||||
| 	for (i = 0; i < cmd_count; i++) { | 	for (i = 0; i < cmd_count; i++) { | ||||||
| 		cmd = cmd_table + i; | 		cmd = cmd_table + i; | ||||||
| 		if (cmd->key != KEYC_NONE && cmd->key == key) | 		if (cmd->key != KEYC_NONE && cmd->key == key) | ||||||
| 			cmd->fn(c, cmd->arg); | 			cmd->fn(c, cmd); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_create(struct client *c, unused int arg) | cmd_fn_create(struct client *c, struct cmd *cmd) | ||||||
| { | { | ||||||
| 	const char	*shell; | 	char	*s; | ||||||
| 	char		*cmd; |  | ||||||
|  |  | ||||||
| 	shell = getenv("SHELL"); | 	s = cmd->str; | ||||||
| 	if (shell == NULL) | 	if (s == NULL) | ||||||
| 		shell = "/bin/ksh"; | 		s = default_command; | ||||||
| 	xasprintf(&cmd, "%s -l", shell); | 	if (session_new(c->session, s, c->sx, c->sy) != 0) | ||||||
| 	if (session_new(c->session, cmd, c->sx, c->sy) != 0) | 		server_write_message(c, "%s failed", s); /* XXX */ | ||||||
| 		fatalx("session_new failed"); | 	else | ||||||
| 	xfree(cmd); | 		server_draw_client(c, 0, c->sy - 1); | ||||||
|  |  | ||||||
| 	server_draw_client(c, 0, c->sy - 1); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_detach(struct client *c, unused int arg) | cmd_fn_detach(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	server_write_client(c, MSG_DETACH, NULL, 0); | 	server_write_client(c, MSG_DETACH, NULL, 0); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_last(struct client *c, unused int arg) | cmd_fn_last(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	if (session_last(c->session) == 0) | 	if (session_last(c->session) == 0) | ||||||
| 		server_window_changed(c); | 		server_window_changed(c); | ||||||
| @@ -204,13 +199,13 @@ cmd_fn_last(struct client *c, unused int arg) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_meta(struct client *c, unused int arg) | cmd_fn_meta(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	window_key(c->session->window, cmd_prefix); | 	window_key(c->session->window, cmd_prefix); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_next(struct client *c, unused int arg) | cmd_fn_next(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	if (session_next(c->session) == 0) | 	if (session_next(c->session) == 0) | ||||||
| 		server_window_changed(c); | 		server_window_changed(c); | ||||||
| @@ -219,7 +214,7 @@ cmd_fn_next(struct client *c, unused int arg) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_previous(struct client *c, unused int arg) | cmd_fn_previous(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	if (session_previous(c->session) == 0) | 	if (session_previous(c->session) == 0) | ||||||
| 		server_window_changed(c); | 		server_window_changed(c); | ||||||
| @@ -228,22 +223,22 @@ cmd_fn_previous(struct client *c, unused int arg) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_refresh(struct client *c, unused int arg) | cmd_fn_refresh(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	server_draw_client(c, 0, c->sy - 1); | 	server_draw_client(c, 0, c->sy - 1); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_select(struct client *c, int arg) | cmd_fn_select(struct client *c, struct cmd *cmd) | ||||||
| { | { | ||||||
| 	if (session_select(c->session, arg) == 0) | 	if (session_select(c->session, cmd->num) == 0) | ||||||
| 		server_window_changed(c); | 		server_window_changed(c); | ||||||
| 	else | 	else | ||||||
| 		server_write_message(c, "Window %u not present", arg);  | 		server_write_message(c, "Window %u not present", cmd->num); | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| cmd_fn_windowinfo(struct client *c, unused int arg) | cmd_fn_windowinfo(struct client *c, unused struct cmd *cmd) | ||||||
| { | { | ||||||
| 	struct window	*w; | 	struct window	*w; | ||||||
| 	char 		*buf; | 	char 		*buf; | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								op.c
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								op.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: op.c,v 1.10 2007-10-03 11:26:34 nicm Exp $ */ | /* $Id: op.c,v 1.11 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -168,7 +168,10 @@ op_bind_key(char *path, int argc, char **argv) | |||||||
| 	struct client_ctx	cctx; | 	struct client_ctx	cctx; | ||||||
| 	int			opt; | 	int			opt; | ||||||
| 	const char	       *errstr; | 	const char	       *errstr; | ||||||
|  | 	char		       *str; | ||||||
|  | 	size_t			len; | ||||||
|  |  	const struct bind      *bind; | ||||||
|  | 	 | ||||||
| 	optind = 1; | 	optind = 1; | ||||||
| 	while ((opt = getopt(argc, argv, "?")) != EOF) { | 	while ((opt = getopt(argc, argv, "?")) != EOF) { | ||||||
| 		switch (opt) { | 		switch (opt) { | ||||||
| @@ -190,19 +193,46 @@ op_bind_key(char *path, int argc, char **argv) | |||||||
| 		return (1); | 		return (1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (argc == 3) { | 	if ((bind = cmd_lookup_bind(data.cmd)) == NULL) { | ||||||
| 		data.arg = strtonum(argv[2], 0, INT_MAX, &errstr); | 		log_warnx("unknown command: %s", data.cmd); | ||||||
| 		if (errstr != NULL) { | 		return (1); | ||||||
| 			log_warnx("argument %s: %s", errstr, argv[2]);  | 	} | ||||||
|  |  | ||||||
|  | 	str = NULL; | ||||||
|  | 	len = 0; | ||||||
|  | 	if (bind->flags & BIND_USER) { | ||||||
|  | 		if (argc != 3) { | ||||||
|  | 			log_warnx("%s requires an argument", data.cmd); | ||||||
| 			return (1); | 			return (1); | ||||||
| 		} | 		} | ||||||
| 	} else |  | ||||||
| 		data.arg = -1; | 		data.flags |= BIND_USER; | ||||||
|  | 		if (bind->flags & BIND_STRING) { | ||||||
|  | 			data.flags |= BIND_STRING; | ||||||
|  | 			str = argv[2]; | ||||||
|  | 			len = strlen(str); | ||||||
|  | 		} else if (bind->flags & BIND_NUMBER) { | ||||||
|  | 			data.flags |= BIND_NUMBER; | ||||||
|  | 			data.num = strtonum(argv[2], 0, INT_MAX, &errstr); | ||||||
|  | 			if (errstr != NULL) { | ||||||
|  | 				log_warnx("argument %s: %s", errstr, argv[2]);  | ||||||
|  | 				return (1); | ||||||
|  | 			} | ||||||
|  | 		} else | ||||||
|  | 			fatalx("no argument type"); | ||||||
|  | 	} else { | ||||||
|  | 		if (argc != 2) { | ||||||
|  | 			log_warnx("%s cannot have an argument", data.cmd); | ||||||
|  | 			return (1); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		data.flags = 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if (client_init(path, &cctx, 1) != 0) | 	if (client_init(path, &cctx, 1) != 0) | ||||||
| 		return (1); | 		return (1); | ||||||
|  |  | ||||||
| 	client_write_server(&cctx, MSG_BINDKEY, &data, sizeof data); | 	client_write_server2(&cctx, MSG_BINDKEY, &data, sizeof data, str, len); | ||||||
|  |  | ||||||
| 	return (client_flush(&cctx)); | 	return (client_flush(&cctx)); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: server-fn.c,v 1.12 2007-10-03 10:18:32 nicm Exp $ */ | /* $Id: server-fn.c,v 1.13 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -230,6 +230,8 @@ server_write_message(struct client *c, const char *fmt, ...) | |||||||
| 	va_start(ap, fmt); | 	va_start(ap, fmt); | ||||||
| 	xvasprintf(&msg, fmt, ap); | 	xvasprintf(&msg, fmt, ap); | ||||||
| 	va_end(ap); | 	va_end(ap); | ||||||
|  | 	if (strlen(msg) > c->sx - 1) | ||||||
|  | 		msg[c->sx - 1] = '\0'; | ||||||
| 	buffer_write(c->out, msg, strlen(msg)); | 	buffer_write(c->out, msg, strlen(msg)); | ||||||
| 	for (i = strlen(msg); i < c->sx; i++) | 	for (i = strlen(msg); i < c->sx; i++) | ||||||
| 		input_store8(c->out, ' '); | 		input_store8(c->out, ' '); | ||||||
|   | |||||||
							
								
								
									
										75
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								server-msg.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: server-msg.c,v 1.17 2007-10-03 11:26:34 nicm Exp $ */ | /* $Id: server-msg.c,v 1.18 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -88,14 +88,13 @@ int | |||||||
| server_msg_fn_new(struct hdr *hdr, struct client *c) | server_msg_fn_new(struct hdr *hdr, struct client *c) | ||||||
| { | { | ||||||
| 	struct new_data	 data; | 	struct new_data	 data; | ||||||
| 	const char      *shell; | 	char	         *msg; | ||||||
| 	char		*cmd, *msg; |  | ||||||
| 	 | 	 | ||||||
| 	if (c->session != NULL) | 	if (c->session != NULL) | ||||||
| 		return (0); | 		return (0); | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_NEW size"); | 		fatalx("bad MSG_NEW size"); | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	c->sx = data.sx; | 	c->sx = data.sx; | ||||||
| 	if (c->sx == 0) | 	if (c->sx == 0) | ||||||
| @@ -115,14 +114,9 @@ server_msg_fn_new(struct hdr *hdr, struct client *c) | |||||||
| 		return (0); | 		return (0); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	shell = getenv("SHELL"); | 	c->session = session_create(data.name, default_command, c->sx, c->sy); | ||||||
| 	if (shell == NULL) |  | ||||||
| 		shell = "/bin/ksh"; |  | ||||||
| 	xasprintf(&cmd, "%s -l", shell); |  | ||||||
| 	c->session = session_create(data.name, cmd, c->sx, c->sy); |  | ||||||
| 	if (c->session == NULL) | 	if (c->session == NULL) | ||||||
| 		fatalx("session_create failed"); | 		fatalx("session_create failed"); | ||||||
| 	xfree(cmd); |  | ||||||
|  |  | ||||||
| 	server_write_client(c, MSG_OKAY, NULL, 0); | 	server_write_client(c, MSG_OKAY, NULL, 0); | ||||||
| 	server_draw_client(c, 0, c->sy - 1); | 	server_draw_client(c, 0, c->sy - 1); | ||||||
| @@ -141,7 +135,7 @@ server_msg_fn_attach(struct hdr *hdr, struct client *c) | |||||||
| 		return (0); | 		return (0); | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_ATTACH size"); | 		fatalx("bad MSG_ATTACH size"); | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	c->sx = data.sx; | 	c->sx = data.sx; | ||||||
| 	if (c->sx == 0) | 	if (c->sx == 0) | ||||||
| @@ -174,7 +168,7 @@ server_msg_fn_size(struct hdr *hdr, struct client *c) | |||||||
| 		return (0); | 		return (0); | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_SIZE size"); | 		fatalx("bad MSG_SIZE size"); | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	c->sx = data.sx; | 	c->sx = data.sx; | ||||||
| 	if (c->sx == 0) | 	if (c->sx == 0) | ||||||
| @@ -206,7 +200,7 @@ server_msg_fn_keys(struct hdr *hdr, struct client *c) | |||||||
|  |  | ||||||
| 	size = hdr->size; | 	size = hdr->size; | ||||||
| 	while (size != 0) { | 	while (size != 0) { | ||||||
| 		key = input_extract16(c->in); | 		key = (int16_t) input_extract16(c->in); | ||||||
| 		size -= 2; | 		size -= 2; | ||||||
|  |  | ||||||
| 		if (c->prefix) { | 		if (c->prefix) { | ||||||
| @@ -235,7 +229,7 @@ server_msg_fn_sessions(struct hdr *hdr, struct client *c) | |||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_SESSIONS size"); | 		fatalx("bad MSG_SESSIONS size"); | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	data.sessions = 0; | 	data.sessions = 0; | ||||||
| 	for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { | 	for (i = 0; i < ARRAY_LENGTH(&sessions); i++) { | ||||||
| @@ -275,7 +269,7 @@ server_msg_fn_windows(struct hdr *hdr, struct client *c) | |||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_WINDOWS size"); | 		fatalx("bad MSG_WINDOWS size"); | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | ||||||
| 		server_write_error(c, "%s", cause); | 		server_write_error(c, "%s", cause); | ||||||
| @@ -318,8 +312,7 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c) | |||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_RENAME size"); | 		fatalx("bad MSG_RENAME size"); | ||||||
|  | 	buffer_read(c->in, &data, sizeof data); | ||||||
| 	buffer_read(c->in, &data, hdr->size); |  | ||||||
|  |  | ||||||
|  	data.newname[(sizeof data.newname) - 1] = '\0'; |  	data.newname[(sizeof data.newname) - 1] = '\0'; | ||||||
| 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | 	if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { | ||||||
| @@ -395,28 +388,40 @@ server_msg_fn_bindkey(struct hdr *hdr, struct client *c) | |||||||
| { | { | ||||||
| 	struct bind_data	data; | 	struct bind_data	data; | ||||||
| 	const struct bind      *bind; | 	const struct bind      *bind; | ||||||
|  | 	char		       *str; | ||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size < sizeof data) | ||||||
| 		fatalx("bad MSG_BIND size"); | 		fatalx("bad MSG_BINDKEY size"); | ||||||
|  | 	buffer_read(c->in, &data, sizeof data); | ||||||
|  |  | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	str = NULL; | ||||||
|  | 	if (data.flags & BIND_STRING) { | ||||||
|  | 		hdr->size -= sizeof data; | ||||||
|  |  | ||||||
|  | 		if (hdr->size != 0) { | ||||||
|  | 			str = xmalloc(hdr->size + 1); | ||||||
|  | 			buffer_read(c->in, str, hdr->size); | ||||||
|  | 			str[hdr->size] = '\0'; | ||||||
|  | 		} | ||||||
|  | 		if (*str == '\0') { | ||||||
|  | 			xfree(str); | ||||||
|  | 			str = NULL; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  	data.cmd[(sizeof data.cmd) - 1] = '\0';	 |  	data.cmd[(sizeof data.cmd) - 1] = '\0';	 | ||||||
| 	if ((bind = cmd_lookup_bind(data.cmd)) == NULL) { | 	if ((bind = cmd_lookup_bind(data.cmd)) == NULL) | ||||||
| 		server_write_error(c, "unknown command: %s", data.cmd); | 		fatalx("unknown command"); | ||||||
| 		return (0); | 	if (!(bind->flags & BIND_USER) && | ||||||
| 	} | 	    (data.flags & (BIND_NUMBER|BIND_STRING)) != 0) | ||||||
|  | 		fatalx("argument missing"); | ||||||
| 	if (bind->arg != -1 && data.arg != -1) {  | 	if ((bind->flags & BIND_USER) && | ||||||
| 		server_write_error(c, "%s cannot have an argument", data.cmd); | 	    (data.flags & (BIND_NUMBER|BIND_STRING)) == 0) | ||||||
| 		return (0); | 		fatalx("argument required"); | ||||||
| 	} |  | ||||||
| 	if (bind->arg == -1 && data.arg == -1) { |  | ||||||
| 		server_write_error(c, "%s requires an argument", data.cmd); |  | ||||||
| 		return (0); |  | ||||||
| 	}		 |  | ||||||
| 	 | 	 | ||||||
| 	cmd_add_bind(data.key, data.arg, bind); | 	cmd_add_bind(data.key, data.num, str, bind); | ||||||
|  | 	if (str != NULL) | ||||||
|  | 		xfree(str); | ||||||
|  |  | ||||||
| 	server_write_client(c, MSG_OKAY, NULL, 0); | 	server_write_client(c, MSG_OKAY, NULL, 0); | ||||||
|  |  | ||||||
| @@ -430,7 +435,7 @@ server_msg_fn_unbindkey(struct hdr *hdr, struct client *c) | |||||||
| 	struct bind_data	data; | 	struct bind_data	data; | ||||||
|  |  | ||||||
| 	if (hdr->size != sizeof data) | 	if (hdr->size != sizeof data) | ||||||
| 		fatalx("bad MSG_UNBIND size"); | 		fatalx("bad MSG_UNBINDKEY size"); | ||||||
|  |  | ||||||
| 	buffer_read(c->in, &data, hdr->size); | 	buffer_read(c->in, &data, hdr->size); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								tmux.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tmux.c,v 1.21 2007-10-03 11:26:34 nicm Exp $ */ | /* $Id: tmux.c,v 1.22 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -36,6 +36,7 @@ volatile sig_atomic_t sigwinch; | |||||||
| volatile sig_atomic_t sigterm; | volatile sig_atomic_t sigterm; | ||||||
| int		 debug_level; | int		 debug_level; | ||||||
| u_int		 status_lines; | u_int		 status_lines; | ||||||
|  | char		*default_command; | ||||||
|  |  | ||||||
| void		 sighandler(int); | void		 sighandler(int); | ||||||
|  |  | ||||||
| @@ -172,6 +173,7 @@ int | |||||||
| main(int argc, char **argv) | main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	const struct op		*op, *found; | 	const struct op		*op, *found; | ||||||
|  | 	const char		*shell; | ||||||
| 	char			*path; | 	char			*path; | ||||||
| 	int	 		 opt; | 	int	 		 opt; | ||||||
| 	u_int			 i; | 	u_int			 i; | ||||||
| @@ -199,6 +201,11 @@ main(int argc, char **argv) | |||||||
|  |  | ||||||
| 	status_lines = 1; | 	status_lines = 1; | ||||||
|  |  | ||||||
|  | 	shell = getenv("SHELL"); | ||||||
|  | 	if (shell == NULL) | ||||||
|  | 		shell = "/bin/ksh"; | ||||||
|  | 	xasprintf(&default_command, "%s -l", shell); | ||||||
|  |  | ||||||
| 	found = NULL; | 	found = NULL; | ||||||
| 	for (i = 0; i < NOP; i++) { | 	for (i = 0; i < NOP; i++) { | ||||||
| 		op = op_table + i; | 		op = op_table + i; | ||||||
|   | |||||||
							
								
								
									
										32
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tmux.h,v 1.35 2007-10-03 11:26:34 nicm Exp $ */ | /* $Id: tmux.h,v 1.36 2007-10-03 12:34:16 nicm Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -339,7 +339,10 @@ struct rename_data { | |||||||
| struct bind_data { | struct bind_data { | ||||||
| 	int		key; | 	int		key; | ||||||
| 	char		cmd[MAXNAMELEN]; | 	char		cmd[MAXNAMELEN]; | ||||||
| 	int		arg; |  | ||||||
|  | 	int		flags; | ||||||
|  |  | ||||||
|  | 	u_int		num; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* Attributes. */ | /* Attributes. */ | ||||||
| @@ -494,18 +497,31 @@ struct client_ctx { | |||||||
| 	struct winsize	 ws; | 	struct winsize	 ws; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /* Key command. */ | ||||||
|  | struct cmd { | ||||||
|  | 	int	key; | ||||||
|  | 	void	(*fn)(struct client *, struct cmd *); | ||||||
|  | 	u_int	num; | ||||||
|  | 	char   *str; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Key binding. */ | /* Key binding. */ | ||||||
| struct bind { | struct bind { | ||||||
| 	const char	*name; | 	const char	*name; | ||||||
| 	void		 (*fn)(struct client *, int); | 	void		 (*fn)(struct client *, struct cmd *); | ||||||
| 	int     	 arg;	/* -1 if user specifies */ | 	 | ||||||
|  | #define BIND_USER 0x1 | ||||||
|  | #define BIND_NUMBER 0x2 | ||||||
|  | #define BIND_STRING 0x4 | ||||||
|  | 	int		 flags; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* tmux.c */ | /* tmux.c */ | ||||||
| extern volatile sig_atomic_t sigwinch; | extern volatile sig_atomic_t sigwinch; | ||||||
| extern volatile sig_atomic_t sigterm; | extern volatile sig_atomic_t sigterm; | ||||||
| extern int debug_level; | extern int	debug_level; | ||||||
| extern u_int status_lines; | extern u_int	status_lines; | ||||||
|  | extern char    *default_command; | ||||||
| int	 	 usage(const char *, ...); | int	 	 usage(const char *, ...); | ||||||
| void		 logfile(const char *); | void		 logfile(const char *); | ||||||
| void		 siginit(void); | void		 siginit(void); | ||||||
| @@ -532,12 +548,14 @@ int	 client_msg_dispatch(struct client_ctx *, char **); | |||||||
|  |  | ||||||
| /* client-fn.c */ | /* client-fn.c */ | ||||||
| void	 client_write_server(struct client_ctx *, enum hdrtype, void *, size_t); | void	 client_write_server(struct client_ctx *, enum hdrtype, void *, size_t); | ||||||
|  | void	 client_write_server2( | ||||||
|  |     	     struct client_ctx *, enum hdrtype, void *, size_t, void *, size_t); | ||||||
| void	 client_fill_sessid(struct sessid *, char [MAXNAMELEN]); | void	 client_fill_sessid(struct sessid *, char [MAXNAMELEN]); | ||||||
|  |  | ||||||
| /* cmd.c */ | /* cmd.c */ | ||||||
| extern int cmd_prefix; | extern int cmd_prefix; | ||||||
| const struct bind *cmd_lookup_bind(const char *); | const struct bind *cmd_lookup_bind(const char *); | ||||||
| void	 cmd_add_bind(int, int, const struct bind *); | void	 cmd_add_bind(int, u_int, char *, const struct bind *); | ||||||
| void	 cmd_remove_bind(int); | void	 cmd_remove_bind(int); | ||||||
| void     cmd_init(void); | void     cmd_init(void); | ||||||
| void     cmd_free(void); | void     cmd_free(void); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott