[comp.lang.c++] Transport Part03/03

schemers@vela.acs.oakland.edu (Roland Schemers III) (10/26/90)

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 3)."
# Contents:  Transport/src/Socket.C Transport/src/Transport.h
# Wrapped by schemers@vela.acs.oakland.edu on Thu Oct 25 15:44:48 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Transport/src/Socket.C' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Transport/src/Socket.C'\"
else
echo shar: Extracting \"'Transport/src/Socket.C'\" \(3702 characters\)
sed "s/^X//" >'Transport/src/Socket.C' <<'END_OF_FILE'
X#include <libc.h>
X#include <osfcn.h>
X#include <iostream.h>
X#include <errno.h>
X
X#include "Transport.h"
X#include "Util.h"
X
Xint Socket::check_syscall(int stat, char *mess)
X{
X	if (stat==-1) {
X		status=errno; 
X		if (return_on_error) return 0;
X		Util::crash_and_burn("Socket",mess,sys_errlist[status]);
X	} else status=0;
X	return 1;
X}
X
Xint Socket::syscall(int stat, char *mess)
X{
X	if (stat==-1) {
X		status=errno; 
X		if (return_on_error) return stat;
X		Util::crash_and_burn("Socket",mess,sys_errlist[status]);
X	} else status=0;
X	return stat;
X}
X
XSocket::Socket(AddressFamily af, SocketType st)
X{
X  type     = st;	// socket type
X  family   = af;	// address family
X  protocol = 0;		// protocol
X  sex      = Unknown;
X}
X
X
XSocket::Socket(AddressFamily af)	// protected, only used from derived
X{					// class constructor
X  family   = af;	// address family
X  protocol = 0;		// protocol
X  sex      = Unknown;
X}
X
XSocket::Socket(SocketType st)	// protected, only used from derived
X{				// class constructor
X  type     = st;	// socket type
X  protocol = 0;		// protocol
X  sex      = Unknown;
X}
X
Xint Socket::socket()
X{
X	td = ::socket(address_family(),socket_type(),0);
X	return check_syscall(td,"socket");
X}
X
Xint Socket::accept(struct sockaddr *sa,int &len)
X{
X	return syscall(::accept(td,sa, &len),"accept");
X}
X
Xint Socket::bind(const struct sockaddr *sa, int sa_len)
X{
X	return check_syscall(::bind(td,sa,sa_len),"bind");
X}
X
Xint Socket::connect(const struct sockaddr *sa, int sa_len)
X{
X	return check_syscall(::connect(td,sa,sa_len),"connect");
X}
X
Xint Socket::getpeername(struct sockaddr *sa, int &sa_len)
X{
X	return check_syscall(::getpeername(td,sa,&sa_len),"getpeername");
X}
X
Xint Socket::getsockname(struct sockaddr *sa, int &sa_len)
X{
X	return check_syscall(::getsockname(td,sa,&sa_len),"getsockname");
X}
X
Xint Socket::recv(char *buffer,int maxbuf,MsgReceiveFlags mrf)
X{
X	return syscall(::recv(td,buffer,maxbuf,int(mrf)),"recv");
X}
X
Xint Socket::recvfrom(char *buffer,int maxbuf,struct sockaddr *sa, 
X			int &len,MsgReceiveFlags mrf)
X{
X     return syscall(::recvfrom(td,buffer,maxbuf,int(mrf),sa,&len),"recvfrom");
X}
X
Xint Socket::recvmsg(struct msghdr *mh,MsgReceiveFlags mrf)
X{
X	return syscall(::recvmsg(td,mh,int(mrf)),"recvmsg");
X}
X
Xint Socket::send(const char *buffer,int num,MsgSendFlags msf)
X{
X	return syscall(::send(td,buffer,num,int(msf)),"send");
X}
X
X
Xint Socket::sendto(const char *buffer,int num,
X		const struct sockaddr *sa, int len,MsgSendFlags msf)
X{
X	return syscall(::sendto(td,buffer,num,int(msf),sa,len),"sendto");
X}
X
Xint Socket::sendmsg(struct msghdr *mh,MsgSendFlags msf)
X{
X	return syscall(::sendmsg(td,mh,int(msf)),"sendmsg");
X}
X
Xint Socket::listen(int max_conn)
X{
X	return check_syscall(::listen(td,max_conn),"listen");
X}
X
X
XSocket::~Socket()
X{
X  if (inuse()) close();
X}
X
Xvoid Socket::linger() 
X{
X  if (!inuse()) return;
X  static struct linger ling = {1,10};
X  int stat=::setsockopt(td,SOL_SOCKET,SO_LINGER,(const char *)&ling,sizeof(ling));
X  if (stat==-1) {
X	status=errno;
X	if (return_on_error) return;
X	Util::crash_and_burn("Socket","linger",sys_errlist[status]);
X  }
X  status=0;
X  
X}
X
Xint Socket::setsockopt(SocketLevelOption slo, FlagOption fo)
X{
X if (!inuse()) return 0;
X int flag=fo;
X  return check_syscall(::setsockopt(td,SOL_SOCKET,int(slo),
X			(const char *) &flag,sizeof(flag)),"setsockopt");
X}
X
Xint Socket::getsockopt(SocketLevelOption slo,FlagOption &fo)
X{
X  if (!inuse()) return 0;
X  int flag; int flagsize=sizeof(flag);
X  int stat=check_syscall(::getsockopt(td,SOL_SOCKET,int(slo),
X			(char *) &flag,&flagsize),"getsockopt");
X  if (flag) fo=On; else fo=Off;
X  return stat;
X
X}
X
Xvoid Socket::shutdown(ShutDownType sdt)
X{
X  if (!inuse()) return;
X  check_syscall(::shutdown(td,sdt),"shutdown");
X}
END_OF_FILE
if test 3702 -ne `wc -c <'Transport/src/Socket.C'`; then
    echo shar: \"'Transport/src/Socket.C'\" unpacked with wrong size!
fi
# end of 'Transport/src/Socket.C'
fi
if test -f 'Transport/src/Transport.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Transport/src/Transport.h'\"
else
echo shar: Extracting \"'Transport/src/Transport.h'\" \(8742 characters\)
sed "s/^X//" >'Transport/src/Transport.h' <<'END_OF_FILE'
X#ifndef TRANSPORT_CLASS_H
X#define TRANSPORT_CLASS_H
X
X#include <sys/socket.h>
X#include <sys/types.h>
X#include <sys/un.h>
X#include <netinet/in.h>
X#include <arpa/inet.h>
X
X#ifdef USE_DECNET
X#include <netdnet/dn.h>
X#include <netdnet/dnetdb.h>
X#endif
X
X#include <iostream.h>
X
Xtypedef struct sockaddr *SOCKADDR_PTR;
Xtypedef const struct sockaddr *CONST_SOCKADDR_PTR;
X
Xclass InetAddress {
X	friend ostream &operator<<(ostream &os, const InetAddress &ia);
Xpublic:
X	static char *Any;	// any address
X	static char *Broadcast;	// broadcast address
X	enum Status {NoHostGiven,UnknownHost,UnKnownService,HostFound};
X	InetAddress();
X	InetAddress(const char *hostname,int port);
X	InetAddress(int port);
X	InetAddress(const char *hostname,const char *service,const char *proto);
X	InetAddress(const char *service,const char *proto);
X	lookup(const char *hostname,int port);
X	lookup(int port) {
X			return lookup(Any,port);
X	}
X	lookup(const char *hostname,const char *service,const char *proto);
X	lookup(const char *service,const char *proto) {
X			return lookup(Any,service,proto);
X	}
X	int ok() const { return stat==HostFound; }
X	Status status() const { return stat; }
X	const char *hostname() const;
X	const char *numeric_hostname() const;
X	int size() const { return sizeof(address); }
X	int port() const;
X	int isany() const { return any_flag; }
X	int isbroadcast() const { return broadcast_flag; }
X	operator SOCKADDR_PTR() { return (SOCKADDR_PTR) &address; }
X	operator CONST_SOCKADDR_PTR() const { return (SOCKADDR_PTR) &address; }
X
X	struct sockaddr_in	address;
X	int			addrlen;
X	Status			stat;
X	int			any_flag;
X	int			broadcast_flag;
X};
X
Xclass UnixAddress {
X	friend ostream &operator<<(ostream &os, const UnixAddress &ia);
Xpublic:
X	static char *Temp;	// any address
X	UnixAddress();
X	UnixAddress(const char *pathname);
X	void set(const char *pathname);
X	const char *pathname() const;
X	int size() const { return sizeof(address); }
X	operator SOCKADDR_PTR() { return (SOCKADDR_PTR) &address; }
X	operator CONST_SOCKADDR_PTR() const { return (SOCKADDR_PTR) &address; }
X
X	struct sockaddr_un	address;
X	int			addrlen;
X};
X
Xclass Transport {
X  public:
X	Transport();
X	virtual void abstract_class()=0;
X	virtual int  close();
X	virtual int  read(char *buffer, int len);
X	virtual int  write(const char *buffer,int len);
X	virtual int  readv(const struct iovec *, int);
X	virtual int  writev(const struct iovec *, int);
X	virtual int  ok();
X	virtual int  inuse();
X	virtual ~Transport() {};
X	int	      return_on_error;
Xprotected:
X	int		    status;	// connection status
X	int			td;	// the transport file descriptor
X};
X
X
Xclass Socket : public virtual Transport {
X	void abstract_class() {}
Xpublic:
X	enum SocketSex { Unknown,Client, Server};
X	enum AddressFamily {	// just work with these three for now
X		AfUnix    =  AF_UNIX,
X		AfInet    =  AF_INET,
X		AfDECnet  =  AF_DECnet
X	};
X	enum SocketType {
X		Stream    =  SOCK_STREAM,
X		Datagram  =  SOCK_DGRAM,
X		Raw       =  SOCK_RAW,
X		RDM       =  SOCK_RDM,
X		SeqPacket =  SOCK_SEQPACKET
X	};
X	enum MsgSendFlags {	
X		MsgSendNoFlags	    =	0,
X		MsgSendDontRoute    =	MSG_DONTROUTE,
X		MsgSendOob	    =	MSG_OOB,
X		MsgSendDontRouteOob =	MSG_OOB|MSG_DONTROUTE
X	};
X	enum MsgReceiveFlags {	
X		MsgReceiveNoFlags =	0,
X		MsgReceivePeek	  =	MSG_PEEK,
X		MsgReceiveOob	  =	MSG_OOB,
X		MsgReceivePeekOob =	MSG_OOB|MSG_PEEK
X	};
X	enum ShutDownType { 
X		ShutDownReceive=0, 
X		ShutDownSend=1, 
X		ShutDownBoth=2 
X	};
X	enum FlagOption { Off = 0, On  = 1 };
X	enum SocketLevelOption {
X		Broadcast	=	SO_BROADCAST,
X		Debug		=	SO_DEBUG,
X		DontRoute	=	SO_DONTROUTE,
X		KeepAlive	=	SO_KEEPALIVE,
X		OOBInline	=	SO_OOBINLINE,
X		ReuseAddr	=	SO_REUSEADDR,
X		UseLoopBack	=	SO_USELOOPBACK
X	};
X	Socket( AddressFamily af,SocketType st);
X	~Socket();
X	virtual int socket();
X	int accept(struct sockaddr *sa, int &len);
X	int bind(const struct sockaddr *,int);
X	int connect(const struct sockaddr *,int);
X	int getpeername(struct sockaddr *, int &len);
X	int getsockname(struct sockaddr *, int &len);
X	int getsockopt(int, int, char *, int *);	//
X	int listen(int);
X	int recv(char *, int, MsgReceiveFlags=MsgReceiveNoFlags);
X	int recvfrom(char *, int, struct sockaddr *, 
X			int &,MsgReceiveFlags=MsgReceiveNoFlags);
X	int send(const char *, int,MsgSendFlags=MsgSendNoFlags);
X	int sendto(const char *, int, const struct sockaddr *, 
X			int,MsgSendFlags=MsgSendNoFlags); 
X	int setsockopt(int, int, const char *, int);	//
X	int recvmsg(struct msghdr *, MsgReceiveFlags=MsgReceiveNoFlags);
X	int sendmsg(struct msghdr *, MsgSendFlags=MsgSendNoFlags);
X	virtual void shutdown(ShutDownType);
X	void linger();
X	int setsockopt(SocketLevelOption slo, FlagOption fo);
X	int getsockopt(SocketLevelOption slo, FlagOption &fo);
X	AddressFamily address_family() 		{ return family;	}
X	SocketType    socket_type() 		{ return type;		}
X	SocketSex     socket_sex()		{ return sex;		}
X	int	      socket_protocol()		{ return protocol;	}
X	int	      isclient()		{ return sex==Client;	}
X	int	      isserver()		{ return sex==Server;	}
Xprotected:
X	Socket(AddressFamily af);
X	Socket(SocketType st);
X	int	      check_syscall(int stat,char *mess);
X	int	      syscall(int stat,char *mess);
X	SocketType	      type;	// Socket Type
X	AddressFamily 	    family;	// Address Family
X	int		  protocol;     // Protocol (currently 0)
X	SocketSex	       sex;	// Client or Server?
X};
X
Xclass UnixSocket : public virtual Socket {
Xpublic:
X	UnixSocket(SocketType st) : Socket(Socket::AfUnix,st) {}
X	int open(const UnixAddress &ua, SocketSex sex);
X	~UnixSocket();
X	int accept(UnixSocket &newsocket);
X	int close();
X	const UnixAddress &local_address() { return local; }
X	const UnixAddress &remote_address() { return remote; }
Xprivate:
X	UnixAddress		local,remote;
X	int			unlink_socket;
X};
X
Xclass InetSocket : public virtual Socket {
Xpublic:		
X	InetSocket(SocketType st) : Socket(Socket::AfInet,st) {}
X	int accept(InetSocket &newsocket);
X	int bind(const InetAddress &ia);
X	int connect(const InetAddress &ia);
X	int getpeername(InetAddress &ia);
X	int getsockname(InetAddress &ia);
X	int recvfrom(char *buffer,int maxbuf,InetAddress &is);
X	int sendto(char *buffer,int len,const InetAddress &is);
X};
X
X#ifdef USE_DECNET
Xclass DECnetSocket : public virtual Socket {
Xpublic:
X	DECnetSocket(SocketType st) : Socket(AfDECnet,st) {};	
X	int accept(DECnetSocket &newsocket);
X	int open(const char *node, int obj);
X	int open(const char *node, const char *obj);
X	int open(int obj);			 	// server
Xprivate:
X	struct sockaddr_dn 	client_addr, server_addr;
X	int			clen,slen;
X	int			object;
X	struct dn_naddr 	*node_addr;
X        struct nodeent		*nodep;
X
X};
X#endif
X
Xclass TransportStream : public virtual Transport {
X  public:
X	TransportStream() {}
X	virtual ~TransportStream() {};
X};
X
Xclass SocketStream : public virtual Socket,public virtual TransportStream {
Xpublic:
X	SocketStream(AddressFamily af) : Socket(af, Stream) {}
X	~SocketStream() {}
X};
X
Xclass UnixStream : public virtual UnixSocket, public virtual SocketStream {
Xpublic:
X	UnixStream() : Socket(AfUnix,Stream), SocketStream(AfUnix),UnixSocket(Stream) {}
X	int open(const char *path, SocketSex sex) {
X		return UnixSocket::open(path,sex);
X	}
X	int accept(UnixStream &newstream) {
X		return UnixSocket::accept(newstream);
X	}
X	int close() { 
X		return UnixSocket::close(); 
X	}
X};
X
Xclass InetStream :public virtual InetSocket, public virtual SocketStream {
Xpublic:						
X	InetStream() : Socket(AfInet,Stream), SocketStream(AfInet),InetSocket(Stream) { }
X 	int accept(InetStream &newstream) {
X		return InetSocket::accept(newstream);
X	}
X	int socket_server(const InetAddress &ia);
X	int socket_client(const InetAddress &ia);
X};
X
X#ifdef USE_DECNET
Xclass DECnetStream : public virtual DECnetSocket, public virtual SocketStream {
Xpublic:
X	DECnetStream() : Socket(AfDECnet,Stream), SocketStream(AfDECnet),DECnetSocket(Stream) {};	
X	int accept(DECnetStream &newstream) {
X		return DECnetSocket::accept(newstream);
X	}
X	int open(const char *node, int obj) {
X		return DECnetSocket::open(node,obj);
X	}
X	int open(const char *node, const char *obj) {
X		return DECnetSocket::open(node,obj);
X	}
X	int open(int obj) {
X		return DECnetSocket::open(obj);
X	}
X};
X
X#endif
X
Xclass TransportDatagram : public virtual Transport {
X  public:
X	TransportDatagram() {}
X	virtual ~TransportDatagram() {};
X};
X
Xclass SocketDatagram : public virtual Socket,public virtual TransportDatagram {
Xpublic:
X	SocketDatagram(AddressFamily af) : Socket(af, Datagram) {}
X	~SocketDatagram() {}
X};
X
Xclass InetDatagram :public virtual InetSocket, public virtual SocketDatagram {
Xpublic:						
X	InetDatagram() : Socket(AfInet,Datagram), 
X				SocketDatagram(AfInet),InetSocket(Datagram) { }
X 	int accept(InetDatagram &newsock) {
X		return InetSocket::accept(newsock);
X	}
X	int socket(); 
X	int socket_client();
X	int socket_server(const InetAddress &ia);
X};
X
X// endif TRANSPORT_CLASS_H
X#endif
END_OF_FILE
if test 8742 -ne `wc -c <'Transport/src/Transport.h'`; then
    echo shar: \"'Transport/src/Transport.h'\" unpacked with wrong size!
fi
# end of 'Transport/src/Transport.h'
fi
echo shar: End of archive 3 \(of 3\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Roland J. Schemers III                              Systems Programmer 
schemers@vela.acs.oakland.edu (Ultrix)              Oakland University 
schemers@argo.acs.oakland.edu (VMS)                 Rochester, MI 48309-4401
"As long as the systems are up, I get to sleep in!" (313)-370-4323