#pragma extend
#include <i86.h>

#define  RMXRET     short
#define  RMXOBJ     selector

#include <rmx.h>
#include <ic.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>

#define  FALSE      0
#define  TRUE       ~FALSE

/* parameter offsets */

#define NOT         1

#define EXISTS      first
#define PATHNAME    (first + 1)

#define STRING1     first
#define EQUALS      (first + 1)
#define STRING2     (first + 2)

#define OS          first
#define OSNAME      (first + 1)

#define SLOT        first
#define SLOTNO      (first + 1)

#define TERM        first
#define TERMNAME    (first + 1)

#define TYPE        first
#define TYPENAME    (first + 1)

RMXOBJ  ci_tkn, co_tkn, cmd_tkn;
short   success;

char    *ffirst( char * ), *fnext( void );

/****************************************************************************/
/* explain_ccode_and_die - outputs explanation of erroneous condition code  */
/* and aborts execution                                                     */
/****************************************************************************/

const char whilel[]  = "while loading command";
const char whilee[]  = "while executing command";
const char whilep[]  = "while parsing command";

void explain_ccode_and_die( short ccode, const char *msg )
    {
    short   status;
    char    buff[50];
        
    buff[0] = 0;
    RQCFORMATEXCEPTION( buff, 50, ccode, 1, &status );

    if ( status != E_OK )
        sprintf( buff, "%04X: E$UNKNOWN$EXCEPTION", ccode );
    else
        cstr( buff, buff );

    printf( "\n%s, %s\n", buff, msg );
    exit( ccode );
    }

/****************************************************************************/
/* execcmd - execute a single command                                       */
/****************************************************************************/

void execcmd( char *cmd )
    {
    short status, cmd_status, index;
    char  elsestr[5];

    /* remove white space from beginning of command */

    while ( *cmd <= ' ' )
        ++cmd;

    /* remove white space from end of command */

    udistr( cmd, cmd );
    index = *cmd;
    
    while ( cmd[index] <= ' ' )
        --index;

    *cmd = index;
    
    /* if our "special" command, handle appropriately */

    if ( index == 4 )
        {
        cstr( elsestr, cmd );

        if ( !strcmpi( elsestr, "else" ) )
            {
            success = ~success;
            return;
            }
        }

    /* have O/S execute command if in "success" command set */

    if ( success )
        {
        RQCSENDCOMMAND( cmd_tkn, cmd, &cmd_status, &status );

        if ( ( status != E_OK ) && ( status != E_CONTINUED ) )
            explain_ccode_and_die( status, whilel );
    
        if ( cmd_status != E_OK )
            explain_ccode_and_die( cmd_status, whilee );
        }
    }
                    
/****************************************************************************/
/* execcmds - executes command(s)                                           */
/****************************************************************************/

void execcmds( char *cmd )
    {
    char *this, *next;

    this = cmd;

    while ( ( next = strchr( this, '!' ) ) != NULL )
        {
        *next = '\0';
        execcmd( this );
        this = ++next;
        }
    
    execcmd( this );
    }

/****************************************************************************/
/* syntax - indicates syntax error, explains the proper syntax and exits    */
/****************************************************************************/

void syntax()
    {
    printf( "\n\nIMPROPER COMMAND SYNTAX !!!\n\n" );
    printf( "  Use: \"IF [NOT] <condition> <commands> [! ELSE ! <commands>]\"\n\n" );
    printf( "Where: <condition> is \"<string1> == <string2>\"\n" );
    printf( "                   or \"EXIST <filename>\"\n" );
    printf( "                   or \"OS <os-name>\"\n" );
    printf( "                   or \"TERM <terminal-name>\"\n" );
    printf( "                   or \"SLOT <mbii-slot>\" (valid only on MBII systems)\n" );
    printf( "                   or \"TYPE <board-type>\" (also valid only on MBII systems)\n\n" );
    printf( "        <commands> is \"<command> [! <command>]*\"\n\n" );
    exit( 0 );
    }

/****************************************************************************/
/* main                                                                     */
/****************************************************************************/

int main( int argc, char *argv[] )
    {
    char                    str[256], *crt_str;
    short                   status, adder, index, first;
    unsigned short          our_slot, his_slot;
    RMXOBJ                  global_job, crt_obj;
    EXCP_HANDLER_ATTRIBS    attribs;

    attribs.mode = NO_EXCEPTIONS;
    RQSETEXCEPTIONHANDLER( &attribs, &status );

    ci_tkn = RQCGETINPUTCONNECTION( CONSOLE_INPUT_DEVICE, &status );

    if ( status == E_OK )
        co_tkn = RQCGETOUTPUTCONNECTION( CONSOLE_OUTPUT_DEVICE, OVER_PREPOSITION, &status );

    if ( status == E_OK )
        cmd_tkn = RQCCREATECOMMANDCONNECTION( ci_tkn, co_tkn, 0, &status );

    if ( status != E_OK )
        explain_ccode_and_die( status, whilep );

    if ( !strcmpi( argv[NOT], "not" ) )
        {
        adder = 1;
        success = TRUE;
        first = NOT + 1;
        }
    else
        {
        adder = 0;
        success = FALSE;
        first = NOT;
        }

    if ( !strcmpi( argv[EXISTS], "exist" ) )
        {
        if ( argc < ( adder + 4 ) )
            syntax();
            
        if ( ffirst( argv[PATHNAME] ) != NULL )
            success = ~success;
        
        first = PATHNAME + 1;
        }
    else
        if ( !strcmpi( argv[OS], "os" ) )
            {
            if ( argc < ( adder + 4 ) )
                syntax();

            dqgetsystemid( str, &status );

            if ( status )
                explain_ccode_and_die( status, whilep );

            cstr( str, str );

            if ( !strcmpi( argv[OSNAME], str ) )
                success = ~success;

            first = OSNAME + 1;
            }
        else
            if ( !strcmpi( argv[SLOT], "slot" ) )
                {
                if ( argc < ( adder + 4 ) )
                    syntax();

                our_slot = RQGETHOSTID( &status );
                
                if ( status )
                    syntax();
                    
                status = sscanf( argv[SLOTNO], "%hu", &his_slot );

                if ( status == EOF )
                    syntax();
                    
                if ( our_slot == his_slot )
                    success = ~success;
                
                first = SLOTNO + 1;
                }
            else
                if ( !strcmpi( argv[TERM], "term" ) )
                    {
                    if ( argc < ( adder + 4 ) )
                        syntax();

                    global_job = RQLOOKUPOBJECT( THIS_JOB, "\010RQGLOBAL", 0, &status );
                
                    if ( status )
                        syntax();

                    crt_obj = RQLOOKUPOBJECT( global_job, "\005R?CRT", 0, &status );
                    
                    if ( status )
                        syntax();
                    
                    cstr( str, (const char *)buildptr( crt_obj, 0 ) );
                  
                    if ( !strcmpi( argv[TERMNAME], str ) )
                        success = ~success;
                
                    first = TERMNAME + 1;
                    }
                else
                    if ( !strcmpi( argv[TYPE], "type" ) )
                        {
                        if ( argc < ( adder + 4 ) )
                            syntax();

                        for ( index = 0; index < 10; index++ )
                            {
                            str[index] = RQGETINTERCONNECT( THIS_SLOT, index + IC_BOARD_ID_B1, &status );
                            
                            if ( status )
                                syntax();
                                
                            if ( !str[index] )
                                break;
                            }
                            
                        if ( !strcmpi( argv[TYPENAME], str ) )
                            success = ~success;
                
                        first = TYPENAME + 1;
                        }
                    else    /* string1 == string2 */
                        {
                        if ( argc < ( adder + 5 ) )
                            syntax();
                
                        if ( strcmp( argv[EQUALS], "==" ) != 0 )
                            syntax();
                    
                        if ( !strcmpi( argv[STRING1], argv[STRING2] ) )
                            success = ~success;
            
                        first = STRING2 + 1;
                        }

    strcpy( str, argv[first] );
        
    for ( index = first + 1; index < argc; index++ )
        {
        if ( strlen(str) > 200 )
            {
            strcat( str, " &" );
            execcmds( str );
            strcpy( str, argv[index] );
            }
        else
            {
            strcat( str, " " );
            strcat( str, argv[index] );
            }
        }

    execcmds( str );
    exit( 0 );
    }
