/*------------------------- New Concepts Consulting ---------------------------- - Application Module Name : OS/2 - File Name : nas_check.cmd - Date : October 26, 2020 - Author : Dariusz Piatkowski - - Description: - This script implements a quick check to see if the TARGET folder is accessible - through a NetDrive plug-in. Such remote folder is usually mapped to a local - drive letter. If teh TARGET folder is NOT accessible the NetDrive control EXE - will be killed and a new session will be started. - - There is a single mode of execution: - 1) TARGET folders can be any location, LOCAL or a NETWORK drive, however if - it is a NETWORK drive it must be mapped to the local filesystem as a drive, - for example through a NetDrive mapping - - Parameters: - Usage => NAS_CHECK "TARGET" - - Modification History - - REVISON DATE/TIME AUTHOR - - Rev 1.0.0 JUN 06, 2020 Dariusz Piatkowski - First version of the code. - - Rev 1.0.1 DEC 18, 2020 Dariusz Piatkowski - Re-wrote the LIBRARY load and un-load code. Now instead of checking the - load status and loading ALL REXX DLLs only the script applicable DLLs are - being handled. - ------------------------------------------------------------------------------*/ main: /* setup the GLOBAL variables */ debug_flag =1 calling_code ='MAIN' msg_level =0 msg_text ='Initializing...' crlf ='0D0A'x /* carriage return / line feed */ target_folder ="" /* TARGET folder */ target_folder_ok ="NO" /* TARGET path verify flag */ module_path ="G:\UTIL\NDFS\" /* PATH to the module_name */ module_name ="NDCTL.EXE" /* name of the EXE file to check */ wps_util_path ="G:\UTIL\MISC\" /* PATH to WPS settings util */ wps_util ="NAS_SETUP.EXE" /* WPS settings util */ app_name ="NAS_CHECK" /* name of this application */ /* define the REXX library load required flags */ rxutilex_api_required =1 /* RxUtilEx */ rexxutil_api_required =0 /* RexxUtil */ rxu_api_required =1 /* RXU */ rxextras_api_required =0 /* RxExtras */ rxlvm_api_required =0 /* RxLVM */ /* define the REXX library load status flags */ rxutilex_api =0 /* RxUtilEx */ rexxutil_api =0 /* RexxUtil */ rxu_api =0 /* RXU */ rxextras_api =0 /* RxExtras */ rxlvm_api =0 /* RxLVM */ /* setup the logging variables */ log_file_path ='G:\tmp\log\' /* location of the LOG file */ log_file_name ='nas_check.log' /* LOG file */ /* pull in the CLI params */ PARSE ARG cli_arg CALL debug debug_flag calling_code msg_level msg_text /* check what REXX libraries to load */ CALL library_load /* get the LOG file details */ nas_check_log = log_file_path||log_file_name /* update the LOG file with a NEW run marker */ msg_text=crlf||"======================================================"||, "=========================" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* get the START message built */ datetime_stamp = date('U')||" - "||time('N') msg_text = app_name||" started: "||datetime_stamp||"..."||crlf CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text msg_text="CLI input params : >"||cli_arg||"<" CALL debug debug_flag calling_code msg_level msg_text /* parse the CLI params to pick up the TARGET info */ CALL cli_parm_parse(cli_arg) msg_text ="Starting NAS remote folder check for: "||target_folder||crlf||, "Utilizing NetDrive control program: "||module_name CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* check to see if we have all the required input params */ IF (target_folder = '') THEN DO msg_text=crlf||"ERROR => Missing TARGET_FOLDER location!" CALL log debug_flag calling_code msg_level msg_text msg_text=crlf||"USAGE => "||app_name||" TARGET_FOLDER" CALL log debug_flag calling_code msg_level msg_text /* final step, check if we should un-load the REXX library DLL */ CALL library_unload RETURN END ELSE DO /* since the INPUT param is not NULL verify that folder can be accessed */ CALL verify_folders msg_text="target_folder_ok flag = "||target_folder_ok CALL debug debug_flag calling_code msg_level msg_text /* force FAIL here */ target_folder_ok="NO" /* check the results and post appropriate message if problems found */ IF target_folder_ok <> "YES" THEN DO /* ran into a problem accessing the TARGET folder */ msg_text=crlf||"TARGET folder is NOT accessible!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END ELSE DO /* folder found, no problem we are GOOD */ msg_text=crlf||"TARGET folder is accessible!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END /* if target folder NOT reachable go ahead and re-set NetDrive daemon */ IF (target_folder_ok <> "YES") THEN DO msg_text=crlf||"Starting the NetDrive daemon re-set..." CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* check the process info */ api_rc=Sys2QueryProcess(module_name) msg_text=module_name||" process info: "||api_rc CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* is the EXE running to start off with? */ IF api_rc="" THEN DO msg_text="The EXE is NOT running, there is nothing to KILL!!!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* set api_rc=1 so that downstream re-start check can use it */ api_rc=1 END ELSE DO /* go ahead and KILL the executable */ api_rc=Sys2KillProcess(module_name) msg_text="Sys2KillProcess RC: "||api_rc CALL debug debug_flag calling_code msg_level msg_text /* we successfully killed the process */ msg_text=crlf||module_name||" has been KILLED!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END /* if previous checks passed, go ahead and re-start the process */ IF (api_rc<>0) THEN DO api_rc=RxStartSession(module_path||module_name,,'I','B',,'O','N') msg_text="RxStartSession RC: "||api_rc CALL debug debug_flag calling_code msg_level msg_text IF (api_rc<>"0 0 0") THEN DO /* problem re-starting the daemon */ msg_text=crlf||module_name||" re-start has FAILED!"||crlf||, "API RC is: "||api_rc CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END ELSE DO /* re-start completed successfully */ msg_text=crlf||module_name||" re-start has completed SUCCESSFULLY!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text /* OK, now run the WPS settings utility */ api_rc=0 /*api_rc=RxStartSession('g:\util\misc\oo-debug.exe','/a v:\photo "DEFAULTVIEW=XVIEW;"','C','F',,'O','A')*/ api_rc=RxStartSession('oo.exe','/a v:\photo "DEFAULTVIEW=XVIEW;"',,,,,'A') /*rcx = RxStartSession( 'oo.exe', '/a F:\Apps\NEPMD\myepm\macros "OPEN=DEFAULT;"')*/ /* api_rc=RxExecPgm(wps_util_path||wps_util,'B') */ /* set the folder default VIEW */ /* api_rc=SysSetObjectData('v:\photo','DEFAULTVIEW=DETAILS') */ IF (api_rc<>"0 0 0") THEN DO /* problem running the WPS settings script */ msg_text=crlf||wps_util_path||wps_util||" WPS settings script has FAILED!"||crlf||, "API RC is: "||api_rc CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END ELSE DO /* re-start completed successfully */ msg_text=crlf||wps_util||" re-start has completed SUCCESSFULLY!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END END END ELSE DO /* we failed to kill the process, TERMINATE the code */ msg_text="Failed to KILL and Re-Start the NetDrive daemon...ERROR!" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text END END /* get the FINISH message built */ datetime_stamp = date('U')||" - "||time('N') msg_text = crlf||app_name||" completed: "||datetime_stamp||"..." CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text msg_text=crlf||app_name||" took "||time('e')||" seconds to complete the "||, backup_type||" backup task!" CALL lineout rsync_log_file,msg_text CALL log debug_flag calling_code msg_level msg_text /* put a final message in the LOG file */ msg_text="============================================================"||, "===================" CALL lineout nas_check_log,msg_text CALL log debug_flag calling_code msg_level msg_text CALL lineout nas_check_log /* final step, check if we should un-load the REXX library DLLs */ CALL library_unload /* put a final COMPLETED msg into the DEBUG log */ msg_text=crlf||"Execution COMPLETED!"||crlf CALL log debug_flag calling_code msg_level msg_text EXIT 0 /* MAIN end */ /* load the REXX DLL based libraries */ library_load: procedure expose debug_flag msg_level crlf rxutilex_api rxu_api, rexxutil_api rxextras_api rxlvm_api, rxutilex_api_required rxu_api_required, rexxutil_api_required rxextras_api_required, rxlvm_api_required /* setup the variables */ calling_code ='library_load' msg_level =msg_level+1 msg_text ='Initializing...' /* put a proc ENTRY into DEBUG */ CALL debug debug_flag calling_code msg_level msg_text /* check ifthe RXU - RXU.DLL - is required */ IF rxu_api_required = 1 THEN DO /* check if the DLL is already loaded */ rxu_api = RxFuncQuery('rxuinit') msg_text="RXU: already in memory, RC="||rxu_api IF rxu_api <> 0 THEN DO CALL RxFuncAdd 'rxuinit','RXU','rxuinit' CALL rxuinit msg_text="RXU: loaded into memory, RC="||rxu_api END CALL debug debug_flag calling_code msg_level msg_text /* RXU version API returns a WHOLE bunch of stuff, so parse it first */ rxu_api_info=rxuquery() msg_text=substr(rxu_api_info,pos(',',rxu_api_info,1)+2,pos(',',rxu_api_info,1)) msg_text="RXU: Using version "||msg_text CALL debug debug_flag calling_code msg_level msg_text END /* check if the RXUTIL - REXXUTIL.DLL - is required */ IF rexxutil_api_required = 1 THEN DO /* check if the DLL is already loaded */ rexxutil_api = RxFuncQuery('SysLoadFuncs') msg_text="REXXUTIL: already in memory, RC="||rexxutil_api IF rexxutil_api <> 0 THEN DO CALL RxFuncAdd 'SysLoadFuncs','REXXUTIL','SysLoadFuncs' CALL SysLoadFuncs msg_text="REXUTIL: loaded into memory, RC="||rexxutil_api END CALL debug debug_flag calling_code msg_level msg_text msg_text="REXXUTIL: Using version "||SysUtilVersion() CALL debug debug_flag calling_code msg_level msg_text END /* check if the RxExtra - RXUTILEX.DLL - is required */ IF rxutilex_api_required = 1 THEN DO /* check if the DLL is already in memory */ rxutilex_api = RxFuncQuery('Sys2LoadFuncs') msg_text="RXUTILEX: already in memory, RC="||rxutilex_api IF rxutilex_api <> 0 THEN DO CALL RxFuncAdd 'Sys2LoadFuncs', 'RXUTILEX', 'Sys2LoadFuncs' CALL Sys2LoadFuncs msg_text="RXUTILEX: loaded into memory, RC="||rxutilex_api END CALL debug debug_flag calling_code msg_level msg_text msg_text = "RXUTILEX: Using version "||Sys2Version() CALL debug debug_flag calling_code msg_level msg_text END /* check if the RxExtra - RXEXTRAS.DLL - is required */ IF rxextras_api_required = 1 THEN DO /* check if the RxExtra - RXEXTRAS.DLL - is already in memory */ rxextras_api = RxFuncQuery('RxExtra') msg_text="RXEXTRAS: already in memory, RC="||rxextras_api IF rxextras_api <> 0 THEN DO CALL RxFuncAdd 'RxExtra', 'RXEXTRAS', 'RxExtra' CALL RxExtra 'Load' msg_text="RXEXTRAS: loaded into memory, RC="||rxextras_api END CALL debug debug_flag calling_code msg_level msg_text msg_text = "RXEXTRAS: Using version "||RxExtra("Load") CALL debug debug_flag calling_code msg_level msg_text END /* check if the RxLvm - RXLVM.DLL - is required */ IF rxlvm_api_required = 1 THEN DO /* check if the DLL is already in memory */ rxlvm_api = RxFuncQuery('RxLvmLoadFuncs') msg_text="RXLVM: already in memory, RC="||rxlvm_api IF rxlvm_api <> 0 THEN DO CALL RxFuncAdd 'RxLvmLoadFuncs', 'RXLVM', 'RxLvmLoadFuncs' CALL RxLvmLoadFuncs msg_text="RXLVM: loaded into memory, RC="||rxlvm_api END CALL debug debug_flag calling_code msg_level msg_text /*msg_text = "RXLVM: Using version "||RxLvmVersion()*/ CALL debug debug_flag calling_code msg_level msg_text END /* put a proc EXIT into DEBUG */ msg_text='Exiting...' CALL debug debug_flag calling_code msg_level msg_text /* reset DEBUG LEVEL tracker */ msg_level=msg_level-1 RETURN 0 /* library_load END */ /* unload the previously loaded REXX DLL based libraries */ library_unload: PROCEDURE expose debug_flag msg_level crlf rxutilex_api rxu_api, rexxutil_api rxextras_api rxlvm_api, rxutilex_api_required rxu_api_required, rexxutil_api_required rxextras_api_required, rxlvm_api_required /* setup the variables */ calling_code ='library_unload' msg_level =msg_level+1 msg_text ='Initializing...' /* put a proc ENTRY into DEBUG */ CALL debug debug_flag calling_code msg_level msg_text /* check if the RXU library is required */ IF rxu_api_required = 1 THEN DO /* check if the library un-load is required */ msg_text="RXU: Un-load not required" IF rxu_api <> 0 THEN DO CALL RxuTerm msg_text="RXU: Un-loaded successfully, RC="||rc END CALL debug debug_flag calling_code msg_level msg_text END /* check if the REXXUTIL library is required */ IF rexxutil_api_required = 1 THEN DO /* check if the library un-load is required */ msg_text="REXXUTIL: Un-load not required" IF rexxutil_api <> 0 THEN DO CALL SysDropFuncs msg_text="REXXUTIL: Un-loaded successfully, RC="||rc END CALL debug debug_flag calling_code msg_level msg_text END /* check if the RXUTILEX library is required */ IF rxutilex_api_required = 1 THEN DO /* check if the library un-load is required */ msg_text="RXUTILEX: Un-load not required" IF rxutilex_api <> 0 THEN DO CALL Sys2DropFuncs msg_text="RXUTILEX: Un-loaded successfully, RC="||rc END CALL debug debug_flag calling_code msg_level msg_text END /* check if the RXEXTRAS library is required */ IF rxextras_api_required = 1 THEN DO /* check if the library un-load is required */ msg_text="RXEXTRAS: Un-load not required" IF rxextras_api <> 0 THEN DO CALL RxExtra 'Drop' msg_text="RXEXTRAS: Un-loaded successfully, RC="||rc END CALL debug debug_flag calling_code msg_level msg_text END /* check if the RXLVM library is required */ IF rxlvm_api_required = 1 THEN DO /*rxlvm_api=1 */ /* check if the library un-load is required */ msg_text="RXLVM: Un-load not required" IF rxlvm_api <> 0 THEN DO CALL RxLvmDropFuncs msg_text="RXLVM: Un-loaded successfully, RC="||rc END CALL debug debug_flag calling_code msg_level msg_text END /* put a proc EXIT into DEBUG */ msg_text='Exiting...' CALL debug debug_flag calling_code msg_level msg_text /* reset DEBUG LEVEL tracker */ msg_level=msg_level-1 RETURN 0 /* library_unload END */ /* subroutine to verify the TARGET path */ verify_folders: PROCEDURE expose debug_flag msg_level target_folder, crlf target_folder_ok /* setup the variables */ calling_code ='verify_paths' msg_level =msg_level+1 msg_text ='Initializing...' /* put a proc ENTRY into DEBUG */ CALL debug debug_flag calling_code msg_level msg_text /* call SysFileTree from RexxUtil library to check the valid TARGET path */ msg_text="Validating the TARGET folder path : "||target_folder CALL debug debug_flag calling_code msg_level msg_text CALL SysFileTree target_folder, 'found1.', 'DO' msg_text="Found "||found1.0||" instances of this folder" CALL debug debug_flag calling_code msg_level msg_text DO i = 1 TO found1.0 msg_text="Found TARGET path : "||found1.i CALL debug debug_flag calling_code msg_level msg_text /* set the flag accordingly */ target_folder_ok="YES" END /* put a proc EXIT into DEBUG */ msg_text='Exiting...' CALL debug debug_flag calling_code msg_level msg_text /* reset DEBUG LEVEL tracker */ msg_level=msg_level-1 RETURN 0 /* verify_paths END */ /* subroutine to handle the command line parameter values */ cli_parm_parse: PROCEDURE expose debug_flag msg_level backup_type, target_folder crlf /* Parse multiple args optionally enclosed in double quotes */ PARSE ARG Args Args = STRIP( Args) /* setup the variables */ calling_code ='cli_parm_parse' msg_level =msg_level+1 msg_text ='Initializing...' /* put a proc ENTRY into DEBUG */ CALL debug debug_flag calling_code msg_level msg_text msg_text="CLI input params : " CALL debug debug_flag calling_code msg_level msg_text||Args /* Init vars */ ARG. = '' ARG.0 = 0 Rest = Args /* DEBUG data */ msg_text="CLI params length = " length(Args) CALL debug debug_flag calling_code msg_level msg_text /* Parse Rest */ DO WHILE Rest <> '' /* Advance arg counter */ NumArgs = ARG.0 + 1 msg_text=NumArgs': Rest = ['Rest']' call debug debug_flag calling_code msg_level msg_text /* Parse Next from Rest */ IF LEFT( Rest, 1) = '"' THEN PARSE VAR Rest '"'Next'"' Rest ELSE PARSE VAR Rest Next Rest msg_text=NumArgs': Next = ['Next']' CALL debug debug_flag calling_code msg_level msg_text /* Strip multiple spaces between args */ Rest = STRIP( Rest) /* Save Next to Arg. array */ ARG.NumArgs = Next ARG.0 = NumArgs END /* Test Arg. array */ DO i = 1 TO ARG.0 msg_text='Arg.'i' = 'ARG.i CALL debug debug_flag calling_code msg_level msg_text END /* assign the results to the MAIN program variables */ target_folder = ARG.1 /* put a proc EXIT into DEBUG */ msg_text='Exiting...' CALL debug debug_flag calling_code msg_level msg_text /* reset DEBUG LEVEL tracker */ msg_level=msg_level-1 RETURN 0 /* cli_parm_parse END */ /* subroutine to encapsulate the string with single quotes */ Enquote: rc = 0 PARSE ARG Filename IF VERIFY( Filename, ' &|<>', 'M') <> 0 THEN /* Filename = "'"Filename"'" */ Filename = '"'Filename'"' RETURN( Filename) /* Enquote END */ /* subroutine to show DEBUG messages */ debug: PROCEDURE PARSE ARG debug_flag calling_code msg_level msg_text /* get my own msg_level variable for indentation loop */ msg_level_cntr = msg_level /* check if DEBUG=ON */ IF (debug_flag=1) THEN DO /* reset variables */ msg_indent='DEBUG : ' /* for each msg_level unit indent accordingly */ DO WHILE msg_level_cntr <> 0 msg_indent = msg_indent||' ==> ' msg_level_cntr = msg_level_cntr-1 END SAY msg_indent||calling_code||' => '||msg_text END RETURN 0 /* debug END */ /* subroutine to show LOG messages */ log: PROCEDURE PARSE ARG debug_flag calling_code msg_level msg_text /* check to see if DEBUG=ON, if so , run through DEBUG routine */ IF (debug_flag) THEN CALL debug debug_flag calling_code msg_level msg_text ELSE SAY msg_text RETURN 0 /* log END */