1 !**************************************************************** ! IDENTIFICATION DIVISION. %TITLE "WATCHDOG - Watchdog timer" ! AUTHOR. Thomas Stegman ! INSTALLATION. Federal Land Bank of Wichita. ! DATE-WRITTEN. 08/30/84 ! DATE-COMPILED. 08/31/84 ! VERSION. 1.2 ! DATE-MODIFIED. 06/24/85 ! MODIFICATION-HISTORY. ! ! Date Who Ver. Comments !--------------------------------------------------------------------- ! 08/31/84 T.Stegman 1.1 Original write ! 06/24/85 S.Cowart 1.2 Modify to use logical WATCHDOG_INTERVAL ! instead of hard-coded value in program ! to determine how long terminal may be ! inactive before being logged off. ! ! Changed program to use a different ! variable (SLEEP_INTERVAL) from ! inactive variable (INTERVAL) to ! determine how long to sleep between ! checks for inactive processes. ! ! 07/03/85 S.Cowart 1.3 Corrected problem with operator term ! (OPA0:) being logged off. ! ! 10/18/85 S.Cowart 1.4 Minor corrections to run under VMS V4 ! and fix to prevent blow off when user ! logoff occurs at time that Watchdog ! tries to broadcast logoff message and ! kill process. ! ! 12/18/85 S.Cowart 1.5 Added check for cputime or bufio ! less than or greater than previous ! value. When using EZLOG to change ! project (CP nnnn), the cputime and ! bufio are reset to zero. Watchdog ! was logging people off because of ! the reset values. ! ! 03/03/86 S.Cowart 1.6 Added 1 second pause after sending ! logoff message to terminal and FORCEX ! in order to allow service to complete ! before deleting process. Changed ! system service calls to V4, i.e. ! BRKTHRU instead of BRDCST. Use ! GETJPI process_index for index into ! arrays; if terminal has operator ! status (REPLY/ENABLE has been done ! from that terminal) then User will ! not be logged off. Issue warning ! 5 minutes before user is to be logged ! off. ! ! 04/21/86 S.Cowart 1.7 Changed condition code parameter ! of SYS$FORCEX to SS$_NORMAL to stop ! NOMSG messages from being displayed ! on logged out terminals. ! ! 01/27/87 S.Cowart 1.8 Added check for OPA0:. Whoever is ! logged in at OPA0: will not be logged ! off. Deleted call to LIB$SIGNAL; this ! was causing WATCHDOG to abort with a ! dump. ! ! 03/24/87 S.Cowart 1.9 Do not warn users of TPU or SPSSG of ! impending logoff in 5 minutes. Because ! these two utilities process the ! incoming broadcast messages and stow ! them, it may still be using cpu when ! Watchdog takes another snapshot of the ! process to compare against next time. ! This tends to happen when the system is ! is loaded down and running slow. ! ! 04/13/87 N.Schroeder 1.10 Vary the logout time interval depending ! on the number of users on the system. ! There are three logicals which contain ! the lower, mid, and upper intervals, ! and two logicals which determine the ! break points for the number of users ! on the system. They interact as follows: ! ! WATCHDOG_UPPER_INTERVAL ! ! ! ! --+-- WATCHDOG_UPPER_USERS ! ! ! WATCHDOG_MID_INTERVAL ! ! ! ! --+-- WATCHDOG_LOWER_USERS ! ! ! WATCHDOG_LOWER_INTERVAL ! ! ! 04/15/87 N.Schroeder Remove some test code that had been ! inadvertently left in last time. ! ! COMMENT SECTION. ! ! WATCHDOG is a program to automatically log off user terminals ! at which there is no activity. The time period is set by the ! system logical WATCHDOG_INTERVAL. We are currently using a value ! of "15" (15 minutes) for WATCHDOG_INTERVAL. ! WATCHDOG will sleep for the sleep_interval, then wake up ! and check for processes which have been inactive for ! greater than or equal to the WATCHDOG_INTERVAL. Currently, the ! sleep_interval is 5 minutes. The value of WATCHDOG_INTERVAL is ! retrieved every time WATCHDOG wakes up. If the value of the ! logical has not changed since last time, then validation of the ! the logical string is bypassed and INTERVAL retains its previous ! value. If the string has changed (or it is the first time thru), ! then the string is validated that it is numerics only. If the ! string contains non-numeric characters, or the system logical ! does not exist, then INTERVAL is set to a default inactive value ! (DEFAULT_INTERVAL currently is 15 minutes). If WATCHDOG_INTERVAL ! is set for a period longer than 60 minutes, it will default to ! 60 minutes. ALSO, IF THERE IS AN ERROR WITH TRYING TO RETRIEVE ! THE WATCHDOG_INTERVAL VALUE, THEN AN ERROR MESSAGE WILL DISPLAY ! AT THE OPERATOR CONSOLE EVERY TIME WATCHDOG WAKES UP UNTIL THE ! PROBLEM IS RESOLVED. ! ! WATCHDOG looks at the list of active processes in the system ! and determines which need to be logged off because of inactivity. ! Processes that are NOT associated with a terminal are left alone. ! Sub-processes as well main processes are examined. Information ! on each process is kept in a set of tables in order to compare ! changes in cpu time, buffered I/O, and the length of time that ! the process has been inactive. %page !**************************************************************** ! ENVIRONMENT DIVISION. ! CONFIGURATION SECTION. ! OBJECT-COMPUTER. DEC VAX 11780 ! SOURCE-COMPUTER. DEC VAX 11780 ! LANGUAGE-TYPE. VAX-11 BASIC ! PROGRAM-TYPE. MAIN ! SPECIAL-NAMES. %page !**************************************************************** ! DATA DIVISION. OPTION TYPE = EXPLICIT ! WORKING-STORAGE SECTION. map (jobinfo) word uic_number & ,word uic_group & ,string username = 12% & ,string term = 8% & ,long term_length & ,long cpu_time & ,long buf_io & ,long proc_count & ,long job_proc_count & ,long owner_pid & ,byte pid_index & ,byte pid_seq & ,word pid_cluster_id & ,string process_name = 15% & ,long process_name_length & ,string image_name = 64 & ,long image_name_length & map (jobinfo) long uic & ,string fill = 44 & ,long pid & map (range) long low_addr, & long high_addr & ! set up item list for get process info sys call record item_list word buff_length1 word item_code1 long buff_addr1 long ret_length_addr1 word buff_length2 word item_code2 long buff_addr2 long ret_length_addr2 word buff_length3 word item_code3 long buff_addr3 long ret_length_addr3 word buff_length4 word item_code4 long buff_addr4 long ret_length_addr4 word buff_length5 word item_code5 long buff_addr5 long ret_length_addr5 word buff_length6 word item_code6 long buff_addr6 long ret_length_addr6 word buff_length7 word item_code7 long buff_addr7 long ret_length_addr7 word buff_length8 word item_code8 long buff_addr8 long ret_length_addr8 word buff_length9 word item_code9 long buff_addr9 long ret_length_addr9 word buff_length10 word item_code10 long buff_addr10 long ret_length_addr10 word buff_length11 word item_code11 long buff_addr11 long ret_length_addr11 word buff_length12 word item_code12 long buff_addr12 long ret_length_addr12 long list_terminator end record item_list declare item_list items map (interval_info) string interval_string = 2 & ,string lower_user_string = 2 & ,string upper_user_string = 2 & ,word interval_string_length & ,string old_interval_string = 2 & ,string old_upper_string = 2 & ,string old_lower_string = 2 & ,string interval_logical = 23 & ! set up item list for translate logical sys call record logical_item_list word log_buff_length1 word log_item_code1 long log_buff_addr1 long log_ret_length_addr1 long log_list_terminator end record logical_item_list declare logical_item_list log_items map (brkthru_info) word sendtype & ,long carr_ctrl & ,long brkthru_flags & ,long brkthru_timeout & ,word compl_status & ,word succss_sends & ,word time_outs & ,word nobrdcsts & ! set up item list for getdvi sys call record dvi_item_list word dvi_buff_length1 word dvi_item_code1 long dvi_buff_addr1 long dvi_ret_length_addr1 long dvi_list_terminator end record dvi_item_list declare dvi_item_list dvi_items map (getdvi_info) long oper_term & ,word dvi_iosb1 & ,word dvi_iosb2 & ,word dvi_iosb3 & ,word dvi_iosb4 & external word sys$gw_ijobcnt & external long function sys$getjpiw & ,sys$getdviw & ,sys$brkthruw & ,sys$delprc & ,sys$forcex & ,sys$purgws & ,sys$waitfr & ,lib$stop & ,lib$signal & ,lib$get_ef & ,sys$trnlnm & external long constant & jpi$_username & ,jpi$_uic & ,jpi$_terminal & ,jpi$_cputim & ,jpi$_bufio & ,jpi$_prccnt & ,jpi$_imagname & ,jpi$_jobprccnt & ,jpi$_owner & ,jpi$_pid & ,jpi$_prcnam & ,jpi$_proc_index & ,lnm$_string & ,ss$_nomoreproc & ,ss$_suspended & ,ss$_normal & ,ss$_devoffline & ,dvi$_opr & ,brk$c_device & ,brk$m_screen & ,brk$m_bottom & declare long sys_status & ,sys_status1 & ,context_pid & ,cur_pid & ,process_id_index & ,interval & ,users_on_system & ,lower_user_limit & ,upper_user_limit & ,event_flag & declare word user_ok & ,i & ,j & ,k & ,upper_bound & ,sleep_interval_secs & declare string message & ,exe_image & declare word constant system_is_up = -1% & ,maxuser = 256% & ,true = -1% & ,false = 0% & ,logical_tbl_search_mask = 6% & ,one_hour = 60% & ,sleep_interval_mins = 5% & ,negative_one = -1% & ! System logical for the time interval (WATCHDOG_INTERVAL) and ! default interval if problem with retrieving WATCHDOG_INTERVAL value. declare string constant upper_interval = "WATCHDOG_UPPER_INTERVAL" & ,mid_interval = "WATCHDOG_MID_INTERVAL" & ,lower_interval = "WATCHDOG_LOWER_INTERVAL" & ,upper_users = "WATCHDOG_UPPER_USERS" & ,lower_users = "WATCHDOG_LOWER_USERS" & ,digits = "0123456789" & ,default_interval = "15" & ,operator_terminal = "OPA0:" & ,system_logical_table = "LNM$SYSTEM" & ,right_bracket = "]" & ,semi_colon = ";" & dimension long cputim(maxuser),bufio(maxuser),seq(maxuser), & inactiv(maxuser),uicsave(maxuser) & dimension byte warning_flag(maxuser) %page !**************************************************************** ! PROCEDURE DIVISION. 100 P_100_Program_Initialization: on error goto error_routine ! Init record block for call to get user process information items::buff_length1 = 12 items::item_code1 = jpi$_username items::buff_addr1 = loc(username) items::buff_length2 = 4 items::item_code2 = jpi$_uic items::buff_addr2 = loc(uic_number) items::buff_length3 = 8 items::item_code3 = jpi$_terminal items::buff_addr3 = loc(term) items::ret_length_addr3 = loc(term_length) items::buff_length4 = 4 items::item_code4 = jpi$_cputim items::buff_addr4 = loc(cpu_time) items::buff_length5 = 4 items::item_code5 = jpi$_bufio items::buff_addr5 = loc(buf_io) items::buff_length6 = 4 items::item_code6 = jpi$_prccnt items::buff_addr6 = loc(proc_count) items::buff_length7 = 4 items::item_code7 = jpi$_jobprccnt items::buff_addr7 = loc(job_proc_count) items::buff_length8 = 4 items::item_code8 = jpi$_owner items::buff_addr8 = loc(owner_pid) items::buff_length9 = 4 items::item_code9 = jpi$_pid items::buff_addr9 = loc(pid_index) items::buff_length10 = 15 items::item_code10 = jpi$_prcnam items::buff_addr10 = loc(process_name) items::ret_length_addr10 = loc(process_name_length) items::buff_length11 = 64 items::item_code11 = jpi$_imagname items::buff_addr11 = loc(image_name) items::ret_length_addr11 = loc(image_name_length) items::buff_length12 = 4 items::item_code12 = jpi$_proc_index items::buff_addr12 = loc(process_id_index) items::list_terminator = 0% log_items::log_buff_length1 = 2% log_items::log_item_code1 = lnm$_string log_items::log_buff_addr1 = loc(interval_string) log_items::log_ret_length_addr1 = loc(interval_string_length) log_items::log_list_terminator = 0% sys_status = lib$get_ef(event_flag) sendtype = brk$c_device brkthru_flags = brk$m_screen or brk$m_bottom carr_ctrl = 32% brkthru_timeout = 5% dvi_items::dvi_buff_length1 = 4% dvi_items::dvi_item_code1 = dvi$_opr dvi_items::dvi_buff_addr1 = loc(oper_term) dvi_items::dvi_list_terminator = 0% old_interval_string = "99" ! Convert sleep interval minutes to equivalent seconds sleep_interval_secs = sleep_interval_mins * 60 if sys_status and 1% = 0% then goto P_32760_Error_exit end if gosub P_900_Get_Users_and_Intervals ! Obtain current logical values high_addr = X"7FFFFFFF"L 200 P_200_Main_Program_logic: sys_status = sys$purgws(low_addr) if sys_status and 1% = 0% then goto P_32760_Error_exit end if while system_is_up context_pid = -1% cur_pid = -1% sys_status = ss$_normal Step_thru_processes: until sys_status = ss$_nomoreproc user_ok = false ! Get user process information cur_pid = context_pid gosub P_1100_Get_user_info context_pid = cur_pid iterate if sys_status = ss$_nomoreproc or & sys_status = ss$_suspended ! If this guy owns a subprocess we will leave him alone ! for now and check him when we check the subprocess. iterate if proc_count > 0 gosub p_1000_check_user_status iterate if user_ok ! If there is a terminal attached that has received ! the 5 minute warning, then we have a main ! process that needs to be deleted. if term_length > 0 then gosub P_1200_Delete_user iterate end if ! This is a subprocess, so we must check all other ! processes in the job; begin by checking this guy's ! owner process. until term_length > 0 cur_pid = owner_pid user_ok = false gosub P_1100_Get_user_info gosub P_1000_Check_user_status iterate Step_thru_processes if user_ok next gosub P_1200_Delete_user iterate ! Get next user info next ! Sleep_interval_secs is number of seconds between sweeps ! for inactive processes sleep (sleep_interval_secs) gosub P_900_Get_Users_and_Intervals ! See if anything changed next 900 P_900_Get_Users_and_Intervals: ! Check WATCHDOG_UPPER_USERS and WATCHDOG_LOWER_USERS to see if they ! have changed. If so, validate them. Then see how many users are on ! the system to determine if the interval should be in the upper, mid, ! or lower range. Then check that logical to see if it has changed. ! If so, validate it. The result is the new current time interval. gosub P_2100_get_upper_users gosub P_2200_get_lower_users users_on_system = sys$gw_ijobcnt interval_logical = mid_interval interval_logical = lower_interval if users_on_system < lower_user_limit interval_logical = upper_interval if users_on_system > upper_user_limit gosub P_2300_get_interval return 1000 P_1000_Check_user_status: ! If the sequence number changed, then this is a new user ! with this pid, so leave him alone. if seq(process_id_index) <> pid_seq then seq(process_id_index) = pid_seq ! Save sequence number warning_flag(process_id_index) = 0 ! Clear warning flag ! Save number of minutes till next check by watchdog inactiv(process_id_index) = sleep_interval_mins gosub P_1300_Save_user_info warning_flag(process_id_index) = 0 user_ok = true return end if ! If this process has no terminal and no owner process, ! then it must be detached so leave it alone. if term_length = 0 and owner_pid = 0 then warning_flag(process_id_index) = 0 user_ok = true return end if ! If this process is logged in at OPA0: then leave alone. if term = operator_terminal then warning_flag(process_id_index) = 0 user_ok = true return end if oper_term = 0% if term_length > 0% then sys_status = sys$getdviw(,,term,dvi_items by ref, & dvi_iosb1 by ref,,,) if sys_status <> ss$_normal then warning_flag(process_id_index) = 0 user_ok = true return end if sys_status = ss$_normal end if ! An operator terminal is immune from Watchdog logout. if oper_term = 1% then warning_flag(process_id_index) = 0 user_ok = true return end if ! If process is running an image then found out image name if image_name_length <> 0% then ! Extract image name and place in exe_image variable exe_image = seg$(image_name,1%,image_name_length) ! Set j to length of image name in exe_image j = len(exe_image) ! Start from the end of the string and go towards the beginning ! looking for a right bracket ("]") for k = j step negative_one until pos(exe_image,right_bracket,k) > 0% next k ! Extract image name starting from the next position to the ! right of the rightmost "]" in exe_image and reassign to ! exe_image. This will strip off device and directory name ! parts of the image name (since it is a VAX standard file ! specification. exe_image = seg$(exe_image,k+1%,len(exe_image)) ! Reset j to new length of image name j = len(exe_image) if pos(exe_image,semi_colon,1%) > 0% then ! Now start from the end as above and look for the rightmost ! semi-colon in the image name. When it is found then drop the ! version number part of the image file name leaving the ! file name and extension parts. for k = j step negative_one until pos(exe_image,semi_colon,k) > 0% next k exe_image = seg$(exe_image,1%,k-1%) end if end if ! If the cpu time has increased by at least 50 ms or ! any buffered i/o has occurred or if cpu time or bufio ! is less than previous or uic has changed, (EZLOG CP function ! entered) then leave him alone. if cpu_time => cputim(process_id_index) + 5 or & buf_io > bufio(process_id_index) or & cpu_time < cputim(process_id_index) or & buf_io < bufio(process_id_index) or & uic <> uicsave(process_id_index) then gosub P_1300_Save_user_info warning_flag(process_id_index) = 0 inactiv(process_id_index) = sleep_interval_mins user_ok = true else ! If accum inactive time is less than the ! WATCHDOG_INTERVAL value, then add the ! sleep_interval_mins to the inactive accum for the ! process if warning_flag(process_id_index) = 0 then inactiv(process_id_index) = & inactiv(process_id_index) & + sleep_interval_mins if inactiv(process_id_index) >= interval then ! Send warning message to user and set warning flag warning_flag(process_id_index) = 1 if exe_image <> "TPU.EXE" and exe_image <> "SPSSGRAPHICS.EXE" then message = time$(0) + " " + username + " will be logged off in " & + num1$(sleep_interval_mins) + " minutes because of inactivity."+ BEL + BEL sys_status = sys$brkthruw(,message, & term,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = ss$_normal ! Retrieve current process values, since sending the warning message increments BUFIO. ! Obtain the job information of the process. sys_status = sys$getjpiw(event_flag by value, pid,, items,,,) sys_status = ss$_normal gosub P_1300_Save_user_info end if end if user_ok = true end if end if return 1100 P_1100_Get_user_info: ! Obtain the job information of the process. sys_status = sys$getjpiw(event_flag by value, cur_pid,, items,,,) if (sys_status and 1%) = 0% and sys_status <> ss$_nomoreproc & and sys_status <> ss$_suspended then goto P_32760_Error_exit end if return if sys_status = ss$_nomoreproc or sys_status = ss$_suspended if sys_status and 1% = 0% then goto P_32760_Error_exit end if ! This is to add a colon to Virtual terminals (VTAnnn) which have ! gone over VTA999. VMS V4.1 has a bug which drops the colon on ! virtual terminal numbers over VTA999. if pos(term,":",1%) = 0% and term_length > 0 then term = seg$(term,1%,term_length) + ":" term_length = term_length + 1% else ! This is to pad the terminal name with blanks. term = seg$(term,1%,term_length) end if return 1200 P_1200_Delete_user: ! Send logoff message to user message = time$(0) + " " + term + " inactive for " + & num1$(interval) + " minutes - " + username + " logged out." + BEL sys_status = sys$brkthruw(,message, & term,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sleep 1% sys_status = 0 if image_name_length > 0 then sys_status = sys$forcex(pid,,ss$_normal by value) sleep 1% sys_status = 0 end if sys_status = sys$delprc(pid,) sys_status = 0 return 1300 P_1300_Save_user_info: ! Save cpu time and buffered i/o on this user cputim(process_id_index) = cpu_time bufio(process_id_index) = buf_io uicsave(process_id_index) = uic return 2100 P_2100_get_upper_users: sys_status = sys$trnlnm(,system_logical_table,upper_users,,log_items) upper_user_string = interval_string select (sys_status) case (ss$_normal) ! If previous string value = current string value then ! no validation is necessary. if upper_user_string <> old_upper_string then ! Validate that string is only numeric characters, no ! spaces, special, or alpha chars. If any problems with ! string, assign in a default string value. upper_bound = interval_string_length for i = 1% to upper_bound if pos(digits,seg$(upper_user_string,i,i),1%) = 0% then i = upper_bound + 1% upper_user_string = "99" message = BEL + BEL + time$(0) + & "*** WATCHDOG_UPPER_USERS" & + " logcl has non-nums." + & " Deflting to 99 users." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end if next i end if old_upper_string = upper_user_string & if upper_user_string <> "99" upper_user_limit = val%(seg$(upper_user_string,1%, & interval_string_length)) ! If not normal return from logical translation, ! then use default interval value case else upper_user_limit = 99 message = BEL + BEL + time$(0) + & "*** WATCHDOG_UPPER_USERS" & + " logcl transl err. " + & "Deflting to 99 users." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end select return 2200 P_2200_get_lower_users: sys_status = sys$trnlnm(,system_logical_table,lower_users,,log_items) lower_user_string = interval_string select (sys_status) case (ss$_normal) ! If previous string value = current string value then ! no validation is necessary. if lower_user_string <> old_lower_string then ! Validate that string is only numeric characters, no ! spaces, special, or alpha chars. If any problems with ! string, assign in a default string value. upper_bound = interval_string_length for i = 1% to upper_bound if pos(digits,seg$(lower_user_string,i,i),1%) = 0% then i = upper_bound + 1% lower_user_string = "00" message = BEL + BEL + time$(0) + & "*** WATCHDOG_LOWER_USERS" & + " logcl has non-nums." + & " Deflting to 0 users." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end if next i end if old_lower_string = lower_user_string & if lower_user_string <> "00" lower_user_limit = val%(seg$(lower_user_string,1%, & interval_string_length)) ! If not normal return from logical translation, ! then use default interval value case else lower_user_limit = 0 message = BEL + BEL + time$(0) + & "*** WATCHDOG_LOWER_USERS" & + " logcl transl err. " + & "Deflting to 0 users." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end select return 2300 P_2300_get_interval: sys_status = sys$trnlnm(,system_logical_table, & interval_logical,,log_items) select (sys_status) case (ss$_normal) ! If previous string value = current string value then ! no validation is necessary. if interval_string <> old_interval_string then ! Validate that string is only ! numeric characters, no spaces, special, or alpha chars ! If any problems with string, assign in a default ! string value for the interval. upper_bound = interval_string_length for i = 1% to upper_bound if pos(digits,seg$(interval_string,i,i),1%) = 0% then i = upper_bound + 1% interval_string = default_interval message = BEL + BEL + time$(0) + & "*** WATCHDOG_INTERVAL" & + " logcl has non-nums." + & " Deflting to " + default_interval + & " min intvl." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end if next i ! Interval value cannot be set to more than 60 minutes interval = val%(seg$(interval_string,1%, & interval_string_length)) if interval > one_hour then interval = one_hour message = BEL + BEL + time$(0) + & "*** Watchdog " & + "intvl set to max of " & + num1$(interval) + " mins." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end if old_interval_string = interval_string end if ! If not normal return from logical translation, ! then use default interval value case else interval = val%(default_interval) message = BEL + BEL + time$(0) + & "*** WATCHDOG_INTERVAL" & + " logcl transl err. " + & "Deflting to " + default_interval + " min " + & "intvl." sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 end select return 31000 Error_routine: ! Unrecoverable error - print error and message and exit message = BEL + BEL + time$(0) + & "*** Watchdog has crashed - BASIC Error # " + num1$(err) & + "at line " + num1$(erl) sys_status = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status = 0 %page 32760 %sbttl "Module end" P_32760_Error_exit: message = time$(0) + "Watchdog sys_status error " + & "Process=" + process_name + ";termid=" + term sys_status1 = sys$brkthruw(,message, & operator_terminal,sendtype by value, & compl_status by ref,carr_ctrl by value, & brkthru_flags by value,, & brkthru_timeout by value,,) sys_status1 = lib$stop(sys_status by value) 32767 end