/*
 *	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  CB                      Initial version.
*       V01.20  JRR     09-Apr-1992	Monsanto modifications.
*	V01.3	JRR	17-Jun-1992	Added header.
*	V01.4	JRR	20-Nov-1992	Modified for C prototypes.
*	V01.5	JRR	08-Mar-1993	Added Boeing enhancement for files.
*/
#include "nqs.h"			/* NQS types and definitions */
#include "netpacket.h"			/* NQS networking */
#include "nqsdirs.h"			/* Directory structures */
#include <pwd.h>			/* Password stuff */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


#ifndef __CEXTRACT__
#if __STDC__

static int reqstat ( char *servername, long flags, uid_t whomuid, char *myname, uid_t myuid );
static showjobs ( int sd );

#else /* __STDC__ */

static int reqstat (/* char *servername, long flags, uid_t whomuid, char *myname, uid_t myuid */);
static showjobs (/* int sd */);

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


#define BSERVERS "/etc/batchservers"


int DEBUG;

main()
{
	FILE * bservfile;
	char buffer[4096];
	long flags;			/* SHO_??? */
	uid_t myuid;			/* Local user-id */
	char myname[MAX_ACCOUNTNAME+1];	/* Local account name */
	char *p;
        struct passwd *passwd;          /* Password file entry */
	int sd;				/* Socket descriptor */
	char *servername;
	uid_t whomuid;			/* Whom we are interested in */

	if ((bservfile = fopen (BSERVERS, "r")) == (FILE *)0) {
		fprintf (stderr, "No batch server configured\n");
		exit (1);
	}
	flags = SHO_R_STANDARD;
	flags |= (SHO_RS_EXIT | SHO_RS_RUN | SHO_RS_STAGE |
		  SHO_RS_QUEUED | SHO_RS_WAIT | SHO_RS_HOLD | SHO_RS_ARRIVE);
	myuid = getuid();
	whomuid = myuid;
	if ((passwd = fetchpwuid (myuid)) == (struct passwd *) 0) {
		fprintf (stderr, "Who are you?\n");
		return (0);
	}
	strncpy (myname, passwd->pw_name, MAX_ACCOUNTNAME+1);
				/* Save account name */
	/*
	 *  Get central server name
	 */
	if (fgets (buffer, sizeof(buffer), bservfile) == (char *)0) {
		fprintf (stderr, "No batch server configured\n");
		exit (1);
	}
	p = buffer;
	while (*p != '\n') p++;
	*p = '\0';
	servername = buffer;
	if ((sd = reqstat (servername, flags, whomuid, myname, myuid)) >=0) {
		showjobs (sd);
	}
	while (fgets (buffer, sizeof(buffer), bservfile) != (char *)0) {
		p = buffer;
		while (*p != '\n') p++;
		*p = '\0';
		if((sd = reqstat (servername, flags, whomuid, myname, myuid)) >= 0) {
			showjobs (sd);
		}
	}
	fclose (bservfile);
}

static int reqstat (
	char *servername,
	long flags,
	uid_t whomuid,
	char *myname,
	uid_t myuid)
{
	struct hostent *ent;
	Mid_t itsmid;			/* The remote machine id */
	int sd;				/* Socket descriptor */
	int timeout;			/* Timeout in between tries */
	long transactcc;		/* Transaction completion code */

	if ((ent = gethostbyname (servername)) == (struct hostent *)0) {
		fprintf (stderr, "%s not in /etc/hosts\n", servername);
		return (-1);
	}
	if (nmap_get_mid (ent, &itsmid) != NMAP_SUCCESS) {
		fprintf (stderr, "%s not in Machine ID database.\n", servername);
		return (-1);
	}

	interclear ();
	interw32i (flags);	/* SHO_??? */
	interwstr ("");		/* not a specific queue */
	interw32i (whomuid);
	interwstr (myname);
	sd = establish (NPK_QSTAT, itsmid, myuid, myname,
			&transactcc);
	/*
	 *  Establish has just told the network server
	 *  on the remote machine what it is that we want.
	 */
	if (sd < 0) {
		if (sd == -2) {
			/*
			 * Retry is in order.
			 */
			timeout = 1;
			do {
				nqssleep (timeout);
				interclear ();
				interw32i (flags);
				interwstr ("");
				interw32i (whomuid);
				interwstr (myname);
				sd = establish (NPK_QSTAT, itsmid,
						myuid, myname,
						&transactcc);
				timeout *= 2;
			} while (sd == -2 && timeout <= 16);
			/*
			 *  Beyond this point, give up on retry.
			 */
			if (sd < 0) {
				analyzetcm (transactcc, stderr, "");
			}
		}
		else {
			/*
			 *  Retry would surely fail.
			 */
			analyzetcm (transactcc, stderr, "");
		}
	}
	return (sd);
}
static showjobs(int sd)
{
	int extrach;			/* Number of chs already read */
	/*
	 *  The server liked us.
	 */
	/*
	 *  First, display any characters that
	 *  were already read inside establish().
	 */
	if (extrach = extrasockch ()) {
		write (STDOUT, bufsockch (), extrach);
	}
	/*
	 *  Then display any characters that the server
	 *  may still want to send us.
	 */
	filecopyentire (sd, STDOUT);
}
