home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
comm
/
amitcp-3.0ß2.lha
/
AmiTCP
/
src
/
amitcp
/
kern
/
amiga_rexx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-05
|
8KB
|
277 lines
RCS_ID_C="$Id: amiga_rexx.c,v 1.17 1994/01/05 10:23:02 jraja Exp $";
/*
* Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
* Helsinki University of Technology, Finland.
* All rights reserved.
*
* $Log: amiga_rexx.c,v $
* Revision 1.17 1994/01/05 10:23:02 jraja
* Added new functions: rexx_show() and rexx_hide().
* Removed AddPort() and RemPort() calls from other functions.
*
* Revision 1.16 1993/07/26 08:22:50 jraja
* Changed ARexx port name from 'NETTRACE' to 'AMITCP'.
*
* Revision 1.15 1993/06/04 11:16:15 jraja
* Fixes for first public release.
*
* Revision 1.14 1993/05/17 01:07:47 ppessi
* Changed RCS version.
*
* Revision 1.13 1993/04/25 03:04:51 jraja
* Moved RemPort() upper in function rexx_deinit(). Changed bsd_free() type
* argument to the same as the corresponding bsd_malloc().
*
* Revision 1.12 93/04/23 21:03:08 21:03:08 puhuri (Markus Peuhkuri)
* Add code to check if we had to alloc more buffer and free it.
*
* Revision 1.11 93/04/23 00:28:34 00:28:34 ppessi (Pekka Pessi)
* using now parseline() (in amiga_config.c) to parse Arexx messages
*
* Revision 1.10 93/04/21 19:08:04 19:08:04 puhuri (Markus Peuhkuri)
* Add new feature: Connections. UNFINISHED.
*
* Revision 1.9 93/04/06 15:15:39 15:15:39 jraja (Jarno Tapio Rajahalme)
* Changed spl function return value storage to spl_t,
* changed bcopys and bzeros to aligned and/or const when possible,
* added inclusion of conf.h to every .c file.
*
* Revision 1.8 93/03/20 07:06:21 07:06:21 ppessi (Pekka Pessi)
* Support multiple instances. Library name, rexx port name and task name fixed.
*
* Revision 1.7 93/03/05 21:11:07 21:11:07 jraja (Jarno Tapio Rajahalme)
* Fixed includes (again).
*
* Revision 1.6 93/03/05 12:28:33 12:28:33 jraja (Jarno Tapio Rajahalme)
* Changed RexxSysBase and UtilityBase to struct Library in GCC to
* follow SASC convention.
* Removed __stdargs in GCC.
*
* Revision 1.5 93/03/05 03:25:59 03:25:59 ppessi (Pekka Pessi)
* Compiles with SASC. Initial test version.
*
* Revision 1.4 93/03/04 10:59:50 10:59:50 jraja (Jarno Tapio Rajahalme)
* Minor cosmetic changes.
*
* Revision 1.3 93/03/02 18:23:12 18:23:12 puhuri (Markus Peuhkuri)
* Transformed toupper to utility/ToUpper and add open&close for utility.lib
*
* Revision 1.2 93/03/01 19:11:56 19:11:56 puhuri (Markus Peuhkuri)
* Major rewrite to remove simplerexx.c and to make arexx-interface
* more efficient.
*
* Revision 1.1 93/02/25 19:59:18 19:59:18 puhuri (Markus Peuhkuri)
* Initial revision
*
*/
#include <conf.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <kern/amiga_config.h>
#include <kern/amiga_includes.h>
#include <dos/rdargs.h>
#if __GNUC__
char *strtok(char *,char *);
#endif
#include <rexx/storage.h>
#include <rexx/rxslib.h>
#if __SASC
#include <proto/rexxsyslib.h>
#include <proto/utility.h>
#elif __GNUC__
/*
* predefine RexxSysBase and UtilityBase to Library to follow SASC convention.
*/
#define BASE_EXT_DECL extern struct Library * RexxSysBase;
#define BASE_NAME (struct RexxSysBase *)RexxSysBase
#include <inline/rexxsyslib.h>
struct ClockData;
#define BASE_EXT_DECL extern struct Library * UtilityBase;
#define BASE_NAME (struct UtilityBase *)UtilityBase
#include <inline/utility.h>
#endif
/*
* The rexx port and error name may change, if there is already an
* AmiTCP/IP task running
*/
#define D_REXX_PORT_NAME "AMITCP"
#define REXX_ERROR_POSTFIX ".LASTERROR"
#define D_REXX_ERROR_NAME D_REXX_PORT_NAME REXX_ERROR_POSTFIX
UBYTE T_REXX_PORT_NAME[] = D_REXX_PORT_NAME;
UBYTE *REXX_PORT_NAME = T_REXX_PORT_NAME;
UBYTE T_REXX_ERROR_NAME[] = D_REXX_ERROR_NAME;
UBYTE *REXX_ERROR_NAME = T_REXX_ERROR_NAME;
#define REXX_RETURN_ERROR ((struct RexxMsg *)-1L)
extern LONG nthLibrary;
#include <kern/amiga_rexx.h>
/*
* This function returns a structure that contains the commands sent from
* ARexx... You will need to parse it and return the structure back
* so that the memory can be freed...
*
* This returns NULL if there was no message...
*/
STKARGFUN long SetRexxVar(struct Message *, char *, char *, long);
struct Library *UtilityBase = NULL;
struct Library *RexxSysBase = NULL;
struct MsgPort *ARexxPort = NULL;
ULONG
rexx_init(void)
{
if (
#ifdef DEBUG
(REXX_PORT_NAME =
bsd_malloc(sizeof(D_REXX_PORT_NAME) + 3, M_CFGVAR, M_WAITOK)) &&
(REXX_ERROR_NAME =
bsd_malloc(sizeof(D_REXX_ERROR_NAME) + 3, M_CFGVAR, M_WAITOK)) &&
#endif
(UtilityBase = OpenLibrary("utility.library", 37)) &&
(RexxSysBase = OpenLibrary("rexxsyslib.library", 0L))) {
ARexxPort = CreateMsgPort();
if (ARexxPort) {
#ifdef DEBUG
strcpy(REXX_PORT_NAME, D_REXX_PORT_NAME);
strcpy(REXX_ERROR_NAME, D_REXX_PORT_NAME);
if (nthLibrary) {
REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)-1] = '.';
REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)] = '0' + nthLibrary;
REXX_PORT_NAME[sizeof(D_REXX_PORT_NAME)+1] = '\0';
REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)-1] = '.';
REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)] = '0' + nthLibrary;
REXX_ERROR_NAME[sizeof(D_REXX_PORT_NAME)+1] = '\0';
}
strcat(REXX_ERROR_NAME, REXX_ERROR_POSTFIX);
#endif
ARexxPort->mp_Node.ln_Name = REXX_PORT_NAME;
return (ULONG)1 << ARexxPort->mp_SigBit;
}
}
rexx_deinit();
return (0);
}
static BOOL rexx_shown = FALSE;
BOOL
rexx_show(void)
{
if (!rexx_shown && ARexxPort) {
AddPort(ARexxPort); /* No return value! */
rexx_shown = TRUE;
return TRUE;
}
return FALSE;
}
BOOL
rexx_hide(void)
{
if (rexx_shown) {
if (ARexxPort) {
/*
* Remove the port from the system's message port list so that the
* port cannot be found any more
*/
RemPort(ARexxPort);
}
rexx_shown = FALSE;
}
return TRUE;
}
void rexx_deinit(void)
{
struct RexxMsg *rmsg;
static STRPTR errstr = "99: Port Closed!";
if (RexxSysBase) {
if (ARexxPort) {
rexx_hide();
/*
* Reply to all messages received with error code set.
*/
while(rmsg = (struct RexxMsg *)GetMsg(ARexxPort)){
SetRexxVar((struct Message *)rmsg, REXX_ERROR_NAME,
errstr, strlen(errstr));
if (rmsg != REXX_RETURN_ERROR){
rmsg->rm_Result2 = 0;
rmsg->rm_Result1 = 100;
ReplyMsg((struct Message *)rmsg);
}
}
DeleteMsgPort(ARexxPort);
ARexxPort = NULL;
}
CloseLibrary(RexxSysBase);
RexxSysBase = NULL;
}
if (UtilityBase) {
CloseLibrary(UtilityBase);
UtilityBase = NULL;
}
}
BOOL rexx_poll(void)
{
struct RexxMsg *rmsg;
if ((rmsg = (struct RexxMsg *)GetMsg(ARexxPort))
&& rmsg != REXX_RETURN_ERROR
&& IsRexxMsg(rmsg)) {
UBYTE rbuf[REPLYBUFLEN];
struct CSource result;
struct CSource csarg;
UBYTE *errstr = NULL;
LONG error = 0;
result.CS_Buffer = rbuf;
result.CS_Length = REPLYBUFLEN - 1;
result.CS_CurChr = 0;
csarg.CS_Buffer = ARG0(rmsg);
csarg.CS_Length = LengthArgstring(ARG0(rmsg)) + 1;
csarg.CS_CurChr = 0;
csarg.CS_Buffer[csarg.CS_Length - 1] = '\n'; /* Sentinel */
rmsg->rm_Result1 = rmsg->rm_Result2 = 0;
if (error = parseline(&csarg, &errstr, &result)) {
SetRexxVar((struct Message*)rmsg, REXX_ERROR_NAME,
errstr, (long)strlen(errstr));
rmsg->rm_Result1 = error;
} else {
if (rmsg->rm_Action & (1L << RXFB_RESULT)) {
rmsg->rm_Result2 = (LONG)
CreateArgstring(result.CS_Buffer, (LONG)strlen(result.CS_Buffer));
}
}
csarg.CS_Buffer[csarg.CS_Length - 1] = '\0';
ReplyMsg((struct Message *)rmsg);
if (result.CS_Buffer != rbuf) /* We've allocated memory */
bsd_free(result.CS_Buffer, M_TEMP);
return TRUE;
}
return FALSE;
}