Example #1
0
int
cmd_set_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args	*args = self->args;
	u_int		 limit;
	char		*pdata, *cause;
	size_t		 psize;
	int		 buffer;

	limit = options_get_number(&global_options, "buffer-limit");

	pdata = xstrdup(args->argv[0]);
	psize = strlen(pdata);

	if (!args_has(args, 'b')) {
		paste_add(&global_buffers, pdata, psize, limit);
		return (0);
	}

	buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
	if (cause != NULL) {
		ctx->error(ctx, "buffer %s", cause);
		xfree(cause);
		xfree(pdata);
		return (-1);
	}

	if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
		ctx->error(ctx, "no buffer %d", buffer);
		xfree(pdata);
		return (-1);
	}

	return (0);
}
Example #2
0
enum cmd_retval
cmd_delete_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args	*args = self->args;
	char		*cause;
	int		 buffer;

	if (!args_has(args, 'b')) {
		paste_free_top(&global_buffers);
		return (CMD_RETURN_NORMAL);
	}

	buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
	if (cause != NULL) {
		cmdq_error(cmdq, "buffer %s", cause);
		free(cause);
		return (CMD_RETURN_ERROR);
	}

	if (paste_free_index(&global_buffers, buffer) != 0) {
		cmdq_error(cmdq, "no buffer %d", buffer);
		return (CMD_RETURN_ERROR);
	}

	return (CMD_RETURN_NORMAL);
}
Example #3
0
int
cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct client		*c = ctx->cmdclient;
	struct paste_buffer	*pb;
	const char		*path;
	char			*cause;
	int			 buffer;
	mode_t			 mask;
	FILE			*f;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			ctx->error(ctx, "no buffers");
			return (-1);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "buffer %s", cause);
			xfree(cause);
			return (-1);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			ctx->error(ctx, "no buffer %d", buffer);
			return (-1);
		}
	}

	path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			ctx->error(ctx, "%s: can't write to stdout", path);
			return (-1);
		}
		bufferevent_write(c->stdout_event, pb->data, pb->size);
	} else {
		mask = umask(S_IRWXG | S_IRWXO);
		if (args_has(self->args, 'a'))
			f = fopen(path, "ab");
		else
			f = fopen(path, "wb");
		umask(mask);
		if (f == NULL) {
			ctx->error(ctx, "%s: %s", path, strerror(errno));
			return (-1);
		}
		if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
			ctx->error(ctx, "%s: fwrite error", path);
			fclose(f);
			return (-1);
		}
		fclose(f);
	}

	return (0);
}
Example #4
0
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct window_pane	*wp;
	struct session		*s;
	struct paste_buffer	*pb;
	const char		*sepstr;
	char			*cause;
	int			 buffer;
	int			 pflag;

	if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL)
		return (-1);

	if (!args_has(args, 'b'))
		buffer = -1;
	else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "buffer %s", cause);
			xfree(cause);
			return (-1);
		}
	}

	if (buffer == -1)
		pb = paste_get_top(&global_buffers);
	else {
		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			ctx->error(ctx, "no buffer %d", buffer);
			return (-1);
		}
	}

	if (pb != NULL) {
		sepstr = args_get(args, 's');
		if (sepstr == NULL) {
			if (args_has(args, 'r'))
				sepstr = "\n";
			else
				sepstr = "\r";
		}
		pflag = args_has(args, 'p') &&
		    (wp->screen->mode & MODE_BRACKETPASTE);
		cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr, pflag);
	}

	/* Delete the buffer if -d. */
	if (args_has(args, 'd')) {
		if (buffer == -1)
			paste_free_top(&global_buffers);
		else
			paste_free_index(&global_buffers, buffer);
	}

	return (0);
}
enum cmd_retval
cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct window_pane	*wp;
	struct session		*s;
	struct paste_buffer	*pb;
	const char		*sepstr;
	char			*cause;
	int			 buffer;
	int			 pflag;

	if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
		return (CMD_RETURN_ERROR);

	if (!args_has(args, 'b'))
		buffer = -1;
	else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	}

	if (buffer == -1)
		pb = paste_get_top(&global_buffers);
	else {
		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	}

	if (pb != NULL) {
		sepstr = args_get(args, 's');
		if (sepstr == NULL) {
			if (args_has(args, 'r'))
				sepstr = "\n";
			else
				sepstr = "\r";
		}
		pflag = (wp->screen->mode & MODE_BRACKETPASTE);
		paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag);
	}

	/* Delete the buffer if -d. */
	if (args_has(args, 'd')) {
		if (buffer == -1)
			paste_free_top(&global_buffers);
		else
			paste_free_index(&global_buffers, buffer);
	}

	return (CMD_RETURN_NORMAL);
}
Example #6
0
enum cmd_retval
cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c;
	struct window_pane	*wp;
	char			*buf, *cause;
	int			 buffer;
	u_int			 limit;
	size_t			 len;

	if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
		return (CMD_RETURN_ERROR);

	len = 0;
	if (args_has(args, 'P'))
		buf = cmd_capture_pane_pending(args, wp, &len);
	else
		buf = cmd_capture_pane_history(args, cmdq, wp, &len);
	if (buf == NULL)
		return (CMD_RETURN_ERROR);

	if (args_has(args, 'p')) {
		c = cmdq->client;
		if (c == NULL ||
		    (c->session != NULL && !(c->flags & CLIENT_CONTROL))) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		evbuffer_add(c->stdout_data, buf, len);
		if (args_has(args, 'P') && len > 0)
		    evbuffer_add(c->stdout_data, "\n", 1);
		server_push_stdout(c);
	} else {
		limit = options_get_number(&global_options, "buffer-limit");
		if (!args_has(args, 'b')) {
			paste_add(buf, len, limit);
			return (CMD_RETURN_NORMAL);
		}

		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(buf);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		if (paste_replace(buffer, buf, len) != 0) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			free(buf);
			return (CMD_RETURN_ERROR);
		}
	}

	return (CMD_RETURN_NORMAL);
}
Example #7
0
enum cmd_retval
cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct paste_buffer	*pb;
	u_int			 limit;
	char			*pdata, *cause;
	size_t			 psize, newsize;
	int			 buffer;

	limit = options_get_number(&global_options, "buffer-limit");

	psize = 0;
	pdata = NULL;

	pb = NULL;
	buffer = -1;

	if (args_has(args, 'b')) {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'a')) {
		pb = paste_get_top(&global_buffers);
		if (pb != NULL)
			buffer = 0;
	}

	if (args_has(args, 'a') && pb != NULL) {
		psize = pb->size;
		pdata = xmalloc(psize);
		memcpy(pdata, pb->data, psize);
	}

	newsize = strlen(args->argv[0]);

	pdata = xrealloc(pdata, 1, psize + newsize);
	memcpy(pdata + psize, args->argv[0], newsize);
	psize += newsize;

	if (buffer == -1)
		paste_add(&global_buffers, pdata, psize, limit);
	else
		paste_replace(&global_buffers, buffer, pdata, psize);

	return (CMD_RETURN_NORMAL);
}
Example #8
0
enum cmd_retval
cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct session		*s;
	struct winlink		*wl;
	struct window		*w;
	struct window_pane	*wp, *new_wp = NULL;
	struct environ		 env;
	const char		*cmd, *cwd, *shell;
	char			*cause, *new_cause;
	u_int			 hlimit;
	int			 size, percentage;
	enum layout_type	 type;
	struct layout_cell	*lc;
	const char		*template;
	struct client		*c;
	struct format_tree	*ft;
	char			*cp;

	if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
		return (CMD_RETURN_ERROR);
	w = wl->window;

	environ_init(&env);
	environ_copy(&global_environ, &env);
	environ_copy(&s->environ, &env);
	server_fill_environ(s, &env);

	if (args->argc == 0)
		cmd = options_get_string(&s->options, "default-command");
	else
		cmd = args->argv[0];
	cwd = cmd_get_default_path(ctx, args_get(args, 'c'));

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			xasprintf(&new_cause, "size %s", cause);
			free(cause);
			cause = new_cause;
			goto error;
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
		if (cause != NULL) {
			xasprintf(&new_cause, "percentage %s", cause);
			free(cause);
			cause = new_cause;
			goto error;
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (wp->sy * percentage) / 100;
		else
			size = (wp->sx * percentage) / 100;
	}
	hlimit = options_get_number(&s->options, "history-limit");

	shell = options_get_string(&s->options, "default-shell");
	if (*shell == '\0' || areshell(shell))
		shell = _PATH_BSHELL;

	if ((lc = layout_split_pane(wp, type, size, 0)) == NULL) {
		cause = xstrdup("pane too small");
		goto error;
	}
	new_wp = window_add_pane(w, hlimit);
	if (window_pane_spawn(
	    new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
		goto error;
	layout_assign_pane(lc, new_wp);

	server_redraw_window(w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(w, new_wp);
		session_select(s, wl->idx);
		server_redraw_session(s);
	} else
		server_status_session(s);

	environ_free(&env);

	if (args_has(args, 'P')) {
		if ((template = args_get(args, 'F')) == NULL)
Example #9
0
static char *
cmd_capture_pane_history(struct args *args, struct cmd_q *cmdq,
    struct window_pane *wp, size_t *len)
{
	struct grid		*gd;
	const struct grid_line	*gl;
	struct grid_cell	*gc = NULL;
	int			 n, with_codes, escape_c0, join_lines;
	u_int			 i, sx, top, bottom, tmp;
	char			*cause, *buf, *line;
	const char		*Sflag, *Eflag;
	size_t			 linelen;

	sx = screen_size_x(&wp->base);
	if (args_has(args, 'a')) {
		gd = wp->saved_grid;
		if (gd == NULL) {
			if (!args_has(args, 'q')) {
				cmdq_error(cmdq, "no alternate screen");
				return (NULL);
			}
			return (xstrdup(""));
		}
	} else
		gd = wp->base.grid;

	Sflag = args_get(args, 'S');
	if (Sflag != NULL && strcmp(Sflag, "-") == 0)
		top = 0;
	else {
		n = args_strtonum(args, 'S', INT_MIN, SHRT_MAX, &cause);
		if (cause != NULL) {
			top = gd->hsize;
			free(cause);
		} else if (n < 0 && (u_int) -n > gd->hsize)
			top = 0;
		else
			top = gd->hsize + n;
		if (top > gd->hsize + gd->sy - 1)
			top = gd->hsize + gd->sy - 1;
	}

	Eflag = args_get(args, 'E');
	if (Eflag != NULL && strcmp(Eflag, "-") == 0)
		bottom = gd->hsize + gd->sy - 1;
	else {
		n = args_strtonum(args, 'E', INT_MIN, SHRT_MAX, &cause);
		if (cause != NULL) {
			bottom = gd->hsize + gd->sy - 1;
			free(cause);
		} else if (n < 0 && (u_int) -n > gd->hsize)
			bottom = 0;
		else
			bottom = gd->hsize + n;
		if (bottom > gd->hsize + gd->sy - 1)
			bottom = gd->hsize + gd->sy - 1;
	}

	if (bottom < top) {
		tmp = bottom;
		bottom = top;
		top = tmp;
	}

	with_codes = args_has(args, 'e');
	escape_c0 = args_has(args, 'C');
	join_lines = args_has(args, 'J');

	buf = NULL;
	for (i = top; i <= bottom; i++) {
		line = grid_string_cells(gd, 0, i, sx, &gc, with_codes,
		    escape_c0, !join_lines);
		linelen = strlen(line);

		buf = cmd_capture_pane_append(buf, len, line, linelen);

		gl = grid_peek_line(gd, i);
		if (!join_lines || !(gl->flags & GRID_LINE_WRAPPED))
			buf[(*len)++] = '\n';

		free(line);
	}
	return (buf);
}
Example #10
0
int
cmd_join_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;

	dst_wl = cmd_find_pane(ctx, args_get(args, 't'), &dst_s, &dst_wp);
	if (dst_wl == NULL)
		return (-1);
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;

	src_wl = cmd_find_pane(ctx, args_get(args, 's'), NULL, &src_wp);
	if (src_wl == NULL)
		return (-1);
	src_w = src_wl->window;

	if (src_w == dst_w) {
		ctx->error(ctx, "can't join a pane to its own window");
		return (-1);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "size %s", cause);
			xfree(cause);
			return (-1);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "percentage %s", cause);
			xfree(cause);
			return (-1);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}

	if ((lc = layout_split_pane(dst_wp, type, size)) == NULL) {
		ctx->error(ctx, "create pane failed: pane too small");
		return (-1);
	}

	layout_close_pane(src_wp);

	if (src_w->active == src_wp) {
		src_w->active = TAILQ_PREV(src_wp, window_panes, entry);
		if (src_w->active == NULL)
			src_w->active = TAILQ_NEXT(src_wp, entry);
	}
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(dst_w, src_wp);
		session_select(dst_s, dst_idx);
		server_redraw_session(dst_s);
	} else
		server_status_session(dst_s);

	return (0);
}
Example #11
0
int
cmd_load_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args	*args = self->args;
	struct client	*c = ctx->cmdclient;
	FILE		*f;
	const char	*path;
	char		*pdata, *new_pdata, *cause;
	size_t		 psize;
	u_int		 limit;
	int		 ch, buffer;
	int		*buffer_ptr;

	if (!args_has(args, 'b'))
		buffer = -1;
	else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "buffer %s", cause);
			xfree(cause);
			return (-1);
		}
	}

	path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			ctx->error(ctx, "%s: can't read from stdin", path);
			return (-1);
		}
		if (c->flags & CLIENT_TERMINAL) {
			ctx->error(ctx, "%s: stdin is a tty", path);
			return (-1);
		}
		if (c->stdin_fd == -1) {
			ctx->error(ctx, "%s: can't read from stdin", path);
			return (-1);
		}

		buffer_ptr = xmalloc(sizeof *buffer_ptr);
		*buffer_ptr = buffer;

		c->stdin_data = buffer_ptr;
		c->stdin_callback = cmd_load_buffer_callback;

		c->references++;
		bufferevent_enable(c->stdin_event, EV_READ);
		return (1);
	}

	if ((f = fopen(path, "rb")) == NULL) {
		ctx->error(ctx, "%s: %s", path, strerror(errno));
		return (-1);
	}

	pdata = NULL;
	psize = 0;
	while ((ch = getc(f)) != EOF) {
		/* Do not let the server die due to memory exhaustion. */
		if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
			ctx->error(ctx, "realloc error: %s", strerror(errno));
			goto error;
		}
		pdata = new_pdata;
		pdata[psize++] = ch;
	}
	if (ferror(f)) {
		ctx->error(ctx, "%s: read error", path);
		goto error;
	}
	if (pdata != NULL)
		pdata[psize] = '\0';

	fclose(f);

	limit = options_get_number(&global_options, "buffer-limit");
	if (buffer == -1) {
		paste_add(&global_buffers, pdata, psize, limit);
		return (0);
	}
	if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
		ctx->error(ctx, "no buffer %d", buffer);
		return (-1);
	}

	return (0);

error:
	if (pdata != NULL)
		xfree(pdata);
	if (f != NULL)
		fclose(f);
	return (-1);
}
enum cmd_retval
cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args	*args = self->args;
	struct client	*c = cmdq->client;
	struct session  *s;
	FILE		*f;
	const char	*path;
	char		*pdata, *new_pdata, *cause;
	size_t		 psize;
	u_int		 limit;
	int		 ch, error, buffer, *buffer_ptr, cwd, fd;

	if (!args_has(args, 'b'))
		buffer = -1;
	else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	}

	path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		buffer_ptr = xmalloc(sizeof *buffer_ptr);
		*buffer_ptr = buffer;

		error = server_set_stdin_callback(c, cmd_load_buffer_callback,
		    buffer_ptr, &cause);
		if (error != 0) {
			cmdq_error(cmdq, "%s: %s", path, cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		return (CMD_RETURN_WAIT);
	}

	if (c != NULL && c->session == NULL)
		cwd = c->cwd;
	else if ((s = cmd_current_session(cmdq, 0)) != NULL)
		cwd = s->cwd;
	else
		cwd = AT_FDCWD;

	if ((fd = openat(cwd, path, O_RDONLY)) == -1 ||
	    (f = fdopen(fd, "rb")) == NULL) {
		if (fd != -1)
			close(fd);
		cmdq_error(cmdq, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}

	pdata = NULL;
	psize = 0;
	while ((ch = getc(f)) != EOF) {
		/* Do not let the server die due to memory exhaustion. */
		if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
			cmdq_error(cmdq, "realloc error: %s", strerror(errno));
			goto error;
		}
		pdata = new_pdata;
		pdata[psize++] = ch;
	}
	if (ferror(f)) {
		cmdq_error(cmdq, "%s: read error", path);
		goto error;
	}
	if (pdata != NULL)
		pdata[psize] = '\0';

	fclose(f);

	limit = options_get_number(&global_options, "buffer-limit");
	if (buffer == -1) {
		paste_add(&global_buffers, pdata, psize, limit);
		return (CMD_RETURN_NORMAL);
	}
	if (paste_replace(&global_buffers, buffer, pdata, psize) != 0) {
		cmdq_error(cmdq, "no buffer %d", buffer);
		free(pdata);
		return (CMD_RETURN_ERROR);
	}

	return (CMD_RETURN_NORMAL);

error:
	free(pdata);
	if (f != NULL)
		fclose(f);
	return (CMD_RETURN_ERROR);
}
Example #13
0
enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path, *newpath, *wd;
	char			*cause, *start, *end;
	size_t			 size, used;
	int			 buffer;
	mode_t			 mask;
	FILE			*f;
	char			*msg;
	size_t			 msglen;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			cmdq_error(cmdq, "no buffers");
			return (CMD_RETURN_ERROR);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	}

	if (self->entry == &cmd_show_buffer_entry)
		path = "-";
	else
		path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		c = cmdq->client;
		if (c == NULL) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
			goto do_stdout;
		goto do_print;
	}

	c = cmdq->client;
	if (c != NULL)
		wd = c->cwd;
	else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
		wd = options_get_string(&s->options, "default-path");
		if (*wd == '\0')
			wd = s->cwd;
	} else
		wd = NULL;
	if (wd != NULL && *wd != '\0') {
		newpath = get_full_path(wd, path);
		if (newpath != NULL)
			path = newpath;
	}

	mask = umask(S_IRWXG | S_IRWXO);
	if (args_has(self->args, 'a'))
		f = fopen(path, "ab");
	else
		f = fopen(path, "wb");
	umask(mask);
	if (f == NULL) {
		cmdq_error(cmdq, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}
	if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
		cmdq_error(cmdq, "%s: fwrite error", path);
		fclose(f);
		return (CMD_RETURN_ERROR);
	}
	fclose(f);

	return (CMD_RETURN_NORMAL);

do_stdout:
	evbuffer_add(c->stdout_data, pb->data, pb->size);
	server_push_stdout(c);
	return (CMD_RETURN_NORMAL);

do_print:
	if (pb->size > (INT_MAX / 4) - 1) {
		cmdq_error(cmdq, "buffer too big");
		return (CMD_RETURN_ERROR);
	}
	msg = NULL;
	msglen = 0;

	used = 0;
	while (used != pb->size) {
		start = pb->data + used;
		end = memchr(start, '\n', pb->size - used);
		if (end != NULL)
			size = end - start;
		else
			size = pb->size - used;

		msglen = size * 4 + 1;
		msg = xrealloc(msg, 1, msglen);

		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
		cmdq_print(cmdq, "%s", msg);

		used += size + (end != NULL);
	}

	free(msg);
	return (CMD_RETURN_NORMAL);
}
enum cmd_retval
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct winlink		*wl;
	struct window		*w;
	const char	       	*errstr;
	char			*cause;
	struct window_pane	*wp;
	u_int			 adjust;
	int			 x, y;

	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
		return (CMD_RETURN_ERROR);
	w = wl->window;

	if (args_has(args, 'Z')) {
		if (w->flags & WINDOW_ZOOMED)
			window_unzoom(w);
		else
			window_zoom(wp);
		server_redraw_window(w);
		server_status_window(w);
		return (CMD_RETURN_NORMAL);
	}
	server_unzoom_window(w);

	if (args->argc == 0)
		adjust = 1;
	else {
		adjust = strtonum(args->argv[0], 1, INT_MAX, &errstr);
		if (errstr != NULL) {
			cmdq_error(cmdq, "adjustment %s", errstr);
			return (CMD_RETURN_ERROR);
		}
	}

	if (args_has(self->args, 'x')) {
		x = args_strtonum(self->args, 'x', PANE_MINIMUM, INT_MAX,
		    &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "width %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		layout_resize_pane_to(wp, LAYOUT_LEFTRIGHT, x);
	}
	if (args_has(self->args, 'y')) {
		y = args_strtonum(self->args, 'y', PANE_MINIMUM, INT_MAX,
		    &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "height %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		layout_resize_pane_to(wp, LAYOUT_TOPBOTTOM, y);
	}

	if (args_has(self->args, 'L'))
		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust);
	else if (args_has(self->args, 'R'))
		layout_resize_pane(wp, LAYOUT_LEFTRIGHT, adjust);
	else if (args_has(self->args, 'U'))
		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, -adjust);
	else if (args_has(self->args, 'D'))
		layout_resize_pane(wp, LAYOUT_TOPBOTTOM, adjust);
	server_redraw_window(wl->window);

	return (CMD_RETURN_NORMAL);
}
Example #15
0
enum cmd_retval
join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
{
	struct args		*args = self->args;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;

	dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp);
	if (dst_wl == NULL)
		return (CMD_RETURN_ERROR);
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;
	server_unzoom_window(dst_w);

	src_wl = cmd_find_pane(cmdq, args_get(args, 's'), NULL, &src_wp);
	if (src_wl == NULL)
		return (CMD_RETURN_ERROR);
	src_w = src_wl->window;
	server_unzoom_window(src_w);

	if (not_same_window && src_w == dst_w) {
		cmdq_error(cmdq, "can't join a pane to its own window");
		return (CMD_RETURN_ERROR);
	}
	if (!not_same_window && src_wp == dst_wp) {
		cmdq_error(cmdq, "source and target panes must be different");
		return (CMD_RETURN_ERROR);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "size %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "percentage %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}
	lc = layout_split_pane(dst_wp, type, size, args_has(args, 'b'));
	if (lc == NULL) {
		cmdq_error(cmdq, "create pane failed: pane too small");
		return (CMD_RETURN_ERROR);
	}

	layout_close_pane(src_wp);

	window_lost_pane(src_w, src_wp);
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);
	else
		notify_window_layout_changed(src_w);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(dst_w, src_wp);
		session_select(dst_s, dst_idx);
		server_redraw_session(dst_s);
	} else
		server_status_session(dst_s);

	notify_window_layout_changed(dst_w);
	return (CMD_RETURN_NORMAL);
}
Example #16
0
enum cmd_retval
cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct session		*s;
	struct winlink		*wl;
	struct window		*w;
	struct window_pane	*wp, *new_wp = NULL;
	struct environ		 env;
	const char		*cmd, *shell, *template;
	char			*cause, *new_cause, *cp;
	u_int			 hlimit;
	int			 size, percentage, cwd, fd = -1;
	enum layout_type	 type;
	struct layout_cell	*lc;
	struct client		*c;
	struct format_tree	*ft;

	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
		return (CMD_RETURN_ERROR);
	w = wl->window;
	server_unzoom_window(w);

	environ_init(&env);
	environ_copy(&global_environ, &env);
	environ_copy(&s->environ, &env);
	server_fill_environ(s, &env);

	if (args->argc == 0)
		cmd = options_get_string(&s->options, "default-command");
	else
		cmd = args->argv[0];

	if (args_has(args, 'c')) {
		ft = format_create();
		if ((c = cmd_find_client(cmdq, NULL, 1)) != NULL)
			format_client(ft, c);
		format_session(ft, s);
		format_winlink(ft, s, s->curw);
		format_window_pane(ft, s->curw->window->active);
		cp = format_expand(ft, args_get(args, 'c'));
		format_free(ft);

		fd = open(cp, O_RDONLY|O_DIRECTORY);
		free(cp);
		if (fd == -1) {
			cmdq_error(cmdq, "bad working directory: %s",
			    strerror(errno));
			return (CMD_RETURN_ERROR);
		}
		cwd = fd;
	} else if (cmdq->client != NULL && cmdq->client->session == NULL)
		cwd = cmdq->client->cwd;
	else
		cwd = s->cwd;

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			xasprintf(&new_cause, "size %s", cause);
			free(cause);
			cause = new_cause;
			goto error;
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
		if (cause != NULL) {
			xasprintf(&new_cause, "percentage %s", cause);
			free(cause);
			cause = new_cause;
			goto error;
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (wp->sy * percentage) / 100;
		else
			size = (wp->sx * percentage) / 100;
	}
	hlimit = options_get_number(&s->options, "history-limit");

	shell = options_get_string(&s->options, "default-shell");
	if (*shell == '\0' || areshell(shell))
		shell = _PATH_BSHELL;

	if ((lc = layout_split_pane(wp, type, size, 0)) == NULL) {
		cause = xstrdup("pane too small");
		goto error;
	}
	new_wp = window_add_pane(w, hlimit);
	if (window_pane_spawn(
	    new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
		goto error;
	layout_assign_pane(lc, new_wp);

	server_redraw_window(w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(w, new_wp);
		session_select(s, wl->idx);
		server_redraw_session(s);
	} else
		server_status_session(s);

	environ_free(&env);

	if (args_has(args, 'P')) {
		if ((template = args_get(args, 'F')) == NULL)
Example #17
0
int
cmd_split_window_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct session		*s;
	struct winlink		*wl;
	struct window		*w;
	struct window_pane	*wp, *new_wp = NULL;
	struct environ		 env;
	char		 	*cmd, *cwd, *cause;
	const char		*shell;
	u_int			 hlimit, paneidx;
	int			 size, percentage;
	enum layout_type	 type;
	struct layout_cell	*lc;

	if ((wl = cmd_find_pane(ctx, args_get(args, 't'), &s, &wp)) == NULL)
		return (-1);
	w = wl->window;

	environ_init(&env);
	environ_copy(&global_environ, &env);
	environ_copy(&s->environ, &env);
	server_fill_environ(s, &env);

	if (args->argc == 0)
		cmd = options_get_string(&s->options, "default-command");
	else
		cmd = args->argv[0];
	cwd = options_get_string(&s->options, "default-path");
	if (*cwd == '\0') {
		if (ctx->cmdclient != NULL && ctx->cmdclient->cwd != NULL)
			cwd = ctx->cmdclient->cwd;
		else
			cwd = s->cwd;
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 's')) {
		size = args_strtonum(args, 's', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "size %s", cause);
			xfree(cause);
			return (-1);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "percentage %s", cause);
			xfree(cause);
			return (-1);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (wp->sy * percentage) / 100;
		else
			size = (wp->sx * percentage) / 100;
	}
	hlimit = options_get_number(&s->options, "history-limit");

	shell = options_get_string(&s->options, "default-shell");
	if (*shell == '\0' || areshell(shell))
		shell = _PATH_BSHELL;

	if ((lc = layout_split_pane(wp, type, size)) == NULL) {
		cause = xstrdup("pane too small");
		goto error;
	}
	new_wp = window_add_pane(w, hlimit);
	if (window_pane_spawn(
	    new_wp, cmd, shell, cwd, &env, s->tio, &cause) != 0)
		goto error;
	layout_assign_pane(lc, new_wp);

	server_redraw_window(w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(w, new_wp);
		session_select(s, wl->idx);
		server_redraw_session(s);
	} else
		server_status_session(s);

	environ_free(&env);

	if (args_has(args, 'P')) {
		paneidx = window_pane_index(wl->window, new_wp);
		ctx->print(ctx, "%s:%u.%u", s->name, wl->idx, paneidx);
	}
	return (0);

error:
	environ_free(&env);
	if (new_wp != NULL)
		window_remove_pane(w, new_wp);
	ctx->error(ctx, "create pane failed: %s", cause);
	xfree(cause);
	return (-1);
}
Example #18
0
int
cmd_capture_pane_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct window_pane	*wp;
	char 			*buf, *line, *cause;
	struct screen		*s;
	struct grid		*gd;
	int			 buffer, n;
	u_int			 i, limit, top, bottom, tmp;
	size_t         		 len, linelen;

	if (cmd_find_pane(ctx, args_get(args, 't'), NULL, &wp) == NULL)
		return (-1);
	s = &wp->base;
	gd = s->grid;

	buf = NULL;
	len = 0;

	n = args_strtonum(args, 'S', SHRT_MIN, SHRT_MAX, &cause);
	if (cause != NULL) {
		top = gd->hsize;
		xfree(cause);
	} else if (n < 0 && (u_int) -n > gd->hsize)
		top = 0;
	else
		top = gd->hsize + n;
	if (top > gd->hsize + gd->sy - 1)
		top = gd->hsize + gd->sy - 1;

	n = args_strtonum(args, 'E', SHRT_MIN, SHRT_MAX, &cause);
	if (cause != NULL) {
		bottom = gd->hsize + gd->sy - 1;
		xfree(cause);
	} else if (n < 0 && (u_int) -n > gd->hsize)
		bottom = 0;
	else
		bottom = gd->hsize + n;
	if (bottom > gd->hsize + gd->sy - 1)
		bottom = gd->hsize + gd->sy - 1;

	if (bottom < top) {
		tmp = bottom;
		bottom = top;
		top = tmp;
	}

	for (i = top; i <= bottom; i++) {
	       line = grid_string_cells(s->grid, 0, i, screen_size_x(s));
	       linelen = strlen(line);

	       buf = xrealloc(buf, 1, len + linelen + 1);
	       memcpy(buf + len, line, linelen);
	       len += linelen;
	       buf[len++] = '\n';

	       xfree(line);
	}

	limit = options_get_number(&global_options, "buffer-limit");

	if (!args_has(args, 'b')) {
		paste_add(&global_buffers, buf, len, limit);
		return (0);
	}

	buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
	if (cause != NULL) {
		ctx->error(ctx, "buffer %s", cause);
		xfree(cause);
		return (-1);
	}

	if (paste_replace(&global_buffers, buffer, buf, len) != 0) {
		ctx->error(ctx, "no buffer %d", buffer);
		xfree(buf);
		return (-1);
	}

	return (0);
}
Example #19
0
int
cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct client		*c = ctx->cmdclient;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path, *newpath, *wd;
	char			*cause;
	int			 buffer;
	mode_t			 mask;
	FILE			*f;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			ctx->error(ctx, "no buffers");
			return (-1);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "buffer %s", cause);
			xfree(cause);
			return (-1);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			ctx->error(ctx, "no buffer %d", buffer);
			return (-1);
		}
	}

	path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			ctx->error(ctx, "%s: can't write to stdout", path);
			return (-1);
		}
		evbuffer_add(c->stdout_data, pb->data, pb->size);
		server_push_stdout(c);
	} else {
		if (c != NULL)
			wd = c->cwd;
		else if ((s = cmd_current_session(ctx, 0)) != NULL) {
			wd = options_get_string(&s->options, "default-path");
			if (*wd == '\0')
				wd = s->cwd;
		} else
			wd = NULL;
		if (wd != NULL && *wd != '\0') {
			newpath = get_full_path(wd, path);
			if (newpath != NULL)
				path = newpath;
		}

		mask = umask(S_IRWXG | S_IRWXO);
		if (args_has(self->args, 'a'))
			f = fopen(path, "ab");
		else
			f = fopen(path, "wb");
		umask(mask);
		if (f == NULL) {
			ctx->error(ctx, "%s: %s", path, strerror(errno));
			return (-1);
		}
		if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
			ctx->error(ctx, "%s: fwrite error", path);
			fclose(f);
			return (-1);
		}
		fclose(f);
	}

	return (0);
}
Example #20
0
enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c = cmdq->client;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path;
	char			*cause, *start, *end, *msg;
	size_t			 size, used, msglen;
	int			 cwd, fd, buffer;
	FILE			*f;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			cmdq_error(cmdq, "no buffers");
			return (CMD_RETURN_ERROR);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	}

	if (self->entry == &cmd_show_buffer_entry)
		path = "-";
	else
		path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
			goto do_stdout;
		goto do_print;
	}

	if (c != NULL && c->session == NULL)
		cwd = c->cwd;
	else if ((s = cmd_current_session(cmdq, 0)) != NULL)
		cwd = s->cwd;
	else
		cwd = AT_FDCWD;

	f = NULL;
	if (args_has(self->args, 'a')) {
		fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
		if (fd != -1)
			f = fdopen(fd, "ab");
	} else {
		fd = openat(cwd, path, O_CREAT|O_RDWR, 0600);
		if (fd != -1)
			f = fdopen(fd, "wb");
	}
	if (f == NULL) {
		if (fd != -1)
			close(fd);
		cmdq_error(cmdq, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}
	if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
		cmdq_error(cmdq, "%s: fwrite error", path);
		fclose(f);
		return (CMD_RETURN_ERROR);
	}
	fclose(f);

	return (CMD_RETURN_NORMAL);

do_stdout:
	evbuffer_add(c->stdout_data, pb->data, pb->size);
	server_push_stdout(c);
	return (CMD_RETURN_NORMAL);

do_print:
	if (pb->size > (INT_MAX / 4) - 1) {
		cmdq_error(cmdq, "buffer too big");
		return (CMD_RETURN_ERROR);
	}
	msg = NULL;
	msglen = 0;

	used = 0;
	while (used != pb->size) {
		start = pb->data + used;
		end = memchr(start, '\n', pb->size - used);
		if (end != NULL)
			size = end - start;
		else
			size = pb->size - used;

		msglen = size * 4 + 1;
		msg = xrealloc(msg, 1, msglen);

		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
		cmdq_print(cmdq, "%s", msg);

		used += size + (end != NULL);
	}

	free(msg);
	return (CMD_RETURN_NORMAL);
}
Example #21
0
int
cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct args		*args = self->args;
	struct session		*s;
	struct paste_buffer	*pb;
	int			 buffer;
	char			*in, *buf, *ptr, *cause;
	size_t			 size, len;
	u_int			 width;

	if ((s = cmd_find_session(ctx, NULL, 0)) == NULL)
		return (-1);

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			ctx->error(ctx, "no buffers");
			return (-1);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			ctx->error(ctx, "buffer %s", cause);
			xfree(cause);
			return (-1);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			ctx->error(ctx, "no buffer %d", buffer);
			return (-1);
		}
	}

	size = pb->size;
	if (size > SIZE_MAX / 4 - 1)
		size = SIZE_MAX / 4 - 1;
	in = xmalloc(size * 4 + 1);
	strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB);

	width = s->sx;
	if (ctx->cmdclient != NULL)
		width = ctx->cmdclient->tty.sx;

	buf = xmalloc(width + 1);
	len = 0;

	ptr = in;
	do {
		buf[len++] = *ptr++;

		if (len == width || buf[len - 1] == '\n') {
			if (buf[len - 1] == '\n')
				len--;
			buf[len] = '\0';

			ctx->print(ctx, "%s", buf);
			len = 0;
		}
	} while (*ptr != '\0');

	if (len != 0) {
		buf[len] = '\0';
		ctx->print(ctx, "%s", buf);
	}
	xfree(buf);

	xfree(in);

	return (0);
}
Example #22
0
static enum cmd_retval
cmd_join_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct cmd_find_state	*current = &item->shared->current;
	struct session		*dst_s;
	struct winlink		*src_wl, *dst_wl;
	struct window		*src_w, *dst_w;
	struct window_pane	*src_wp, *dst_wp;
	char			*cause;
	int			 size, percentage, dst_idx;
	enum layout_type	 type;
	struct layout_cell	*lc;
	int			 not_same_window, flags;

	if (self->entry == &cmd_join_pane_entry)
		not_same_window = 1;
	else
		not_same_window = 0;

	dst_s = item->target.s;
	dst_wl = item->target.wl;
	dst_wp = item->target.wp;
	dst_w = dst_wl->window;
	dst_idx = dst_wl->idx;
	server_unzoom_window(dst_w);

	src_wl = item->source.wl;
	src_wp = item->source.wp;
	src_w = src_wl->window;
	server_unzoom_window(src_w);

	if (not_same_window && src_w == dst_w) {
		cmdq_error(item, "can't join a pane to its own window");
		return (CMD_RETURN_ERROR);
	}
	if (!not_same_window && src_wp == dst_wp) {
		cmdq_error(item, "source and target panes must be different");
		return (CMD_RETURN_ERROR);
	}

	type = LAYOUT_TOPBOTTOM;
	if (args_has(args, 'h'))
		type = LAYOUT_LEFTRIGHT;

	size = -1;
	if (args_has(args, 'l')) {
		size = args_strtonum(args, 'l', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(item, "size %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
	} else if (args_has(args, 'p')) {
		percentage = args_strtonum(args, 'p', 0, 100, &cause);
		if (cause != NULL) {
			cmdq_error(item, "percentage %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}
		if (type == LAYOUT_TOPBOTTOM)
			size = (dst_wp->sy * percentage) / 100;
		else
			size = (dst_wp->sx * percentage) / 100;
	}
	if (args_has(args, 'b'))
		flags = SPAWN_BEFORE;
	else
		flags = 0;
	lc = layout_split_pane(dst_wp, type, size, flags);
	if (lc == NULL) {
		cmdq_error(item, "create pane failed: pane too small");
		return (CMD_RETURN_ERROR);
	}

	layout_close_pane(src_wp);

	window_lost_pane(src_w, src_wp);
	TAILQ_REMOVE(&src_w->panes, src_wp, entry);

	src_wp->window = dst_w;
	TAILQ_INSERT_AFTER(&dst_w->panes, dst_wp, src_wp, entry);
	layout_assign_pane(lc, src_wp);

	recalculate_sizes();

	server_redraw_window(src_w);
	server_redraw_window(dst_w);

	if (!args_has(args, 'd')) {
		window_set_active_pane(dst_w, src_wp, 1);
		session_select(dst_s, dst_idx);
		cmd_find_from_session(current, dst_s, 0);
		server_redraw_session(dst_s);
	} else
		server_status_session(dst_s);

	if (window_count_panes(src_w) == 0)
		server_kill_window(src_w);
	else
		notify_window("window-layout-changed", src_w);
	notify_window("window-layout-changed", dst_w);

	return (CMD_RETURN_NORMAL);
}