/*******************************************************************************
 * Copyright (c) 2005, 2009 Intel Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Andy Kaylor, Intel - Initial API and Implementation
 *    IBM - Portions of processing code moved from older RAC (by Andy Kaylor)
 *
 * $Id: RACSupport.c,v 1.13 2009/08/26 14:59:59 jwest Exp $
 *
 *******************************************************************************/ 

#include "tptp/TPTPTypes.h"
#include "tptp/TPTPSupportTypes.h"
#include "tptp/TPTPSupportUtils.h"
#include "tptp/BaseTLLog.h"
#include "tptp/compatibility/RACSupport.h"

#ifndef _WIN32
#include <sys/time.h>
#include <stdlib.h>
#endif

/**
  * Function prototypes
  */
static unsigned char* copyRAUINTToBuffer(unsigned char *buffer, ra_uint_t uintData);
static unsigned char* readRAUINTFromBuffer(unsigned char *buffer, ra_uint_t *uint);
static unsigned char* copyRASTRINGToBuffer(unsigned char *buffer, ra_string_t *stringData);
static unsigned char* copyRABinaryArrayToBuffer(unsigned char *buffer, ra_string_t *binaryData);
static unsigned char* readRASTRINGFromBuffer(unsigned char *buffer, ra_string_t *newString);
static unsigned char* readRABinaryArrayFromBuffer(unsigned char *buffer, ra_string_t *newArray);
static int determineRASTRINGSize(ra_string_t *rastring);
static int determineRABinaryArraySize(ra_string_t *rastring);

/** DETERMINE_MESSAGE_LENGTH  ***************************************************
  * DEtermines the size buffer required to fit the information that is stored in
  * the specified ra_message_t structure.
  * @param  message - the message to determine the length of.
  * @returns     >0 - the size of buffser required.
  *               0 - the message parameter was NULL
  */
int ra_determineMessageLength(ra_message_t *message) {
	if(!message) {
		return 0;
	}

	/* Acknowledgement messages are all the same length */
	if(message->type == RA_ACKNOWLEDGEMENT_MESSAGE) {
		return 4*sizeof(ra_uint_t);
	}

	/* Control messages */
	if(message->type == RA_CONTROL_MESSAGE) {
		ra_command_list_node_t *current;
		int currentSize=5*sizeof(ra_uint_t);
		/* Add the key */
		currentSize+=determineRASTRINGSize(&message->key);
		/* add the count */
		currentSize+=sizeof(ra_uint_t);


		/* Walk the command list determining the length of each command */
		current=message->commands.head;
		while(current != NULL) {
			/* Add the tag size */
			ra_command_t *command=current->command;
			currentSize+=sizeof(ra_uint_t);
			switch(command->tag) {
				unsigned int i;
			case RA_AUTHENTICATE:
				currentSize+=determineRASTRINGSize(&command->info.authenticate.user);
				currentSize+=determineRASTRINGSize(&command->info.authenticate.passwd);
				break;
			case RA_AUTHENTICATION_SUCCESSFUL:
				currentSize+=determineRASTRINGSize(&command->info.authenticate_successful.key);
				break;
			case RA_AUTHENTICATION_FAILED:
				currentSize+=sizeof(ra_uint_t);
				break;
            case RA_SERVER_SECURITY_REQUIREMENTS:
                currentSize+=2*sizeof(ra_uint_t);
                break;
			case RA_LAUNCH_PROCESS:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.launch_process.executable);
				currentSize+=determineRASTRINGSize(&command->info.launch_process.arguments);
				currentSize+=determineRASTRINGSize(&command->info.launch_process.location);
				currentSize+=sizeof(ra_uint_t);
				if(command->info.launch_process.environment.length) {
					for(i=0; i<command->info.launch_process.environment.length; i++) {
						currentSize+=determineRASTRINGSize(((ra_string_t*)((ra_string_t**)command->info.launch_process.environment.data)[i]));
					}
				}
				currentSize+=sizeof(ra_uint_t);
				if(command->info.launch_process.agents.length) {
					for(i=0; i<command->info.launch_process.agents.length; i++) {
						currentSize+=determineRASTRINGSize(((ra_string_t*)((ra_string_t**)command->info.launch_process.agents.data)[i]));
					}
				}
				break;
			case RA_PROCESS_LAUNCHED:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.process_launched.executable);
				currentSize+=determineRASTRINGSize(&command->info.process_launched.arguments);
				currentSize+=determineRASTRINGSize(&command->info.process_launched.processUUID);
				currentSize+=sizeof(ra_uint_t);
				if(command->info.process_launched.environment.length) {
					for(i=0; i<command->info.process_launched.environment.length; i++) {
						currentSize+=determineRASTRINGSize(((ra_string_t*)((ra_string_t**)command->info.process_launched.environment.data)[i]));
					}
				}
				break;
			case RA_REGISTER_AGENT_NOTIFICATION:
			case RA_QUERY_AGENT_DETAILS:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.register_agent_notification.agent);
				break;
			case RA_QUERY_PROCESS_LIST:
				currentSize+=sizeof(ra_uint_t);
				break;
			case RA_PROCESS_LIST:
				currentSize+=sizeof(ra_uint_t);
				currentSize+=sizeof(ra_uint_t) * (1+command->info.registered_process_list.processes.length);
				break;
			case RA_QUERY_AGENT_LIST:
			case RA_KILL_PROCESS:
			case RA_PROCESS_EXITED:
				currentSize+=2*sizeof(ra_uint_t);
				break;
			case RA_AGENT_LIST:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.registered_agents_list.executable);
				if(command->info.registered_agents_list.agents.length) {
					for(i=0; i<command->info.registered_agents_list.agents.length; i++) {
						currentSize+=determineRASTRINGSize(((ra_string_t*)((ra_string_t**)command->info.registered_agents_list.agents.data)[i]));
					}
				}
				break;
			case RA_ATTACH_TO_AGENT:
			case RA_DETACH_FROM_AGENT:
			case RA_STOP_MONITORING_AGENT:
			case RA_AGENT_QUERY_STATE: /* Bug 54376 */
			case RA_AGENT_ATTACHED: /* Bug 54376 */
			case RA_AGENT_DETACHED: /* Bug 54376 */
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.attach.agent);
				break;
			case RA_ERROR_STRING:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.error_string.agent);
				currentSize+=determineRASTRINGSize(&command->info.error_string.messageId);
				currentSize+=determineRASTRINGSize(&command->info.error_string.message);
				break;
			case RA_START_MONITORING_AGENT_REMOTE:
				currentSize+=4*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.start_monitor_remote.agent);
				break;
			case RA_START_MONITORING_AGENT_LOCAL:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.start_monitor_local.agent);
				currentSize+=determineRASTRINGSize(&command->info.start_monitor_local.file);
				break;
			case RA_SET_NAME_VALUE_PAIR:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.set_nv_pair.agent);
				currentSize+=determineRASTRINGSize(&command->info.set_nv_pair.type);
				currentSize+=determineRASTRINGSize(&command->info.set_nv_pair.name);
				currentSize+=determineRASTRINGSize(&command->info.set_nv_pair.value);
				break;
			case RA_CUSTOM_COMMAND:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.custom_command.agent);
				currentSize+=determineRASTRINGSize(&command->info.custom_command.message);
				break;
            case RA_BINARY_CUSTOM_COMMAND: /* Bug 73074 */
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.custom_command.agent);
				currentSize+=determineRABinaryArraySize(&command->info.custom_command.message);
				break;
			case RA_AGENT_ACTIVE:
			case RA_AGENT_INACTIVE:
			case RA_AGENT_DETAILS:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.agent_active.agent);
				currentSize+=determineRASTRINGSize(&command->info.agent_active.processUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_active.agentUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_active.agentType);
				break;
			case RA_AGENT_SCOPING_INFORMATION:
				currentSize+=2*sizeof(ra_uint_t);
/* BEGIN:  235649 */
#if defined __linux__
				currentSize+=sizeof(ra_uint_t);
#endif
/* END: 235649 */
				currentSize+=determineRASTRINGSize(&command->info.agent_scoping_information.processUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_scoping_information.agent);
				currentSize+=determineRASTRINGSize(&command->info.agent_scoping_information.agentUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_scoping_information.agentType);
				currentSize+=determineRASTRINGSize(&command->info.agent_scoping_information.nodeUUID);
				break;
			case RA_AGENT_CONFIGURATION:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.agent_configuration.processUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_configuration.agent);
				currentSize+=determineRASTRINGSize(&command->info.agent_configuration.agentUUID);
				currentSize+=determineRASTRINGSize(&command->info.agent_configuration.agentType);
				currentSize+=determineRASTRINGSize(&command->info.agent_configuration.nodeUUID);
				if(command->info.agent_configuration.configuration.length) {
					for(i=0; i<command->info.agent_configuration.configuration.length; i++) {
						ra_agentConfigEntry_t *entry=((ra_agentConfigEntry_t*)(command->info.agent_configuration.configuration.data[i]));
						currentSize+=determineRASTRINGSize(&entry->type);
						currentSize+=determineRASTRINGSize(&entry->name);
						currentSize+=determineRASTRINGSize(&entry->value);
					}
				}
				break;
			case RA_AGENT_CONTROLER_AVAILABLE:
			case RA_AGENT_CONTROLER_UNAVAILABLE:
				currentSize+=determineRASTRINGSize(&command->info.agentName);
				break;
			case RA_AGENT_REQUEST_MONITOR:
			case RA_CONTROLLER_REQUEST_MONITOR:
			case RA_PEER_UNREACHABLE:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.agent);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.node);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.peerAgent);
				currentSize+=determineRABinaryArraySize(&command->info.agent_request_monitor.peerNode); /* Bug 80893 */
				break;
			/* Bug 77768 begins */
			case RA_AGENT_REQUEST_MONITOR_PORT:
			case RA_CONTROLLER_REQUEST_MONITOR_PORT:
				currentSize+=3*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.agent);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.node);
				currentSize+=determineRASTRINGSize(&command->info.agent_request_monitor.peerAgent);
				currentSize+=determineRABinaryArraySize(&command->info.agent_request_monitor.peerNode);
				currentSize+=2*sizeof(ra_uint_t); /* The 2 ports */
				break;
			/* Bug 77768 ends */
			case RA_GET_PROPERTY_LIST:
				currentSize+=sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.query_property_list.name);
				currentSize+=determineRASTRINGSize(&command->info.query_property_list.type);
				currentSize+=determineRASTRINGSize(&command->info.query_property_list.agentUUID);
				break;
			case RA_PROPERTY_LIST:
				/* ra_agentConfigEntry_t */
				currentSize+=sizeof(ra_uint_t); /* context */

				/* array length */
				currentSize += sizeof(ra_uint_t);
				/* Names, Types, Values */
				if(command->info.property_list.entries.length) {
					for(i = 0; i < command->info.property_list.entries.length; i++) {
						currentSize += determineRASTRINGSize(&(((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->name));
						currentSize += determineRASTRINGSize(&(((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->type));
						currentSize += determineRASTRINGSize(&(((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->value));
					}
				}
				break;
			/** Added by Giridhar.S on 13/2/04 **/
			case RA_MANAGE_FILE:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.manage_file.filename);
				break;
			case RA_RESOURCE_LOCATION:
				currentSize+=2*sizeof(ra_uint_t);
				currentSize+=determineRASTRINGSize(&command->info.resource_location.jobKey);
				break;
			} /* switch */
			current=current->next;
		} /* while */
		message->length=currentSize;
		return currentSize;
	} /* if*/
	return 0;
}

/** WRITE_MESSAGE_TO_BUFFER  **************************************************
  * Walks the data structure associted with a message and formats this into a
  * buffer that can then be transfered over a TCP connection.
  * @param       buffer - the previously allocated buffer to copy the message data to.
  * @param bufferLength - the length of the buffer.
  * @param      message - the message data structure to extract the data from.
  * @returns         >0 - the length of the buffer used for the message.
  *                  <0 - buffer is not large enough.
  */
unsigned int ra_writeMessageToBuffer(unsigned char *buffer,
									 unsigned int bufferLength,
									 ra_message_t *message) {
	unsigned char *current;
	ra_command_list_node_t *currentNode;
#ifdef MVS
	unsigned char *tmpbuf;
   unsigned int msglen;
#endif

	/* Is the buffer large enough for the header information */
	if(bufferLength < 12 ) {
		return -1;
	}

#ifdef MVS
/* 190770 - allocate temporary buffer for message to include an extra byte at the end
            for use by copyRASTRINGToBuffer - only necessary for non acknowledgement
            messages */
	if(message->type != RA_ACKNOWLEDGEMENT_MESSAGE) {
      tmpbuf = (unsigned char *)ra_malloc(bufferLength+1);
      current = tmpbuf;
   }
   else {
      current = buffer;
   }
#else
	current=buffer;
#endif

	/* Place the header information in the buffer */
	current=copyRAUINTToBuffer(current, RA_MAGIC);
	current=copyRAUINTToBuffer(current, RA_VERSION);
	current=copyRAUINTToBuffer(current, message->type);
	current=copyRAUINTToBuffer(current, message->ticket);

	if(message->type == RA_ACKNOWLEDGEMENT_MESSAGE) {
		return current-buffer;
	}

	current=copyRAUINTToBuffer(current, message->length);

	/* Is there enough room to add the key? */
#ifdef MVS
	if(bufferLength-(current-tmpbuf) < message->key.length+4 ) {
/* 190770 - copy what we already have to the real message buffer and ra_free the temp space */
      memcpy(buffer, tmpbuf, current-tmpbuf);
      ra_free(tmpbuf);
#else
	if(bufferLength-(current-buffer) < message->key.length+4 ) {
#endif
		return -1;
	}
	current=copyRASTRINGToBuffer(current, &message->key);

	/* Place the command count if there is room */
#ifdef MVS
	if(bufferLength-(current-tmpbuf) < 4 ) {
/* 190770 - copy what we already have to the real message buffer and ra_free the temp space */
      memcpy(buffer, tmpbuf, current-tmpbuf);
      ra_free(tmpbuf);
#else
	if(bufferLength-(current-buffer) < 4 ) {
#endif
		return -1;
	}
	current=copyRAUINTToBuffer(current, message->commands.count);



	/* Copy each of the commands in turn */
	currentNode=message->commands.head;
	while(currentNode != NULL) {
		current=copyRAUINTToBuffer(current, currentNode->command->tag);
		switch(currentNode->command->tag) {
			ra_uint_t i;
		case RA_AUTHENTICATE:
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.authenticate.user);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.authenticate.passwd);
			break;
		case RA_AUTHENTICATION_SUCCESSFUL:
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.authenticate_successful.key);
			break;
		case RA_AUTHENTICATION_FAILED:
            current=copyRAUINTToBuffer(current, currentNode->command->info.authenticate_failed.ticket);
            break;
        case RA_SERVER_SECURITY_REQUIREMENTS:
            current=copyRAUINTToBuffer(current, currentNode->command->info.serverSecurityRequirements.flag);
            current=copyRAUINTToBuffer(current, currentNode->command->info.serverSecurityRequirements.securePort);
            break;
        case RA_QUERY_PROCESS_LIST:
			current=copyRAUINTToBuffer(current, currentNode->command->info.query_process_list.context);
			break;
		case RA_LAUNCH_PROCESS:
			current=copyRAUINTToBuffer(current, currentNode->command->info.launch_process.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.launch_process.consoleIP);
			current=copyRAUINTToBuffer(current, currentNode->command->info.launch_process.consolePort);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.launch_process.executable);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.launch_process.arguments);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.launch_process.location);
			current=copyRAUINTToBuffer(current, currentNode->command->info.launch_process.environment.length);
			for(i=0; i<currentNode->command->info.launch_process.environment.length; i++) {
#ifdef _HPUX
				current=copyRASTRINGToBuffer(current, (ra_string_t *)currentNode->command->info.launch_process.environment.data[i]);
#else
				current=copyRASTRINGToBuffer(current, currentNode->command->info.launch_process.environment.data[i]);
#endif
			}
			current=copyRAUINTToBuffer(current, currentNode->command->info.launch_process.agents.length);
			for(i=0; i<currentNode->command->info.launch_process.agents.length; i++) {
#ifdef _HPUX
				current=copyRASTRINGToBuffer(current, (ra_string_t *)currentNode->command->info.launch_process.agents.data[i]);
#else
				current=copyRASTRINGToBuffer(current, currentNode->command->info.launch_process.agents.data[i]);
#endif
			}
			break;
		case RA_PROCESS_LAUNCHED:
			current=copyRAUINTToBuffer(current, currentNode->command->info.process_launched.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.process_launched.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.process_launched.processUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.process_launched.executable);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.process_launched.arguments);
			current=copyRAUINTToBuffer(current, currentNode->command->info.process_launched.environment.length);
			for(i=0; i<currentNode->command->info.process_launched.environment.length; i++) {
				current=copyRASTRINGToBuffer(current, (ra_string_t *)currentNode->command->info.process_launched.environment.data[i]);
			}
			break;
		case RA_PROCESS_LIST:
			current=copyRAUINTToBuffer(current, currentNode->command->info.registered_process_list.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.registered_process_list.processes.length);
			for(i=0; i<currentNode->command->info.registered_process_list.processes.length; i++) {
				current=copyRAUINTToBuffer(current, *((ra_uint_t*)(currentNode->command->info.registered_process_list.processes.data[i])));
			}
			break;
		case RA_QUERY_AGENT_LIST:
		case RA_KILL_PROCESS:
		case RA_PROCESS_EXITED:
			current=copyRAUINTToBuffer(current, currentNode->command->info.query_agent_list.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.query_agent_list.processId);
			break;
		case RA_AGENT_LIST:
			current=copyRAUINTToBuffer(current, currentNode->command->info.registered_agents_list.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.registered_agents_list.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.registered_agents_list.executable);
			current=copyRAUINTToBuffer(current, currentNode->command->info.registered_agents_list.agents.length);
			for(i=0; i<currentNode->command->info.registered_agents_list.agents.length; i++) {
				current=copyRASTRINGToBuffer(current, (ra_string_t *)currentNode->command->info.registered_agents_list.agents.data[i]);
			}
			break;
		case RA_REGISTER_AGENT_NOTIFICATION:
		case RA_QUERY_AGENT_DETAILS:
			current=copyRAUINTToBuffer(current, currentNode->command->info.register_agent_notification.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.register_agent_notification.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.register_agent_notification.agent);
			break;
		case RA_ATTACH_TO_AGENT:
		case RA_DETACH_FROM_AGENT:
		case RA_STOP_MONITORING_AGENT:
		case RA_AGENT_QUERY_STATE: /* Bug 54376 */
		case RA_AGENT_ATTACHED: /* Bug 54376 */
		case RA_AGENT_DETACHED: /* Bug 54376 */
			current=copyRAUINTToBuffer(current, currentNode->command->info.attach.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.attach.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.attach.agent);
			break;
		case RA_ERROR_STRING:
			current=copyRAUINTToBuffer(current, currentNode->command->info.error_string.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.error_string.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.error_string.agent);
			current=copyRAUINTToBuffer(current, currentNode->command->info.error_string.severity);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.error_string.messageId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.error_string.message);
			break;
		case RA_START_MONITORING_AGENT_REMOTE:
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_remote.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_remote.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.start_monitor_remote.agent);
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_remote.ip);
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_remote.port);
			break;
		case RA_START_MONITORING_AGENT_LOCAL:
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_local.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.start_monitor_local.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.start_monitor_local.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.start_monitor_local.file);
			break;
		case RA_SET_NAME_VALUE_PAIR:
			current=copyRAUINTToBuffer(current, currentNode->command->info.set_nv_pair.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.set_nv_pair.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.set_nv_pair.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.set_nv_pair.type);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.set_nv_pair.name);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.set_nv_pair.value);
			break;
		case RA_CUSTOM_COMMAND:
			current=copyRAUINTToBuffer(current, currentNode->command->info.custom_command.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.custom_command.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.custom_command.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.custom_command.message);
			break;
        case RA_BINARY_CUSTOM_COMMAND:
            current=copyRAUINTToBuffer(current, currentNode->command->info.custom_command.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.custom_command.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.custom_command.agent);
			current=copyRABinaryArrayToBuffer(current, &currentNode->command->info.custom_command.message);
			break;
		case RA_AGENT_ACTIVE:
		case RA_AGENT_INACTIVE:
		case RA_AGENT_DETAILS:
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_active.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_active.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_active.processUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_active.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_active.agentUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_active.agentType);
			break;
		case RA_AGENT_SCOPING_INFORMATION:
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_scoping_information.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_scoping_information.processId);
/* BEGIN:  235649 */
#if defined __linux__
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_scoping_information.messageProcessId);
#endif
/* END: 235649 */
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_scoping_information.processUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_scoping_information.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_scoping_information.agentUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_scoping_information.agentType);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_scoping_information.nodeUUID);
			break;
		case RA_AGENT_CONFIGURATION:
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_configuration.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_configuration.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_configuration.processUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_configuration.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_configuration.agentUUID);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_configuration.agentType);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_configuration.nodeUUID);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_configuration.configuration.length);
			for(i=0; i<currentNode->command->info.agent_configuration.configuration.length; i++) {
				ra_agentConfigEntry_t *entry=((ra_agentConfigEntry_t**)currentNode->command->info.agent_configuration.configuration.data)[i];
				current=copyRASTRINGToBuffer(current, &entry->type);
				current=copyRASTRINGToBuffer(current, &entry->name);
				current=copyRASTRINGToBuffer(current, &entry->value);
			}
			break;
		case RA_AGENT_CONTROLER_AVAILABLE:
		case RA_AGENT_CONTROLER_UNAVAILABLE:
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agentName);
			break;
		case RA_AGENT_REQUEST_MONITOR:
		case RA_CONTROLLER_REQUEST_MONITOR:
		case RA_PEER_UNREACHABLE:
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor.node);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor.peerProcessId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor.peerAgent);
			current=copyRABinaryArrayToBuffer(current, &currentNode->command->info.agent_request_monitor.peerNode); /* Bug 80893 */
			break;
		/* Bug 77768 begins */
		case RA_AGENT_REQUEST_MONITOR_PORT:
		case RA_CONTROLLER_REQUEST_MONITOR_PORT:
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor_port.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor_port.processId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor_port.agent);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor_port.node);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor_port.peerProcessId);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.agent_request_monitor_port.peerAgent);
			current=copyRABinaryArrayToBuffer(current, &currentNode->command->info.agent_request_monitor_port.peerNode);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor_port.port);
			current=copyRAUINTToBuffer(current, currentNode->command->info.agent_request_monitor_port.peerPort);
			break;
		/* Bug 77768 ends */
		case RA_GET_PROPERTY_LIST:
			current=copyRAUINTToBuffer(current, currentNode->command->info.query_property_list.context);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.query_property_list.name);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.query_property_list.type);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.query_property_list.agentUUID);
			break;
		case RA_PROPERTY_LIST:
			/* contect */
			current=copyRAUINTToBuffer(current, currentNode->command->info.property_list.context);
			/* Array length */
			current=copyRAUINTToBuffer(current, currentNode->command->info.property_list.entries.length);
			/* Names, Types, Values */
			for(i = 0; i < currentNode->command->info.property_list.entries.length; i++) {
				current=copyRASTRINGToBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)currentNode->command->info.property_list.entries.data)[i]->name));
				current=copyRASTRINGToBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)currentNode->command->info.property_list.entries.data)[i]->type));
				current=copyRASTRINGToBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)currentNode->command->info.property_list.entries.data)[i]->value));
			}
			break;
		/** Added by Giridhar.S on 13/2/04 **/
		case RA_MANAGE_FILE:
			current=copyRAUINTToBuffer(current, currentNode->command->info.manage_file.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.manage_file.operation);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.manage_file.filename);
			break;
		case RA_RESOURCE_LOCATION:
			current=copyRAUINTToBuffer(current, currentNode->command->info.resource_location.context);
			current=copyRAUINTToBuffer(current, currentNode->command->info.resource_location.port);
			current=copyRASTRINGToBuffer(current, &currentNode->command->info.resource_location.jobKey);
			break;
		}

		currentNode=currentNode->next;
	}
#ifdef MVS
/* 190770 - calculate the message length, copy the message to the real buffer
            and ra_free the temp space */
   msglen = current-tmpbuf;
   memcpy(buffer, tmpbuf, msglen);
   ra_free(tmpbuf);
	return msglen;
#else
	return current-buffer;
#endif
}

/** READ_MESSAGE_FROM_BUFFER  *************************************************
  * Read a buffer and create a message_t data structure with all the information
  * contained in the buffer.  Use ra_destroyMessage() to tptp_free the associated memory
  * for the message_t structure when finished with it.
  * @param        buffer - the buffer with the data for the message.
  * @param messageLength - the length of the buffer containing the message data.
  * @returns       !NULL - the address of the message created.
  *                 NULL - invalid message data.
  */
ra_message_t* ra_readMessageFromBuffer(unsigned char *buffer,
									   unsigned long messageLength) {

	ra_message_t *message;
	ra_uint_t type, ticket, i, count;
	unsigned char *current;

	/* Extract the type and ticket from the raw buffer and then create the message object */
	current=readRAUINTFromBuffer(&buffer[8], &type);
	current=readRAUINTFromBuffer(current, &ticket);

	message=ra_createMessage(type, ticket);

	/* Was this a valid message type */
	if(!message) {
		return NULL;
	}

	/* If this is an acknowledgment message this is the end of the message */
	if(message->type == RA_ACKNOWLEDGEMENT_MESSAGE) {
		return message;
	}

	current=readRAUINTFromBuffer(current, &message->length);

	/* Extract the key */
	current=readRASTRINGFromBuffer(current, &message->key);


	/* Get the command count */
	current=readRAUINTFromBuffer(current, &count);

	/* Collect each command in turn */
	for(i=0; i<count; i++) {
		/* Allocate the new command */
		ra_command_t *command=(ra_command_t*)tptp_malloc(sizeof(ra_command_t));
		current=readRAUINTFromBuffer(current, &command->tag);
		switch(command->tag) {
			ra_uint_t i;
		case RA_AUTHENTICATE:
			current=readRASTRINGFromBuffer(current, &command->info.authenticate.user);
			current=readRASTRINGFromBuffer(current, &command->info.authenticate.passwd);
			break;
		case RA_AUTHENTICATION_SUCCESSFUL:
			current=readRASTRINGFromBuffer(current, &command->info.authenticate_successful.key);
			break;
		case RA_AUTHENTICATION_FAILED:
			current=readRAUINTFromBuffer(current, &command->info.authenticate_failed.ticket);
			break;
        case RA_SERVER_SECURITY_REQUIREMENTS:
            current=readRAUINTFromBuffer(current, &command->info.serverSecurityRequirements.flag);
            current=readRAUINTFromBuffer(current, &command->info.serverSecurityRequirements.securePort);
            break;
		case RA_LAUNCH_PROCESS:
			current=readRAUINTFromBuffer(current, &command->info.launch_process.context);
			current=readRAUINTFromBuffer(current, &command->info.launch_process.consoleIP);
			current=readRAUINTFromBuffer(current, &command->info.launch_process.consolePort);
			current=readRASTRINGFromBuffer(current, &command->info.launch_process.executable);
			current=readRASTRINGFromBuffer(current, &command->info.launch_process.arguments);
			current=readRASTRINGFromBuffer(current, &command->info.launch_process.location);
			current=readRAUINTFromBuffer(current, &command->info.launch_process.environment.length);
			if(command->info.launch_process.environment.length) {
				command->info.launch_process.environment.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.launch_process.environment.length);
				for(i=0; i<command->info.launch_process.environment.length; i++) {
					((ra_string_t**)command->info.launch_process.environment.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
					current=readRASTRINGFromBuffer(current, ((ra_string_t*)(((ra_string_t**)command->info.launch_process.environment.data)[i])));
				}
			}
			current=readRAUINTFromBuffer(current, &command->info.launch_process.agents.length);
			if(command->info.launch_process.agents.length) {
				command->info.launch_process.agents.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.launch_process.agents.length);
				for(i=0; i<command->info.launch_process.agents.length; i++) {
					((ra_string_t**)command->info.launch_process.agents.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
					current=readRASTRINGFromBuffer(current, (ra_string_t*)(((ra_string_t**)command->info.launch_process.agents.data)[i]));
				}
			}
			break;
		case RA_PROCESS_LAUNCHED:
			current=readRAUINTFromBuffer(current, &command->info.process_launched.context);
			current=readRAUINTFromBuffer(current, &command->info.process_launched.processId);
			current=readRASTRINGFromBuffer(current, &command->info.process_launched.processUUID);
			current=readRASTRINGFromBuffer(current, &command->info.process_launched.executable);
			current=readRASTRINGFromBuffer(current, &command->info.process_launched.arguments);
			current=readRAUINTFromBuffer(current, &command->info.process_launched.environment.length);
			if(command->info.process_launched.environment.length) {
				command->info.process_launched.environment.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.process_launched.environment.length);
				for(i=0; i<command->info.process_launched.environment.length; i++) {
					((ra_string_t**)command->info.process_launched.environment.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
					current=readRASTRINGFromBuffer(current, (ra_string_t*)(((ra_string_t**)command->info.process_launched.environment.data)[i]));
				}
			}
			break;
		case RA_QUERY_PROCESS_LIST:
			current=readRAUINTFromBuffer(current, &command->info.query_process_list.context);
			break;
		case RA_PROCESS_LIST:
			current=readRAUINTFromBuffer(current, &command->info.registered_process_list.context);
			current=readRAUINTFromBuffer(current, &command->info.registered_process_list.processes.length);
			if(command->info.registered_process_list.processes.length) {
				command->info.registered_process_list.processes.data=(void**)tptp_malloc(sizeof(ra_uint_t*)*command->info.registered_process_list.processes.length);
				for(i=0; i<command->info.registered_process_list.processes.length; i++) {
					((ra_uint_t**)command->info.registered_process_list.processes.data)[i]=(ra_uint_t*)tptp_malloc(sizeof(ra_uint_t));
					current=readRAUINTFromBuffer(current, (ra_uint_t*)(((ra_uint_t**)command->info.registered_process_list.processes.data)[i]));
				}
			}
			break;
		case RA_QUERY_AGENT_LIST:
		case RA_KILL_PROCESS:
		case RA_PROCESS_EXITED:
			current=readRAUINTFromBuffer(current, &command->info.query_agent_list.context);
			current=readRAUINTFromBuffer(current, &command->info.query_agent_list.processId);
			break;
		case RA_AGENT_LIST:
			current=readRAUINTFromBuffer(current, &command->info.registered_agents_list.context);
			current=readRAUINTFromBuffer(current, &command->info.registered_agents_list.agents.length);
			current=readRASTRINGFromBuffer(current, &command->info.registered_agents_list.executable);
			command->info.registered_agents_list.agents.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.registered_agents_list.agents.length);
			if(command->info.registered_agents_list.agents.length) {
				for(i=0; i<command->info.registered_agents_list.agents.length; i++) {
					((ra_string_t**)command->info.registered_agents_list.agents.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
					current=readRASTRINGFromBuffer(current, (ra_string_t*)(((ra_string_t**)command->info.registered_agents_list.agents.data)[i]));
				}
			}
			break;
		case RA_REGISTER_AGENT_NOTIFICATION:
		case RA_QUERY_AGENT_DETAILS:
			current=readRAUINTFromBuffer(current, &command->info.register_agent_notification.context);
			current=readRAUINTFromBuffer(current, &command->info.register_agent_notification.processId);
			current=readRASTRINGFromBuffer(current, &command->info.register_agent_notification.agent);
			break;
		case RA_ATTACH_TO_AGENT:
		case RA_DETACH_FROM_AGENT:
		case RA_STOP_MONITORING_AGENT:
		case RA_AGENT_QUERY_STATE: /* Bug 54376 */
		case RA_AGENT_ATTACHED: /* Bug 54376 */
		case RA_AGENT_DETACHED: /* Bug 54376 */
			current=readRAUINTFromBuffer(current, &command->info.attach.context);
			current=readRAUINTFromBuffer(current, &command->info.attach.processId);
			current=readRASTRINGFromBuffer(current, &command->info.attach.agent);
			break;
		case RA_ERROR_STRING:
			current=readRAUINTFromBuffer(current, &command->info.error_string.context);
			current=readRAUINTFromBuffer(current, &command->info.error_string.processId);
			current=readRASTRINGFromBuffer(current, &command->info.error_string.agent);
			current=readRAUINTFromBuffer(current, &command->info.error_string.severity);
			current=readRASTRINGFromBuffer(current, &command->info.error_string.messageId);
			current=readRASTRINGFromBuffer(current, &command->info.error_string.message);
			break;
		case RA_START_MONITORING_AGENT_REMOTE:
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_remote.context);
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_remote.processId);
			current=readRASTRINGFromBuffer(current, &command->info.start_monitor_remote.agent);
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_remote.ip);
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_remote.port);
			break;
		case RA_START_MONITORING_AGENT_LOCAL:
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_local.context);
			current=readRAUINTFromBuffer(current, &command->info.start_monitor_local.processId);
			current=readRASTRINGFromBuffer(current, &command->info.start_monitor_local.agent);
			current=readRASTRINGFromBuffer(current, &command->info.start_monitor_local.file);
			break;
		case RA_SET_NAME_VALUE_PAIR:
			current=readRAUINTFromBuffer(current, &command->info.set_nv_pair.context);
			current=readRAUINTFromBuffer(current, &command->info.set_nv_pair.processId);
			current=readRASTRINGFromBuffer(current, &command->info.set_nv_pair.agent);
			current=readRASTRINGFromBuffer(current, &command->info.set_nv_pair.type);
			current=readRASTRINGFromBuffer(current, &command->info.set_nv_pair.name);
			current=readRASTRINGFromBuffer(current, &command->info.set_nv_pair.value);
			break;
		case RA_CUSTOM_COMMAND:
			current=readRAUINTFromBuffer(current, &command->info.custom_command.context);
			current=readRAUINTFromBuffer(current, &command->info.custom_command.processId);
			current=readRASTRINGFromBuffer(current, &command->info.custom_command.agent);
			current=readRASTRINGFromBuffer(current, &command->info.custom_command.message);
			break;
        case RA_BINARY_CUSTOM_COMMAND:
            current=readRAUINTFromBuffer(current, &command->info.custom_command.context);
			current=readRAUINTFromBuffer(current, &command->info.custom_command.processId);
			current=readRASTRINGFromBuffer(current, &command->info.custom_command.agent);
			current=readRABinaryArrayFromBuffer(current, &command->info.custom_command.message);
			break;
		case RA_AGENT_ACTIVE:
		case RA_AGENT_INACTIVE:
		case RA_AGENT_DETAILS:
			current=readRAUINTFromBuffer(current, &command->info.agent_active.context);
			current=readRAUINTFromBuffer(current, &command->info.agent_active.processId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_active.processUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_active.agent);
			current=readRASTRINGFromBuffer(current, &command->info.agent_active.agentUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_active.agentType);
			break;
		case RA_AGENT_SCOPING_INFORMATION:
			current=readRAUINTFromBuffer(current, &command->info.agent_scoping_information.context);
			current=readRAUINTFromBuffer(current, &command->info.agent_scoping_information.processId);
/* BEGIN:  235649 */
#if defined __linux__
			current=readRAUINTFromBuffer(current, &command->info.agent_scoping_information.messageProcessId);
#endif
/* END: 235649 */
			current=readRASTRINGFromBuffer(current, &command->info.agent_scoping_information.processUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_scoping_information.agent);
			current=readRASTRINGFromBuffer(current, &command->info.agent_scoping_information.agentUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_scoping_information.agentType);
			current=readRASTRINGFromBuffer(current, &command->info.agent_scoping_information.nodeUUID);
			break;
		case RA_AGENT_CONFIGURATION:
			current=readRAUINTFromBuffer(current, &command->info.agent_configuration.context);
			current=readRAUINTFromBuffer(current, &command->info.agent_configuration.processId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_configuration.processUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_configuration.agent);
			current=readRASTRINGFromBuffer(current, &command->info.agent_configuration.agentUUID);
			current=readRASTRINGFromBuffer(current, &command->info.agent_configuration.agentType);
			current=readRASTRINGFromBuffer(current, &command->info.agent_configuration.nodeUUID);
			current=readRAUINTFromBuffer(current, &command->info.agent_configuration.configuration.length);
			command->info.agent_configuration.configuration.data=(void**)tptp_malloc(sizeof(ra_agentConfigEntry_t*)*command->info.agent_configuration.configuration.length);
			if(command->info.agent_configuration.configuration.length) {
				for(i=0; i<command->info.agent_configuration.configuration.length; i++) {
					((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]=(ra_agentConfigEntry_t*)tptp_malloc(sizeof(ra_agentConfigEntry_t));
					current=readRASTRINGFromBuffer(current, &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->type);
					current=readRASTRINGFromBuffer(current, &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->name);
					current=readRASTRINGFromBuffer(current, &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->value);
				}
			}
			break;
		case RA_AGENT_CONTROLER_AVAILABLE:
		case RA_AGENT_CONTROLER_UNAVAILABLE:
			current=readRASTRINGFromBuffer(current, &command->info.agentName);
			break;
		case RA_AGENT_REQUEST_MONITOR:
		case RA_CONTROLLER_REQUEST_MONITOR:
		case RA_PEER_UNREACHABLE:
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor.context);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor.processId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor.agent);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor.node);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor.peerProcessId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor.peerAgent);
			current=readRABinaryArrayFromBuffer(current, &command->info.agent_request_monitor.peerNode); /* Bug 80893 */
			break;
		/* Bug 77768 begins */
		case RA_AGENT_REQUEST_MONITOR_PORT:
		case RA_CONTROLLER_REQUEST_MONITOR_PORT:
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor_port.context);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor_port.processId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor_port.agent);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor_port.node);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor_port.peerProcessId);
			current=readRASTRINGFromBuffer(current, &command->info.agent_request_monitor_port.peerAgent);
			current=readRABinaryArrayFromBuffer(current, &command->info.agent_request_monitor_port.peerNode);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor_port.port);
			current=readRAUINTFromBuffer(current, &command->info.agent_request_monitor_port.peerPort);
			break;
		/* Bug 77768 ends */
		case RA_GET_PROPERTY_LIST:
			current=readRAUINTFromBuffer(current, &command->info.query_property_list.context);
			current=readRASTRINGFromBuffer(current, &command->info.query_property_list.name);
			current=readRASTRINGFromBuffer(current, &command->info.query_property_list.type);
			current=readRASTRINGFromBuffer(current, &command->info.query_property_list.agentUUID);
			break;
		case RA_PROPERTY_LIST:
			current=readRAUINTFromBuffer(current, &command->info.property_list.context);
			/* Array length */
			current=readRAUINTFromBuffer(current, &command->info.property_list.entries.length);
			/* Names, Types, Values */
			if(command->info.property_list.entries.length) {
				command->info.property_list.entries.data = (void**)tptp_malloc(sizeof(ra_agentConfigEntry_t*) * command->info.property_list.entries.length);
				for(i = 0; i < command->info.property_list.entries.length; i++) {
					((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i] = (ra_agentConfigEntry_t*)tptp_malloc(sizeof(ra_agentConfigEntry_t));
					current = readRASTRINGFromBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->name));
					current = readRASTRINGFromBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->type));
					current = readRASTRINGFromBuffer(current, (ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->value));
				}
			}
			break;
		/** Added by Giridhar.S on 13/2/04 **/
		case RA_MANAGE_FILE:
			current=readRAUINTFromBuffer(current, &command->info.manage_file.context);
			current=readRAUINTFromBuffer(current, &command->info.manage_file.operation);
			current=readRASTRINGFromBuffer(current, &command->info.manage_file.filename);
			break;
		case RA_RESOURCE_LOCATION:
			current=readRAUINTFromBuffer(current, &command->info.resource_location.context);
			current=readRAUINTFromBuffer(current, &command->info.resource_location.port);
			current=readRASTRINGFromBuffer(current, &command->info.resource_location.jobKey);
			break;
		}
		/* Place the command in the command list */
		ra_addCommandToMessage(message, command);
	}
	return message;
}


/** CREATE_MESSAGE  ***********************************************************
  * Allocates the memory for a message and loads it with the specified type and
  * ticket.  In order to tptp_free the memory used for this message use ra_destroyMessage()
  * @param  type  - the type of message, be it an RA_ACKNOWLEDGEMENT_MESSAGE
  *                 or a RA_CONTROL_MESSAGE.
  * @param ticket - the ticket number for this message. If this is an
  *                 RA_ACKNOWLEDGEMENT_MESSAGE this should be the ticket of the
  *                 corresponding RA_CONTROL_MESSAGE.
  * @returns !NULL - the address of the newley allocated message.
  *           NULL - inappropriate message type.
  */
ra_message_t* ra_createMessage(ra_uint_t type,
							   ra_uint_t ticket) {
	ra_message_t *message;
	if(type==RA_ACKNOWLEDGEMENT_MESSAGE) {
		message=(ra_message_t*)tptp_malloc(sizeof(ra_message_t));
		message->ticket=ticket;
		message->type=type;
		return message;
	}
	else if (type==RA_CONTROL_MESSAGE) {
		message=(ra_message_t*)tptp_malloc(sizeof(ra_message_t));
		message->ticket=ticket;
		message->type=type;
		message->length=5*sizeof(ra_uint_t);  /* Initial length with no key or commands */
		message->key.length=0;
		message->key.data=NULL;
		message->commands.head=message->commands.tail=NULL;
		message->commands.count=0;
		return message;
	}
	return NULL;

}

/** DESTROY_MESSAGE  **********************************************************
  * tptp_free's all the memory currenltly held by a message and it's associated commands.
  * @param  message - the message to tptp_free all the memory of.
  * @param depptptp_free - Control messages consist of a list of ra_command_t stuctures
  *                   that are maintained within containers, if deeptptp_free is true,
  *                   the actual commands are deleted along with the containers.  If
  *                   deeptptp_free is false, only the containers are deleted.  This is
  *                   usefull for occasions when commands are copied from one message
  *                   to another without a depp copy.
  */
void ra_destroyMessage(ra_message_t *message,
					   BOOL deepFree) {
	ra_command_list_node_t *currentNode;
	ra_command_t *currentCommand;
	if(message->type == RA_ACKNOWLEDGEMENT_MESSAGE) {
		tptp_free(message);
		return;
	}

	tptp_free(message->key.data);

	currentNode=message->commands.head;
	while (currentNode != NULL) {
		ra_command_list_node_t *temp;
		currentCommand=currentNode->command;
		/* Only delete the command data if asked to and if there is something to delete */
		if(deepFree && currentCommand!=NULL) {
			switch(currentCommand->tag) {
				ra_uint_t i;
			case RA_AUTHENTICATE:
				tptp_free(currentCommand->info.authenticate.user.data);
				currentCommand->info.authenticate.user.data=NULL;
				tptp_free(currentCommand->info.authenticate.passwd.data);
				currentCommand->info.authenticate.passwd.data=NULL;
				break;
			case RA_AUTHENTICATION_SUCCESSFUL:
				tptp_free(currentCommand->info.authenticate_successful.key.data);
				currentCommand->info.authenticate_successful.key.data=NULL;
				break;
			case RA_AUTHENTICATION_FAILED:
				break;
            case RA_SERVER_SECURITY_REQUIREMENTS:
                break;
			case RA_LAUNCH_PROCESS:
				tptp_free(currentCommand->info.launch_process.executable.data);
				currentCommand->info.launch_process.executable.data=NULL;
				tptp_free(currentCommand->info.launch_process.arguments.data);
				currentCommand->info.launch_process.arguments.data=NULL;
				tptp_free(currentCommand->info.launch_process.location.data);
				currentCommand->info.launch_process.location.data=NULL;
				for(i=0; i<currentCommand->info.launch_process.environment.length; i++) {
					tptp_free(((ra_string_t*)(currentCommand->info.launch_process.environment.data[i]))->data);
					((ra_string_t*)(currentCommand->info.launch_process.environment.data[i]))->data=NULL;
					tptp_free(((ra_string_t*)(currentCommand->info.launch_process.environment.data[i])));
					currentCommand->info.launch_process.environment.data[i]=NULL;
				}
				for(i=0; i<currentCommand->info.launch_process.agents.length; i++) {
					tptp_free(((ra_string_t*)(currentCommand->info.launch_process.agents.data[i]))->data);
					((ra_string_t*)(currentCommand->info.launch_process.agents.data[i]))->data=NULL;
					tptp_free(((ra_string_t*)(currentCommand->info.launch_process.agents.data[i])));
					currentCommand->info.launch_process.agents.data[i]=NULL;
				}
				break;
			case RA_PROCESS_LAUNCHED:
				tptp_free(currentCommand->info.process_launched.executable.data);
				currentCommand->info.process_launched.executable.data=NULL;
				tptp_free(currentCommand->info.process_launched.arguments.data);
				currentCommand->info.process_launched.arguments.data=NULL;
				tptp_free(currentCommand->info.process_launched.processUUID.data);
				currentCommand->info.process_launched.processUUID.data=NULL;
				for(i=0; i<currentCommand->info.process_launched.environment.length; i++) {
					tptp_free(((ra_string_t*)(currentCommand->info.process_launched.environment.data[i]))->data);
					((ra_string_t*)(currentCommand->info.process_launched.environment.data[i]))->data=NULL;
					tptp_free(((ra_string_t*)(currentCommand->info.process_launched.environment.data[i])));
					currentCommand->info.process_launched.environment.data[i]=NULL;
				}
				break;
			case RA_QUERY_PROCESS_LIST:
				break;
			case RA_PROCESS_LIST:
				for(i=0; i<currentCommand->info.registered_process_list.processes.length; i++) {
					tptp_free(((ra_uint_t*)currentCommand->info.registered_process_list.processes.data[i]));
					currentCommand->info.registered_process_list.processes.data[i]=NULL;
				}
				break;
			case RA_QUERY_AGENT_LIST:
			case RA_KILL_PROCESS:
			case RA_PROCESS_EXITED:
				break;
			case RA_AGENT_LIST:
				tptp_free(currentCommand->info.registered_agents_list.executable.data);
				currentCommand->info.registered_agents_list.executable.data=NULL;
				for(i=0; i<currentCommand->info.registered_agents_list.agents.length; i++) {
					tptp_free(currentCommand->info.registered_agents_list.agents.data[i]);
					currentCommand->info.registered_agents_list.agents.data[i]=NULL;
				}
				break;
			case RA_REGISTER_AGENT_NOTIFICATION:
			case RA_QUERY_AGENT_DETAILS:
				tptp_free(currentCommand->info.register_agent_notification.agent.data);
				currentCommand->info.register_agent_notification.agent.data=NULL;
				break;
			case RA_ATTACH_TO_AGENT:
			case RA_DETACH_FROM_AGENT:
			case RA_START_MONITORING_AGENT_REMOTE:
			case RA_STOP_MONITORING_AGENT:
			case RA_AGENT_QUERY_STATE: /* Bug 54376 */
			case RA_AGENT_ATTACHED: /* Bug 54376 */
			case RA_AGENT_DETACHED: /* Bug 54376 */
				tptp_free(currentCommand->info.attach.agent.data);
				currentCommand->info.attach.agent.data=NULL;
				break;
			case RA_ERROR_STRING:
				tptp_free(currentCommand->info.error_string.agent.data);
				currentCommand->info.error_string.agent.data=NULL;
				tptp_free(currentCommand->info.error_string.messageId.data);
				currentCommand->info.error_string.messageId.data=NULL;
				tptp_free(currentCommand->info.error_string.message.data);
				currentCommand->info.error_string.message.data=NULL;
				break;
			case RA_START_MONITORING_AGENT_LOCAL:
				tptp_free(currentCommand->info.start_monitor_local.agent.data);
				currentCommand->info.start_monitor_local.agent.data=NULL;
				tptp_free(currentCommand->info.start_monitor_local.file.data);
				currentCommand->info.start_monitor_local.file.data=NULL;
				break;
			case RA_SET_NAME_VALUE_PAIR:
				tptp_free(currentCommand->info.set_nv_pair.agent.data);
				currentCommand->info.set_nv_pair.agent.data=NULL;
				tptp_free(currentCommand->info.set_nv_pair.type.data);
				currentCommand->info.set_nv_pair.type.data=NULL;
				tptp_free(currentCommand->info.set_nv_pair.name.data);
				currentCommand->info.set_nv_pair.name.data=NULL;
				tptp_free(currentCommand->info.set_nv_pair.value.data);
				currentCommand->info.set_nv_pair.value.data=NULL;
				break;
			case RA_CUSTOM_COMMAND:
            case RA_BINARY_CUSTOM_COMMAND:
				tptp_free(currentCommand->info.custom_command.agent.data);
				currentCommand->info.custom_command.agent.data=NULL;
				tptp_free(currentCommand->info.custom_command.message.data);
				currentCommand->info.custom_command.message.data=NULL;
				break;
			case RA_AGENT_ACTIVE:
			case RA_AGENT_INACTIVE:
			case RA_AGENT_DETAILS:
				tptp_free(currentCommand->info.agent_active.agent.data);
				currentCommand->info.agent_active.agent.data=NULL;
				tptp_free(currentCommand->info.agent_active.agentUUID.data);
				currentCommand->info.agent_active.agentUUID.data=NULL;
				tptp_free(currentCommand->info.agent_active.processUUID.data);
				currentCommand->info.agent_active.processUUID.data=NULL;
				tptp_free(currentCommand->info.agent_active.agentType.data);
				currentCommand->info.agent_active.agentType.data=NULL;
				break;
			case RA_AGENT_SCOPING_INFORMATION:
				tptp_free(currentCommand->info.agent_scoping_information.agentUUID.data);
				currentCommand->info.agent_scoping_information.agentUUID.data=NULL;
				tptp_free(currentCommand->info.agent_scoping_information.processUUID.data);
				currentCommand->info.agent_scoping_information.processUUID.data=NULL;
				tptp_free(currentCommand->info.agent_scoping_information.agentType.data);
				currentCommand->info.agent_scoping_information.agentType.data=NULL;
				tptp_free(currentCommand->info.agent_scoping_information.nodeUUID.data);
				currentCommand->info.agent_scoping_information.nodeUUID.data=NULL;
				break;
			case RA_AGENT_CONFIGURATION:
				tptp_free(currentCommand->info.agent_configuration.agentUUID.data);
				currentCommand->info.agent_configuration.agentUUID.data=NULL;
				tptp_free(currentCommand->info.agent_configuration.processUUID.data);
				currentCommand->info.agent_configuration.processUUID.data=NULL;
				tptp_free(currentCommand->info.agent_configuration.agentType.data);
				currentCommand->info.agent_configuration.agentType.data=NULL;
				tptp_free(currentCommand->info.agent_configuration.nodeUUID.data);
				currentCommand->info.agent_configuration.nodeUUID.data=NULL;
				for(i=0; i<currentCommand->info.agent_configuration.configuration.length; i++) {
					ra_agentConfigEntry_t *entry=((ra_agentConfigEntry_t*)(currentCommand->info.agent_configuration.configuration.data[i]));
					tptp_free(entry->type.data);
					entry->type.data=NULL;
					tptp_free(entry->name.data);
					entry->name.data=NULL;
					tptp_free(entry->value.data);
					entry->value.data=NULL;
				}
				break;
			case RA_AGENT_CONTROLER_AVAILABLE:
			case RA_AGENT_CONTROLER_UNAVAILABLE:
				tptp_free(currentCommand->info.agentName.data);
				currentCommand->info.agentName.data=NULL;
				break;
			case RA_AGENT_REQUEST_MONITOR:
			case RA_CONTROLLER_REQUEST_MONITOR:
			case RA_PEER_UNREACHABLE:
			case RA_AGENT_REQUEST_MONITOR_PORT: /* Bug 77768 */
			case RA_CONTROLLER_REQUEST_MONITOR_PORT: /* Bug 77768 */
				tptp_free(currentCommand->info.agent_request_monitor.agent.data);
				currentCommand->info.agent_request_monitor.agent.data=NULL;
				tptp_free(currentCommand->info.agent_request_monitor.node.data);
				currentCommand->info.agent_request_monitor.node.data=NULL;
				tptp_free(currentCommand->info.agent_request_monitor.peerAgent.data);
				currentCommand->info.agent_request_monitor.peerAgent.data=NULL;
				tptp_free(currentCommand->info.agent_request_monitor.peerNode.data);
				currentCommand->info.agent_request_monitor.peerNode.data=NULL;
				break;
			case RA_GET_PROPERTY_LIST:
				tptp_free(currentCommand->info.query_property_list.name.data);
				currentCommand->info.query_property_list.name.data = NULL;
				tptp_free(currentCommand->info.query_property_list.type.data);
				currentCommand->info.query_property_list.type.data = NULL;
				tptp_free(currentCommand->info.query_property_list.agentUUID.data);
				currentCommand->info.query_property_list.agentUUID.data = NULL;
				break;
			case RA_PROPERTY_LIST:
				/* Names, Types, Values */
				for(i = 0; i < currentCommand->info.property_list.entries.length; i++) {
					tptp_free(((ra_agentConfigEntry_t**)currentCommand->info.property_list.entries.data)[i]->name.data);
					tptp_free(((ra_agentConfigEntry_t**)currentCommand->info.property_list.entries.data)[i]->type.data);
					tptp_free(((ra_agentConfigEntry_t**)currentCommand->info.property_list.entries.data)[i]->value.data);
				}
				if(currentCommand->info.property_list.entries.length > 0) {
					tptp_free((ra_agentConfigEntry_t**)currentCommand->info.property_list.entries.data);
				}
				break;
			/** Added by Giridhar.S on 13/2/04 **/
			case RA_MANAGE_FILE:
				tptp_free(currentCommand->info.manage_file.filename.data);
				currentCommand->info.manage_file.filename.data=NULL;
				break;
			case RA_RESOURCE_LOCATION:
				tptp_free(currentCommand->info.resource_location.jobKey.data);
				currentCommand->info.resource_location.jobKey.data=NULL;
				break;

			}
			tptp_free(currentCommand);
			currentNode->command=NULL;
		}
		temp=currentNode;
		currentNode=currentNode->next;
		tptp_free(temp);
		temp=NULL;
	}
	tptp_free(message);
	message=NULL;
}

 
/** ADD_COMMAND_TO_MESSAGE  ***************************************************
  * Adds a command to the message command list.
  * @param  message - the previously allocated message to append the command to.
  * @param  command - the command to append to the message command list.  If this
  *                   is NULL, the memory for the command is allocated.
  * @retruns        - a pointer to the appended command.
  */
ra_command_t* ra_addCommandToMessage(ra_message_t *message,
									 ra_command_t *command) {
	ra_command_list_node_t *newNode;
	ra_command_t *newCommand=command;
	newNode=(ra_command_list_node_t*)tptp_malloc(sizeof(ra_command_list_node_t));

	if(newCommand==NULL) {
		newCommand=(ra_command_t*)tptp_malloc(sizeof(ra_command_t));
	}

	/* If there is no message just return the command */
	if(!message) {
		return newCommand;
	}

	/* Insert the command in message_list */
	newNode->command=newCommand;
	newNode->next=NULL;
	newNode->previous=message->commands.tail;
	message->commands.tail=newNode;

	/* If this not the first entry we must set the link in the previous tail */
	if(newNode->previous) {
		newNode->previous->next=newNode;
	}
	else {
		message->commands.head=newNode;
	}
	message->commands.count++;

	return newCommand;
}

/** CRITICAL_SECTION_CREATE  ***************************************************
  * Create a critical section.
  */
void ra_mutexCreate(ra_critsec_t *lock) {
#ifdef _WIN32
	InitializeCriticalSection(lock);
#else
	pthread_mutex_init(lock, 0); /* unlocked by default */
#endif
}

/** CRITICAL_SECTION_ENTER  ***********************************************************
  * Enter a previously created critical section on this thread.
  */
void ra_mutexEnter(ra_critsec_t *lock) {
#ifdef _WIN32
	EnterCriticalSection(lock);
#else
	pthread_mutex_lock(lock);
#endif
}

/** CRITICAL_SECTION_EXIT  ************************************************************
  * Exit a previously entered critical section on this thread.
  */
void ra_mutexExit(ra_critsec_t *lock) {
#ifdef _WIN32
	LeaveCriticalSection(lock);
#else
	pthread_mutex_unlock(lock);
#endif
}

/** CRITICAL_SECTION_DESTROY  *********************************************************
  * Destroy a critical section.
  */
void ra_mutexDestroy(ra_critsec_t *lock) {
#ifdef _WIN32
	DeleteCriticalSection(lock);
#else
	pthread_mutex_destroy(lock);
#endif
}


static unsigned char* copyRAUINTToBuffer(unsigned char *buffer,
							   ra_uint_t uintData) {
	buffer[0]=(unsigned char)(uintData>>24 & 0x000000ff);
	buffer[1]=(unsigned char)(uintData>>16 & 0x000000ff);
	buffer[2]=(unsigned char)(uintData>>8  & 0x000000ff);
	buffer[3]=(unsigned char)uintData;
	return &buffer[4];
}

static unsigned char* readRAUINTFromBuffer(unsigned char *buffer, ra_uint_t *uint) {
	*uint=((ra_uint_t)(buffer[0]<<24)
					  |(ra_uint_t)(buffer[1]<<16)
					  |(ra_uint_t)(buffer[2]<<8)
					  | buffer[3]);
	return &buffer[sizeof(ra_uint_t)];
}

/* 190770 - Note that for 390, the buffer to copy into must be at least one byte larger
            than the data in stringData to accomodate a terminating null character
            required for EBCDIC to ASCII conversion */
static unsigned char* copyRASTRINGToBuffer(unsigned char *buffer, ra_string_t *stringData) {

	ra_uint_t padding = 0;
	ra_uint_t utf8Len = 0;
	ra_uint_t nativeLen = 0;
	char* utf8Buffer = 0;
	char* nativeBuffer = 0;
#if _DEBUG
	char* dbgBuffer = 0;
#endif

	nativeLen = stringData->length;
	nativeBuffer = stringData->data;

	if(nativeLen == 0) {
		copyRAUINTToBuffer(buffer, 0);
		return &buffer[sizeof(ra_uint_t)];
	}
	else {
		utf8Len = native2unicode(&utf8Buffer, nativeBuffer, nativeLen);

		if(utf8Len && utf8Buffer) {
			padding = 4 - (utf8Len)%4;
			if(padding == 4) {
				padding = 0;
			}

			copyRAUINTToBuffer(buffer, utf8Len);
			memcpy(&buffer[4], utf8Buffer, utf8Len);
			BZERO(&buffer[4 + utf8Len], padding); /* Fill the rest of the bytes with zeros */

		}
		else {
			copyRAUINTToBuffer(buffer, 0);
		}

#if 0 // _DEBUG
	dbgBuffer = (char*)tptp_malloc(sizeof(char*) * (utf8Len + 1));
	memcpy(dbgBuffer, utf8Buffer, utf8Len);
	dbgBuffer[utf8Len] = '\0';
	printf("DEBUG: (Native->UTF8) \"%s\" -> \"%s\"\n", nativeBuffer, dbgBuffer);
	tptp_free(dbgBuffer);
#endif

		if(utf8Buffer != 0) {
			tptp_free(utf8Buffer);
		}

		return &buffer[sizeof(ra_uint_t) + utf8Len + padding];
	}
}

static unsigned char* copyRABinaryArrayToBuffer(unsigned char *buffer, ra_string_t *binaryData) {
	ra_uint_t padding=4-(binaryData->length)%4;

	if(padding==4) {
		padding=0;
	}

	copyRAUINTToBuffer(buffer, binaryData->length);
	memcpy(&buffer[4], binaryData->data, binaryData->length);
	BZERO(&buffer[4 + binaryData->length], padding); /* Fill the rest of the bytes with zeros */

	return &buffer[sizeof(ra_uint_t)+binaryData->length+padding];
}

static unsigned char* readRASTRINGFromBuffer(unsigned char *buffer, ra_string_t *newString) {
	ra_uint_t padding = 0;
	ra_uint_t utf8Len = 0;
	ra_uint_t nativeLen = 0;
	char* utf8Buffer = 0;
	char* nativeBuffer = 0;

	readRAUINTFromBuffer(buffer, &utf8Len);

	if(utf8Len == 0) {
		newString->data = (char*)tptp_malloc(sizeof(char));
		newString->data[0] = '\0';
		newString->length = 0;

		return &buffer[sizeof(ra_uint_t)];
	}
	else {
		utf8Buffer = (char*)tptp_malloc(sizeof(char) * (utf8Len + 1));
		BZERO(utf8Buffer, utf8Len + 1);
		memcpy(utf8Buffer, &buffer[4], utf8Len); /* read the bytes from buffer */
		utf8Buffer[utf8Len] = '\0';

		/* Convert the value from UTF-8 to native encoding */
		nativeLen = unicode2native(&nativeBuffer, utf8Buffer, utf8Len);

		if(nativeLen && nativeBuffer) {
			newString->data = (char*)tptp_malloc(sizeof(char) * (nativeLen + 1));
			BZERO(newString->data, nativeLen + 1);
			memcpy(newString->data, nativeBuffer, nativeLen);
			newString->length = nativeLen;
		}
		else {
			newString->data = (char*)tptp_malloc(sizeof(char));
			newString->data[0] = '\0';
			newString->length = 0;
		}

#if 0 // _DEBUG
	printf("DEBUG: (UTF8->Native) \"%s\" -> \"%s\"\n", utf8Buffer, newString->data);
#endif

		tptp_free(utf8Buffer);
		if(nativeBuffer != 0) {
			tptp_free(nativeBuffer);
		}

		padding = 4 - (utf8Len) % 4;
		if(padding == 4) {
			padding = 0;
		}

		return &buffer[sizeof(ra_uint_t) + utf8Len + padding];
	}
}

static unsigned char* readRABinaryArrayFromBuffer(unsigned char *buffer,
											      ra_string_t *newArray) {
	ra_uint_t padding;
	readRAUINTFromBuffer(buffer, &newArray->length);
	newArray->data=(char*)tptp_malloc(newArray->length+1);
	memcpy(newArray->data, &buffer[4], newArray->length);
	newArray->data[newArray->length]='\0';
	padding=4-(newArray->length)%4;
	if(padding==4) {
		padding=0;
	}

	
	return &buffer[sizeof(ra_uint_t)+newArray->length+padding];
}


static int determineRASTRINGSize(ra_string_t *rastring) {
	ra_uint_t padding;
	char* utf8Buffer = 0;
	ra_uint_t utf8Len;

	/* The NULL string is sizeof(ra_uint_t) long */
	if(rastring == NULL) {
		return sizeof(ra_uint_t);
	}
	else if((rastring->length == 0) || (rastring->data == NULL)) {
		/* NULL string as well */
		return sizeof(ra_uint_t);
	}

	utf8Len = native2unicode(&utf8Buffer, rastring->data, rastring->length);

	padding=4 - (utf8Len)%4;
	if(padding==4) {
		padding=0;
	}

	if(utf8Buffer != 0) {
		tptp_free(utf8Buffer);
	}

	return sizeof(ra_uint_t) + utf8Len + padding;
}

/* Bug 73074 - Binary Custom Command does not need conversion */
static int determineRABinaryArraySize(ra_string_t *rastring) {
	ra_uint_t padding;

	/* The NULL string is sizeof(ra_uint_t) long */
	if(rastring == NULL) {
		return sizeof(ra_uint_t);
	}
	else if(rastring->data == NULL) {
		/* NULL string as well */
		return sizeof(ra_uint_t);
	}

	padding = 4 - (rastring->length)%4;
	if(padding==4) {
		padding=0;
	}

	return sizeof(ra_uint_t) + rastring->length + padding;
}

/** CREATE_RASTRING  ************************************************************
  * Creates an ra_string_t from a null terminated array of characters.  This does
  * a complete copy of the stringBuffer.
  * @param    newString - the address of a ra_string_t structure to load.
  * @param stringBuffer - null terminated buffer of characters to copy into the
  *                       ra_string_t structure.
  */
void ra_createRASTRING(ra_string_t *newString,
					   const char *stringBuffer) {
	if(stringBuffer) {
		newString->length=strlen(stringBuffer);
		newString->data=(char*)tptp_malloc(newString->length+1);
		strcpy(newString->data, stringBuffer);
	}
	else {
		newString->length=0;
		newString->data=NULL;
	}
}

/** CREATE_RASTRING3  ************************************************************
  * Creates an ra_string_t from an array of characters.  This does
  * a complete copy of the stringBuffer for length characters.
  * @param    newString - the address of a ra_string_t structure to load.
  * @param stringBuffer - null terminated buffer of characters to copy into the
  *                       ra_string_t structure.
  * @param       length - the number of octets to copy into the string.
  */
extern void ra_createRASTRING3(ra_string_t *newString,
							  const char *stringBuffer,
							  unsigned long length) {

	if(stringBuffer && length) {
		newString->length=length;
		newString->data=(char*)tptp_malloc(length+1);
		memcpy(newString->data, stringBuffer, length);
	}
	else {
		newString->length=0;
		newString->data=NULL;
	}
}

/** COPY_RASTRING  **************************************************************
  * Creates a copy of the source ra_string_t to the destination ar_string_t.  This
  * does not ra_free any memory currently associated with the destination ra_string_t
  * data portion.
  * @param	destination - the ra_string_t to copy the source data to.
  * @param       source - the source ra_string_t structure.
  */
void ra_copyRASTRING(ra_string_t* destination,
					 const ra_string_t* source) {

	destination->length=source->length;
	destination->data=(char *)tptp_malloc(sizeof(char)*source->length+1);
	if(source->data) {
		memcpy(destination->data, source->data, source->length);
	}
	destination->data[source->length]='\0';
}

/** DESTROY_RASTRING  **************************************************************
  * free any memory currently associated with the destination ra_string_t
  * data portion.
  * @param	ra_string_t to destroy.
  */
void ra_destroyRASTRING(ra_string_t *rastring) {
	tptp_free(rastring->data);
	rastring->data=NULL;
	rastring->length=0;
}


/** GENERATE_UUID  ************************************************
  * Creates an ra_string_t containing a UUID.
  * @param  uuid - the address of the ra_string_t to load the UUID into.
  */
void ra_generateUUID(ra_string_t *uuid) {
#ifdef _WIN32
	UUID temp;
	char *result;
	UuidCreate(&temp);
	UuidToString(&temp, &result);
	uuid->length=strlen(result);
	uuid->data=strdup(result);
	RpcStringFree(&result);
#else
	/* RKD:  This isn't a real UUID but should be close enough for our purposes */
	static BOOL firstTime=TRUE;
	static unsigned short seed[3];
	struct timeval tv;
	#ifndef MVS
		struct timezone tz;
	#endif
	unsigned long seconds, microseconds;
	char *buffer;

	buffer=(char*)tptp_malloc(128);
	if(buffer) {
      BZERO(buffer, 128);
		/* Get a timestamp */
		#ifdef MVS
			gettimeofday(&tv, 0);
		#else
			gettimeofday(&tv, &tz);
		#endif
		seconds=tv.tv_sec;
		microseconds=tv.tv_usec;

		/* Seed our generator on the first pass */
		if(firstTime) {
			seed[0]=seconds;
			seed[1]=microseconds;
			seed[2]=0;
#ifdef __OS400__
			srand(microseconds);
#else
			seed48(seed);
#endif
			firstTime=FALSE;
		}

		/* Generate the randon part of the UUID */
#ifdef __OS400__
		sprintf(buffer, "UUID-%d-%d-%d-%d", seconds, microseconds, rand(), rand());
#elif MVS
/*    188870 - snprintf not available on 390 */
		sprintf(buffer, "UUID-%d-%d-%d-%d", seconds, microseconds, lrand48(), lrand48());
#else
		snprintf(buffer, 128, "UUID-%lu-%lu-%ld-%ld", seconds, microseconds, lrand48(), lrand48());
#endif
		buffer[127]='\0';
		uuid->length=strlen(buffer);
		uuid->data=buffer;
		return;

	}
	uuid->length=0;
	uuid->data=NULL;
#endif
}

/** CLONE_COMMAND **************************************************************
  * Unlike the other functions in this file, this didn't come directly from the 
  * RAC.  This function makes a copy of a command, allocating memory as necessary
  * so that the original message can be freed with a deep free.
  *
  * @param       src - the ra_command_t to be copied
  */

ra_command_t* ra_cloneCommand( ra_command_t* src ) {
	ra_command_t *command;

	if ( src == NULL ) {
		return NULL;
	}

	/* Allocate the new command */
	command=(ra_command_t*)tptp_malloc(sizeof(ra_command_t));
	command->tag = src->tag;
	switch(command->tag) {
		ra_uint_t i;
	case RA_AUTHENTICATE:
		ra_copyRASTRING(&command->info.authenticate.user, &src->info.authenticate.user);
		ra_copyRASTRING(&command->info.authenticate.passwd, &src->info.authenticate.passwd);
		break;
	case RA_AUTHENTICATION_SUCCESSFUL:
		ra_copyRASTRING(&command->info.authenticate_successful.key, &src->info.authenticate_successful.key);
		break;
	case RA_AUTHENTICATION_FAILED:
		command->info.authenticate_failed.ticket=src->info.authenticate_failed.ticket;
		break;
    case RA_SERVER_SECURITY_REQUIREMENTS:
        command->info.serverSecurityRequirements.flag=src->info.serverSecurityRequirements.flag;
        command->info.serverSecurityRequirements.securePort=src->info.serverSecurityRequirements.securePort;
        break;
	case RA_LAUNCH_PROCESS:
		command->info.launch_process.context=src->info.launch_process.context;
		command->info.launch_process.consoleIP=src->info.launch_process.consoleIP;
		command->info.launch_process.consolePort=src->info.launch_process.consolePort;
		ra_copyRASTRING(&command->info.launch_process.executable, &src->info.launch_process.executable);
		ra_copyRASTRING(&command->info.launch_process.arguments, &src->info.launch_process.arguments);
		ra_copyRASTRING(&command->info.launch_process.location, &src->info.launch_process.location);
		command->info.launch_process.environment.length=src->info.launch_process.environment.length;
		if(command->info.launch_process.environment.length) {
			command->info.launch_process.environment.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.launch_process.environment.length);
			for(i=0; i<command->info.launch_process.environment.length; i++) {
				((ra_string_t**)command->info.launch_process.environment.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
				ra_copyRASTRING(((ra_string_t*)(((ra_string_t**)command->info.launch_process.environment.data)[i])), ((ra_string_t*)(((ra_string_t**)src->info.launch_process.environment.data)[i])));
			}
		}
		command->info.launch_process.agents.length=src->info.launch_process.agents.length;
		if(command->info.launch_process.agents.length) {
			command->info.launch_process.agents.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.launch_process.agents.length);
			for(i=0; i<command->info.launch_process.agents.length; i++) {
				((ra_string_t**)command->info.launch_process.agents.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
				ra_copyRASTRING((ra_string_t*)(((ra_string_t**)command->info.launch_process.agents.data)[i]), (ra_string_t*)(((ra_string_t**)src->info.launch_process.agents.data)[i]));
			}
		}
		break;
	case RA_PROCESS_LAUNCHED:
		command->info.process_launched.context=src->info.process_launched.context;
		command->info.process_launched.processId=src->info.process_launched.processId;
		ra_copyRASTRING(&command->info.process_launched.processUUID, &src->info.process_launched.processUUID);
		ra_copyRASTRING(&command->info.process_launched.executable, &src->info.process_launched.executable);
		ra_copyRASTRING(&command->info.process_launched.arguments, &src->info.process_launched.arguments);
		command->info.process_launched.environment.length=src->info.process_launched.environment.length;
		if(command->info.process_launched.environment.length) {
			command->info.process_launched.environment.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.process_launched.environment.length);
			for(i=0; i<command->info.process_launched.environment.length; i++) {
				((ra_string_t**)command->info.process_launched.environment.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
				ra_copyRASTRING((ra_string_t*)(((ra_string_t**)command->info.process_launched.environment.data)[i]), (ra_string_t*)(((ra_string_t**)src->info.process_launched.environment.data)[i]));
			}
		}
		break;
	case RA_QUERY_PROCESS_LIST:
		command->info.query_process_list.context=src->info.query_process_list.context;
		break;
	case RA_PROCESS_LIST:
		command->info.registered_process_list.context=src->info.registered_process_list.context;
		command->info.registered_process_list.processes.length=src->info.registered_process_list.processes.length;
		if(command->info.registered_process_list.processes.length) {
			command->info.registered_process_list.processes.data=(void**)tptp_malloc(sizeof(ra_uint_t*)*command->info.registered_process_list.processes.length);
			for(i=0; i<command->info.registered_process_list.processes.length; i++) {
				((ra_uint_t**)command->info.registered_process_list.processes.data)[i]=(ra_uint_t*)tptp_malloc(sizeof(ra_uint_t));
				(((ra_uint_t**)command->info.registered_process_list.processes.data)[i])=(ra_uint_t*)(((ra_uint_t**)src->info.registered_process_list.processes.data)[i]);
			}
		}
		break;
	case RA_QUERY_AGENT_LIST:
	case RA_KILL_PROCESS:
	case RA_PROCESS_EXITED:
		command->info.query_agent_list.context=src->info.query_agent_list.context;
		command->info.query_agent_list.processId=src->info.query_agent_list.processId;
		break;
	case RA_AGENT_LIST:
		command->info.registered_agents_list.context=src->info.registered_agents_list.context;
		command->info.registered_agents_list.agents.length=src->info.registered_agents_list.agents.length;
		ra_copyRASTRING(&command->info.registered_agents_list.executable, &src->info.registered_agents_list.executable);
		command->info.registered_agents_list.agents.data=(void**)tptp_malloc(sizeof(ra_string_t*)*command->info.registered_agents_list.agents.length);
		if(command->info.registered_agents_list.agents.length) {
			for(i=0; i<command->info.registered_agents_list.agents.length; i++) {
				((ra_string_t**)command->info.registered_agents_list.agents.data)[i]=(ra_string_t*)tptp_malloc(sizeof(ra_string_t));
				ra_copyRASTRING((ra_string_t*)(((ra_string_t**)command->info.registered_agents_list.agents.data)[i]), (ra_string_t*)(((ra_string_t**)src->info.registered_agents_list.agents.data)[i]));
			}
		}
		break;
	case RA_REGISTER_AGENT_NOTIFICATION:
	case RA_QUERY_AGENT_DETAILS:
		command->info.register_agent_notification.context=src->info.register_agent_notification.context;
		command->info.register_agent_notification.processId=src->info.register_agent_notification.processId;
		ra_copyRASTRING(&command->info.register_agent_notification.agent, &src->info.register_agent_notification.agent);
		break;
	case RA_ATTACH_TO_AGENT:
	case RA_DETACH_FROM_AGENT:
	case RA_STOP_MONITORING_AGENT:
	case RA_AGENT_QUERY_STATE: /* Bug 54376 */
	case RA_AGENT_ATTACHED: /* Bug 54376 */
	case RA_AGENT_DETACHED: /* Bug 54376 */
		command->info.attach.context=src->info.attach.context;
		command->info.attach.processId=src->info.attach.processId;
		ra_copyRASTRING(&command->info.attach.agent, &src->info.attach.agent);
		break;
	case RA_ERROR_STRING:
		command->info.error_string.context=src->info.error_string.context;
		command->info.error_string.processId=src->info.error_string.processId;
		ra_copyRASTRING(&command->info.error_string.agent, &src->info.error_string.agent);
		command->info.error_string.severity=src->info.error_string.severity;
		ra_copyRASTRING(&command->info.error_string.messageId, &src->info.error_string.messageId);
		ra_copyRASTRING(&command->info.error_string.message, &src->info.error_string.message);
		break;
	case RA_START_MONITORING_AGENT_REMOTE:
		command->info.start_monitor_remote.context=src->info.start_monitor_remote.context;
		command->info.start_monitor_remote.processId=src->info.start_monitor_remote.processId;
		ra_copyRASTRING(&command->info.start_monitor_remote.agent, &src->info.start_monitor_remote.agent);
		command->info.start_monitor_remote.ip=src->info.start_monitor_remote.ip;
		command->info.start_monitor_remote.port=src->info.start_monitor_remote.port;
		break;
	case RA_START_MONITORING_AGENT_LOCAL:
		command->info.start_monitor_local.context=src->info.start_monitor_local.context;
		command->info.start_monitor_local.processId=src->info.start_monitor_local.processId;
		ra_copyRASTRING(&command->info.start_monitor_local.agent, &src->info.start_monitor_local.agent);
		ra_copyRASTRING(&command->info.start_monitor_local.file, &src->info.start_monitor_local.file);
		break;
	case RA_SET_NAME_VALUE_PAIR:
		command->info.set_nv_pair.context=src->info.set_nv_pair.context;
		command->info.set_nv_pair.processId=src->info.set_nv_pair.processId;
		ra_copyRASTRING(&command->info.set_nv_pair.agent, &src->info.set_nv_pair.agent);
		ra_copyRASTRING(&command->info.set_nv_pair.type, &src->info.set_nv_pair.type);
		ra_copyRASTRING(&command->info.set_nv_pair.name, &src->info.set_nv_pair.name);
		ra_copyRASTRING(&command->info.set_nv_pair.value, &src->info.set_nv_pair.value);
		break;
	case RA_CUSTOM_COMMAND:
		command->info.custom_command.context=src->info.custom_command.context;
		command->info.custom_command.processId=src->info.custom_command.processId;
		ra_copyRASTRING(&command->info.custom_command.agent, &src->info.custom_command.agent);
		ra_copyRASTRING(&command->info.custom_command.message, &src->info.custom_command.message);
		break;
    case RA_BINARY_CUSTOM_COMMAND:
        command->info.custom_command.context=src->info.custom_command.context;
		command->info.custom_command.processId=src->info.custom_command.processId;
		ra_copyRASTRING(&command->info.custom_command.agent, &src->info.custom_command.agent);
		ra_copyRASTRING(&command->info.custom_command.message, &src->info.custom_command.message);
		break;
	case RA_AGENT_ACTIVE:
	case RA_AGENT_INACTIVE:
	case RA_AGENT_DETAILS:
		command->info.agent_active.context=src->info.agent_active.context;
		command->info.agent_active.processId=src->info.agent_active.processId;
		ra_copyRASTRING(&command->info.agent_active.processUUID, &src->info.agent_active.processUUID);
		ra_copyRASTRING(&command->info.agent_active.agent, &src->info.agent_active.agent);
		ra_copyRASTRING(&command->info.agent_active.agentUUID, &src->info.agent_active.agentUUID);
		ra_copyRASTRING(&command->info.agent_active.agentType, &src->info.agent_active.agentType);
		break;
	case RA_AGENT_SCOPING_INFORMATION:
		command->info.agent_scoping_information.context=src->info.agent_scoping_information.context;
		command->info.agent_scoping_information.processId=src->info.agent_scoping_information.processId;
/* BEGIN:  235649 */
#if defined __linux__
		command->info.agent_scoping_information.messageProcessId=src->info.agent_scoping_information.messageProcessId;
#endif
/* END: 235649 */
		ra_copyRASTRING(&command->info.agent_scoping_information.processUUID, &src->info.agent_scoping_information.processUUID);
		ra_copyRASTRING(&command->info.agent_scoping_information.agent, &src->info.agent_scoping_information.agent);
		ra_copyRASTRING(&command->info.agent_scoping_information.agentUUID, &src->info.agent_scoping_information.agentUUID);
		ra_copyRASTRING(&command->info.agent_scoping_information.agentType, &src->info.agent_scoping_information.agentType);
		ra_copyRASTRING(&command->info.agent_scoping_information.nodeUUID, &src->info.agent_scoping_information.nodeUUID);
		break;
	case RA_AGENT_CONFIGURATION:
		command->info.agent_configuration.context=src->info.agent_configuration.context;
		command->info.agent_configuration.processId=src->info.agent_configuration.processId;
		ra_copyRASTRING(&command->info.agent_configuration.processUUID, &src->info.agent_configuration.processUUID);
		ra_copyRASTRING(&command->info.agent_configuration.agent, &src->info.agent_configuration.agent);
		ra_copyRASTRING(&command->info.agent_configuration.agentUUID, &src->info.agent_configuration.agentUUID);
		ra_copyRASTRING(&command->info.agent_configuration.agentType, &src->info.agent_configuration.agentType);
		ra_copyRASTRING(&command->info.agent_configuration.nodeUUID, &src->info.agent_configuration.nodeUUID);
		command->info.agent_configuration.configuration.length=src->info.agent_configuration.configuration.length;
		command->info.agent_configuration.configuration.data=(void**)tptp_malloc(sizeof(ra_agentConfigEntry_t*)*command->info.agent_configuration.configuration.length);
		if(command->info.agent_configuration.configuration.length) {
			for(i=0; i<command->info.agent_configuration.configuration.length; i++) {
				((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]=(ra_agentConfigEntry_t*)tptp_malloc(sizeof(ra_agentConfigEntry_t));
				ra_copyRASTRING(&((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->type,  &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->type);
				ra_copyRASTRING(&((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->name,  &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->name);
				ra_copyRASTRING(&((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->value, &((ra_agentConfigEntry_t**)command->info.agent_configuration.configuration.data)[i]->value);
			}
		}
		break;
	case RA_AGENT_CONTROLER_AVAILABLE:
	case RA_AGENT_CONTROLER_UNAVAILABLE:
		ra_copyRASTRING(&command->info.agentName, &src->info.agentName);
		break;
	case RA_AGENT_REQUEST_MONITOR:
	case RA_CONTROLLER_REQUEST_MONITOR:
	case RA_PEER_UNREACHABLE:
		command->info.agent_request_monitor.context=src->info.agent_request_monitor.context;
		command->info.agent_request_monitor.processId=src->info.agent_request_monitor.processId;
		ra_copyRASTRING(&command->info.agent_request_monitor.agent, &src->info.agent_request_monitor.agent);
		ra_copyRASTRING(&command->info.agent_request_monitor.node, &src->info.agent_request_monitor.node);
		command->info.agent_request_monitor.peerProcessId=src->info.agent_request_monitor.peerProcessId;
		ra_copyRASTRING(&command->info.agent_request_monitor.peerAgent, &src->info.agent_request_monitor.peerAgent);
		ra_copyRASTRING(&command->info.agent_request_monitor.peerNode, &src->info.agent_request_monitor.peerNode); /* Bug 80893 */
		break;
	/* Bug 77768 begins */
	case RA_AGENT_REQUEST_MONITOR_PORT:
	case RA_CONTROLLER_REQUEST_MONITOR_PORT:
		command->info.agent_request_monitor_port.context=src->info.agent_request_monitor_port.context;
		command->info.agent_request_monitor_port.processId=src->info.agent_request_monitor_port.processId;
		ra_copyRASTRING(&command->info.agent_request_monitor_port.agent, &src->info.agent_request_monitor_port.agent);
		ra_copyRASTRING(&command->info.agent_request_monitor_port.node, &src->info.agent_request_monitor_port.node);
		command->info.agent_request_monitor_port.peerProcessId=src->info.agent_request_monitor_port.peerProcessId;
		ra_copyRASTRING(&command->info.agent_request_monitor_port.peerAgent, &src->info.agent_request_monitor_port.peerAgent);
		ra_copyRASTRING(&command->info.agent_request_monitor_port.peerNode, &src->info.agent_request_monitor_port.peerNode);
		command->info.agent_request_monitor_port.port=src->info.agent_request_monitor_port.port;
		command->info.agent_request_monitor_port.peerPort=src->info.agent_request_monitor_port.peerPort;
		break;
	/* Bug 77768 ends */
	case RA_GET_PROPERTY_LIST:
		command->info.query_property_list.context=src->info.query_property_list.context;
		ra_copyRASTRING(&command->info.query_property_list.name, &src->info.query_property_list.name);
		ra_copyRASTRING(&command->info.query_property_list.type, &src->info.query_property_list.type);
		ra_copyRASTRING(&command->info.query_property_list.agentUUID, &src->info.query_property_list.agentUUID);
		break;
	case RA_PROPERTY_LIST:
		command->info.property_list.context=src->info.property_list.context;
		/* Array length */
		command->info.property_list.entries.length=src->info.property_list.entries.length;
		/* Names, Types, Values */
		if(command->info.property_list.entries.length) {
			command->info.property_list.entries.data = (void**)tptp_malloc(sizeof(ra_agentConfigEntry_t*) * command->info.property_list.entries.length);
			for(i = 0; i < command->info.property_list.entries.length; i++) {
				((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i] = (ra_agentConfigEntry_t*)tptp_malloc(sizeof(ra_agentConfigEntry_t));
				ra_copyRASTRING((ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->name),(ra_string_t*)(&((ra_agentConfigEntry_t**)src->info.property_list.entries.data)[i]->name));
				ra_copyRASTRING((ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->type),(ra_string_t*)(&((ra_agentConfigEntry_t**)src->info.property_list.entries.data)[i]->type));
				ra_copyRASTRING((ra_string_t*)(&((ra_agentConfigEntry_t**)command->info.property_list.entries.data)[i]->value),(ra_string_t*)(&((ra_agentConfigEntry_t**)src->info.property_list.entries.data)[i]->value));
			}
		}
		break;
	/** Added by Giridhar.S on 13/2/04 **/
	case RA_MANAGE_FILE:
		command->info.manage_file.context=src->info.manage_file.context;
		command->info.manage_file.operation=src->info.manage_file.operation;
		ra_copyRASTRING(&command->info.manage_file.filename, &src->info.manage_file.filename);
		break;
	case RA_RESOURCE_LOCATION:
		command->info.resource_location.context=src->info.resource_location.context;
		command->info.resource_location.port=src->info.resource_location.port;
		ra_copyRASTRING(&command->info.resource_location.jobKey, &src->info.resource_location.jobKey);
		break;
	}

	return command;
}

/* Bug 59544 */
/*
 * This function return the environment variable (see also java.c)
 *
 */
int ra_getEnvironmentVariable(char* name, char* buffer, int size) {
#ifdef _WIN32
	return GetEnvironmentVariable(name, buffer, size);
#else
	int len;
	char *currentValue = getenv(name);
	if (!currentValue) {
		return 0;
	}

	len = strlen(currentValue) + 1;

	if (size >= len) {
		memcpy(buffer, currentValue, len);
	}

	return len; /* Bug 68919 */
#endif
}
