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 ); }
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 ); }