/*
 * ShufflerProtocol.c
 * $Id: ShufflerProtocol.c,v 1.2 1996/04/30 21:48:03 abaird Exp $
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <errno.h>

extern int errno ;

#include "ShufflerProtocol.h"

/*
 * Receive a message.
 * Receive the given message from the given client. 
 * Returns:
 *     <0 : in case of errors,
 *     sz : siz eof receive message.
 * This function assumes that only <em>one</em> thread receives and send 
 * messages.
 */

int ShufflerGetNextMessage (int fd, ShufflerMessage msg) {
    struct msghdr rmsg ;
    struct iovec  iov[1] ;
    int got = - 1 ;

    iov[0].iov_base      = (char *) &(msg->msg) ;
    iov[0].iov_len       = sizeof (msg->msg) ;
    rmsg.msg_name         = NULL ;
    rmsg.msg_namelen      = 0 ;
    rmsg.msg_iov          = iov ;
    rmsg.msg_iovlen       = 1 ;
    rmsg.msg_accrights    = (caddr_t) &(msg->fds[0]) ;
    rmsg.msg_accrightslen = sizeof (msg->fds) ;
  retry:
    if ( (got = recvmsg (fd, &rmsg, 0)) <= 0 ) {
	if ( errno == EINTR )
	    goto retry ;
	return (errno != 0) ? -errno : -1 ;
    }
    return got ;
}

/*
 * Send a message.
 * Send the given message to the given client. 
 * Returns:
 *     <0 : in case of errors,
 *     sz : number of bytes sent.
 * This function assumes that only <em>one</em> thread receives and send 
 * messages.
 */


int ShufflerSendMessage (int fd, ShufflerMessage msg) {
    struct msghdr smsg ;
    struct iovec  iov[1] ;

    iov[0].iov_base       = (char *) &(msg->msg) ;
    iov[0].iov_len        = sizeof(msg->msg) ;
    smsg.msg_name         = NULL ;
    smsg.msg_namelen      = 0 ;
    smsg.msg_iov          = iov ;
    smsg.msg_iovlen       = 1 ;
    if ( msg->msg.op & SHUFFLER_FLAG_HASFD ) {
	smsg.msg_accrights    = (caddr_t) &(msg->fds) ;
	smsg.msg_accrightslen = sizeof (msg->fds) ;
    } else {
	smsg.msg_accrights    = (caddr_t) NULL ;
	smsg.msg_accrightslen = 0 ;
    }	
    return sendmsg (fd, &smsg, 0) ;
}

