unit SockDef;
(*
**
** SOCKDEF routines
**
** Copyright (c) 1998 by Thomas W. Mueller
**
** Created : 24-Oct-1998
** Last update : 24-Oct-1998
**
**
*)

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
 INTERFACE
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

uses
  Sysutils,
{$IFDEF OS2}
  Os2def;
{$ENDIF}
{$IFDEF LINUX}
  Linux;
{$ENDIF}
{$IFDEF WIN32}
  Windows;
{$ENDIF}

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

{$IFDEF VER0_99_13}
type pInteger = ^Integer;
     tFarProc = pointer;
     SmallInt = System.Integer;
{$ENDIF}

{$IFDEF LINUX}
type ULONG    = longint;
{$ENDIF}

type
  tSockDesc  = LongInt;
  SmallWord  = System.Word;

type
  eSocketErr = class(Exception);

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

const
  MaxHostNameLen = 120;

(*
** Option flags per-socket.
*)
{$IFNDEF LINUX}
(*
** Level number for (get/set)sockopt() to apply to socket itself.
*)
  SOL_SOCKET      =$ffff;          // options for socket level

  SO_DEBUG        =$0001;          // turn on debugging info recording
  SO_ACCEPTCONN   =$0002;          // socket has had listen()
  SO_REUSEADDR    =$0004;          // allow local address reuse
  SO_KEEPALIVE    =$0008;          // keep connections alive
  SO_DONTROUTE    =$0010;          // just use interface addresses
  SO_BROADCAST    =$0020;          // permit sending of broadcast msgs
  SO_USELOOPBACK  =$0040;          // bypass hardware when possible
  SO_LINGER       =$0080;          // linger on close if data present
  SO_OOBINLINE    =$0100;          // leave received OOB data in line

(*
** Additional options, not kept in so_options.
*)
  SO_SNDBUF       =$1001;          // send buffer size
  SO_RCVBUF       =$1002;          // receive buffer size
  SO_SNDLOWAT     =$1003;          // send low-water mark
  SO_RCVLOWAT     =$1004;          // receive low-water mark
  SO_SNDTIMEO     =$1005;          // send timeout
  SO_RCVTIMEO     =$1006;          // receive timeout
  SO_ERROR        =$1007;          // get error status and clear
  SO_TYPE         =$1008;          // get socket type

{$ELSE}
  SOL_SOCKET      = 1;

  SO_DEBUG        = 1;
  SO_REUSEADDR    = 2;
  SO_TYPE         = 3;
  SO_ERROR        = 4;
  SO_DONTROUTE    = 5;
  SO_BROADCAST    = 6;
  SO_SNDBUF       = 7;
  SO_RCVBUF       = 8;
  SO_KEEPALIVE    = 9;
  SO_OOBINLINE    = 10;
  SO_NO_CHECK     = 11;
  SO_PRIORITY     = 12;
  SO_LINGER       = 13;
  SO_BSDCOMPAT    = 14;
{$ENDIF}


(*
** Address families.
*)
  AF_UNSPEC      =  0;              // unspecified
  AF_UNIX        =  1;              // local to host (pipes, portals)
  AF_INET        =  2;              // internetwork: UDP, TCP, etc.
  AF_IMPLINK     =  3;              // arpanet imp addresses
  AF_PUP         =  4;              // pup protocols: e.g. BSP
  AF_CHAOS       =  5;              // mit CHAOS protocols
  AF_NS          =  6;              // XEROX NS protocols
  AF_NBS         =  7;              // nbs protocols
  AF_ECMA        =  8;              // european computer manufacturers
  AF_DATAKIT     =  9;              // datakit protocols
  AF_CCITT       = 10;              // CCITT protocols, X.25 etc
  AF_SNA         = 11;              // IBM SNA
  AF_DECnet      = 12;              // DECnet
  AF_DLI         = 13;              // Direct data link interface
  AF_LAT         = 14;              // LAT
  AF_HYLINK      = 15;              // NSC Hyperchannel
  AF_APPLETALK   = 16;              // Apple Talk

  AF_OS2         = AF_UNIX;

  AF_NB          = 17;                // Netbios
  AF_NETBIOS     = AF_NB;

  AF_MAX         = 18;

(*
** Protocol families, same as address families for now.
*)
  PF_UNSPEC       = AF_UNSPEC;
  PF_UNIX         = AF_UNIX;
  PF_INET         = AF_INET;
  PF_IMPLINK      = AF_IMPLINK;
  PF_PUP          = AF_PUP;
  PF_CHAOS        = AF_CHAOS;
  PF_NS           = AF_NS;
  PF_NBS          = AF_NBS;
  PF_ECMA         = AF_ECMA;
  PF_DATAKIT      = AF_DATAKIT;
  PF_CCITT        = AF_CCITT;
  PF_SNA          = AF_SNA;
  PF_DECnet       = AF_DECnet;
  PF_DLI          = AF_DLI;
  PF_LAT          = AF_LAT;
  PF_HYLINK       = AF_HYLINK;
  PF_APPLETALK    = AF_APPLETALK;
  PF_NETBIOS      = AF_NB;
  PF_NB           = AF_NB;
  PF_OS2          = PF_UNIX;
  PF_MAX          = AF_MAX;

(*
** Maximum queue length specifiable by listen.
*)

  SOMAXCONN       = 5;

  FREAD  =1;
  FWRITE =2;

  MSG_OOB         =$1;             // process out-of-band data
  MSG_PEEK        =$2;             // peek at incoming message
  MSG_DONTROUTE   =$4;             // send without using routing tables
  MSG_FULLREAD    =$8;             // send without using routing tables

  MSG_MAXIOVLEN   =16;

const
{ All Windows Sockets error constants are biased by WSABASEERR from the "normal" }

  WSABASEERR              = 10000;

{ Windows Sockets definitions of regular Microsoft C error constants }

  WSAEINTR                = (WSABASEERR+4);
  WSAEBADF                = (WSABASEERR+9);
  WSAEACCES               = (WSABASEERR+13);
  WSAEFAULT               = (WSABASEERR+14);
  WSAEINVAL               = (WSABASEERR+22);
  WSAEMFILE               = (WSABASEERR+24);

{ Windows Sockets definitions of regular Berkeley error constants }

{$IFNDEF LINUX}
  WSAEWOULDBLOCK          = (WSABASEERR+35);
  WSAEINPROGRESS          = (WSABASEERR+36);
  WSAEALREADY             = (WSABASEERR+37);
  WSAENOTSOCK             = (WSABASEERR+38);
  WSAEDESTADDRREQ         = (WSABASEERR+39);
  WSAEMSGSIZE             = (WSABASEERR+40);
  WSAEPROTOTYPE           = (WSABASEERR+41);
  WSAENOPROTOOPT          = (WSABASEERR+42);
  WSAEPROTONOSUPPORT      = (WSABASEERR+43);
  WSAESOCKTNOSUPPORT      = (WSABASEERR+44);
  WSAEOPNOTSUPP           = (WSABASEERR+45);
  WSAEPFNOSUPPORT         = (WSABASEERR+46);
  WSAEAFNOSUPPORT         = (WSABASEERR+47);
  WSAEADDRINUSE           = (WSABASEERR+48);
  WSAEADDRNOTAVAIL        = (WSABASEERR+49);
  WSAENETDOWN             = (WSABASEERR+50);
  WSAENETUNREACH          = (WSABASEERR+51);
  WSAENETRESET            = (WSABASEERR+52);
  WSAECONNABORTED         = (WSABASEERR+53);
  WSAECONNRESET           = (WSABASEERR+54);
  WSAENOBUFS              = (WSABASEERR+55);
  WSAEISCONN              = (WSABASEERR+56);
  WSAENOTCONN             = (WSABASEERR+57);
  WSAESHUTDOWN            = (WSABASEERR+58);
  WSAETOOMANYREFS         = (WSABASEERR+59);
  WSAETIMEDOUT            = (WSABASEERR+60);
  WSAECONNREFUSED         = (WSABASEERR+61);
  WSAELOOP                = (WSABASEERR+62);
  WSAENAMETOOLONG         = (WSABASEERR+63);
  WSAEHOSTDOWN            = (WSABASEERR+64);
  WSAEHOSTUNREACH         = (WSABASEERR+65);
  WSAENOTEMPTY            = (WSABASEERR+66);
  WSAEPROCLIM             = (WSABASEERR+67);
  WSAEUSERS               = (WSABASEERR+68);
  WSAEDQUOT               = (WSABASEERR+69);
  WSAESTALE               = (WSABASEERR+70);
  WSAEREMOTE              = (WSABASEERR+71);

  WSAEDISCON              = (WSABASEERR+101);
{$ENDIF}

{$IFDEF LINUX}
  WSAEWOULDBLOCK          = 11;
  WSAEINPROGRESS          = 115;
  WSAEALREADY             = 114;
  WSAENOTSOCK             = 88;
  WSAEDESTADDRREQ         = 89;
  WSAEMSGSIZE             = 90;
  WSAEPROTOTYPE           = 91;
  WSAENOPROTOOPT          = 92;
  WSAEPROTONOSUPPORT      = 93;
  WSAESOCKTNOSUPPORT      = 94;
  WSAEOPNOTSUPP           = 95;
  WSAEPFNOSUPPORT         = 96;
  WSAEAFNOSUPPORT         = 97;
  WSAEADDRINUSE           = 98;
  WSAEADDRNOTAVAIL        = 99;
  WSAENETDOWN             = 100;
  WSAENETUNREACH          = 101;
  WSAENETRESET            = 102;
  WSAECONNABORTED         = 103;
  WSAECONNRESET           = 104;
  WSAENOBUFS              = 105;
  WSAEISCONN              = 106;
  WSAENOTCONN             = 107;
  WSAESHUTDOWN            = 108;
  WSAETOOMANYREFS         = 109;
  WSAETIMEDOUT            = 110;
  WSAECONNREFUSED         = 111;
  WSAELOOP                = 40;
  WSAENAMETOOLONG         = 36;
  WSAEHOSTDOWN            = 112;
  WSAEHOSTUNREACH         = 113;
  WSAENOTEMPTY            = 39;
  WSAEPROCLIM             = 00;
  WSAEUSERS               = 87;
  WSAEDQUOT               = 122;
  WSAESTALE               = 116;
  WSAEREMOTE              = 66;
{$ENDIF}

{ Extended Windows Sockets error constant definitions }

  WSASYSNOTREADY          = (WSABASEERR+91);
  WSAVERNOTSUPPORTED      = (WSABASEERR+92);
  WSANOTINITIALISED       = (WSABASEERR+93);

{ Error return codes from gethostbyname() and gethostbyaddr()
  (when using the resolver). Note that these errors are
  retrieved via WSAGetLastError() and must therefore follow
  the rules for avoiding clashes with error numbers from
  specific implementations or language run-time systems.
  For this reason the codes are based at WSABASEERR+1001.
  Note also that [WSA]NO_ADDRESS is defined only for
  compatibility purposes. }

{ Authoritative Answer: Host not found }

  WSAHOST_NOT_FOUND       = (WSABASEERR+1001);
  HOST_NOT_FOUND          = WSAHOST_NOT_FOUND;

{ Non-Authoritative: Host not found, or SERVERFAIL }

  WSATRY_AGAIN            = (WSABASEERR+1002);
  TRY_AGAIN               = WSATRY_AGAIN;

{ Non recoverable errors, FORMERR, REFUSED, NOTIMP }

  WSANO_RECOVERY          = (WSABASEERR+1003);
  NO_RECOVERY             = WSANO_RECOVERY;

{ Valid name, no data record of requested type }

  WSANO_DATA              = (WSABASEERR+1004);
  NO_DATA                 = WSANO_DATA;

{ no address, look for MX record }

  WSANO_ADDRESS           = WSANO_DATA;
  NO_ADDRESS              = WSANO_ADDRESS;

{ Windows Sockets errors redefined as regular Berkeley error constants.
  These are commented out in Windows NT to avoid conflicts with errno.h.
  Use the WSA constants instead. }

  EWOULDBLOCK        =  WSAEWOULDBLOCK;
  EINPROGRESS        =  WSAEINPROGRESS;
  EALREADY           =  WSAEALREADY;
  ENOTSOCK           =  WSAENOTSOCK;
  EDESTADDRREQ       =  WSAEDESTADDRREQ;
  EMSGSIZE           =  WSAEMSGSIZE;
  EPROTOTYPE         =  WSAEPROTOTYPE;
  ENOPROTOOPT        =  WSAENOPROTOOPT;
  EPROTONOSUPPORT    =  WSAEPROTONOSUPPORT;
  ESOCKTNOSUPPORT    =  WSAESOCKTNOSUPPORT;
  EOPNOTSUPP         =  WSAEOPNOTSUPP;
  EPFNOSUPPORT       =  WSAEPFNOSUPPORT;
  EAFNOSUPPORT       =  WSAEAFNOSUPPORT;
  EADDRINUSE         =  WSAEADDRINUSE;
  EADDRNOTAVAIL      =  WSAEADDRNOTAVAIL;
  ENETDOWN           =  WSAENETDOWN;
  ENETUNREACH        =  WSAENETUNREACH;
  ENETRESET          =  WSAENETRESET;
  ECONNABORTED       =  WSAECONNABORTED;
  ECONNRESET         =  WSAECONNRESET;
  ENOBUFS            =  WSAENOBUFS;
  EISCONN            =  WSAEISCONN;
  ENOTCONN           =  WSAENOTCONN;
  ESHUTDOWN          =  WSAESHUTDOWN;
  ETOOMANYREFS       =  WSAETOOMANYREFS;
  ETIMEDOUT          =  WSAETIMEDOUT;
  ECONNREFUSED       =  WSAECONNREFUSED;
  ELOOP              =  WSAELOOP;
  ENAMETOOLONG       =  WSAENAMETOOLONG;
  EHOSTDOWN          =  WSAEHOSTDOWN;
  EHOSTUNREACH       =  WSAEHOSTUNREACH;
  ENOTEMPTY          =  WSAENOTEMPTY;
  EPROCLIM           =  WSAEPROCLIM;
  EUSERS             =  WSAEUSERS;
  EDQUOT             =  WSAEDQUOT;
  ESTALE             =  WSAESTALE;
  EREMOTE            =  WSAEREMOTE;

  SockAddr_Len       = 16;
  In_Addr_Len        =  4;
  InAddr_Any         =  0;
  InAddr_Loopback    = $7F000001;
  InAddr_Broadcast   = $FFFFFFFF;
  InAddr_None        = $FFFFFFFF;

  SOCK_NULL      =  0;
  SOCK_STREAM    =  1;            // stream socket
  SOCK_DGRAM     =  2;            // datagram socket
  SOCK_RAW       =  3;            // raw-protocol interface
  SOCK_RDM       =  4;            // reliably-delivered message
  SOCK_SEQPACKET =  5;            // sequenced packet stream

  IPPROTO_NULL   =  0;
  IPPROTO_UDP    =  17;
  IPPROTO_TCP    =  6;


const
  IOCPARM_MASK = $7f;
  IOC_VOID     = $20000000;
  IOC_OUT      = $40000000;
  IOC_IN       = $80000000;
  IOC_INOUT    = (IOC_IN or IOC_OUT);

{$IFNDEF LINUX}
  FIONREAD     = IOC_OUT or { get # bytes to read }
    ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or
    (Longint(Byte('f')) shl 8) or 127;
  FIONBIO      = IOC_IN or { set/clear non-blocking i/o }
    ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or
    (Longint(Byte('f')) shl 8) or 126;
  FIOASYNC     = IOC_IN or { set/clear async i/o }
    ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or
    (Longint(Byte('f')) shl 8) or 125;
{$ENDIF}

type
  pLongInt = ^LongInt;

  pIoVec = ^tIoVec;
  tIoVec = packed record
    iov_base: POINTER;
    iov_len: LongInt;
  end;

(*
** Structure used for manipulating linger option.
*)
  tLinger = packed record
    l_onoff: LongInt;                // option on/off
    l_linger: LongInt;               // linger time
  END;

(*
** Structure used by kernel to pass protocol
** information in raw sockets.
*)

  tSockProto = packed record
    sp_family: WORD;              // address family
    sp_protocol: WORD;            // protocol
  END;

  off_t = LongInt;

  tuio = packed record
    uio_iov: pIoVec;
    uio_iovcnt: LongInt;
    uio_offset: off_t;
    uio_segflg: LongInt;
    uio_resid: LongInt;
  END;

  pIn_Addr = ^tIn_Addr;
  tIn_Addr = packed record
             case integer of
               0: (IPAddr:   ULong);
               1: (ClassA:   byte;
                   ClassB:   byte;
                   ClassC:   byte;
                   ClassD:   byte)
             end;

(*
** Structure used by kernel to store most
** addresses.
*)
  pSockAddr=^tSockAddr;
  tSockAddr=packed record
            case integer of
              0: (Sin_Family: SmallWord;
                  Sin_Port:   SmallWord;
                  Sin_Addr:   tIn_Addr;
                  Sin_Zero:   array[1.. 8] of byte);
              1: (Sa_Family:  SmallWord;
                  Sa_Addr:    array[1..14] of byte);
            end;

(*
** Message header for recvmsg and sendmsg calls.
*)
  pMsgHdr = ^tMsgHdr;
  tMsgHdr = packed record
    msg_name: pChar;               // optional address
    msg_namelen: LongInt;            // size of address
    msg_iov: pIoVec;         // scatter/gather array
    msg_iovlen: LongInt;             // # elements in msg_iov
    msg_accrights: pChar;          // access rights sent/received
    msg_accrightslen: LongInt;
  END;

  uio_rw = ( UIO_READ, UIO_WRITE );

  pHostEnt = ^tHostEnt;
  tHostEnt = packed record
    H_Name:      ^string;
    H_Alias:     pointer;
{$IFNDEF WIN32}
    H_AddrType:  longint;
    H_Length:    longint;
{$ELSE}
    h_addrtype: Smallint;
    h_length: Smallint;
{$ENDIF}
    H_Addr_List: ^pIn_Addr;
  END;

  pProtoEnt = ^tProtoEnt;
  TProtoEnt = packed record
    p_name:    pChar;     (* official protocol name *)
    p_aliases: ^pChar;   (* alias list *)
    p_proto:   SmallInt;       (* protocol # *)
  end;

  pServEnt = ^tServEnt;
  tServEnt = packed record
    s_name:    pChar;        // official service name
    s_aliases: ^pChar;       // alias list
    s_port:    SmallInt;      // port #
    s_proto:   pChar;        // protocol to use
  END;

// these types are only used in windows version
const
  FD_SETSIZE     =   64;

type
  PFDSet = ^TFDSet;
  TFDSet = packed record
    fd_count: ULONG;
    fd_array: array[0..FD_SETSIZE-1] of ULONG;
  end;

  PTimeVal = ^TTimeVal;
  TTimeVal = packed record
    tv_sec: Longint;
    tv_usec: Longint;
  end;

const
  WSADESCRIPTION_LEN     =   256;
  WSASYS_STATUS_LEN      =   128;

type
  PWSAData = ^TWSAData;
  TWSAData = packed record
    wVersion: Word;
    wHighVersion: Word;
    szDescription: array[0..WSADESCRIPTION_LEN] of Char;
    szSystemStatus: array[0..WSASYS_STATUS_LEN] of Char;
    iMaxSockets: Word;
    iMaxUdpDg: Word;
    lpVendorInfo: PChar;
  end;

(*
** The re-defination of error constants are necessary to avoid conflict with
** standard IBM C Set/2 V1.0 error constants.
**
** All OS/2 SOCKET API error constants are biased by SOCBASEERR from the "normal"
**
*)

const
  SOCBASEERR = 10000;

(*
** OS/2 SOCKET API definitions of regular Microsoft C 6.0 error constants
*)

const
  SOCEPERM = (SOCBASEERR+1);             (* Not owner *)
  SOCESRCH = (SOCBASEERR+3);             (* No such process *)
  SOCEINTR = (SOCBASEERR+4);             (* Interrupted system call *)
  SOCENXIO = (SOCBASEERR+6);             (* No such device or address *)
  SOCEBADF = (SOCBASEERR+9);             (* Bad file number *)
  SOCEACCES = (SOCBASEERR+13);            (* Permission denied *)
  SOCEFAULT = (SOCBASEERR+14);            (* Bad address *)
  SOCEINVAL = (SOCBASEERR+22);            (* Invalid argument *)
  SOCEMFILE = (SOCBASEERR+24);            (* Too many open files *)
  SOCEPIPE = (SOCBASEERR+32);            (* Broken pipe *)

  SOCEOS2ERR = (SOCBASEERR+100);            (* OS/2 Error *)

(*
** OS/2 SOCKET API definitions of regular BSD error constants
*)

const
  SOCEWOULDBLOCK = (SOCBASEERR+35);            (* Operation would block *)
  SOCEINPROGRESS = (SOCBASEERR+36);            (* Operation now in progress *)
  SOCEALREADY = (SOCBASEERR+37);            (* Operation already in progress *)
  SOCENOTSOCK = (SOCBASEERR+38);            (* Socket operation on non-socket *)
  SOCEDESTADDRREQ = (SOCBASEERR+39);            (* Destination address required *)
  SOCEMSGSIZE = (SOCBASEERR+40);            (* Message too long *)
  SOCEPROTOTYPE = (SOCBASEERR+41);            (* Protocol wrong type for socket *)
  SOCENOPROTOOPT = (SOCBASEERR+42);            (* Protocol not available *)
  SOCEPROTONOSUPPORT = (SOCBASEERR+43);            (* Protocol not supported *)
  SOCESOCKTNOSUPPORT = (SOCBASEERR+44);            (* Socket type not supported *)
  SOCEOPNOTSUPP = (SOCBASEERR+45);            (* Operation not supported on socket *)
  SOCEPFNOSUPPORT = (SOCBASEERR+46);            (* Protocol family not supported *)
  SOCEAFNOSUPPORT = (SOCBASEERR+47);            (* Address family not supported by protocol family *)
  SOCEADDRINUSE = (SOCBASEERR+48);            (* Address already in use *)
  SOCEADDRNOTAVAIL = (SOCBASEERR+49);            (* Can't assign requested address *)
  SOCENETDOWN = (SOCBASEERR+50);            (* Network is down *)
  SOCENETUNREACH = (SOCBASEERR+51);            (* Network is unreachable *)
  SOCENETRESET = (SOCBASEERR+52);            (* Network dropped connection on reset *)
  SOCECONNABORTED = (SOCBASEERR+53);            (* Software caused connection abort *)
  SOCECONNRESET = (SOCBASEERR+54);            (* Connection reset by peer *)
  SOCENOBUFS = (SOCBASEERR+55);            (* No buffer space available *)
  SOCEISCONN = (SOCBASEERR+56);            (* Socket is already connected *)
  SOCENOTCONN = (SOCBASEERR+57);            (* Socket is not connected *)
  SOCESHUTDOWN = (SOCBASEERR+58);            (* Can't send after socket shutdown *)
  SOCETOOMANYREFS = (SOCBASEERR+59);            (* Too many references: can't splice *)
  SOCETIMEDOUT = (SOCBASEERR+60);            (* Connection timed out *)
  SOCECONNREFUSED = (SOCBASEERR+61);            (* Connection refused *)
  SOCELOOP = (SOCBASEERR+62);            (* Too many levels of symbolic links *)
  SOCENAMETOOLONG = (SOCBASEERR+63);            (* File name too long *)
  SOCEHOSTDOWN = (SOCBASEERR+64);            (* Host is down *)
  SOCEHOSTUNREACH = (SOCBASEERR+65);            (* No route to host *)
  SOCENOTEMPTY = (SOCBASEERR+66);            (* Directory not empty *)

(*
** OS/2 SOCKET API errors redefined as regular BSD error constants
*)

(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
 IMPLEMENTATION
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)

end. { unit SockDef }
