[BACK]Return to server-msg.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/server-msg.c, Revision 1.6

1.6     ! nicm        1: /* $OpenBSD: server-msg.c,v 1.5 2009/07/07 17:24:32 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
                      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 <stdlib.h>
                     23: #include <string.h>
                     24: #include <time.h>
                     25: #include <unistd.h>
                     26:
                     27: #include "tmux.h"
                     28:
1.6     ! nicm       29: void   server_msg_fn_command(struct hdr *, struct client *);
        !            30: void   server_msg_fn_identify(struct hdr *, struct client *);
        !            31: void   server_msg_fn_resize(struct hdr *, struct client *);
        !            32: void   server_msg_fn_exiting(struct hdr *, struct client *);
        !            33: void   server_msg_fn_unlock(struct hdr *, struct client *);
        !            34: void   server_msg_fn_wakeup(struct hdr *, struct client *);
1.1       nicm       35:
                     36: void printflike2 server_msg_fn_command_error(
                     37:            struct cmd_ctx *, const char *, ...);
                     38: void printflike2 server_msg_fn_command_print(
                     39:            struct cmd_ctx *, const char *, ...);
                     40: void printflike2 server_msg_fn_command_info(
                     41:            struct cmd_ctx *, const char *, ...);
                     42:
                     43: struct server_msg {
                     44:        enum hdrtype    type;
1.6     ! nicm       45:        void            (*fn)(struct hdr *, struct client *);
1.1       nicm       46: };
                     47: const struct server_msg server_msg_table[] = {
                     48:        { MSG_IDENTIFY, server_msg_fn_identify },
                     49:        { MSG_COMMAND, server_msg_fn_command },
                     50:        { MSG_RESIZE, server_msg_fn_resize },
                     51:        { MSG_EXITING, server_msg_fn_exiting },
                     52:        { MSG_UNLOCK, server_msg_fn_unlock },
                     53:        { MSG_WAKEUP, server_msg_fn_wakeup },
                     54: };
                     55:
                     56: int
                     57: server_msg_dispatch(struct client *c)
                     58: {
                     59:        struct hdr               hdr;
                     60:        const struct server_msg *msg;
                     61:        u_int                    i;
                     62:
                     63:        for (;;) {
                     64:                if (BUFFER_USED(c->in) < sizeof hdr)
                     65:                        return (0);
                     66:                memcpy(&hdr, BUFFER_OUT(c->in), sizeof hdr);
                     67:                if (BUFFER_USED(c->in) < (sizeof hdr) + hdr.size)
                     68:                        return (0);
                     69:                buffer_remove(c->in, sizeof hdr);
                     70:
                     71:                for (i = 0; i < nitems(server_msg_table); i++) {
                     72:                        msg = server_msg_table + i;
                     73:                        if (msg->type == hdr.type) {
1.6     ! nicm       74:                                msg->fn(&hdr, c);
1.1       nicm       75:                                break;
                     76:                        }
                     77:                }
                     78:                if (i == nitems(server_msg_table))
                     79:                        fatalx("unexpected message");
                     80:        }
                     81: }
                     82:
                     83: void printflike2
                     84: server_msg_fn_command_error(struct cmd_ctx *ctx, const char *fmt, ...)
                     85: {
                     86:        va_list ap;
                     87:        char   *msg;
                     88:
                     89:        va_start(ap, fmt);
                     90:        xvasprintf(&msg, fmt, ap);
                     91:        va_end(ap);
                     92:
                     93:        server_write_client(ctx->cmdclient, MSG_ERROR, msg, strlen(msg));
                     94:        xfree(msg);
                     95: }
                     96:
                     97: void printflike2
                     98: server_msg_fn_command_print(struct cmd_ctx *ctx, const char *fmt, ...)
                     99: {
                    100:        va_list ap;
                    101:        char   *msg;
                    102:
                    103:        va_start(ap, fmt);
                    104:        xvasprintf(&msg, fmt, ap);
                    105:        va_end(ap);
                    106:
                    107:        server_write_client(ctx->cmdclient, MSG_PRINT, msg, strlen(msg));
                    108:        xfree(msg);
                    109: }
                    110:
                    111: void printflike2
                    112: server_msg_fn_command_info(struct cmd_ctx *ctx, const char *fmt, ...)
                    113: {
                    114:        va_list ap;
                    115:        char   *msg;
                    116:
                    117:        if (be_quiet)
                    118:                return;
                    119:
                    120:        va_start(ap, fmt);
                    121:        xvasprintf(&msg, fmt, ap);
                    122:        va_end(ap);
                    123:
                    124:        server_write_client(ctx->cmdclient, MSG_PRINT, msg, strlen(msg));
                    125:        xfree(msg);
                    126: }
                    127:
1.6     ! nicm      128: void
1.1       nicm      129: server_msg_fn_command(struct hdr *hdr, struct client *c)
                    130: {
                    131:        struct msg_command_data data;
                    132:        struct cmd_ctx          ctx;
                    133:        struct cmd_list        *cmdlist;
                    134:        struct cmd             *cmd;
                    135:
                    136:        if (hdr->size < sizeof data)
                    137:                fatalx("bad MSG_COMMAND size");
                    138:        buffer_read(c->in, &data, sizeof data);
                    139:
                    140:        cmdlist = cmd_list_recv(c->in);
                    141:        server_activity = time(NULL);
                    142:
                    143:        ctx.error = server_msg_fn_command_error;
                    144:        ctx.print = server_msg_fn_command_print;
                    145:        ctx.info = server_msg_fn_command_info;
                    146:
                    147:        ctx.msgdata = &data;
                    148:        ctx.curclient = NULL;
                    149:        ctx.cursession = NULL;
                    150:
                    151:        ctx.cmdclient = c;
                    152:
                    153:        if (data.pid != -1) {
                    154:                TAILQ_FOREACH(cmd, cmdlist, qentry) {
                    155:                        if (cmd->entry->flags & CMD_CANTNEST) {
                    156:                                server_msg_fn_command_error(&ctx,
                    157:                                    "sessions should be nested with care. "
                    158:                                    "unset $TMUX to force");
                    159:                                cmd_list_free(cmdlist);
                    160:                                server_write_client(c, MSG_EXIT, NULL, 0);
1.6     ! nicm      161:                                return;
1.1       nicm      162:                        }
                    163:                }
                    164:        }
                    165:
                    166:        if (cmd_list_exec(cmdlist, &ctx) != 1)
                    167:                server_write_client(c, MSG_EXIT, NULL, 0);
                    168:        cmd_list_free(cmdlist);
                    169: }
                    170:
1.6     ! nicm      171: void
1.1       nicm      172: server_msg_fn_identify(struct hdr *hdr, struct client *c)
                    173: {
                    174:        struct msg_identify_data        data;
                    175:         char                          *term;
                    176:
                    177:        if (hdr->size < sizeof data)
                    178:                fatalx("bad MSG_IDENTIFY size");
                    179:        buffer_read(c->in, &data, sizeof data);
                    180:        term = cmd_recv_string(c->in);
                    181:
                    182:        log_debug("identify msg from client: %u,%u (%d)",
                    183:            data.sx, data.sy, data.version);
                    184:
                    185:        if (data.version != PROTOCOL_VERSION) {
                    186: #define MSG "protocol version mismatch"
                    187:                server_write_client(c, MSG_ERROR, MSG, (sizeof MSG) - 1);
                    188: #undef MSG
1.4       nicm      189:                server_write_client(c, MSG_EXIT, NULL, 0);
1.6     ! nicm      190:                return;
1.1       nicm      191:        }
                    192:
                    193:        c->tty.sx = data.sx;
                    194:        c->tty.sy = data.sy;
                    195:
                    196:        c->cwd = NULL;
1.3       nicm      197:        data.cwd[(sizeof data.cwd) - 1] = '\0';
1.1       nicm      198:        if (*data.cwd != '\0')
                    199:                c->cwd = xstrdup(data.cwd);
                    200:
                    201:        data.tty[(sizeof data.tty) - 1] = '\0';
                    202:        tty_init(&c->tty, data.tty, term);
                    203:        if (data.flags & IDENTIFY_UTF8)
                    204:                c->tty.flags |= TTY_UTF8;
                    205:        if (data.flags & IDENTIFY_256COLOURS)
                    206:                c->tty.term_flags |= TERM_256COLOURS;
                    207:        else if (data.flags & IDENTIFY_88COLOURS)
                    208:                c->tty.term_flags |= TERM_88COLOURS;
                    209:        if (data.flags & IDENTIFY_HASDEFAULTS)
                    210:                c->tty.term_flags |= TERM_HASDEFAULTS;
1.5       nicm      211:
                    212:        if (term != NULL)
                    213:                xfree(term);
1.1       nicm      214:
                    215:        c->flags |= CLIENT_TERMINAL;
                    216: }
                    217:
1.6     ! nicm      218: void
1.1       nicm      219: server_msg_fn_resize(struct hdr *hdr, struct client *c)
                    220: {
                    221:        struct msg_resize_data  data;
                    222:
                    223:        if (hdr->size != sizeof data)
                    224:                fatalx("bad MSG_RESIZE size");
                    225:        buffer_read(c->in, &data, sizeof data);
                    226:
                    227:        log_debug("resize msg from client: %u,%u", data.sx, data.sy);
                    228:
                    229:        c->tty.sx = data.sx;
                    230:        if (c->tty.sx == 0)
                    231:                c->tty.sx = 80;
                    232:        c->tty.sy = data.sy;
                    233:        if (c->tty.sy == 0)
                    234:                c->tty.sy = 25;
                    235:
                    236:        c->tty.cx = UINT_MAX;
                    237:        c->tty.cy = UINT_MAX;
                    238:        c->tty.rupper = UINT_MAX;
                    239:        c->tty.rlower = UINT_MAX;
                    240:
                    241:        recalculate_sizes();
                    242:
                    243:        /* Always redraw this client. */
                    244:        server_redraw_client(c);
                    245: }
                    246:
1.6     ! nicm      247: void
1.1       nicm      248: server_msg_fn_exiting(struct hdr *hdr, struct client *c)
                    249: {
                    250:        if (hdr->size != 0)
                    251:                fatalx("bad MSG_EXITING size");
                    252:
                    253:        log_debug("exiting msg from client");
                    254:
                    255:        c->session = NULL;
                    256:
                    257:        tty_close(&c->tty, c->flags & CLIENT_SUSPENDED);
                    258:
                    259:        server_write_client(c, MSG_EXITED, NULL, 0);
                    260: }
                    261:
1.6     ! nicm      262: void
1.1       nicm      263: server_msg_fn_unlock(struct hdr *hdr, struct client *c)
                    264: {
                    265:         char   *pass;
                    266:
                    267:        if (hdr->size == 0)
                    268:                fatalx("bad MSG_UNLOCK size");
                    269:        pass = cmd_recv_string(c->in);
                    270:
                    271:        log_debug("unlock msg from client");
                    272:
                    273:        if (server_unlock(pass) != 0) {
                    274: #define MSG "bad password"
                    275:                server_write_client(c, MSG_ERROR, MSG, (sizeof MSG) - 1);
                    276: #undef MSG
                    277:        }
                    278:
                    279:        server_write_client(c, MSG_EXIT, NULL, 0);
1.2       nicm      280:
                    281:        memset(pass, 0, strlen(pass));
                    282:        xfree(pass);
1.1       nicm      283: }
                    284:
1.6     ! nicm      285: void
1.1       nicm      286: server_msg_fn_wakeup(struct hdr *hdr, struct client *c)
                    287: {
                    288:        if (hdr->size != 0)
                    289:                fatalx("bad MSG_WAKEUP size");
                    290:
                    291:        log_debug("wakeup msg from client");
                    292:
                    293:        c->flags &= ~CLIENT_SUSPENDED;
                    294:        tty_start_tty(&c->tty);
                    295:        server_redraw_client(c);
                    296: }