HLCSTCP ;SFIRMFO/TNV-ALB/JFP,PKE - (TCP/IP) MLLP ;09/13/2006
;;1.6;HEALTH LEVEL SEVEN;**19,43,49,57,58,64,84,109,133**;Oct 13, 1995;Build 13
;Per VHA Directive 2004-038, this routine should not be modified.
;
; This is an implementation of the HL7 Minimal Lower Layer Protocol
;
;taskman entry/startup option, HLDP defined in menu entry,
Q:'$D(HLDP)
N HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
;HLCSOUT= 1-error
I '$$INIT D EXITS("Init Error") Q
; Start the client
I $G(HLTCPCS)="C" D Q
. ; identify process for ^%SY
. D SETNM^%ZOSV($E("HLClnt:"_HLDP,1,15))
. D ST1
. F D ^HLCSTCP2 Q:$$STOP!$G(HLCSOUT)
. I $G(HLCSOUT)=1 D MON("Error") H 1 Q
. I $G(HLCSOUT)=2 D EXITS("Inactive") Q
. D EXITS("Shutdown")
;
; identify process for ^%SY
D SETNM^%ZOSV($E("HLSrv:"_HLDP,1,15))
;HLCSFAIL=1 port failed to open
S HLCSFAIL=1
;single threaded listener
I $G(HLTCPCS)="S" D Q
. D ST1,MON("Listen"),LISTEN^%ZISTCP(HLTCPORT,"SERVER^HLCSTCP("""_HLDP_""")")
. ;couldn't open listener port
. I HLCSFAIL D EXITS("Openfail") Q
;
;multi-threaded listener (OpenM)
I $G(HLTCPCS)="M",^%ZOSF("OS")["OpenM" D Q
. D ST1,MON("Listen"),LISTEN^%ZISTCPS(HLTCPORT,"SERVERS^HLCSTCP("""_HLDP_""")")
Q
;
SERVER(HLDP) ; single server using Taskman
S HLCSFAIL=0
I '$$INIT D EXITS("Init error") Q
D ^HLCSTCP1
I $$STOP D CLOSE^%ZISTCP,EXITS("Shutdown") S IO("C")="" Q
Q:$G(HLCSOUT)=1
D MON("Idle")
Q
;
SERVERS(HLDP) ; Multi-threaded server using Taskman
I '$$INIT D EXITS("Init error") Q
G LISTEN
;
;multiple process servers, called from an external utility
MSM ;MSM entry point, called from User-Defined Services
;HLDP=ien in the HL LOWER LEVEL PROTOCOL PARAMETER file for the
;HL7 Multi-Threaded SERVER
S (IO,IO(0))=$P
G LISTEN
;
CACHEVMS(%) ;Cache'/VMS tcpip/ucx entry point, called from HLSEVEN.COM file,
;listener, % = HLDP
I $G(%)="" D ^%ZTER Q
S IO="SYS$NET",HLDP=%
S IO(0)="_NLA0:" O IO(0) ;Setup null device
; **Cache'/VMS specific code**
O IO::5 E D MON("Openfail") Q
X "U IO:(::""-M"")" ;Packet mode like DSM
D LISTEN C IO Q
;
EN ;vms ucx entry point, called from HLSEVEN.COM file,
;listener, % = device^HLDP
I $G(%)="" D ^%ZTER Q
S IO="SYS$NET",U="^",HLDP=$P(%,U,2)
S IO(0)="_NLA0:" O IO(0) ;Setup null device
; **VMS specific code, need to share device**
O IO:(TCPDEV):60 E D MON("Openfail") Q
LISTEN ;
N HLLSTN,HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
I '$$INIT D ^%ZTER Q
; identify process for ^%SY
D SETNM^%ZOSV($E("HLSrv:"_HLDP,1,15))
;HLLSTN used to identify a listener to tag MON
S HLLSTN=1
;increment job count, run server
D UPDT(1),^HLCSTCP1,EXITM
Q
;
DCOPEN(HLDP) ;open direct connect - called from HLMA2
Q:'$$INIT 0
Q:HLTCPADD=""!(HLTCPORT="") 0
Q:'$$OPEN^HLCSTCP2 0
Q 1
;
INIT() ; Initialize Variables
; HLDP should be set to the IEN or name of Logical Link, file 870
S HLOS=$P($G(^%ZOSF("OS")),"^")
N DA,DIQUIET,DR,TMP,X,Y
S DIQUIET=1
D DT^DICRW
I 'HLDP S HLDP=$O(^HLCS(870,"B",HLDP,0)) I 'HLDP Q 0
S DA=HLDP
S DR="200.02;200.021;200.022;200.03;200.04;200.05;200.09;400.01;400.02;400.03;400.04;400.05"
D GETS^DIQ(870,DA,DR,"IN","TMP","TMP")
;
I $D(TMP("DIERR")) QUIT 0
; -- re-transmit attempts
S HLDRETR=+$G(TMP(870,DA_",",200.02,"I"))
S HLDRETR("CLOSE")=+$G(TMP(870,DA_",",200.022,"I"))
; -- exceed re-transmit action
S HLRETRA=$G(TMP(870,DA_",",200.021,"I"))
; -- block size
S HLDBSIZE=+$G(TMP(870,DA_",",200.03,"I"))
; -- read timeout
S HLDREAD=+$G(TMP(870,DA_",",200.04,"I"))
; -- ack timeout
S HLDBACK=+$G(TMP(870,DA_",",200.05,"I"))
; -- uni-directional wait
S HLDWAIT=$G(TMP(870,DA_",",200.09,"I"))
; -- tcp address
S HLTCPADD=$G(TMP(870,DA_",",400.01,"I"))
; -- tcp port
S HLTCPORT=$G(TMP(870,DA_",",400.02,"I"))
; -- tcp/ip service type
S HLTCPCS=$G(TMP(870,DA_",",400.03,"I"))
; -- link persistence
S HLTCPLNK=$G(TMP(870,DA_",",400.04,"I"))
; -- retention
S HLTCPRET=$G(TMP(870,DA_",",400.05,"I"))
;
; -- set defaults in case something's not set
S:HLDREAD=0 HLDREAD=10
S:HLDBACK=0 HLDBACK=60
S:HLDBSIZE=0 HLDBSIZE=245
S:HLDRETR=0 HLDRETR=5
S:HLTCPRET="" X=$P($$PARAM^HLCS2,U,12),HLTCPRET=$S(X:X,1:15)
;
Q 1
;
ST1 ;record startup in 870 for single server
;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
;14=Shutdown LLP, 3=LLP Online, 18=Gross Errors
N HLJ,X
F L +^HLCS(870,HLDP,0):2 Q:$T
S X="HLJ(870,"""_HLDP_","")"
S @X@(4)="Init",(@X@(10),@X@(18))="@",@X@(14)=0
I HLTCPCS["C" S @X@(3)=$S(HLTCPLNK["Y":"PC",1:"NC")
E S @X@(3)=$S(HLTCPCS["S":"SS",HLTCPCS["M":"MS",1:"")
I @X@(3)'="NC" S @X@(9)=$$NOW^XLFDT
S:$G(ZTSK) @X@(11)=ZTSK
D FILE^HLDIE("","HLJ","","ST1","HLCSTCP") ;HL*1.6*109
L -^HLCS(870,HLDP,0)
Q
;
MON(Y) ;Display current state & check for shutdown
;don't display for multiple server
Q:$G(HLLSTN)
F L +^HLCS(870,HLDP,0):2 Q:$T
S $P(^HLCS(870,HLDP,0),U,5)=Y
L -^HLCS(870,HLDP,0)
Q:'$D(HLTRACE)
N X U IO(0)
W !,"IN State: ",Y
I '$$STOP D
. R !,"Type Q to Quit: ",X#1:1
. I $L(X),"Qq"[X S $P(^HLCS(870,HLDP,0),U,15)=1
U IO
Q
UPDT(Y) ;update job count for multiple servers,X=1 increment
N HLJ,X
F L +^HLCS(870,HLDP,0):2 Q:$T
S X=+$P(^HLCS(870,HLDP,0),U,5),$P(^(0),U,5)=$S(Y:X+1,1:X-1)_" server"
;if incrementing, set the Device Type field to Multi-Server
I X S HLJ(870,HLDP_",",3)="MS" D FILE^HLDIE("","HLJ","","UPDT","HLCSTCP") ;HL*1.6*109
L -^HLCS(870,HLDP,0)
Q
STOP() ;stop flag set
N X
F L +^HLCS(870,HLDP,0):2 Q:$T
S X=+$P(^HLCS(870,HLDP,0),U,15)
L -^HLCS(870,HLDP,0)
Q X
;
LLCNT(DP,Y,Z) ;update Logical Link counters
;DP=ien of Logical Link in file 870
;Y: 1=msg rec, 2=msg proc, 3=msg to send, 4=msg sent
;Z: ""=add to counter, 1=subtract from counter
Q:'$D(^HLCS(870,+$G(DP),0))!('$G(Y))
N P,X
S P=$S(Y<3:"IN",1:"OUT")_" QUEUE "_$S(Y#2:"BACK",1:"FRONT")_" POINTER"
F L +^HLCS(870,DP,P):2 Q:$T
S X=+$G(^HLCS(870,DP,P)),^(P)=X+$S($G(Z):-1,1:1)
L -^HLCS(870,DP,P)
Q
SDFLD ; set Shutdown? field to yes
Q:'$G(HLDP)
N HLJ,X
F L +^HLCS(870,HLDP,0):2 Q:$T
;14=Shutdown LLP?
S HLJ(870,HLDP_",",14)=1
D FILE^HLDIE("","HLJ","","SDFLD","HLCSTCP") ;HL*1.6*109
L -^HLCS(870,HLDP,0)
Q
;
EXITS(Y) ; Single service shutdown and cleans up
N HLJ,X
F L +^HLCS(870,HLDP,0):2 Q:$T
;4=status,10=Time Stopped,9=Time Started,11=Task Number
S X="HLJ(870,"""_HLDP_","")"
S @X@(4)=Y,@X@(11)="@"
S:$G(HLCSOUT)'=2 @X@(10)=$$NOW^XLFDT,@X@(9)="@"
D FILE^HLDIE("","HLJ","","EXITS","HLCSTCP") ; HL*1.6*109
L -^HLCS(870,HLDP,0)
I $D(ZTQUEUED) S ZTREQ="@"
Q
;
EXITM ;Multiple service shutdown and clean up
D UPDT(0)
I $D(ZTQUEUED) S ZTREQ="@"
Q
HLCSTCP ;SFIRMFO/TNV-ALB/JFP,PKE - (TCP/IP) MLLP ;09/13/2006
+1 ;;1.6;HEALTH LEVEL SEVEN;**19,43,49,57,58,64,84,109,133**;Oct 13, 1995;Build 13
+2 ;Per VHA Directive 2004-038, this routine should not be modified.
+3 ;
+4 ; This is an implementation of the HL7 Minimal Lower Layer Protocol
+5 ;
+6 ;taskman entry/startup option, HLDP defined in menu entry,
+7 IF '$DATA(HLDP)
QUIT
+8 NEW HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
+9 ;HLCSOUT= 1-error
+10 IF '$$INIT
DO EXITS("Init Error")
QUIT
+11 ; Start the client
+12 IF $GET(HLTCPCS)="C"
Begin DoDot:1
+13 ; identify process for ^%SY
+14 DO SETNM^%ZOSV($EXTRACT("HLClnt:"_HLDP,1,15))
+15 DO ST1
+16 FOR
DO ^HLCSTCP2
IF $$STOP!$G(HLCSOUT)
QUIT
+17 IF $GET(HLCSOUT)=1
DO MON("Error")
HANG 1
QUIT
+18 IF $GET(HLCSOUT)=2
DO EXITS("Inactive")
QUIT
+19 DO EXITS("Shutdown")
End DoDot:1
QUIT
+20 ;
+21 ; identify process for ^%SY
+22 DO SETNM^%ZOSV($EXTRACT("HLSrv:"_HLDP,1,15))
+23 ;HLCSFAIL=1 port failed to open
+24 SET HLCSFAIL=1
+25 ;single threaded listener
+26 IF $GET(HLTCPCS)="S"
Begin DoDot:1
+27 DO ST1
DO MON("Listen")
DO LISTEN^%ZISTCP(HLTCPORT,"SERVER^HLCSTCP("""_HLDP_""")")
+28 ;couldn't open listener port
+29 IF HLCSFAIL
DO EXITS("Openfail")
QUIT
End DoDot:1
QUIT
+30 ;
+31 ;multi-threaded listener (OpenM)
+32 IF $GET(HLTCPCS)="M"
IF ^%ZOSF("OS")["OpenM"
Begin DoDot:1
+33 DO ST1
DO MON("Listen")
DO LISTEN^%ZISTCPS(HLTCPORT,"SERVERS^HLCSTCP("""_HLDP_""")")
End DoDot:1
QUIT
+34 QUIT
+35 ;
SERVER(HLDP) ; single server using Taskman
+1 SET HLCSFAIL=0
+2 IF '$$INIT
DO EXITS("Init error")
QUIT
+3 DO ^HLCSTCP1
+4 IF $$STOP
DO CLOSE^%ZISTCP
DO EXITS("Shutdown")
SET IO("C")=""
QUIT
+5 IF $GET(HLCSOUT)=1
QUIT
+6 DO MON("Idle")
+7 QUIT
+8 ;
SERVERS(HLDP) ; Multi-threaded server using Taskman
+1 IF '$$INIT
DO EXITS("Init error")
QUIT
+2 GOTO LISTEN
+3 ;
+4 ;multiple process servers, called from an external utility
MSM ;MSM entry point, called from User-Defined Services
+1 ;HLDP=ien in the HL LOWER LEVEL PROTOCOL PARAMETER file for the
+2 ;HL7 Multi-Threaded SERVER
+3 SET (IO,IO(0))=$PRINCIPAL
+4 GOTO LISTEN
+5 ;
CACHEVMS(%) ;Cache'/VMS tcpip/ucx entry point, called from HLSEVEN.COM file,
+1 ;listener, % = HLDP
+2 IF $GET(%)=""
DO ^%ZTER
QUIT
+3 SET IO="SYS$NET"
SET HLDP=%
+4 ;Setup null device
SET IO(0)="_NLA0:"
OPEN IO(0)
+5 ; **Cache'/VMS specific code**
+6 OPEN IO::5
IF '$TEST
DO MON("Openfail")
QUIT
+7 ;Packet mode like DSM
XECUTE "U IO:(::""-M"")"
+8 DO LISTEN
CLOSE IO
QUIT
+9 ;
EN ;vms ucx entry point, called from HLSEVEN.COM file,
+1 ;listener, % = device^HLDP
+2 IF $GET(%)=""
DO ^%ZTER
QUIT
+3 SET IO="SYS$NET"
SET U="^"
SET HLDP=$PIECE(%,U,2)
+4 ;Setup null device
SET IO(0)="_NLA0:"
OPEN IO(0)
+5 ; **VMS specific code, need to share device**
+6 OPEN IO:(TCPDEV):60
IF '$TEST
DO MON("Openfail")
QUIT
LISTEN ;
+1 NEW HLLSTN,HLCSOUT,HLDBACK,HLDBSIZE,HLDREAD,HLDRETR,HLRETRA,HLDWAIT,HLOS,HLTCPADD,HLTCPCS,HLTCPLNK,HLTCPORT,HLTCPRET,HLCSFAIL
+2 IF '$$INIT
DO ^%ZTER
QUIT
+3 ; identify process for ^%SY
+4 DO SETNM^%ZOSV($EXTRACT("HLSrv:"_HLDP,1,15))
+5 ;HLLSTN used to identify a listener to tag MON
+6 SET HLLSTN=1
+7 ;increment job count, run server
+8 DO UPDT(1)
DO ^HLCSTCP1
DO EXITM
+9 QUIT
+10 ;
DCOPEN(HLDP) ;open direct connect - called from HLMA2
+1 IF '$$INIT
QUIT 0
+2 IF HLTCPADD=""!(HLTCPORT="")
QUIT 0
+3 IF '$$OPEN^HLCSTCP2
QUIT 0
+4 QUIT 1
+5 ;
INIT() ; Initialize Variables
+1 ; HLDP should be set to the IEN or name of Logical Link, file 870
+2 SET HLOS=$PIECE($GET(^%ZOSF("OS")),"^")
+3 NEW DA,DIQUIET,DR,TMP,X,Y
+4 SET DIQUIET=1
+5 DO DT^DICRW
+6 IF 'HLDP
SET HLDP=$ORDER(^HLCS(870,"B",HLDP,0))
IF 'HLDP
QUIT 0
+7 SET DA=HLDP
+8 SET DR="200.02;200.021;200.022;200.03;200.04;200.05;200.09;400.01;400.02;400.03;400.04;400.05"
+9 DO GETS^DIQ(870,DA,DR,"IN","TMP","TMP")
+10 ;
+11 IF $DATA(TMP("DIERR"))
QUIT 0
+12 ; -- re-transmit attempts
+13 SET HLDRETR=+$GET(TMP(870,DA_",",200.02,"I"))
+14 SET HLDRETR("CLOSE")=+$GET(TMP(870,DA_",",200.022,"I"))
+15 ; -- exceed re-transmit action
+16 SET HLRETRA=$GET(TMP(870,DA_",",200.021,"I"))
+17 ; -- block size
+18 SET HLDBSIZE=+$GET(TMP(870,DA_",",200.03,"I"))
+19 ; -- read timeout
+20 SET HLDREAD=+$GET(TMP(870,DA_",",200.04,"I"))
+21 ; -- ack timeout
+22 SET HLDBACK=+$GET(TMP(870,DA_",",200.05,"I"))
+23 ; -- uni-directional wait
+24 SET HLDWAIT=$GET(TMP(870,DA_",",200.09,"I"))
+25 ; -- tcp address
+26 SET HLTCPADD=$GET(TMP(870,DA_",",400.01,"I"))
+27 ; -- tcp port
+28 SET HLTCPORT=$GET(TMP(870,DA_",",400.02,"I"))
+29 ; -- tcp/ip service type
+30 SET HLTCPCS=$GET(TMP(870,DA_",",400.03,"I"))
+31 ; -- link persistence
+32 SET HLTCPLNK=$GET(TMP(870,DA_",",400.04,"I"))
+33 ; -- retention
+34 SET HLTCPRET=$GET(TMP(870,DA_",",400.05,"I"))
+35 ;
+36 ; -- set defaults in case something's not set
+37 IF HLDREAD=0
SET HLDREAD=10
+38 IF HLDBACK=0
SET HLDBACK=60
+39 IF HLDBSIZE=0
SET HLDBSIZE=245
+40 IF HLDRETR=0
SET HLDRETR=5
+41 IF HLTCPRET=""
SET X=$PIECE($$PARAM^HLCS2,U,12)
SET HLTCPRET=$SELECT(X:X,1:15)
+42 ;
+43 QUIT 1
+44 ;
ST1 ;record startup in 870 for single server
+1 ;4=status 9=Time Started, 10=Time Stopped, 11=Task Number
+2 ;14=Shutdown LLP, 3=LLP Online, 18=Gross Errors
+3 NEW HLJ,X
+4 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+5 SET X="HLJ(870,"""_HLDP_","")"
+6 SET @X@(4)="Init"
SET (@X@(10),@X@(18))="@"
SET @X@(14)=0
+7 IF HLTCPCS["C"
SET @X@(3)=$SELECT(HLTCPLNK["Y":"PC",1:"NC")
+8 IF '$TEST
SET @X@(3)=$SELECT(HLTCPCS["S":"SS",HLTCPCS["M":"MS",1:"")
+9 IF @X@(3)'="NC"
SET @X@(9)=$$NOW^XLFDT
+10 IF $GET(ZTSK)
SET @X@(11)=ZTSK
+11 ;HL*1.6*109
DO FILE^HLDIE("","HLJ","","ST1","HLCSTCP")
+12 LOCK -^HLCS(870,HLDP,0)
+13 QUIT
+14 ;
MON(Y) ;Display current state & check for shutdown
+1 ;don't display for multiple server
+2 IF $GET(HLLSTN)
QUIT
+3 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+4 SET $PIECE(^HLCS(870,HLDP,0),U,5)=Y
+5 LOCK -^HLCS(870,HLDP,0)
+6 IF '$DATA(HLTRACE)
QUIT
+7 NEW X
USE IO(0)
+8 WRITE !,"IN State: ",Y
+9 IF '$$STOP
Begin DoDot:1
+10 READ !,"Type Q to Quit: ",X#1:1
+11 IF $LENGTH(X)
IF "Qq"[X
SET $PIECE(^HLCS(870,HLDP,0),U,15)=1
End DoDot:1
+12 USE IO
+13 QUIT
UPDT(Y) ;update job count for multiple servers,X=1 increment
+1 NEW HLJ,X
+2 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+3 SET X=+$PIECE(^HLCS(870,HLDP,0),U,5)
SET $PIECE(^(0),U,5)=$SELECT(Y:X+1,1:X-1)_" server"
+4 ;if incrementing, set the Device Type field to Multi-Server
+5 ;HL*1.6*109
IF X
SET HLJ(870,HLDP_",",3)="MS"
DO FILE^HLDIE("","HLJ","","UPDT","HLCSTCP")
+6 LOCK -^HLCS(870,HLDP,0)
+7 QUIT
STOP() ;stop flag set
+1 NEW X
+2 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+3 SET X=+$PIECE(^HLCS(870,HLDP,0),U,15)
+4 LOCK -^HLCS(870,HLDP,0)
+5 QUIT X
+6 ;
LLCNT(DP,Y,Z) ;update Logical Link counters
+1 ;DP=ien of Logical Link in file 870
+2 ;Y: 1=msg rec, 2=msg proc, 3=msg to send, 4=msg sent
+3 ;Z: ""=add to counter, 1=subtract from counter
+4 IF '$DATA(^HLCS(870,+$GET(DP),0))!('$GET(Y))
QUIT
+5 NEW P,X
+6 SET P=$SELECT(Y<3:"IN",1:"OUT")_" QUEUE "_$SELECT(Y#2:"BACK",1:"FRONT")_" POINTER"
+7 FOR
LOCK +^HLCS(870,DP,P):2
IF $TEST
QUIT
+8 SET X=+$GET(^HLCS(870,DP,P))
SET ^(P)=X+$SELECT($GET(Z):-1,1:1)
+9 LOCK -^HLCS(870,DP,P)
+10 QUIT
SDFLD ; set Shutdown? field to yes
+1 IF '$GET(HLDP)
QUIT
+2 NEW HLJ,X
+3 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+4 ;14=Shutdown LLP?
+5 SET HLJ(870,HLDP_",",14)=1
+6 ;HL*1.6*109
DO FILE^HLDIE("","HLJ","","SDFLD","HLCSTCP")
+7 LOCK -^HLCS(870,HLDP,0)
+8 QUIT
+9 ;
EXITS(Y) ; Single service shutdown and cleans up
+1 NEW HLJ,X
+2 FOR
LOCK +^HLCS(870,HLDP,0):2
IF $TEST
QUIT
+3 ;4=status,10=Time Stopped,9=Time Started,11=Task Number
+4 SET X="HLJ(870,"""_HLDP_","")"
+5 SET @X@(4)=Y
SET @X@(11)="@"
+6 IF $GET(HLCSOUT)'=2
SET @X@(10)=$$NOW^XLFDT
SET @X@(9)="@"
+7 ; HL*1.6*109
DO FILE^HLDIE("","HLJ","","EXITS","HLCSTCP")
+8 LOCK -^HLCS(870,HLDP,0)
+9 IF $DATA(ZTQUEUED)
SET ZTREQ="@"
+10 QUIT
+11 ;
EXITM ;Multiple service shutdown and clean up
+1 DO UPDT(0)
+2 IF $DATA(ZTQUEUED)
SET ZTREQ="@"
+3 QUIT