/*
 *	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  CA                      Initial version.
*       V01.20  JRR     09-Apr-1992	Monsanto modifications.
*	V01.3	JRR	11-Nov-1992	Some fixes.
*	V01.4	JRR
*	V01.5	JRR	08-Mar-1993	Added Boeing enhancement for files.
*	V01.6	JRR	18-Aug-1993	Fixed up usage message.
*	V01.7	JRR	02-Mar-1994	Fixed up NETDB.
*/
/*++ qmsg.c - Network Queueing System
 *
 * $Source: /usr2/jrroma/nqs/nqs-3.35.6/src/RCS/qmsg.c,v $
 *
 * DESCRIPTION:
 *
 *	Write a message to the stdout or stderr file(s) of a batch request.
 *
 *
 *	Author:
 *	-------
 *	Clayton Andreasen, Cray Research, Inc.
 *	July 18, 1986.
 *
 *
 * STANDARDS VIOLATIONS:
 *   None.
 *
 * REVISION HISTORY: ($Revision: 1.7 $ $Date: 1994/03/30 20:37:07 $ $State: Exp $)
 * $Log: qmsg.c,v $
 * Revision 1.7  1994/03/30  20:37:07  jrroma
 * Version 3.35.6
 *
 * Revision 1.6  93/09/10  13:57:29  jrroma
 * Version 3.35
 * 
 * Revision 1.5  93/07/13  21:34:10  jrroma
 * Version 3.34
 * 
 * Revision 1.4  92/12/22  15:43:23  jrroma
 * Version 3.30
 * 
 * Revision 1.3  92/06/17  08:45:38  jrroma
 * Version 3.21
 * 
 * Revision 1.2  92/05/06  10:46:05  jrroma
 *  Version 3.20
 * 
 * Revision 1.1  92/04/09  12:49:08  jrroma
 * Initial revision
 * 
 * Revision 3.2  91/02/11  16:59:05  root
 * Version 2.0 Source
 * 
 * Revision 2.2  87/04/22  15:11:32  hender
 * Sterling version 4/22/87
 * 
 *
 */

#include "nqs.h"			/* NQS types and definitions */
#include <errno.h>
#include <netdb.h>			/* Network database files */
#include "nqsdirs.h"			/* NQS files and directories */


#ifndef __CEXTRACT__
#if __STDC__

static void qmsg_usage ( void );
static void qmsg_version ( void );

#else /* __STDC__ */

static void qmsg_usage (/* void */);
static void qmsg_version (/* void */);

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

char *Qmsg_prefix = "Qmsg";

/*** main
 *
 *
 *	qmsg [ -eo ] <request-id>
 */
main (int argc, char *argv[])
{
	int	i;
	char	buffer[4096];		/* message buffer */
	int	errflag;		/* write to stderr flag */
	int	outflag;		/* write to stdout flag */
	int	fd_err;			/* stderr file descriptor */
	int	fd_out;			/* stdout file descriptor */
	long	seqno;			/* Sequence# for req */
	Mid_t	mid;			/* Machine-id of originating machine */
	Mid_t	target_mid;		/* Possibly remote node */
	Mid_t	my_mid;			/* Our mid */
	char	*argument;		/* Ptr to cmd line arg text */
	char *root_dir;                 /* Fully qualified file name */	
	
	if ( ! buildenv()) {
	    fprintf (stderr, "%s(FATAL): Unable to ", Qmsg_prefix);
	    fprintf (stderr, "establish directory independent ");
	    fprintf (stderr, "environment.\n");
	    exit (1);
	}

	root_dir = getfilnam (Nqs_root, SPOOLDIR);
	if (root_dir == (char *)NULL) {
	    fprintf (stderr, "%s(FATAL): Unable to ", Qmsg_prefix);
	    fprintf (stderr, "determine root directory name.\n");
	    exit (1);
	}
	if (chdir (root_dir) == -1) {
	    fprintf (stderr, "%s(FATAL): Unable to chdir() to the NQS ",
                 Qmsg_prefix);
	    fprintf (stderr, "root directory.\n");
	    relfilnam (root_dir);
	    exit (1);
	}
	relfilnam (root_dir);

	/*
	 *  Set effective uid to real uid.
	 */
	setuid( getuid() );

	/*
	 *  Interpret flags.
	 */
	while (*++argv != NULL && **argv == '-') {
	    argument = *argv;
	    while (*++argument) {
		switch (*argument) {
		case 'e':		/* write in stderr */
		    errflag = 1;
		    break;
		case 'o':		/* write in stdout */
		    outflag = 1;
		    break;
		case 'v':
		    qmsg_version();
		    break;
		default:
		    qmsg_usage();
		}
	    }
	}
	/*
	 * Default to stderr if neither is specified.
	 */
	if (!( errflag | outflag )) errflag = 1;

	/*
	 *  Validate the request-id.
	 */
	if (*argv == NULL) { 		/* If no request-ids was specified */
		fprintf (stderr, "No request-id specified.\n");
		qmsg_usage();
	}
	switch (reqspec (*argv, &seqno, &mid, &target_mid)) {
	case -1:
	    fprintf (stderr, "Invalid request-id syntax ");
	    fprintf (stderr, "for request-id: %s.\n", *argv);
	    exit (1);
	case -2:
	    fprintf (stderr, "Unknown machine for request-id: %s.\n", *argv);
	    exit (1);
	case -3:
	    fprintf (stderr, "Network mapping database ");
	    fprintf (stderr, "inaccessible.  Seek staff support.\n");
	    exit (1);
	case -4:
	    fprintf (stderr, "Network mapping database error when parsing ");
	    fprintf (stderr, "request-id: %s.  Seek staff support.\n", *argv);
	    exit (1);
	}
	localmid (&my_mid);
	if (target_mid != my_mid) {
	    fprintf (stderr, "Cannot write to remote node.\n");
	    exit (1);
	}
	if (errflag) {
	    fd_err = open(namstderr(seqno, mid), O_WRONLY|O_APPEND);
	    if (fd_err < 0) {
	        /*
	         * We cannot open stderr.  Perhaps it was submitted -eo
		 * If we want to write to stdout as well, then this is
		 * not a problem.
	         */
		errflag = 0;
		if (!outflag) {
		    perror ("Error opening request's stderr file");
		    exit(1);
		}
	    }
	}
	if (outflag) {
	    fd_out = open(namstdout(seqno, mid), O_WRONLY|O_APPEND);
	    if (fd_out < 0) {
		perror ("Error opening request's stdout file");
		exit(1);
	    }
	}
	/*
	 *  Copy the message to stderr and/or stdout.
	 */
	while ((i = read(0, buffer, sizeof(buffer))) > 0) {
	    if (errflag) {
	        if (write(fd_err, buffer, i) < 0) {
	            perror ("Error writing to request's stderr file");
		    exit(1);
		}
	    }
	    if (outflag) {
		if (write(fd_out, buffer, i) < 0) {
		    perror ("Error writing to request's stderr file");
		    exit(1);
		}
	    }
	}
	if (i < 0) {
	    perror ("Error reading message");
	    exit(1);
	}
	exit (0);
}


/*** qmsg_usage
 *
 *
 *	qmsg_usage():
 *	Show how to use this command.
 */
static void qmsg_usage()
{
    fprintf (stderr, "qmsg -- write message to NQS request log or error file\n");
    fprintf (stderr, "usage:    qmsg [-e] [-o] [-v] <request-id>\n");
    fprintf (stderr, " -e            append to stderr file (the default)\n");
    fprintf (stderr, " -o            append to stdout file\n");
    fprintf (stderr, " -v            print version information\n");
    fprintf (stderr, " <request-id>  NQS request identifier\n");
    exit (1);
}

/*** qmsg_version
 *
 *
 *	qmsg_version():
 *	Show the current version of this program.
 */
static void qmsg_version()
{
    fprintf (stderr, "NQS Version %s\n", NQS_VERSION);
    exit (1);
}
