home *** CD-ROM | disk | FTP | other *** search
- /* $Revision Header * Header built automatically - do not edit! *************
- *
- * (C) Copyright 1990 by MXM
- *
- * Name .....: RexxHostLib.c
- * Created ..: Sunday 07-Jan-90 18:55
- * Revision .: 12
- *
- * Date Author Comment
- * ========= ======== ====================
- * 26-Apr-90 Olsen Supports short integers (16 bits)
- * 13-Apr-90 Olsen Added assembly language routines
- * 31-Mar-90 Olsen Rewrote RexxStrCmp
- * 19-Mar-90 Olsen More sanity checks
- * 17-Mar-90 Olsen Added RexxStrCmp, rewrote
- * CreateRexxHost/DeleteRexxHost,
- * ANSIfication
- * 16-Mar-90 Olsen Rework for Aztec 5.0 release
- * 07-Jan-90 Olsen Added string conversion functions
- * 07-Jan-90 Olsen Added GetToken
- * 07-Jan-90 Olsen - Empty log message -
- * 07-Jan-90 Olsen Removed bug in SendRexxCommand
- * 07-Jan-90 Olsen - Empty log message -
- * 07-Jan-90 Olsen Created this file!
- *
- ****************************************************************************
- *
- * This Amiga shared library is based on example source code
- * written by Gary Samad & Bill Hawes.
- *
- * $Revision Header ********************************************************/
- #define REVISION 12
-
- /* The protos. */
-
- struct RexxMsg *CreateRexxMsg(struct MsgPort *,char *,char *);
- STRPTR CreateArgstring(char *,LONG);
- VOID DeleteRexxMsg(struct RexxMsg *);
- VOID DeleteArgstring(char *);
- STATIC LONG AmigaToUpper(LONG);
-
- /* The magic pragma. */
-
- #pragma regcall(AmigaToUpper(d0))
-
- /* Bill Hawes didn't distribute an .fd file along
- * with the 1.10 release of ARexx. I had to put these
- * pragmas together by hand.
- */
-
- #pragma amicall(RexxSysBase, 0x90, CreateRexxMsg(a0,a1,d0))
- #pragma amicall(RexxSysBase, 0x7e, CreateArgstring(a0,d0))
- #pragma amicall(RexxSysBase, 0x96, DeleteRexxMsg(a0))
- #pragma amicall(RexxSysBase, 0x84, DeleteArgstring(a0))
-
- /* Global revision identifier. */
-
- LONG Revision = REVISION;
-
- /* CreateRexxHost(HostName):
- *
- * Creates a RexxHost (special MsgPort) with a given name.
- * Returns NULL if port already exists.
- */
-
- struct RexxHost *
- CreateRexxHost(STRPTR HostName)
- {
- struct RexxHostBase *RexxHostBase;
- struct RexxHost *RexxHost = NULL;
-
- /* Our pointer to ExecBase. */
-
- extern struct ExecBase *SysBase;
-
- if(HostName && HostName[0])
- {
- /* Already present? */
-
- if(!FindPort((char *)HostName))
- {
- LONG SigBit;
-
- /* Allocate a signal bit. */
-
- if((SigBit = AllocSignal(-1)) == -1)
- goto Quit;
-
- /* Allocate the port body. */
-
- if(!(RexxHost = (struct RexxHost *)AllocMem(sizeof(struct RexxHost),MEMF_PUBLIC | MEMF_CLEAR)))
- {
- FreeSignal(SigBit);
- goto Quit;
- }
-
- /* Initialize the MsgPort node head. */
-
- RexxHost -> rh_Port . mp_Node . ln_Type = NT_MSGPORT;
- RexxHost -> rh_Port . mp_Node . ln_Pri = 1;
-
- /* Allocate memory for MsgPort name. */
-
- if(!(RexxHost -> rh_Port . mp_Node . ln_Name = (char *)AllocMem(StrLen((char *)HostName) + 1,MEMF_PUBLIC)))
- {
- FreeMem(RexxHost,sizeof(struct RexxHost));
- FreeSignal(SigBit);
-
- RexxHost = NULL;
-
- goto Quit;
- }
-
- /* Copy the name. */
-
- StrCpy(RexxHost -> rh_Port . mp_Node . ln_Name,(char *)HostName);
-
- /* Deal with the rest of the flags. */
-
- RexxHost -> rh_Port . mp_Flags = PA_SIGNAL;
- RexxHost -> rh_Port . mp_SigBit = SigBit;
- RexxHost -> rh_Port . mp_SigTask = SysBase -> ThisTask;
-
- /* A dummy ID. */
-
- RexxHost -> rh_SpecialID = 'REXX';
-
- /* Finally add it to the public port list. */
-
- AddPort(&RexxHost -> rh_Port);
- }
- }
-
- Quit: return(RexxHost);
- }
-
- /* DeleteRexxHost(RexxHost):
- *
- * Deletes a MsgPort as created by CreateRexxHost().
- * Returns NULL, so user can do 'Host = DeleteRexxHost(Host);'.
- */
-
- VOID *
- DeleteRexxHost(struct RexxHost *RexxHost)
- {
- struct RexxHostBase *RexxHostBase;
-
- if(RexxHost && RexxHost -> rh_SpecialID == 'REXX')
- {
- /* Remove it from the public list. */
-
- RemPort(&RexxHost -> rh_Port);
-
- /* Make it difficult to reuse it by accident. */
-
- RexxHost -> rh_Port . mp_Node . ln_Type = 0xFF;
- RexxHost -> rh_Port . mp_MsgList . lh_Head = (struct Node *)-1;
-
- /* Free the name. */
-
- FreeMem(RexxHost -> rh_Port . mp_Node . ln_Name,StrLen(RexxHost -> rh_Port . mp_Node . ln_Name) + 1);
-
- /* Free the allocated signal bit. */
-
- FreeSignal(RexxHost -> rh_Port . mp_SigBit);
-
- /* Free the body. */
-
- FreeMem(RexxHost,sizeof(struct RexxHost));
- }
-
- return(NULL);
- }
-
- /* SendRexxCommand(HostPort,CommandString,FileExtension,HostName):
- *
- * Sends a command to the rexx server, requires pointers
- * to the MsgPort of the calling Host and the command string.
- * File extension and host name are optional and may be
- * NULL.
- */
-
- LONG
- SendRexxCommand(struct RexxHost *HostPort,STRPTR CommandString,STRPTR FileExtension,STRPTR HostName)
- {
- struct RexxHostBase *RexxHostBase;
-
- struct MsgPort *RexxPort = (struct MsgPort *)FindPort(RXSDIR);
- struct RexxMsg *HostMessage;
-
- /* Valid pointers given? */
-
- if(!CommandString || !HostPort || HostPort -> rh_SpecialID != 'REXX' || !RexxPort)
- return(FALSE);
-
- /* No special host name given? Take the MsgPort name. */
-
- if(!HostName)
- HostName = (STRPTR)HostPort -> rh_Port . mp_Node . ln_Name;
-
- /* No file name extension? Take the default. */
-
- if(!FileExtension)
- FileExtension = (STRPTR)"rexx";
-
- /* Create the message. */
-
- if(!(HostMessage = CreateRexxMsg((struct MsgPort *)HostPort,(char *)FileExtension,(char *)HostName)))
- return(FALSE);
-
- /* Add the command. */
-
- if(!(HostMessage -> rm_Args[0] = CreateArgstring((char *)CommandString,StrLen((char *)CommandString))))
- {
- DeleteRexxMsg(HostMessage);
- return(FALSE);
- }
-
- /* This is a command, not a function. */
-
- HostMessage -> rm_Action = RXCOMM;
-
- /* Release it... */
-
- PutMsg(RexxPort,HostMessage);
-
- /* Successful action. */
-
- return(TRUE);
- }
-
- /* FreeRexxCommand(RexxMessage):
- *
- * Frees the contents of a RexxMsg.
- */
-
- VOID
- FreeRexxCommand(struct RexxMsg *RexxMessage)
- {
- struct RexxHostBase *RexxHostBase;
-
- /* Valid pointer given? */
-
- if(RexxMessage && RexxMessage -> rm_Node . mn_Node . ln_Type == NT_REPLYMSG)
- {
- /* Remove argument. */
-
- if(RexxMessage -> rm_Args[0])
- DeleteArgstring((char *)RexxMessage -> rm_Args[0]);
-
- /* Free the message. */
-
- DeleteRexxMsg(RexxMessage);
- }
- }
-
- /* ReplyRexxCommand(RexxMessage,Primary,Secondary,Result):
- *
- * Sends a RexxMsg back to the rexx server, can include
- * result codes.
- */
-
- VOID
- ReplyRexxCommand(struct RexxMsg *RexxMessage,LONG Primary,LONG Secondary,STRPTR Result)
- {
- struct RexxHostBase *RexxHostBase;
-
- /* Valid pointer given? */
-
- if(RexxMessage && RexxMessage -> rm_Node . mn_Node . ln_Type == NT_MESSAGE)
- {
- /* No secondary result and results wanted? */
-
- if(Secondary == NULL && (RexxMessage -> rm_Action & RXFF_RESULT))
- {
- /* Build result string... */
-
- if(Result)
- Secondary = (LONG)CreateArgstring((char *)Result,StrLen((char *)Result));
- }
-
- /* Set both results... */
-
- RexxMessage -> rm_Result1 = Primary;
- RexxMessage -> rm_Result2 = Secondary;
-
- /* ...and reply the message. */
-
- ReplyMsg(RexxMessage);
- }
- }
-
- /* GetRexxCommand(RexxMessage):
- *
- * Returns a pointer to the command string if
- * the RexxMsg is a command request.
- */
-
- STRPTR
- GetRexxCommand(struct RexxMsg *RexxMessage)
- {
- struct RexxHostBase *RexxHostBase;
-
- if(!RexxMessage || RexxMessage -> rm_Node . mn_Node . ln_Type == NT_REPLYMSG)
- return(NULL);
- else
- return(RexxMessage -> rm_Args[0]);
- }
-
- /* GetRexxArg(RexxMessage):
- *
- * Returns a pointer to the first RexxMsg argument.
- */
-
- STRPTR
- GetRexxArg(struct RexxMsg *RexxMessage)
- {
- struct RexxHostBase *RexxHostBase;
-
- if(!RexxMessage)
- return(NULL);
- else
- return(RexxMessage -> rm_Args[0]);
- }
-
- /* GetRexxResult1(RexxMessage):
- *
- * Returns the 1st RexxMsg result.
- */
-
- LONG
- GetRexxResult1(struct RexxMsg *RexxMessage)
- {
- struct RexxHostBase *RexxHostBase;
-
- if(!RexxMessage)
- return(NULL);
- else
- return(RexxMessage -> rm_Result1);
- }
-
- /* GetRexxResult2(RexxMessage):
- *
- * Returns the 2nd RexxMsg result.
- */
-
- LONG
- GetRexxResult2(struct RexxMsg *RexxMessage)
- {
- struct RexxHostBase *RexxHostBase;
-
- if(!RexxMessage)
- return(NULL);
- else
- return(RexxMessage -> rm_Result2);
- }
-
- /* GetToken(String,StartChar,AuxBuff,MaxLength):
- *
- * Fills a string with the next given string
- * argument.
- */
-
- STRPTR
- GetToken(STRPTR String,LONG *StartChar,STRPTR AuxBuff,LONG MaxLength)
- {
- struct RexxHostBase *RexxHostBase;
-
- LONG i,StrEnd = 0,MaxPos = StrLen((char *)String);
-
- /* Last counter position. */
-
- if(MaxPos >= MaxLength)
- MaxPos = MaxLength - 1;
-
- /* Already finished with argument string? */
-
- if(*StartChar > StrLen((char *)String) - 1 || !String || !String[0] || !AuxBuff || !MaxLength)
- return(NULL);
-
- /* Parse the argument string... */
-
- for(i = *StartChar ; i <= MaxPos ; i++)
- {
- /* Skip leading blanks... */
-
- if(!StrEnd && String[i] == ' ')
- {
- while(String[i] == ' ' && i < MaxPos)
- {
- i++;
-
- (*StartChar)++;
- }
- }
-
- /* Found an argument. */
-
- if(String[i] == ' ' || String[i] == 0)
- {
- /* Copy it to the auxiliary buffer. */
-
- StrNCpy((char *)AuxBuff,(char *)(String + *StartChar),StrEnd);
- AuxBuff[StrEnd] = 0;
-
- /* Change the position counter (since
- * we can't use static data initialisation
- * calling program has to supply a
- * counter variable).
- */
-
- (*StartChar) += StrEnd;
-
- return(AuxBuff);
- }
-
- /* Increment character counter. */
-
- StrEnd++;
- }
-
- return(NULL);
- }
-
- /* GetStringValue(String):
- *
- * Returns the numeric value taken from given string
- * (just like atoi(), taken from example source code
- * by K&R).
- */
-
- LONG
- GetStringValue(STRPTR String)
- {
- struct RexxHostBase *RexxHostBase;
-
- LONG i,Value,Sign = 1;
-
- /* Valid argument given? */
-
- if(!String || !String[0])
- return(0);
-
- /* Skip leading blank characters. */
-
- for(i = 0 ; String[i] == ' ' || String[i] == '\n' || String[i] == '\t' ; i++);
-
- /* Remember sign extension. */
-
- if(String[i] == '+' || String[i] == '-')
- Sign = (String[i++] == '+') ? 1 : -1;
-
- /* Convert from ASCII to decimal. */
-
- for(Value = 0 ; String[i] >= '0' && String[i] <= '9' ; i++)
- Value = 10 * Value + String[i] - '0';
-
- /* Return real value. */
-
- return(Sign * Value);
- }
-
- /* BuildValueString(Value,String):
- *
- * Puts a numeric value in decimal form into a
- * given string (similar to itoa(), taken from
- * example source code by K&R).
- */
-
- STRPTR
- BuildValueString(LONG Value,STRPTR String)
- {
- struct RexxHostBase *RexxHostBase;
-
- LONG i = 0,j,c,Sign;
-
- /* Valid argument given? */
-
- if(!String)
- return(NULL);
-
- /* Remember sign extension. */
-
- if((Sign = Value) < 0)
- Value = -Value;
-
- /* Convert it into ASCII characters (in
- * reverse order, i.e. 1234 = "4321").
- */
-
- do
- String[i++] = Value % 10 + '0';
- while((Value /= 10) > 0);
-
- /* Add sign extension. */
-
- if(Sign < 0)
- String[i++] = '-';
-
- /* String NULL-termination. */
-
- String[i] = 0;
-
- /* Reverse the string. */
-
- for(i = 0, j = StrLen((char *)String) - 1 ; i < j ; i++, j--)
- {
- c = String[i];
- String[i] = String[j];
- String[j] = c;
- }
-
- /* Finished, return the string. */
-
- return(String);
- }
-
- /* AmigaToUpper(c):
- *
- * Replacement for toupper() macro, also knows how to
- * map international characters to uppercase. Note: not
- * a real library module.
- */
-
- STATIC LONG
- AmigaToUpper(LONG c)
- {
- /* -------- DEC --------- -------- ASCII ------- */
-
- if((c >= 224 && c <= 254) || (c >= 'a' && c <= 'z'))
- c -= 32;
-
- return(c);
- }
-
- /* RexxStrCmp(Source,Target):
- *
- * Compares two strings ignoring case.
- */
-
- LONG
- RexxStrCmp(STRPTR Source,STRPTR Target)
- {
- struct RexxHostBase *RexxHostBase;
-
- /* Do the string comparison ignoring case. */
-
- for( ; AmigaToUpper(*Source) == AmigaToUpper(*Target) ; Source++, Target++)
- {
- if(!(*Source))
- return(0);
- }
-
- return(AmigaToUpper(*Source) - AmigaToUpper(*Target));
- }
-