--
--	sockudpcli.occ - UDP client
--	Copyright (C) 2000-2008 Fred Barnes <frmb@kent.ac.uk>
--      Modifications (C) 2008 Tom Carlson
--
--	This program is free software; you can redistribute it and/or modify
--	it under the terms of the GNU General Public License as published by
--	the Free Software Foundation; either version 2 of the License, or
--	(at your option) any later version.
--
--	This program is distributed in the hope that it will be useful,
--	but WITHOUT ANY WARRANTY; without even the implied warranty of
--	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--	GNU General Public License for more details.
--
--	You should have received a copy of the GNU General Public License
--	along with this program; if not, write to the Free Software
--	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
--

#INCLUDE "sock.module"
#INCLUDE "course.module"

--{{{  constants
VAL max.message.len IS 64:
--}}}  

--{{{  PROC send.message (SOCKET sock, VAL []BYTE message, INT res)
PROC send.message (SOCKET sock, VAL []BYTE message, INT res)
  SEQ
    socket.sendto (sock, message, 0, res)
:
--}}}  

--{{{ PROC sock.udp.cli (CHAN BYTE kyb?, scr!, err!)
PROC sock.udp.cli (CHAN BYTE kyb?, scr!, err!)

  --{{{  start here
  [128]BYTE hostname:
  [max.message.len]BYTE message:
  INT host.len, msg.len:
  INT remote.port, remote.addr:
  INT res:
  SOCKET sock:
  SEQ
    --{{{  get hostname/port
    out.string ("Hostname ?: ", 0, scr!)
    scr ! FLUSH
    in.string (hostname, host.len, (SIZE hostname), kyb?, scr!)
    scr ! '*n'
    socket.addr.of.host ([hostname FOR host.len], remote.addr, res)
    IF
      res < 0
        SEQ
          out.string ("Unable to determine address of ", 0, scr!)
          out.string ([hostname FOR host.len], 0, scr!)
          out.string ("*n", 0, scr!)
          STOP
      TRUE
        SKIP
    out.string ("Port ?: ", 0, scr!)
    scr ! FLUSH
    in.int (remote.port, 5, kyb?, scr!)
    scr ! '*n'
    --}}}  
    --{{{  create socket
    socket.create (sock, PF.INET, SOCK.DGRAM, IPPROTO.UDP)
    IF
      sock[fd] < 0
        SEQ
          out.string ("Unable to connect to ", 0, scr!)
          out.string ([hostname FOR host.len], 0, scr!)
          out.string (" port ", 0, scr!)
          out.int (remote.port, 0, scr!)
          out.string ("*n", 0, scr!)
          STOP
      TRUE
        SKIP
    sock[remote.addr] := remote.addr
    sock[remote.port] := remote.port
    --}}}  
    --{{{  deal with broadcast address
    BOOL bcast:
    SEQ
      [4]BYTE bytes RETYPES remote.addr:
      IF
        IF i = 0 FOR (SIZE bytes)
          bytes[i] = #FF
            bcast := TRUE
        TRUE
          bcast := FALSE
      IF
        bcast
          SEQ
            socket.setsockopt (sock, SOL.SOCKET, SO.BROADCAST, 1, res)
            IF
              res < 0
                SEQ
                  out.string ("Unable to set broadcast option on socket*n", 0, scr!)
                  socket.close (sock)
                  STOP
              TRUE
                out.string ("Broadcast option set on socket*n", 0, scr!)
        TRUE
          SKIP
    --}}}  
    --{{{  loop reading messages and sending them
    res := 1
    WHILE res > 0
      SEQ
        out.string ("Message (empty message exits) ?: ", 0, scr!)
        scr ! FLUSH
        in.string (message, msg.len, (SIZE message), kyb?, scr!)
        scr ! '*n'
        IF
          msg.len > 0
            send.message (sock, [message FOR msg.len], res)
          TRUE
            res := 0
    --}}}  
    --{{{  close socket
    socket.close (sock)
    --}}}  
  --}}}  

:
--}}}  

