/**********************************************************************/
/*                                                                    */
/* Copyright (c) 2001 by Sun Microsystems, Inc.                       */
/* All rights reserved.                                               */
/*                                                                    */
/**********************************************************************/


/* $Date:   19 Sep 2001 16:44:10  $ */
/* $Modtime:   18 Sep 2001 16:38:20  $ */

/* $Workfile:   kixmqtst.c  $ $Revision:   1.0  $ */

/*
 * $Log:   /unikix/source2/SunMTP7.2.0/unikixsrc/test/mq/PVCS/kixmqtst.c_v  $
 * 
 *    Rev 1.0   19 Sep 2001 16:44:10   unikix
 * Initial 7.2
 * 
 *    Rev 1.0   30 Jan 2000 11:45:20   unikix
 * Initial 7.0
 * 
 *    Rev 1.0   15 Mar 1999 19:57:52   unikix
 * Initial 6.0
 * 
 *    Rev 1.1   22 Feb 1999 10:38:30   chuckb
 * D003643
 * Ensure buffer is larger enough for a terminating NUL character.
 * Replace tab and CR characters with space, since the recommended
 * test procedure, display of the result queue with CEBR,
 * mangles lines with these characters (at least using unikixl on NT) --
 * it appears that a tab within a CEBR display line is positioned
 * at the input data field (where an input tab character would go).
 * 
 *    Rev 1.0   05/22/97 17:10:56   unikix
 * Initial 5.1
 * 
 *    Rev 1.0   08/26/96 16:32:32   rick
 * Initial revision.
*/

/************************************************************************/
/* kixmqtst								*/
/* --------								*/
/*   This program is a sample for use with Sun MTP and MQSeries. It's	*/
/*   purpose is to write the contents of a file onto an MQSeries	*/
/*   queue. When this queue is set up using the kixmqtst.mqconfig	*/
/*   runmqsc script, and Sun MTP is up with a Trigger queue processor	*/
/*   the transaction XXXX will be run which will copy the messages	*/
/*   from the queue onto a Sun MTP Temp Storage Queue			*/
/************************************************************************/

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#include <cmqc.h>		/* MQSeries Header file			*/
#include "kixmqerr.h"		/* Error code header file		*/

/*
** getopt() needs this
*/
extern char *optarg;


static char InputFileName[256];
static char QueueManager[48];
static char QueueName[48];


#ifdef __STDC__
int main( int ArgC, char **ArgV )
#else
int main( ArgC , ArgV )
int ArgC;
char **ArgV;
#endif
{
    char	*Buffer;	/* Block containing whole of i/p file	*/
    char	*pLine;		/* Start of a line of text		*/
    char	*pLineEnd;	/* End of a line of text		*/
    MQHCONN	hConn;
    MQLONG	CompCode;
    MQLONG	Reason;
    MQOD	ObjDesc;
    MQHOBJ	hObj_Queue;
    MQLONG	Options;
    MQMD	Descriptor;
    MQPMO	PutOptions;
    MQLONG	LineLen;	/* Length of the line passed to MQ	*/
    int		c;		/* Char used in getopt()		*/
    FILE	*fp;		/* File to read from			*/
    int		rc;		/* General Return code			*/
    struct stat sb;		/* Returned from stat()			*/

    /********************************************************************/
    /* Initialize values						*/
    /********************************************************************/
    QueueManager[0]	= '\0';
    QueueName[0]	= '\0';
    InputFileName[0]	= '\0';

    /********************************************************************/
    /* Get parameters							*/
    /********************************************************************/
    while (( c = getopt( ArgC, ArgV, ":m:q:i:h" )) != -1 )
    {
	switch(c)
	{
	    case 'i':
		strcpy(InputFileName,optarg);
		break;
	    case 'm':
		strcpy(QueueManager,optarg);
		break;
	    case 'q':
		strcpy(QueueName,optarg);
		break;
	    case 'h':
	    case '?':
		exit(0);
		break;
	}
    }

    /********************************************************************/
    /* Check parameters							*/
    /********************************************************************/
    if ( InputFileName[0] == '\0' )
    {
	fprintf(stderr, "Please specify a file\n");
	exit(1);
    }

    rc = stat(InputFileName,&sb);
    if ( rc != 0 )
    {
	fprintf(stderr, "File <%s> is bad!\n",InputFileName);
	exit(1);
    }

    /********************************************************************/
    /* Get the data from the file - Note this may cause problems	*/
    /*                                   if the file is too big		*/
    /********************************************************************/
    fp = fopen(InputFileName,"r");
    if ( fp == (FILE *)NULL )
    {
	fprintf(stderr, "File <%s> fopen() failed!\n",InputFileName);
	exit(1);
    }

    Buffer = (char *)malloc(sb.st_size+1);	/* Add a byte for a \0 */

    rc = fread(Buffer,1,sb.st_size,fp);
    if ( rc <= 0 )
    {
	fprintf(stderr, "File <%s> fread() failed [%d]!\n",InputFileName,rc);
	fclose(fp);
	exit(1);
    }

    fclose(fp);

    /********************************************************************/
    /* Ensure there is a null at the end so we our later loop works	*/
    /********************************************************************/
    Buffer[sb.st_size]='\0';

    /********************************************************************/
    /* Replace tabs and CRs with spaces to make the output look OK in	*/
    /* CEBR								*/
    /********************************************************************/
    {
	int i;
	for ( i=0;i<sb.st_size;i++ )
	{
	    switch ( Buffer[i] )
	    {
		case '\r':
		case '\t':
		    Buffer[i] = ' ';
		    break;
	    }
	}
    }

    printf("kixmqtst: Writing file to [%s][%s] ...",QueueManager,QueueName);
    fflush(stdout);

    /********************************************************************/
    /* Connect to the queue manager					*/
    /********************************************************************/
    MQCONN( QueueManager , &hConn, &CompCode, &Reason );
    CHECK_RC( "MQCONN", CompCode, Reason );

    /********************************************************************/
    /* Open a Queue							*/
    /********************************************************************/
    memcpy(ObjDesc.StrucId, MQOD_STRUC_ID,sizeof( MQOD_STRUC_ID ));
    ObjDesc.Version		= MQOD_VERSION_1;
    ObjDesc.ObjectType		= MQOT_Q;
    strcpy(ObjDesc.ObjectName,QueueName);
    ObjDesc.ObjectQMgrName[0]	= '\0';
    ObjDesc.DynamicQName[0]	= '\0';
    ObjDesc.AlternateUserId[0]	= '\0';

    Options =	MQOO_OUTPUT;

    MQOPEN( hConn, &ObjDesc, Options, &hObj_Queue, &CompCode, &Reason );
    CHECK_RC( "MQOPEN", CompCode, Reason );

    /********************************************************************/
    /* For each line, put it on the queue				*/
    /********************************************************************/
    pLine=Buffer;
    while ( *pLine != '\0' )
    {
	/****************************************************************/
	/* Find the end of the line					*/
	/****************************************************************/
	pLineEnd = strchr(pLine,'\n');
	if ( pLineEnd == (char *)NULL )
	{
	    pLineEnd = pLine+strlen(pLine)+1;
	}

	/****************************************************************/
	/* Write to then Queue						*/
	/****************************************************************/
	memcpy(Descriptor.StrucId, MQMD_STRUC_ID,sizeof( MQMD_STRUC_ID ));
	Descriptor.Version            = MQMD_VERSION_1;
	Descriptor.Report             = MQRO_NONE;
	Descriptor.MsgType            = MQMT_DATAGRAM;
	Descriptor.Expiry             = MQEI_UNLIMITED;
	Descriptor.Feedback           = MQFB_NONE;
	Descriptor.Encoding           = MQENC_NATIVE;
	Descriptor.CodedCharSetId     = MQCCSI_Q_MGR;
	memcpy(Descriptor.Format, MQFMT_NONE,sizeof( MQFMT_NONE ));
	Descriptor.Priority           = MQPRI_PRIORITY_AS_Q_DEF;
	Descriptor.Persistence        = MQPER_PERSISTENCE_AS_Q_DEF;
	Descriptor.BackoutCount       = 0;
	Descriptor.ReplyToQ[0]        = '\0';
	Descriptor.ReplyToQMgr[0]     = '\0';
	Descriptor.UserIdentifier[0]  = '\0';
	memcpy(Descriptor.AccountingToken, MQACT_NONE,sizeof( MQACT_NONE ));

	memcpy(PutOptions.StrucId, MQPMO_STRUC_ID,sizeof( MQPMO_STRUC_ID ));
	PutOptions.Version            = MQPMO_VERSION_1;
	PutOptions.Options            = MQPMO_DEFAULT_CONTEXT;
	PutOptions.Timeout            = 50000;	/* !!!!! */

	LineLen=pLineEnd-pLine;

	memcpy(Descriptor.MsgId, MQMI_NONE,sizeof( MQMI_NONE ));
	memcpy(Descriptor.CorrelId, MQCI_NONE,sizeof( MQCI_NONE ));

	MQPUT( hConn, hObj_Queue, &Descriptor, &PutOptions, LineLen, pLine,
		    &CompCode, &Reason );
	CHECK_RC( "MQPUT", CompCode, Reason );

	/****************************************************************/
	/* Move to next line						*/
	/****************************************************************/
	if ( *pLineEnd != '\0' )
	{
	    pLine = pLineEnd+1;
	}
	else
	{
	    pLine = pLineEnd;
	}
    }

    /********************************************************************/
    /* Close the Queue							*/
    /********************************************************************/
    Options =	MQCO_NONE;

    MQCLOSE( hConn, &hObj_Queue, Options, &CompCode, &Reason );
    CHECK_RC( "MQCLOSE", CompCode, Reason );

    /********************************************************************/
    /* Disconnect from the queue manager				*/
    /********************************************************************/
    MQDISC( &hConn, &CompCode, &Reason );
    CHECK_RC( "MQDISC", CompCode, Reason );

    printf(" Done\n");

    /********************************************************************/
    /* Free the buffer							*/
    /********************************************************************/
    free(Buffer);

    exit(0);
}
