| /* $Id: client-msg.c,v 1.9 2007-10-12 11:24:15 nicm Exp $ */ | 
 |  | 
 | /* | 
 |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | 
 |  * | 
 |  * Permission to use, copy, modify, and distribute this software for any | 
 |  * purpose with or without fee is hereby granted, provided that the above | 
 |  * copyright notice and this permission notice appear in all copies. | 
 |  * | 
 |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 
 |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 
 |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 
 |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
 |  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | 
 |  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | 
 |  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
 |  */ | 
 |  | 
 | #include <sys/types.h> | 
 |  | 
 | #include <stdlib.h> | 
 | #include <string.h> | 
 | #include <unistd.h> | 
 |  | 
 | #include "tmux.h" | 
 |  | 
 | int	client_msg_fn_data(struct hdr *, struct client_ctx *, char **); | 
 | int	client_msg_fn_detach(struct hdr *, struct client_ctx *, char **); | 
 | int	client_msg_fn_error(struct hdr *, struct client_ctx *, char **); | 
 | int	client_msg_fn_exit(struct hdr *, struct client_ctx *, char **); | 
 | int	client_msg_fn_okay(struct hdr *, struct client_ctx *, char **); | 
 | int	client_msg_fn_pause(struct hdr *, struct client_ctx *, char **); | 
 |  | 
 | struct client_msg { | 
 | 	enum hdrtype   type; | 
 | 	 | 
 | 	int	       (*fn)(struct hdr *, struct client_ctx *, char **); | 
 | }; | 
 | struct client_msg client_msg_table[] = { | 
 | 	{ MSG_DATA, client_msg_fn_data }, | 
 | 	{ MSG_DETACH, client_msg_fn_detach }, | 
 | 	{ MSG_ERROR, client_msg_fn_error }, | 
 | 	{ MSG_EXIT, client_msg_fn_exit }, | 
 | 	{ MSG_PAUSE, client_msg_fn_pause }, | 
 | }; | 
 | #define NCLIENTMSG (sizeof client_msg_table / sizeof client_msg_table[0]) | 
 |  | 
 | int | 
 | client_msg_dispatch(struct client_ctx *cctx, char **error) | 
 | { | 
 | 	struct hdr		 hdr; | 
 | 	struct client_msg	*msg; | 
 | 	u_int		 	 i; | 
 |  | 
 | 	if (BUFFER_USED(cctx->srv_in) < sizeof hdr) | 
 | 		return (1); | 
 | 	memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr); | 
 | 	if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size) | 
 | 		return (1); | 
 | 	buffer_remove(cctx->srv_in, sizeof hdr); | 
 | 	 | 
 | 	for (i = 0; i < NCLIENTMSG; i++) { | 
 | 		msg = client_msg_table + i; | 
 | 		if (msg->type == hdr.type) { | 
 | 			if (msg->fn(&hdr, cctx, error) != 0) | 
 | 				return (-1); | 
 | 			return (0); | 
 | 		} | 
 | 	} | 
 | 	fatalx("unexpected message"); | 
 | } | 
 |  | 
 | int | 
 | client_msg_fn_data( | 
 |     struct hdr *hdr, struct client_ctx *cctx, unused char **error) | 
 | { | 
 | 	local_output(cctx->srv_in, hdr->size); | 
 | 	return (0); | 
 | } | 
 |  | 
 | int | 
 | client_msg_fn_pause( | 
 |     struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) | 
 | { | 
 | 	if (hdr->size != 0) | 
 | 		fatalx("bad MSG_PAUSE size"); | 
 |  | 
 | 	cctx->flags |= CCTX_PAUSE; | 
 |  | 
 | 	return (0); | 
 | } | 
 |  | 
 | int | 
 | client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error) | 
 | { | 
 | 	if (hdr->size > SIZE_MAX - 1) | 
 | 		fatalx("bad MSG_ERROR size"); | 
 |  | 
 | 	*error = xmalloc(hdr->size + 1); | 
 | 	buffer_read(cctx->srv_in, *error, hdr->size); | 
 | 	(*error)[hdr->size] = '\0'; | 
 |  | 
 | 	return (-1); | 
 | } | 
 |  | 
 | int | 
 | client_msg_fn_exit( | 
 |     struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) | 
 | { | 
 | 	if (hdr->size != 0) | 
 | 		fatalx("bad MSG_EXIT size"); | 
 |  | 
 | 	cctx->flags |= CCTX_EXIT; | 
 |  | 
 | 	return (-1); | 
 | } | 
 |  | 
 | int | 
 | client_msg_fn_detach( | 
 |     struct hdr *hdr, unused struct client_ctx *cctx, unused char **error) | 
 | { | 
 | 	if (hdr->size != 0) | 
 | 		fatalx("bad MSG_DETACH size"); | 
 |  | 
 | 	cctx->flags |= CCTX_DETACH; | 
 |  | 
 | 	return (-1); | 
 | } |