Annotation of embedaddon/tmux/cmd-load-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: 
        !            21: #include <errno.h>
        !            22: #include <fcntl.h>
        !            23: #include <stdio.h>
        !            24: #include <stdlib.h>
        !            25: #include <string.h>
        !            26: #include <unistd.h>
        !            27: 
        !            28: #include "tmux.h"
        !            29: 
        !            30: /*
        !            31:  * Loads a paste buffer from a file.
        !            32:  */
        !            33: 
        !            34: static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmdq_item *);
        !            35: 
        !            36: static void            cmd_load_buffer_callback(struct client *, int, void *);
        !            37: 
        !            38: const struct cmd_entry cmd_load_buffer_entry = {
        !            39:        .name = "load-buffer",
        !            40:        .alias = "loadb",
        !            41: 
        !            42:        .args = { "b:", 1, 1 },
        !            43:        .usage = CMD_BUFFER_USAGE " path",
        !            44: 
        !            45:        .flags = CMD_AFTERHOOK,
        !            46:        .exec = cmd_load_buffer_exec
        !            47: };
        !            48: 
        !            49: struct cmd_load_buffer_data {
        !            50:        struct cmdq_item        *item;
        !            51:        char                    *bufname;
        !            52: };
        !            53: 
        !            54: static enum cmd_retval
        !            55: cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item)
        !            56: {
        !            57:        struct args                     *args = self->args;
        !            58:        struct cmd_load_buffer_data     *cdata;
        !            59:        struct client                   *c = item->client;
        !            60:        FILE                            *f;
        !            61:        const char                      *path, *bufname;
        !            62:        char                            *pdata, *new_pdata, *cause, *file;
        !            63:        size_t                           psize;
        !            64:        int                              ch, error;
        !            65: 
        !            66:        bufname = NULL;
        !            67:        if (args_has(args, 'b'))
        !            68:                bufname = args_get(args, 'b');
        !            69: 
        !            70:        path = args->argv[0];
        !            71:        if (strcmp(path, "-") == 0) {
        !            72:                cdata = xcalloc(1, sizeof *cdata);
        !            73:                cdata->item = item;
        !            74: 
        !            75:                if (bufname != NULL)
        !            76:                        cdata->bufname = xstrdup(bufname);
        !            77: 
        !            78:                error = server_set_stdin_callback(c, cmd_load_buffer_callback,
        !            79:                    cdata, &cause);
        !            80:                if (error != 0) {
        !            81:                        cmdq_error(item, "%s: %s", path, cause);
        !            82:                        free(cause);
        !            83:                        return (CMD_RETURN_ERROR);
        !            84:                }
        !            85:                return (CMD_RETURN_WAIT);
        !            86:        }
        !            87: 
        !            88:        file = server_client_get_path(c, path);
        !            89:        f = fopen(file, "rb");
        !            90:        if (f == NULL) {
        !            91:                cmdq_error(item, "%s: %s", file, strerror(errno));
        !            92:                free(file);
        !            93:                return (CMD_RETURN_ERROR);
        !            94:        }
        !            95: 
        !            96:        pdata = NULL;
        !            97:        psize = 0;
        !            98:        while ((ch = getc(f)) != EOF) {
        !            99:                /* Do not let the server die due to memory exhaustion. */
        !           100:                if ((new_pdata = realloc(pdata, psize + 2)) == NULL) {
        !           101:                        cmdq_error(item, "realloc error: %s", strerror(errno));
        !           102:                        goto error;
        !           103:                }
        !           104:                pdata = new_pdata;
        !           105:                pdata[psize++] = ch;
        !           106:        }
        !           107:        if (ferror(f)) {
        !           108:                cmdq_error(item, "%s: read error", file);
        !           109:                goto error;
        !           110:        }
        !           111:        if (pdata != NULL)
        !           112:                pdata[psize] = '\0';
        !           113: 
        !           114:        fclose(f);
        !           115:        free(file);
        !           116: 
        !           117:        if (paste_set(pdata, psize, bufname, &cause) != 0) {
        !           118:                cmdq_error(item, "%s", cause);
        !           119:                free(pdata);
        !           120:                free(cause);
        !           121:                return (CMD_RETURN_ERROR);
        !           122:        }
        !           123: 
        !           124:        return (CMD_RETURN_NORMAL);
        !           125: 
        !           126: error:
        !           127:        free(pdata);
        !           128:        if (f != NULL)
        !           129:                fclose(f);
        !           130:        return (CMD_RETURN_ERROR);
        !           131: }
        !           132: 
        !           133: static void
        !           134: cmd_load_buffer_callback(struct client *c, int closed, void *data)
        !           135: {
        !           136:        struct cmd_load_buffer_data     *cdata = data;
        !           137:        char                            *pdata, *cause, *saved;
        !           138:        size_t                           psize;
        !           139: 
        !           140:        if (!closed)
        !           141:                return;
        !           142:        c->stdin_callback = NULL;
        !           143: 
        !           144:        server_client_unref(c);
        !           145:        if (c->flags & CLIENT_DEAD)
        !           146:                goto out;
        !           147: 
        !           148:        psize = EVBUFFER_LENGTH(c->stdin_data);
        !           149:        if (psize == 0 || (pdata = malloc(psize + 1)) == NULL)
        !           150:                goto out;
        !           151: 
        !           152:        memcpy(pdata, EVBUFFER_DATA(c->stdin_data), psize);
        !           153:        pdata[psize] = '\0';
        !           154:        evbuffer_drain(c->stdin_data, psize);
        !           155: 
        !           156:        if (paste_set(pdata, psize, cdata->bufname, &cause) != 0) {
        !           157:                /* No context so can't use server_client_msg_error. */
        !           158:                if (~c->flags & CLIENT_UTF8) {
        !           159:                        saved = cause;
        !           160:                        cause = utf8_sanitize(saved);
        !           161:                        free(saved);
        !           162:                }
        !           163:                evbuffer_add_printf(c->stderr_data, "%s", cause);
        !           164:                server_client_push_stderr(c);
        !           165:                free(pdata);
        !           166:                free(cause);
        !           167:        }
        !           168: out:
        !           169:        cdata->item->flags &= ~CMDQ_WAITING;
        !           170: 
        !           171:        free(cdata->bufname);
        !           172:        free(cdata);
        !           173: }

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