Another weekend, another couple of hours bashing on COBOL. The client
now makes a connection, asks for the top document (sending an empty
CRLF) then prints out what it received. Here's a screen shot (the
contents of the SYSOUT spool dataset):
********************************* TOP OF DATA **********************************
gopher for mvs
initializing sockets api
getting foreign host IP
hostname-value republic.circumlunar.space
hostname-length 0026
hostaddr-value 10753750
getting socket
connecting to remote server...
sending request to remote gophper server...
reading data...
read: retcode = 0, done.
displaying data
iWelcome to the Mare Serenitatis Circumlunar Corporate Republic TITLE null.host
\ / null.host 1 i
. / \ * null.host 1 i
i ==================-+-+-+-+-+-+-+-+-+-+================== null.host 1 i
/\/\/\/\//++++++ null.host 1 i \_______ .oo. . . . .oo._____
\_______ oooo _______/ null.host 1 i . | \||||/ |
| [++++] | null.host 1 i * }:{ |
(((II))) * null.host 1 i .
i . \::/ null.host 1 i
(((((oo))))) null.host 1 i * \ /
. YY null.host 1 i / \ /\ n
/><\ null.host 1 i !----------|UU|----------! null.hos
/__________| null.host 1 i . ++ null.host 1 i
null.host 1 i . . null.host 1 i
st 1 i null.host 1 i null.host 1 i null.host 1 1About this Server /about
er Colony Zaibatsu / zaibatsu.circumlunar.space 70 0Signup for a Republic user
space 70 i null.host 1 1Recent Phlog Updates /updates republic.circumlunar.s
d asylum here: null.host 1 i null.host 1 1aidanh010 /~aidanh010 republic.cir
republic.circumlunar.space 70 1ben /~ben republic.circumlunar.space 70 1cleber
1emar /~emar republic.circumlunar.space 70 1katolaz /~katolaz republic.circuml
ircumlunar.space 70 1kst /~kst republic.circumlunar.space 70 1leeb /~leeb repu
republic.circumlunar.space 70 1mijk /~mijk republic.circumlunar.space 70 1mrgu
70 1np89 /~np89 republic.circumlunar.space 70 1rond /~rond republic.circumlun
ircumlunar.space 70 1uwu /~uwu republic.circumlunar.space 70 .
closing socket
terminating sockets api
done!
******************************** BOTTOM OF DATA ********************************
So, I can make requests to the gopher server and receive stuff
back. Excellent. A lazy man might call it a day there and say 'job
done', gopher client *technically* written. I'm going to put a bit
more effort in than that, however :)
republic.circumlunar.space is an ASCII system and MVS is EBCDIC, so
anything sent and received needs to be translated on its way in and
out. Fortunately, the sockets API provides two functions to do this
for me: EZACIC04 and EZACIC05. Snappy names, aren't they?
They're pretty straightforward to use. To send the top page CRLF to
the server, I move EBCDIC into a buffer, call EZACIC04 with the buffer
and the buffer length, and it returns ASCII data to me in the same
buffer:
move X"0D25" to send-empty.
move 2 to send-bytes-remain.
call 'EZACIC04' using send-empty send-bytes-remain.
'send-empty' is the data buffer
X"0D25" is EBCDIC hex code for CR and LF
'send-bytes-remain' is the length of the buffer (which also doubles
as the counter for bytes read for the socket write call further down
the code)
Reading stuff back is much the same, only going from ASCII to EBCDIC
via EZACIC05:
call 'EZACIC05' using read-buffer recv-bytes-read.
display read-buffer(1:recv-bytes-read).
Earlier in the code, a socket read call is made, depositing the
received ASCII in 'read-buffer', and the number of bytes read into
'recv-bytes-read'. Pass these over to EZACIC05, and it transforms the
ASCII in-place to EBCDIC, which then gets printed out.
The output is all mashed together because COBOL only starts a new line
with each 'display' statement. At the moment I'm dumping the entire
buffer out at once. Soon fix that though - 'inspect' is going to count
the lines for me, and I think 'unstring' and a variable-length table
will help me get things looking a bit better.