#include "fsysudefs.h"
#define EXPORT_BOOLEAN
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/message.h>
#include <mach/notify.h>
#include <mach/mach_types.h>
#include <mach/mig_errors.h>
#include <mach/msg_type.h>
#ifndef	KERNEL
#include <strings.h>
#endif	KERNEL
/* LINTLIBRARY */

extern mach_port_t mig_get_reply_port();
extern void mig_dealloc_reply_port();

#ifndef	mig_internal
#define	mig_internal	static
#endif

#ifndef	mig_external
#define mig_external
#endif

#ifndef	TypeCheck
#define	TypeCheck 1
#endif

#ifndef	UseExternRCSId
#ifdef	hc
#define	UseExternRCSId		1
#endif
#endif

#ifndef	UseStaticMsgType
#if	!defined(hc) || defined(__STDC__)
#define	UseStaticMsgType	1
#endif
#endif

#define msgh_request_port	msgh_remote_port
#define msgh_reply_port		msgh_local_port


/* Routine fsys_startup */
mig_external kern_return_t U_fsys_startup
#if	(defined(__STDC__) || defined(c_plusplus))
(
	mach_port_t bootstrap,
	fsys_t control_port,
	file_t *realnode,
	file_t *dotdot_node
)
#else
	(bootstrap, control_port, realnode, dotdot_node)
	mach_port_t bootstrap;
	fsys_t control_port;
	file_t *realnode;
	file_t *dotdot_node;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t control_portType;
		fsys_t control_port;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t realnodeType;
		file_t realnode;
		mach_msg_type_t dotdot_nodeType;
		file_t dotdot_node;
	} Reply;

	union {
		Request In;
		Reply Out;
	} Mess;

	register Request *InP = &Mess.In;
	register Reply *OutP = &Mess.Out;

	mach_msg_return_t msg_result;
#if	TypeCheck
	boolean_t msgh_simple;
#endif	TypeCheck
#if	TypeCheck
	unsigned int msgh_size;
#endif	TypeCheck

#if	UseStaticMsgType
	static mach_msg_type_t control_portType = {
		/* msgt_name = */		MACH_MSG_TYPE_COPY_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t RetCodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t realnodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t dotdot_nodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	InP->control_portType = control_portType;
#else	UseStaticMsgType
	InP->control_portType.msgt_name = MACH_MSG_TYPE_COPY_SEND;
	InP->control_portType.msgt_size = 32;
	InP->control_portType.msgt_number = 1;
	InP->control_portType.msgt_inline = TRUE;
	InP->control_portType.msgt_longform = FALSE;
	InP->control_portType.msgt_deallocate = FALSE;
	InP->control_portType.msgt_unused = 0;
#endif	UseStaticMsgType

	InP->control_port = control_port;

	InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX|
		MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = bootstrap;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_seqno = 0;
	InP->Head.msgh_id = 22000;

	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, sizeof(Request), sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	if (msg_result != MACH_MSG_SUCCESS) {
		if ((msg_result == MACH_SEND_INVALID_REPLY) ||
		    (msg_result == MACH_RCV_INVALID_NAME))
			mig_dealloc_reply_port();
		return msg_result;
	}

	if (OutP->Head.msgh_id != 22100) {
		if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)
		return MIG_SERVER_DIED;
		else
		return MIG_REPLY_MISMATCH;
	}

#if	TypeCheck
	msgh_size = OutP->Head.msgh_size;
	msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);

	if (((msgh_size != 48) || msgh_simple) &&
	    ((msgh_size != sizeof(mig_reply_header_t)) ||
	     !msgh_simple ||
	     (OutP->RetCode == KERN_SUCCESS)))
		return MIG_TYPE_ERROR;
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->RetCodeType != * (int *) &RetCodeCheck)
#else	UseStaticMsgType
	if ((OutP->RetCodeType.msgt_inline != TRUE) ||
	    (OutP->RetCodeType.msgt_longform != FALSE) ||
	    (OutP->RetCodeType.msgt_name != MACH_MSG_TYPE_INTEGER_32) ||
	    (OutP->RetCodeType.msgt_number != 1) ||
	    (OutP->RetCodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	if (OutP->RetCode != KERN_SUCCESS)
		return OutP->RetCode;

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->realnodeType != * (int *) &realnodeCheck)
#else	UseStaticMsgType
	if ((OutP->realnodeType.msgt_inline != TRUE) ||
	    (OutP->realnodeType.msgt_longform != FALSE) ||
	    (OutP->realnodeType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (OutP->realnodeType.msgt_number != 1) ||
	    (OutP->realnodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	*realnode = OutP->realnode;

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->dotdot_nodeType != * (int *) &dotdot_nodeCheck)
#else	UseStaticMsgType
	if ((OutP->dotdot_nodeType.msgt_inline != TRUE) ||
	    (OutP->dotdot_nodeType.msgt_longform != FALSE) ||
	    (OutP->dotdot_nodeType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (OutP->dotdot_nodeType.msgt_number != 1) ||
	    (OutP->dotdot_nodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	*dotdot_node = OutP->dotdot_node;

	return KERN_SUCCESS;
}

/* Routine fsys_goaway */
mig_external kern_return_t U_fsys_goaway
#if	(defined(__STDC__) || defined(c_plusplus))
(
	fsys_t fsys,
	int flags
)
#else
	(fsys, flags)
	fsys_t fsys;
	int flags;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t flagsType;
		int flags;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
	} Reply;

	union {
		Request In;
		Reply Out;
	} Mess;

	register Request *InP = &Mess.In;
	register Reply *OutP = &Mess.Out;

	mach_msg_return_t msg_result;

#if	UseStaticMsgType
	static mach_msg_type_t flagsType = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t RetCodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	InP->flagsType = flagsType;
#else	UseStaticMsgType
	InP->flagsType.msgt_name = MACH_MSG_TYPE_INTEGER_32;
	InP->flagsType.msgt_size = 32;
	InP->flagsType.msgt_number = 1;
	InP->flagsType.msgt_inline = TRUE;
	InP->flagsType.msgt_longform = FALSE;
	InP->flagsType.msgt_deallocate = FALSE;
	InP->flagsType.msgt_unused = 0;
#endif	UseStaticMsgType

	InP->flags = flags;

	InP->Head.msgh_bits =
		MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = fsys;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_seqno = 0;
	InP->Head.msgh_id = 22001;

	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, sizeof(Request), sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	if (msg_result != MACH_MSG_SUCCESS) {
		if ((msg_result == MACH_SEND_INVALID_REPLY) ||
		    (msg_result == MACH_RCV_INVALID_NAME))
			mig_dealloc_reply_port();
		return msg_result;
	}

	if (OutP->Head.msgh_id != 22101) {
		if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)
		return MIG_SERVER_DIED;
		else
		return MIG_REPLY_MISMATCH;
	}

#if	TypeCheck
	if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) ||
	    (OutP->Head.msgh_size != 32))
		return MIG_TYPE_ERROR;
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->RetCodeType != * (int *) &RetCodeCheck)
#else	UseStaticMsgType
	if ((OutP->RetCodeType.msgt_inline != TRUE) ||
	    (OutP->RetCodeType.msgt_longform != FALSE) ||
	    (OutP->RetCodeType.msgt_name != MACH_MSG_TYPE_INTEGER_32) ||
	    (OutP->RetCodeType.msgt_number != 1) ||
	    (OutP->RetCodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	return OutP->RetCode;
}

/* Routine fsys_getroot */
mig_external kern_return_t U_fsys_getroot
#if	(defined(__STDC__) || defined(c_plusplus))
(
	fsys_t fsys,
	int flags,
	mach_port_t auth_realnode,
	mach_port_t *file
)
#else
	(fsys, flags, auth_realnode, file)
	fsys_t fsys;
	int flags;
	mach_port_t auth_realnode;
	mach_port_t *file;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t flagsType;
		int flags;
		mach_msg_type_t auth_realnodeType;
		mach_port_t auth_realnode;
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t fileType;
		mach_port_t file;
	} Reply;

	union {
		Request In;
		Reply Out;
	} Mess;

	register Request *InP = &Mess.In;
	register Reply *OutP = &Mess.Out;

	mach_msg_return_t msg_result;
#if	TypeCheck
	boolean_t msgh_simple;
#endif	TypeCheck
#if	TypeCheck
	unsigned int msgh_size;
#endif	TypeCheck

#if	UseStaticMsgType
	static mach_msg_type_t flagsType = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t auth_realnodeType = {
		/* msgt_name = */		MACH_MSG_TYPE_MOVE_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t RetCodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t fileCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	InP->flagsType = flagsType;
#else	UseStaticMsgType
	InP->flagsType.msgt_name = MACH_MSG_TYPE_INTEGER_32;
	InP->flagsType.msgt_size = 32;
	InP->flagsType.msgt_number = 1;
	InP->flagsType.msgt_inline = TRUE;
	InP->flagsType.msgt_longform = FALSE;
	InP->flagsType.msgt_deallocate = FALSE;
	InP->flagsType.msgt_unused = 0;
#endif	UseStaticMsgType

	InP->flags = flags;

#if	UseStaticMsgType
	InP->auth_realnodeType = auth_realnodeType;
#else	UseStaticMsgType
	InP->auth_realnodeType.msgt_name = MACH_MSG_TYPE_MOVE_SEND;
	InP->auth_realnodeType.msgt_size = 32;
	InP->auth_realnodeType.msgt_number = 1;
	InP->auth_realnodeType.msgt_inline = TRUE;
	InP->auth_realnodeType.msgt_longform = FALSE;
	InP->auth_realnodeType.msgt_deallocate = FALSE;
	InP->auth_realnodeType.msgt_unused = 0;
#endif	UseStaticMsgType

	InP->auth_realnode = auth_realnode;

	InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX|
		MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = fsys;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_seqno = 0;
	InP->Head.msgh_id = 22002;

	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, sizeof(Request), sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	if (msg_result != MACH_MSG_SUCCESS) {
		if ((msg_result == MACH_SEND_INVALID_REPLY) ||
		    (msg_result == MACH_RCV_INVALID_NAME))
			mig_dealloc_reply_port();
		return msg_result;
	}

	if (OutP->Head.msgh_id != 22102) {
		if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)
		return MIG_SERVER_DIED;
		else
		return MIG_REPLY_MISMATCH;
	}

#if	TypeCheck
	msgh_size = OutP->Head.msgh_size;
	msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);

	if (((msgh_size != 40) || msgh_simple) &&
	    ((msgh_size != sizeof(mig_reply_header_t)) ||
	     !msgh_simple ||
	     (OutP->RetCode == KERN_SUCCESS)))
		return MIG_TYPE_ERROR;
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->RetCodeType != * (int *) &RetCodeCheck)
#else	UseStaticMsgType
	if ((OutP->RetCodeType.msgt_inline != TRUE) ||
	    (OutP->RetCodeType.msgt_longform != FALSE) ||
	    (OutP->RetCodeType.msgt_name != MACH_MSG_TYPE_INTEGER_32) ||
	    (OutP->RetCodeType.msgt_number != 1) ||
	    (OutP->RetCodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	if (OutP->RetCode != KERN_SUCCESS)
		return OutP->RetCode;

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->fileType != * (int *) &fileCheck)
#else	UseStaticMsgType
	if ((OutP->fileType.msgt_inline != TRUE) ||
	    (OutP->fileType.msgt_longform != FALSE) ||
	    (OutP->fileType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (OutP->fileType.msgt_number != 1) ||
	    (OutP->fileType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	*file = OutP->file;

	return KERN_SUCCESS;
}

/* Routine fsys_getfile */
mig_external kern_return_t U_fsys_getfile
#if	(defined(__STDC__) || defined(c_plusplus))
(
	fsys_t fsys,
	idarray_t uids,
	mach_msg_type_number_t uidsCnt,
	idarray_t gids,
	mach_msg_type_number_t gidsCnt,
	data_t filehandle,
	mach_msg_type_number_t filehandleCnt,
	file_t *file
)
#else
	(fsys, uids, uidsCnt, gids, gidsCnt, filehandle, filehandleCnt, file)
	fsys_t fsys;
	idarray_t uids;
	mach_msg_type_number_t uidsCnt;
	idarray_t gids;
	mach_msg_type_number_t gidsCnt;
	data_t filehandle;
	mach_msg_type_number_t filehandleCnt;
	file_t *file;
#endif
{
	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_long_t uidsType;
		uid_t uids[512];
		mach_msg_type_long_t gidsType;
		uid_t gids[512];
		mach_msg_type_long_t filehandleType;
		char filehandle[2048];
	} Request;

	typedef struct {
		mach_msg_header_t Head;
		mach_msg_type_t RetCodeType;
		kern_return_t RetCode;
		mach_msg_type_t fileType;
		file_t file;
	} Reply;

	union {
		Request In;
		Reply Out;
	} Mess;

	register Request *InP = &Mess.In;
	register Reply *OutP = &Mess.Out;

	mach_msg_return_t msg_result;
	boolean_t msgh_simple = TRUE;
	unsigned int msgh_size;
	unsigned int msgh_size_delta;

#if	UseStaticMsgType
	static mach_msg_type_long_t uidsType = {
	{
		/* msgt_name = */		0,
		/* msgt_size = */		0,
		/* msgt_number = */		0,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		TRUE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	},
		/* msgtl_name = */	MACH_MSG_TYPE_INTEGER_32,
		/* msgtl_size = */	32,
		/* msgtl_number = */	512,
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_long_t gidsType = {
	{
		/* msgt_name = */		0,
		/* msgt_size = */		0,
		/* msgt_number = */		0,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		TRUE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	},
		/* msgtl_name = */	MACH_MSG_TYPE_INTEGER_32,
		/* msgtl_size = */	32,
		/* msgtl_number = */	512,
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_long_t filehandleType = {
	{
		/* msgt_name = */		0,
		/* msgt_size = */		0,
		/* msgt_number = */		0,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		TRUE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	},
		/* msgtl_name = */	MACH_MSG_TYPE_CHAR,
		/* msgtl_size = */	8,
		/* msgtl_number = */	2048,
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t RetCodeCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_INTEGER_32,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	static mach_msg_type_t fileCheck = {
		/* msgt_name = */		MACH_MSG_TYPE_PORT_SEND,
		/* msgt_size = */		32,
		/* msgt_number = */		1,
		/* msgt_inline = */		TRUE,
		/* msgt_longform = */		FALSE,
		/* msgt_deallocate = */		FALSE,
		/* msgt_unused = */		0
	};
#endif	UseStaticMsgType

#if	UseStaticMsgType
	InP->uidsType = uidsType;
#else	UseStaticMsgType
	InP->uidsType.msgtl_name = MACH_MSG_TYPE_INTEGER_32;
	InP->uidsType.msgtl_size = 32;
	InP->uidsType.msgtl_header.msgt_name = 0;
	InP->uidsType.msgtl_header.msgt_size = 0;
	InP->uidsType.msgtl_header.msgt_number = 0;
	InP->uidsType.msgtl_header.msgt_inline = TRUE;
	InP->uidsType.msgtl_header.msgt_longform = TRUE;
	InP->uidsType.msgtl_header.msgt_deallocate = FALSE;
	InP->uidsType.msgtl_header.msgt_unused = 0;
#endif	UseStaticMsgType

	if (uidsCnt > 512) {
		InP->uidsType.msgtl_header.msgt_inline = FALSE;
		*((uid_t **)InP->uids) = uids;
		msgh_simple = FALSE;
	}
	else {
		bcopy((char *) uids, (char *) InP->uids, 4 * uidsCnt);
	}

	InP->uidsType.msgtl_number = uidsCnt;

	msgh_size_delta = (InP->uidsType.msgtl_header.msgt_inline) ? 4 * uidsCnt : sizeof(uid_t *);
	msgh_size = 60 + msgh_size_delta;
	InP = (Request *) ((char *) InP + msgh_size_delta - 2048);
#if	UseStaticMsgType
	InP->gidsType = gidsType;
#else	UseStaticMsgType
	InP->gidsType.msgtl_name = MACH_MSG_TYPE_INTEGER_32;
	InP->gidsType.msgtl_size = 32;
	InP->gidsType.msgtl_header.msgt_name = 0;
	InP->gidsType.msgtl_header.msgt_size = 0;
	InP->gidsType.msgtl_header.msgt_number = 0;
	InP->gidsType.msgtl_header.msgt_inline = TRUE;
	InP->gidsType.msgtl_header.msgt_longform = TRUE;
	InP->gidsType.msgtl_header.msgt_deallocate = FALSE;
	InP->gidsType.msgtl_header.msgt_unused = 0;
#endif	UseStaticMsgType

	if (gidsCnt > 512) {
		InP->gidsType.msgtl_header.msgt_inline = FALSE;
		*((uid_t **)InP->gids) = gids;
		msgh_simple = FALSE;
	}
	else {
		bcopy((char *) gids, (char *) InP->gids, 4 * gidsCnt);
	}

	InP->gidsType.msgtl_number = gidsCnt;

	msgh_size_delta = (InP->gidsType.msgtl_header.msgt_inline) ? 4 * gidsCnt : sizeof(uid_t *);
	msgh_size += msgh_size_delta;
	InP = (Request *) ((char *) InP + msgh_size_delta - 2048);
#if	UseStaticMsgType
	InP->filehandleType = filehandleType;
#else	UseStaticMsgType
	InP->filehandleType.msgtl_name = MACH_MSG_TYPE_CHAR;
	InP->filehandleType.msgtl_size = 8;
	InP->filehandleType.msgtl_header.msgt_name = 0;
	InP->filehandleType.msgtl_header.msgt_size = 0;
	InP->filehandleType.msgtl_header.msgt_number = 0;
	InP->filehandleType.msgtl_header.msgt_inline = TRUE;
	InP->filehandleType.msgtl_header.msgt_longform = TRUE;
	InP->filehandleType.msgtl_header.msgt_deallocate = FALSE;
	InP->filehandleType.msgtl_header.msgt_unused = 0;
#endif	UseStaticMsgType

	if (filehandleCnt > 2048) {
		InP->filehandleType.msgtl_header.msgt_inline = FALSE;
		*((char **)InP->filehandle) = filehandle;
		msgh_simple = FALSE;
	}
	else {
		bcopy((char *) filehandle, (char *) InP->filehandle, filehandleCnt);
	}

	InP->filehandleType.msgtl_number = filehandleCnt;

	msgh_size += (InP->filehandleType.msgtl_header.msgt_inline) ? filehandleCnt + 3 & ~3 : sizeof(char *);
	InP = &Mess.In;
	InP->Head.msgh_bits = msgh_simple ?
		MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE) :
		(MACH_MSGH_BITS_COMPLEX|
		 MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE));
	/* msgh_size passed as argument */
	InP->Head.msgh_request_port = fsys;
	InP->Head.msgh_reply_port = mig_get_reply_port();
	InP->Head.msgh_seqno = 0;
	InP->Head.msgh_id = 22003;

	msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
	if (msg_result != MACH_MSG_SUCCESS) {
		if ((msg_result == MACH_SEND_INVALID_REPLY) ||
		    (msg_result == MACH_RCV_INVALID_NAME))
			mig_dealloc_reply_port();
		return msg_result;
	}

	if (OutP->Head.msgh_id != 22103) {
		if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE)
		return MIG_SERVER_DIED;
		else
		return MIG_REPLY_MISMATCH;
	}

#if	TypeCheck
	msgh_size = OutP->Head.msgh_size;
	msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);

	if (((msgh_size != 40) || msgh_simple) &&
	    ((msgh_size != sizeof(mig_reply_header_t)) ||
	     !msgh_simple ||
	     (OutP->RetCode == KERN_SUCCESS)))
		return MIG_TYPE_ERROR;
#endif	TypeCheck

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->RetCodeType != * (int *) &RetCodeCheck)
#else	UseStaticMsgType
	if ((OutP->RetCodeType.msgt_inline != TRUE) ||
	    (OutP->RetCodeType.msgt_longform != FALSE) ||
	    (OutP->RetCodeType.msgt_name != MACH_MSG_TYPE_INTEGER_32) ||
	    (OutP->RetCodeType.msgt_number != 1) ||
	    (OutP->RetCodeType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	if (OutP->RetCode != KERN_SUCCESS)
		return OutP->RetCode;

#if	TypeCheck
#if	UseStaticMsgType
	if (* (int *) &OutP->fileType != * (int *) &fileCheck)
#else	UseStaticMsgType
	if ((OutP->fileType.msgt_inline != TRUE) ||
	    (OutP->fileType.msgt_longform != FALSE) ||
	    (OutP->fileType.msgt_name != MACH_MSG_TYPE_PORT_SEND) ||
	    (OutP->fileType.msgt_number != 1) ||
	    (OutP->fileType.msgt_size != 32))
#endif	UseStaticMsgType
		return MIG_TYPE_ERROR;
#endif	TypeCheck

	*file = OutP->file;

	return KERN_SUCCESS;
}
