/*
 *	Network Queueing System (NQS)
 *  This version of NQS is Copyright (C) 1992  John Roman
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 1, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*
*  PROJECT:     Network Queueing System
*  AUTHOR:      John Roman
*
*  Modification history:
*
*       Version Who     When            Description
*       -------+-------+---------------+-------------------------
*       V01.10  JRR                     Initial version.
*       V01.20  JRR     12-Feb-1992	Fixed static routine calls.
*	V01.3	JRR	17-Jun-1992	Added header.
*	V01.4	JRR	23-Nov-1992	Modified for C prototypes
*/
/*++ verifyreq.c - Network Queueing System
 *
 * $Source: /usr2/jrroma/nqs/nqs-3.30/lib/RCS/verifyreq.c,v $
 *
 * DESCRIPTION:
 *
 *	Verify a rawreq structure.
 *
 *
 *	Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	March 28, 1986.
 *
 *
 * STANDARDS VIOLATIONS:
 *   None.
 *
 * REVISION HISTORY: ($Revision: 1.4 $ $Date: 1992/12/22 15:46:37 $ $State: Exp $)
 * $Log: verifyreq.c,v $
 * Revision 1.4  1992/12/22  15:46:37  jrroma
 * Version 3.30
 *
 * Revision 1.3  92/06/18  13:25:01  jrroma
 * Added gnu header
 * 
 * Revision 1.2  92/02/12  11:15:03  jrroma
 * Fixed static routine calls.
 * 
 * Revision 1.1  92/02/12  11:12:14  jrroma
 * Initial revision
 * 
 *
 */

#include "nqs.h"

#ifndef __CEXTRACT__
#if __STDC__

static int vfycpulim ( struct cpulimit *cpulimit );
static int vfyquolim ( struct quotalimit *quota );

#else /* __STDC__ */

static int vfycpulim (/* struct cpulimit *cpulimit */);
static int vfyquolim (/* struct quotalimit *quota */);

#endif /* __STDC__ */
#endif /* __CEXTRACT__ */

/*** verifyreq
 *
 *
 *	int verifyreq():
 *	Verify a rawreq structure.
 *
 *	Returns:
 *		0: if the rawreq structure is valid.
 *	       -1: otherwise.
 */
int verifyreq (struct rawreq *rawreq)
{
	register int i;			/* Loop index var */

	if (verifyhdr (rawreq) == -1) {
		/*
		 *  There is something wrong in the common part
		 *  of the rawreq structure.
		 */
		return (-1);
	}
	if (rawreq->type == RTYPE_DEVICE) {
		/*
		 *  The request is a device-oriented request.
		 */
		if (rawreq->v.dev.forms [MAX_FORMNAME] != '\0' ||
		    rawreq->v.dev.reserved1 != 0 ||
		    rawreq->v.dev.reserved2 != 0 ||
		    rawreq->v.dev.copies < 0 ||
		    rawreq->v.dev.copies > MAX_COPIES) {
			/*
			 *  Values out of bounds.
			 */
			return (-1);
		}
		/*
		 *  Verify device preference list.
		 */
		for (i = 0; i < MAX_DEVPREF; i++) {
			if (rawreq->v.dev.devprefname [i][MAX_DEVNAME]!='\0') {
				/*
				 *  Device preference name is NOT null
				 *  terminated.
				 */
				return (-1);
			}
		}
	}
	else {
		/*
		 *  The request is not device-oriented.
		 *  Verify quota limits and CPU requirements.
		 *  The following conditional is broken up to
		 *  be kind to little compilers.
		 */
		if (vfyquolim (&rawreq->v.bat.ppcoresize) == -1 ||
		    vfyquolim (&rawreq->v.bat.ppdatasize) == -1 ||
		    vfyquolim (&rawreq->v.bat.pppfilesize) == -1 ||
		    vfyquolim (&rawreq->v.bat.prpfilespace) == -1 ||
		    vfyquolim (&rawreq->v.bat.ppqfilesize) == -1 ||
		    vfyquolim (&rawreq->v.bat.prqfilespace) == -1 ||
		    vfyquolim (&rawreq->v.bat.pptfilesize) == -1 ||
		    vfyquolim (&rawreq->v.bat.prtfilespace) == -1 ||
		    vfyquolim (&rawreq->v.bat.ppmemsize) == -1) {
			/*
			 *  Values out of bounds.
			 */
			return (-1);
		}
		if (vfyquolim (&rawreq->v.bat.prmemsize) == -1 ||
		    vfyquolim (&rawreq->v.bat.ppstacksize) == -1 ||
		    vfycpulim (&rawreq->v.bat.ppcputime) == -1 ||
		    vfycpulim (&rawreq->v.bat.prcputime) == -1 ||
		    vfyquolim (&rawreq->v.bat.ppworkset) == -1 ||
		    rawreq->v.bat.ppnice < MIN_REQNICE ||
		    rawreq->v.bat.ppnice > MAX_REQNICE ||
		    rawreq->v.bat.prdrives < 0 ||
		    rawreq->v.bat.prncpus < 0) {
			/*
			 *  Values out of bounds.
			 */
			return (-1);
		}
		/*
		 *  Verify predecessor list.
		 */
		for (i = 0; i < MAX_PREDECESSOR; i++) {
			if (rawreq->v.bat.predecessors[i][MAX_REQNAME]!='\0') {
				/*
				 *  Predecessor name is NOT null terminated.
				 */
				return (-1);
			}
		}
		/*
		 *  Verify everything else.
		 */
		if (rawreq->v.bat.shell_name [MAX_SHELLNAME] != '\0' ||
		    rawreq->v.bat.stderr_name [MAX_REQPATH] != '\0' ||
		    rawreq->v.bat.stdlog_name [MAX_REQPATH] != '\0' ||
		    rawreq->v.bat.stdout_name [MAX_REQPATH] != '\0' ||
		    rawreq->v.bat.instacount < 0 ||
		    rawreq->v.bat.instacount > MAX_INSTAPERREQ ||
		    rawreq->v.bat.oustacount < 0 ||
		    rawreq->v.bat.oustacount > MAX_OUSTAPERREQ) {
			/*
			 *  Values out of bounds.
			 */
			return (-1);
		}
	}
	return (0);			/* Rawreq checks out */
}


/*** vfyquolim
 *
 *
 *	int vfyquolim():
 *	Verify a quota limit.
 *
 *	Returns:
 *		0: if the specified quota limit was ok.
 *	       -1: if the quota limit was corrupt.
 */
static int vfyquolim (struct quotalimit *quota)
{
	switch (quota->max_units) {
	case QLM_BYTES:
	case QLM_WORDS:
	case QLM_KBYTES:
	case QLM_KWORDS:
	case QLM_MBYTES:
	case QLM_MWORDS:
	case QLM_GBYTES:
	case QLM_GWORDS:
		switch (quota->warn_units) {
		case QLM_BYTES:
		case QLM_WORDS:
		case QLM_KBYTES:
		case QLM_KWORDS:
		case QLM_MBYTES:
		case QLM_MWORDS:
		case QLM_GBYTES:
		case QLM_GWORDS:
			if (quota->max_quota <= 2147483647 &&
			    quota->warn_quota <= 2147483647) {
				/*
				 *  Quota limit coefficients are limited
				 *  to values in the range [0..2^31-1].
				 */
				if (!secgrfir (quota->max_quota,
					       quota->max_units,
					       quota->warn_quota,
					       quota->warn_units)) {
					/*
					 *  The warn limit values must
					 *  be <= the maximum limit value.
					 */
					return (0);	/* Valid limit */
				}
			}
		}
	}
	return (-1);			/* Bad quota limit */
}


/*** vfycpulim
 *
 *
 *	int vfycpulim():
 *	Verify a CPU time limit.
 *
 *	Returns:
 *		0: if the specified CPU time limit was ok.
 *	       -1: if the CPU time limit was corrupt.
 */
static int vfycpulim (struct cpulimit *cpulimit)
{
	if (cpulimit->max_ms >= 0 &&
	    cpulimit->max_ms <= 999 &&
	    cpulimit->warn_ms >= 0 &&
	    cpulimit->warn_ms <= 999 &&
	   (cpulimit->max_seconds > cpulimit->warn_seconds ||
	   (cpulimit->max_seconds == cpulimit->warn_seconds &&
	    cpulimit->max_ms >= cpulimit->warn_ms))) {
		/*
		 *  Valid CPU time limit.
		 */
		return (0);
	}
	return (-1);			/* Bad CPU limit */
}
