/*
 *	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     16-Jan-1992	Added support for RS6000.
*       V01.3   JRR     12-Feb-1992	Fixed declaration of static routines.
*       V01.4   JRR     02-Mar-1992	Added Cosmic V2 changes.
*       V01.5   JRR     03-Mar-1992	mid_t is now Mid_t.
*       V01.6   JRR     18-Mar-1992	Fix up MODREQ.
*       V01.7   JRR     23-Mar-1992	Add suspend / resume processing.
*       V01.8   JRR     08-Apr-1992     Add CERN enhancements.
*                       16-Apr-1992     Added complex user limits.
*	V01.9	JRR	17-Jun-1992	Added header.
*	V01.10	JRR	24-Aug-1992	Added memdump.
*			21-Aug-1992	Added load & rreqcom.
*			19-Nov-1992	Added more load packets.
*	V01.10 (also)   26-Feb-1992	Added Boeing enhancement for Mids.
*	V01.11	JRR	18-Aug-1993	Everyone likes plock.
*					Fixes from Ryoichi Shibano
*					(shibano@bsd2.kbnes.nec.co.jp)
*	V01.12	JRR	21-Oct-1993	Added alterreq.
*	V01.13	JRR	28-Feb-1994	Added support for SOLARIS.
*	V01.14	JRR	07-Apr-1994	Ranking compute servers.
*/
/*++ nqs_main.c - Network Queueing System
 *
 * $Source: /usr2/jrroma/nqs/nqs-3.36/src/RCS/nqs_main.c,v $
 *
 * DESCRIPTION:
 *
 *
 *	This module is the main NQS module and processes requests from
 *	NQS client processes.
 *
 *
 *	This module accepts the request packet types:
 *
 *		PKT_ABOQUE:
 *			Abort all running reqs in the named queue.
 *		PKT_ADDFOR:
 *			Add a form to the NQS forms list.
 *		PKT_ADDNQSMAN:
 *			Add an account to the NQS manager account
 *			access list.
 *              PKT_ADDQUECOM:
 *                      Add a queue to a queue complex.
 *		PKT_ADDQUEDES:
 *			Add a pipe queue destination for the named
 *			queue.
 *		PKT_ADDQUEDEV:
 *			Add a queue/device mapping.
 *		PKT_ADDQUEGID:
 *			Add a gid to the access list for a queue.
 *		PKT_ADDQUEUID:
 *			Add a uid to the access list for a queue.
 *		PKT_CREDEV:
 *			Create a new device.
 *		PKT_CREBATQUE:
 *			Create a new batch queue.
 *              PKT_CRECOM:
 *                      Create a queue complex.
 *		PKT_CREDEVQUE:
 *			Create a new device queue.
 *		PKT_CREPIPQUE:
 *			Create a new pipe queue.
 *              PKT_DELCOM:
 *                      Delete a queue complex.
 *		PKT_DELDEV:
 *			Delete a device.
 *		PKT_DELFOR:
 *			Delete a form from the NQS forms list.
 *		PKT_DELNQSMAN:
 *			Delete an account from the NQS manager
 *			account access list.
 *		PKT_DELQUE:
 *			Delete a queue.
 *		PKT_DELQUEDES:
 *			Delete a destination for the named queue.
 *		PKT_DELQUEDEV:
 *			Delete a queue/device mapping.
 *		PKT_DELQUEGID:
 *			Delete a gid from the access list for a queue.
 *		PKT_DELQUEUID:
 *			Delete a uid from the access list for a queue.
 *		PKT_DELREQ:
 *			Delete the specified request.
 *		PKT_DISDEV:
 *			Disable a device.
 *		PKT_DISQUE:
 *			Disable a queue.
 *		PKT_ENADEV:
 *			Enable a device.
 *		PKT_ENAQUE:
 *			Enable a queue.
 *		PKT_FAMILY:
 *			Receive "process-family" of req server
 *			report.
 *		PKT_LOCDAE:
 *			Lock the NQS daemon in memory.  Make the NQS
 *			daemon immune to swapping.
 *		PKT_MODREQ:
 *			Modify queued req parameters.
 *              PKT_MOVQUE:
 *                      Move all requests on a queue to another queue.
 *		PKT_MOVREQ:
 *			Move request between local queues.
 *		PKT_PURQUE:
 *			Purge queued and waiting reqs from a queue.
 *		PKT_QUEREQ:
 *			Queue a new request.
 *		PKT_QUEREQVLPQ:
 *			Queue a request via a local pipe queue.
 *              PKT_REMQUECOM:
 *                      Remove a queue from a queue complex.
 *		PKT_REQCOM:
 *			An NQS request has completed execution.
 *		PKT_RMTACCEPT:
 *			Remote destination has tentatively accepted
 *			the request.
 *		PKT_RMTARRIVE:
 *			The specified request previously queued in
 *			the pre-arrive state is now in the arriving
 *			state.
 *		PKT_RMTDEPART:
 *			Remote destination has committed the request
 *			for arrival.
 *		PKT_RMTENADES:
 *			Enable a pipe queue destination.
 *		PKT_RMTENAMAC:
 *			Enable a remote machine.
 *		PKT_RMTFAIDES:
 *			Mark a pipe queue destination as failed.
 *		PKT_RMTFAIMAC:
 *			Mark a remote machine as failed.
 *		PKT_RMTQUEREQ:
 *			Queue an NQS request via a remote pipe queue.
 *		PKT_RMTRECEIVED:
 *			The specified request that was previously in
 *			the arriving state has been completely received
 *			on the local machine.
 *		PKT_RMTSCHDES:
 *			Schedule a pipe-queue destination for retry.
 *		PKT_RMTSCHMAC:
 *			Schedule a machine destination for retry.
 *		PKT_RMTSTASIS:
 *			Request is no longer in the pre-depart state.
 *		PKT_SCHEDULEREQ:
 *			Schedule a request for later retry.
 *		PKT_SENSEDAEMON:
 *			Not handled by this module.
 *              PKT_SETCOMLIM:
 *                      Set a queue complex run limit.
 *              PKT_SETCOMUSERLIM:
 *                      Set a queue complex user run limit.
 *		PKT_SETDEB:
 *			Set the debug level.
 *		PKT_SETDEFBATPR:
 *			Set the default intra-queue batch-req priority.
 *		PKT_SETDEFBATQU:
 *			Set the default batch queue.
 *		PKT_SETDEFDESTI
 *			Set default maximum amount of time that a
 *			destination is allowed to be in the retry
 *			state before being marked as failed.
 *		PKT_SETDEFDESWA:
 *			Set the default number of seconds to wait before
 *			retrying failed destinations.
 *		PKT_SETDEFDEVPR:
 *			Set the default intra-queue device-req priority.
 *		PKT_SETDEFPRIFO:
 *			Set the default print forms.
 *		PKT_SETDEFPRIQU:
 *			Set the default print queue.
 *		PKT_SETDEVFOR:
 *			Set the device forms in the specified device.
 *		PKT_SETDEVSER:
 *			Set the device server and arguments for the
 *			specified device.
 *		PKT_SETFOR:
 *			Set the NQS forms list to the single specified
 *			form.
 *		PKT_SETLIFE:
 *			Set the lifetime of pipe and network queue reqs
 *			in seconds.
 *		PKT_SETLOGFIL:
 *			Switch NQS message output to the new log file.
 *			ALL messages of severity:  INFO, LOG, DEBUG, WARN,
 *			ERROR, and FATAL are written to this file.
 *			Note that messages of severity ERROR and FATAL
 *			are also written to the crash file.
 *		PKT_SETMAXCOP:
 *			Set the maximum number of print copies.
 *		PKT_SETMAXOPERE:
 *			Set max device open retries.
 *		PKT_SETMAXPRISI:
 *			Set the maximum size of an NQS print file.
 *		PKT_SETNDFBATQU:
 *			Set no default batch queue.
 *		PKT_SETNDFPRIFO:
 *			Set no default print forms.
 *		PKT_SETNDFPRIQU:
 *			Set no default print queue.
 *		PKT_SETNETCLI:
 *			Configure/set the NQS network client.
 *		PKT_SETNETDAE:
 *			Configure/set the NQS network daemon.
 *		PKT_SETNETSER:
 *			Configure/set the NQS network server.
 *		PKT_SETNONETDAE:
 *			Set no NQS network daemon.
 *		PKT_SETNOQUEACC:
 *			Set queue access to reject all gid's, uid's.
 *              PKT_SETNOQUECHAR:
 *                      Turn off queue characteristics (status bits).
 *		PKT_SETNQSMAI:
 *			Set the NQS mail account name.
 *		PKT_SETNQSMAN:
 *			Set the NQS manager account list to the single
 *			account of root, with full NQS privileges.
 *		PKT_SETOPEWAI:
 *			Set the number of seconds to wait between failed
 *			device opens.
 *		PKT_SETPIPCLI:
 *			Set pipe client and arguments.
 *		PKT_SETPIPONL:
 *			Set pipeonly entry attribute for queue.
 *		PKT_SETPPCORE:
 *			Set the per-process core file size limit
 *			for a queue.
 *		PKT_SETPPCPUT:
 *			Set the per-process cpu time limit
 *			for a queue.
 *		PKT_SETPPDATA:
 *			Set the per-process data segment size limit
 *			for a queue.
 *		PKT_SETPPMEM:
 *			Set the per-process memory size limit
 *			for a queue.
 *		PKT_SETPPNICE:
 *			Set the per-process nice value 
 *			for a queue.
 *		PKT_SETPPPFILE:
 *			Set the per-process permanent file size limit
 *			for a queue.
 *		PKT_SETPPQFILE:
 *			Set the per-process quick file size limit
 *			for a queue.
 *		PKT_SETPPSTACK:
 *			Set the per-process stack segment size limit
 *			for a queue.
 *		PKT_SETPPTFILE:
 *			Set the per-process temporary file size limit
 *			for a queue.
 *		PKT_SETPPWORK:
 *			Set the per-process working set size limit
 *			for a queue.
 *		PKT_SETPRCPUT:
 *			Set the per-request cpu time limit
 *			for a queue.
 *		PKT_SETPRDRIVES:
 *			Set the per-request tape drive limit
 *			for a queue.
 *		PKT_SETPRMEM:
 *			Set the per-request memory size limit
 *			for a queue.
 *		PKT_SETPRNCPUS:
 *			Set the per-request limit on number of processors
 *			for a queue.
 *		PKT_SETPRPFILE:
 *			Set the per-request permanent file size limit
 *			for a queue.
 *		PKT_SETPRQFILE:
 *			Set the per-request quick file size limit
 *			for a queue.
 *		PKT_SETPRTFILE:
 *			Set the per-request temporary file size limit
 *			for a queue.
 *              PKT_SETQUECHAR:
 *                      Set the characteristics (status flags) of a queue.
 *		PKT_SETQUEDES:
 *			Set the destination set for the named queue to
 *			the single specified destination.
 *		PKT_SETQUEDEV:
 *			Set the queue/device mapping set for the named
 *			queue to the single specified device.
 *		PKT_SETQUENDP:
 *			Set the queue nondegrading priority 
 *		PKT_SETQUEPRI:
 *			Set the inter-queue priority for the named
 *			queue.
 *		PKT_SETQUERUN:
 *			Set the run-limit for a batch or pipe queue.
 *		PKT_SETSHSFIX:
 *			Set fixed shell-choice strategy.
 *		PKT_SETSHSFRE:
 *			Set free shell-choice strategy.
 *		PKT_SETSHSLOG:
 *			Set login shell-choice strategy.
 *		PKT_SETUNRQUEAC:
 *			Set queue access to accept all gid's, uid's.
 *		PKT_SHUTDOWN:
 *			Shutdown the NQS daemon.
 *		PKT_STAQUE:
 *			Start an NQS queue.
 *		PKT_STOQUE:
 *			Stop an NQS queue.
 *		PKT_UNLDAE:
 *			Unlock the NQS daemon from memory.  Let the
 *			NQS daemon be subject to swapping just like
 *			every other process.
 *		PKT_SETQUEUSR:
 *			Set the per queue user limit.
 *		PKT_SETGBATLIM:
 *			Set the global batch limit.
 *		PKT_SUSPENDREQ:
 *			Suspend or resume a batch request.
 *		PKT_SETPIPLIM:
 *			Set the global pipe route limit.
 *		PKT_VERQUEUSR:
 *			Verify batch queue user-limit.
 *		PKT_MOVQUE:
 *			Move all requests on a queue to another queue.
 *		PKT_HOLDREQ:
 *			Hold an NQS request.
 *		PKT_RELREQ:
 *			Release an NQS request.
 *		PKT_MEMDUMP:
 *			Dump daemon's internal data structures.
 *		PKT_LOAD:
 *			Report on a processor's load.
 *		PKT_RREQCOM:
 *			Report completion of a request.
 *		PKT_SETNQSSCHED:
 *			Set the NQS scheduler.
 *		PKT_SETDEFLOADINT:
 *			Set the default load interval.
 *		PKT_SETLOADDAE:
 *			Set the load daemon.
 *		PKT_CTLDAE:
 *			Startup or shutdown a daemon.
 *		PKT_ALTERREQ:
 *			Modify a request.
 *		PKT_SETSERVPERF
 *			Set server performance.
 *		PKT_SETSERVAVAIL
 *			Set server available.
 *
 *
 *
 *	Author:
 *	-------
 *	Brent A. Kingsbury, Sterling Software Incorporated.
 *	October 7, 1985.
 *
 *
 * STANDARDS VIOLATIONS:
 *   None.
 *
 * REVISION HISTORY: ($Revision: 1.14 $ $Date: 1994/09/02 17:39:40 $ $State: Exp $)
 * $Log: nqs_main.c,v $
 * Revision 1.14  1994/09/02  17:39:40  jrroma
 * Version 3.36
 *
 * Revision 1.13  94/03/30  20:36:40  jrroma
 * Version 3.35.6
 * 
 * Revision 1.12  94/02/24  21:30:53  jrroma
 * Version 3.35.3
 * 
 * Revision 1.11  93/09/10  13:57:16  jrroma
 * Version 3.35
 * 
 * Revision 1.10  93/07/13  21:33:53  jrroma
 * Version 3.34
 * 
 * Revision 1.9  92/12/22  15:40:42  jrroma
 * Version 3.30
 * 
 * Revision 1.8  92/06/18  17:31:09  jrroma
 * Added gnu header
 * 
 * Revision 1.7  92/05/06  10:41:06  jrroma
 *  Version 3.20
 * 
 * Revision 1.6  92/03/20  10:58:30  jrroma
 * *** empty log message ***
 * 
 * Revision 1.5  92/03/03  17:02:42  jrroma
 * Changed mid_t to Mid_t.
 * 
 * Revision 1.4  92/03/02  14:59:37  jrroma
 * Added Cosmic V2 changes.
 * 
 * Revision 1.3  92/02/12  13:42:28  jrroma
 * Fixed declaration of static routines.
 * 
 * Revision 1.2  92/01/17  11:01:08  jrroma
 * Added support for RS6000.
 * 
 * Revision 1.1  92/01/17  11:00:08  jrroma
 * Initial revision
 * 
 *
 */

#include "nqs.h"			/* Include NQS constants/types	*/
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>			/* Password file */
#include "nqspacket.h"			/* NQS local message packet types */
#include "nqsvars.h"			/* NQS global variables and */
					/* directories */
#include "informcc.h"			/* NQS information codes */
#include "transactcc.h"			/* NQS transaction completion codes */
#if	LINUX
  #include "lock.h"			/* Definitions for plock() calls*/
#else
  #include <sys/lock.h>
#endif
#include <sys/resource.h>               /* Get struct rusage definition */


#ifndef __CEXTRACT__
#if __STDC__

static void badpacket ( int pid, uid_t ruid, int report_protocol_error );
static int getpchar ( void );
static int invalidunits ( short units );
static void showbytes ( char *bytes, unsigned length );
static int validstr ( int str_n, int size_limit );

#else /* __STDC__ */

static void badpacket (/* int pid, uid_t ruid, int report_protocol_error */);
static int getpchar (/* void */);
static int invalidunits (/* short units */);
static void showbytes (/* char *bytes, unsigned length */);
static int validstr (/* int str_n, int size_limit */);

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

char *packet_types[] = 
 { "ABOQUE",
 "ADDFOR",
 "ADDNQSMAN",
 "ADDQUEDES",
 "ADDQUEDEV",
 "ADDQUEGID",
 "ADDQUEUID",
 "CREDEV",
 "CREBATQUE",
 "CREDEVQUE",               /* 9 */
 "CREPIPQUE",
 "DELDEV",
 "DELFOR",
 "DELNQSMAN",
 "DELQUE",
 "DELQUEDES",
 "DELQUEDEV",
 "DELQUEGID",
 "DELQUEUID",
 "DELREQ",                     /* 19 */
 "DISDEV",
 "DISQUE",
 "ENADEV",
 "ENAQUE",
 "FAMILY",
 "LOCDAE",
 "MODREQ",
 "MOVREQ",
 "PURQUE",
 "QUEREQ",                    /* 29 */
 "QUEREQVLPQ",
 "REQCOM",
 "RMTACCEPT",
 "RMTARRIVE",
 "RMTDEPART",
 "RMTENADES",
 "RMTENAMAC",
 "RMTFAIDES",
 "RMTDAIMAC",
 "RMTQUEREQ",                   /* 39 */
 "RMTRECEIVED",
 "RMTSCHDES",
 "RMTSCHMAC",
 "RMTSTASIS",
 "SCHEDULEREQ",
 "SENSEDAEMON",
 "SETDEB",
 "SETDEFBATPR",
 "SETDEFBATQU",
 "SETDEFDESTI",                /* 49 */
 "SETDEFDESWA",
 "SETDEFDEVPR",
 "SETDEFPRIFO",
 "SETDEFPRIQU",
 "SETDEVFOR",
 "SETDEVSER",
 "SETFOR",
 "SETLIFE",
 "SETLOGFIL",
 "SETMAXCOP",                  /* 59 */
 "SETMAXOPERE",
 "SETMAXPRISI",
 "SETNDFBATQU",
 "SETNDFPRIFO",
 "SETNDFPRIQU",
 "SETNETCLI",
 "SETNETDAE",
 "SETNETSER",
 "SETNONETDAE",
 "UNDEFINED1",                /* 69 */
 "SETNOQUEACC",
 "SETNQSMAI",
 "SETNQSMAN",
 "SETOPEWAI",
 "SETPIPCLI",
 "SETPIPONL",
 "SETPPCORE",
 "SETPPCPUT",
 "SETPPDATA",
 "SETPPMEM",                    /* 79 */
 "SETPPNICE",
 "SETPPPFILE",
 "SETPPQFILE",
 "SETPPSTACK",
 "SETPPTFILE",
 "SETPPWORK",
 "SETPRCPUT",
 "SETPRDRIVES",
 "SETPRMEM",
 "SETPRNCPUS",                    /* 89 */
 "SETPRPFILE",
 "SETPRQFILE",
 "SETPRTFILE",
 "SETQUEDES",
 "SETQUEDEV",
 "SETQUEPRI",
 "SETQUERUN",
 "SETSHSFIX",
 "SETSHSFRE",
 "SETSHSLOG",                     /* 99 */
 "SETUNRQUEAC",
 "SHUTDOWN",
 "STAQUE",
 "STOQUE",
 "UNLDAE",
 "SETQUENDP",
 "SETGBATLIM",
 "SETQUEUSR",
 "ADDQUECOM",
 "CRECOM",                          /* 109 */
 "DELCOM",
 "MOVQUE",
 "REMQUECOM",
 "SETCOMLIM",
 "SETCPUACC",
 "SUSPENDREQ",
 "HOLDREQ",
 "RELREQ",
 "SETPIPLIM",
 "VERQUEUSR",
 "SETQUECHAR",
 "SETNOQUECHAR",
 "SETCOMUSERLIM", 
 "MEMDUMP", 
 "LOAD", 
 "RCOMP",
 "SETNQSSCHED", 
 "SETDEFLOADINT", 
 "CTLDAE", 
 "SETLOADDAE", 
 "ALTERREQ", 
 "SETSERVPERF",
 "SETSERVAVAIL"};

  
/*** main
 *
 *
 *	int main():
 *	Start of the NQS local daemon.
 */
int main (argc, argv)
int argc;
char *argv[];
{
	int integers;			/* Number of 32-bit precision signed-*/
					/* integer values present in the */
					/* received message packet. */
	int strings;			/* Number of character/byte strings */
					/* in the received message packet. */
	int pid;			/* Pid of requester */
	uid_t ruid;			/* Real user-id of requester */
	int i;				/* Loop variable */
	int i1;				/* Integer argument #1. */
	int i2;				/* Integer argument #2. */
	int i3;				/* Integer argument #3. */
	int i4;				/* Integer argument #4. */
	int i5;				/* Integer argument #5. */
	long l1;			/* Long integer argument #1. */
	long l2;			/* Long integer argument #2. */
	Mid_t m1;			/* Mid argument #1 */
	short s1;			/* Short integer argument #1. */
	short s2;			/* Short integer argument #2. */
	unsigned long ul1;		/* Unsigned long argument #1. */
	int old_LB_Scheduler;		/* Save the old Scheduler mid here */

	Argv0 = argv[0];		/* Save pointer to daemon argv[0] */
	Argv0size = strlen (Argv0);	/* and size for later use */
	nqs_boot();			/* Boot/initialize NQS */
	/*
	 *  Loop forever to read requests.
	 */
	if (Debug) {
		printf ("D$main(): Looping to read request packets.\n");
		fflush (stdout);
	}
	for (;;) {
		/*
		 *  Loop to read packets until packet error, or no more
		 *  packets and we are shutting down.
		 */
		switch (interread (getpchar)) {
		case -1:
			/*
			 *  A shutdown request was received earlier.
			 *  The protection on the NQS local daemon request
			 *  pipe has been set to deny write access to
			 *  ALL processes.  Furthermore, no process
			 *  has the request pipe open for writing at
			 *  this time.  It is therefore safe to
			 *  shutdown now.
			 */
			close (Read_fifo);	/* Close read FIFO file dscr */
			printf ("I$NQS shutdown complete.\n");
			exit (0);
		case -2:		/* Bad packet received.  Abort */
					/* execution. */
			printf ("F$Inconsistent message ");
			printf ("packet received by NQS local daemon.\n");
			printf ("I$No recovery possible.\n");
			errno = 0;	/* Not a system call error. */
			nqs_abort();	/* Abort NQS execution. */
		}
		/*
		 *  Otherwise, the packet is self-consistent.
		 *  We have a request to process.
		 */
		integers = intern32i();	/* Get number of 32-bit precision */
					/* integers in message packet */
		if (integers < 3) {
			/*
			 *  The message packet at a minimum must contain
			 *  a packet-type value, client process-id, and
			 *  client process real user-id, as the last three
			 *  (3) integers in the message packet.
			 */
			printf ("E$Received message packet ");
			printf ("authentication error.\n");
			printf ("I$Message packet ignored.\n");
			fflush (stdout);
			continue;	/* Loop to read next message packet */
		}
		integers -= 3;		/* Delete the 3 integer values of */
					/* packet type, client process-id,*/
					/* and client process real user-id*/
		pid = interr32i (integers + 2);
					/* Get local client process-id. */
		ruid = interr32i (integers + 3);
					/* Get local client process real-uid */
		strings = internstr();	/* Get number of strings in packet */
		/*
		 *  The packet has been minimally authenticated.
		 */
		alarm (0);		/* Disable any virtual alarm timers. */
					/* This is absolutely critical so that*/
					/* the alarm functions do not run */
					/* asynchronously at a time when the */
					/* NQS data structures are possibly */
					/* being updated. */
		if (Debug) {
			printf ("D$main(): Received packet ");
			printf ("from local process: %1d\n", pid);
			printf ("D$main(): Client process ");
			printf ("real user-id = %1d\n", ruid);
			if (interr32i(integers+1) > PKT_MAXIMUM) 
			      printf("D$Main(): Packet type is %d UNKNOWN!\n",
				     interr32i (integers + 1));
			else
			    printf ("D$main(): Packet type is %s\n",
				packet_types [interr32i (integers + 1)]);
			if (integers != 0 || strings != 0) {
				printf ("D$main(): Packet contents are as ");
				printf ("follows:\n");
				fflush (stdout);
				for (i = 1; i <= strings; i++) {
					printf ("D$main(): String [%1d] = ", i);
					showbytes (interrstr (i),
						   interlstr (i));
					fflush (stdout);
				}
				for (i = 1; i <= integers; i++) {
					printf ("D$main(): Integer ");
					if (interr32sign (i)) {
						printf ("[%1d] = %1ld\n",
							i, interr32i (i));
					}
					else {
						printf ("[%1d] = %1lu\n",
							i, interr32u (i));
					}
				}
			}
			fflush (stdout);
		}
		/*
		 *  Based upon the packet type, we perform a case statement.
		 */
		switch ((int) interr32i (integers + 1)) {
		case PKT_ABOQUE:	/* Abort all running reqs in a queue */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				if (i1 >= 0) {
					nqs_complt (
						upq_aboque (
							interrstr (1), i1
						),
						pid);
				}
				else badpacket (pid, ruid, 1);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ADDFOR:	/* Add an NQS form */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_FORMNAME)) {
				nqs_complt (upf_addfor (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ADDNQSMAN:	/* Add an NQS manager account */
			if (strings == 0 && integers == 3 &&
			    !interr32sign (1)) {
				nqs_complt (
					upm_addnqsman (
						(uid_t) interr32i (1),
						(Mid_t) interr32u (2),
						(int) interr32i (3)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_ADDQUECOM:     /* Add a queue to a queue complex */
                        if (strings == 2 &&
                            validstr (1, MAX_QUEUENAME) &&
                            validstr (2, MAX_QCOMPLXNAME)) {
                                nqs_complt (
                                        upc_addquecom (
                                                interrstr (1), interrstr (2) ),
                                        pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;
		case PKT_ADDQUEDES:	/* Add a queue destination */
			if (strings == 2 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_QUEUENAME)) {
				nqs_complt (
					upd_addquedes (
						interrstr (1), interrstr (2),
						(Mid_t) interr32u (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ADDQUEDEV:	/* Add a queue/device mapping */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_DEVNAME)) {
				nqs_complt (
					upv_addquedev (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ADDQUEGID:	/* Add a gid to queue's access list */
			if (strings == 1 && integers == 1 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upq_addqueacc (
						interrstr (1),
						interr32i (1) | MAKEGID
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ADDQUEUID:	/* Add a uid to queue's access list */
			if (strings == 1 && integers == 1 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upq_addqueacc (
						interrstr (1),
						interr32i (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ALTERREQ:	/* Modify an NQS request */
			if (strings == 0 && integers == 4) {
				nqs_complt (nqs_alterreq ((uid_t) interr32i (1),
					interr32i (2), (Mid_t) interr32u(3), 
					interr32i (4)),	    /* priority */
							 pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_CREBATQUE:	/* Create a new NQS batch queue */
			if (strings == 1 && integers == 4 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				i2 = interr32i (2);
				i3 = (interr32i (3) != 0);
				i4 = interr32i (4);
				if (i1 < 0 || i1 > MAX_QPRIORITY || i2 < 0
					|| i4 < 0 ) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_creque (
						interrstr (1), QUE_BATCH,
						i1, 0, i2, i3, i4, NULL, 0
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_CRECOM:        /* Create a queue complex */
                        if (strings == 1 &&
                            validstr (1, MAX_QCOMPLXNAME)) {
                                nqs_complt( upc_crecom( interrstr (1) ), pid );                        }
                        else badpacket (pid, ruid, 1);
                        break;
		case PKT_CREDEV:	/* Create a new NQS device */
			if (strings == 4 && integers == 0 &&
			    validstr (1, MAX_DEVNAME) &&
			    validstr (2, MAX_FORMNAME) &&
			    validstr (3, MAX_PATHNAME) &&
			    validstr (4, MAX_SERVERNAME)) {
				nqs_complt (
					upv_credev (
						interrstr (1), interrstr (2),
						interrstr (3), interrstr (4)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_CREDEVQUE:	/* Create a new NQS device queue */
			if (strings == 1 && integers == 2 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				i2 = (interr32i (2) != 0);
				if (i1 < 0 || i1 > MAX_QPRIORITY) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_creque (
						interrstr (1), QUE_DEVICE,
						i1, 0, 0, i2, 0, NULL, 0
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_CREPIPQUE:	/* Create a new NQS pipe queue */
			if (strings == 2 && integers == 4 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_SERVERNAME)) {
				i1 = interr32i (1);
				i2 = interr32i (2);
				i3 = (interr32i (3) != 0);
				if (i1 < 0 || i1 > MAX_QPRIORITY || i2 < 0) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_creque (
						interrstr (1), QUE_PIPE,
						i1, 0, i2, i3, 0, interrstr (2),
						interr32i(4)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_DELCOM:        /* Delete a queue complex */
                        if (strings == 1 && integers == 0 &&
                            validstr (1, MAX_QCOMPLXNAME)) {
                                nqs_complt (upc_delcom (interrstr (1)), pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;
		case PKT_DELDEV:	/* Delete a device */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_DEVNAME)) {
				nqs_complt (upv_deldev (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELFOR:	/* Delete an NQS form */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_FORMNAME)) {
				nqs_complt (upf_delfor (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELNQSMAN:	/* Delete an NQS manager account */
			if (strings == 0 && integers == 3 &&
			    !interr32sign (1)) {
				nqs_complt (
					upm_delnqsman (
						(uid_t) interr32i (1),
						(Mid_t) interr32u (2),
						(int) interr32i (3)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELQUE:	/* Delete a queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_delque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELQUEDES:	/* Delete a pipe queue destination */
			if (strings == 2 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_QUEUENAME)) {
				nqs_complt (
					upd_delquedes (
						interrstr (1), interrstr (2),
						(Mid_t) interr32u (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELQUEDEV:	/* Delete a queue/device mapping */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_DEVNAME)) {
				nqs_complt (
					upv_delquedev (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELQUEGID:  /* Delete a gid from queue's access list */
			if (strings == 1 && integers == 1 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upq_delqueacc (
						interrstr (1),
						interr32i (1) | MAKEGID
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELQUEUID:  /* Delete a uid from queue's access list */
			if (strings == 1 && integers == 1 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upq_delqueacc (
						interrstr (1),
						interr32i (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DELREQ:	/* Delete an NQS req */
			if (strings == 0 && integers == 6) {
				i1 = interr32i (1);
				l2 = interr32i (2);
				i5 = interr32i (5);
				if (i1 < 0 || l2 < 0 || l2 > MAX_SEQNO_USER ||
				    i5 < 0) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					nqs_delreq ((uid_t) i1, l2,
						    (Mid_t) interr32u (3), 
						    (Mid_t) interr32u (4), i5,
						    (int) interr32i (6)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DISDEV:	/* Disable a device */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_DEVNAME)) {
				nqs_complt (upv_disdev (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_DISQUE:	/* Disable a queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_disque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ENADEV:	/* Enable a device */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_DEVNAME)) {
				nqs_complt (upv_enadev (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_ENAQUE:	/* Enable a queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_enaque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_FAMILY:	/* Report server "process-family" */
			if (strings == 0 && integers == 2) {
				nqs_family ((int) interr32i (1),
					    (int) interr32i (2));
			}
			else badpacket (pid, ruid, 0);
			break;
		case PKT_LOAD:		/* Report on a processor's load */
			if (strings == 1 && integers == 3) {
			    nqs_complt (nqs_load ((Mid_t) interr32u (1), /* Mid */
					(int) interr32i (2),  /* Version */
					(int) interr32i (3),  /* # jobs */
					 interrstr(1)),   /* string */
					 pid);
			}
			else badpacket (pid, ruid, 0);
			break;
		
		case PKT_LOCDAE:	/* Lock NQS local daemon in memory. */
			if (strings == 0 && integers == 0) {
				if (Plockdae == 0) {
					/*
					 *  The daemon is not presently locked
					 *  in memory.
					 */
#if !LINUX
					if (plock (PROCLOCK) == 0) {
						nqs_complt (TCML_COMPLETE, pid);
						Plockdae = 1;
						udb_genparams();
					}
					else nqs_complt (TCML_PLOCKFAIL, pid);
#else
					nqs_complt (TCML_COMPLETE, pid);
#endif
				}
				else nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_MEMDUMP:        /* Memory dump */
                        if (strings == 0 && integers == 1 ) {
                                nqs_complt (
				    nqs_memdump ( (int) interr32i (1) )
				            , pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;

		case PKT_MODREQ:	/* Modify req */
			if (integers == 7) {
				i1 = interr32i (1);
				l2 = interr32i (2);
                                if (i1 < 0 || l2 < 0 || l2 > MAX_SEQNO_USER) {
                                        badpacket (pid, ruid, 1);
                                }
                                else nqs_complt (
                                        nqs_modreq ((uid_t) i1, l2,
                                                    (Mid_t) interr32u (3),
                                                    interr32i (4),
                                                    interr32i (5),
                                                    interr32i (6),
                                                    interr32i (7)),
                                        pid);

			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_MOVQUE:        /* Move all requests on a queue to */
                                        /* another queue */
                        if (strings == 2 && integers == 0 &&
                            validstr (1, MAX_QUEUENAME) &&
                            validstr (2, MAX_QUEUENAME)) {
                                nqs_complt (nqs_movque ( interrstr (1),
                                        interrstr (2)), pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;

		case PKT_MOVREQ:	/* Move req between local queues */
                       if (strings == 1 && integers == 2 &&
                            validstr (1, MAX_QUEUENAME)) {
                                l1 = interr32i (1);
                                m1 = interr32u (2);
                                if (l1 < 0 || l1 > MAX_SEQNO_USER) {
                                        badpacket (pid, ruid, 1);
                                }
                                else nqs_complt (
                                        nqs_movreq (l1, (Mid_t) m1,
                                                    interrstr(1)),
                                        pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;

		case PKT_PURQUE:	/* Purge queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_purque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_QUEREQ:	/* Queue a NQS req */
			if (strings == 1 && integers == 0 &&
			    interlstr (1) > 0) {
				l1 = nqs_quereq (0, interrstr (1), 0L,
						(Mid_t) 0, (char *) 0,
						(Mid_t) 0);
				/*
				 *  Signal the client that we have made
				 *  our decision concerning the queueing
				 *  of the request.
				 */
				if (kill (pid, SIGALRM) == -1) {
					/*
					 *  What?  Unable to signal client?
					 */
					switch (errno) {
					case EINVAL:
						printf ("E$Invalid pid given");
						printf (" to nqs_main().\n");
						fflush (stdout);
						break;
					case EPERM:
						printf ("F$NQS not running ");
						printf ("as root in ");
						printf ("nqs_main().\n");
						nqs_abort();
					}
					/*
					 *  If the error is ESRCH, then we
					 *  don't get worried, it simply means
					 *  that the submitting process has
					 *  exited, or more seriously -- that
					 *  we were given a wrong process-id.
					 */
				}
				if ((l1 & XCI_FULREA_MASK) == TCML_SUBMITTED) {
					/*
					 *  The req was queued successfully.
					 *  We may need to spawn a req here.
					 */
					nsq_spawn();	/* MAYBE Spawn a req */
				}
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_QUEREQVLPQ:	/* Queue an NQS request via a local */
					/* pipe queue. */
			if (strings == 1 && integers == 2 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					nqs_quereq (
						1, (char *) 0, interr32i (1),
						(Mid_t) interr32u (2),
						interrstr (1), (Mid_t) 0
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_REMQUECOM:     /* Remove a queue from a queue */
                                        /* complex */
                        if (strings == 2 && integers == 0 &&
                            validstr (1, MAX_QUEUENAME) &&
                            validstr (2, MAX_QCOMPLXNAME)) {
                                nqs_complt (
                                        upc_remquecom( interrstr(1),
                                                interrstr(2)),
                                        pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;
		case PKT_REQCOM:	/* Request-complete packet */
			if (strings == 2 && integers == 3 &&
#if	HPUX | SGI | SOLARIS | SYS52 | IBMRS | LINUX
			    interlstr (1) == sizeof (struct tms)) {
#else
#if	BSD43 | ULTRIX | DECOSF
			    interlstr (1) == sizeof (struct rusage)) {
#else
BAD SYSTEM TYPE
#endif
#endif
				/*
				 *  We invoke nqs_reqcom() with a
				 *  pointer to the tms (or rusage)
				 *  structure passed in the request-
				 *  completion packet.
				 *
				 *  Pid has the process-id of the
				 *  exited NQS shepherd process for
				 *  the completed req request reporting
				 *  CPU usage times.
				 */
				nqs_reqcom ((long) interr32i (1),
					    (Mid_t) interr32u (2),
					    (int) interr32i (3),
#if	HPUX | SGI | SOLARIS | SYS52 | IBMRS | LINUX
					    (struct tms *) interrstr (1),
#else
#if	BSD43 | ULTRIX | DECOSF
					    (struct rusage *) interrstr (1),
#else
BAD SYSTEM TYPE
#endif
#endif
					    interrstr (2));
			}
			else badpacket (pid, ruid, 0);
			break;
		case PKT_RREQCOM:	/* Remote request has completed */
			if (strings == 0 && integers == 4) {
			    nqs_complt (
				nqs_rreqcom ((Mid_t) interr32u (1), /* which machine */
					   (Mid_t) interr32u (2),   /* Req orig mid */
					   interr32i(3),            /* Req seqno */
					   interr32i(4)		    /* Remaining jobs */
				), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		
		case PKT_RMTACCEPT:	/* Remote destination has */
					/* tentatively accepted the request */
			if (strings == 0 && integers == 2) {
				nqs_complt (
					pip_rmtaccept (interr32i (1),
						       interr32u (2)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTARRIVE:	/* The specified request previously */
					/* queued in the pre-arrive state is */
					/* now in the arriving state */
			if (strings == 0 && integers == 2) {
				nqs_complt (
					pip_rmtarrive (interr32i (1),
						       interr32u (2)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTDEPART:	/* Remote destination has committed */
					/* the request for arrival */
			if (strings == 0 && integers == 2) {
				nqs_complt (
					pip_rmtdepart (interr32i (1),
						       interr32u (2)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTENADES:	/* Enable a pipe queue destination */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upd_destination (
						interrstr (1), interr32u (1),
						0, 0L
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTENAMAC:	/* Enable a remote machine */
			if (strings == 0 && integers == 1) {
				nqs_complt (upd_machine (interr32u (1), 0, 0L),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTFAIDES:	/* Mark a pipe queue destination as */
					/* failed */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					upd_destination (
						interrstr (1), interr32u (1),
						1, 0L
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTFAIMAC:	/* Mark a remote machine as failed */
			if (strings == 0 && integers == 1) {
				nqs_complt (upd_machine (interr32u (1), 1, 0L),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTQUEREQ:	/* Queue an NQS request via a remote */
					/* pipe queue. */
			if (strings == 1 && integers == 3 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					nqs_quereq (
						2, (char *) 0, interr32i (1),
						(Mid_t) interr32u (2),
						interrstr (1), interr32i (3)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTRECEIVED:	/* The specified request that was */
					/* previously in the arriving state */
					/* has been completely received on */
					/* the local machine */
			if (strings == 0 && integers == 2) {
				nqs_complt (
					pip_reqreceived (interr32i (1),
							 interr32u (2)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTSCHDES:	/* Schedule a pipe-queue destination */
			if (strings == 1 && integers == 2 &&
			    validstr (1, MAX_QUEUENAME) && !interr32sign (2)) {
				nqs_complt (
					upd_destination (
						interrstr (1), interr32u (1),
						2, interr32i (2)
					), pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTSCHMAC:	/* Schedule a machine for retry */
			if (integers == 2 && !interr32sign (2)) {
				nqs_complt (upd_machine (interr32u (1), 2,
							 interr32i (2)),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_RMTSTASIS:	/* Request was in the pre-depart */
					/* state, but the transaction */
					/* resolution was such that the */
					/* request has become free to be */
					/* delivered to another machine, and */
					/* is now in the stasis state */
			if (strings == 0 && integers == 2) {
				nqs_complt (
					pip_rmtstasis (interr32i (1),
						       interr32u (2)
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SCHEDULEREQ:	/* Schedule a request retry */
			if (strings == 0 && integers == 3 &&
			    !interr32sign (3)) {
				nqs_complt (
					pip_schedulereq (
						interr32i (1), interr32u (2),
						interr32i (3)
					), pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_SETGBATLIM:	/* Set global batch limit level */
			if (strings == 0 && integers == 1) {
			        nqs_complt (
				    upp_setgblbatlim(
					 interr32i (1) ), pid );
			}
			else badpacket (pid, ruid, 1);
			break;
                case PKT_SETCOMLIM:     /* Set queue complex run limit */
                        if (strings == 1 && integers == 1 &&
                            validstr (1, MAX_QCOMPLXNAME)) {
                                nqs_complt (
                                        upc_setcomlim( interrstr(1),
                                                interr32i(1)),
                                        pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;
                case PKT_SETCOMUSERLIM:     /* Set queue complex user run limit */
                        if (strings == 1 && integers == 1 &&
                            validstr (1, MAX_QCOMPLXNAME)) {
                                nqs_complt (
                                        upc_setcomuserlim( interrstr(1),
                                                interr32i(1)),
                                        pid);
                        }
                        else badpacket (pid, ruid, 1);
                        break;
		case PKT_SETNQSSCHED:	/* Set NQS scheduler */
			if (strings == 0 && integers == 1) {
			    old_LB_Scheduler = LB_Scheduler;
			    LB_Scheduler = (Mid_t) interr32u (1);
			    if (!LB_Scheduler && old_LB_Scheduler) 
				    nqs_ctldae(STOP_DAEMON, LOAD_DAEMON);
			    if (!old_LB_Scheduler && LB_Scheduler)
				    nqs_ctldae(START_DAEMON, LOAD_DAEMON);			    
			    udb_genparams();
			    nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEB:	/* Set debug level */
			if (strings == 0 && integers == 1) {
				Debug = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFBATPR:	/* Set default intra-queue batch-req */
					/* Priority */
			if (strings == 0 && integers == 1) {
				i1 = interr32i (1);
				if (i1 < 0 || i1 > MAX_RPRIORITY) {
					badpacket (pid, ruid, 1);
				}
				else {
					Defbatpri = i1;
					udb_genparams();
					nqs_complt (TCML_COMPLETE, pid);
				}
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFBATQU:	/* Set default batch queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upp_setdefbatque (interrstr (1)),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFDESTI:	/* Set default destination */
					/* retry state time tolerance */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Defdesrettim = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFDESWA:	/* Set default failed destination */
					/* wait retry time */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Defdesretwai = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFDEVPR:	/* Set default intra-queue device-req */
					/* priority */
			if (strings == 0 && integers == 1) {
				i1 = interr32i (1);
				if (i1 < 0 || i1 > MAX_RPRIORITY) {
					badpacket (pid, ruid, 1);
				}
				else {
					Defdevpri = i1;
					udb_genparams();
					nqs_complt (TCML_COMPLETE, pid);
				}
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFPRIFO:	/* Set default print forms */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_FORMNAME)) {
				nqs_complt (upp_setdefprifor (interrstr (1)),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFPRIQU:	/* Set default print queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upp_setdefprique (interrstr (1)),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEVFOR:	/* Set device forms */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_DEVNAME) &&
			    validstr (2, MAX_FORMNAME)) {
				nqs_complt (
					upv_setdevfor (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEVSER:	/* Set device server */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_DEVNAME) &&
			    validstr (2, MAX_SERVERNAME)) {
				nqs_complt (
					upv_setdevser (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETFOR:	/* Set the NQS forms list */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_FORMNAME)) {
				udb_setfor (interrstr (1));
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETLIFE:	/* Set lifetime of NQS pipe and */
					/* network reqs */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Lifetime = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETLOGFIL:	/* Switch to new logfile */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_PATHNAME)) {
				nqs_complt (upp_setlogfil (interrstr(1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETMAXCOP:	/* Set max number of print copies */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Maxcopies = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETMAXOPERE:	/* Set max device-open retry count */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Maxoperet = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETMAXPRISI:	/* Set max print file size */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				Maxprint = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNDFBATQU:	/* Set no default batch queue */
			if (strings == 0 && integers == 0) {
				nqs_complt (upp_setdefbatque (""), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
 		case PKT_SETNDFPRIFO:	/* Set no default print forms */
			if (strings == 0 && integers == 0) {
				nqs_complt (upp_setdefprifor (""), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNDFPRIQU:	/* Set no default print queue */
			if (strings == 0 && integers == 0) {
				nqs_complt (upp_setdefprique (""), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNETCLI:	/* Configure/set the NQS network */
					/* client */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_SERVERNAME)) {
				strcpy (Netclient, interrstr (1));
				udb_netprocs();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNETDAE:	/* Configure/set the NQS network */
					/* daemon */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_SERVERNAME)) {
				strcpy (Netdaemon, interrstr (1));
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETLOADDAE:	/* Configure/set the NQS load */
					/* daemon */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_SERVERNAME)) {
			        if ( !(strcmp("no-load-daemon",interrstr (1)))) 
					 Loaddaemon[0] = '\0';
				else strcpy (Loaddaemon, interrstr (1));
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNETSER:	/* Configure/set the NQS network */
					/* server */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_SERVERNAME)) {
				strcpy (Netserver, interrstr (1));
				udb_netprocs();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNONETDAE:	/* Set no NQS network daemon */
			if (strings == 0 && integers == 0) {
				Netdaemon [0] = '\0';
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNOQUEACC:	/* Set queue to reject all gids, uids */
			if (strings ==  1 && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_setnoqueacc (interrstr (1)),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETQUECHAR:	/* Set queue characteristics */
			if (strings ==  1 && validstr (1, MAX_QUEUENAME)) {
			    i1 = interr32i (1);
			    if (i1 < 0) badpacket (pid, ruid, 1);
			    else {
				nqs_complt (upq_setquechar (interrstr (1),i1),
					pid);
			    }
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNOQUECHAR:	/* Turn off queue characteristics */
			if (strings ==  1 && validstr (1, MAX_QUEUENAME)) {
			    i1 = interr32i (1);
			    if (i1 < 0) badpacket (pid, ruid, 1);
			    else {
				nqs_complt (upq_setnoquechar (interrstr (1),i1),
					pid);
			    }
			}
                        else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNQSMAI:	/* Set NQS mail account user-id and */
					/* name */
			if (strings == 0 && integers == 1 &&
			    !interr32sign (1)) {
				i1 = interr32i (1);
				if (fetchpwuid (i1) == NULL) {
					/*
					 *  No such account exists on the
					 *  local machine.
					 */
					nqs_complt (TCML_NOSUCHACC, pid);
				}
				else {
					Mail_uid = i1;
					udb_genparams();
					nqs_complt (TCML_COMPLETE, pid);
				}
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETNQSMAN:	/* Set the NQS manager set to the */
					/* single account of root with full */
					/* NQS privileges. */
			if (strings == 0 && integers == 0) {
				udb_setnqsman();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETOPEWAI:	/*Set the failed device open wait time*/
			if (strings == 0 && integers == 1) {
				i1 = interr32i (1);
				if (i1 < 0) badpacket (pid, ruid, 1);
				else {
					Opewai = i1;
					udb_genparams();
					nqs_complt (TCML_COMPLETE, pid);
				}
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPIPCLI:	/* Set pipe client */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_SERVERNAME)) {
				nqs_complt (
					upq_setpipcli (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPCORE:	/* Set core file size limit for queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPCORE
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPCPUT:	/* Set per-process cpu time */
					/* limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				s1 = (short) interr32i (2);
				s2 = (short) interr32i (3);
				if (s1 < 0 || s1 > 999 ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setcpulim (
						interrstr (1), interr32u (1),
						s1, s2, LIM_PPCPUT
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPDATA:	/* Set data size limit for queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPDATA
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPMEM:	/* Set per-process memory size */
					/* limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPMEM
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPNICE:	/* Set nice value for queue */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = (int) interr32i (1);
				if (i1 < MIN_REQNICE || i1 > MAX_REQNICE) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setniclim (
						interrstr (1), i1
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPPFILE:	/* Set per-process permanent file */
					/* size limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPPFILE
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPSTACK:	/* Set stack size limit for queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPSTACK
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPTFILE:	/* Set per-process temporary file */
					/* size limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPTFILE
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPPWORK:	/* Set working set size limit */
					/* for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PPWORK
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPRCPUT:	/* Set per-request cpu time limit */
					/* for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				s1 = (short) interr32i (2);
				s2 = (short) interr32i (3);
				if (s1 < 0 || s1 > 999 ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setcpulim (
						interrstr (1), interr32u (1),
						s1, s2, LIM_PRCPUT
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPRMEM:	/* Set per_request memory limit */
					/* for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PRMEM
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPRPFILE:	/* Set per-request permanent file */
					/* size limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PRPFILE
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPRTFILE:	/* Set per-request temporary file */
					/* size limit for a queue */
			if (strings == 1 && integers == 3 &&
			    !interr32sign (1) && validstr (1, MAX_QUEUENAME)) {
				ul1 = interr32u (1);
				s1 = interr32i (2);
				s2 = interr32i (3);
				if (ul1 > 2147483647 || invalidunits (s1) ||
				    s2 < 0 || s2 > 1) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquolim (
						interrstr (1),
						ul1, s1, s2, LIM_PRTFILE
					), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETQUEDES:	/* Set destination set for the */
					/* named queue to the single */
					/* specified destination. */
			if (strings == 2 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_QUEUENAME)) {
				nqs_complt (
					upd_setquedes (
						interrstr (1), interrstr (2),
						(Mid_t) interr32u (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETQUEDEV:	/* Set device set for queue to the */
					/* single named device */
			if (strings == 2 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME) &&
			    validstr (2, MAX_DEVNAME)) {
				nqs_complt (
					upv_setquedev (
						interrstr (1), interrstr (2)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETQUENDP:     /* Set queue nondegrading priority */
                        if (strings == 1 && integers == 1 &&
                            validstr (1, MAX_QUEUENAME)) {
                                i1 = interr32i (1);
                                if (i1 < MIN_QUENDP || i1 > MAX_QUENDP) {
                                        badpacket (pid, ruid, 1);
                                }
                                else nqs_complt (
                                        upq_setquendp (
                                                interrstr (1), i1
                                        ),
                                        pid);
                        }
                        else {
				badpacket (pid, ruid, 1);
			}
                        break;

		case PKT_SETQUEPRI:	/* Set inter-queue queue priority */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				if (i1 < 0 || i1 > MAX_QPRIORITY) {
					badpacket (pid, ruid, 1);
				}
				else nqs_complt (
					upq_setquepri (
						interrstr (1), i1
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
 		case PKT_SETQUEUSR:	/* Set user run-limit for a batch or */
					/* pipe queue */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				if (i1 <= 0) badpacket (pid, ruid, 1);
				else nqs_complt (
					upq_setqueusr (
						interrstr (1), i1
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
 		case PKT_SETQUERUN:	/* Set run-limit for a batch or */
					/* pipe queue */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				i1 = interr32i (1);
				if (i1 <= 0) badpacket (pid, ruid, 1);
				else nqs_complt (
					upq_setquerun (
						interrstr (1), i1
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETSERVAVAIL:	/* Set a compute server available */
			if (strings == 0 && integers == 1) {
				nqs_complt (
					upserv_setavail (
						(Mid_t) interr32u (1)
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETSERVPERF:	/* Set a compute servers performance */
			if (strings == 0 && integers == 2 ) {
				i1 = interr32i (2);
				if (i1 < 0) badpacket (pid, ruid, 1);
				nqs_complt (
					upserv_setperf (
						(Mid_t) interr32u (1),
						i1
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
 		case PKT_SETSHSFIX:	/* Set fixed shell-choice strategy */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_SERVERNAME)) {
				Shell_strategy = SHSTRAT_FIXED;
				strcpy (Fixed_shell, interrstr (1));
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETSHSFRE:	/* Set free shell-choice strategy */
			Shell_strategy = SHSTRAT_FREE;
			Fixed_shell [0] = '\0';
			udb_genparams();
			nqs_complt (TCML_COMPLETE, pid);
			break;
		case PKT_SETSHSLOG:	/* Set login shell-choice strategy */
			Shell_strategy = SHSTRAT_LOGIN;
			Fixed_shell [0] = '\0';
			udb_genparams();
			nqs_complt (TCML_COMPLETE, pid);
			break;
		case PKT_SETUNRQUEAC:	/* Set queue to accept all gids, uids */
			if (strings ==  1 && validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_setunrqueacc (interrstr (1)),
					    pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SHUTDOWN:	/* Shutdown request. */
			if (strings == 0 && integers == 1) {
				i1 = interr32i (1);
				if (i1 < 0) badpacket (pid, ruid, 1);
				else nqs_complt (
					ups_shutdown (
						pid, ruid, i1
					),
					pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_STAQUE:	/* Start a queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_staque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_STOQUE:	/* Stop a queue */
			if (strings == 1 && integers == 0 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (upq_stoque (interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SUSPENDREQ:	/* supend or resume a request */
			if ( integers == 6) {
				l1 = interr32i(2);
				if (l1 > MAX_SEQNO_USER) badpacket(pid,ruid,1);	
				l2 = interr32i(5);
				if (l1 < 0 ) badpacket(pid,ruid,1);
				nqs_complt (
				    nqs_suspendreq(
					interr32i(1),	/* uid */
					l1,			/* seqno */
					(Mid_t) interr32u(3),	/* orig mid */
					(Mid_t) interr32u(4), 	/* target mid */
					l2,			/* privs */ 
					interr32i(6)),		/* action */
					pid);
			} 
			else badpacket (pid, ruid, 1);
			break;
			
		case PKT_UNLDAE:	/* Unlock NQS local daemon from memory*/
			if (strings == 0 && integers == 0) {
				if (Plockdae) {
					/*
					 *  The daemon is presently locked
					 *  in memory.
					 */
#if !LINUX
					if (plock (UNLOCK) == 0) {
						nqs_complt (TCML_COMPLETE, pid);
						Plockdae = 0;
						udb_genparams();
					}
					else nqs_complt (TCML_PLOCKFAIL, pid);
#else
					nqs_complt (TCML_COMPLETE, pid);
#endif
				}
				else nqs_complt (TCML_COMPLETE, pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_SETPIPLIM:	/* Set global pipe route limit */
			if (strings == 0 && integers == 1) {
				nqs_complt (
					upp_setgblpiplim (
						interr32i (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_VERQUEUSR:	/* Verify batch queue user-limit */
			if (strings == 1 && integers == 1 &&
			    validstr (1, MAX_QUEUENAME)) {
				nqs_complt (
					bsc_verqueusr (
						(uid_t) interr32i (1),
						(struct nqsqueue *) 0,
					interrstr (1)), pid);
			}
			else badpacket (pid, ruid, 1);
			break;
		case PKT_HOLDREQ:	/* Hold an NQS request */
			if (strings == 0 && integers == 3) {
				nqs_complt (nqs_holdreq ((uid_t) interr32i (1),
							 interr32i (2),
							 (Mid_t) interr32u(3)),
							 pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_RELREQ:	/* Release an NQS request */
			if (strings == 0 && integers == 3) {
				nqs_complt (nqs_relreq ((uid_t) interr32i (1),
							interr32i (2),
							(Mid_t) interr32u (3)),
							pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_SETDEFLOADINT:	/* Set default load interval */
			if (strings == 0 && integers == 1) {
				Defloadint = interr32i (1);
				udb_genparams();
				nqs_complt (TCML_COMPLETE, pid);
			} else badpacket (pid, ruid, 1);
			break;
		case PKT_CTLDAE:	/* Control a daemon */
			if (strings == 0 && integers == 2) {
				nqs_complt (nqs_ctldae ( interr32i (1),
							interr32i (2)),
							pid);
			} else badpacket (pid, ruid, 1);
			break;
		default:
			badpacket(pid, ruid, 1);
			break;
		}
		nqs_valarm ();		/* Re-enable any virtual timers */
					/* (see nqs_vtimer.c()). It is */
					/* now safe to do so since the NQS */
					/* data structures will remain */
					/* stable until the next message */
					/* packet is received. */
	}
}


/*** getpchar
 *
 *
 *	int getpchar():
 *
 *	Return the next character from the NQS FIFO "mailbox" pipe.
 *	Return -1 if no processes in the system have the request
 *		  FIFO mailbox named-pipe open and a shutdown
 *		  request was received earlier.
 *
 *	If a character is returned, then the value as a signed
 *	integer MUST be positive, and hold eight (8 - count them),
 *	bits of data!
 */
static int getpchar ()
{
	static char buffer [MAX_PACKET];
					/* Fifo receive buffer */
	static int bufptr = 0;		/* Fifo input buffer index ptr */
	static int n_read = 0;		/* # of chars returned from read() */
	register int no_packet_yet;	/* Flag used in read loop. */

	if (bufptr < n_read) {
		/*
		 *  Return the next character read from the input buffer.
		 */
		return (buffer [bufptr++] & 0377);
	}
	/*
	 *  Otherwise, we need to fetch another buffer from the NQS
 	 *  FIFO "mailbox" request pipe.  Read until an error other
	 *  than EINTR or a request arrives on the input pipe.
	 */
	bufptr = 1;			/* Reset input buffer ptr */
	no_packet_yet = 1;
	do  {
		if ((n_read = read (Read_fifo, buffer, MAX_PACKET)) == -1) {
			if (errno != EINTR) {
				printf ("F$Error reading NQS request pipe.\n");
				nqs_abort();
			}
		}
		else no_packet_yet = 0;	/* Successfully got a packet */
	} while (no_packet_yet);
	if (n_read == 0) {
		/*
		 *  No more requests.  A shutdown request was received
		 *  earlier AND all processes with active request traffic
		 *  have exited.
		 */
		return (-1);		/* No more characters will be read */
	}
	return (buffer [0] & 0377);	/* Return the next character */
}


/*** badpacket
 *
 *
 *	void badpacket():
 *
 *	Write a message to the NQS log process concerning the bad packet
 *	received.
 */
static void badpacket (pid, ruid, report_protocol_error)
int pid;				/* Process id */
uid_t ruid;				/* Real user-id */
int report_protocol_error;		/* Boolean report protocol error */
					/* in packet, if non-zero. */
{
	if (report_protocol_error) nqs_complt (TCML_PROTOFAIL, pid);
	printf ("E$Bad packet received from process %1d.\n", pid);
	printf ("I$Sender process real UID = %1u.\n", ruid);
	printf ("I$Bad packet ignored.\n");
	fflush (stdout);
}


/*** invalidunits
 *
 *
 *	int invalidunits():
 *	Return non-zero if the specified quota limit units are invalid.
 */
static int invalidunits (units)
short units;				/* Quota limit units */
{
	switch (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:
		return (0);		/* Units are valid */
	}
	return (-1);			/* Units are invalid */
}


/*** showbytes
 *
 *
 *	void showbytes():
 *	Show byte/string datum as received in message packet.
 */
static void showbytes (bytes, length)
register char *bytes;			/* Array of bytes. */
register unsigned length;		/* Length of byte array. */
{
	register short ch;		/* Byte/character */
	register int col;		/* Column counter */
	short truncate_flag;		/* String truncated flag */

	col = 0;			/* # of columns written */
	truncate_flag = 0;
	if (length > 300) {
		truncate_flag = 1;	/* Truncate to 300 chars on */
		length = 300;		/* display */
	}
	while (length--) {
		if (col >= 24) {
			putchar ('\n');
			printf ("D$main(): ");
			col = 0;
		}
		ch = (*bytes & 0377);	/* Mask to 8 bits */
		bytes++;		/* Increment to next byte */
		if (ch < ' ' || ch > 127) {
			/*
			 *  This character is unprintable, or is a tab
			 *  character.
			 */
			printf ("[\\%03o]", ch);
			col += 6;
		}
		else {
			putchar (ch);
			col += 1;
		}
	}
	putchar ('\n');
	if (truncate_flag) {
		/*
		 *  String truncated.
		 */
		printf ("String diagnostic output truncated.\n");
	}
}


/*** validstr
 *
 *
 *	int validstr():
 *	Validate string.
 *
 *	Returns:
 *		1: if the specified string parameter in the received
 *		   message packet is not null, and is of length less
 *		   than, or equal to size_limit.
 *		0: otherwise.
 */
static int validstr (str_n, size_limit)
register int str_n;			/* Message packet string [n] */
register int size_limit;		/* Maximum size limit */
{
	register int size;

	size = interlstr (str_n);
	if (size && size <= size_limit) return (1);
	return (0);
}
