/**********************************************************
***
***						LISTING 2
***
***						holder.c
***
***		Program to illustrate message passing under QNX.
***		Written and tested under QNX version 2.15C atp
***		Compiler used:  Quantum's C compiler
***
***		holder.c is meant to be run in the background and
***		provides the following services to the sender.c 
***		(listing 3) program:
***
***		1)  Store a text string.
***		2)  Reply with a previously stored string.
***		3)  Commit suicide.
***
***		The action carried out depends on the value of the
***		header word of the message that sender.c sends to
***		holder.c.
***
**********************************************************/

#include <stdio.h>
#include <task_msgs.h>
#include "message.h"


#define INIT_MSG		"*** No stored messages ***"

main(argc, argv)
int argc;
char **argv;
{
	unsigned stid;				/* Variable to hold 
                                   sender's task id.    */
	unsigned rtid;				/* Variable to hold 
                                   this task's task id. */
	struct message buff, rbuff;	/* Message buffers      */
	extern char Cmd_flags;		/* Magic variable		*/
/*
	If any arguments have been passed to this program or if
	the program has not been run in background mode, print
	a command usage message and exit.
*/
	if (argc != 1 || (Cmd_flags & RUN_BACKGROUND) == 0 )
	{
		printf("\nUsage:   holder &\n");
		exit(-1);
	}
/*
	Register a name with the operating system so that other
	tasks can find out its task id.
*/
	if((rtid = name_attach(HOLDER_NAME, 0)) == 0)
	{
		printf("\nholder task couldn't attach name\n");
		exit(-1);
	}
/*
	Initialize the reply buffer with an initial text 
	string.
*/
	strcpy(rbuff.text, INIT_MSG);

/*
	Now wait for a message.  Upon receiving a message, 
	carry out the appropriate action based on the header
	word of the message.  Then reply with the result to
	the sending task.
*/
	for (;;)
	{
		stid = receive(0, &buff, sizeof(buff) );
		switch (buff.mssg_type)
		{
			case STORE:
				strcpy(rbuff.text, buff.text);
				rbuff.mssg_type = STORED;
				break;
			case RETRIEVE:
				rbuff.mssg_type = RETRIEVED;
				break;
			case KILL:	/* de-register name & die. */
				name_detach(HOLDER_NAME, rtid);
				exit(0);
				break;
			default:
				rbuff.mssg_type = ERROR;
				break;
		}
		reply(stid, &rbuff, sizeof(rbuff) );
	}

}

