File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / tmux / cmd-save-buffer.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:22:44 2017 UTC (6 years, 11 months ago) by misho
Branches: tmux, MAIN
CVS tags: v2_4p0, v2_4, HEAD
tmux 2.4

    1: /* $OpenBSD$ */
    2: 
    3: /*
    4:  * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
    5:  *
    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.
    9:  *
   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.
   17:  */
   18: 
   19: #include <sys/types.h>
   20: #include <sys/stat.h>
   21: 
   22: #include <errno.h>
   23: #include <fcntl.h>
   24: #include <stdlib.h>
   25: #include <string.h>
   26: #include <unistd.h>
   27: 
   28: #include "tmux.h"
   29: 
   30: /*
   31:  * Saves a paste buffer to a file.
   32:  */
   33: 
   34: static enum cmd_retval	cmd_save_buffer_exec(struct cmd *, struct cmdq_item *);
   35: 
   36: const struct cmd_entry cmd_save_buffer_entry = {
   37: 	.name = "save-buffer",
   38: 	.alias = "saveb",
   39: 
   40: 	.args = { "ab:", 1, 1 },
   41: 	.usage = "[-a] " CMD_BUFFER_USAGE " path",
   42: 
   43: 	.flags = CMD_AFTERHOOK,
   44: 	.exec = cmd_save_buffer_exec
   45: };
   46: 
   47: const struct cmd_entry cmd_show_buffer_entry = {
   48: 	.name = "show-buffer",
   49: 	.alias = "showb",
   50: 
   51: 	.args = { "b:", 0, 0 },
   52: 	.usage = CMD_BUFFER_USAGE,
   53: 
   54: 	.flags = CMD_AFTERHOOK,
   55: 	.exec = cmd_save_buffer_exec
   56: };
   57: 
   58: static enum cmd_retval
   59: cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item)
   60: {
   61: 	struct args		*args = self->args;
   62: 	struct client		*c = item->client;
   63: 	struct paste_buffer	*pb;
   64: 	const char		*path, *bufname, *bufdata, *start, *end;
   65: 	const char		*flags;
   66: 	char			*msg, *file;
   67: 	size_t			 size, used, msglen, bufsize;
   68: 	FILE			*f;
   69: 
   70: 	if (!args_has(args, 'b')) {
   71: 		if ((pb = paste_get_top(NULL)) == NULL) {
   72: 			cmdq_error(item, "no buffers");
   73: 			return (CMD_RETURN_ERROR);
   74: 		}
   75: 	} else {
   76: 		bufname = args_get(args, 'b');
   77: 		pb = paste_get_name(bufname);
   78: 		if (pb == NULL) {
   79: 			cmdq_error(item, "no buffer %s", bufname);
   80: 			return (CMD_RETURN_ERROR);
   81: 		}
   82: 	}
   83: 	bufdata = paste_buffer_data(pb, &bufsize);
   84: 
   85: 	if (self->entry == &cmd_show_buffer_entry)
   86: 		path = "-";
   87: 	else
   88: 		path = args->argv[0];
   89: 	if (strcmp(path, "-") == 0) {
   90: 		if (c == NULL) {
   91: 			cmdq_error(item, "can't write to stdout");
   92: 			return (CMD_RETURN_ERROR);
   93: 		}
   94: 		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
   95: 			goto do_stdout;
   96: 		goto do_print;
   97: 	}
   98: 
   99: 	flags = "wb";
  100: 	if (args_has(self->args, 'a'))
  101: 		flags = "ab";
  102: 
  103: 	file = server_client_get_path(c, path);
  104: 	f = fopen(file, flags);
  105: 	if (f == NULL) {
  106: 		cmdq_error(item, "%s: %s", file, strerror(errno));
  107: 		free(file);
  108: 		return (CMD_RETURN_ERROR);
  109: 	}
  110: 
  111: 	if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
  112: 		cmdq_error(item, "%s: write error", file);
  113: 		fclose(f);
  114: 		return (CMD_RETURN_ERROR);
  115: 	}
  116: 
  117: 	fclose(f);
  118: 	free(file);
  119: 
  120: 	return (CMD_RETURN_NORMAL);
  121: 
  122: do_stdout:
  123: 	evbuffer_add(c->stdout_data, bufdata, bufsize);
  124: 	server_client_push_stdout(c);
  125: 	return (CMD_RETURN_NORMAL);
  126: 
  127: do_print:
  128: 	if (bufsize > (INT_MAX / 4) - 1) {
  129: 		cmdq_error(item, "buffer too big");
  130: 		return (CMD_RETURN_ERROR);
  131: 	}
  132: 	msg = NULL;
  133: 
  134: 	used = 0;
  135: 	while (used != bufsize) {
  136: 		start = bufdata + used;
  137: 		end = memchr(start, '\n', bufsize - used);
  138: 		if (end != NULL)
  139: 			size = end - start;
  140: 		else
  141: 			size = bufsize - used;
  142: 
  143: 		msglen = size * 4 + 1;
  144: 		msg = xrealloc(msg, msglen);
  145: 
  146: 		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
  147: 		cmdq_print(item, "%s", msg);
  148: 
  149: 		used += size + (end != NULL);
  150: 	}
  151: 
  152: 	free(msg);
  153: 	return (CMD_RETURN_NORMAL);
  154: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>