Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: ZISTCP

ZISTCP.m

Go to the documentation of this file.
  1. %ZISTCP ;ISC/RWF,ISD/HGW - DEVICE HANDLER TCP/IP CALLS ;07/11/14 11:37
  1. ;;8.0;KERNEL;**36,34,59,69,118,225,275,638**;Jul 10, 1995;Build 16
  1. ;Per VA Directive 6402, this routine should not be modified.
  1. Q
  1. ;
  1. CALL(IP,SOCK,TO) ;Open a socket to the IP address <procedure>
  1. N %A,ZISOS,X,NIO
  1. S ZISOS=^%ZOSF("OS"),TO=$G(TO,30)
  1. N $ETRAP S $ETRAP="G OPNERR^%ZISTCP"
  1. S POP=1
  1. I '$$VALIDATE^XLFIPV(IP) S IP=$$ADDRESS^XLFNSLK(IP) ;Lookup the name
  1. I '$$VALIDATE^XLFIPV(IP) Q ;Not in the IP format
  1. I (SOCK<1)!(SOCK>65535) Q
  1. G CVXD:ZISOS["VAX",CONT:ZISOS["OpenM",CGTM:ZISOS["GT.M",CMSM:ZISOS["MSM"
  1. S POP=1
  1. Q
  1. CVXD ;Open VAX DSM Socket
  1. S NIO=SOCK
  1. O NIO:(TCPCHAN,ADDRESS=IP):TO G:'$T NOOPN
  1. U NIO:NOECHO D VAR(NIO)
  1. Q
  1. CMSM ;Open MSM Socket
  1. S NIO=56 O NIO::TO G:'$T NOOPN
  1. U NIO::"TCP" W /SOCKET(IP,SOCK) I $KEY="" C NIO G NOOPN
  1. D VAR(NIO)
  1. Q
  1. CONT ;Open OpenM socket
  1. I $$VERSION^%ZOSV'<5 S %A=$ZUTIL(68,55,1)
  1. S NIO="|TCP|"_SOCK
  1. ;p638 If IP contains ".", use IPv4 IP address (may be IPv4-mapped, so convert)
  1. ; Else use IPv6 address
  1. I IP["." D
  1. . O NIO:($$FORCEIP4^XLFIPV(IP):SOCK:"-M"::512:512):TO G:'$T NOOPN
  1. E D
  1. . O NIO:("["_IP_"]":SOCK:"-M"::512:512):TO G:'$T NOOPN
  1. U NIO D VAR(NIO)
  1. Q
  1. CGTM ;Open GT.M Socket
  1. S NIO="SCK$"_$P($H,",",2) ;Just needs to be unique for job
  1. O NIO:(CONNECT=IP_":"_SOCK_":TCP":ATTACH="client"):TO:"SOCKET"
  1. I '$T S POP=1 Q
  1. U NIO S NIO("KEY")=$KEY
  1. S NIO("SOCKET")=$P(NIO("KEY"),"|",2)
  1. I $P(NIO("KEY"),"|")'="ESTABLISHED" D LOG("** ="_NIO("KEY")_"= **") W 1/0 ; PROTOCOL ERROR
  1. ;U NIO:(SOCKET=NIO("SOCKET"):WIDTH=512:NOWRAP:IOERROR="TRAP":EXCEPT="G GTMERR^%ZISTCP")
  1. U NIO:(SOCKET=NIO("SOCKET"):WIDTH=512:NOWRAP:EXCEPT="G GTMERR^%ZISTCP")
  1. D VAR(NIO) S IOF="#" ;Set buffer flush
  1. Q
  1. VAR(%IO) ;Setup IO variables
  1. S:'$D(IO(0)) IO(0)=$I
  1. S IO=%IO,IO(1,IO)=$G(IP),POP=0
  1. ;Set IOF to the normal buffer flush. W @IOF.
  1. S IOT="TCP",IOST="P-TCP",IOST(0)=0
  1. S IOF=$$FLUSHCHR
  1. Q
  1. NOOPN ;Didn't make the conection
  1. S POP=1
  1. Q
  1. OPNERR ;
  1. ;D ^%ZTER
  1. S POP=1
  1. D ERRCLR
  1. Q
  1. UCXOPEN(NIO) ;This call only applies to SERVER jobs tied to UCX/VMS
  1. N $ETRAP,%ZISV,%ZISOS S $ETRAP="G OPNERR^%ZISTCP"
  1. S %ZISV=$$VERSION^%ZOSV,%ZISOS=^%ZOSF("OS"),POP=1
  1. I %ZISOS["DSM",%ZISV<7 O NIO:(SHARE):5 D:$T VAR(NIO)
  1. I %ZISOS["DSM",%ZISV'<7 S NIO="SYS$NET" O NIO:(TCPDEV):5 D:$T VAR(NIO)
  1. Q
  1. CLOSE ;Close and reset
  1. N NIO,$ETRAP S $ETRAP="G CLOSEX^%ZISTCP"
  1. S NIO=IO,IO=$S($G(IO(0))]"":IO(0),1:$P)
  1. I NIO]"" C NIO K IO(1,NIO) S IO("CLOSE")=NIO
  1. CLOSEX D HOME^%ZIS
  1. D ERRCLR
  1. Q
  1. ERRCLR ;
  1. S:$ECODE]"" IO("LASTERR")=$G(IO("ERROR")),IO("ERROR")=$ECODE,$ECODE=""
  1. Q
  1. ;
  1. FLUSHCHR() ;Return the value to write @ of to flush the TCP buffer
  1. N OS S OS=$P(^%ZOSF("OS"),"^")
  1. Q $S(OS["GT.M":"#",1:"!")
  1. ;
  1. ;In ZRULE, set ZISQUIT=1 to quit
  1. LISTEN(SOCK,RTN,ZRULE) ;Listen on socket, run routine, single thread.
  1. N %A,ZISOS,X,NIO,EXIT,IOF,IP
  1. N $ES,$ET S $ET="D OPNERR^%ZISTCP"
  1. S ZISOS=^%ZOSF("OS"),ZRULE=$G(ZRULE)
  1. D GETENV^%ZOSV S U="^",XUENV=Y,XQVOL=$P(Y,U,2)
  1. S POP=1
  1. I $G(^%ZIS(14.5,"LOGON",XQVOL)) Q
  1. LOOP S POP=1 D LVXD:ZISOS["DSM",LONT:ZISOS["OpenM",LGTM:ZISOS["GT.M",LMSM:ZISOS["MSM"
  1. I POP Q ;Quit Server
  1. S EXIT=0,EXIT=$$LAUNCH(NIO,RTN)
  1. I $G(^%ZIS(14.5,"LOGON",XQVOL)) S EXIT=1
  1. I ZISOS["DSM" X "U NIO:DISCONNECT"
  1. E C NIO ;
  1. Q:EXIT ;Quit server, App set IO("C"), Logon inhibit.
  1. G LOOP
  1. LMSM ;MSM
  1. ;For multi thread use MSM's MSERVER process.
  1. ;This is the listener for TCP connects.
  1. S NIO=56 O NIO::30 Q:'$T S POP=0
  1. U NIO::"TCP" W /SOCKET("",SOCK)
  1. S POP=$$EXIT
  1. Q
  1. LONT ;Open port in Accept mode with standard terminators, standard buffers.
  1. N %ZA,%ZB
  1. S NIO="|TCP|"_SOCK,%A=0
  1. ;(adr:sock:term:ibuf:obuf:queue)
  1. O NIO:(:SOCK:"AT"::512:512:3):30 Q:'$T S POP=0
  1. ;Wait on read for a connect
  1. U NIO F D Q:%A!POP
  1. . R *NEWCHAR:60 S %ZA=$ZA,%ZB=$ZB S:$T %A=1 Q:%A
  1. . S POP=$$EXIT
  1. I POP C NIO Q
  1. U NIO:(::"-M") ;Work like DSM
  1. Q
  1. ;
  1. LVXD ;Open port and listen
  1. ;Use UCX for multiple listeners
  1. S NIO=SOCK O NIO:(TCPCHAN):30 Q:'$T S POP=0
  1. U NIO ;Let application wait at the read for a connect.
  1. Q
  1. ;
  1. LGTM ;GT.M single thread server
  1. N %A K ^TMP("ZISTCP",$J)
  1. ;S $ZINTERRUPT="I $$JOBEXAM^ZU($ZPOSITION)"
  1. S NIO="SCK$"_$S($J>86400:$J,1:84600+$J) ;Construct a dummy, but "unique" devicename for job
  1. D LOG("Open for Listen "_NIO)
  1. ;Open the device
  1. O NIO:(ZLISTEN=SOCK_":TCP":ATTACH="listener"):30:"SOCKET"
  1. I '$T D LOG("Can't Open Socket: "_SOCK) Q
  1. U NIO S NIO("ZISTCP",0)=$KEY D LOG("Have port.")
  1. ;Start Listening
  1. W /LISTEN(1) S NIO("ZISTCP",1)=$KEY D LOG("Start Listening. "_NIO("ZISTCP",1))
  1. ;Wait for connection
  1. S %A=0,POP=0 F D Q:%A!POP
  1. . W /WAIT(30) ;Wait for connect
  1. . I $P($KEY,"|",1)="CONNECT" S NIO("ZISTCP",2)=$KEY,%A=1
  1. . S POP=$$EXIT
  1. . Q
  1. I POP C NIO Q
  1. ;
  1. S NIO("SOCK")=$P($G(NIO("ZISTCP",2)),"|",2)
  1. D LOG("Got connection on "_NIO("SOCK"))
  1. ;Close the main socket
  1. C NIO:(SOCKET="listener")
  1. ;Use the new socket
  1. ;U NIO:(SOCKET=NIO("SOCK"):WIDTH=512:NOWRAP:IOERROR="TRAP":EXCEPT="G GTMERR^%ZISTCP")
  1. U NIO:(SOCKET=NIO("SOCK"):WIDTH=512:NOWRAP:EXCEPT="G GTMERR^%ZISTCP")
  1. S POP=0
  1. Q
  1. ;
  1. GTMERR ;The use will set this as a place to go on a IO error
  1. S $ECODE=",U911,"
  1. Q
  1. ;
  1. EXIT() ;See if time to exit
  1. I $$S^%ZTLOAD Q 1
  1. N ZISQUIT S ZISQUIT=0
  1. I $L(ZRULE) X ZRULE I $G(ZISQUIT) Q 1
  1. Q 0
  1. ;
  1. LAUNCH(IO,RTN) ;Run job for this connection.
  1. N NIO,SOCK,EXIT,XQVOL
  1. D VAR(IO)
  1. S ^XUTL("XQ",$J,0)=$$DT^XLFDT
  1. D LOG("Run "_RTN)
  1. D @RTN
  1. D LOG("Return from call, Exit="_$D(IO("C")))
  1. Q $D(IO("C")) ;Use IO("C") to quit server
  1. ;
  1. LOG(MSG) ;LOG STATUS
  1. N CNT
  1. S CNT=$G(^TMP("ZISTCP",$J))+1,^TMP("ZISTCP",$J)=CNT,^($J,CNT)=MSG
  1. Q
  1. ;