.TITLE BREAK - detects and deletes detached LOGINOUT processes .ENABLE DEBUG .IDENT /01/ ; +++ ; ; FUNCTIONAL DESCRIPTION: ; This program scans through the current processes on ; a system looking for any that are (1) disconnected ; and (2) running LOGINOUT. These processes are then ; deleted. ; ; IMPLICIT INPUTS: ; $GETJPI data from system image ; ; IMPLICIT OUTPUTS: ; none ; ; COMPLETION STATUS: ; ; SS$_NORMAL Normal Successful completion ; (others are possible in error conditions) ; ; SIDE EFFECTS: ; Deletes processes. ; ; ; AUTHOR, DATE;TIME of CREATION ; Joel M Snyder, 15-May-1985 ; ; ; --- .PAGE ; +++ ; FURTHER INFORMATION ; ; This program was written in response to a problem generated ; by VAX/VMS V4.0 "disconnectable" terminals. Any disconnectable ; terminal will generate up to MAXPROCNT jobs, disconnected, ; and running LOGINOUT, if someone presses the BREAK key enough ; times. While user education will help this problem, this program ; provides a means of self-defence for VAX systems seeing this ; behavior. ; ; To use, put a $ RUN/DETACH/PRIV=WORLD BREAK in your SYSTARTUP.COM. ; .page ; system call macros $JPIDEF $DVIDEF ; some miscellaneous constants PHYSICAL_DEVICE_LENGTH = 64 ; maximum size of a device WILDCARD = -1 ; wildcard $GETJPI starter IMAGE_LENGTH = 80 ; length of an image name TERMINAL_LENGTH=8 ; size of a VTA term name PID_LENGTH = 4 ; size of a PID in bytes .PAGE ; impure storage locations .PSECT RWDATA,WRT,NOEXE,NOSHR,LONG PID: .long 0 ; context for $GETJPI ;+++ $GETDVI LIST dvilist:.word PHYSICAL_DEVICE_LENGTH ; get the physical .word dvi$_tt_phydevnam ; device for a VTA device .address ptty .address ptty_len ; .long 0 ; END OF $GETDVI list ;--- END $GETDVI LIST ;+++ $GETJPI LIST list: .word IMAGE_LENGTH ; currently running .word jpi$_imagname ; image for this process .address image ; pointer to data .address image_len ; length of image name ; .word TERMINAL_LENGTH ; terminal name for this .word jpi$_terminal ; process, expressed as .address tty ; a VTAxxx string normally. .address tty_len ; pointer and length ; .word PID_LENGTH ; PID for this process, .word jpi$_pid ; expressed as a longword .address rpid ; integer .address rpid_len ; pointer and length ; .long 0 ; end of list. ;--- END $GETJPI LIST ; The following information is order specific. Do not ; change the order of items in this data structure. image_len: .long 0 ; length of image name image_ptr: .address image ; pointer to image name image: .blkb IMAGE_LENGTH ; bytes for image name logimage_cnt: .word 8 ; size of word "LOGINOUT" logimage: .ascii 'LOGINOUT' ; string to MATCHC on. tty_len: .long 0 ; length of VT tty_ptr: .address tty ; pointer to terminal name tty: .blkb TERMINAL_LENGTH ; bytes for terminal name rpid: .blkb PID_LENGTH ; real pid rpid_len: .long 0 ; and length ptty: .blkb PHYSICAL_DEVICE_LENGTH ; bytes for physical dev ptty_len: .blkl 1 ; and length timetowait: .ascid /0 00:01:00.00/ ; time to wait binarytime: .blkq 1 ; between scans. .PAGE ; ; Executable Code ; .PSECT CODE,EXE,RD,NOWRT ; .entry break,^M ;+++ ; initialize the $GETJPI by moving a -1 into the PID value ; that is used for calling. ;--- init: movl #WILDCARD,PID ; init $GETJPI entry mask ;+++ ; do the $GETJPI (waiting, as is appropriate in V4). See if there ; are no more processes. If no more available, then goto the wait ; loop. If there is any other error, then quit (exiting R0). ; Assuming that there is a process and there is no error, find ; if the length of the tty is 0. If the TTY length is zero, then ; this process doesn't have an associated terminal and thus is ; not a candidate for deleting (ex, NULL, JOB_CONTROL, etc). ;--- get: $getjpiw_s pidadr=pid,- ; PID itmlst=list ; get data from $GETJPI cmpw r0,#SS$_NOMOREPROC ; if no more processes, beql wait ; then goto wait loop blbc r0,get ; if an error, then cmpw tty_len,#0 ; quit. If no tty, then beql get ; get another process ;+++ ; get the physical device name for the virtual terminal for ; this process. Quit on error here. If the physical length ; is zero, then this terminal is disconnected. If not, return ; to the main GET: loop. Then check the image name. If the ; image name contains LOGINOUT, then this is a disconnected ; process running LOGINOUT. ;--- dvi: $getdvi_s devnam=tty_len,- ; Char Descript of TTY itmlst=dvilist ; get physical device blbc r0,get ; if an error, then ignore cmpl ptty_len,#0 ; if physical size .NE. 0, bnequ get ; then get another user matchc logimage_cnt,logimage,image_len,image cmpl r1,#logimage ; if .NOT. running LOGINOUT, beqlu get ; then get another user. kill: $delprc_s pidadr=rpid ; delete this user and brw get ; continue scan. ;+++ ; enter this section of code on error. Exit immediately. ; see next block comment for information on turning BREAK ; into a subroutine in your standard idle job killer program. ;--- ;quit: $exit_s code=R0 ; on error, go here. ;+++ ; enter this segment of code between passes through the $GETJPI ; table. Convert the time in TIMETOWAIT ( an ASCII delta) to ; a binary absolute time. Schedule a wakeup for that time, and ; hibernate until the time passes. Upon waking up, go back to ; the initialization code and start again. To turn this program ; into a subroutine, insert a MOVZWL #SS$_NORMAL, R0 and a RSB ; at WAIT instead of the timing information. Then, put a RSB at ; QUIT instead of the $EXIT. Fix the register mask (I think that ; the MATCHC uses R0->R5) and call BREAK, testing R0 for SS$_NORMAL. ;--- ;wait: $bintim_s timbuf=timetowait,timadr=binarytime ; $schdwk_s daytim=binarytime ; convert time to wait, ; $hiber_s ; $schd and $hiber ; brw init ; upon waking, re-init wait: movzwl #SS$_NORMAL, R0 ret .end ; of executable code