Return the command client return code with MSG_EXIT now that MSG_ERROR and
[tmux-openbsd.git] / cmd-copy-buffer.c
blob5f407e0c33517bfa666b79c482d9ede3cf306611
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <stdlib.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Copies a session paste buffer to another session.
30 int cmd_copy_buffer_parse(struct cmd *, int, char **, char **);
31 int cmd_copy_buffer_exec(struct cmd *, struct cmd_ctx *);
32 void cmd_copy_buffer_free(struct cmd *);
33 void cmd_copy_buffer_init(struct cmd *, int);
34 size_t cmd_copy_buffer_print(struct cmd *, char *, size_t);
36 struct cmd_copy_buffer_data {
37 char *dst_session;
38 char *src_session;
39 int dst_idx;
40 int src_idx;
43 const struct cmd_entry cmd_copy_buffer_entry = {
44 "copy-buffer", "copyb",
45 "[-a src-index] [-b dst-index] [-s src-session] [-t dst-session]",
46 0, "",
47 cmd_copy_buffer_init,
48 cmd_copy_buffer_parse,
49 cmd_copy_buffer_exec,
50 cmd_copy_buffer_free,
51 cmd_copy_buffer_print
54 /* ARGSUSED */
55 void
56 cmd_copy_buffer_init(struct cmd *self, unused int arg)
58 struct cmd_copy_buffer_data *data;
60 self->data = data = xmalloc(sizeof *data);
61 data->dst_session = NULL;
62 data->src_session = NULL;
63 data->dst_idx = -1;
64 data->src_idx = -1;
67 int
68 cmd_copy_buffer_parse(struct cmd *self, int argc, char **argv, char **cause)
70 struct cmd_copy_buffer_data *data;
71 const char *errstr;
72 int n, opt;
74 self->entry->init(self, KEYC_NONE);
75 data = self->data;
77 while ((opt = getopt(argc, argv, "a:b:s:t:")) != -1) {
78 switch (opt) {
79 case 'a':
80 if (data->src_idx == -1) {
81 n = strtonum(optarg, 0, INT_MAX, &errstr);
82 if (errstr != NULL) {
83 xasprintf(cause, "buffer %s", errstr);
84 goto error;
86 data->src_idx = n;
88 break;
89 case 'b':
90 if (data->dst_idx == -1) {
91 n = strtonum(optarg, 0, INT_MAX, &errstr);
92 if (errstr != NULL) {
93 xasprintf(cause, "buffer %s", errstr);
94 goto error;
96 data->dst_idx = n;
98 break;
99 case 's':
100 if (data->src_session == NULL)
101 data->src_session = xstrdup(optarg);
102 break;
103 case 't':
104 if (data->dst_session == NULL)
105 data->dst_session = xstrdup(optarg);
106 break;
107 default:
108 goto usage;
111 argc -= optind;
112 argv += optind;
114 return (0);
116 usage:
117 xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
119 error:
120 self->entry->free(self);
121 return (-1);
125 cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
127 struct cmd_copy_buffer_data *data = self->data;
128 struct paste_buffer *pb;
129 struct paste_stack *dst_ps, *src_ps;
130 u_char *pdata;
131 struct session *dst_session, *src_session;
132 u_int limit;
134 if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL ||
135 (src_session = cmd_find_session(ctx, data->src_session)) == NULL)
136 return (-1);
137 dst_ps = &dst_session->buffers;
138 src_ps = &src_session->buffers;
140 if (data->src_idx == -1) {
141 if ((pb = paste_get_top(src_ps)) == NULL) {
142 ctx->error(ctx, "no buffers");
143 return (-1);
145 } else {
146 if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) {
147 ctx->error(ctx, "no buffer %d", data->src_idx);
148 return (-1);
151 limit = options_get_number(&dst_session->options, "buffer-limit");
153 pdata = xmalloc(pb->size);
154 memcpy(pdata, pb->data, pb->size);
156 if (data->dst_idx == -1)
157 paste_add(dst_ps, pdata, pb->size, limit);
158 else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) {
159 ctx->error(ctx, "no buffer %d", data->dst_idx);
160 xfree(pdata);
161 return (-1);
164 return (0);
167 void
168 cmd_copy_buffer_free(struct cmd *self)
170 struct cmd_copy_buffer_data *data = self->data;
172 if (data->dst_session != NULL)
173 xfree(data->dst_session);
174 if (data->src_session != NULL)
175 xfree(data->src_session);
176 xfree(data);
179 size_t
180 cmd_copy_buffer_print(struct cmd *self, char *buf, size_t len)
182 struct cmd_copy_buffer_data *data = self->data;
183 size_t off = 0;
185 off += xsnprintf(buf, len, "%s", self->entry->name);
186 if (data == NULL)
187 return (off);
188 if (off < len && data->src_idx != -1) {
189 off += xsnprintf(buf + off, len - off, " -a %d",
190 data->src_idx);
192 if (off < len && data->dst_idx != -1) {
193 off += xsnprintf(buf + off, len - off, " -b %d",
194 data->dst_idx);
196 if (off < len && data->src_session != NULL) {
197 off += cmd_prarg(buf + off, len - off, " -s ",
198 data->src_session);
200 if (off < len && data->dst_session != NULL) {
201 off += cmd_prarg(buf + off, len - off, " -t ",
202 data->dst_session);
204 return (off);