Contents of file "client.pf"
#! /usr/local/postforth/pfkern
: USAGE ( -) ( Show usage if not enough args supplied)
' ARGC , ' 4 , ' < ,
IF " Usage: " ' 2 , ' TYPE , ' 1 , ' ARGV , ' 2 , ' TYPE ,
" REMOTE_HOST REMOTE_PORT [[LINE1] [LINE2] ...]" ' 2 , ' TYPE ,
' 2 , ' CR , ' 0 , ' EXIT ,
ENDIF ' ;S ,
CONSTANT AF_INET 2 ,
CONSTANT SOCK_STREAM 1 ,
CONSTANT TCP 6 ,
VARIABLE CHILD 0 ,
VARIABLE THIS AF_INET S, 0 SWAB S, 16# 0 , 0 , 0 ,
HERE THIS - CONSTANT SOCKLEN , ( length of socket structure in bytes)
VARIABLE THAT AF_INET S, 10# 80 SWAB S, 16# 0100007F , 0 , 0 ,
VARIABLE SOCKETHANDLE 0 ,
: DOKILL ( -) ( cleanup on control-C)
' CHILD , ' @ , ' DUP , ( do we have a child process?)
IF ' _KILL , ' SWAP , ' SIGKILL , ' 0 , ' SYSCALL , ( destroy it)
ENDIF
' EXIT , ( exit with status from KILL, or 0 if no child)
SIGCHLD ' DOKILL @ SIGNAL ( die when child exits)
[ TCP SOCK_STREAM AF_INET ] >R SP@
>R _SOCKETCALL _SOCKET R> 0 SYSCALL
SOCKETHANDLE ! R> [DROP]
[ SOCKLEN THIS SOCKETHANDLE @ ] >R SP@
>R _SOCKETCALL _BIND R> 0 SYSCALL
R> [DROP]
[ SOCKLEN THAT SOCKETHANDLE @ ] >R SP@
>R _SOCKETCALL __CONNECT R> 0 SYSCALL
R> [DROP]
: CLIENT
' FORK , ' DUP ,
IF ( parent process, get keyboard input and pass to server)
' DUP , ' CHILD , ' ! , ( store child PID first)
BEGIN
' 0 , ' B/BUF , ' IN , ' READ , ' DUP , ' 1 , ' < ,
IF ' DOKILL ,
ELSE ' SOCKETHANDLE , ' @ , ' SWAP , ' IN , ' WRITE ,
ENDIF
AGAIN
ELSE ( child process, get what server sends back and display it)
BEGIN
' SOCKETHANDLE , ' @ , ' LIT , 10# 1024 ,
' PAD , ' READ , ' DUP , ' 1 , ' < ,
IF ' DOKILL ,
ELSE ' 1 , ' SWAP , ' PAD , ' WRITE ,
ENDIF
AGAIN
ENDIF ' ;S ,
USAGE CLIENT