/*
 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
 * 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 "flock.h"

#include "xlat/f_owner_types.h"
#include "xlat/f_seals.h"
#include "xlat/fcntlcmds.h"
#include "xlat/fdflags.h"
#include "xlat/lockfcmds.h"
#include "xlat/notifyflags.h"

static void
print_struct_flock64(const struct_kernel_flock64 *fl, const int getlk)
{
	tprints("{l_type=");
	printxval(lockfcmds, fl->l_type, "F_???");
	tprints(", l_whence=");
	printxval(whence_codes, fl->l_whence, "SEEK_???");
	tprintf(", l_start=%Ld, l_len=%Ld",
		(long long) fl->l_start, (long long) fl->l_len);
	if (getlk)
		tprintf(", l_pid=%lu", (unsigned long) fl->l_pid);
	tprints("}");
}

static void
printflock64(struct tcb *tcp, const long addr, const int getlk)
{
	struct_kernel_flock64 fl;

	if (fetch_struct_flock64(tcp, addr, &fl))
		print_struct_flock64(&fl, getlk);
}

static void
printflock(struct tcb *tcp, const long addr, const int getlk)
{
	struct_kernel_flock64 fl;

	if (fetch_struct_flock(tcp, addr, &fl))
		print_struct_flock64(&fl, getlk);
}

static void
print_f_owner_ex(struct tcb *tcp, const long addr)
{
	struct { int type, pid; } owner;

	if (umove_or_printaddr(tcp, addr, &owner))
		return;

	tprints("{type=");
	printxval(f_owner_types, owner.type, "F_OWNER_???");
	tprintf(", pid=%d}", owner.pid);
}

SYS_FUNC(fcntl)
{
	if (entering(tcp)) {
		printfd(tcp, tcp->u_arg[0]);
		tprints(", ");
		printxval(fcntlcmds, tcp->u_arg[1], "F_???");
		switch (tcp->u_arg[1]) {
		case F_SETFD:
			tprints(", ");
			printflags(fdflags, tcp->u_arg[2], "FD_???");
			break;
		case F_SETOWN:
		case F_SETPIPE_SZ:
			tprintf(", %ld", tcp->u_arg[2]);
			break;
		case F_DUPFD:
		case F_DUPFD_CLOEXEC:
			tprintf(", %ld", tcp->u_arg[2]);
			return RVAL_DECODED | RVAL_FD;
		case F_SETFL:
			tprints(", ");
			tprint_open_modes(tcp->u_arg[2]);
			break;
		case F_SETLK:
		case F_SETLKW:
			tprints(", ");
			printflock(tcp, tcp->u_arg[2], 0);
			break;
		case F_SETLK64:
		case F_SETLKW64:
		case F_OFD_SETLK:
		case F_OFD_SETLKW:
			tprints(", ");
			printflock64(tcp, tcp->u_arg[2], 0);
			break;
		case F_SETOWN_EX:
			tprints(", ");
			print_f_owner_ex(tcp, tcp->u_arg[2]);
			break;
		case F_NOTIFY:
			tprints(", ");
			printflags(notifyflags, tcp->u_arg[2], "DN_???");
			break;
		case F_SETLEASE:
			tprints(", ");
			printxval(lockfcmds, tcp->u_arg[2], "F_???");
			break;
		case F_ADD_SEALS:
			tprints(", ");
			printflags(f_seals, tcp->u_arg[2], "F_SEAL_???");
			break;
		case F_SETSIG:
			tprints(", ");
			tprints(signame(tcp->u_arg[2]));
			break;
		case F_GETOWN:
		case F_GETPIPE_SZ:
			break;
		default:
			return 0;
		}
		return RVAL_DECODED;
	} else {
		switch (tcp->u_arg[1]) {
		case F_GETFD:
			if (syserror(tcp) || tcp->u_rval == 0)
				return 0;
			tcp->auxstr = sprintflags("flags ", fdflags, tcp->u_rval);
			return RVAL_HEX | RVAL_STR;
		case F_GETFL:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = sprint_open_modes(tcp->u_rval);
			return RVAL_HEX | RVAL_STR;
		case F_GETLK:
			tprints(", ");
			printflock(tcp, tcp->u_arg[2], 1);
			break;
		case F_GETLK64:
		case F_OFD_GETLK:
			tprints(", ");
			printflock64(tcp, tcp->u_arg[2], 1);
			break;
		case F_GETOWN_EX:
			tprints(", ");
			print_f_owner_ex(tcp, tcp->u_arg[2]);
			break;
		case F_GETLEASE:
			if (syserror(tcp))
				return 0;
			tcp->auxstr = xlookup(lockfcmds, tcp->u_rval);
			return RVAL_HEX | RVAL_STR;
		case F_GET_SEALS:
			if (syserror(tcp) || tcp->u_rval == 0)
				return 0;
			tcp->auxstr = sprintflags("seals ", f_seals, tcp->u_rval);
			return RVAL_HEX | RVAL_STR;
		case F_GETSIG:
			if (syserror(tcp) || tcp->u_rval == 0)
				return 0;
			tcp->auxstr = signame(tcp->u_rval);
			return RVAL_STR;
		default:
			tprintf(", %#lx", tcp->u_arg[2]);
			break;
		}
	}
	return 0;
}
