/* init.c */ /* Copyright © 1989 by Donald T. Meyer, Stormgate Software * All Rights Reserved */ #include "rxil.h" #include #include static void unique_name( char portname[] ); struct RxsLib *RexxSysBase = NULL; static char library_version_string[] = RXIL_VERSION_STRING; /* NAME * RxilInit * * SYNOPSIS * rdef = RxilInit( flags, portname ); * * struct RxilDef *rdef; * * ULONG flags; * char *portname; * * FUNCTION * Open the ARexx library and setup our message ports. Then * allocate a RxilDef structure and do some default initialization * of it. * The portname will have a unique "instance" number appended * to it in the format "_#" where is the string as * specified in the portname argument, and is a decimal number * from 1-99 inclusive. This feature may be inhibited by setting * the RXIL_AS_IS flag. * * Even though this may fail, that should probably not be fatal * since the ARexx functionality is optional. The RxilCheckPort() * function is smart enough to just return if the rexx initialization * was not successsfull. Not to mention that RxilCheckPort() should * never get called since the rexx_sig_bit mask should be zero. * * INPUTS * flags These are various defined constants which control * which ports get opened and other various aspects * of port initialization. * * portname This is the name to use for the public ARexx port * that commands will be received at. It is suggested * that this be in uppercase and contain no spaces. * Maximum length is 40 characters, as set by the * defined constant RXIL_MAX_PORTNAME_LEN. * See discussion above about instance numbers. * * RESULT * A pointer to a RxilDef structure. Return is NULL for failure * to initialize the ARexx ports. * * SIDES * * HISTORY * 01-Aug-89 Creation. * 23-Sep-89 Changed "flags" arg from int to ULONG * 26-Sep-89 Sets the (new) version string pointer. * 01-Oct-89 Changed PublicPort name storage from a pointer to * a character array. Added "instance" numbering. * Added check on portname length. * * BUGS * This should probably share one signal bit between both ports * to avoid "hogging" signal bits. * * SEE ALSO * RxilCleanup(), RXIL_AS_IS, RXIL_MAX_PORTNAME_LEN */ struct RxilDef *RxilInit( ULONG flags, char *portname ) { char buf[24]; struct RxilDef *rdef; if( ( strlen(portname) < 1 ) || ( strlen(portname) > RXIL_MAX_PORTNAME_LEN ) ) { /* Portname is of an invalid length */ return( NULL ); } rdef = AllocMem( sizeof(struct RxilDef), MEMF_PUBLIC | MEMF_CLEAR ); if( rdef == NULL ) { return( NULL ); } /* Default initialization of the new RxilDef structure */ rdef->Console = NULL; rdef->Extension = "rexx"; rdef->HostPort = "REXX"; strcpy( rdef->PortName, portname ); if( FlagIsClear( flags, RXIL_AS_IS ) ) { /* Make sure the public port name is unique */ unique_name( rdef->PortName ); } /* Open Rexx library */ RexxSysBase = (struct RxsLib *)OpenLibrary( RXSNAME, 0L ); if( RexxSysBase == NULL ) { FreeMem( rdef, sizeof(struct RxilDef) ); return( NULL ); } if( FlagIsSet( flags, RXIL_PUBLIC ) ) { /* Setup our public port */ rdef->PublicPort = CreatePort( rdef->PortName, 1L ); if( rdef->PublicPort == NULL ) { CloseLibrary( (struct Library *)RexxSysBase ); RexxSysBase = NULL; FreeMem( rdef, sizeof(struct RxilDef) ); return( NULL ); } rdef->SigBit |= 1L << (rdef->PublicPort->mp_SigBit); } if( FlagIsSet( flags, RXIL_SECRET ) ) { /* Setup our secret port */ strcpy( rdef->SecretPortName, rdef->PortName ); strcat( rdef->SecretPortName, "_PRIVATE_" ); stcul_d( buf, (long)FindTask(NULL) ); strcat( rdef->SecretPortName, buf ); rdef->SecretPort = CreatePort( rdef->SecretPortName, 1L ); if( rdef->SecretPort == NULL ) { /* Failure */ if( rdef->PublicPort ) { RxilDeletePort( rdef->PublicPort ); rdef->PublicPort = NULL; } CloseLibrary( (struct Library *)RexxSysBase ); RexxSysBase = NULL; rdef->SigBit = 0; FreeMem( rdef, sizeof(struct RxilDef) ); return( NULL ); } rdef->SigBit |= 1L << (rdef->SecretPort->mp_SigBit); } /* Set the version string pointer. */ rdef->Version = &library_version_string[0]; return( rdef ); } /* * This will take the port name in the buffer, and add a sequential * invocation number to it to insure uniqueness. * * Note that this will increase the length of the given string! * Make sure that the buffer is at least 4 characters longer than * the original string. */ static void unique_name( char portname[] ) { char buf[RXIL_MAX_PORTNAME_LEN+10], buf2[4]; unsigned int i; for( i=1; i<100; i++ ) { strcpy( buf, portname ); /* Orig. name "APP" (example) */ strcat( buf, "_#" ); /* "APP_#" */ stcu_d( buf2, i ); strcat( buf, buf2 ); /* "APP_#1" */ if( FindPort( buf ) == NULL ) { /* Okay, this name does not exist. Let's use it. */ strcpy( portname, buf ); return; } } /* Amazing! If we actually get here, there are already 99 instances * of this program running. I cannot imagine ever getting here. :-) * If we do, then I guess we'll just collide... */ }