






          SOCKO
          Client/Server Library
          Version 2.0

          For use with PC-NFS (R) tool kit 2.0 and 4.0 running under a
          PC-NFS (R) v3.5c and up environment, BSD (R) and SysV (R) Unix,
          Including release 3 & 4 compliant systems

          Written By: Jim Dunn and Ron Adkins

          Released to the Public Domain












          _________________
          TABLE OF CONTENTS

          I.        INTRODUCTION
                    INTRODUCTION
                    INTRODUCTION   . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 3

          II.       COMPILATION
                    COMPILATION
                    COMPILATION    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 3

          III.      FUNCTIONS
                    FUNCTIONS
                    FUNCTIONS . . . . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . 4        A.   sockc     . . . . . . . .
          . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
                    B.   socke     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 4
                    C.   socknbio  . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 5
                    D.   socko     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 5
                    E.   sockoa    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 6
                    F.   sockp     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 6
                    G.   sockr     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 7
                    H.   sockrn    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 7
                    I.   sockrx    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 8
                    J.   sockt     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 8






                    K.   sockd     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 9
                    L.   sockw     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 9
                    M.   sockwn    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 10

          IV.  SOURCE CODE
               SOURCE CODE
               SOURCE CODE    . . . . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . 11
                    A.   sockc     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 11
                    B.   socke     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 11
                    C.   socknbio  . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 12
                    D.   socko     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 13
                    E.   sockoa    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 17
                    F.   sockp     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 20
                    G.   sockr     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 21
                    H.   sockrn    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 23
                    I.   sockrx    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 25
                    J.   sockt     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 27
                    K.   sockd     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 27
                    L.   sockw     . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 28
                    M.   sockwn    . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . . . . . . 29


          V.   CREDITS
               CREDITS
               CREDITS   . . . . . . . . . . . . . . . . . . . . . . . . .
          . . . . . . . . . . . 31
          _____________
          INTRODUCTION:


                Socko was designed to provide an easier, more portable
          method of writing client/server programs than the traditional way
          of using Berkeley (R) socket code.  Since Socko was written
          entirely with Microsoft C 6.0 (R) and Berkeley (R) socket
          functions, it can be used on a number of systems including BSD
          (R)  and  SysV (R) Unix.  With a little modification, Socko could
          be incorporated on almost any system with network capability.

               Socko provides the user with a simpler, more portable way of
          writing client/server code by compacting the extensive Berkeley
          (R) socket functions into 12 user friendly functions.  The most
          commonly used functions to write a client/server program with the


                                          2






          Socko library are:  Socko() -- to open a socket connection;
          Sockr() -- to read data from the open socket; Sockw() -- to write
          data to the open socket; Sockc() -- to close an opened socket.
          With these four functions, a simple client/server program can be
          designed.  And, by using the remaining Socko functions later
          described, more extensive client/server programs can be made.

               Socko was originally designed  to be used with PC-NFS (R)
          tool kit version 1.0.  But, later it was upgraded for PC-NFS (R)
          tool kit version 2.0 and 4.0, making the 1.0 version obsolete.
          We feel that Socko can be a great asset to programmers and
          managers who know little about client/server technology and
          Berkeley (R) socket functions.




          ____________
          COMPILATION:


               To compile Socko for the PC using Microsoft C 6.0 (R) and
          PC-NFS (R) tool kit 4.0, simply type "compile {memory model}" at
          the C:> prompt, where {memory model} is the memory model you want
          to compile; small, medium, or large.  Please note that to compile
          Socko for use under PC-NFS (R)  tool kit 2.0, you must edit
          compile.bat and change the /DTK4 to /DTK2 in every compile line.
          To compile Socko while in the Unix environment, use the script
          files designed for your specific system.  Use "comp_bsd.sh" to
          compile under BSD (R) Unix.  Use "comp_sy5.sh" to compile under
          SysV (R) Unix.  And, use "comp_seq.sh" to compile under a SysV
          (R) release 3 or 4 compliant system.  The scripts will compile
          and link together a library called libsocko.a.  You can then link
          this library in with your program and use the functions which
          follow.


          NOTE:     Microsoft C 6.0 (R) is a registered trademark of
          Microsoft Inc.
               PC-NFS (R) is a registered trademark of Sun Microsystems
          Inc.
               SysV (R) is a registered trademark of AT&T Inc.
               All other systems are registered trademarks of their
          respective companies.


          __________
          FUNCTIONS:


               The following functions are included in the Socko library.
          Please note that not all of these functions are needed to create
          a client/server program, but they are there if you need them.





                                          3






          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockc

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function will close the opened socket with the file
          descriptor fd.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockc(int fd);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd - Socket file descriptor.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               Always returns a zero for OK.





          ____
          NAME
          ____
          NAME
          ____
          NAME

               socke

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function places the contents of buf , along with the
          accompanying errno message,   into a global variable called
          sockerrmsg, then returns.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               void socke(char *msg);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               msg  - The address of the message to place into sockerrmsg.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               None.








                                          4






          ____
          NAME
          ____
          NAME
          ____
          NAME

               socknbio

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function modifies the Non-Blocking Input/Output status
          of a socket.


          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int socknbio(int fd, int nbios);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd   - Socket file descriptor
               nbios     - Non-Blocking I/O status (BLOCK or NONBLOCK).
                      BLOCK means that Non-Blocking is turned off.
                      NONBLOCK means that Non-Blocking is turned on.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               A zero if status change was successful, or a -1 if an error
          occurred.








          ____
          NAME
          ____
          NAME
          ____
          NAME

               socko

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function opens a socket connection to the specified
          host.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int socko(char *host, char *service, char *protocol, int
          port, int nbios);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               host      - The address of the host to connect to.
               service        - The service name.



                                          5






               protocol  - The protocol to use on the socket, "tcp" or
          "udp".
               port      - The port number to bind a connection to.
                         - If port is equal to zero, then socko uses the
          port number
                           of the server.
                         - If port is greater that zero, then socko tries
          to bind a
                           connection to that port number.
               nbios          - Non-Blocking I/O status.  (See socknbio)


          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               The number of the open socket descriptor, or a -1 if an
          error occurred.
          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockoa

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function opens a socket on the server, then listens for
          and accepts connections from       clients.  Upon acceptance, the
          function func is called.
                      NOTE:  On Unix machines, this function is
          multitasking, multiuser.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockoa(char *service, char *protocol, void (*func) ());

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               service        - The service name.
               protocol  - The protocol to use on the socket, "tcp" or
          "udp".
               func      - The local function to call when a client
          connects to the
                           server.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               The number of the accepted client socket, or a -1 if an
          error occurred.










                                          6












          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockp


          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function pauses for the specified number of
          milliseconds.
                      NOTE:  When using  this function under SysV Unix, the
          number of milliseconds is rounded
               to the nearest thousand.  (Ex.-- if  1400 milliseconds were
          specified, sockp would pause for                  1000
          milliseconds).

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               void sockp(long d);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               d - The duration in milliseconds to pause for.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               None.
          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockr

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function reads one byte at a time from socket fd into
          ptr up to a new line or until      maxlen characters have been
          read.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockr(int fd, char *ptr, int maxlen);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd        - Socket file descriptor.
               ptr       - Address of character array to read into.
               maxlen    - The maximum number of characters to read into
          ptr.


                                          7







          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               A zero if OK, or a -1 if an error occurred.












          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockrn

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function reads a block of bytes from socket fd into
          bufptr.  Use caution when using    this function.  You must know
          exactly how many bytes of information is waiting on the 
               socket.  Otherwise sockrn may "Lock Up" or return an error.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockrn(int fd, char *bufptr, int toread);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd   - Socket file descriptor.
               bufptr    - Address of character array to read into.
               toread    - The exact number of bytes to read into bufptr.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               The number of bytes read, or a -1 if an error occurred.


          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockrx

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function reads a block of bytes from socket fd into
          bufptr, but only as many as   there are waiting on the socket.
          If toread is greater than the actual number of bytes   available,
          then only the bytes available will be read.



                                          8






          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockrx(int fd, char *bufptr, int toread);


          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd   - Socket file descriptor.
               bufptr    - Address of character array to read into.
               toread    - The maximum number of bytes to try and read into
                bufptr.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               The number of bytes read, or a -1 if an error occurred.














          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockt

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function finds the time value for the host specified.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               unsigned long sockt(char *host);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               host - Pointer to the host from which to receive the time.

          _____
          CALLS
          _____
          CALLS
          _____
          CALLS

               socko()

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               Time value, or a -1 if an error occurred


                                          9







          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockd


          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function finds the date value for the host specified.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               char *sockd(char *host);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               host - Pointer to the host from which to receive the date.

          _____
          CALLS
          _____
          CALLS
          _____
          CALLS

               socko()

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               Date value, or NULL if an error occurred.






          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockw

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function writes a character array one character at a
          time to socket fd, while assuring a     new line.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockw(int fd, char *ptr);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd   - Socket file descriptor.
               ptr  - Address of character array to write.

          _____
          CALLS
          _____
          CALLS
          _____
          CALLS

               sockwn()


                                         10








          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               A zero if OK, or a -1 if an error occurred.


          ____
          NAME
          ____
          NAME
          ____
          NAME

               sockwn

          ___________
          DESCRIPTION
          ___________
          DESCRIPTION
          ___________
          DESCRIPTION

               This function writes a block of bytes to socket fd, but does
          not assure a new line.

          ________
          SYNOPSIS
          ________
          SYNOPSIS
          ________
          SYNOPSIS

               #include "socko.h"
               int sockwn(int fd, char *ptr, int nbytes);

          _________
          ARGUMENTS
          _________
          ARGUMENTS
          _________
          ARGUMENTS

               fd     - Socket file descriptor.
               ptr    - Address of character array to write.
               nbytes - The actual number of bytes from array to write.

          ____________
          RETURN VALUE
          ____________
          RETURN VALUE
          ____________
          RETURN VALUE

               The number of bytes actually written, or a -1 if an error
          occurred.

























                                         11
















          ___________
          SOURCE CODE


               The following source is arranged by alphabetical order.


          _____
          SOCKC
          _____
          SOCKC
          _____
          SOCKC

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifndef UNIX
          # include <io.h>
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #include <sys/socket.h>

          int sockc(fd)
          register int fd;
          {
            shutdown(fd, 2);
            close(fd);
            return 0;
          }










                                         12






          _____
          SOCKE
          _____
          SOCKE
          _____
          SOCKE

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          char *pname = NULL;

          extern int errno;
          extern int sys_nerr;

          extern char *sys_errlist[];

          char *socke_str()
          {
            static char msgstr[256];

            if (errno != 0) {
              if (errno > 0 && errno < sys_nerr)
                sprintf(msgstr, "%s", sys_errlist[errno]);
              else
                sprintf(msgstr, "(errno = %d)", errno);
            } else {
              msgstr[0] = 0;
            }
            return (msgstr);
          }

          char sockerrmsg[513];



          void socke(buf)
          char *buf;
          {
          /*  printf("%s : %s\n", buf, socke_str()); */ /* this is for
          testing only */
            sprintf(sockerrmsg,"%s : %s\n", buf, socke_str());
          }






          ________
          SOCKNBIO
          ________
          SOCKNBIO
          ________
          SOCKNBIO

          _
          .
          _
          .
          _
          .



                                         13







          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          # include <sys/socket.h>
          # include <sys/ioctl.h>

          #ifndef FIONBIO
          # define FIONBIO 1
          #endif

          static int zero = 0;     /* used by ioctl() -> blocking */
          static int one = 1; /* used by ioctl() -> non-blocking */

          int socknbio(fd, nbios)
            int fd, nbios;
          {
            int rc;
            char msg[128];

          #ifndef SEQ
            if (nbios == 0)
          #ifdef TK4
              rc = tk_ioctl(fd, FIONBIO, &zero);  /* blocking */
            else
              rc = tk_ioctl(fd, FIONBIO, &one);   /* non-blocking */
          #else
              rc = ioctl(fd, FIONBIO, &zero);     /* blocking */
            else
              rc = ioctl(fd, FIONBIO, &one); /* non-blocking */
          #endif

            if (rc < 0) {
              sprintf(msg, "socknbio(): can't set socket non-blocking
          status");
              socke(msg);
              return (-1);
            } else {
              return 0;
            }
          #endif
          }





                                         14









          _____
          SOCKO
          _____
          SOCKO
          _____
          SOCKO

          _
          .
          _
          .
          _
          .

          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifndef UNIX
          # include <io.h>
          # include <tklib.h>
          #else
          # include <sys/types.h>
          #endif

          #ifdef SYSV
          # include <arpa/inet.h>
          # include <stropts.h>
          #endif

          #include <sys/socket.h>
          #include <sys/ioctl.h>
          #include <netdb.h>
          #include <netinet/in.h>

          #ifdef UNIX
          # include <sys/time.h>
          # include <errno.h>
          extern int errno;
          #else
          # include <in_addr.h>
          # include <sys/nfs_time.h>
          # include <tk_errno.h>
          #endif

          #ifndef FIONBIO
          # define FIONBIO 1
          #endif

          struct timeval wait_time;
          fd_set rwfds;

          /* library globals; available to calling program, if desired */

          struct sockaddr_in socko_srvr_addr;
          struct servent socko_srvr_info;
          struct hostent socko_host_info;

          /* local globals; available only to this file */


                                         15







          static int zero = 0;     /* used by ioctl() -> blocking */
          static int one = 1; /* used by ioctl() -> non-blocking */

          #ifndef INADDR_NONE
          #define INADDR_NONE 0xffffffff
          #endif

          int socko(host, service, protocol, port, nbios)
            char *host, *service, *protocol;
            int port, nbios;
          {
            char msg[81];
            static int fd = -1;
            int resvport, i, rc;
            unsigned long inaddr;
            struct servent *sp;
            struct hostent *hp;
            struct protoent *pp;

            bzero((char *) &socko_srvr_addr, sizeof(socko_srvr_addr));
            socko_srvr_addr.sin_family = AF_INET;

            if (service != NULL) {
              for (i = 0; i <= strlen(service); i++) { /* remove newlines
          */
                if (service[i] == '\n')
                  service[i] = 0;
              }
              for (i = 0; i <= strlen(protocol); i++) {     /* remove
          newlines */
                if (protocol[i] == '\n')
                protocol[i] = 0;
              }
              if ((sp = getservbyname(service, protocol)) == NULL) {
                sprintf(msg, "socko(): unknown service: %s/%s", service,
          protocol);
                socke(msg);
                return (-1);
              }
              socko_srvr_info = *sp;
              if (port > 0)
                socko_srvr_addr.sin_port = htons(port);
              else
                socko_srvr_addr.sin_port = sp->s_port;
            } else {
              if (port <= 0) {
                sprintf(msg, "socko(): must specify either service or
          port");
                socke(msg);
                return (-2);
              }
              socko_srvr_addr.sin_port = htons(port);
            }


                                         16







            for (i = strlen(host) - 1; i >= 0; i--)    /* remove newlines
          */
              if (host[i] == '\n' || host[i] == '\r')
                host[i] = 0;
            if ((int) (inaddr = inet_addr(host)) != INADDR_NONE) {    /*
          check if dot'd */
              bcopy((char *) &inaddr, (char *) &socko_srvr_addr.sin_addr,
          sizeof(inaddr));
              socko_host_info.h_name = NULL;
            } else {
              if ((hp = gethostbyname(host)) == NULL) {
                sprintf(msg, "socko(): host name error: %s", host);
                socke(msg);
                return (-3);
              }
              socko_host_info = *hp;
              bcopy(hp->h_addr, (char *) &socko_srvr_addr.sin_addr, hp-
          >h_length);
            }

            if (port >= 0) {
              pp = getprotobyname(protocol);
              if (protocol[0] == 't') {
                fd = socket(AF_INET, SOCK_STREAM, (int) pp->p_proto);
              } else {
                fd = socket(AF_INET, SOCK_DGRAM, (int) pp->p_proto);
              }
              if (fd < 0) {
                sprintf(msg, "sockoa(): can't create %s socket", protocol);
                socke(msg);
                return (-4);
              }
            } else {
              if (port < 0) {
                /* resvport = IPPORT_RESERVED - 1;
                if ((fd = rresvport(&resvport)) < 0) {
                  sprintf(msg, "socko(): can't get a reserved port"); */
                  sprintf(msg, "socko(): ressvport() illegally called");
                  socke(msg);
                  return (-5);
              /*  }  */
              }
            }

          #ifndef SEQ
            if (nbios == 0)
          #ifdef TK4
              rc = tk_ioctl(fd, FIONBIO, &zero);  /* blocking */
            else
              rc = tk_ioctl(fd, FIONBIO, &one);   /* non-blocking */
          #else
              rc = ioctl(fd, FIONBIO, &zero);     /* blocking */
            else


                                         17






              rc = ioctl(fd, FIONBIO, &one); /* non-blocking */
          #endif

            if (rc < 0) {
              sprintf(msg, "socko(): can't set socket non-blocking
          status");
              socke(msg);
              close(fd);
              return (-6);
            }
          #endif
            if (connect(fd, (struct sockaddr *) & socko_srvr_addr,
                     sizeof(socko_srvr_addr)) < 0) {
          #ifndef SYSV
              if (errno == EINPROGRESS) {
          #endif

          #ifdef SEQ
              if (errno == EINPROGRESS) {
          #endif

                FD_ZERO(&rwfds);
                FD_SET(fd, &rwfds);
                wait_time.tv_sec = 10;
                wait_time.tv_usec = 0;
                if ((select(32, (fd_set *) 0, &rwfds, (fd_set *) 0,
          &wait_time)) < 1) {
                  sprintf(msg, "socko(): can't connect to server");
                  socke(msg);
                  close(fd);
                  return (-7);
                }
          #ifndef SYSV
              }
              else return(-8);
          #endif

          #ifdef SEQ
              }
              else return(-8);
          #endif

            }
            return (fd);
          }



          ______
          SOCKOA
          ______
          SOCKOA
          ______
          SOCKOA

          _
          .
          _
          .
          _
          .


          #ifdef UNIX


                                         18






          void exit();
          #else
          void exit(int);
          #endif

          void sockoa_child_status();

          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifndef UNIX
          # include <io.h>
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #include <sys/socket.h>
          #include <netdb.h>
          #include <netinet/in.h>
          #include <sys/ioctl.h>
          #include <signal.h>

          #ifdef UNIX
          #ifndef SYSV
          # include <sys/wait.h>
          #endif
          # include <sys/time.h>
          # include <errno.h>
          extern int errno;
          #else
          # include <sys/nfs_time.h>
          # include <tk_errno.h>
          #endif

          struct timeval wait_time;
          fd_set rwfds;

          /* library globals; available to calling program, if desired */

          struct sockaddr_in sock_srvr_addr;
          struct servent sock_srvr_info;
          struct hostent sock_host_info;
          int sockoa_fd = -1;

          /* local globals; not available to calling program */

          static int fd = -1, id = -1;


                                         19







          #ifndef INADDR_NONE
          #define INADDR_NONE 0xffffffff
          #endif

          void sockoa_dead_end()
          {
            if( fd > 0 )
              close(fd);
            if( sockoa_fd > 0 )
              close(sockoa_fd);
            exit(1);
          }

          #ifdef UNIX
          #ifndef SYSV
          void sockoa_child_status()
          {
            union wait status;

            while (wait3(&status, WNOHANG, 0) > 0)
              ;
          }
          #endif
          #endif

          int sockoa(service, protocol, func)
            char *service, *protocol;
            void (*func) ();
          {
            char msg[81];
            unsigned int i, len;
          #ifndef UNIX
            int ch;
          #endif
            struct servent *sp;
            struct protoent *pp;

            signal(SIGINT, sockoa_dead_end);
            signal(SIGTERM, sockoa_dead_end);

            for (i = 0; i <= strlen(service); i++)     /* remove newlines
          */
              if (service[i] == '\n')
                service[i] = 0;
            for (i = 0; i <= strlen(protocol); i++)    /* remove newlines
          */
              if (protocol[i] == '\n')
                protocol[i] = 0;
            if ((sp = getservbyname(service, protocol)) == NULL) {
              sprintf(msg, "sockoa(): unknown service: %s/%s", service,
          protocol);
              socke(msg);
              return (-1);


                                         20






            }
            sock_srvr_addr.sin_addr.s_addr = INADDR_ANY;
            sock_srvr_addr.sin_port = sp->s_port;

            pp = getprotobyname(protocol);
            if (protocol[0] == 't') {
              fd = socket(AF_INET, SOCK_STREAM, (int) pp->p_proto);
            } else {
              fd = socket(AF_INET, SOCK_DGRAM, (int) pp->p_proto);
            }
            if (fd < 0) {
              sprintf(msg, "sockoa(): can't create %s socket", protocol);
              socke(msg);
              return (-1);
            }
            if (bind(fd, (struct sockaddr *) & sock_srvr_addr,
                 sizeof(sock_srvr_addr)) < 0) {
              sprintf(msg, "sockoa(): can't connect to server");
              socke(msg);
              close(fd);
              return (-1);
            }
          #ifdef UNIX
          #ifdef SYSV
            signal(SIGCLD, sockoa_child_status);
          #else
            signal(SIGCHLD, sockoa_child_status);
          #endif    /* sysv */
          #endif    /* unix */

            if (listen(fd, 5) < 0) {
              sprintf(msg, "sockoa(): error received from listen() in
          server");
              socke(msg);
              sockoa_dead_end();
            }
            while (1) {
              len = sizeof(sock_srvr_addr);
              if ((sockoa_fd = accept(fd, (struct sockaddr *) &
          sock_srvr_addr, &len)) < 0) {
          #ifndef UNIX
                if( kbhit() ) {
                  ch = getch();
                  if( ch == 27 ) {
                    sockoa_dead_end();
                  }
                }
          #endif
                if( errno == EINTR )
                  continue;
                sprintf(msg, "sockoa(): error received from accept() in
          server");
                socke(msg);
                sockoa_dead_end();


                                         21






              }
          #ifdef UNIX
              id = fork();
              if( id == 0 ) { /* the child */
                close(fd);
          #endif
                (*func)();          /* these two lines alone are used */
                sockoa_dead_end();  /* by msdos instead of forking */
          #ifdef UNIX
              } else {   /* the parent */
                close(sockoa_fd);
              }
          #endif
            }
          }






          _____
          SOCKP
          _____
          SOCKP
          _____
          SOCKP

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #ifdef SYSV
          #ifdef SEQ
          # include <time.h>
          #else
          # include <sys/time.h>
          #endif
          #else
          # include <sys/timeb.h>
          #endif

          void sockp(d)
            long d;
          {
          #ifdef SYSV
            struct tm *itimer;
            time_t t;


                                         22






            long t1, t2;

            t = time(NULL);
            itimer = localtime(&t);
            t1 = itimer->tm_sec * 1000;
            t2 = itimer->tm_sec * 1000 + d;

            while (t1 < t2) {
              t = time(NULL);
              itimer = localtime(&t);
              t1 = itimer->tm_sec * 1000;
            }
          #else
            struct timeb tstruct;
            long t1, t2;

            ftime(&tstruct);
            t1 = tstruct.time * 1000 + tstruct.millitm;
            t2 = t1;

            while (t1 + d > t2) {
              ftime(&tstruct);
              t2 = tstruct.time * 1000 + tstruct.millitm;
            }
          #endif
          }






          _____
          SOCKR
          _____
          SOCKR
          _____
          SOCKR

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/time.h>
          #else
          # include <io.h>
          # include <sys/nfs_time.h>
          #endif

          #ifdef UNIX
          #include <sys/types.h>
          #include <errno.h>
          extern int errno;


                                         23






          #else
          #include <tklib.h>
          #include <tk_errno.h>
          #endif

          #include <sys/socket.h>
          #include <netdb.h>
          #include <netinet/in.h>

          struct timeval wait_time;
          fd_set rwfds;

          int sockr(fd, ptr, maxlen)
            register int fd;
            register char *ptr;
            register int maxlen;
          {
            int n, rc;
            char c;
            n = 0;
            for (;;) {
              if (n > maxlen)
                break;
              if ((rc = recv(fd, &c, 1, 0)) == 1) {
                ptr[n] = c;
                n++;
                if (c == '\n')
                  break;
              } else if (rc < 0) { /* No byte read this round */
          #ifndef SYSV
                if (errno == EWOULDBLOCK) {
          #endif

          #ifdef SEQ
                if (errno == EWOULDBLOCK) {
          #endif

                  FD_ZERO(&rwfds);
                  FD_SET(fd, &rwfds);
                  wait_time.tv_sec = 25;
                  wait_time.tv_usec = 0;
                  if ((select(32, &rwfds, (fd_set*) 0, (fd_set *) 0,
          &wait_time)) < 1)
                    return(-1);
          #ifndef SYSV
                } else
                  return(-1);
          #endif

          #ifdef SEQ
                } else
                  return(-1);
          #endif



                                         24






              } else {   /* rc == 0, means socket closed */
                *ptr = 0;
                return (-1);  /* return a -1 for socket error */
              }
            }
            ptr[n] = 0;

            if( ptr[strlen(ptr)-1] == '\n' )
                ptr[strlen(ptr)-1] = 0;   /* stripping newline */
            if( ptr[strlen(ptr)-1] == '\r' )
                ptr[strlen(ptr)-1] = 0;   /* stripping carriage return */
            if( ptr[strlen(ptr)-1] == '\n' )
                ptr[strlen(ptr)-1] = 0;   /* stripping newline */
            strcat(ptr, "\n");     /* assure a newline */

            return (0);
          }





          ______
          SOCKRN
          ______
          SOCKRN
          ______
          SOCKRN

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #include <sys/socket.h>

          #ifdef UNIX
          # include <sys/time.h>
          # include <errno.h>
          extern int errno;
          #else
          # include <io.h>
          # include <sys/nfs_time.h>
          # include <tk_errno.h>
          #endif

          struct timeval wait_time;
          fd_set rwfds;



                                         25






          int sockrn(fd, bufptr, toread)
            register int fd;
            register char *bufptr;
            register int toread;
          {
            int nread;
            int total = 0;
            while (toread > 0) {
              nread = recv(fd, bufptr, toread, 0);
              if (nread > 0) {
                bufptr += nread;
                total += nread;
                toread -= nread;
              }
              else if (nread < 0) {
          #ifndef SYSV
                if (errno == EWOULDBLOCK) {
          #endif

          #ifdef SEQ
                if (errno == EWOULDBLOCK) {
          #endif

                  FD_ZERO(&rwfds);
                  FD_SET(fd, &rwfds);
                  wait_time.tv_sec = 25;
                  wait_time.tv_usec = 0;
                  if ((select(32, &rwfds, (fd_set*) 0, (fd_set *) 0,
          &wait_time)) < 1)
                    return(-1);
          #ifndef SYSV
                } else
                  return(-1);
          #endif

          #ifdef SEQ
                } else
                  return(-1);
          #endif

              } else
                return(-1);
            }
            *bufptr = 0;
            return (total);
          }

          ______
          SOCKRX
          ______
          SOCKRX
          ______
          SOCKRX

          _
          .
          _
          .
          _
          .


          #include <stdio.h>



                                         26






          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #include <sys/socket.h>

          #ifdef UNIX
          # include <sys/time.h>
          # include <errno.h>
          extern int errno;
          #else
          # include <io.h>
          # include <sys/nfs_time.h>
          # include <tk_errno.h>
          #endif

          struct timeval wait_time;
          fd_set rwfds;

          int sockrx(fd, bufptr, toread)
            register int fd;
            register char *bufptr;
            register int toread;
          {
            int togo = 0;
            int nread = 0;
            int total = 0;

            for(;;) {
              togo = recv(fd,bufptr,toread,MSG_PEEK);
              if (togo >= 0)
                break;
              else {
          #ifndef SYSV
                if (errno == EWOULDBLOCK) {
          #endif

          #ifdef SEQ
                if (errno == EWOULDBLOCK) {
          #endif
                  FD_ZERO(&rwfds);
                  FD_SET(fd, &rwfds);
                  wait_time.tv_sec = 25;
                  wait_time.tv_usec = 0;
                  if ((select(32, &rwfds, (fd_set*) 0, (fd_set *) 0,
          &wait_time)) < 1)
                    return(-1);
          #ifndef SYSV


                                         27






                }
                else
                  return(-1);
          #endif

          #ifdef SEQ
                }
                else
                  return(-1);
          #endif

              }
            }
            while(togo > 0) {
              nread = recv(fd, bufptr, togo, 0);
              if (nread > 0) {
                bufptr += nread;
                togo -= nread;
                total += nread;
              }
              else if (nread < 0) {
          #ifndef SYSV
                if (errno == EWOULDBLOCK) {
          #endif

          #ifdef SEQ
                if (errno == EWOULDBLOCK) {
          #endif
                  FD_ZERO(&rwfds);
                  FD_SET(fd, &rwfds);
                  wait_time.tv_sec = 25;
                  wait_time.tv_usec = 0;
                  if ((select(32, &rwfds, (fd_set*) 0, (fd_set *) 0,
          &wait_time)) < 1)
                    return(-1);
          #ifndef SYSV
                }
                else
                  return(-1);
          #endif

          #ifdef SEQ
                }
                else
                  return(-1);
          #endif
              } else {
                *bufptr = 0;
                return(-1);
              }
            }
            *bufptr = 0;
            return (total);
          }


                                         28











          ________________
          SOCKT  &   SOCKD
          ________________
          SOCKT  &   SOCKD
          ________________
          SOCKT  &   SOCKD

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          #else
          # include <tklib.h>
          #endif

          #include <sys/socket.h>

          extern int errno;

          #define MAXLINE 512
          #define TVAL_SIZE 4

          unsigned long sockt(host)
            char *host;
          {
            int fd, i;
            unsigned long temptime;

            if ((fd = socko(host, "time", 0, 1)) < 0) {
              socke("socko(): error in sockt()");
              return 0L;
            }
            i = sockrn(fd, (char *) &temptime, TVAL_SIZE);
            sockc(fd);
            if (i != TVAL_SIZE) {
              socke("sockrn(): short error in sockt()");
              return 0L;
            } else {
              return (ntohl(temptime));
            }
          }

          char *sockd(host)
            char *host;
          {
            int fd;
            static char buff[MAXLINE];


                                         29







            if ((fd = socko(host, "daytime", 0, 1)) < 0) {
              socke("socko(): error in sockd()");
              return NULL;
            }
            if (sockr(fd, buff, MAXLINE) < 0) {
              socke("sockr(): error in sockd()");
              return NULL;
            }
            for (fd = strlen(buff); fd >= 0; fd--)
              if (buff[fd] == '\n')
                buff[fd] = 0;
            return (buff);
          }





          _____
          SOCKW
          _____
          SOCKW
          _____
          SOCKW

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #include <string.h>

          int sockw(fd, ptr)
            register int fd;
            register char *ptr;
          {
            int nbytes, tbytes;

            tbytes = strlen(ptr);
            for (nbytes = 0; nbytes <= tbytes; nbytes++) {
              if (ptr[nbytes] == '\n')  /* looking for a newline */
                ptr[nbytes] = 0;
              if (ptr[nbytes] == '\r')  /* looking for a return */
                ptr[nbytes] = 0;
              if (ptr[nbytes] == 0)     /* or a NULL */
                break;
            }
            strcat(ptr, "\n");     /* assuring the newline */
            nbytes = strlen(ptr);
            if (sockwn(fd, ptr, nbytes) == nbytes)
              return (0);
            else
              return (-1);
          }


                                         30







          ______
          SOCKWN
          ______
          SOCKWN
          ______
          SOCKWN

          _
          .
          _
          .
          _
          .


          #include <stdio.h>

          #ifdef SYSV
          # include "bcopy.h"
          #endif

          #ifdef UNIX
          # include <sys/types.h>
          # include <sys/time.h>
          # include <errno.h>
          extern int errno;
          #else
          # include <tklib.h>
          # include <io.h>
          # include <sys/nfs_time.h>
          # include <tk_errno.h>
          #endif

          #include <sys/socket.h>

          struct timeval wait_time;
          fd_set rwfds;

          int sockwn(fd, ptr, nbytes)
            register int fd;
            register char *ptr;
            register int nbytes;
          {
            int nleft, nwritten;
            nleft = nbytes;

            while (nleft > 0) {
              nwritten = send(fd, ptr, nleft, 0);
              if (nwritten < 0) {
          #ifndef SYSV
                if (errno == EWOULDBLOCK) {
          #endif

          #ifdef SEQ
                if (errno == EWOULDBLOCK) {
          #endif
                  FD_ZERO(&rwfds);
                  FD_SET(fd, &rwfds);
                  wait_time.tv_sec = 25;
                  wait_time.tv_usec = 0;
                  if ((select(32, (fd_set*) 0, &rwfds, (fd_set *) 0,
          &wait_time)) < 1)
                    return(-1);


                                         31






          #ifndef SYSV
                } else
                  return(-1);
          #endif

          #ifdef SEQ
                } else
                  return(-1);
          #endif
              }
              else if (nwritten == 0)
                break;
              else {
                nleft -= nwritten;
                ptr += nwritten;
              }
            }
            return (nbytes - nleft);
          }





































                                         32








          _______
          CREDITS



               The Socko library of client/server functions was written
          originally for Microsoft C 6.0 (R)    Socko was written by Jim
          Dunn and Ron Adkins and has been tested on an IBM PC compatible
          computer with PC-NFS (R) toolk kit 4.0 running under a PC-NFS (R)
          v3.5c environment,  and on the UNIX system with both BSD (R) and
          SysV (R) compliant systems.  If you use Socko, please note that
          it is at your own risk.  We feel that Socko is a highly stable
          library of functions with very few flaws,  but we encouage
          comments and suggestions.  If you have any that you would like to
          share, please E-Mail me, Ron Adkins, at:   radkins@dsac.dla.mil.








































                                         33
