/* ARexx handling routines for ReminderCheck */

/* $Id: ARexx.c,v 1.1 1993/04/09 15:05:12 Matti_Rintala Exp $ */

#include <string.h>

#include <exec/types.h>
#include <exec/exec.h>
#include <rexx/storage.h>
#include <rexx/rxslib.h>

#ifdef __SASC
#include <proto/exec.h>
#include <proto/rexxsyslib.h>
#endif

#include "Constants.h"
#include "ARexx.h"

/* Calculate maximum length of the command line */
/* 'address "PORT" "COMMAND"' or rexxfilename "datestr" "textstr" */
#define MAXCMDLINE 10+AREXXPORTLEN+3+AREXXCOMLEN+2+TEXTLEN

/* Buffer for ARexx command */
static char cmdline[MAXCMDLINE+1];

/* Port for ARexx replys */
static struct MsgPort *MyPort = NULL;

struct Library *RexxSysBase = NULL;

/* initarexx initializes ARexx resources */
void initarexx(void) {

  /* Open RexxSys library */
  RexxSysBase = OpenLibrary(RXSNAME, 0);

  /* Open port */
  MyPort = CreateMsgPort();
}

/* releasearexx releases ARexx resources */
void releasearexx(void) {

  /* Close RexxSys library */
  if (RexxSysBase != NULL) {
    CloseLibrary(RexxSysBase);
    RexxSysBase = NULL;
  }

  /* Close port */
  if (MyPort != NULL) {
    DeleteMsgPort(MyPort);
    MyPort = NULL;
  }
}

/* makearexx handles the ARexx part of reminding */
void makearexx(struct EventNode *node, time_t *date) {
  
  struct RexxMsg *msg;
  char *buffer = cmdline;		/* Pointer to command line */
  int len;
  struct MsgPort *aport;

  /* Return if No Arexx mode event or if no message port or library */
  if ((node->mode != AREXXCMODE && node->mode != AREXXSMODE) ||
      MyPort == NULL || RexxSysBase == NULL)
    return;

  if ((msg = CreateRexxMsg(MyPort, NULL, NULL)) != NULL) {
    /* Now calculate correct argument string to buffer */
    if (node->mode == AREXXCMODE) {
      /* For ARexx command, argument is 'address "PORT" "COMMAND"' */
      strcpy(buffer, "\'address \"");
      buffer += 10;

      strncpy(buffer, node->arexxport, AREXXPORTLEN);
      len = strlen(node->arexxport);
      buffer += (len > AREXXPORTLEN) ? AREXXPORTLEN : len;

      *buffer++ = '\"';
      *buffer++ = ' ';
      *buffer++ = '\"';

      strncpy(buffer, node->arexxcom, AREXXCOMLEN);
      len = strlen(node->arexxcom);
      buffer += (len > AREXXCOMLEN) ? AREXXCOMLEN : len;

      *buffer++ = '\"';
      *buffer++ = '\'';
    }
    else {
      /* Script command is format scriptfile "datestr" "textstr" */
      struct tm *d;		/* For calculating datestr */

      strncpy(buffer, node->arexxcom, AREXXCOMLEN);
      len = strlen(node->arexxcom);
      buffer += (len > AREXXCOMLEN) ? AREXXCOMLEN : len;

      *buffer++ = ' ';
      *buffer++ = '\"';

      d = localtime(date);	/* Convert date to correct format */
      buffer += strftime(buffer, 16, "%a %d-%b-%Y", d);	/* Print datestr */

      *buffer++ = '\"';
      *buffer++ = ' ';
      *buffer++ = '\"';

      strncpy(buffer, node->text, TEXTLEN);
      len = strlen(node->text);
      buffer += (len > TEXTLEN) ? TEXTLEN : len;

      *buffer++ = '\"';
    }

    /* Calculate length of argument string */
    len = (int)(buffer - cmdline);
    /* Make ARexx argument string */
    if ((msg->rm_Args[0] = CreateArgstring(cmdline, len)) != NULL) {
      msg->rm_Action = RXCOMM | RXFF_NOIO; /* ARexx command flags */

      /* Then find AREXX port and send message */
      Forbid();
      if ((aport = FindPort("AREXX")) != NULL)
	PutMsg(aport, (struct Message *)msg);
      Permit();

      /* If sending was succesfull, wait for reply and remove it */
      if (aport) {
	WaitPort(MyPort);
	GetMsg(MyPort);
      }

      ClearRexxMsg(msg, 1);	/* Clear message */
    }
    DeleteRexxMsg(msg);		/* Delete message */
  }
}


