mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	Similarly for MSG_COMMAND - allow full imsg limit not arbitrary 2048.
This commit is contained in:
		
							
								
								
									
										66
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								client.c
									
									
									
									
									
								
							@@ -54,7 +54,8 @@ int		client_get_lock(char *);
 | 
			
		||||
int		client_connect(char *, int);
 | 
			
		||||
void		client_send_identify(int);
 | 
			
		||||
void		client_send_environ(void);
 | 
			
		||||
void		client_write_server(enum msgtype, void *, size_t);
 | 
			
		||||
int		client_write_one(enum msgtype, int, const void *, size_t);
 | 
			
		||||
int		client_write_server(enum msgtype, const void *, size_t);
 | 
			
		||||
void		client_update_event(void);
 | 
			
		||||
void		client_signal(int, short, void *);
 | 
			
		||||
void		client_stdin_callback(int, short, void *);
 | 
			
		||||
@@ -165,12 +166,13 @@ client_main(int argc, char **argv, int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd		*cmd;
 | 
			
		||||
	struct cmd_list		*cmdlist;
 | 
			
		||||
	struct msg_command_data	 cmddata;
 | 
			
		||||
	int			 cmdflags, fd;
 | 
			
		||||
	struct msg_command_data	*data;
 | 
			
		||||
	int			 cmdflags, fd, i;
 | 
			
		||||
	pid_t			 ppid;
 | 
			
		||||
	enum msgtype		 msg;
 | 
			
		||||
	char			*cause;
 | 
			
		||||
	struct termios		 tio, saved_tio;
 | 
			
		||||
	size_t			 size;
 | 
			
		||||
 | 
			
		||||
	/* Set up the initial command. */
 | 
			
		||||
	cmdflags = 0;
 | 
			
		||||
@@ -265,19 +267,32 @@ client_main(int argc, char **argv, int flags)
 | 
			
		||||
 | 
			
		||||
	/* Send first command. */
 | 
			
		||||
	if (msg == MSG_COMMAND) {
 | 
			
		||||
		/* How big is the command? */
 | 
			
		||||
		size = 0;
 | 
			
		||||
		for (i = 0; i < argc; i++)
 | 
			
		||||
			size += strlen(argv[i]) + 1;
 | 
			
		||||
		data = xmalloc((sizeof *data) + size);
 | 
			
		||||
 | 
			
		||||
		/* Fill in command line arguments. */
 | 
			
		||||
		cmddata.pid = environ_pid;
 | 
			
		||||
		cmddata.session_id = environ_session_id;
 | 
			
		||||
		data->pid = environ_pid;
 | 
			
		||||
		data->session_id = environ_session_id;
 | 
			
		||||
 | 
			
		||||
		/* Prepare command for server. */
 | 
			
		||||
		cmddata.argc = argc;
 | 
			
		||||
		if (cmd_pack_argv(
 | 
			
		||||
		    argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
 | 
			
		||||
		data->argc = argc;
 | 
			
		||||
		if (cmd_pack_argv(argc, argv, (char*)(data + 1), size) != 0) {
 | 
			
		||||
			fprintf(stderr, "command too long\n");
 | 
			
		||||
			free(data);
 | 
			
		||||
			return (1);
 | 
			
		||||
		}
 | 
			
		||||
		size += sizeof *data;
 | 
			
		||||
 | 
			
		||||
		client_write_server(msg, &cmddata, sizeof cmddata);
 | 
			
		||||
		/* Send the command. */
 | 
			
		||||
		if (client_write_server(msg, data, size) != 0) {
 | 
			
		||||
			fprintf(stderr, "failed to send command\n");
 | 
			
		||||
			free(data);
 | 
			
		||||
			return (1);
 | 
			
		||||
		}
 | 
			
		||||
		free(data);
 | 
			
		||||
	} else if (msg == MSG_SHELL)
 | 
			
		||||
		client_write_server(msg, NULL, 0);
 | 
			
		||||
 | 
			
		||||
@@ -349,12 +364,29 @@ client_send_environ(void)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Write a message to the server without a file descriptor. */
 | 
			
		||||
void
 | 
			
		||||
client_write_server(enum msgtype type, void *buf, size_t len)
 | 
			
		||||
/* Helper to send one message. */
 | 
			
		||||
int
 | 
			
		||||
client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
 | 
			
		||||
	client_update_event();
 | 
			
		||||
	int	retval;
 | 
			
		||||
 | 
			
		||||
	retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd,
 | 
			
		||||
	    (void*)buf, len);
 | 
			
		||||
	if (retval != 1)
 | 
			
		||||
		return (-1);
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Write a message to the server without a file descriptor. */
 | 
			
		||||
int
 | 
			
		||||
client_write_server(enum msgtype type, const void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	int	retval;
 | 
			
		||||
 | 
			
		||||
	retval = client_write_one(type, -1, buf, len);
 | 
			
		||||
	if (retval == 0)
 | 
			
		||||
		client_update_event();
 | 
			
		||||
	return (retval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Update client event based on whether it needs to read or read and write. */
 | 
			
		||||
@@ -537,14 +569,16 @@ client_dispatch_wait(void *data0)
 | 
			
		||||
				fatalx("bad MSG_STDOUT size");
 | 
			
		||||
			memcpy(&stdoutdata, data, sizeof stdoutdata);
 | 
			
		||||
 | 
			
		||||
			client_write(STDOUT_FILENO, stdoutdata.data, stdoutdata.size);
 | 
			
		||||
			client_write(STDOUT_FILENO, stdoutdata.data,
 | 
			
		||||
			    stdoutdata.size);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_STDERR:
 | 
			
		||||
			if (datalen != sizeof stderrdata)
 | 
			
		||||
				fatalx("bad MSG_STDERR size");
 | 
			
		||||
			memcpy(&stderrdata, data, sizeof stderrdata);
 | 
			
		||||
 | 
			
		||||
			client_write(STDERR_FILENO, stderrdata.data, stderrdata.size);
 | 
			
		||||
			client_write(STDERR_FILENO, stderrdata.data,
 | 
			
		||||
			    stderrdata.size);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_VERSION:
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ void	server_client_reset_state(struct client *);
 | 
			
		||||
int	server_client_assume_paste(struct session *);
 | 
			
		||||
 | 
			
		||||
int	server_client_msg_dispatch(struct client *);
 | 
			
		||||
void	server_client_msg_command(struct client *, struct msg_command_data *);
 | 
			
		||||
void	server_client_msg_command(struct client *, struct imsg *);
 | 
			
		||||
void	server_client_msg_identify(
 | 
			
		||||
	    struct client *, struct msg_identify_data *, int);
 | 
			
		||||
void	server_client_msg_shell(struct client *);
 | 
			
		||||
@@ -786,10 +786,10 @@ int
 | 
			
		||||
server_client_msg_dispatch(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	struct imsg		 imsg;
 | 
			
		||||
	struct msg_command_data	 commanddata;
 | 
			
		||||
	struct msg_identify_data identifydata;
 | 
			
		||||
	struct msg_environ_data	 environdata;
 | 
			
		||||
	struct msg_stdin_data	 stdindata;
 | 
			
		||||
	const char		*data;
 | 
			
		||||
	ssize_t			 n, datalen;
 | 
			
		||||
 | 
			
		||||
	if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
 | 
			
		||||
@@ -800,6 +800,8 @@ server_client_msg_dispatch(struct client *c)
 | 
			
		||||
			return (-1);
 | 
			
		||||
		if (n == 0)
 | 
			
		||||
			return (0);
 | 
			
		||||
 | 
			
		||||
		data = imsg.data;
 | 
			
		||||
		datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
 | 
			
		||||
 | 
			
		||||
		if (imsg.hdr.peerid != PROTOCOL_VERSION) {
 | 
			
		||||
@@ -811,13 +813,6 @@ server_client_msg_dispatch(struct client *c)
 | 
			
		||||
 | 
			
		||||
		log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd);
 | 
			
		||||
		switch (imsg.hdr.type) {
 | 
			
		||||
		case MSG_COMMAND:
 | 
			
		||||
			if (datalen != sizeof commanddata)
 | 
			
		||||
				fatalx("bad MSG_COMMAND size");
 | 
			
		||||
			memcpy(&commanddata, imsg.data, sizeof commanddata);
 | 
			
		||||
 | 
			
		||||
			server_client_msg_command(c, &commanddata);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_IDENTIFY:
 | 
			
		||||
			if (datalen != sizeof identifydata)
 | 
			
		||||
				fatalx("bad MSG_IDENTIFY size");
 | 
			
		||||
@@ -827,10 +822,13 @@ server_client_msg_dispatch(struct client *c)
 | 
			
		||||
#endif
 | 
			
		||||
			server_client_msg_identify(c, &identifydata, imsg.fd);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_COMMAND:
 | 
			
		||||
			server_client_msg_command(c, &imsg);
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_STDIN:
 | 
			
		||||
			if (datalen != sizeof stdindata)
 | 
			
		||||
				fatalx("bad MSG_STDIN size");
 | 
			
		||||
			memcpy(&stdindata, imsg.data, sizeof stdindata);
 | 
			
		||||
			memcpy(&stdindata, data, sizeof stdindata);
 | 
			
		||||
 | 
			
		||||
			if (c->stdin_callback == NULL)
 | 
			
		||||
				break;
 | 
			
		||||
@@ -905,15 +903,26 @@ server_client_msg_dispatch(struct client *c)
 | 
			
		||||
 | 
			
		||||
/* Handle command message. */
 | 
			
		||||
void
 | 
			
		||||
server_client_msg_command(struct client *c, struct msg_command_data *data)
 | 
			
		||||
server_client_msg_command(struct client *c, struct imsg *imsg)
 | 
			
		||||
{
 | 
			
		||||
	struct cmd_list	*cmdlist = NULL;
 | 
			
		||||
	int		 argc;
 | 
			
		||||
	char	       **argv, *cause;
 | 
			
		||||
	struct msg_command_data	  data;
 | 
			
		||||
	char			 *buf;
 | 
			
		||||
	size_t			  len;
 | 
			
		||||
	struct cmd_list		 *cmdlist = NULL;
 | 
			
		||||
	int			  argc;
 | 
			
		||||
	char			**argv, *cause;
 | 
			
		||||
 | 
			
		||||
	argc = data->argc;
 | 
			
		||||
	data->argv[(sizeof data->argv) - 1] = '\0';
 | 
			
		||||
	if (cmd_unpack_argv(data->argv, sizeof data->argv, argc, &argv) != 0) {
 | 
			
		||||
	if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
 | 
			
		||||
		fatalx("bad MSG_COMMAND size");
 | 
			
		||||
	memcpy(&data, imsg->data, sizeof data);
 | 
			
		||||
 | 
			
		||||
	buf = (char*)imsg->data + sizeof data;
 | 
			
		||||
	len = imsg->hdr.len  - IMSG_HEADER_SIZE - sizeof data;
 | 
			
		||||
	if (len > 0 && buf[len - 1] != '\0')
 | 
			
		||||
		fatalx("bad MSG_COMMAND string");
 | 
			
		||||
 | 
			
		||||
	argc = data.argc;
 | 
			
		||||
	if (cmd_unpack_argv(buf, len, argc, &argv) != 0) {
 | 
			
		||||
		cmdq_error(c->cmdq, "command too long");
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -236,7 +236,6 @@ void
 | 
			
		||||
server_lock_client(struct client *c)
 | 
			
		||||
{
 | 
			
		||||
	const char	*cmd;
 | 
			
		||||
	size_t		 cmdlen;
 | 
			
		||||
 | 
			
		||||
	if (c->flags & CLIENT_CONTROL)
 | 
			
		||||
		return;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								tmux.h
									
									
									
									
									
								
							@@ -55,7 +55,6 @@ extern char   **environ;
 | 
			
		||||
 * Maximum sizes of strings in message data. Don't forget to bump
 | 
			
		||||
 * PROTOCOL_VERSION if any of these change!
 | 
			
		||||
 */
 | 
			
		||||
#define COMMAND_LENGTH 2048	/* packed argv size */
 | 
			
		||||
#define TERMINAL_LENGTH 128	/* length of TERM environment variable */
 | 
			
		||||
#define ENVIRON_LENGTH 1024	/* environment variable length */
 | 
			
		||||
 | 
			
		||||
@@ -468,16 +467,14 @@ enum msgtype {
 | 
			
		||||
 * Don't forget to bump PROTOCOL_VERSION if any of these change!
 | 
			
		||||
 */
 | 
			
		||||
struct msg_command_data {
 | 
			
		||||
	pid_t		pid;		/* from $TMUX or -1 */
 | 
			
		||||
	int		session_id;	/* from $TMUX or -1 */
 | 
			
		||||
	pid_t	pid;		/* from $TMUX or -1 */
 | 
			
		||||
	int	session_id;	/* from $TMUX or -1 */
 | 
			
		||||
 | 
			
		||||
	int		argc;
 | 
			
		||||
	char		argv[COMMAND_LENGTH];
 | 
			
		||||
};
 | 
			
		||||
	int	argc;
 | 
			
		||||
}; /* followed by packed argv */
 | 
			
		||||
 | 
			
		||||
struct msg_identify_data {
 | 
			
		||||
	char		cwd[MAXPATHLEN];
 | 
			
		||||
 | 
			
		||||
	char		term[TERMINAL_LENGTH];
 | 
			
		||||
 | 
			
		||||
#ifdef __CYGWIN__
 | 
			
		||||
@@ -1316,7 +1313,7 @@ struct client {
 | 
			
		||||
#define CLIENT_EXIT 0x4
 | 
			
		||||
#define CLIENT_REDRAW 0x8
 | 
			
		||||
#define CLIENT_STATUS 0x10
 | 
			
		||||
#define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */
 | 
			
		||||
#define CLIENT_REPEAT 0x20
 | 
			
		||||
#define CLIENT_SUSPENDED 0x40
 | 
			
		||||
#define CLIENT_BAD 0x80
 | 
			
		||||
#define CLIENT_IDENTIFY 0x100
 | 
			
		||||
@@ -1919,10 +1916,10 @@ void	 server_window_loop(void);
 | 
			
		||||
/* server-fn.c */
 | 
			
		||||
void	 server_fill_environ(struct session *, struct environ *);
 | 
			
		||||
void	 server_write_ready(struct client *);
 | 
			
		||||
int	 server_write_client(
 | 
			
		||||
	     struct client *, enum msgtype, const void *, size_t);
 | 
			
		||||
void	 server_write_session(
 | 
			
		||||
	     struct session *, enum msgtype, const void *, size_t);
 | 
			
		||||
int	 server_write_client(struct client *, enum msgtype, const void *,
 | 
			
		||||
	     size_t);
 | 
			
		||||
void	 server_write_session(struct session *, enum msgtype, const void *,
 | 
			
		||||
	     size_t);
 | 
			
		||||
void	 server_redraw_client(struct client *);
 | 
			
		||||
void	 server_status_client(struct client *);
 | 
			
		||||
void	 server_redraw_session(struct session *);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user