home *** CD-ROM | disk | FTP | other *** search
- From: mat@zeus.opt-sci.arizona.edu (Mat Watson)
- Newsgroups: alt.sources
- Subject: Simple Socket Library
- Message-ID: <MAT.91Apr29003829@zeus.math.arizona.edu>
- Date: 29 Apr 91 07:38:30 GMT
-
- ***** Simple Socket Library *******
- by Mat Watson and Hubert Bartels
-
- The Simple Socket library is intended to simplify programming with BSD
- sockets, by providing a set of functions which mimic the stdio library.
- The basic data type used by the library is the SOCKET,
- which is analogous to the stdio FILE data type. Here's a comparison
- of some code fragments to illustrate the similarities:
-
- --Normal file IO-- --Using Simple Sockets--
- #include <stdio.h> #include <ss.h>
- ... ...
- FILE *fp; SOCKET *sp;
- ... ...
- fp = fopen("foobar.dat","r"); sp = ConnectSock("whereami.edu",4010)
- ... ...
- fgets( buffer, 99, fp); SockGets( buffer, 99, sp);
-
- The calls which open and close the sockets themselves hide many of the
- gory details associated with using sockets, and provide a more natural
- interface. The call to ConnectSock() above takes two arguments: a
- host name, and a port number. Which is a good deal simpler than the
- series of steps one normally takes to establish a connection using
- standard system calls. As is the case with most other routines that
- simplify a complicated process, the Simple Socket Library makes
- certain assumptions about how one wishes to use sockets to
- communicate.
-
- This library assumes communications using 'streams' as opposed to
- datagrams, as they are quite similar to the stdio 'streams'. In
- addition, the library does not use ioctl() to modify socket
- characteristics. So if you want to make the sockets non blocking (for
- example), you'll have to modify the library code ( or this
- functionality could probably be added later ). Instead, sockets
- should be checked to see if they are ready to be accessed before
- trying to read from one.
-
- Since I don't have the time to write a bonafide manual, I put together
- some test/example programs that should be looked over. The file named
- Testing explains how to use the test programs. I also wrote the file
- named Notes, which gives a man page like synopsis and a short
- description for the library routines. The file named Install has
- instructions for building the library.
-
- Much of the code is based on a version of the stdio library written by
- Hubert Bartels. Without that code as a basis, this library probably
- wouldn't be here now. Thanks Hubert.
-
- If you find the code useful, have any constructive criticism, bug
- fixes, or suggestions for improvement, send them to me (Mat). I'm
- finishing up my dissertation, so don't be surprised if I'm a bit slow
- in replying :-).
-
- This code is know to run on a: Sun3/160, Sparc 2, Data General Aviion,
- and IBM risc workstation. It compiled on an ATT 3b2, but didn't
- run too well at all.
-
- --Mat 4/29/91
-
- Authors:
- Mat Watson mat@zeus.opt-sci.arizona.edu
- and
- Hubert Bartels hgb@catalina.opt-sci.arizona.edu
-
- ------------------------------- Cut Here -------------------------
- #!/bin/sh
- # shar: Shell Archiver (v1.22)
- #
- # Run the following text with /bin/sh to create:
- # README
- # Makefile
- # Notes
- # Testing
- # Install
- # ss.c
- # ss.base.h
- # ss.sun.h
- # ss.ibm.h
- # ss.3b2.h
- # test.h
- # stdlib.h
- # server1.c
- # client1.c
- # server2.c
- # client2.c
- # server3.c
- # client3.c
- #
- sed 's/^X//' << 'SHAR_EOF' > README &&
- X***** Simple Socket Library *******
- Xby Mat Watson and Hubert Bartels
- X
- XThe Simple Socket library is intended to simplify programming with BSD
- Xsockets, by providing a set of functions which mimic the stdio library.
- XThe basic data type used by the library is the SOCKET,
- Xwhich is analogous to the stdio FILE data type. Here's a comparison
- Xof some code fragments to illustrate the similarities:
- X
- X--Normal file IO-- --Using Simple Sockets--
- X#include <stdio.h> #include <ss.h>
- X... ...
- XFILE *fp; SOCKET *sp;
- X... ...
- Xfp = fopen("foobar.dat","r"); sp = ConnectSock("whereami.edu",4010)
- X... ...
- Xfgets( buffer, 99, fp); SockGets( buffer, 99, sp);
- X
- XThe calls which open and close the sockets themselves hide many of the
- Xgory details associated with using sockets, and provide a more natural
- Xinterface. The call to ConnectSock() above takes two arguments: a
- Xhost name, and a port number. Which is a good deal simpler than the
- Xseries of steps one normally takes to establish a connection using
- Xstandard system calls. As is the case with most other routines that
- Xsimplify a complicated process, the Simple Socket Library makes
- Xcertain assumptions about how one wishes to use sockets to
- Xcommunicate.
- X
- XThis library assumes communications using 'streams' as opposed to
- Xdatagrams, as they are quite similar to the stdio 'streams'. In
- Xaddition, the library does not use ioctl() to modify socket
- Xcharacteristics. So if you want to make the sockets non blocking (for
- Xexample), you'll have to modify the library code ( or this
- Xfunctionality could probably be added later ). Instead, sockets
- Xshould be checked to see if they are ready to be accessed before
- Xtrying to read from one.
- X
- XSince I don't have the time to write a bonafide manual, I put together
- Xsome test/example programs that should be looked over. The file named
- XTesting explains how to use the test programs. I also wrote the file
- Xnamed Notes, which gives a man page like synopsis and a short
- Xdescription for the library routines. The file named Install has
- Xinstructions for building the library.
- X
- XMuch of the code is based on a version of the stdio library written by
- XHubert Bartels. Without that code as a basis, this library probably
- Xwouldn't be here now. Thanks Hubert.
- X
- XIf you find the code useful, have any constructive criticism, bug
- Xfixes, or suggestions for improvement, send them to me (Mat). I'm
- Xfinishing up my dissertation, so don't be surprised if I'm a bit slow
- Xin replying :-).
- X
- XThis code is know to run on a: Sun3/160, Sparc 2, Data General Aviion,
- Xand IBM risc workstation. It compiled on an ATT 3b2, but didn't
- Xrun too well at all.
- X
- X--Mat 4/29/90
- X
- XAuthors:
- XMat Watson mat@zeus.opt-sci.arizona.edu
- Xand
- XHubert Bartels hgb@catalina.opt-sci.arizona.edu
- X
- X
- SHAR_EOF
- chmod 0775 README || echo "restore of README fails"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X# Makefile
- XVERSION = 1.0
- XPATCHLEVEL = 0
- X
- X# Make sure you create the directories that libss.a and ss.h
- X# will get copied to.
- X# The directory where the file libss.a will get copied to on installation.
- XINSTALL_LIB_DIR = /usr/local/lib/here
- X# The directory where the file ss.h will get copied to on installation.
- XINSTALL_INC_DIR = /usr/local/include
- X
- X# Uncomment these lines to compile on a 3B2
- X#DEFINES =
- X#LIBS = -lss -lnet -lnsl_s
- X#INCLUDEDIRS = -I/usr/netinclude
- X#HEADERFILE = ss.3b2.h
- X
- X# Uncomment the following lines for a Sun3 or Sparc.
- XDEFINES = -DVerbose_Errors
- XLIBS = -lss
- XINCLUDEDIRS =
- XHEADERFILE = ss.sun.h
- X
- X# Uncomment the following lines for an Aviion.
- X#DEFINES = -DVerbose_Errors -D_BSD_SOURCE # -D__STDC__
- X#LIBS = -lss
- X#INCLUDEDIRS =
- X#HEADERFILE = ss.sun.h
- X
- X# Uncomment the following lines for an IBM risc workstation.
- X#DEFINES = -DVerbose_Errors
- X#LIBS = -lss
- X#INCLUDEDIRS =
- X#HEADERFILE = ss.ibm.h
- X
- X# gcc compiler options
- X#CC = gcc
- X#CFLAGS = -g $(DEFINES) $(INCLUDEDIRS) #-traditional
- X
- X#CC = cc
- X#CFLAGS = -g $(DEFINES) $(INCLUDEDIRS)
- X
- XOBJS = ss.o
- X
- XCFILES = ss.c
- X
- XMISCFILES = README Makefile Notes Testing Install
- X
- XHFILES = ss.base.h ss.sun.h ss.ibm.h ss.3b2.h test.h stdlib.h
- X
- XDEMOFILES = server1.c client1.c server2.c client2.c server3.c client3.c
- X
- XARCHIVEFILES = $(MISCFILES) $(CFILES) $(HFILES) $(DEMOFILES)
- X
- X.c.o:
- X $(CC) -c $(CFLAGS) $<
- X
- Xall: libss.a client1 server1 client2 server2 client3 server3
- X
- Xlibss.a: ss.h $(OBJS)
- X ar rcv libss.a $(OBJS)
- X ranlib libss.a
- X
- Xss.h: ss.base.h $(HEADERFILE)
- X cat $(HEADERFILE) ss.base.h > ss.h
- X
- X$(OBJS): ss.h
- X
- Xinstall:
- X cp libss.a $(INSTALL_LIB_DIR)
- X cp ss.h $(INSTALL_INC_DIR)
- X
- Xtar:
- X tar cf - $(ARCHIVEFILES) | compress > ss-$(VERSION).tar.Z
- Xshar:
- X xshar $(ARCHIVEFILES) > ss-$(VERSION).shar
- X
- Xclean:
- X rm *.o core
- X
- Xrealclean: clean
- X rm server1 server2 server3 client1 client2 client3 libss.a
- Xlint:
- X lint $(CFILES) $(DEFINES)
- X
- Xserver1: server1.o libss.a
- X $(CC) server1.o -L. $(LIBS) -o server1
- X
- Xclient1: client1.o libss.a
- X $(CC) client1.o -L. $(LIBS) -o client1
- X
- Xserver2: server2.o libss.a
- X $(CC) server2.o -lss -L. -o server2
- X
- Xclient2: client1.o libss.a
- X $(CC) client1.o -lss -L. -o client2
- X
- Xserver3: server3.o libss.a
- X $(CC) server3.o -lss -L. -o server3
- X
- Xclient3: client3.o libss.a
- X $(CC) client3.o -lss -L. -o client3
- X
- SHAR_EOF
- chmod 0775 Makefile || echo "restore of Makefile fails"
- sed 's/^X//' << 'SHAR_EOF' > Notes &&
- X######## Commands for opening and closing sockets ###########
- X
- XSocket * ServerSock( int port_number )
- X
- XOpens a socket on port number 'port_number' on the machine that the
- Xserver program is running on. Returns a pointer to an open socket
- Xthat clients may use to connect to. If an error occurs, SeverSock
- Xreturns SS_NULL.
- X
- XSOCKET * ConnectSock( char * hostname, int port_number )
- X
- XAllows a client program to connect to a socket on port 'port_number'
- Xon system 'hostname'. Returns a pointer to an open socket which the
- Xclient program can use to communicate with the server program. If the
- Xcommand fails for any reason, it returns SS_NULL.
- X
- XSOCKET * AcceptSock( SOCKET * server_socket )
- X
- XUses the accept() system call to accept a connect request from a
- Xclient. The variable 'server_socket' must point to the socket opened
- Xby the server program using the ServerSock() command. Returns a
- Xpointer to an open socket that the server program may use to
- Xcommunicate with the client program. AcceptSock() blocks if there are
- Xno connection requests pending on the server socket. If this command
- Xfails for any reason, it returns SS_NULL.
- X
- Xint SockClose( SOCKET * sp)
- X
- XCloses the socket pointed to by 'sp', and performs some internal
- Xhousecleaning. Returns 0 if successful, otherwise returns SS_EOF.
- X
- X######## Commands for reading from and writing to sockets ########
- XMost of these commands are intended to behave similarly to their stdio
- Xnamesakes; replace FILE in your man pages with SOCKET and you'll
- Xhave a pretty good description of what these routines do. For example:
- XSockPuts() behaves similarly to the stdio function fputs().
- X
- Xint SockGetc( SOCKET * sp )
- X
- XReturns the next character (byte) to be input from the socket 'sp'.
- X
- Xint SockPutc( char c, SOCKET * sp )
- X
- XWrites the character 'c' to the socket 'sp'. Returns the character
- Xwritten.
- X
- Xint SockWrites( char * string, SOCKET * sp )
- Xint SockPuts( char * string, SOCKET * sp )
- X
- XThese functions write the string 'string' to the socket 'sp'.
- XSockPuts returns the value of the last character written to the buffer
- Xif successful, otherwise it returns SS_EOF. SockWrites returns 0 if
- Xsuccessful, otherwise returns SS_EOF. SockPuts buffers it's output,
- Xwhile SockWrites issues the SockFlush() command on 'sp' to force
- Xcharacters in 'string' to be sent.
- X
- Xchar * SockGets( char * buffer, int nbytes, SOCKET * sp )
- X
- XReads characters from the socket 'sp' into 'buffer' until nbytes have
- Xbeen read, a newline character is read, or an end of file is reached.
- XIf the end of file is reached SockGets returns SS_EOF, otherwise it
- Xreturns 'buffer'.
- X
- Xint SockFlush( SOCKET * sp)
- X
- XForces any buffered data in 'sp' to be sent. Returns 0 on success,
- Xand SS_EOF on failure.
- X
- X################ Checking sockets ###############
- XThese routines are built around the select() system call, and are
- Xused to check for sockets being ready for reading and writing,
- Xor to wait for an event to occur ( like the arival of data from
- Xanother machine ).
- X
- Xint SockSelect( double timeval, char * flag )
- X
- XThis function performs a select() system call on all open sockets.
- XSockSelect() returns the number of sockets which select() found to be
- Xready. To examine the state of a particular socket after calling
- XSockSelect() you must use one of: IsReadSet(), IsWriteSet(), or
- XIsExceptSet(). The select call will block for 'timeval' seconds if
- Xtimeval is positive. If 'timeval' is negative, then the select call
- Xwill block indefinitely until at least one of the open sockets is
- Xready. The variable 'flag' is used to determine what the select()
- Xwill check for:
- X
- X 'flag' select() checks for
- X ----- ------------------
- X "r" socket ready to be read from.
- X "w" socket ready to be written to.
- X "e" socket has exceptional condition pending.
- X
- XAny combination of the set {r,w,e} may be used in any order. For
- Xexample: flag = "er", will cause select() to check for sockets ready
- Xto be read from or having exceptional conditions pending.
- X
- Xint IsWriteSet( SOCKET * sp )
- Xint IsReadSet( SOCKET * sp )
- Xint IsExceptSet( SOCKET * sp )
- X
- XThese functions check a particular socket to see it is ready for
- Xreading, writing, or has an exceptional condition pending. If the
- Xsocket is ready, the functions return 1, otherwise they return 0.
- XThese functions use information obtained during the last SockSelect()
- Xcall.
- X
- Xint SockIsRead( SOCKET * sp )
- Xint SockIsWrite( SOCKET * sp )
- X
- XThese functions combine the select() system call and FD_ISSET() macro,
- Xand are used to check whether a socket is ready for reading or
- Xwriting. If the socket is ready the functions return 1, otherwise
- Xthey return 0. These functions have no timeval parameter (see
- XSockSelect()), and return immediately.
- X
- SHAR_EOF
- chmod 0644 Notes || echo "restore of Notes fails"
- sed 's/^X//' << 'SHAR_EOF' > Testing &&
- XSeveral test programs have been provided which, in addition to making
- Xsure the code works, serve as examples of how to use the library
- Xroutines.
- X
- XThe test programs are set up to work in pairs; client1 works with
- Xserver1, client2 works with server2 and so on.
- X
- XTesting is most easily done on a windowing system. Open a window,
- Xand start up a server program:
- X% server1
- XThen open another window, and start up a client program:
- X% client1
- X
- XTest program descriptions:
- X
- Xclient1/server1 - server1 waits for a client1 to connect and prints
- X out any and all input it recieve from the client. Once the
- X client disconnects the server waits for another connection.
- X Client1 connects to the server, and accepts input from the
- X standard input which it sends to the server. Upon receipt
- X of an EOF (^D) client1 stops and says goodbye.
- X
- Xclient2/server2 - server2 waits a short while for a client to connect.
- X If no client attempts a connection, the server goes off and
- X does something else, and then waits again. If a client connects,
- X then server2 behaves the same as server1. Client2 is identical
- X to client1.
- X
- Xclient3/server3 - Server3 is able to multiplex clients. Whenever one
- X of the clients is ready for reading, the server reads a single
- X line, and then waits again. Client3 requires no user input;
- X it carries on a trivial conversation with the server. I found
- X this command to be usefull for starting several client3 programs:
- X % sleep 6 ; ( client3 & client3 & client3 & )
- X The command waits six seconds ( giving me time to bring up the
- X window I was running the server in ), and then starts three client3
- X programs in parallel.
- SHAR_EOF
- chmod 0644 Testing || echo "restore of Testing fails"
- sed 's/^X//' << 'SHAR_EOF' > Install &&
- XTo build the Simple Socket Library:
- X
- X1. Edit the Makefile.
- X
- XYou will need to set the install directories, and uncomment the
- Xdefines that go along with your machine.
- X
- X2. Edit test.h
- X
- XYou will need to set the machine name and port number that you
- Xwant the test programs to use.
- X
- X3. type % make
- X
- XTakes about 3 minutes on my sun3 to build the library and test
- Xprograms.
- X
- X4. Run the test programs. See the file named Testing for instructions
- Xon how to do this.
- X
- X5. If your happy with what you see, then go ahead and install
- Xthe library and header file. Make sure that you create the directories
- Xyou named at the top of the Makefile.
- X
- Xmake install
- X
- X6. Send problems, fixes, and comments to: mat@zues.opt-sci.arizona.edu
- X
- XI can't promise to fix problems associated with porting to new machines,
- Xas I've already ported the code to all the machines that I know anything
- Xat all about.
- X
- X--Mat
- SHAR_EOF
- chmod 0644 Install || echo "restore of Install fails"
- sed 's/^X//' << 'SHAR_EOF' > ss.c &&
- X/* Simple Socket Libary
- X Written by Mat Watson and Hubert Bartels. 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X
- X#include "ss.h"
- X
- X/* #include "private_globals.h" */
- X/* #include <signal.h> */
- X
- Xint ss_server_flag;
- Xint ss_client_flag;
- Xint ss_init_flag=0;
- XSOCKARRAY ss_sockbuff;
- Xint max_sd; /* this variable is a private global */
- X
- Xchar *malloc();
- X
- XSOCKET *AcceptSock( ssp )
- XSOCKET *ssp; /* Server Socket Pointer */
- X{
- X SOCKET *csp; /* Client Socket Pointer */
- X struct sockaddr *adrp; /* Address Poiner */
- X int *adrlen; /* Address Length */
- X int csd; /* Client Socket Descriptor */
- X
- X if( !(ss_sockbuff.n_sockets < MaxSockets) )
- X return (SOCKET *) SS_NULL;
- X
- X /* Allocate space for the client's socket structure */
- X csp = (SOCKET *)malloc( sizeof( SOCKET ));
- X
- X if( !csp )
- X sserror("AcceptSock: malloc()",EXIT);
- X
- X csp->_rcnt = 0;
- X csp->_rptr = SS_NULL;
- X csp->_rbase = SS_NULL;
- X csp->_wcnt = 0;
- X csp->_wptr = SS_NULL;
- X csp->_wbase = SS_NULL;
- X csp->_flag = 0;
- X
- X adrp = (struct sockaddr *)0;
- X adrlen = (int *)0;
- X
- X csd = accept( ssp->sd, adrp, adrlen );
- X if( csd < 0 ) {
- X#ifdef Verbose_Errors
- X sserror("AcceptSock: accept()",CONT);
- X#endif
- X return SS_NULL;
- X }
- X
- X /* Set the value of the maximum socket descriptor used so far */
- X max_sd = csd >= max_sd ? csd : max_sd;
- X
- X csp->sd = csd;
- X
- X AddSock( csp, &ss_sockbuff );
- X
- X /* Return a pointer to the client socket */
- X return csp;
- X}
- X
- Xvoid AddSock( sp, sap )
- XSOCKET *sp;
- XSOCKARRAY *sap;
- X{
- X int n;
- X n = sap->n_sockets;
- X sap->n_sockets++;
- X sap->spa[n] = sp;
- X return;
- X}
- X
- XSOCKET *ConnectSock( hostname, port_number )
- Xchar *hostname;
- Xunsigned port_number;
- X{
- X SOCKET *sp;
- X struct hostent *hep;
- X struct sockaddr *adrp;
- X int adrlen;
- X int result;
- X
- X SockInit( 'c' );
- X
- X sp = (SOCKET *) malloc( sizeof( SOCKET ) );
- X
- X if( !sp ) {
- X#ifdef Verbose_Errors
- X sserror("ConnectSock: malloc()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X sp->_rcnt = 0;
- X sp->_rptr = SS_NULL;
- X sp->_rbase = SS_NULL;
- X sp->_wcnt = 0;
- X sp->_wptr = SS_NULL;
- X sp->_wbase = SS_NULL;
- X sp->_flag = 0;
- X
- X AddSock( sp, &ss_sockbuff );
- X
- X hep = gethostbyname( hostname );
- X if( hep == (struct hostent *)0 ) {
- X#ifdef Verbose_Errors
- X perror("ConnectSock: gethostbyname()");
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X bcopy( (char *)(hep->h_addr), (char *)&(sp->addr.sin_addr), hep->h_length );
- X
- X sp->addr.sin_family = AF_INET;
- X sp->addr.sin_port = htons( (u_short)port_number );
- X sp->sd = socket( AF_INET, SOCK_STREAM, 0 );
- X if( sp->sd < 0 ) {
- X#ifdef Verbos_Errors
- X sserror("ConnectSock: socket()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X adrp = (struct sockaddr *) &(sp->addr);
- X adrlen = sizeof( sp->addr );
- X
- X result = connect( sp->sd, adrp, adrlen );
- X if( result < 0 ) {
- X#ifdef Verbos_Errors
- X sserror("ConnectSock: connect()",CONT);
- X#endif
- X close(sp->sd);
- X free((char *) sp );
- X return (SOCKET *) SS_NULL;
- X }
- X max_sd = sp->sd >= max_sd ? sp->sd : max_sd ;
- X return sp;
- X}
- X
- Xint IsExceptSet( sp )
- XSOCKET *sp;
- X{
- X int result, i;
- X SOCKARRAY * sap;
- X sap = &ss_sockbuff;
- X i = SockIndex( sp, sap );
- X if( i == -1 )
- X return -1; /* Socket is not in ss_sockbuff */
- X result = FD_ISSET( sap->spa[i]->sd, &(sap->exceptfds) );
- X return result;
- X}
- X
- Xint IsReadSet( sp )
- XSOCKET *sp;
- X{
- X int result, i;
- X SOCKARRAY * sap;
- X sap = &ss_sockbuff;
- X i = SockIndex( sp, sap );
- X if( i == -1 )
- X return i; /* Socket is not in the ss_sockbuff */
- X result = FD_ISSET( sap->spa[i]->sd, &(sap->readfds) );
- X return result;
- X}
- X
- Xint IsWriteSet( sp )
- XSOCKET *sp;
- X{
- X int result, i;
- X SOCKARRAY * sap;
- X sap = &ss_sockbuff;
- X i = SockIndex( sp, sap );
- X if( i == -1 )
- X return -1; /* Socket is not in ss_sockbuff */
- X result = FD_ISSET( sap->spa[i]->sd, &(sap->writefds) );
- X return result;
- X}
- X
- Xvoid RemoveSock( sp )
- XSOCKET *sp;
- X{
- X int i, n;
- X SOCKARRAY *sap;
- X sap = &ss_sockbuff;
- X
- X for( i = 0; i < sap->n_sockets; i++ )
- X if( sp == sap->spa[i] ) break;
- X
- X n = i;
- X
- X for( i = n + 1; i < sap->n_sockets; i++ )
- X sap->spa[i-1] = sap->spa[i];
- X
- X sap->spa[sap->n_sockets - 1] = SS_NULL;
- X sap->n_sockets--;
- X return;
- X}
- X
- X
- XSOCKET *ServerSock( port_number )
- Xunsigned port_number;
- X{
- X int sd;
- X int optval;
- X unsigned optlen;
- X SOCKET *sp;
- X int result;
- X
- X SockInit( 's' );
- X
- X sd = socket( AF_INET, SOCK_STREAM, 0 );
- X if( sd < 0 ) {
- X sserror("ServerSock: socket()",EXIT);
- X /* return (SOCKET *) SS_NULL; */
- X }
- X
- X optval = 1; /* any nonzero value will cause the flag to be set */
- X optlen = sizeof( int );
- X result = setsockopt( sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, optlen );
- X if( result != 0 ) {
- X#ifdef Verbose_Errors
- X sserror("ServerSock: setsockopt()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X sp = (SOCKET *)malloc( sizeof(SOCKET));
- X if( !sp ) {
- X#ifdef Verbose_Errors
- X sserror("ServerSock: mallock()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X sp->addr.sin_family = AF_INET;
- X sp->addr.sin_addr.s_addr = INADDR_ANY;
- X sp->addr.sin_port = htons( (u_short)port_number );
- X
- X result = bind( sd, (struct sockaddr *)&(sp->addr), sizeof(struct sockaddr));
- X if( result !=0 ) {
- X#ifdef Verbose_Errors
- X sserror("ServerSock: bind()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X max_sd = sd >= max_sd ? sd : max_sd;
- X sp->sd = sd;
- X sp->_rcnt = 0;
- X sp->_rptr = SS_NULL;
- X sp->_rbase = SS_NULL;
- X sp->_wcnt = 0;
- X sp->_wptr = SS_NULL;
- X sp->_wbase = SS_NULL;
- X sp->_flag = 0;
- X
- X result = listen( sd, 5 );
- X if( result != 0 ) {
- X#ifdef Verbose_Errors
- X sserror("ServerSock: listen()",CONT);
- X#endif
- X return (SOCKET *) SS_NULL;
- X }
- X
- X AddSock( sp, &ss_sockbuff );
- X
- X return sp;
- X}
- X
- Xvoid SockArrayInit( sap )
- XSOCKARRAY *sap;
- X{
- X int i;
- X sap->n_sockets = 0;
- X for( i = 0; i < MaxSockets; i++ )
- X sap->spa[i] = SS_NULL;
- X return;
- X}
- X
- X/* fclose.c
- X
- X Hubert Bartels
- X
- X August 8, 1985
- X
- X fclose closes the file and frees the entry in the _iob block.
- X
- X Modified for sockets by Mat Watson 12/1/90
- X
- X*/
- Xint SockClose(sp)
- XSOCKET *sp;
- X{
- X int result;
- X
- X RemoveSock( sp );
- X
- X result = SockFlush(sp); /* Flush the buffer if needed */
- X if( result < 0 ) {
- X#ifdef Verbose_Errors
- X sserror("SockClose(): SockFlush failed",CONT);
- X#endif
- X return SS_EOF;
- X }
- X result = close((int)sp->sd); /* Close the file */
- X if( result < 0 )
- X sserror("SockClose: close() failed",EXIT);
- X sp->sd = '\0';
- X sp->_rcnt = 0;
- X sp->_rptr = SS_NULL;
- X if( (sp->_flag & SS_IONBF) == 0 )
- X free( (char *) sp->_rbase );
- X sp->_rbase = SS_NULL;
- X
- X sp->_wcnt = 0;
- X sp->_wptr = SS_NULL;
- X if( (sp->_flag & SS_IONBF) == 0 )
- X free( (char *) sp->_wbase );
- X sp->_wbase = SS_NULL;
- X sp->_flag = 0;
- X return 0; /* Success */
- X}
- X
- X/* SockFilbuf.c
- X Modified for sockets by Mat Watson 12/01/90
- X*/
- X/* filbuf.c
- X
- X Hubert Bartels
- X
- X July 8, 1985
- X
- X filbuf is used to fill the buffer of files being read by the
- X polyp. As such, it is part of the file system of the polyp.
- X*/
- Xint _SockFilbuf(sp)
- XSOCKET *sp;
- X{
- X static char smallbuf[NOFILE]; /* for unbuffered i/o */
- X char *calloc();
- X
- X if( (sp->_flag & (SS_IOEOF | SS_IOERR)) != 0 )
- X return(SS_EOF);
- X
- X while (sp->_rbase == SS_NULL) /* find buffer space */
- X if(sp->_flag & SS_IONBF) /* unbuffered */
- X sp->_rbase = &smallbuf[sp->sd];
- X else if ((sp->_rbase = calloc(SS_BUFSIZ, 1)) == SS_NULL)
- X sp->_flag |= SS_IONBF; /* Cannot get unbuffered */
- X else
- X sp->_flag |= SS_IOMYBUF; /* Got a big buffer */
- X
- X sp->_rptr = sp->_rbase;
- X sp->_rcnt = read(sp->sd, sp->_rptr,
- X sp->_flag & SS_IONBF ? 1 : SS_BUFSIZ);
- X if(--sp->_rcnt < 0) {
- X if(sp->_rcnt == -1 || errno == ECONNRESET ) /* ECONNRESET if socket */
- X sp->_flag |= SS_IOEOF; /* was closed. */
- X else {
- X sp->_flag |= SS_IOERR;
- X#ifdef Verbose_Errors
- X sserror("SockFilbuf(): read()",CONT);
- X#endif
- X }
- X sp->_rcnt = 0;
- X return(SS_EOF);
- X }
- X return(*sp->_rptr++ & 0377); /* make character positive */
- X}
- X/* SockFlsbuf.c
- X Modified for sockets by Mat Watson 12/01/90
- X*/
- X/* flsbuf.c
- X
- X Hubert Bartels
- X
- X July 29, 1985
- X
- X Version 2.0
- X Correct the bug, initialization of buffer
- X flsbuf is used to flush the buffer of files being written by
- X the polyp. As such, it is part of the file system of the polyp.
- X _flsbuf may be called with unbuffered or buffered data. There
- X may be data still in the buffers when the program completes.
- X either fflush or fclose should be called when closing the program
- X or file, to enure that all the data has been read out.
- X*/
- X
- Xint _SockFlsbuf(x,sp)
- Xchar x;
- XSOCKET *sp;
- X{
- X static char smallbuf[NOFILE]; /* for unbuffered i/o */
- X char *malloc();
- X
- X if( (sp->_flag & SS_IOERR) != 0)
- X return SS_EOF;
- X if (sp->_wbase == SS_NULL) { /* find buffer space */
- X if(sp->_flag & SS_IONBF) { /* unbuffered */
- X sp->_wbase = &smallbuf[sp->sd];
- X }
- X else if ((sp->_wbase = malloc(SS_BUFSIZ)) == SS_NULL) {
- X sp->_wbase = &smallbuf[sp->sd];
- X sp->_flag |= SS_IONBF; /* Cannot get unbuffered */
- X }
- X else
- X sp->_flag |= SS_IOMYBUF; /* Got a big buffer */
- X sp->_wptr = sp->_wbase; /* Initialize pointer */
- X sp->_wcnt = (sp->_flag & SS_IONBF)?0:SS_BUFSIZ; /* Buffer size */
- X if(sp->_flag & SS_IONBF) { /* If unbuffered */
- X write(sp->sd,&x, 1);
- X sp->_wcnt = 0;
- X }
- X else {
- X *(sp)->_wptr++ = x; /* Store char */
- X sp->_wcnt--;
- X }
- X return 0;
- X } /* End of sp->_base buffer allocation */
- X if(sp->_flag & SS_IONBF) { /* If unbuffered */
- X write(sp->sd,&x, 1);
- X sp->_wcnt = 0;
- X } else {
- X if(write(sp->sd,sp->_wbase,(SS_BUFSIZ-sp->_wcnt)) == -1)
- X sp->_flag |= SS_IOERR;
- X sp->_wcnt = SS_BUFSIZ;
- X sp->_wptr = sp->_wbase;
- X *(sp)->_wptr++ = x;
- X sp->_wcnt--;
- X }
- X return 0;
- X}
- X
- X/* SockFlush.c
- X Modified for sockets by Mat Watson 12/01/90
- X*/
- X/* fflush.c
- X
- X Hubert Bartels
- X
- X July 29, 1985
- X
- X fflush is called to clear out the buffers to ensure that everything
- X has been written. Called in the middle of the programs, it ensures
- X that the information will be complete before finishing some long
- X calculation. Called at the end, it performs the sync function for
- X the program.
- X*/
- X
- Xint SockFlush(sp)
- XSOCKET *sp;
- X{
- X int n_writen;
- X char *my_base;
- X
- X if(
- X /* (sp->_flag &SS_IOWRT) == 0 || */ /* Not Appropriate for Sock */
- X (sp->_flag & SS_IOERR) != 0
- X ) {
- X#ifdef Verbose_Errors
- X sserror("SockFlush: SS_IOERR is set",CONT);
- X#endif
- X return SS_EOF; /* If errors in file */
- X }
- X if( sp->_wbase == SS_NULL )
- X return 0; /* No buffer to flush */
- X if((sp->_flag & SS_IONBF) == 0) { /* If buffered */
- X my_base = sp->_wbase;
- X while( sp->_wcnt != SS_BUFSIZ ) {
- X n_writen = write( sp->sd, my_base, (SS_BUFSIZ - sp->_wcnt) );
- X if( n_writen < 0 ) {
- X extern int errno;
- X if( errno == EPIPE )
- X return 0;
- X#ifdef Verbose_Errors
- X sserror("SockFlush: write error",CONT);
- X /* When the socket has been set non blocking and the socket
- X would otherwise block, write will return a -1 and errno
- X will be set to EWOULDBLOCK. */
- X /* When write tries to send characters to a client or server
- X that has dissconnected errno is set to EPIPE */
- X#endif
- X return SS_EOF;
- X }
- X sp->_wcnt += n_writen;
- X my_base += n_writen;
- X }
- X sp->_wcnt = SS_BUFSIZ;
- X sp->_wptr = sp->_wbase;
- X }
- X return 0;
- X}
- X
- X/* SockGets.c
- X Modified for sockets by Mat Watson 12/01/90
- X*/
- X/* fgets.c
- X
- X read a newline-terminated string from device (file) dev
- X
- X Hubert Bartels
- X August 12, 1985
- X*/
- X
- Xchar *SockGets(s, n, sp)
- Xchar *s;
- Xint n;
- XSOCKET *sp;
- X{
- X int c;
- X char *cs;
- X
- X cs = s;
- X while ( --n > 0 && ( c = SockGetc( sp )) >= 0 ) {
- X *cs++ = (char)c;
- X if ( (char)c =='\n' )
- X break;
- X }
- X if ( c < 0 && cs == s )
- X return SS_NULL;
- X *cs++ = '\0';
- X return s;
- X}
- X
- X/* SockIndex.c
- X Writen by Mat Watson 12/01/90
- X*/
- X
- Xint SockIndex( sp, sap )
- XSOCKET *sp;
- XSOCKARRAY *sap;
- X{
- X int i;
- X
- X for( i = 0; i < sap->n_sockets; i++ )
- X if( sp == sap->spa[i] ) break;
- X
- X if( i == sap->n_sockets )
- X i = -1;
- X
- X return i;
- X}
- X
- X/* SockInit.c
- X Writen by Mat Watson 12/01/90
- X*/
- Xvoid SockInit( c )
- Xchar c;
- X{
- X if( ss_server_flag == 0 && c == 's' )
- X ss_server_flag = 1;
- X
- X if( ss_client_flag == 0 && c == 'c' )
- X ss_client_flag = 1;
- X
- X if( ss_init_flag == 0 ) {
- X ss_sockbuff.n_sockets = 0;
- X ss_init_flag = 1;
- X max_sd = 0;
- X signal(SIGPIPE,SockSignal);
- X }
- X
- X return;
- X}
- X
- X/* SockIsRead.c
- X Writen by Mat Watson 12/01/90
- X*/
- X
- Xint SockIsRead( sp )
- XSOCKET *sp;
- X{
- X int result;
- X struct timeval to;
- X fd_set readfds;
- X
- X to.tv_sec = 0;
- X to.tv_usec = 0;
- X
- X
- X FD_ZERO( &readfds );
- X FD_SET( sp->sd, &readfds );
- X result = select( max_sd+1, &readfds, (fd_set *)0, (fd_set *)0, &to );
- X if( result == -1 )
- X sserror("SockSelect1(): select() returned -1",CONT);
- X
- X return FD_ISSET( sp->sd, &readfds ) ? 1 : 0;
- X}
- X
- Xint SockIsWrite( sp )
- XSOCKET *sp;
- X{
- X int result;
- X struct timeval to;
- X fd_set writefds;
- X
- X to.tv_sec = 0;
- X to.tv_usec = 0;
- X
- X
- X FD_ZERO( &writefds );
- X FD_SET( sp->sd, &writefds );
- X result = select( max_sd+1, (fd_set *)0, &writefds, (fd_set *)0, &to );
- X if( result == -1 )
- X sserror("SockSelect1(): select() returned -1",CONT);
- X
- X return FD_ISSET( sp->sd, &writefds ) ? 1 : 0;
- X}
- X
- X/* SockPuts.c
- X Modified for sockets by Mat Watson 12/01/90
- X*/
- X/* fputs.c
- X
- X places a string on the output file pointed to by fp.
- X
- X Hubert Bartels
- X August 12, 1985
- X*/
- Xint SockPuts(s, sp)
- XSOCKET *sp;
- Xchar *s;
- X{
- X int r;
- X char c;
- X
- X while (c = *s++)
- X r = SockPutc(c, sp);
- X return(r);
- X}
- X
- Xint SockSelect( timeout, flag )
- Xdouble timeout;
- Xchar *flag;
- X{
- X int i;
- X int result;
- X long seconds;
- X long microseconds;
- X SOCKARRAY * sap;
- X struct timeval to, *tvp;
- X fd_set *rfdsp, *wfdsp, *efdsp;
- X char *cp;
- X
- X sap = &ss_sockbuff;
- X
- X if( timeout < 0.0 ) {
- X tvp = SS_NULL;
- X }
- X else {
- X seconds = timeout / 1.0;
- X microseconds = (timeout - (double)seconds) / 1e-6;
- X to.tv_sec = seconds;
- X to.tv_usec = microseconds;
- X tvp = &to;
- X }
- X
- X rfdsp = (fd_set *)0;
- X wfdsp = (fd_set *)0;
- X efdsp = (fd_set *)0;
- X
- X for( cp = flag; *cp != '\0'; cp++ ) {
- X if( *cp == 'r' ) {
- X rfdsp = &(sap->readfds);
- X FD_ZERO( rfdsp );
- X for( i = 0; i < sap->n_sockets; i ++ )
- X FD_SET( sap->spa[i]->sd, rfdsp );
- X }
- X else if( *cp == 'w' ) {
- X wfdsp = &(sap->writefds);
- X FD_ZERO( wfdsp );
- X for( i = 0; i < sap->n_sockets; i ++ )
- X FD_SET( sap->spa[i]->sd, wfdsp );
- X }
- X else if( *cp == 'e' ) {
- X efdsp = &(sap->exceptfds);
- X FD_ZERO( efdsp );
- X for( i = 0; i < sap->n_sockets; i ++ )
- X FD_SET( sap->spa[i]->sd, efdsp );
- X }
- X else {
- X sserror("SockSelect(): Unknown flag",CONT);
- X }
- X }
- X
- X result = select( max_sd+1, rfdsp, wfdsp, efdsp, tvp );
- X if( result == -1 )
- X perror("SockSelect(): select() returned -1");
- X
- X return result;
- X}
- X
- Xvoid SockSignal( sig )
- Xint sig;
- X{
- X switch ( sig )
- X {
- X case SIGPIPE :
- X#ifdef Verbose_Signals
- X sserror(
- X "Caught a SIGPIPE signal, Server/Client probably disconnected",
- X CONT );
- X#endif
- X break;
- X }
- X return;
- X}
- X
- X/* SockWrites
- X Writen by Mat Watson 12/01/90
- X Based on fputs.c by Hubert Bartels.
- X*/
- Xint SockWrites(s, sp)
- XSOCKET *sp;
- Xchar *s;
- X{
- X int r;
- X char c;
- X
- X while (c = *s++)
- X r = SockPutc(c, sp);
- X r = SockFlush( sp );
- X return(r);
- X}
- X
- Xvoid sserror( mesg, code )
- Xchar * mesg;
- Xint code;
- X{
- X fprintf(stderr,"%s",mesg);
- X fputc(' ',stderr);
- X fflush(stderr);
- X perror(NULL);
- X if ( code == EXIT ) exit( 1 );
- X return;
- X}
- SHAR_EOF
- chmod 0644 ss.c || echo "restore of ss.c fails"
- sed 's/^X//' << 'SHAR_EOF' > ss.base.h &&
- X/* ss.h */
- X/* writen by Mat Watson 12/01/90 */
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X
- X#define MaxSockets 30
- X#define EXIT 0
- X#define CONT 1
- X
- Xtypedef struct m_in_socket SOCKET;
- Xtypedef struct m_in_socket_array SOCKARRAY;
- X
- Xstruct m_in_socket {
- X int sd;
- X struct sockaddr_in addr;
- X int _rcnt;
- X char *_rptr;
- X char *_rbase;
- X int _rbufsiz;
- X int _wcnt;
- X char *_wptr;
- X char *_wbase;
- X int _wbufsiz;
- X short _flag;
- X};
- X
- Xstruct m_in_socket_array {
- X int n_sockets;
- X SOCKET *spa[MaxSockets];
- X fd_set readfds;
- X fd_set writefds;
- X fd_set exceptfds;
- X};
- X
- X/* define flags */
- X/**/
- X#define SS_IOFBF 0
- X#define SS_IOREAD 01
- X#define SS_IOWRT 02
- X#define SS_IONBF 04
- X#define SS_IOMYBUF 010
- X#define SS_IOEOF 020
- X#define SS_IOERR 040
- X#define SS_IOSTRG 0100
- X#define SS_IOLBF 0200
- X#define SS_IORW 0400
- X#define SS_NULL 0
- X#define SS_EOF (-1)
- X#define SS_BUFSIZ 1024
- X
- X#define SockGetc(p) (--(p)->_rcnt>=0? ((int)*(p)->_rptr++):_SockFilbuf(p))
- X
- X#define SockPutc(x, p) (--(p)->_wcnt >= 0 ?\
- X (int)(*(p)->_wptr++ = (char)(x)) :\
- X (((p)->_flag & SS_IOLBF) && -(p)->_wcnt < (p)->_wbufsiz ?\
- X ((*(p)->_wptr = (char)(x)) != '\n' ?\
- X (int)(*(p)->_wptr++) :\
- X _SockFlsbuf(*(char *)(p)->_wptr, p)) :\
- X _SockFlsbuf((char)(x), p)))
- X
- X#define SockEof(p) (((p)->_flag&SS_IOEOF)!=0)
- X#define SockError(p) (((p)->_flag&SS_IOERR)!=0)
- X#define SockFileno(p) ((p)->sd)
- X#define SockClearerr(p) (void) ((p)->_flag &= ~(SS_IOERR|SS_IOEOF))
- X
- X#ifdef __STDC__
- X# define P_(s) s
- X#else
- X# define P_(s) ()
- X#endif
- X
- X
- X/* ss.c */
- XSOCKET *AcceptSock P_((SOCKET *ssp ));
- Xvoid AddSock P_((SOCKET *sp , SOCKARRAY *sap ));
- XSOCKET *ConnectSock P_((char *hostname , unsigned port_number ));
- Xint IsExceptSet P_((SOCKET *sp ));
- Xint IsReadSet P_((SOCKET *sp ));
- Xint IsWriteSet P_((SOCKET *sp ));
- Xvoid RemoveSock P_((SOCKET *sp ));
- XSOCKET *ServerSock P_((unsigned port_number ));
- Xvoid SockArrayInit P_((SOCKARRAY *sap ));
- Xint SockClose P_((SOCKET *sp ));
- Xint _SockFilbuf P_((SOCKET *sp ));
- Xint _SockFlsbuf P_((int x , SOCKET *sp ));
- Xint SockFlush P_((SOCKET *sp ));
- Xchar *SockGets P_((char *s , int n , SOCKET *sp ));
- Xint SockIndex P_((SOCKET *sp , SOCKARRAY *sap ));
- Xvoid SockInit P_((int c ));
- Xint SockIsRead P_((SOCKET *sp ));
- Xint SockIsWrite P_((SOCKET *sp ));
- Xint SockPuts P_((char *s , SOCKET *sp ));
- Xint SockSelect P_((double timeout , char *flag ));
- Xvoid SockSignal P_((int sig ));
- Xint SockWrites P_((char *s , SOCKET *sp ));
- Xvoid sserror P_((char *mesg , int code ));
- X
- X#undef P_
- SHAR_EOF
- chmod 0644 ss.base.h || echo "restore of ss.base.h fails"
- sed 's/^X//' << 'SHAR_EOF' > ss.sun.h &&
- X/* ss.h */
- X/* writen by Mat Watson 12/01/90 */
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include "stdlib.h"
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <sys/time.h>
- SHAR_EOF
- chmod 0644 ss.sun.h || echo "restore of ss.sun.h fails"
- sed 's/^X//' << 'SHAR_EOF' > ss.ibm.h &&
- X/* ss.h */
- X/* writen by Mat Watson 12/01/90 */
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include "stdlib.h"
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <sys/select.h>
- X#include <netinet/in.h>
- X#include <netdb.h>
- X#include <sys/time.h>
- SHAR_EOF
- chmod 0644 ss.ibm.h || echo "restore of ss.ibm.h fails"
- sed 's/^X//' << 'SHAR_EOF' > ss.3b2.h &&
- X/* ss.h */
- X/* writen by Mat Watson 12/01/90 */
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <errno.h>
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/socket.h>
- X#include <sys/in.h>
- X#include <netdb.h>
- X#include <sys/time.h>
- Xtypedef int fd_set;
- Xtypedef unsigned short u_short;
- SHAR_EOF
- chmod 0644 ss.3b2.h || echo "restore of ss.3b2.h fails"
- sed 's/^X//' << 'SHAR_EOF' > test.h &&
- X#define SERVER_HOSTNAME "zeus.opt-sci.arizona.edu" /* your machine name. */
- X#define PORT_NUMBER 4020
- SHAR_EOF
- chmod 0644 test.h || echo "restore of test.h fails"
- sed 's/^X//' << 'SHAR_EOF' > stdlib.h &&
- X/* stdlib.h */
- Xchar *malloc();
- Xchar *calloc();
- SHAR_EOF
- chmod 0644 stdlib.h || echo "restore of stdlib.h fails"
- sed 's/^X//' << 'SHAR_EOF' > server1.c &&
- X/* server1.c */
- X/*
- X Writen by Mat Watson 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include "ss.h"
- X#include "test.h"
- X
- Xmain()
- X{
- X SOCKET *ssp, *csp;
- X char buffer[100], *result;
- X int n_read;
- X
- X /* open a socket that clients can connect to. */
- X ssp = ServerSock( PORT_NUMBER );
- X
- X /* Wait for a client to connect. Accept input from the client.
- X Close the client socket pointer when the connection is broken
- X by the client. Then wait again for another connection. */
- X
- X (void)printf("Use ^C to stop this program\n");
- X
- X while(1) {
- X /* Wait for a client to connect. */
- X csp = AcceptSock( ssp );
- X
- X (void)printf("Accepted a client.\n");
- X
- X /* Read whatever the client sends, and print that out to the
- X * standard output.
- X */
- X while((result=SockGets(buffer,sizeof(buffer)-1,csp)) != SS_NULL) {
- X (void)printf("%s", buffer);
- X }
- X
- X /* Close the socket. */
- X SockClose( csp );
- X (void)printf("Client disconnected.\n");
- X }
- X}
- SHAR_EOF
- chmod 0644 server1.c || echo "restore of server1.c fails"
- sed 's/^X//' << 'SHAR_EOF' > client1.c &&
- X/* client1.c */
- X/*
- X Writen by Mat Watson 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include "ss.h"
- X#include "test.h"
- X
- Xmain()
- X{
- X char *line, buffer[200];
- X SOCKET *ssp;
- X
- X
- X /* Establish a connection with the server. */
- X ssp = ConnectSock( SERVER_HOSTNAME, PORT_NUMBER );
- X if( ssp == SS_NULL )
- X sserror("server1: ConnectSock()", EXIT);
- X
- X /* Get text from the standard input, and send it to the server program */
- X (void)printf("enter text (^d to quit)\n");
- X while( ( line = gets(buffer) ) != NULL ) {
- X sprintf(buffer, "%s\n", line);
- X SockWrites(buffer, ssp);
- X }
- X (void)printf("Saioonara\n");
- X SockClose(ssp);
- X exit(0);
- X}
- SHAR_EOF
- chmod 0644 client1.c || echo "restore of client1.c fails"
- sed 's/^X//' << 'SHAR_EOF' > server2.c &&
- X/* server2.c */
- X/*
- X Writen by Mat Watson 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include "ss.h"
- X
- X#define PORT_NUMBER 4020
- X
- Xmain()
- X{
- X SOCKET *ssp, *csp;
- X char buffer[100], *result;
- X
- X /* Open a socket for clients to connect to. */
- X ssp = ServerSock( PORT_NUMBER );
- X
- X /* Look to see if a client wants to connect to the server socket.
- X If there's a client take input from it until the client breaks
- X the connection. If there's no client trying to connect then
- X just do something else. */
- X
- X (void)printf("Use ^C to stop this program\n");
- X
- X while(1) {
- X SockSelect( 5.0, "r" ); /* Wait 5 seconds for a client to
- X request a connection. */
- X if( IsReadSet( ssp ) ) { /* Is a client is trying to connect? */
- X csp = AcceptSock( ssp ); /* Accept the connection. */
- X (void)printf("Accepted a client\n");
- X /* Accept input until client disconnects. Print that output to the
- X standard ouput. */
- X while( (result=SockGets(buffer,sizeof(buffer)-1,csp)) != SS_NULL ) {
- X (void)printf("%s", buffer);
- X }
- X if( SockClose(csp) == SS_EOF )
- X sserror("server2 - SockClose()",CONT);
- X (void)printf("Client disconnected.\n");
- X }
- X else {
- X (void)printf("doing something else\n");
- X }
- X }
- X}
- SHAR_EOF
- chmod 0644 server2.c || echo "restore of server2.c fails"
- sed 's/^X//' << 'SHAR_EOF' > client2.c &&
- X/* client2.c */
- X/*
- X Writen by Mat Watson 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X/* Exercise the SockPuts() or the SockWrites() command */
- X#include <stdio.h>
- X#include "ss.h"
- X#include "test.h"
- X
- Xmain()
- X{
- X char *line, buffer[200], message[200];
- X SOCKET *ssp;
- X ssp = ConnectSock( "zeus.opt-sci.arizona.edu", 4020 );
- X if( ssp == SS_NULL ) {
- X printf("ConnectSock returned SS_NULL. Exiting ..... \n\n");
- X exit(1);
- X }
- X
- X#ifdef PUTC
- X SockPutc('a',ssp);
- X SockPutc('\n',ssp);
- X SockFlush(ssp);
- X#endif /* PUTC */
- X SockWrites("I'm the client\n",ssp);
- X printf("enter text (^d to end)\n");
- X while( ( line = gets(buffer) ) != NULL ) {
- X sprintf(message,"%s\n",line);
- X /*
- X SockPuts(message,ssp);
- X */
- X SockWrites(message,ssp);
- X }
- X
- X SockFlush(ssp);
- X SockClose(ssp);
- X exit(0);
- X}
- SHAR_EOF
- chmod 0644 client2.c || echo "restore of client2.c fails"
- sed 's/^X//' << 'SHAR_EOF' > server3.c &&
- X/* server.c */
- X/* Writen by Mat Watson 12/01/90
- X*/
- X/*
- XCopyright (c) 1990 Mat Watson and Hubert Bartels. All rights reserved.
- X
- XPermission to use, copy, and/or distribute for any purpose and
- Xwithout fee is hereby granted, provided that both the above copyright
- Xnotice and this permission notice appear in all copies and derived works.
- XFees for distribution of this software or for derived sources may only
- Xbe charged with the express written permission of the copyright holders.
- XThis software is provided ``as is'' without express or implied warranty.
- X*/
- X#include <stdio.h>
- X#include "ss.h"
- X#include "test.h"
- X
- Xtypedef struct client_list CLIST;
- Xchar *malloc();
- Xstruct client_list {
- X CLIST *prev;
- X CLIST *next;
- X SOCKET *sp;
- X};
- X
- XCLIST * AddClient( sp, clp )
- XSOCKET *sp;
- XCLIST *clp;
- X{
- X CLIST *newclp;
- X
- X newclp = (CLIST *)malloc( sizeof( struct client_list ) );
- X newclp->prev = SS_NULL;
- X newclp->sp = sp;
- X newclp->next = clp;
- X if( clp != SS_NULL )
- X clp->prev = newclp;
- X return newclp;
- X}
- X
- XCLIST * RemoveClient( p_remove, clp )
- XCLIST *p_remove;
- XCLIST *clp;
- X{
- X CLIST *p, *pnext;
- X
- X for( p = clp; p; p = p->next )
- X if( p == p_remove )
- X break;
- X if( !p )
- X perror("RemoveClient(): sp not in client list");
- X if( p->prev )
- X (p->prev)->next = p->next;
- X if( p->next )
- X (p->next)->prev = p->prev;
- X
- X pnext = p->next; /* we may want to return this value
- X after deallocating p */
- X
- X free( (char *)p );
- X return p == clp ? pnext : clp;
- X}
- X
- Xmain()
- X{
- X SOCKET *ssp, *csp;
- X char buffer[100], *result, cmesg[100];
- X int n_read;
- X CLIST *clp, *p;
- X int test;
- X
- X clp = SS_NULL;
- X
- X (void)printf("Use ^C to stop this program.\n");
- X
- X ssp = ServerSock( PORT_NUMBER );
- X printf("Server socket opened on descriptor %d\n",ssp->sd);
- X
- X while(1) {
- X (void)printf("Waiting for input or a connection.\n");
- X SockSelect( -5.0, "r" ); /* Block until something is ready to be
- X read from. */
- X if( IsReadSet( ssp ) > 0 ) { /* Connect new clients first. */
- X csp = AcceptSock( ssp );
- X clp = AddClient( csp, clp );
- X (void)printf("Adding client on descriptor %d.\n",csp->sd);
- X /* Ask a silly question.*/
- X SockWrites("Client, what is your pid number?\n",csp);
- X }
- X else /* no new clients to connect. */ {
- X if( clp != SS_NULL ) {
- X (void)printf("Looping over clients.\n");
- X p = clp;
- X while( p ) {
- X (void)printf(" "); /* Not necessary. Makes output look nice. */
- X if( /* Either of the following two statements will work. */
- X IsReadSet(p->sp) > 0 /* This function relies on the last call to
- X SockSelect(). */
- X /* SockIsRead(p->sp) /* This function calls select() again; however,
- X it only affects IsXxxSet() for this socket.
- X */
- X ) {
- X result = SockGets(buffer, 99 , p->sp );
- X if( result == SS_NULL ) {
- X goto remove;
- X }
- X printf("%s",buffer); /* Get a silly answer. */
- X /* Repeat the silly question. */
- X test = SockWrites("Client, what is your pid number?\n",p->sp);
- X if( test == SS_EOF ) {
- X goto remove;
- X }
- X } /* end if socket ready to read from */
- X else {
- X (void)printf("Descriptor %d was not ready for reading.\n",p->sp->sd);
- X }
- X p = p->next;
- X continue;
- X remove: {
- X CLIST *tmp;
- X (void)printf("Removing client with descriptor = %d.\n",p->sp->sd);
- X tmp = p->next;
- X SockClose( p->sp );
- X /* RemoveClient frees the space pointed to by p, so we need to
- X store its 'next' pointer in the variable tmp. */
- X clp = RemoveClient( p, clp );
- X p = tmp;
- X } /* end ther remove clause. */
- X } /* end the while clients. */
- X (void)printf("Done looping over clients.\n");
- X } /* end if client list is non null. */
- X } /* end of else. No new clients to connect. */
- X } /* end of infinite while loop. */
- X} /* end the program */
- SHAR_EOF
- chmod 0644 server3.c || echo "restore of server3.c fails"
- sed 's/^X//' << 'SHAR_EOF' > client3.c &&
- X/* client3.c */
- X/*
- X Writen by Mat Watson 12/01/90
- X*/
- X#include <stdio.h>
- X#include <errno.h>
- X#include "ss.h"
- X#include "test.h"
- Xmain()
- X{
- X char *line, buffer[200], message[200],message1[100];
- X int pid;
- X int result;
- X SOCKET *ssp;
- X int n;
- X int i;
- X
- X /* Attempt to connect to the server program. */
- X ssp = ConnectSock( SERVER_HOSTNAME, PORT_NUMBER );
- X if( ssp == SS_NULL ) {
- X printf("ConnectSock returned SS_NULL. Exiting ..... \n\n");
- X return;
- X }
- X
- X pid = getpid();
- X (void)printf("This clients pid is %d.\n",pid);
- X /* Create a message to send to the server program. */
- X sprintf(message,"Client pid = %d.\n",pid);
- X
- X i = 3;
- X while( i ) {
- X i--;
- X sleep(2);
- X n = SockSelect( -5.0, "r" ); /* Block, Check for any open socket
- X being read ready. */
- X if( IsReadSet( ssp ) ) { /* Do we have anything to be read from the
- X server? */
- X SockGets(message1,99,ssp); /* Read it. */
- X printf("%s",message1); /* Print it out. */
- X fflush(stdout); /* Now! :-) */
- X result = SockWrites(message,ssp);
- X if( result == SS_EOF ) break; /* Probably connection broken. */
- X }
- X }
- X if( errno == EPIPE )
- X (void)printf("Server disconnected\n");
- X (void)printf("bye\n"); fflush(stdout);
- X exit(0);
- X}
- SHAR_EOF
- chmod 0644 client3.c || echo "restore of client3.c fails"
- exit 0
-