XWBTCPH ;ISC-SF/EG - TCP/IP PROCESS HANDLER ; 4/28/95
;;1.0T11;RPC BROKER;;Oct 31, 1995
;;V1.0T10;KERNEL RPC BROKER;
;Based on:
;XQORTCPH ;SLC/KCM - Service TCP Messages [ 12/04/94 9:06 PM ]
;XWBTCPH ;XXX/KCMO converted to use UCX service; 4/28/95
;
;Modified by ISC-SF/EG
; 0. No longer supports old style OERR messages
; 1. Makes call to RPC broker
; 2. Handles MSM Server under Windows NT
; 3. Handles MSM under Unix - same as DSM
; 4. Result of an rpc call can be a closed form of global
; 5. Can receive a large local array, within limits of job
; partition size.
; 6. Sets default device to NULL device prior to call, restores
; at termination. Prevents garbage from 'talking' calls.
; 7. All reads have a timeout.
; 8. Intro message is sent when first connected.
;
EN ; -- Main entry point for the UCX service call
N TYPE,XWBTBUF,XWBTBUF1,XWBTDEV,XWBTLEN,XWBTOS,XWBTRTN,XWBWRAP
N X,XWBL,XWB1,XWB2,Y,XWBTIME,XWBPTYPE,XWBPLEN,XWBNULL,XWBODEV
S XWBTIME=1
S XWBOS=$S(^%ZOSF("OS")["DSM":"DSM",^("OS")["UNIX":"UNIX",1:"MSM")
S XWBNULL=$S(XWBOS="DSM":"NLA0:",1:"")
IF XWBOS="DSM" D
. IF '$D(%)#2 S %=$P($ZIO,":")_":" ; Call with dsm$xecute()
. S (XWBTDEV,IO,IO(0))=%,X=$E(%_"WKSTA",1,15)
. D SETENV^%ZOSV
. O IO:(SHARE) X ^%ZOSF("TRMOFF")
IF XWBOS="MSM"!(XWBOS="UNIX") D
. S (XWBTDEV,IO,IO(0))=56
IF XWBOS="DSM" S $ETRAP="S %ZTER11S=$STACK D ETRAP^XWBTCPH"
E S X="ETRAP^XWBTCPH",@^%ZOSF("TRAP")
S DIQUIET=1,X="ETRAP^XWBTCPH",@^%ZOSF("TRAP") D DT^DICRW
;S DIQUIET=1 D DT^DICRW
S U="^"
;
MAIN ; -- main message processing loop
F D Q:XWBTBUF="#BYE#"
. ;
. ; -- read client request
. R XWBTBUF#15:600 IF '$T S XWBTBUF="#BYE#" W XWBTBUF,$C(4),! Q
. IF $L(XWBTBUF)=0 S XWBTBUF="#BYE#" W XWBTBUF,$C(4),! Q
. S TYPE=$S($E(XWBTBUF,1,5)="{XWB}":1,1:0)
. S XWBTLEN=$E(XWBTBUF,6,10)
. S XWBPLEN=$E(XWBTBUF,11,15)
. R XWBTBUF#XWBPLEN:XWBTIME
. I $P(XWBTBUF,U)="TCPconnect" D Q
. . W "accept",$C(4),! ;Ack
. IF TYPE D
. . K XWBR
. . IF XWBTBUF="#BYE#" W "#BYE#",$C(4),! Q ; -- clean disconnect
. . S XWBTLEN=XWBTLEN-15
. . ;IF XWBTLEN>240 S XWBR=$$RCN()
. . D CALLP^XWBBRK(.XWBR,XWBTBUF)
. . S XWBPTYPE=$S('$D(XWBPTYPE):1,XWBPTYPE<1:1,XWBPTYPE>6:1,1:XWBPTYPE)
. IF XWBTBUF="#BYE#" Q
. IF XWBOS="DSM"!(XWBOS="UNIX") D SNDDSM
. IF XWBOS="MSM" D SND
. W $C(4),! ;send eot and flush buffer
IF 'TYPE D
. W "#UNKNOWN MESSAGE TYPE#",$C(4),! Q ;end session
;
C XWBTDEV Q
;
SND ; -- Send data (all except DSM)
N I,T
; -- single value
IF XWBPTYPE=1 S XWBR=$G(XWBR) W XWBR Q
; -- table delimited by CR+LF
IF XWBPTYPE=2 D Q
. S I="" F S I=$O(XWBR(I)) Q:I="" W XWBR(I),$C(13,10)
; -- word processing
IF XWBPTYPE=3 D Q
. S I="" F S I=$O(XWBR(I)) Q:I="" W XWBR(I) W:XWBWRAP $C(13,10)
; -- global array
IF XWBPTYPE=4 D Q
. S I=XWBR,T=$E(I,1,$L(I)-1) W:$D(@I)>10 @I F S I=$Q(@I) Q:I=""!(I'[T) W @I W:XWBWRAP $C(13,10)
; -- global instance
IF XWBPTYPE=5 S XWBR=$G(@XWBR) W XWBR Q
; -- variable length records
IF XWBPTYPE=6 S I="" F S I=$O(XWBR(I)) Q:I="" W $C($L(XWBR(I))),XWBR(I)
Q
SNDDSM ; -- send data for DSM (requires buffer flush (!) every 512 chars)
N I,T
; -- single value
IF XWBPTYPE=1 S XWBR=$G(XWBR) W XWBR Q
; -- table delimited by CR+LF
I XWBPTYPE=2 D Q
. S I="" F S I=$O(XWBR(I)) Q:I="" W:($X+$L(XWBR(I)))>512 ! W XWBR(I),$C(13,10)
; -- word processing
IF XWBPTYPE=3 D Q
. S I="" F S I=$O(XWBR(I)) Q:I="" W:($X+$L(XWBR(I)))>512 ! W XWBR(I) W:XWBWRAP $C(13,10)
; -- global array
IF XWBPTYPE=4 D Q
. S I=XWBR,T=$E(I,1,$L(I)-1) W:$D(@I)>10 @I F S I=$Q(@I) Q:I=""!(I'[T) W:($X+$L(@I))>512 ! W @I W:XWBWRAP&(@I'=$C(13,10)) $C(13,10)
; -- global instance
IF XWBPTYPE=5 S XWBR=$G(@XWBR) W XWBR Q
; -- variable length records
IF XWBPTYPE=6 S I="" F S I=$O(XWBR(I)) Q:I="" W:($X+$L(XWBR(I)))>512 ! W $C($L(XWBR(I))),XWBR(I)
Q
;
ETRAP ; -- on trapped error, send error info to client
N XWBERR
S XWBERR=$C(24)_"M ERROR="_$ZERROR_$C(13,10)_"LAST REF="_$ZR_$C(4)
U XWBTDEV
IF XWBOS="DSM" D
. I $D(XWBTLEN),XWBTLEN,$ZE'["SYSTEM-F" W XWBERR D @^%ZOSF("ERRTN")
IF XWBOS="MSM" D
. W XWBERR D @^%ZOSF("ERRTN")
C XWBTDEV HALT
;
RCN() ;read entire buffer in chunks of 240 - save in global
N I,T
T S T=$R(10000)+1
L +^TMP("XWB",$J,T):3 IF '$T G T
F I=1:1:(XWBTLEN\240) D
. S ^TMP("XWB",$J,T,I)=$$BREAD(240)
S ^TMP("XWB",$J,T,I+1)=$$BREAD(XWBTLEN#240)
Q "^TMP(""XWB"","_$J_","_T_")"
;
BREAD(L) ;read tcp buffer, L is length
N E,X,DONE
S (E,DONE)=0
R X#L:XWBTIME
S E=X
IF $L(E)<L F D Q:'DONE
. IF $L(E)=L S DONE=1 Q
. R X#(L-$L(E)):XWBTIME
. S E=E_X
Q E
;
XWBTCPH ;ISC-SF/EG - TCP/IP PROCESS HANDLER ; 4/28/95
+1 ;;1.0T11;RPC BROKER;;Oct 31, 1995
+2 ;;V1.0T10;KERNEL RPC BROKER;
+3 ;Based on:
+4 ;XQORTCPH ;SLC/KCM - Service TCP Messages [ 12/04/94 9:06 PM ]
+5 ;XWBTCPH ;XXX/KCMO converted to use UCX service; 4/28/95
+6 ;
+7 ;Modified by ISC-SF/EG
+8 ; 0. No longer supports old style OERR messages
+9 ; 1. Makes call to RPC broker
+10 ; 2. Handles MSM Server under Windows NT
+11 ; 3. Handles MSM under Unix - same as DSM
+12 ; 4. Result of an rpc call can be a closed form of global
+13 ; 5. Can receive a large local array, within limits of job
+14 ; partition size.
+15 ; 6. Sets default device to NULL device prior to call, restores
+16 ; at termination. Prevents garbage from 'talking' calls.
+17 ; 7. All reads have a timeout.
+18 ; 8. Intro message is sent when first connected.
+19 ;
EN ; -- Main entry point for the UCX service call
+1 NEW TYPE,XWBTBUF,XWBTBUF1,XWBTDEV,XWBTLEN,XWBTOS,XWBTRTN,XWBWRAP
+2 NEW X,XWBL,XWB1,XWB2,Y,XWBTIME,XWBPTYPE,XWBPLEN,XWBNULL,XWBODEV
+3 SET XWBTIME=1
+4 SET XWBOS=$SELECT(^%ZOSF("OS")["DSM":"DSM",^("OS")["UNIX":"UNIX",1:"MSM")
+5 SET XWBNULL=$SELECT(XWBOS="DSM":"NLA0:",1:"")
+6 IF XWBOS="DSM"
Begin DoDot:1
+7 ; Call with dsm$xecute()
IF '$DATA(%)#2
SET %=$PIECE($ZIO,":")_":"
+8 SET (XWBTDEV,IO,IO(0))=%
SET X=$EXTRACT(%_"WKSTA",1,15)
+9 DO SETENV^%ZOSV
+10 OPEN IO:(SHARE)
XECUTE ^%ZOSF("TRMOFF")
End DoDot:1
+11 IF XWBOS="MSM"!(XWBOS="UNIX")
Begin DoDot:1
+12 SET (XWBTDEV,IO,IO(0))=56
End DoDot:1
+13 IF XWBOS="DSM"
SET $ETRAP="S %ZTER11S=$STACK D ETRAP^XWBTCPH"
+14 IF '$TEST
SET X="ETRAP^XWBTCPH"
SET @^%ZOSF("TRAP")
+15 SET DIQUIET=1
SET X="ETRAP^XWBTCPH"
SET @^%ZOSF("TRAP")
DO DT^DICRW
+16 ;S DIQUIET=1 D DT^DICRW
+17 SET U="^"
+18 ;
MAIN ; -- main message processing loop
+1 FOR
Begin DoDot:1
+2 ;
+3 ; -- read client request
+4 READ XWBTBUF#15:600
IF '$TEST
SET XWBTBUF="#BYE#"
WRITE XWBTBUF,$CHAR(4),!
QUIT
+5 IF $LENGTH(XWBTBUF)=0
SET XWBTBUF="#BYE#"
WRITE XWBTBUF,$CHAR(4),!
QUIT
+6 SET TYPE=$SELECT($EXTRACT(XWBTBUF,1,5)="{XWB}":1,1:0)
+7 SET XWBTLEN=$EXTRACT(XWBTBUF,6,10)
+8 SET XWBPLEN=$EXTRACT(XWBTBUF,11,15)
+9 READ XWBTBUF#XWBPLEN:XWBTIME
+10 IF $PIECE(XWBTBUF,U)="TCPconnect"
Begin DoDot:2
+11 ;Ack
WRITE "accept",$CHAR(4),!
End DoDot:2
QUIT
+12 IF TYPE
Begin DoDot:2
+13 KILL XWBR
+14 ; -- clean disconnect
IF XWBTBUF="#BYE#"
WRITE "#BYE#",$CHAR(4),!
QUIT
+15 SET XWBTLEN=XWBTLEN-15
+16 ;IF XWBTLEN>240 S XWBR=$$RCN()
+17 DO CALLP^XWBBRK(.XWBR,XWBTBUF)
+18 SET XWBPTYPE=$SELECT('$DATA(XWBPTYPE):1,XWBPTYPE<1:1,XWBPTYPE>6:1,1:XWBPTYPE)
End DoDot:2
+19 IF XWBTBUF="#BYE#"
QUIT
+20 IF XWBOS="DSM"!(XWBOS="UNIX")
DO SNDDSM
+21 IF XWBOS="MSM"
DO SND
+22 ;send eot and flush buffer
WRITE $CHAR(4),!
End DoDot:1
IF XWBTBUF="#BYE#"
QUIT
+23 IF 'TYPE
Begin DoDot:1
+24 ;end session
WRITE "#UNKNOWN MESSAGE TYPE#",$CHAR(4),!
QUIT
End DoDot:1
+25 ;
+26 CLOSE XWBTDEV
QUIT
+27 ;
SND ; -- Send data (all except DSM)
+1 NEW I,T
+2 ; -- single value
+3 IF XWBPTYPE=1
SET XWBR=$GET(XWBR)
WRITE XWBR
QUIT
+4 ; -- table delimited by CR+LF
+5 IF XWBPTYPE=2
Begin DoDot:1
+6 SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
WRITE XWBR(I),$CHAR(13,10)
End DoDot:1
QUIT
+7 ; -- word processing
+8 IF XWBPTYPE=3
Begin DoDot:1
+9 SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
WRITE XWBR(I)
IF XWBWRAP
WRITE $CHAR(13,10)
End DoDot:1
QUIT
+10 ; -- global array
+11 IF XWBPTYPE=4
Begin DoDot:1
+12 SET I=XWBR
SET T=$EXTRACT(I,1,$LENGTH(I)-1)
IF $DATA(@I)>10
WRITE @I
FOR
SET I=$QUERY(@I)
IF I=""!(I'[T)
QUIT
WRITE @I
IF XWBWRAP
WRITE $CHAR(13,10)
End DoDot:1
QUIT
+13 ; -- global instance
+14 IF XWBPTYPE=5
SET XWBR=$GET(@XWBR)
WRITE XWBR
QUIT
+15 ; -- variable length records
+16 IF XWBPTYPE=6
SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
WRITE $CHAR($LENGTH(XWBR(I))),XWBR(I)
+17 QUIT
SNDDSM ; -- send data for DSM (requires buffer flush (!) every 512 chars)
+1 NEW I,T
+2 ; -- single value
+3 IF XWBPTYPE=1
SET XWBR=$GET(XWBR)
WRITE XWBR
QUIT
+4 ; -- table delimited by CR+LF
+5 IF XWBPTYPE=2
Begin DoDot:1
+6 SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
IF ($X+$LENGTH(XWBR(I)))>512
WRITE !
WRITE XWBR(I),$CHAR(13,10)
End DoDot:1
QUIT
+7 ; -- word processing
+8 IF XWBPTYPE=3
Begin DoDot:1
+9 SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
IF ($X+$LENGTH(XWBR(I)))>512
WRITE !
WRITE XWBR(I)
IF XWBWRAP
WRITE $CHAR(13,10)
End DoDot:1
QUIT
+10 ; -- global array
+11 IF XWBPTYPE=4
Begin DoDot:1
+12 SET I=XWBR
SET T=$EXTRACT(I,1,$LENGTH(I)-1)
IF $DATA(@I)>10
WRITE @I
FOR
SET I=$QUERY(@I)
IF I=""!(I'[T)
QUIT
IF ($X+$LENGTH(@I))>512
WRITE !
WRITE @I
IF XWBWRAP&(@I'=$CHAR(13,10))
WRITE $CHAR(13,10)
End DoDot:1
QUIT
+13 ; -- global instance
+14 IF XWBPTYPE=5
SET XWBR=$GET(@XWBR)
WRITE XWBR
QUIT
+15 ; -- variable length records
+16 IF XWBPTYPE=6
SET I=""
FOR
SET I=$ORDER(XWBR(I))
IF I=""
QUIT
IF ($X+$LENGTH(XWBR(I)))>512
WRITE !
WRITE $CHAR($LENGTH(XWBR(I))),XWBR(I)
+17 QUIT
+18 ;
ETRAP ; -- on trapped error, send error info to client
+1 NEW XWBERR
+2 SET XWBERR=$CHAR(24)_"M ERROR="_$ZERROR_$CHAR(13,10)_"LAST REF="_$ZR_$CHAR(4)
+3 USE XWBTDEV
+4 IF XWBOS="DSM"
Begin DoDot:1
+5 IF $DATA(XWBTLEN)
IF XWBTLEN
IF $ZE'["SYSTEM-F"
WRITE XWBERR
DO @^%ZOSF("ERRTN")
End DoDot:1
+6 IF XWBOS="MSM"
Begin DoDot:1
+7 WRITE XWBERR
DO @^%ZOSF("ERRTN")
End DoDot:1
+8 CLOSE XWBTDEV
HALT
+9 ;
RCN() ;read entire buffer in chunks of 240 - save in global
+1 NEW I,T
T SET T=$RANDOM(10000)+1
+1 LOCK +^TMP("XWB",$JOB,T):3
IF '$TEST
GOTO T
+2 FOR I=1:1:(XWBTLEN\240)
Begin DoDot:1
+3 SET ^TMP("XWB",$JOB,T,I)=$$BREAD(240)
End DoDot:1
+4 SET ^TMP("XWB",$JOB,T,I+1)=$$BREAD(XWBTLEN#240)
+5 QUIT "^TMP(""XWB"","_$JOB_","_T_")"
+6 ;
BREAD(L) ;read tcp buffer, L is length
+1 NEW E,X,DONE
+2 SET (E,DONE)=0
+3 READ X#L:XWBTIME
+4 SET E=X
+5 IF $LENGTH(E)<L
FOR
Begin DoDot:1
+6 IF $LENGTH(E)=L
SET DONE=1
QUIT
+7 READ X#(L-$LENGTH(E)):XWBTIME
+8 SET E=E_X
End DoDot:1
IF 'DONE
QUIT
+9 QUIT E
+10 ;