Пример #1
0
int
main(int argc, char **argv)
{
    rcComm_t *conn;
    rodsEnv myRodsEnv;
    rErrMsg_t errMsg;
    int status;
    msParamArray_t msParamArray;
    dataObjInp_t dataObjOpenInp, dataObjCreateInp, dataObjCopyInp;
    execMyRuleInp_t execMyRuleInp;
    msParamArray_t *outParamArray = NULL;


    if (argc != 4) {
        fprintf(stderr, "Usage: %s rods_dataObj1, rods_dataObj2\n",argv[0]);
        exit(1);
    }

    status = getRodsEnv (&myRodsEnv);

    if (status < 0) {
	fprintf (stderr, "getRodsEnv error, status = %d\n", status);
	exit (1);
    }

    memset (&msParamArray, 0, sizeof (msParamArray));

    memset (&dataObjOpenInp, 0, sizeof (dataObjOpenInp));
    snprintf (dataObjOpenInp.objPath, MAX_NAME_LEN, "%s/%s",
      myRodsEnv.rodsCwd, argv[1]);

    memset (&dataObjCreateInp, 0, sizeof (dataObjCreateInp));
    snprintf (dataObjCreateInp.objPath, MAX_NAME_LEN, "%s/%s",
      myRodsEnv.rodsCwd, argv[2]);

    memset (&dataObjCopyInp, 0, sizeof (dataObjCopyInp));
    snprintf (dataObjCopyInp.objPath, MAX_NAME_LEN, "%s/%s",
      myRodsEnv.rodsCwd, argv[3]);

    addMsParam (&msParamArray, "*A", "DataObjInp_PI", &dataObjOpenInp, NULL);
    addMsParam (&msParamArray, "*B", "DataObjInp_PI", &dataObjCreateInp, NULL);
    addMsParam (&msParamArray, "*C", "DataObjInp_PI", &dataObjCopyInp, NULL);

#if 0
    memset (&dataObjLseekInp, 0, sizeof (dataObjLseekInp));
    dataObjLseekInp.fileInx = 101;
    dataObjLseekInp.offset = 1000;
    dataObjLseekInp.whence = SEEK_SET;
    addMsParam (&msParamArray, "C", "fileLseekInp_PI", 
      &dataObjLseekInp, NULL);
#endif

    memset (&errMsg, 0, sizeof (rErrMsg_t));

    conn = rcConnect (myRodsEnv.rodsHost, myRodsEnv.rodsPort, USER_NAME,
      RODS_ZONE, 0, &errMsg);

    if (conn == NULL) {
        fprintf (stderr, "rcConnect error\n");
        exit (1);
    }

    status = clientLogin(conn);
    if (status != 0) {
        rcDisconnect(conn);
        exit (7);
    }

    memset (&execMyRuleInp, 0, sizeof (execMyRuleInp));
#if 0
    rstrcpy (execMyRuleInp.myRule, "myTestRule||msiDataObjOpen(*A,*X)##|msiDataObjLseek(*X,*B,*Y)##msiDataObjClose(*C,*Z)", META_STR_LEN);
    rstrcpy (execMyRuleInp.myRule, "myTestRule||msiDataObjOpen(*A,*X)##msiDataObjCreate(*B,null,*Y)##msiDataObjClose(*X,*Z1)##msiDataObjClose(*Y,*Z2)", META_STR_LEN);
    rstrcpy (execMyRuleInp.outParamDesc, "*X%*Y%*Z1%*Z2", LONG_NAME_LEN);
#endif
    rstrcpy (execMyRuleInp.myRule, "myTestRule||msiDataObjOpen(*A,*S_FD)##msiDataObjCreate(*B,null,*D_FD)##msiDataObjLseek(*S_FD,10,SEEK_SET,*junk1)##msiDataObjRead(*S_FD,10000,*R_BUF)##msiDataObjWrite(*D_FD,*R_BUF,*W_LEN)##msiDataObjClose(*S_FD,*junk2)##msiDataObjClose(*D_FD,*junk3)##msiDataObjCopy(*B,*C,null,*junk4)##delayExec(msiDataObjRepl(*C,demoResc8,*junk5),<A></A>)##msiDataObjUnlink(*B,*junk6)", META_STR_LEN);
    rstrcpy (execMyRuleInp.outParamDesc, "*R_BUF%*W_LEN", LONG_NAME_LEN);

    execMyRuleInp.inpParamArray = &msParamArray;  
    status = rcExecMyRule (conn, &execMyRuleInp, &outParamArray);

    if (status < 0) {
        rError_t *err;
        rErrMsg_t *errMsg;
	int i, len;

	printf ("rcExecMyRule error, status = %d\n", status);
        if ((err = conn->rError) != NULL) {
            len = err->len;
            for (i=0;i<len;i++) {
                errMsg = err->errMsg[i];
                printf("Level %d: %s\n",i, errMsg->msg);
	    }
        }
    } else {
	 printf ("rcExecMyRule success\n");
    }
    rcDisconnect (conn);
} 
Пример #2
0
int
main( int argc, char **argv ) {

    signal( SIGPIPE, SIG_IGN );

    int status;
    rodsEnv myEnv;
    rErrMsg_t errMsg;
    rcComm_t *conn;
    boost::program_options::variables_map argsMap;
    irods::error err;
    bool useSaveFile = false;
    execMyRuleInp_t execMyRuleInp;
    msParamArray_t *outParamArray = NULL;
    msParamArray_t msParamArray;
    int rulegen;

    int connFlag = 0;
    char saveFile[MAX_NAME_LEN];
    char ruleFile[MAX_NAME_LEN];
    char cmdLineInput[MAX_NAME_LEN];
    err = parseProgramOptions( argc, argv, argsMap ); 

    if ( !err.ok() ) {
        std::cerr << "Error in parsing command line arguments" << std::endl;
        exit( 1 );
    }

    if ( argsMap.count( "help" ) ) {
        usage(/*std::cout*/);
        exit( 0 );
    }

    /* init data structures */
    memset( &execMyRuleInp, 0, sizeof( execMyRuleInp ) );
    memset( &msParamArray, 0, sizeof( msParamArray ) );
    execMyRuleInp.inpParamArray = &msParamArray;
    execMyRuleInp.condInput.len = 0;

    /* add key val for test mode */
    if ( argsMap.count( "test" ) ) {
        addKeyVal( &execMyRuleInp.condInput, "looptest", "true" );
    }
    /* add key val for specifying instance on which to run rule */
    if ( argsMap.count( "rule-engine-plugin-instance" ) ) {
        addKeyVal( &execMyRuleInp.condInput, irods::CFG_INSTANCE_NAME_KW.c_str(), argsMap["rule-engine-plugin-instance"].as<std::string>().c_str() );
    }
    /* Don't need to parse parameters if just listing available rule_engine_instances */
    if ( argsMap.count( "available" ) ) {
        /* add key val for listing available rule engine instances */
        addKeyVal( &execMyRuleInp.condInput, "available", "true" );
    } else {
        /* read rules from the input file */
        if ( argsMap.count( "file" ) ) {
            FILE *fptr;
            int len;
            int gotRule = 0;
            char buf[META_STR_LEN];
            const char* fileName;

            try {
                fileName = argsMap["file"].as< std::string >().c_str();
            } catch ( boost::bad_any_cast& e ) {
                std::cerr << "Bad filename provided to --file option\n";
                std::cerr << "Use -h or --help for help\n";
                exit( 10 );
            } catch ( std::out_of_range& e ) {
                std::cerr << "No filename provided to --file option\n";
                std::cerr << "Use -h or --help for help\n";
                exit( 10 );
            }

            // =-=-=-=-=-=-=-
            // initialize pluggable api table
            irods::api_entry_table&  api_tbl = irods::get_client_api_table();
            irods::pack_entry_table& pk_tbl  = irods::get_pack_table();
            init_api_table( api_tbl, pk_tbl );

            /* if the input file name starts with "i:", the get the file from iRODS server */
            if ( !strncmp( fileName, "i:", 2 ) ) {
                status = getRodsEnv( &myEnv );

                if ( status < 0 ) {
                    rodsLogError( LOG_ERROR, status, "main: getRodsEnv error. " );
                    exit( 1 );
                }

                conn = rcConnect( myEnv.rodsHost, myEnv.rodsPort, myEnv.rodsUserName,
                        myEnv.rodsZone, 0, &errMsg );

                if ( conn == NULL ) {
                    exit( 2 );
                }

                status = clientLogin( conn );
                if ( status != 0 ) {
                    rcDisconnect( conn );
                    exit( 7 );
                }
                if ( status == 0 ) {
                    char *myargv[3];
                    int myargc, myoptind;
                    rodsPathInp_t rodsPathInp;
                    rodsArguments_t myRodsArgs;
                    connFlag = 1;

                    myargv[0] = strdup( fileName + 2 );
                    myargv[1] = saveFile;
                    myargc = 2;
                    myoptind = 0;
                    const char *fileType = strrchr( fileName, '.' );
                    if ( fileType == NULL ) {
                        printf( "Unsupported input file type\n" );
                        exit( 10 );
                    }
                    if ( strcmp( fileType, ".r" ) == 0 ) {
                        rulegen = 1;
                    }
                    else if ( strcmp( fileType, ".ir" ) == 0 || strcmp( fileType, ".irb" ) == 0 ) {
                        rulegen = 0;
                    }
                    else {
                        rodsLog( LOG_ERROR,
                                "Unsupported input file type %s\n", fileType );
                        exit( 10 );
                    }
                    snprintf( saveFile, MAX_NAME_LEN, "/tmp/tmpiruleFile.%i.%i.%s",
                            ( unsigned int ) time( 0 ), getpid(), rulegen ? "r" : "ir" );
                    status = parseCmdLinePath( myargc, myargv, myoptind, &myEnv,
                            UNKNOWN_OBJ_T, UNKNOWN_FILE_T, 0, &rodsPathInp );
                    status = getUtil( &conn, &myEnv, &myRodsArgs, &rodsPathInp );
                    if ( status < 0 ) {
                        rcDisconnect( conn );
                        exit( 3 );
                    }

                    useSaveFile = true;
                    connFlag = 1;
                }
            }

            if ( useSaveFile ) {
                rstrcpy( ruleFile, saveFile, MAX_NAME_LEN );
            } else {
                rstrcpy( ruleFile, fileName, MAX_NAME_LEN );
            }

            fptr = fopen( ruleFile, "r" );

            /* test if the file can be opened */
            if ( fptr == NULL ) {
                rodsLog( LOG_ERROR, "Cannot open input file %s. errno = %d\n",
                        ruleFile, errno );
                exit( 1 );
            }

            /* test if the file extension is supported */
            const char *fileType = strrchr( ruleFile, '.' );
            if ( fileType == NULL ) {
                printf( "Unsupported input file type\n" );
                exit( 10 );

            }
            else if ( strcmp( fileType, ".r" ) == 0 ) {
                rulegen = 1;
            }
            else if ( strcmp( fileType, ".ir" ) == 0 || strcmp( fileType, ".irb" ) == 0 ) {
                rulegen = 0;
            }
            else {
                rodsLog( LOG_ERROR,
                        "Unsupported input file type %s\n", fileType );
                exit( 10 );
            }

            /* add the @external directive in the rule if the input file is in the new rule engine syntax */
            if ( rulegen ) {
                rstrcpy( execMyRuleInp.myRule, "@external\n", META_STR_LEN );
            }

            while ( ( len = getLine( fptr, buf, META_STR_LEN ) ) > 0 ) {
                if ( argsMap.count( "list" ) ) {
                    puts( buf );
                }

                /* skip comments if the input file is in the old rule engine syntax */
                if ( !rulegen && buf[0] == '#' ) {
                    continue;
                }

                if ( rulegen ) {
                    if ( startsWith( buf, "INPUT" ) || startsWith( buf, "input" ) ) {
                        gotRule = 1;
                        trimSpaces( trimPrefix( buf ) );
                    }
                    else if ( startsWith( buf, "OUTPUT" ) || startsWith( buf, "output" ) ) {
                        gotRule = 2;
                        trimSpaces( trimPrefix( buf ) );
                    }
                }

                if ( gotRule == 0 ) {
                    if ( !rulegen ) {
                        /* the input is a rule */
                        snprintf( execMyRuleInp.myRule + strlen( execMyRuleInp.myRule ), META_STR_LEN - strlen( execMyRuleInp.myRule ), "%s\n", buf );
                    }
                    else {
                        snprintf( execMyRuleInp.myRule + strlen( execMyRuleInp.myRule ), META_STR_LEN - strlen( execMyRuleInp.myRule ), "%s\n", buf );
                    }
                }
                else if ( gotRule == 1 ) {
                    if ( rulegen ) {
                        if ( convertListToMultiString( buf, 1 ) != 0 ) {
                            rodsLog( LOG_ERROR,
                                "Input parameter list format error for %s\n", ruleFile );
                            exit( 10 );
                        }
                    }
                    parseParameters( argsMap, rulegen, &execMyRuleInp, buf );
                }
                else if ( gotRule == 2 ) {
                    if ( rulegen ) {
                        if ( convertListToMultiString( buf, 0 ) != 0 ) {
                            rodsLog( LOG_ERROR,
                                "Output parameter list format error for %s\n", ruleFile );
                            exit( 10 );
                        }
                    }
                    if ( strcmp( buf, "null" ) != 0 ) {
                        rstrcpy( execMyRuleInp.outParamDesc, buf, LONG_NAME_LEN );
                    }
                    break;
                }
                else {
                    break;
                }
                if ( !rulegen ) {
                    gotRule++;
                }
            }

            if ( argsMap.count( "list" ) ) {
                puts( "-----------------------------------------------------------------" );
            }

            if ( gotRule != 2 ) {
                rodsLog( LOG_ERROR, "Incomplete rule input for %s", ruleFile );
                //                     argsMap["file"].as<std::string>().c_str() );
                exit( 2 );
            }
            if ( connFlag == 1 ) {
                fclose( fptr );
                unlink( saveFile );
            }
        }
        else {	/* command line input */
            std::vector< std::string > parameters;
            try {
                parameters = argsMap["parameters"].as< std::vector< std::string> >();
            } catch ( boost::bad_any_cast& e ) {
                std::cerr << "Bad parameter list provided\n";
                std::cerr << "Use -h or --help for help\n";
                exit( 10 );
            } catch ( std::out_of_range& e ) {
                std::cerr << "No parameters list provided\n";
                std::cerr << "Use -h or --help for help\n";
                exit( 10 );
            }

            rulegen = 1;
            if ( parameters.size() < 3 ) {
                rodsLog( LOG_ERROR, "incomplete input" );
                fprintf(stderr, "Use -h for help.\n" );
                exit( 3 );
            }
            
            snprintf( execMyRuleInp.myRule, META_STR_LEN, "@external rule { %s }", parameters.at(0).c_str() );
            rstrcpy( cmdLineInput, parameters.at(1).c_str(), MAX_NAME_LEN );

            if (0 != parseParameters( argsMap, 1, &execMyRuleInp, cmdLineInput )) {
                rodsLog (LOG_ERROR, "Invalid input parameter list specification");
                fprintf( stderr, "Use -h for help.\n" );
                exit(10);
            }

            if ( parameters.at(2) != "null") {
                rstrcpy( execMyRuleInp.outParamDesc, parameters.at(2).c_str(), LONG_NAME_LEN );
            }
        }
    }

    if ( connFlag == 0 ) {
        status = getRodsEnv( &myEnv );

        if ( status < 0 ) {
            rodsLogError( LOG_ERROR, status, "main: getRodsEnv error. " );
            exit( 1 );
        }

        conn = rcConnect( myEnv.rodsHost, myEnv.rodsPort, myEnv.rodsUserName,
                          myEnv.rodsZone, 0, &errMsg );

        if ( conn == NULL ) {
            rodsLogError( LOG_ERROR, errMsg.status, "rcConnect failure %s",
                          errMsg.msg );
            exit( 2 );
        }

        status = clientLogin( conn );
        if ( status != 0 ) {
            rcDisconnect( conn );
            exit( 7 );
        }
    }

    if ( argsMap.count( "verbose" ) ) {
        printf( "rcExecMyRule: %s\n", rulegen ? execMyRuleInp.myRule + 10 : execMyRuleInp.myRule );
        printf( "outParamDesc: %s\n", execMyRuleInp.outParamDesc );
    }

    status = rcExecMyRule( conn, &execMyRuleInp, &outParamArray );

    if ( argsMap.count( "test" ) ) {
        printErrorStack( conn->rError );
    }

    if ( status < 0 ) {
        msParam_t *mP;
        execCmdOut_t *execCmdOut;

        if ( !rulegen ) {
            rodsLogError( LOG_ERROR, status, "rcExecMyRule error. The rule engine is running under backward compatible mode. To run the rule(s) under normal mode, try renaming the file extension to \".r\". " );

        }
        else {
            rodsLogError( LOG_ERROR, status, "rcExecMyRule error. " );

        }
        printErrorStack( conn->rError );
        if ( ( mP = getMsParamByType( outParamArray, ExecCmdOut_MS_T ) ) != NULL ) {
            execCmdOut = ( execCmdOut_t * ) mP->inOutStruct;
            if ( execCmdOut->stdoutBuf.buf != NULL ) {
                fprintf( stdout, "%s", ( char * ) execCmdOut->stdoutBuf.buf );
            }
            if ( execCmdOut->stderrBuf.buf != NULL ) {
                fprintf( stderr, "%s", ( char * ) execCmdOut->stderrBuf.buf );
            }
        }
        rcDisconnect( conn );
        exit( 4 );
    }

    if ( argsMap.count( "verbose" ) ) {
        printf( "ExecMyRule completed successfully.    Output \n\n" );
        printMsParamNew( outParamArray, 1 );
    }
    else {
        printMsParamNew( outParamArray, 0 );
        msParam_t *mP;
        execCmdOut_t *execCmdOut;
        if ( ( mP = getMsParamByType( outParamArray, ExecCmdOut_MS_T ) ) != NULL ) {
            execCmdOut = ( execCmdOut_t * ) mP->inOutStruct;
            if ( execCmdOut->stdoutBuf.buf != NULL ) {
                fprintf( stdout, "%s", ( char * ) execCmdOut->stdoutBuf.buf );
            }
            if ( execCmdOut->stderrBuf.buf != NULL ) {
                fprintf( stderr, "%s", ( char * ) execCmdOut->stderrBuf.buf );
            }
        }
    }
    if ( argsMap.count( "verbose" ) && conn->rError != NULL ) {
        int i, len;
        rErrMsg_t *errMsg;
        len = conn->rError->len;
        for ( i = 0; i < len; i++ ) {
            errMsg = conn->rError->errMsg[i];
            printf( "%s\n", errMsg->msg );
        }
    }

    printErrorStack( conn->rError );
    rcDisconnect( conn );
    exit( 0 );

}
Пример #3
0
int
main( int argc, char **argv ) {
    int status;
    rodsEnv myEnv;
    rErrMsg_t errMsg;
    rcComm_t *conn;
    rodsArguments_t myRodsArgs;
    char *optStr;
    execMyRuleInp_t execMyRuleInp;
    msParamArray_t *outParamArray = NULL;
    msParamArray_t msParamArray;
    int rulegen;

    int connFlag = 0;
    char saveFile[MAX_NAME_LEN];

    optStr = "ZhlvF:s";

    status = parseCmdLineOpt( argc, argv, optStr, 1, &myRodsArgs );

    if ( status < 0 ) {
        printf( "Use -h for help.\n" );
        exit( 1 );
    }

    if ( myRodsArgs.help == True ) {
        usage();
        exit( 0 );
    }

    /* init data structures */
    memset( &execMyRuleInp, 0, sizeof( execMyRuleInp ) );
    memset( &msParamArray, 0, sizeof( msParamArray ) );
    execMyRuleInp.inpParamArray = &msParamArray;
    execMyRuleInp.condInput.len = 0;

    /* add key val for test mode */
    if ( myRodsArgs.test == True ) {
        addKeyVal( &execMyRuleInp.condInput, "looptest", "true" );
    }

    /* read rules from the input file */
    if ( myRodsArgs.file == True ) {
        FILE *fptr;
        int len;
        int gotRule = 0;
        char buf[META_STR_LEN];
        char *inpParamNames[1024];
        char *outParamNames[1024];

        // =-=-=-=-=-=-=-
        // initialize pluggable api table
        irods::api_entry_table&  api_tbl = irods::get_client_api_table();
        irods::pack_entry_table& pk_tbl  = irods::get_pack_table();
        init_api_table( api_tbl, pk_tbl );

        /* if the input file name starts with "i:", the get the file from iRODS server */
        if ( !strncmp( myRodsArgs.fileString, "i:", 2 ) ) {
            status = getRodsEnv( &myEnv );

            if ( status < 0 ) {
                rodsLogError( LOG_ERROR, status, "main: getRodsEnv error. " );
                exit( 1 );
            }

            conn = rcConnect( myEnv.rodsHost, myEnv.rodsPort, myEnv.rodsUserName,
                              myEnv.rodsZone, 0, &errMsg );

            if ( conn == NULL ) {
                exit( 2 );
            }

            status = clientLogin( conn );
            if ( status != 0 ) {
                rcDisconnect( conn );
                exit( 7 );
            }
            if ( status == 0 ) {
                char *myargv[3];
                int myargc, myoptind;
                rodsPathInp_t rodsPathInp;
                connFlag = 1;

                myargv[0] = strdup( myRodsArgs.fileString + 2 );
                myargv[1] = saveFile;
                myargc = 2;
                myoptind = 0;
                char *fileType = strrchr( myRodsArgs.fileString, '.' );
                if ( fileType == NULL ) {
                    printf( "Unsupported input file type\n" );
                    exit( 10 );
                }
                if ( strcmp( fileType, ".r" ) == 0 ) {
                    rulegen = 1;
                }
                else if ( strcmp( fileType, ".ir" ) == 0 || strcmp( fileType, ".irb" ) == 0 ) {
                    rulegen = 0;
                }
                else {
                    rodsLog( LOG_ERROR,
                             "Unsupported input file type %s\n", fileType );
                    exit( 10 );
                }
                snprintf( saveFile, MAX_NAME_LEN, "/tmp/tmpiruleFile.%i.%i.%s",
                          ( unsigned int ) time( 0 ), getpid(), rulegen ? "r" : "ir" );
                status = parseCmdLinePath( myargc, myargv, myoptind, &myEnv,
                                           UNKNOWN_OBJ_T, UNKNOWN_FILE_T, 0, &rodsPathInp );
                status = getUtil( &conn, &myEnv, &myRodsArgs, &rodsPathInp );
                if ( status < 0 ) {
                    rcDisconnect( conn );
                    exit( 3 );
                }
                myRodsArgs.fileString = saveFile;
                connFlag = 1;
            }
        }

        fptr = fopen( myRodsArgs.fileString, "r" );

        /* test if the file can be opened */
        if ( fptr == NULL ) {
            rodsLog( LOG_ERROR, "Cannot open input file %s. errno = %d\n",
                     myRodsArgs.fileString, errno );
            exit( 1 );
        }

        /* test if the file extension is supported */
        char *fileType = strrchr( myRodsArgs.fileString, '.' );
        if ( fileType == NULL ) {
            printf( "Unsupported input file type\n" );
            exit( 10 );

        }
        else if ( strcmp( fileType, ".r" ) == 0 ) {
            rulegen = 1;
        }
        else if ( strcmp( fileType, ".ir" ) == 0 || strcmp( fileType, ".irb" ) == 0 ) {
            rulegen = 0;
        }
        else {
            rodsLog( LOG_ERROR,
                     "Unsupported input file type %s\n", fileType );
            exit( 10 );
        }

        /* add the @external directive in the rule if the input file is in the new rule engine syntax */
        if ( rulegen ) {
            rstrcpy( execMyRuleInp.myRule, "@external\n", META_STR_LEN );
        }

        while ( ( len = getLine( fptr, buf, META_STR_LEN ) ) > 0 ) {
            if ( myRodsArgs.longOption == True ) {
                puts( buf );
            }

            /* skip comments if the input file is in the old rule engine syntax */
            if ( !rulegen && buf[0] == '#' ) {
                continue;
            }

            if ( rulegen ) {
                if ( startsWith( buf, "INPUT" ) || startsWith( buf, "input" ) ) {
                    gotRule = 1;
                    trimSpaces( trimPrefix( buf ) );
                }
                else if ( startsWith( buf, "OUTPUT" ) || startsWith( buf, "output" ) ) {
                    gotRule = 2;
                    trimSpaces( trimPrefix( buf ) );
                }
            }

            if ( gotRule == 0 ) {
                if ( !rulegen ) {
                    /* the input is a rule */
                    snprintf( execMyRuleInp.myRule + strlen( execMyRuleInp.myRule ), META_STR_LEN - strlen( execMyRuleInp.myRule ), "%s\n", buf );
                }
                else {
                    snprintf( execMyRuleInp.myRule + strlen( execMyRuleInp.myRule ), META_STR_LEN - strlen( execMyRuleInp.myRule ), "%s\n", buf );
                }
            }
            else if ( gotRule == 1 ) {
                if ( rulegen ) {
                    if ( convertListToMultiString( buf, 1 ) != 0 ) {
                        rodsLog( LOG_ERROR,
                                 "Input parameter list format error for %s\n", myRodsArgs.fileString );
                        exit( 10 );
                    }
                }
                extractVarNames( inpParamNames, buf );
                parseMsInputParam( argc, argv, optind, rulegen, myRodsArgs.string, &execMyRuleInp, buf );
            }
            else if ( gotRule == 2 ) {
                if ( rulegen ) {
                    if ( convertListToMultiString( buf, 0 ) != 0 ) {
                        rodsLog( LOG_ERROR,
                                 "Output parameter list format error for %s\n", myRodsArgs.fileString );
                        exit( 10 );
                    }
                }
                extractVarNames( outParamNames, buf );
                if ( strcmp( buf, "null" ) != 0 ) {
                    rstrcpy( execMyRuleInp.outParamDesc, buf, LONG_NAME_LEN );
                }
                break;
            }
            else {
                break;
            }
            if ( !rulegen ) {
                gotRule++;
            }
        }

        if ( myRodsArgs.longOption == True ) {
            puts( "-----------------------------------------------------------------" );
        }

        if ( gotRule != 2 ) {
            rodsLog( LOG_ERROR, "Incomplete rule input for %s",
                     myRodsArgs.fileString );
            exit( 2 );
        }
        if ( connFlag == 1 ) {
            fclose( fptr );
            unlink( saveFile );
        }
    }
    else {	/* command line input */
        rulegen = 1;
        int nArg = argc - optind; /* number of rule arguments */
        if ( nArg < 3 ) {
            rodsLog( LOG_ERROR, "no input" );
            printf( "Use -h for help.\n" );
            exit( 3 );
        }

        snprintf( execMyRuleInp.myRule, META_STR_LEN, "@external rule { %s }", argv[optind] );
        parseMsInputParam( 0, NULL, 0, 1, myRodsArgs.string, &execMyRuleInp, argv[optind + 1] );
        if ( strcmp( argv[optind + 2], "null" ) != 0 ) {
            rstrcpy( execMyRuleInp.outParamDesc, argv[optind + 2],
                     LONG_NAME_LEN );
        }
    }


    if ( connFlag == 0 ) {
        status = getRodsEnv( &myEnv );

        if ( status < 0 ) {
            rodsLogError( LOG_ERROR, status, "main: getRodsEnv error. " );
            exit( 1 );
        }

        conn = rcConnect( myEnv.rodsHost, myEnv.rodsPort, myEnv.rodsUserName,
                          myEnv.rodsZone, 0, &errMsg );

        if ( conn == NULL ) {
            rodsLogError( LOG_ERROR, errMsg.status, "rcConnect failure %s",
                          errMsg.msg );
            exit( 2 );
        }

        status = clientLogin( conn );
        if ( status != 0 ) {
            rcDisconnect( conn );
            exit( 7 );
        }
    }

    if ( myRodsArgs.verbose == True ) {
        printf( "rcExecMyRule: %s\n", rulegen ? execMyRuleInp.myRule + 10 : execMyRuleInp.myRule );
        printf( "outParamDesc: %s\n", execMyRuleInp.outParamDesc );
    }

    status = rcExecMyRule( conn, &execMyRuleInp, &outParamArray );

    if ( myRodsArgs.test == True ) {
        printErrorStack( conn->rError );
    }

    if ( status < 0 ) {
        msParam_t *mP;
        execCmdOut_t *execCmdOut;

        if ( !rulegen ) {
            rodsLogError( LOG_ERROR, status, "rcExecMyRule error. The rule engine is running under backward compatible mode. To run the rule(s) under normal mode, try renaming the file extension to \".r\". " );

        }
        else {
            rodsLogError( LOG_ERROR, status, "rcExecMyRule error. " );

        }
        printErrorStack( conn->rError );
        if ( ( mP = getMsParamByType( outParamArray, ExecCmdOut_MS_T ) ) != NULL ) {
            execCmdOut = ( execCmdOut_t * ) mP->inOutStruct;
            if ( execCmdOut->stdoutBuf.buf != NULL ) {
                fprintf( stdout, "%s", ( char * ) execCmdOut->stdoutBuf.buf );
            }
            if ( execCmdOut->stderrBuf.buf != NULL ) {
                fprintf( stderr, "%s", ( char * ) execCmdOut->stderrBuf.buf );
            }
        }
        rcDisconnect( conn );
        exit( 4 );
    }

    if ( myRodsArgs.verbose == True ) {
        printf( "ExecMyRule completed successfully.    Output \n\n" );
        printMsParamNew( outParamArray, 1 );
    }
    else {
        printMsParamNew( outParamArray, 0 );
        msParam_t *mP;
        execCmdOut_t *execCmdOut;
        if ( ( mP = getMsParamByType( outParamArray, ExecCmdOut_MS_T ) ) != NULL ) {
            execCmdOut = ( execCmdOut_t * ) mP->inOutStruct;
            if ( execCmdOut->stdoutBuf.buf != NULL ) {
                fprintf( stdout, "%s", ( char * ) execCmdOut->stdoutBuf.buf );
            }
            if ( execCmdOut->stderrBuf.buf != NULL ) {
                fprintf( stderr, "%s", ( char * ) execCmdOut->stderrBuf.buf );
            }
        }
    }
    if ( myRodsArgs.verbose == True && conn->rError != NULL ) {
        int i, len;
        rErrMsg_t *errMsg;
        len = conn->rError->len;
        for ( i = 0; i < len; i++ ) {
            errMsg = conn->rError->errMsg[i];
            printf( "%s\n", errMsg->msg );
        }
    }

    printErrorStack( conn->rError );
    rcDisconnect( conn );
    exit( 0 );

}