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 .: 14
- *
- * Date Author Comment
- * ========= ======== ====================
- * 09-Sep-90 Olsen Bug fixed in GetToken, added
- * IsSpace() and GetRexxClip()
- * 24-May-90 Olsen General rewrite, added new functions
- * 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 14
-
- /* Main rexx library base. */
-
- extern struct RxsLib *RexxSysBase;
-
- /* 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;
-
- /* Valid name given? */
-
- if(HostName && HostName[0])
- {
- /* Already present? */
-
- if(!FindPort((char *)HostName))
- {
- /* Allocate the port body. */
-
- if(RexxHost = (struct RexxHost *)AllocMem(sizeof(struct RexxHost),MEMF_PUBLIC | MEMF_CLEAR))
- {
- /* Allocate a signal bit. */
-
- if((RexxHost -> rh_Port . mp_SigBit = AllocSignal(-1)) != -1)
- {
- /* 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))
- {
- /* 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_SigTask = SysBase -> ThisTask;
-
- /* A dummy ID. */
-
- RexxHost -> rh_SpecialID = 'REXX';
-
- /* Finally add it to the public port list. */
-
- AddPort(&RexxHost -> rh_Port);
-
- /* And return it to the caller. */
-
- return(RexxHost);
- }
-
- FreeSignal(RexxHost -> rh_Port . mp_SigBit);
- }
-
- FreeMem(RexxHost,sizeof(struct RexxHost));
- }
- }
- }
-
- return(NULL);
- }
-
- /* 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;
-
- /* Valid host port given? */
-
- if(RexxHost && RexxHost -> rh_SpecialID == 'REXX')
- {
- /* Remove it from the public list. */
-
- RemPort(&RexxHost -> rh_Port);
-
- /* 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)
- {
- /* 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))
- {
- /* Add the command. */
-
- if(HostMessage -> rm_Args[0] = CreateArgstring((char *)CommandString,StrLen((char *)CommandString)))
- {
- /* This is a command, not a function. */
-
- HostMessage -> rm_Action = RXCOMM;
-
- /* Release it... */
-
- PutMsg(RexxPort,HostMessage);
-
- /* Successful action. */
-
- return(TRUE);
- }
-
- DeleteRexxMsg(HostMessage);
- }
- }
-
- return(FALSE);
- }
-
- /* 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);
- }
-
- /* IsSpace():
- *
- * Returns TRUE if the input character is a space, tab,
- * carriage return, newline, form feed or vertical tab.
- */
-
- STATIC BYTE
- IsSpace(UBYTE c)
- {
- if((c >= 13 && c <= 17) || c == 32)
- return(TRUE);
- else
- return(FALSE);
- }
-
- /* 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;
-
- SHORT i,StrEnd = 0,MaxPos = StrLen((char *)String);
-
- /* Last counter position. */
-
- if(MaxPos >= MaxLength + *StartChar)
- MaxPos = MaxLength + *StartChar - 1;
-
- /* Already finished with argument string? */
-
- if(*StartChar <= StrLen((char *)String) - 1 && String && String[0] && AuxBuff && MaxLength)
- {
- /* Parse the argument string... */
-
- for(i = *StartChar ; i <= MaxPos ; i++)
- {
- /* Skip leading blanks... */
-
- if(!StrEnd && IsSpace(String[i]))
- {
- while(IsSpace(String[i]) && i < MaxPos)
- {
- i++;
-
- (*StartChar)++;
- }
- }
-
- /* Found an argument. */
-
- if(IsSpace(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 Value;
- BYTE Sign = 1;
- SHORT i;
-
- /* Valid argument given? */
-
- if(String && !String[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);
- }
-
- return(0);
- }
-
- /* 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;
-
- SHORT i = 0,j;
- LONG Sign;
- UBYTE c;
-
- /* Valid argument given? */
-
- if(String)
- {
- /* 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;
- }
- }
-
- return(String);
- }
-
- /* AmigaToUpper(c):
- *
- * Replacement for toupper() macro, also knows how to
- * map international characters to uppercase. Note: not
- * a real library module.
- */
-
- STATIC UBYTE
- AmigaToUpper(UBYTE 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));
- }
-
- /* GetRexxMsg():
- *
- * Picks up pending RexxMessages from a RexxHost and
- * returns them to the caller. I desired, will wait
- * for new messages to arrive if none is present yet.
- */
-
- struct RexxMsg *
- GetRexxMsg(struct RexxHost *RexxHost,LONG Wait)
- {
- struct RexxHostBase *RexxHostBase;
- struct RexxMsg *RexxMessage = NULL;
-
- /* Valid pointer given? */
-
- if(RexxHost && RexxHost -> rh_SpecialID == 'REXX')
- {
- /* Try to pick up a message. */
-
- while(!(RexxMessage = (struct RexxMsg *)GetMsg((struct MsgPort *)RexxHost)))
- {
- /* No message available. Are we to wait? */
-
- if(Wait)
- WaitPort((struct MsgPort *)RexxHost);
- else
- break;
- }
- }
-
- /* Return the result (may be NULL). */
-
- return(RexxMessage);
- }
-
- /* SendRexxMsg():
- *
- * Sends a single (or a list of) command(s) to Rexx host
- * and returns the secondary result.
- */
-
- ULONG
- SendRexxMsg(STRPTR HostName,STRPTR *MsgList,STRPTR SingleMsg,LONG GetResult)
- {
- struct RexxHostBase *RexxHostBase;
- struct RexxMsg *RexxMessage;
- struct MsgPort *HostPort,*ReplyPort;
- ULONG Result = 0;
- SHORT i;
-
- /* Valid pointers given? */
-
- if(HostName && (MsgList || SingleMsg))
- {
- /* Can we find the host? */
-
- if(HostPort = (struct MsgPort *)FindPort((char *)HostName))
- {
- /* Allocate a reply port. */
-
- if(ReplyPort = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR))
- {
- if((ReplyPort -> mp_SigBit = AllocSignal(-1)) != -1)
- {
- ReplyPort -> mp_Node . ln_Type = NT_MSGPORT;
- ReplyPort -> mp_Flags = PA_SIGNAL;
- ReplyPort -> mp_SigTask = SysBase -> ThisTask;
-
- InitList(&ReplyPort -> mp_MsgList);
-
- /* Create a Rexx message. */
-
- if(RexxMessage = (struct RexxMsg *)CreateRexxMsg(ReplyPort,"",(char *)HostName))
- {
- /* A list of arguments or only a single arg? */
-
- if(MsgList)
- {
- for(i = 0 ; i < 16 ; i++)
- RexxMessage -> rm_Args[i] = MsgList[i];
- }
- else
- RexxMessage -> rm_Args[0] = SingleMsg;
-
- /* Do we want result codes? */
-
- if(GetResult)
- RexxMessage -> rm_Action = RXFF_RESULT;
-
- /* Send packet and wait for the reply. */
-
- PutMsg(HostPort,RexxMessage);
- WaitPort(ReplyPort);
-
- /* Remember result. */
-
- if(GetResult && !RexxMessage -> rm_Result1)
- Result = RexxMessage -> rm_Result2;
-
- /* Remove Rexx message. */
-
- DeleteRexxMsg(RexxMessage);
- }
-
- /* Free reply port signal bit. */
-
- FreeSignal(ReplyPort -> mp_SigBit);
- }
-
- /* Free the replyport itself. */
-
- FreeMem(ReplyPort,sizeof(struct MsgPort));
- }
- }
- }
-
- /* Return the result. */
-
- return(Result);
- }
-
- /* GetRexxString():
- *
- * Copy the result string returned by SendRexxMsg to user
- * buffer and/or remove the original string.
- */
-
- VOID
- GetRexxString(STRPTR SourceString,STRPTR DestString)
- {
- struct RexxHostBase *RexxHostBase;
-
- /* Valid pointer given? */
-
- if(SourceString)
- {
- /* Destination memory buffer given? */
-
- if(DestString)
- StrCpy((char *)DestString,(char *)SourceString);
-
- /* Deallocate the original string. */
-
- DeleteArgstring((char *)SourceString);
- }
- }
-
- /* GetRexxClip():
- *
- * Searches the rexx clip list for a node with given
- * name.
- */
-
- LONG
- GetRexxClip(char *Name,LONG WhichArg)
- {
- struct RexxHostBase *RexxHostBase;
-
- /* Do we have valid buffers and size? */
-
- if(Name && Name[0])
- {
- struct RexxRsrc *Node;
-
- /* Can we find the clip node? */
-
- if(Node = (struct RexxRsrc *)FindRsrcNode(&RexxSysBase -> rl_ClipList,Name,RRT_CLIP))
- {
- if(WhichArg)
- return(Node -> rr_Arg1);
- else
- return(Node -> rr_Arg2);
- }
- }
-
- return(NULL);
- }
-