- XWBTCPL ;SLC/KCM - Listener for TCP connects [ 02/13/95 9:01 PM ] ;10/16/96 11:33
- ;;1.1T3;RPC BROKER;;Nov 25, 1996
- ;ISC-SF/EG - DHCP Broker
- ;
- ; This routine is the background process that listens for client
- ; requests to connect to M. When a request is received, This
- ; procedure will job a s small routine to listen for new requests
- ; on the known service port.
- ;
- ; This job may be started in the background with: D STRT^XWBTCP(PORT)
- ;
- ; When running, this job may be stopped with: D STOP^XWBTCP(PORT)
- ;
- ; Where port is the known service port to listen for connections
- ;
- EN(XWBTSKT) ; -- accept clients and start the individual message handler
- N IP,REF,RETRY,XWBVER
- S U="^"
- S RETRY="START"
- X ^%ZOSF("UCI") S REF=Y
- S IP="0.0.0.0" ;get server IP
- IF $G(XWBTSKT)="" S XWBTSKT=9000 ; default service port
- S XWBTDEV=XWBTSKT
- ;
- D SETNM^%ZOSV($E("RPCB_Port:"_XWBTSKT,1,15)) ;change process name
- N LEN,MSG,XWBOS,DONE,DSMTCP,X
- ; -- check the TCP stop parameter
- ;IF $G(^XWB(IP,REF,XWBTSKT,"STOP")) K ^XWB(IP,REF,XWBTSKT) Q ; -- change to param file later ***
- Q:'$$SEMAPHOR(XWBTSKT,"LOCK") ; -- quit if job is already running
- ;
- D UPDTREC(XWBTSKT,3) ;updt RPC BROKER SITE PARAMETER record as RUNNING
- ;
- RESTART ;
- S DONE=0
- S XWBOS=$S(^%ZOSF("OS")["DSM":"DSM",^("OS")["MSM":"MSM",^("OS")["OpenM":"OpenM",1:"")
- IF $$NEWERR^%ZTER N $ESTACK S $ETRAP="S %ZTER11S=$STACK D ETRAP^XWBTCPL"
- E S X="ETRAP^XWBTCPL",@^%ZOSF("TRAP")
- ;
- ; -- check the TCP stop parameter
- ;IF $G(^XWB(IP,REF,XWBTSKT,"STOP")) K ^XWB(IP,REF,XWBTSKT) Q ; -- change to param file later ***
- ;
- I XWBOS="DSM" O XWBTSKT:TCPCHAN:5 ;Open listener
- ; -- loop until TCP stop parameter is set
- ;F D Q:$G(^XWB(IP,REF,XWBTSKT,"STOP"))
- F D Q:DONE
- . L +^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER")
- . K ^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER") ;clear problem marker
- . L -^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER")
- . ;
- . ; -- listen for connect & get the initial message from the client
- . I XWBOS="DSM" U XWBTSKT
- . I XWBOS="MSM" S XWBTDEV=56 O 56 U 56::"TCP" W /SOCKET("",XWBTSKT)
- . I XWBOS="OpenM" S XWBTDEV="|TCP|"_XWBTSKT O XWBTDEV:(:XWBTSKT:"AT") U XWBTDEV R *X
- . S XWBVER=0
- . R LEN#11 IF $E(LEN,1,5)'="{XWB}" Q
- . IF $E(LEN,11,11)="|" D
- . . R X#1
- . . R XWBVER#$A(X)
- . . R LEN#5
- . . R MSG#LEN
- . ELSE S X=$E(LEN,11,11),LEN=$E(LEN,6,10)-1 R MSG#LEN S MSG=X_MSG
- . ; -- msg should be: action^client IP^client port^token
- . ;
- . ; -- if the action is TCPconnect (usual case)
- . I $P(MSG,"^")="TCPconnect" D
- . . ;-- decrypt token
- . . N X,%T S X="",%T=0
- . . IF XWBOS="DSM" J EN^XWBTCPC($P(MSG,"^",2),$P(MSG,"^",3),$P(X,"^"),XWBVER):OPTION="/SYMBOL=100000":5 S %T=$T
- . . IF XWBOS="MSM" J EN^XWBTCPC($P(MSG,"^",2),$P(MSG,"^",3),$P(X,"^"),XWBVER):100000:5 S %T=$T
- . . I XWBOS="OpenM" J EN^XWBTCPC($P(MSG,"^",2),$P(MSG,"^",3),$P(X,"^"),XWBVER)::5 S %T=$T
- . . I %T D SNDERR W "accept",$C(4),!
- . . E D SNDERR W "reject",$C(4),! S ^TMP("TCP",$P($H,",",2))="REJECT"
- . ;
- . ; -- if the action is TCPdebug (when msg handler run interactively)
- . I $P(MSG,"^")="TCPdebug" D SNDERR W "accept",$C(4),!
- . ;
- . ; -- if the action is TCPshutdown, this listener will quit if the
- . ; stop flag has been set. This request comes from an M process.
- . I $P(MSG,"^")="TCPshutdown" S DONE=1 W "ack",!
- . ;Now release the connection.
- . I XWBOS="DSM" U XWBTSKT:DISCONNECT ; release this socket
- . I XWBOS="MSM" C 56
- . I XWBOS="OpenM" C XWBTDEV
- . Q
- ; -- loop end
- ;
- IF XWBOS="DSM" C XWBTSKT
- S %=$$SEMAPHOR(XWBTSKT,"UNLOCK") ; destroy 'running flag'
- ;K ^XWB(IP,REF,XWBTSKT,"STOP")
- D UPDTREC(XWBTSKT,6) ;updt RPC BROKER SITE PARAMETER record as STOPPED
- 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)
- D ^%ZTER ;Record it
- S RETRY=RETRY+1 H 3
- IF RETRY=5 H ;give up trying, server should not restart
- IF $$NEWERR^%ZTER S $ETRAP="Q:($ESTACK&'$QUIT) Q:$ESTACK 0 S $ECODE="""" G RESTART^XWBTCPL"
- IF XWBOS="DSM" D
- . I $D(XWBTLEN),XWBTLEN,$ZE'["SYSTEM-F" D SNDERR W XWBERR
- IF XWBOS'="DSM" D G RESTART
- . D SNDERR W XWBERR
- S $ECODE=",U1," Q ;Pass error up to pop stack.
- ;
- SNDERR ;send error information
- ;XWBSEC is the security packet, XWBERROR is application packet
- N X
- S X=$G(XWBSEC)
- W $C($L(X))_X
- S X=$G(XWBERROR)
- W $C($L(X))_X W !
- S XWBERROR="" ;clears parameters
- Q
- ;
- ;
- UPDTREC(XWBTSKT,STATE,XWBENV) ; -- update STATUS field and ^%ZIS X-ref of the
- ;RPC BROKER SITE PARAMETER file
- ;XWBTSKT: listener port
- N C,XWBOXIEN,XWBPOIEN,XWBFDA
- S C=",",U="^"
- I $G(XWBENV)'="" S Y=XWBENV
- E D GETENV^%ZOSV ;get Y=UCI^VOL^NODE^BOXLOOKUP of current system
- I STATE=3 S ^%ZIS(8994.171,"RPCB Listener",$P(Y,U,2),$P(Y,U),$P(Y,U,4),XWBTSKT)=$J
- I STATE=6 K ^%ZIS(8994.171,"RPCB Listener",$P(Y,U,2),$P(Y,U),$P(Y,U,4),XWBTSKT)
- ;
- S XWBOXIEN=$$FIND1^DIC(8994.17,",1,","",$P(Y,U,4)) ;find rec for box
- S XWBPOIEN=$$FIND1^DIC(8994.171,C_XWBOXIEN_",1,","",XWBTSKT)
- D:XWBPOIEN>0 ;update STATUS field if entry was found
- . D FDA^DILF(8994.171,XWBPOIEN_C_XWBOXIEN_C_1_C,1,"R",STATE,"XWBFDA")
- . D FILE^DIE("","XWBFDA")
- Q
- ;
- ;
- SEMAPHOR(XWBTSKT,XWBACT) ;Lock/Unlock listener semaphore
- ;XWBTSKT: listener port, XWBACT: "LOCK" | "UNLOCK" action to perform
- ;if LOCK is requested, it will be attempted with 1 sec timeout and if
- ;lock was obtained RESULT will be 1, otherwise it will be 0. For
- ;unlock RESULT will always be 1.
- N RESULT
- S U="^",RESULT=1
- D GETENV^%ZOSV ;get Y=UCI^VOL^NODE^BOXLOOKUP of current system
- I XWBACT="LOCK" D
- . L +^%ZIS(8994.171,"RPCB Listener",$P(Y,U,2),$P(Y,U),$P(Y,U,4),XWBTSKT):1
- . S RESULT=$T
- E L -^%ZIS(8994.171,"RPCB Listener",$P(Y,U,2),$P(Y,U),$P(Y,U,4),XWBTSKT)
- Q RESULT
- XWBTCPL ;SLC/KCM - Listener for TCP connects [ 02/13/95 9:01 PM ] ;10/16/96 11:33
- +1 ;;1.1T3;RPC BROKER;;Nov 25, 1996
- +2 ;ISC-SF/EG - DHCP Broker
- +3 ;
- +4 ; This routine is the background process that listens for client
- +5 ; requests to connect to M. When a request is received, This
- +6 ; procedure will job a s small routine to listen for new requests
- +7 ; on the known service port.
- +8 ;
- +9 ; This job may be started in the background with: D STRT^XWBTCP(PORT)
- +10 ;
- +11 ; When running, this job may be stopped with: D STOP^XWBTCP(PORT)
- +12 ;
- +13 ; Where port is the known service port to listen for connections
- +14 ;
- EN(XWBTSKT) ; -- accept clients and start the individual message handler
- +1 NEW IP,REF,RETRY,XWBVER
- +2 SET U="^"
- +3 SET RETRY="START"
- +4 XECUTE ^%ZOSF("UCI")
- SET REF=Y
- +5 ;get server IP
- SET IP="0.0.0.0"
- +6 ; default service port
- IF $GET(XWBTSKT)=""
- SET XWBTSKT=9000
- +7 SET XWBTDEV=XWBTSKT
- +8 ;
- +9 ;change process name
- DO SETNM^%ZOSV($EXTRACT("RPCB_Port:"_XWBTSKT,1,15))
- +10 NEW LEN,MSG,XWBOS,DONE,DSMTCP,X
- +11 ; -- check the TCP stop parameter
- +12 ;IF $G(^XWB(IP,REF,XWBTSKT,"STOP")) K ^XWB(IP,REF,XWBTSKT) Q ; -- change to param file later ***
- +13 ; -- quit if job is already running
- IF '$$SEMAPHOR(XWBTSKT,"LOCK")
- QUIT
- +14 ;
- +15 ;updt RPC BROKER SITE PARAMETER record as RUNNING
- DO UPDTREC(XWBTSKT,3)
- +16 ;
- RESTART ;
- +1 SET DONE=0
- +2 SET XWBOS=$SELECT(^%ZOSF("OS")["DSM":"DSM",^("OS")["MSM":"MSM",^("OS")["OpenM":"OpenM",1:"")
- +3 IF $$NEWERR^%ZTER
- NEW $ESTACK
- SET $ETRAP="S %ZTER11S=$STACK D ETRAP^XWBTCPL"
- +4 IF '$TEST
- SET X="ETRAP^XWBTCPL"
- SET @^%ZOSF("TRAP")
- +5 ;
- +6 ; -- check the TCP stop parameter
- +7 ;IF $G(^XWB(IP,REF,XWBTSKT,"STOP")) K ^XWB(IP,REF,XWBTSKT) Q ; -- change to param file later ***
- +8 ;
- +9 ;Open listener
- IF XWBOS="DSM"
- OPEN XWBTSKT:TCPCHAN:5
- +10 ; -- loop until TCP stop parameter is set
- +11 ;F D Q:$G(^XWB(IP,REF,XWBTSKT,"STOP"))
- +12 FOR
- Begin DoDot:1
- +13 LOCK +^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER")
- +14 ;clear problem marker
- KILL ^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER")
- +15 LOCK -^XWB(IP,REF,XWBTSKT,"PROBLEM MARKER")
- +16 ;
- +17 ; -- listen for connect & get the initial message from the client
- +18 IF XWBOS="DSM"
- USE XWBTSKT
- +19 IF XWBOS="MSM"
- SET XWBTDEV=56
- OPEN 56
- USE 56::"TCP"
- WRITE /SOCKET("",XWBTSKT)
- +20 IF XWBOS="OpenM"
- SET XWBTDEV="|TCP|"_XWBTSKT
- OPEN XWBTDEV:(:XWBTSKT:"AT")
- USE XWBTDEV
- READ *X
- +21 SET XWBVER=0
- +22 READ LEN#11
- IF $EXTRACT(LEN,1,5)'="{XWB}"
- QUIT
- +23 IF $EXTRACT(LEN,11,11)="|"
- Begin DoDot:2
- +24 READ X#1
- +25 READ XWBVER#$ASCII(X)
- +26 READ LEN#5
- +27 READ MSG#LEN
- End DoDot:2
- +28 IF '$TEST
- SET X=$EXTRACT(LEN,11,11)
- SET LEN=$EXTRACT(LEN,6,10)-1
- READ MSG#LEN
- SET MSG=X_MSG
- +29 ; -- msg should be: action^client IP^client port^token
- +30 ;
- +31 ; -- if the action is TCPconnect (usual case)
- +32 IF $PIECE(MSG,"^")="TCPconnect"
- Begin DoDot:2
- +33 ;-- decrypt token
- +34 NEW X,%T
- SET X=""
- SET %T=0
- +35 IF XWBOS="DSM"
- JOB EN^XWBTCPC($PIECE(MSG,"^",2),$PIECE(MSG,"^",3),$PIECE(X,"^"),XWBVER):OPTION="/SYMBOL=100000":5
- SET %T=$TEST
- +36 IF XWBOS="MSM"
- JOB EN^XWBTCPC($PIECE(MSG,"^",2),$PIECE(MSG,"^",3),$PIECE(X,"^"),XWBVER):100000:5
- SET %T=$TEST
- +37 IF XWBOS="OpenM"
- JOB EN^XWBTCPC($PIECE(MSG,"^",2),$PIECE(MSG,"^",3),$PIECE(X,"^"),XWBVER)::5
- SET %T=$TEST
- +38 IF %T
- DO SNDERR
- WRITE "accept",$CHAR(4),!
- +39 IF '$TEST
- DO SNDERR
- WRITE "reject",$CHAR(4),!
- SET ^TMP("TCP",$PIECE($HOROLOG,",",2))="REJECT"
- End DoDot:2
- +40 ;
- +41 ; -- if the action is TCPdebug (when msg handler run interactively)
- +42 IF $PIECE(MSG,"^")="TCPdebug"
- DO SNDERR
- WRITE "accept",$CHAR(4),!
- +43 ;
- +44 ; -- if the action is TCPshutdown, this listener will quit if the
- +45 ; stop flag has been set. This request comes from an M process.
- +46 IF $PIECE(MSG,"^")="TCPshutdown"
- SET DONE=1
- WRITE "ack",!
- +47 ;Now release the connection.
- +48 ; release this socket
- IF XWBOS="DSM"
- USE XWBTSKT:DISCONNECT
- +49 IF XWBOS="MSM"
- CLOSE 56
- +50 IF XWBOS="OpenM"
- CLOSE XWBTDEV
- +51 QUIT
- End DoDot:1
- IF DONE
- QUIT
- +52 ; -- loop end
- +53 ;
- +54 IF XWBOS="DSM"
- CLOSE XWBTSKT
- +55 ; destroy 'running flag'
- SET %=$$SEMAPHOR(XWBTSKT,"UNLOCK")
- +56 ;K ^XWB(IP,REF,XWBTSKT,"STOP")
- +57 ;updt RPC BROKER SITE PARAMETER record as STOPPED
- DO UPDTREC(XWBTSKT,6)
- +58 QUIT
- +59 ;
- 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 ;Record it
- DO ^%ZTER
- +4 SET RETRY=RETRY+1
- HANG 3
- +5 ;give up trying, server should not restart
- IF RETRY=5
- HANG
- +6 IF $$NEWERR^%ZTER
- SET $ETRAP="Q:($ESTACK&'$QUIT) Q:$ESTACK 0 S $ECODE="""" G RESTART^XWBTCPL"
- +7 IF XWBOS="DSM"
- Begin DoDot:1
- +8 IF $DATA(XWBTLEN)
- IF XWBTLEN
- IF $ZE'["SYSTEM-F"
- DO SNDERR
- WRITE XWBERR
- End DoDot:1
- +9 IF XWBOS'="DSM"
- Begin DoDot:1
- +10 DO SNDERR
- WRITE XWBERR
- End DoDot:1
- GOTO RESTART
- +11 ;Pass error up to pop stack.
- SET $ECODE=",U1,"
- QUIT
- +12 ;
- SNDERR ;send error information
- +1 ;XWBSEC is the security packet, XWBERROR is application packet
- +2 NEW X
- +3 SET X=$GET(XWBSEC)
- +4 WRITE $CHAR($LENGTH(X))_X
- +5 SET X=$GET(XWBERROR)
- +6 WRITE $CHAR($LENGTH(X))_X
- WRITE !
- +7 ;clears parameters
- SET XWBERROR=""
- +8 QUIT
- +9 ;
- +10 ;
- UPDTREC(XWBTSKT,STATE,XWBENV) ; -- update STATUS field and ^%ZIS X-ref of the
- +1 ;RPC BROKER SITE PARAMETER file
- +2 ;XWBTSKT: listener port
- +3 NEW C,XWBOXIEN,XWBPOIEN,XWBFDA
- +4 SET C=","
- SET U="^"
- +5 IF $GET(XWBENV)'=""
- SET Y=XWBENV
- +6 ;get Y=UCI^VOL^NODE^BOXLOOKUP of current system
- IF '$TEST
- DO GETENV^%ZOSV
- +7 IF STATE=3
- SET ^%ZIS(8994.171,"RPCB Listener",$PIECE(Y,U,2),$PIECE(Y,U),$PIECE(Y,U,4),XWBTSKT)=$JOB
- +8 IF STATE=6
- KILL ^%ZIS(8994.171,"RPCB Listener",$PIECE(Y,U,2),$PIECE(Y,U),$PIECE(Y,U,4),XWBTSKT)
- +9 ;
- +10 ;find rec for box
- SET XWBOXIEN=$$FIND1^DIC(8994.17,",1,","",$PIECE(Y,U,4))
- +11 SET XWBPOIEN=$$FIND1^DIC(8994.171,C_XWBOXIEN_",1,","",XWBTSKT)
- +12 ;update STATUS field if entry was found
- IF XWBPOIEN>0
- Begin DoDot:1
- +13 DO FDA^DILF(8994.171,XWBPOIEN_C_XWBOXIEN_C_1_C,1,"R",STATE,"XWBFDA")
- +14 DO FILE^DIE("","XWBFDA")
- End DoDot:1
- +15 QUIT
- +16 ;
- +17 ;
- SEMAPHOR(XWBTSKT,XWBACT) ;Lock/Unlock listener semaphore
- +1 ;XWBTSKT: listener port, XWBACT: "LOCK" | "UNLOCK" action to perform
- +2 ;if LOCK is requested, it will be attempted with 1 sec timeout and if
- +3 ;lock was obtained RESULT will be 1, otherwise it will be 0. For
- +4 ;unlock RESULT will always be 1.
- +5 NEW RESULT
- +6 SET U="^"
- SET RESULT=1
- +7 ;get Y=UCI^VOL^NODE^BOXLOOKUP of current system
- DO GETENV^%ZOSV
- +8 IF XWBACT="LOCK"
- Begin DoDot:1
- +9 LOCK +^%ZIS(8994.171,"RPCB Listener",$PIECE(Y,U,2),$PIECE(Y,U),$PIECE(Y,U,4),XWBTSKT):1
- +10 SET RESULT=$TEST
- End DoDot:1
- +11 IF '$TEST
- LOCK -^%ZIS(8994.171,"RPCB Listener",$PIECE(Y,U,2),$PIECE(Y,U),$PIECE(Y,U,4),XWBTSKT)
- +12 QUIT RESULT