/* This version of rexx.c uses the rexxhost.library code incorporated
   directly into the program.
*/
#include "rexxhostbase.h"
#include <stdio.h>
#include "mb.h"

struct Library *RexxSysBase;
extern char optflags[];
struct RexxHost      *rexx_host;
struct MsgPort *non_rexx = 0L;
long rexxbit = 0L;
extern char tmpstr[];
char *portname = "CBBS-A";
extern char hostport;
/* Try to open the rexxsupport.library. Option G (6) turns REXX off */
open_rexx()
{

   portname[5] = hostport;
   if(!optflags[6]) {
      non_rexx = CreatePort((UBYTE *)portname,0L);
      return(0);
   }
   if((RexxSysBase = OpenLibrary((UBYTE *)RXSNAME, 0L)) == NULL) {
      printf("couldn't open rexxsupport.library.\n");
      return(1);
   }
      /* set up a public port for rexx to talk to us later */

   if(!(rexx_host = CreateRexxHost((STRPTR)portname)))   {
      printf("Can't set up public rexx port for port %c\n",hostport);
      CloseLibrary((struct Library *)RexxSysBase);
      return(1);
   }
   rexxbit = (1L << rexx_host->rh_Port.mp_SigBit);
   return(0);
}
close_rexx()
{
   struct RexxMsg *rexxmessage;  /* incoming rexx messages */
   STRPTR Arg;

   if(non_rexx) {
      DeletePort(non_rexx);
      return;
   }
/* Drain any messages for us */
   while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
      if(Arg = GetRexxCommand(rexxmessage)) {
         ReplyRexxCommand(rexxmessage,0L,0L,0L);
      }
      else {
         FreeRexxCommand(rexxmessage);
      }
   }
   if(rexx_host)
      rexx_host = DeleteRexxHost(rexx_host);

   if(RexxSysBase)CloseLibrary((struct Library *)RexxSysBase) ;
   RexxSysBase = NULL ;
}

/* This is called near the beginning of 'mb' to see if a port already
   exists with the given name. But if the hostport is a digit then this
   is a SYSOP process and if there's one already there then increment
   the digit and see if we can generate a free one
*/
testport()
{
   register char c;

   c = hostport;

   if(!optflags[6])return;
   portname[5] = c;
   while(FindPort((UBYTE *)portname)) {
      if(isdigit(c) && (c < '9')) {
         c++;
         portname[5] = c;
         continue;
      }
      printf("There's already a process on port '%c'\n",hostport);
      return(1);
   }
   hostport = c;
   return(0);
}

/* This routine can only be called from SYSOP. */
/* If you issue an A command, it is changed to an X and sent to a specified
   port or to all ports.
   Will also issue a 'Q' command to a port for you.
*/
putcomd(a,b)
char a,b;
{
   char data[3];
   STRPTR rexxname;
   char portchar;
   register PORTS *p;

   if(!optflags[6])return;
   /* Do AI - forward on all ports.
      a and b are the A command changed to an X .. eg AI will be input as XI
   */
   /* 'X ' or 'XI' force that command to all ports */
   if(a == 'X') {
      if((b == ' ') || (b == 'I')) {
         for(p = porthd; p isnt NULL; p = p->next) {
            if(p->id == 'Z')continue;
            rexxname = (STRPTR)"CBBS-A";
            rexxname[5] = p->id;
            data[0] = a;
            data[1] = b;
            data[2] = 0;
            if(SendRexxMsg(rexxname,0L,(STRPTR)data,1L) == 0) {
               sprintf(tmpstr,"Can't find port %c\n",p->id);
               ttputs(tmpstr);
            }
         }
         return;
      }
   }
   /* Either the command is of the form:
      Qx - where x is a port name which must be an alpha.
      Ix - where x is an alpha port name, or a digit which will be mapped
           into an alpha (A is 1 etc.) This allows you to get at port I
           by sending X9. XI won't send to port I, it'll go to all of them.
   */
   portchar = 0;
   if(isdigit(b)) {
      portchar = b ^ 0x70;
      b = ' ';
   }
   else {
      if(isalpha(b)) {
         portchar = toupper(b);
         b = 'I';
      }
   }
   if((portchar == 0) || ((portchar < 'A') && (portchar > 'P'))) {
      ttputs("Unrecognized port\n");
      return;
   }
   rexxname = (STRPTR)"CBBS-A";
   rexxname[5] = portchar;
   data[0] = a;
   if(a == 'Q')data[1] = ' ';
   else
               data[1] = b;
   data[2] = 0;
/*printf("->%s '%s'\n",rexxname,data);*/
   if(SendRexxMsg(rexxname,0L,(STRPTR)data,1L))return;
   sprintf(tmpstr,"Can't find port %c\n",portchar);
   ttputs(tmpstr);
}
/* Do a Quit in SYSOP (only). This sends a quit to another port. */
rexx_done()
{
   putcomd(port->opt1,port->opt2);
}
