1*1b09dd8dSnicm /* $OpenBSD: cmd-load-buffer.c,v 1.65 2022/06/09 09:12:55 nicm Exp $ */
2311827fbSnicm
3311827fbSnicm /*
4311827fbSnicm * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
5311827fbSnicm *
6311827fbSnicm * Permission to use, copy, modify, and distribute this software for any
7311827fbSnicm * purpose with or without fee is hereby granted, provided that the above
8311827fbSnicm * copyright notice and this permission notice appear in all copies.
9311827fbSnicm *
10311827fbSnicm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11311827fbSnicm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12311827fbSnicm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13311827fbSnicm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14311827fbSnicm * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15311827fbSnicm * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16311827fbSnicm * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17311827fbSnicm */
18311827fbSnicm
197b013918Snicm #include <sys/types.h>
207b013918Snicm
21311827fbSnicm #include <errno.h>
22e1803d63Snicm #include <fcntl.h>
23b707c8c3Snicm #include <stdio.h>
24311827fbSnicm #include <stdlib.h>
25311827fbSnicm #include <string.h>
267b013918Snicm #include <unistd.h>
27311827fbSnicm
28311827fbSnicm #include "tmux.h"
29311827fbSnicm
30311827fbSnicm /*
31521765b0Snicm * Loads a paste buffer from a file.
32311827fbSnicm */
33311827fbSnicm
3468e0a7f2Snicm static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmdq_item *);
35dc1f0f5fSnicm
36311827fbSnicm const struct cmd_entry cmd_load_buffer_entry = {
37c057646bSnicm .name = "load-buffer",
38c057646bSnicm .alias = "loadb",
39c057646bSnicm
40a51dead1Snicm .args = { "b:t:w", 1, 1, NULL },
41e4f0ed7fSnicm .usage = CMD_BUFFER_USAGE " " CMD_TARGET_CLIENT_USAGE " path",
42c057646bSnicm
43e4f0ed7fSnicm .flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG|CMD_CLIENT_CANFAIL,
44c057646bSnicm .exec = cmd_load_buffer_exec
45311827fbSnicm };
46311827fbSnicm
47765b9a58Snicm struct cmd_load_buffer_data {
48e4f0ed7fSnicm struct client *client;
4968e0a7f2Snicm struct cmdq_item *item;
50f4bc7c7aSnicm char *name;
51765b9a58Snicm };
52765b9a58Snicm
53f4bc7c7aSnicm static void
cmd_load_buffer_done(__unused struct client * c,const char * path,int error,int closed,struct evbuffer * buffer,void * data)54f4bc7c7aSnicm cmd_load_buffer_done(__unused struct client *c, const char *path, int error,
55f4bc7c7aSnicm int closed, struct evbuffer *buffer, void *data)
56f4bc7c7aSnicm {
57f4bc7c7aSnicm struct cmd_load_buffer_data *cdata = data;
58e4f0ed7fSnicm struct client *tc = cdata->client;
59f4bc7c7aSnicm struct cmdq_item *item = cdata->item;
60f4bc7c7aSnicm void *bdata = EVBUFFER_DATA(buffer);
61f4bc7c7aSnicm size_t bsize = EVBUFFER_LENGTH(buffer);
62f4bc7c7aSnicm void *copy;
63f4bc7c7aSnicm char *cause;
64f4bc7c7aSnicm
65f4bc7c7aSnicm if (!closed)
66f4bc7c7aSnicm return;
67f4bc7c7aSnicm
68f4bc7c7aSnicm if (error != 0)
69f4bc7c7aSnicm cmdq_error(item, "%s: %s", path, strerror(error));
70f4bc7c7aSnicm else if (bsize != 0) {
71f4bc7c7aSnicm copy = xmalloc(bsize);
72f4bc7c7aSnicm memcpy(copy, bdata, bsize);
73f4bc7c7aSnicm if (paste_set(copy, bsize, cdata->name, &cause) != 0) {
74f4bc7c7aSnicm cmdq_error(item, "%s", cause);
75f4bc7c7aSnicm free(cause);
76f4bc7c7aSnicm free(copy);
77e4f0ed7fSnicm } else if (tc != NULL &&
78e4f0ed7fSnicm tc->session != NULL &&
79e4f0ed7fSnicm (~tc->flags & CLIENT_DEAD))
80*1b09dd8dSnicm tty_set_selection(&tc->tty, "", copy, bsize);
81e4f0ed7fSnicm if (tc != NULL)
82e4f0ed7fSnicm server_client_unref(tc);
83f4bc7c7aSnicm }
84f4bc7c7aSnicm cmdq_continue(item);
85f4bc7c7aSnicm
86f4bc7c7aSnicm free(cdata->name);
87f4bc7c7aSnicm free(cdata);
88f4bc7c7aSnicm }
89f4bc7c7aSnicm
90dc1f0f5fSnicm static enum cmd_retval
cmd_load_buffer_exec(struct cmd * self,struct cmdq_item * item)9168e0a7f2Snicm cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
92311827fbSnicm {
9390d7ba38Snicm struct args *args = cmd_get_args(self);
94e4f0ed7fSnicm struct client *tc = cmdq_get_target_client(item);
95765b9a58Snicm struct cmd_load_buffer_data *cdata;
96f4bc7c7aSnicm const char *bufname = args_get(args, 'b');
97f4bc7c7aSnicm char *path;
98311827fbSnicm
99a1750446Snicm cdata = xcalloc(1, sizeof *cdata);
100f4bc7c7aSnicm cdata->item = item;
101f4bc7c7aSnicm if (bufname != NULL)
102f4bc7c7aSnicm cdata->name = xstrdup(bufname);
103e4f0ed7fSnicm if (args_has(args, 'w') && tc != NULL) {
104e4f0ed7fSnicm cdata->client = tc;
105e4f0ed7fSnicm cdata->client->references++;
106e4f0ed7fSnicm }
107ca7befccSnicm
1081693b10bSnicm path = format_single_from_target(item, args_string(args, 0));
109040343aeSnicm file_read(cmdq_get_client(item), path, cmd_load_buffer_done, cdata);
110980ca567Snicm free(path);
111980ca567Snicm
112175d36ccSnicm return (CMD_RETURN_WAIT);
113636a2c4aSnicm }
114