예제 #1
0
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_paste_buffer_data	*data = self->data;
	struct window_pane		*wp;
	struct session			*s;
	struct paste_buffer		*pb;

	if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL)
		return (-1);

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

	if (pb != NULL)
		cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr);

	/* Delete the buffer if -d. */
	if (data->flag_delete) {
		if (data->buffer == -1)
			paste_free_top(&s->buffers);
		else
			paste_free_index(&s->buffers, data->buffer);
	}

	return (0);
}
예제 #2
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);
}
예제 #3
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);
}
예제 #5
0
파일: paste.c 프로젝트: taksatou/tmux
/* Return each item of the stack in turn. */
struct paste_buffer *
paste_walk_stack(struct paste_stack *ps, u_int *idx)
{
	struct paste_buffer	*pb;

	pb = paste_get_index(ps, *idx);
	(*idx)++;
	return (pb);
}
예제 #6
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);
}
예제 #7
0
int
cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_buffer_data	*data = self->data;
	struct session		*s;
	struct paste_buffer	*pb;
	mode_t			mask;
	FILE			*f;

	if ((s = cmd_find_session(ctx, data->target)) == NULL)
		return (-1);

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

	mask = umask(S_IRWXG | S_IRWXO);
	if (data->chflags & CMD_CHFLAG('a'))
		f = fopen(data->arg, "ab");
	else
		f = fopen(data->arg, "wb");
	umask(mask);
	if (f == NULL) {
		ctx->error(ctx, "%s: %s", data->arg, strerror(errno));
		return (-1);
	}

	if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
	    	ctx->error(ctx, "%s: fwrite error", data->arg);
	    	fclose(f);
	    	return (-1);
	}

	fclose(f);

	return (0);
}
예제 #8
0
int
cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
    struct cmd_copy_buffer_data	*data = self->data;
    struct paste_buffer		*pb;
    struct paste_stack		*dst_ps, *src_ps;
    u_char				*pdata;
    struct session			*dst_session, *src_session;
    u_int				 limit;

    if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
            (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
        return (-1);
    dst_ps = &dst_session->buffers;
    src_ps = &src_session->buffers;

    if (data->src_idx == -1) {
        if ((pb = paste_get_top(src_ps)) == NULL) {
            ctx->error(ctx, "no buffers");
            return (-1);
        }
    } else {
        if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) {
            ctx->error(ctx, "no buffer %d", data->src_idx);
            return (-1);
        }
    }
    limit = options_get_number(&dst_session->options, "buffer-limit");

    pdata = xmalloc(pb->size);
    memcpy(pdata, pb->data, pb->size);

    if (data->dst_idx == -1)
        paste_add(dst_ps, pdata, pb->size, limit);
    else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
        ctx->error(ctx, "no buffer %d", data->dst_idx);
        xfree(pdata);
        return (-1);
    }

    return (0);
}
예제 #9
0
int
cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_buffer_data	*data = self->data;
	struct winlink		*wl;
	struct window_pane	*wp;
	struct session		*s;
	struct paste_buffer	*pb;

	if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL)
		return (-1);
	wp = wl->window->active;

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

	if (pb != NULL) {
		/* -r means raw data without LF->CR conversion. */
		if (cmd_check_flag(data->chflags, 'r'))
			bufferevent_write(wp->event, pb->data, pb->size);
		else
			cmd_paste_buffer_lf2cr(wp, pb->data, pb->size);
	}

	/* Delete the buffer if -d. */
	if (cmd_check_flag(data->chflags, 'd')) {
		if (data->buffer == -1)
			paste_free_top(&s->buffers);
		else
			paste_free_index(&s->buffers, data->buffer);
	}

	return (0);
}
예제 #10
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);
}
예제 #11
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);
}
예제 #12
0
int
cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_buffer_data	*data = self->data;
	struct session		*s;
	struct paste_buffer	*pb;
	char			*in, *buf, *ptr;
	size_t			 size, len;
	u_int			 width;

	if ((s = cmd_find_session(ctx, data->target)) == NULL)
		return (-1);

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

	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);
}
예제 #13
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);
}
예제 #14
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);
}