/*-
 * swap.c --
 *	Remote Procedure Call byte-swapping functions
 *
 * Copyright (c) 1988, 1989 by the Regents of the University of California
 * Copyright (c) 1988, 1989 by Adam de Boor
 * Copyright (c) 1989 by Berkeley Softworks
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any non-commercial purpose
 * and without fee is hereby granted, provided that the above copyright
 * notice appears in all copies.  The University of California,
 * Berkeley Softworks and Adam de Boor make no representations about
 * the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 */
#ifndef lint
static char *rcsid =
"$Id: swap.c,v 1.37 2000/09/12 07:24:09 stolcke Exp $ ICSI (Berkeley)";
#endif /* not lint */

#include    <string.h>

#include    "customsInt.h"

/*-
 *-----------------------------------------------------------------------
 * Swap_Timeval --
 *	Swap the two elements of a Time_Interval
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	The elements are swapped.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Timeval (len, data)
    int	    	  	len;
    Time_Interval	*data;
{
    Rpc_SwapLong(sizeof(data->tv_sec), &data->tv_sec);
    Rpc_SwapLong(sizeof(data->tv_usec), &data->tv_usec);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Avail --
 *	Byte-swap all fields of an Avail_Data structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Avail (len, data)
    int	    	  len;
    Avail_Data	  *data;
{
    Rpc_SwapLong(sizeof(data->changeMask), &data->changeMask);
    Rpc_SwapLong(sizeof(data->localJobs), &data->localJobs);
    Rpc_SwapLong(sizeof(data->idleTime), &data->idleTime);
    Rpc_SwapLong(sizeof(data->idleCrit), &data->idleCrit);
    Rpc_SwapLong(sizeof(data->swapPct), &data->swapPct);
    Rpc_SwapLong(sizeof(data->loadAvg), &data->loadAvg);
    Rpc_SwapLong(sizeof(data->imports), &data->imports);
    Rpc_SwapLong(sizeof(data->procs), &data->procs);
    Rpc_SwapLong(sizeof(data->cpuLimit), &data->cpuLimit);
    Rpc_SwapLong(sizeof(data->memLimit), &data->memLimit);
    Rpc_SwapLong(sizeof(data->checkUser), &data->checkUser);
    Rpc_SwapLong(sizeof(data->niceLevel), &data->niceLevel);
    Rpc_SwapLong(sizeof(data->evictDelay), &data->evictDelay);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_AllocReply --
 *	Byte-swap an AllocReply structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_AllocReply (len, data)
    int	    	  len;
    AllocReply	  *data;
{
    Rpc_SwapLong(sizeof(data->avail), &data->avail);
    Rpc_SwapLong(sizeof(data->rating), &data->rating);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Host --
 *	Byte-swap a Host_Data structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Host (len, data)
    int	    	  len;
    Host_Data	  *data;
{
    Rpc_SwapShort(sizeof(data->uid), &data->uid);
    Rpc_SwapShort(sizeof(data->flags), &data->flags);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_ExportPermit --
 *	Byte-swap an ExportPermit structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_ExportPermit (len, data)
    int	    	  len;
    ExportPermit  *data;
{
    /*
     * Don't swap address -- is kept in network byte order all along.
     */
    Rpc_SwapLong(sizeof(data->id), &data->id);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_AllocData --
 *	Byte-swap an AllocData structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_AllocData (len, data)
    int	    	  len;
    AllocData     *data;
{
    Swap_ExportPermit(sizeof(data->permit), &data->permit);
    Rpc_SwapLong(sizeof(data->flags), &data->flags);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_WayBill --
 *	Swap a WayBill structure and its associated data.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_WayBill (len, data)
    int	    	  len;
    WayBill 	  *data;
{
    register char *cp;
    register int  i;
    register Rpc_Long *lp;

    Rpc_SwapLong(sizeof(data->id), &data->id);
    /*
     * Don't swap port number -- is kept in network byte order all along.
     */
    Rpc_SwapLong(sizeof(data->deadline), &data->deadline);
    Rpc_SwapShort(sizeof(data->ruid), &data->ruid);
    Rpc_SwapShort(sizeof(data->euid), &data->euid);
    Rpc_SwapShort(sizeof(data->rgid), &data->rgid);
    Rpc_SwapShort(sizeof(data->egid ), &data->egid);
    Rpc_SwapLong(sizeof(data->umask), &data->umask);
    Rpc_SwapLong(sizeof(data->ngroups), &data->ngroups);
    for (i = data->ngroups, lp = data->groups; i >= 0; i--, lp++) {
	Rpc_SwapLong(sizeof(*lp), lp);
    }
    Rpc_SwapLong(sizeof(data->priority), &data->priority);
    for (i = 0; i < 2*MAX_NUM_RLIMITS; i++) {
	Rpc_SwapLong(sizeof(data->rlimits[i]), &data->rlimits[i]);
    }
    /*
     * Skip the cwd and the file to execute
     */
    cp = (char *)&data[1];
    cp += strlen(cp) + 1;
    cp += strlen(cp) + 1;
    lp = Customs_Align(cp, Rpc_Long *);
    /*
     * Swap the number of arguments
     */
    Rpc_SwapLong(sizeof(*lp), lp);
    for (cp = (char *)&lp[1], i = *lp; i > 0; i--) {
	cp += strlen(cp) + 1;
    }

    /*
     * Swap the number of environment variables
     */
    lp = Customs_Align(cp, Rpc_Long *);
    Rpc_SwapLong(sizeof(*lp), lp);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Kill --
 *	Byte-swap a Kill_Data structure.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Kill (len, data)
    int	    	  len;
    Kill_Data	  *data;
{
    Rpc_SwapLong(sizeof(data->id), &data->id);
    Rpc_SwapLong(sizeof(data->signal), &data->signal);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_RegPacket --
 *
 * Results:
 *
 * Side Effects:
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_RegPacket (len, data)
    int	    	  len;
    char    	  *data;
{
    register Rpc_Long *lp;

    /*
     * The format of a reg packet is
     *		<hostname>\0+<arch>\
     *		<client-1>\0<client-2>\0...<client-n>\0\0\
     *		<attr-1>\0<attr-2>\0...<attr-m>\0\0
     * so skip the hostname and swap only the architecture code.
     */
    lp = Customs_Align(data + strlen(data)+1, Rpc_Long *);
    Rpc_SwapLong(sizeof(*lp), lp);  /* Machine architecture */
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Info --
 *
 * Results:
 *
 * Side Effects:
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Info (len, data)
    int	    	  len;
    register char *data;
{
    register int  i, j;

    Rpc_SwapLong(sizeof(Rpc_Long), data);
    data += sizeof(Rpc_Long);

    /*
     * Get number of hosts in i first, then swap it.
     */
    i = *(int *)data;
    Rpc_SwapLong(sizeof(int), data);
    data += sizeof(int);

    while (i > 0) {
	data += strlen(data) + 1;		/* skip host name */
	while (*data) {
	    data += strlen(data) + 1;		/* skip attributes */
	}
	data++;					/* null byte */
	data = Customs_Align(data, char *);
	Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data); /* Availability */
	data += sizeof(Rpc_Long);
	Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data); /* Rating */
	data += sizeof(Rpc_Long);
	Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data); /* Architecture */
	data += sizeof(Rpc_Long);
	j = *(Rpc_Long *)data;
	Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data); /* No. of clients */
	data += sizeof(Rpc_Long);

	while (j > 0) {
	    Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data);
	    data += sizeof(Rpc_Long);
	    j--;
	}
	i--;
    }
    Rpc_SwapLong(sizeof(Rpc_Long), (Rpc_Long *)data);	/* Last Allocated */
}

/*-
 *-----------------------------------------------------------------------
 * Swap_AvailInt --
 *	Byte-swap an internal Avail packet.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_AvailInt (len, data)
    int	    	  len;
    Avail	  *data;
{
    /*
     * Don't swap address -- is kept in network byte order all along.
     */
    Swap_Timeval(sizeof(data->interval), &data->interval);
    Rpc_SwapLong(sizeof(data->avail), &data->avail);
    Rpc_SwapLong(sizeof(data->rating), &data->rating);
    Rpc_SwapLong(sizeof(data->clock), &data->clock);
    Rpc_SwapLong(sizeof(data->nJobs), &data->nJobs);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Version --
 *	Byte-swap a version info packet
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Version (len, data)
    int	    	  len;
    Version_Data   *data;
{
    Rpc_SwapShort(sizeof(data->majorversion), &data->majorversion);
    Rpc_SwapShort(sizeof(data->minorversion), &data->minorversion);
    Rpc_SwapShort(sizeof(data->patchlevel), &data->patchlevel);
    Rpc_SwapShort(sizeof(data->buildno), &data->buildno);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Jobs --
 *	Byte-swap a job info list.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Jobs (len, data)
    int	    	  len;
    Job_Info	  *data;
{
    int		  numJobs;
    register int  j;

    numJobs = len / sizeof(Job_Info);

    for (j = 0; j < numJobs; j++) {
	Rpc_SwapLong(sizeof(data[j].pid), &data[j].pid);
	Rpc_SwapLong(sizeof(data[j].id), &data[j].id);
	Rpc_SwapLong(sizeof(data[j].time), &data[j].time);
	Rpc_SwapShort(sizeof(data[j].uid), &data[j].uid);
	/*
	 * Don't swap port and address -- are kept in network byte order
	 * throughout.
	 */
    }
}

/*-
 *-----------------------------------------------------------------------
 * Swap_Stats --
 *	Byte-swap jobs statistics.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_Stats (len, data)
    int	    	  len;
    Job_Stats	  *data;
{
    Rpc_SwapLong(sizeof(data->start), &data->start);
    Rpc_SwapLong(sizeof(data->jobs), &data->jobs);
    Rpc_SwapLong(sizeof(data->evictions), &data->evictions);
    Rpc_SwapLong(sizeof(data->signals), &data->signals);
    Rpc_SwapLong(sizeof(data->realTime), &data->realTime);
    Rpc_SwapLong(sizeof(data->userTime), &data->userTime);
    Rpc_SwapLong(sizeof(data->sysTime), &data->sysTime);
    Rpc_SwapLong(sizeof(data->avail), &data->avail);
    Rpc_SwapLong(sizeof(data->availChecks), &data->availChecks);
}

/*-
 *-----------------------------------------------------------------------
 * Swap_SockAddr --
 *	Byte-swap a internet socket address
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	Ditto.
 *
 *-----------------------------------------------------------------------
 */
/*ARGSUSED*/
void
Swap_SockAddr (len, data)
    int	    	  len;
    SockAddr	  *data;
{
    Rpc_SwapShort(sizeof(data->family), &data->family);

    /*
     * Don't swap port and address -- are kept in network byte order
     * throughout.
     */
}

