/** message.c
*
*                     Copyright 1988, W.G.J. Langeveld
*                           All Rights Reserved
*                           Freely Distributable
*
*   Send a message to the REXX host.
*
**/
#include "functions.h"
#include "exec/exec.h"
#include "libraries/dos.h"
#include "libraries/dosextens.h"
#include "intuition/intuition.h"
#include "stdio.h"

#include <rexx/rxslib.h>
#include <rexx/rexxio.h>
#include <rexx/errors.h>
#include <rexx/storage.h>

static struct RexxMsg *msg;
static struct MsgPort *port = NULL, *REXXrport = NULL;
static struct FileHandle *nilfh = NULL;
static char *cmdbuff = NULL;

extern char *malloc(), *free();
char *ltoa();

/**
*
*   Send the command string "command" to the REXX host.
*   if the "flag" is set, this is a STRING command, else it is a rexx script.
*
**/
char *SendREXXMsg(command, flag)
char *command;
int flag;
{
   static char buffer[80];

   msg = (struct RexxMsg *) AllocMem((long) sizeof(struct RexxMsg),
                                     MEMF_PUBLIC|MEMF_CLEAR);
   if (!msg) {
      rxcleanup();
      return("REXX - out of memory");
   }
   REXXrport = CreatePort(NULL, 0L);
   if (!REXXrport) {
      rxcleanup();
      return("REXX - Couldn't create reply port");
   }
   cmdbuff = malloc(255);
   if (cmdbuff == NULL) {
      rxcleanup();
      return("REXX - out of memory");
   }
   nilfh = Open("nil:", ACCESS_WRITE);
   if (nilfh == NULL) {
      rxcleanup();
      return("Couldn't open nil:");
   }

   msg->rm_Node.mn_ReplyPort = REXXrport;
   msg->rm_Action = RXCOMM;
   if (flag) msg->rm_Action |= RXFF_STRING;
   strcpy(cmdbuff, command);
   msg->rm_Args[0] = (STRPTR) cmdbuff;
   msg->rm_FileExt = (STRPTR) "rexx";
   msg->rm_Result1 = 0L;
   msg->rm_Result2 = 0L;
   msg->rm_Stdin = (long) nilfh;
   msg->rm_Stdout = (long) nilfh;

   Forbid();
   port = FindPort("REXX", 0L);
   if (port) PutMsg(port, msg);
   Permit();

   if (!port) {
      rxcleanup();
      return("REXX - REXX is not here");
   }

   WaitPort(REXXrport);
   GetMsg(REXXrport);

   if (msg->rm_Result1) {
      strcpy(buffer, "REXX - macro exited with error ");
      strcat(buffer, ltoa(msg->rm_Result1) );
      rxcleanup();
      return(buffer);
   }
   else {
      rxcleanup();
      return(NULL);
   }
}

/**
*
*   Cleanup all allocated resources
*
**/
static rxcleanup()
{
   if (REXXrport) {
      DeletePort(REXXrport);
      REXXrport = NULL;
   }
   if (nilfh) {
      Close(nilfh);
      nilfh = NULL;
   }
   if (cmdbuff) {
      free(cmdbuff);
      cmdbuff = NULL;
   }
   if (msg) {
      FreeMem(msg, (long)sizeof(struct RexxMsg));
      msg = NULL;
   }
   return;
}


/**
*
*   Convert a long to an ascii string. sprintf is too much...
*
**/
static char *ltoa(n)
long n;
{
   static char nums[] = "0123456789", str[10], c;
   int i, j;

   j = -1;
   while (n) {
      j++;
      i = n % 10;
      str[j] = nums[i];
      n /= 10;
   }
   str[j + 1] = '\0';
   for (i = 0, j = (strlen(str) - 1); i < j; i++, j--) {
      c = str[i];
      str[i] = str[j];
      str[j] = c;
   }

   return(str);
}
