Annotation of embedaddon/tmux/cmd-save-buffer.c, revision 1.1
1.1 ! misho 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>