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