/* dispatch.c */ /* Copyright © 1989 by Donald T. Meyer, Stormgate Software * All Rights Reserved */ #include "rxil.h" #include /* NAME * RxilDispatch * * SYNOPSIS * RxilDispatch( rexxmsg, cmd ); * * struct RexxMsg *rexxmsg; * char *cmd; * * FUNCTION * This is really an "internal" function which is used by * the RxilCheckPort() function to dispatch commands. * * It is not static, since it may be usefull by itself, or * it may desireable to replace it with a custom version * in some applications. This can be done simply by overriding * it, rather than editing the library itself. * * This is NOT a "safe" call, since it should never be called * directly from client code. * It is however safe if the client fails to initialize the command * table pointer. * * * INPUTS * rexxmsg = pointer to the RexxMsg structure for the command we * are dispatching. * cmd = the command name string. * * RESULT * None * * SIDES * * HISTORY * 01-Aug-89 Creation. * 26-Sep-89 Changed to use maximum and minimum argcounts. * * BUGS * * SEE ALSO * RxilCheckPort() */ void RxilDispatch( struct RexxMsg *rexxmsg, char *cmd ) { unsigned int i; int match = -1; unsigned int argcount; /* Make call "safe" even if RxilInit() failed */ if( global_rdef->CommandTable == NULL ) { /* This is an unlikely mistake on the client's part, but * let's fail gracefully just in case. */ rexxmsg->rm_Result1 = RXERR_UNKNOWN_CMD; return; } for( i=0; global_rdef->CommandTable[i].Name != NULL; i++ ) { if( global_rdef->CommandTable[i].CaseFlag == TRUE ) { /* Case sensitive */ if( strcmp( global_rdef->CommandTable[i].Name, cmd ) == 0 ) { /* A match */ match = i; break; } } else { /* Not case sensitive */ if( stricmp( global_rdef->CommandTable[i].Name, cmd ) == 0 ) { /* A match */ match = i; break; } } } if( match == -1 ) { /* No match found */ rexxmsg->rm_Result1 = RXERR_UNKNOWN_CMD; return; } /* Check privilege level */ if( global_rdef->CommandTable[match].Privilege > global_rdef->FromRexx ) { /* Not from the correct port! */ rexxmsg->rm_Result1 = RXERR_NOT_A_HARMLESS_CMD; return; } /* Are we locked? If so, we respond only to commands * received at the secret port. */ if( ( global_rdef->LockCount != 0 ) && ( global_rdef->FromRexx < RXIL_SECRET ) ) { rexxmsg->rm_Result1 = RXERR_BUSY; return; } #if 0 /* Do the argument checking */ if( ( global_rdef->CommandTable[match].ArgCount != RXIL_NO_ARGCHECK ) && ( (global_rdef->ArgCount-1) != global_rdef->CommandTable[match].ArgCount ) ) { /* Wrong number of args */ rexxmsg->rm_Result1 = RXERR_ARG_COUNT; return; } #endif /* Do the argument checking */ argcount = global_rdef->ArgCount - 1; /* This is -1 since ArgCount * includes the command name * itself. This is in keeping * with the 'C' conventions * for argc and argv. */ if( argcount < global_rdef->CommandTable[match].MinArgs ) { /* Wrong number of args */ rexxmsg->rm_Result1 = RXERR_NO_ARGUMENT; return; } if( argcount > global_rdef->CommandTable[match].MaxArgs ) { /* Wrong number of args */ rexxmsg->rm_Result1 = RXERR_TOO_MANY_ARGS; return; } /* Call the function. */ (*(global_rdef->CommandTable[match].Func))(rexxmsg); }