/*
 * Copyright (c) 2010 Andreas Schwab <schwab@linux-m68k.org>
 * Copyright (c) 2012-2013 Denys Vlasenko <vda.linux@googlemail.com>
 * Copyright (c) 2014 Masatake YAMATO <yamato@redhat.com>
 * Copyright (c) 2010-2016 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2016-2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"
#include "msghdr.h"
#include "xstring.h"
#include <limits.h>

static bool
fetch_struct_mmsghdr_for_print(struct tcb *const tcp,
				  const kernel_ulong_t addr,
				  const unsigned int len, void *const mh)
{
	return (entering(tcp) || !syserror(tcp)) &&
	       fetch_struct_mmsghdr(tcp, addr, mh);
}

struct print_struct_mmsghdr_config {
	const int *p_user_msg_namelen;
	unsigned int msg_len_vlen;
	unsigned int count;
	bool use_msg_len;
};

static bool
print_struct_mmsghdr(struct tcb *tcp, void *elem_buf,
		     size_t elem_size, void *data)
{
	const struct mmsghdr *const mmsg = elem_buf;
	struct print_struct_mmsghdr_config *const c = data;

	if (!c->count) {
		tprints("...");
		return false;
	}
	--c->count;

	tprints("{msg_hdr=");
	print_struct_msghdr(tcp, &mmsg->msg_hdr, c->p_user_msg_namelen,
			    c->use_msg_len ? mmsg->msg_len : (kernel_ulong_t) -1);
	if (c->msg_len_vlen) {
		tprintf(", msg_len=%u", mmsg->msg_len);
		--c->msg_len_vlen;
	}
	tprints("}");

	if (c->p_user_msg_namelen)
		++c->p_user_msg_namelen;

	return true;
}

static void
free_mmsgvec_data(void *ptr)
{
	char **pstr = ptr;
	free(*pstr);
	*pstr = 0;

	free(ptr);
}

struct mmsgvec_data {
	char *timeout;
	unsigned int count;
	int namelen[IOV_MAX];
};

static void
save_mmsgvec_namelen(struct tcb *const tcp, kernel_ulong_t addr,
		     unsigned int len, const char *const timeout)
{
	if (len > IOV_MAX)
		len = IOV_MAX;

	const size_t data_size = offsetof(struct mmsgvec_data, namelen)
				 + sizeof(int) * len;
	struct mmsgvec_data *const data = xmalloc(data_size);
	data->timeout = xstrdup(timeout);

	unsigned int i, fetched;

	for (i = 0; i < len; ++i, addr += fetched) {
		struct mmsghdr mh;

		fetched = fetch_struct_mmsghdr(tcp, addr, &mh);
		if (!fetched)
			break;
		data->namelen[i] = mh.msg_hdr.msg_namelen;
	}
	data->count = i;

	set_tcb_priv_data(tcp, data, free_mmsgvec_data);
}

static void
decode_mmsgvec(struct tcb *const tcp, const kernel_ulong_t addr,
	       const unsigned int vlen, const unsigned int msg_len_vlen,
	       const bool use_msg_len)
{
	struct mmsghdr mmsg;
	struct print_struct_mmsghdr_config c = {
		.msg_len_vlen = msg_len_vlen,
		.count = IOV_MAX,
		.use_msg_len = use_msg_len
	};
	const struct mmsgvec_data *const data = get_tcb_priv_data(tcp);

	if (data) {
		if (data->count < c.count)
			c.count = data->count;
		c.p_user_msg_namelen = data->namelen;
	}

	print_array(tcp, addr, vlen, &mmsg, sizeof_struct_mmsghdr(),
		    fetch_struct_mmsghdr_for_print,
		    print_struct_mmsghdr, &c);
}

void
dumpiov_in_mmsghdr(struct tcb *const tcp, kernel_ulong_t addr)
{
	unsigned int len = tcp->u_rval;
	unsigned int i, fetched;
	struct mmsghdr mmsg;

	for (i = 0; i < len; ++i, addr += fetched) {
		fetched = fetch_struct_mmsghdr(tcp, addr, &mmsg);
		if (!fetched)
			break;
		tprintf(" = %" PRI_klu " buffers in vector %u\n",
			(kernel_ulong_t) mmsg.msg_hdr.msg_iovlen, i);
		dumpiov_upto(tcp, mmsg.msg_hdr.msg_iovlen,
			     ptr_to_kulong(mmsg.msg_hdr.msg_iov),
			     mmsg.msg_len);
	}
}

SYS_FUNC(sendmmsg)
{
	if (entering(tcp)) {
		/* sockfd */
		printfd(tcp, tcp->u_arg[0]);
		tprints(", ");
		if (!verbose(tcp)) {
			/* msgvec */
			printaddr(tcp->u_arg[1]);
			/* vlen */
			tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
			/* flags */
			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
			return RVAL_DECODED;
		}
	} else {
		const unsigned int msg_len_vlen =
			syserror(tcp) ? 0 : tcp->u_rval;
		/* msgvec */
		temporarily_clear_syserror(tcp);
		decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_arg[2],
			       msg_len_vlen, false);
		restore_cleared_syserror(tcp);
		/* vlen */
		tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
		/* flags */
		printflags(msg_flags, tcp->u_arg[3], "MSG_???");
	}
	return 0;
}

SYS_FUNC(recvmmsg)
{
	if (entering(tcp)) {
		printfd(tcp, tcp->u_arg[0]);
		tprints(", ");
		if (verbose(tcp)) {
			save_mmsgvec_namelen(tcp, tcp->u_arg[1], tcp->u_arg[2],
					     sprint_timespec(tcp, tcp->u_arg[4]));
		} else {
			/* msgvec */
			printaddr(tcp->u_arg[1]);
			/* vlen */
			tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
			/* flags */
			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
			tprints(", ");
			print_timespec(tcp, tcp->u_arg[4]);
		}
		return 0;
	} else {
		if (verbose(tcp)) {
			/* msgvec */
			decode_mmsgvec(tcp, tcp->u_arg[1], tcp->u_rval,
				       tcp->u_rval, true);
			/* vlen */
			tprintf(", %u, ", (unsigned int) tcp->u_arg[2]);
			/* flags */
			printflags(msg_flags, tcp->u_arg[3], "MSG_???");
			tprints(", ");
			/* timeout on entrance */
			tprints(*(const char **) get_tcb_priv_data(tcp));
		}
		if (syserror(tcp))
			return 0;
		if (tcp->u_rval == 0) {
			tcp->auxstr = "Timeout";
			return RVAL_STR;
		}
		if (!verbose(tcp) || !tcp->u_arg[4])
			return 0;
		/* timeout on exit */
		static char str[sizeof("left") + TIMESPEC_TEXT_BUFSIZE];
		xsprintf(str, "left %s", sprint_timespec(tcp, tcp->u_arg[4]));
		tcp->auxstr = str;
		return RVAL_STR;
	}
}
