socket-emulation - socket emulation library for xenix (SYSV)

pgd at bbt.se pgd at bbt.se
Thu Dec 20 06:59:04 AEST 1990


Here is a hack I made, when I was tired of always missing those
sockets. It is only tested on a few programs, and not deeply either.
Prerequsites are UNIX SYSV, named pipes and file locks.
Xenix and gcc helps. 

#!/bin/sh
# This is socket-emulation, a shell archive (shar 3.32)
# made 12/19/1990 19:56 UTC by pgd at compuram.bbt.se
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   4223 -rw-rw---- README
#   3259 -rw-rw---- accept.c
#   1934 -rw-rw---- bind.c
#   3270 -rw-rw---- connect.c
#    909 -rw-rw---- hostbyaddr.c
#    898 -rw-rw---- hostbyname.c
#    643 -rw-rw---- getpeername.c
#    621 -rw-rw---- getsockname.c
#    995 -rw-rw---- getsockopt.c
#    428 -rw-rw---- listen.c
#    923 -rw-rw---- setsockopt.c
#   3109 -rw-rw---- socket.c
#   1427 -rw-rw---- soclose.c
#    874 -rw-rw---- soread.c
#    483 -rw-rw---- sowrite.c
#   1211 -rw-rw---- soioctl.c
#   2664 -rw-rw---- netdb.h
#   4578 -rw--w---- socket.h
#   2068 -rw--w---- socketvar.h
#   1030 -rw-rw---- Makefile
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X		  Socket Emulation Library for SYSV
X		  ---------------------------------
X
XThis library emulates the BSD sockets with SYSV named pipes. It is
Xmeant as a drop-in for those who have no sockets, but still want to
Xuse programs using sockets. In particular, it was developed to get
XX-windows working on xenix without any networking (or streams).
X
XWARNING:
X--------
XThe whole package is a fast hack. Don't expect any miracles. I have no
Xaccess to an UNIX system with real pipes, and don't even have manual
Xpages for the functions, so the implementation is just an educated
Xguess. The functions might return the wrong error codes on failures,
Xetc. If you figure out something wrong, i am happy to hear about it.
XCurrently it is only working on a XENIX/386 2.3.2 system with gcc.
X
X
XINSTALLATION:
X-------------
XIf you have are running Xenix 2.3.2, and have gcc, you can just put
Xeverything in a directory, and type make. Gcc will give some warnings,
Xthat is allright, but the compilation should proceed nicely, and it
Xwill stop with the libsocket.a library ready.
XI put socket.h in /usr/include/sys, netdb.h in /usr/include, and
XSlibsocket.a in /lib/386. If you like that, you can just do a "make
Xinstall", as root. Otherwise you have to install manually.
X
XIf you don't have Xenix or gcc, it will probably not compile so
Xeasily.  Be prepared to do some hacking to get it going. I would
Xrecommend to start trying on something less than X-windows, unless you
Xreally like extra trouble.
X
X
XDESCRIPTION:
X------------
XEach socket is implemented as a pipe (fifo) in the /tmp directory. The
Xnames are generated uniquely, and have no significance outside the
Xsocket library. This pipe is the control channel. It is only read on,
Xnever written on by the socket creator.
X
XWhen you bind a name to the socket, a link is created to that pipe,
Xwith a name according to the bound name. The client program can later
Xconnect to that socket, and the communication channel is created as
Xtwo more pipes (with unique names) in the /tmp directory. Two pipes
Xare needed since sockets are bi-directional, but pipes only
Xuni-directional. The hand-shaking between the two processes go through
Xthe respective control pipes, created by the socket() call.
X
XAll in all, each socket connection uses 4 pipes. One each as control
Xchannels for the sockets (in the two processes), and one each for the
Xdata transfer.
X
XThe file descriptor returned by the socket() call, is connected to the
Xread channel, when the connection is established. But you should avoid
Xusing any i/o calls on that file descriptor directly. The read(),
Xwrite(), ioctl(), and close() procedures are defined as macros in the
Xsocket.h file, and are redirected to the procedures soread(),
Xsowrite(), soioctl() and soclose(). If the i/o is going to a socket
Xfile descriptor, those procedures takes care of redirecting the
Xfunction to the correct i/o channel, otherwise they just to the same
Xthing as their normal counterparts.
X
XThis means that in every c-file where you do a read(), write(),
Xioctl() or close() on a file, which is a socket, you have to include
Xsocket.h. This is normally always the case anyway.
X
XOnly two address families are defined AF_UNIX and AF_INET. Inet
Xsockets all go to the same machine.
X
XDIFFERENCES:
X------------
XThere is no <netinet/in.h> file. The definitions in that file is
Xincluded in socket.h, so you can normally just comment out any
Xreferences to it. The same for un.h
XThere is a symbol SOCKET_EMULATION defined by socket.h, that can be
Xused for conditional compilation in the c files.
XThe error numbers are completely different from the BSD ones.
X
X
XBUGS:
X-----
Xselect() should be trapped also. as it is now, select() on writes
Xdoes not work.
X
X
XCOPYRIGHTS:
X----------- 
XCopyright on a hack? Are you kidding?  Some parts were snatched from
Xthe BSD tahoe distribution. Maybe their copyright should be somewhere.
XI guess a warning is enough. But as all source is very heavily munged,
Xi figured it is so different, so that there is hardly any similarity.
XTry grepping on the comments. Maybe one, or two, are left from the bsd
Xfiles. 
X
XMY ADDRESS:
X-----------
XI would be happy to hear some feedback about problems. My e-mail
Xaddress is: pgd at compuram.bbt.se
X
X
XP.Garbha
SHAR_EOF
$TOUCH -am 1219204390 README &&
chmod 0660 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "4223"; then
	echo original size 4223, current size $Wc_c
fi
# ============= accept.c ==============
echo "x - extracting accept.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > accept.c &&
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/param.h>
X#include <sys/stat.h>
X#include <sys/fcntl.h>
X#include <memory.h>
X#include <malloc.h>
X#include <errno.h>
X#include <prototypes.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xstatic int doconnect(struct socket *so);
Xstatic struct socket_packet msg;
X
Xint
Xaccept(int s, struct sockaddr *name, int *anamelen)
X{
X	register struct socket *so;
X	int cc, fd, e;
X
X	if ((so = GETSOCKET(s)) == NULL)
X		return -1;
X	if ((so->so_options & SO_ACCEPTCONN) == 0) {
X		errno = EINVAL;
X		return -1;
X	}
X	/*
X	 * Read a packet from the pipe
X	 */
X	cc = read(so->so_fd, (char *)&msg, sizeof(msg));
X	if (cc == 0 && so->so_state & SS_NBIO) {
X		errno = EWOULDBLOCK;
X		return -1;
X	}
X	if (cc == -1)
X		return -1;
X	if (msg.scm_magic != SOCKET_MAGIC) {
X		/* Garbage block. Do nothing */
X		errno = EIO;
X		return -1;
X	}
X
X	/*
X	 * Dispatch on packet type
X	 */
X	switch (msg.scm_msg) {
X	case MSG_CONNECT:
X		if ((fd = doconnect(so)) != -1) {
X			so = GETSOCKET(fd);
X			*anamelen = SOCKADDRLEN(so->so_conn);
X			memcpy((char *)name, (char *)so->so_conn, *anamelen);
X			return fd;
X		}
X	case MSG_DISCONNECT:
X		e = _sodisconnect2(so);
X		errno = ECONNABORTED;
X		return -1;
X
X	default:
X		errno = EOPNOTSUPP;
X		return -1;
X	}
X}
X
X	
Xstatic int
Xdoconnect(register struct socket *so)
X{
X	register struct socket *so2;
X	int rfd, wfd, sofd, pfd;
X	char twname[20], trname[20];
X	int peersotype;
X	int cc;
X
X	/*
X	 * Open up our side of the socket files.
X	 * Note that read and write sides are swapped.
X	 *
X	 */
X	sprintf(twname, "/tmp/%s", msg.scm_wname);
X	if ((rfd = open(twname, O_RDWR)) == -1)
X		return -1;
X	fcntl(rfd, F_SETFD, O_RDONLY);
X	sprintf(trname, "/tmp/%s", msg.scm_rname);
X	if ((wfd = open(trname, O_RDWR)) == -1) {
X		close(rfd);
X		return -1;
X	}
X	fcntl(wfd, F_SETFD, O_WRONLY);
X	if ((pfd = open(msg.scm_addr.un.sun_path, O_RDWR)) == -1) {
X		close(rfd); close(wfd);
X		return -1;
X	}
X
X	/*
X	 * Connection established. Pass back
X	 * our message.
X	 */
X	msg.scm_magic = SOCKET_MAGIC;
X	peersotype = msg.scm_type;
X	msg.scm_type = so->so_type;
X	msg.scm_msg = peersotype == so->so_type ? MSG_CONNECT_OK : MSG_FAIL;
X	memcpy((char *)&msg.scm_addr, (char *)so->so_addr, SOCKADDRLEN(so->so_addr));
X	cc = write(pfd, (char *)&msg, sizeof msg);
X	if (cc == -1)
X		goto bad;
X	if (cc != sizeof msg) {
X		errno = EIO;
X		goto bad;
X	}
X	if (peersotype != so->so_type) {
X		errno = EPROTOTYPE;
X		goto bad;
X	}
X
X	if ((sofd = socket(so->so_domain, so->so_type, so->so_protocol)) == -1)
X		goto bad;
X	/*
X	 * Juggle around the file descriptors so that the socket
X	 * fd refers to the read pipe.
X	 */
X	so2 = GETSOCKET(sofd);
X	sofd = dup(so->so_fd);
X	if (sofd == -1) {
X		soclose(sofd);
X		goto bad;
X	}
X	rfd = dup2(rfd, so2->so_fd);
X	if (rfd == -1) {
X		close(sofd);
X		soclose(sofd);
X		goto bad;
X	}
X	so2->so_fd = sofd;
X	so2->so_rfd = rfd;
X	so2->so_wfd = wfd;
X	so2->so_pfd = pfd;
X	so2->so_addr = NULL;
X	so2->so_conn = (struct sockaddr *)malloc(SOCKADDRLEN(so->so_addr));
X	memcpy((char *)so2->so_conn, (char *)&msg.scm_addr, SOCKADDRLEN(so->so_addr));
X	so2->so_rname = strdup(msg.scm_wname);
X	so2->so_wname = strdup(msg.scm_rname);
X	so2->so_state |= SS_ISCONNECTED;
X	return rfd;
X
Xbad:
X	close(rfd); close(wfd); close(pfd);
X	unlink(trname); unlink (twname);
X	return -1;
X}
X
X
SHAR_EOF
$TOUCH -am 1215095190 accept.c &&
chmod 0660 accept.c ||
echo "restore of accept.c failed"
set `wc -c accept.c`;Wc_c=$1
if test "$Wc_c" != "3259"; then
	echo original size 3259, current size $Wc_c
fi
# ============= bind.c ==============
echo "x - extracting bind.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > bind.c &&
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <memory.h>
X#include <sys/errno.h>
X#include <prototypes.h>
X#include <errno.h>
X#include <sys/fcntl.h>
X#include "socket.h"
X#include "socketvar.h"
X
X/*
X * Bind an address to an already defined socket.
X * AF_UNIX sockets can be located anywhere in the file
X * structure. The file according to the pathname is linked to
X * the socket pipe created by socket().
X * AF_INET sockets are simulated by a file in the /usr/spool/socket
X * directory, unique according to the socket number
X * AF_UNSPEC sockets use the original pipe created by socket().
X */
Xint
Xbind(int sofd, struct sockaddr *name, int namelen)
X{
X	register struct socket *so;
X	char *path;
X	int fd, e;
X
X	if ((so = GETSOCKET(sofd)) == NULL)
X		return -1;
X	if (so->so_state & SS_ISCONNECTED) {
X		errno = EADDRINUSE;
X		return -1;
X	}
X	if (so->so_domain != name->sa_family) {
X		errno = EPROTOTYPE;
X		return -1;
X	}
X	if (so->so_addr != NULL) {
X		errno = EADDRINUSE;
X		return -1;
X	}
X	/*
X	 * Create a link to the socket according to the
X	 * address given.
X	 */
X	if (name->sa_family != AF_UNSPEC) {
X		path = _socketname(name);
X		if (path == NULL) {
X			errno = EOPNOTSUPP;
X			return -1;
X		}
X		if (link(so->so_name, path) == -1) {
X			if (errno != EEXIST)
X				return -1;
X			/*
X			 * Socket address exists. Check if it is bound
X			 * to an active socket, or just "left around"
X			 */
X			fd = open(path, O_RDWR);
X			if (fd == -1)
X				return -1;
X			e = _checksolock(fd, 0);
X			if (e == -1) {
X				close(fd);
X				return -1;
X			}
X			if (e) {
X				errno = EADDRINUSE;
X				close(fd);
X				return -1;
X			}
X			/*
X			 * The socked file is free. Delete it, and
X			 * try the bind it to the socket again.
X			 */
X			close(fd);
X			unlink(path);
X			if (link(so->so_name, path) == -1)
X				return -1;
X		}
X	}
X	so->so_addr = (struct sockaddr *)malloc(namelen);
X	memcpy((char *)so->so_addr, (char *)name, namelen);
X	return 0;
X}
SHAR_EOF
$TOUCH -am 1215055390 bind.c &&
chmod 0660 bind.c ||
echo "restore of bind.c failed"
set `wc -c bind.c`;Wc_c=$1
if test "$Wc_c" != "1934"; then
	echo original size 1934, current size $Wc_c
fi
# ============= connect.c ==============
echo "x - extracting connect.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > connect.c &&
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <memory.h>
X#include <sys/fcntl.h>
X#include <errno.h>
X#include <prototypes.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xstatic int seq = 1;
X
Xint
Xconnect(int s, struct sockaddr *name, int namelen)
X{
X	register struct socket *so;
X	int pid, cc;
X	char rname[15], wname[15], trname[20], twname[20];
X	int rfd, wfd;
X	struct socket_packet msg;
X	char *path;
X	int pfd, sofd;
X
X	if ((so = GETSOCKET(s)) == NULL)
X		return -1;
X	if (so->so_options & SO_ACCEPTCONN) {
X		errno = EOPNOTSUPP;
X		return -1;
X	}
X	/*
X	 * Can connect only once, otherwise, try to disconnect first.
X	 * This allows user to disconnect by connecting to, e.g.,
X	 * a null address.
X	 */
X	if (so->so_state & SS_ISCONNECTED) {
X		if (_sodisconnect(so) < 0) {
X			errno = EISCONN;
X			return -1;
X		}
X	}
X
X	/*
X	 * Now find socket to connect to, 
X	 */
X	path = _socketname(name);
X	if (path == NULL) {
X		errno = EOPNOTSUPP;
X		return -1;
X	}
X	if ((pfd = open(path, O_RDWR)) == -1)
X		return -1;
X	fcntl(rfd, F_SETFD, O_WRONLY);
X
X	/*
X	 * Check if other side is listening
X	 */
X	if (_checksolock(pfd, SO_ACCEPTCONN) == -1) {
X		errno = ENOTCONN;
X		close(pfd);
X		return -1;
X	}
X
X	/*
X	 * Other side is listening. Set up the socket
X	 * data channels.
X	 */
X	pid = getpid();
X	sprintf(rname, "SR.%d.%d", pid, ++seq);
X	sprintf(trname, "/tmp/%s", rname);
X	sprintf(wname, "SW.%d.%d", pid, seq);
X	sprintf(twname, "/tmp/%s", wname);
X	if (mknod(trname, S_IFIFO|0777, 0) == -1 ||
X	    mknod(twname, S_IFIFO|0777, 0) == -1)
X		goto bad3;
X	if ((rfd = open(trname, O_RDWR)) == -1)
X		goto bad2;
X	fcntl(rfd, F_SETFD, O_RDONLY);
X	if ((wfd = open(twname, O_RDWR)) == -1)
X		goto bad1;
X	fcntl(wfd, F_SETFD, O_WRONLY);
X	/*
X	 * Now send a message telling that we want to connect
X	 */
X	msg.scm_magic = SOCKET_MAGIC;
X	msg.scm_msg = MSG_CONNECT;
X	msg.scm_type = so->so_type;
X	strcpy(msg.scm_rname, rname);
X	strcpy(msg.scm_wname, wname);
X	strcpy((char *)&msg.scm_addr.un.sun_path, so->so_name);
X	cc = write(pfd, (char *)&msg, sizeof(msg));
X	if (cc == -1)
X		goto bad;
X	if (cc != sizeof(msg)) {
X		errno = EPIPE; goto bad;
X	}
X
X	/*
X	 * Message sent. Now we have to receive a message
X	 * on our socket pipe, to finalize the handshake.
X	 */
X	cc = read(so->so_fd, (char *)&msg, sizeof(msg));
X	if (cc == -1)
X		goto bad;
X	if (cc != sizeof(msg) || msg.scm_magic != SOCKET_MAGIC) {
X		errno = EIO;
X		goto bad;
X	}
X	if (msg.scm_msg != MSG_CONNECT_OK) {
X		errno = ECONNREFUSED;
X		goto bad;
X	}
X	if (so->so_type != msg.scm_type) {
X		errno = EPROTOTYPE;
X		goto bad;
X	}
X
X	/*
X	 * Juggle around the file descriptors so that the socket
X	 * fd refers to the read pipe.
X	 */
X	sofd = dup(so->so_fd);
X	if (sofd == -1)
X		goto bad;
X	rfd = dup2(rfd, so->so_fd);
X	if (rfd == -1) {
X		close(sofd);
X		goto bad;
X	}
X	so->so_conn = (struct sockaddr *)malloc(SOCKADDRLEN(&msg.scm_addr.sa));
X	memcpy((char *)so->so_conn, (char *)&msg.scm_addr, SOCKADDRLEN(&msg.scm_addr.sa));
X	so->so_state |= SS_ISCONNECTED;
X	so->so_rname = strdup(rname);
X	so->so_wname = strdup(wname);
X	so->so_rfd = rfd;
X	so->so_wfd = wfd;
X	so->so_pfd = pfd;
X	so->so_fd = sofd;
X	return 0;
X
Xbad:	close(wfd); 
Xbad1:	close(rfd);
Xbad2:	unlink(trname); unlink(twname);
Xbad3:	close(pfd);
X	so->so_rfd = so->so_wfd = so->so_pfd = -1;
X	return -1;
X}
X
SHAR_EOF
$TOUCH -am 1215093790 connect.c &&
chmod 0660 connect.c ||
echo "restore of connect.c failed"
set `wc -c connect.c`;Wc_c=$1
if test "$Wc_c" != "3270"; then
	echo original size 3270, current size $Wc_c
fi
# ============= hostbyaddr.c ==============
echo "x - extracting hostbyaddr.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > hostbyaddr.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/utsname.h>
X#include "netdb.h"
X#include "socket.h"
X
Xstatic int hassysname;
Xstatic struct utsname sysname;
Xint h_errno;
X
Xstruct hostent *
Xgethostbyaddr(struct sockaddr *host)
X{
X	static struct hostent hent;
X	static struct sockaddr_in inaddr;
X
X	if (!hassysname) {
X		if (uname(&sysname) == -1)
X			return NULL;
X		hassysname = 1;
X	}
X	/*
X	 * Here, the host name must match the current host
X	 * for the function to work.
X	 * As an alternative, we can map all host names
X	 * to the current host.
X	 */
X#if 0
X	if (strcmp(host, sysname.nodename) == 0) {
X#endif
X		hent.h_name = sysname.nodename;
X		hent.h_aliases = NULL;
X		hent.h_addrtype = AF_INET;
X		hent.h_length = 1;
X		hent.h_addr = &inaddr;
X		inaddr.sin_family = AF_INET;
X		inaddr.sin_port = 0;
X		inaddr.sin_addr.s_addr = 0;
X		return &hent;
X#if 0
X	} else {
X		h_errno = HOST_NOT_FOUND;
X		return NULL;
X	}
X#endif
X}
SHAR_EOF
$TOUCH -am 1215115390 hostbyaddr.c &&
chmod 0660 hostbyaddr.c ||
echo "restore of hostbyaddr.c failed"
set `wc -c hostbyaddr.c`;Wc_c=$1
if test "$Wc_c" != "909"; then
	echo original size 909, current size $Wc_c
fi
# ============= hostbyname.c ==============
echo "x - extracting hostbyname.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > hostbyname.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/utsname.h>
X#include "netdb.h"
X#include "socket.h"
X
Xstatic int hassysname;
Xstatic struct utsname sysname;
Xint h_errno;
X
Xstruct hostent *
Xgethostbyname(char *host)
X{
X	static struct hostent hent;
X	static struct sockaddr_in inaddr;
X
X	if (!hassysname) {
X		if (uname(&sysname) == -1)
X			return NULL;
X		hassysname = 1;
X	}
X	/*
X	 * Here, the host name must match the current host
X	 * for the function to work.
X	 * As an alternative, we can map all host names
X	 * to the current host.
X	 */
X#if 0
X	if (strcmp(host, sysname.nodename) == 0) {
X#endif
X		hent.h_name = sysname.nodename;
X		hent.h_aliases = NULL;
X		hent.h_addrtype = AF_INET;
X		hent.h_length = 1;
X		hent.h_addr = &inaddr;
X		inaddr.sin_family = AF_INET;
X		inaddr.sin_port = 0;
X		inaddr.sin_addr.s_addr = 0;
X		return &hent;
X#if 0
X	} else {
X		h_errno = HOST_NOT_FOUND;
X		return NULL;
X	}
X#endif
X}
SHAR_EOF
$TOUCH -am 1214084890 hostbyname.c &&
chmod 0660 hostbyname.c ||
echo "restore of hostbyname.c failed"
set `wc -c hostbyname.c`;Wc_c=$1
if test "$Wc_c" != "898"; then
	echo original size 898, current size $Wc_c
fi
# ============= getpeername.c ==============
echo "x - extracting getpeername.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > getpeername.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <errno.h>
X#include <prototypes.h>
X#include <string.h>
X#include <memory.h>
X#include "socket.h"
X#include "socketvar.h"
X
X/*
X * Get name of peer for connected socket.
X */
Xint
Xgetpeername(int fdes, struct sockaddr *asa, int *alen)
X{
X	register struct socket *so;
X	int len;
X
X	if ((so = GETSOCKET(fdes)) == NULL)
X		return -1;
X	if (so->so_conn) {
X		len = so->so_conn->sa_family == AF_UNIX
X			? strlen(((struct sockaddr_un *)so->so_conn)->sun_path)
X				+ 1 + sizeof(short)
X			: sizeof(struct sockaddr);
X		*alen = len;
X		memcpy((char *)asa, (char *)so->so_conn, len);
X	} else
X		*alen = 0;
X	return 0;
X}
X
SHAR_EOF
$TOUCH -am 1213151490 getpeername.c &&
chmod 0660 getpeername.c ||
echo "restore of getpeername.c failed"
set `wc -c getpeername.c`;Wc_c=$1
if test "$Wc_c" != "643"; then
	echo original size 643, current size $Wc_c
fi
# ============= getsockname.c ==============
echo "x - extracting getsockname.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > getsockname.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <errno.h>
X#include <prototypes.h>
X#include <string.h>
X#include <memory.h>
X#include "socket.h"
X#include "socketvar.h"
X
X/*
X * Get socket name.
X */
Xint
Xgetsockname(int fdes, struct sockaddr *asa, int *alen)
X{
X	register struct socket *so;
X	int len;
X
X	if ((so = GETSOCKET(fdes)) == NULL)
X		return -1;
X	if (so->so_addr) {
X		len = so->so_addr->sa_family == AF_UNIX
X			? strlen(((struct sockaddr_un *)so->so_addr)->sun_path)
X				+ 1 + sizeof(short)
X			: sizeof(struct sockaddr);
X		*alen = len;
X		memcpy((char *)asa, (char *)so->so_addr, len);
X	} else
X		*alen = 0;
X	return 0;
X}
X
SHAR_EOF
$TOUCH -am 1213151490 getsockname.c &&
chmod 0660 getsockname.c ||
echo "restore of getsockname.c failed"
set `wc -c getsockname.c`;Wc_c=$1
if test "$Wc_c" != "621"; then
	echo original size 621, current size $Wc_c
fi
# ============= getsockopt.c ==============
echo "x - extracting getsockopt.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > getsockopt.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <errno.h>
X#include <prototypes.h>
X#include <string.h>
X#include <memory.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xgetsockopt(int s, int level, int name, int *val, int *avalsize)
X{
X	struct socket *so;
X
X	if ((so = GETSOCKET(s)) == NULL)
X		return -1;
X	if (level != SOL_SOCKET) {
X		errno = ENOPROTOOPT;
X		return -1;
X	}
X	switch (name) {
X	case SO_LINGER:
X	case SO_USELOOPBACK:
X	case SO_DONTROUTE:
X	case SO_DEBUG:
X	case SO_KEEPALIVE:
X	case SO_REUSEADDR:
X	case SO_BROADCAST:
X	case SO_OOBINLINE:
X		*val = so->so_options & name;
X		*avalsize = sizeof(so->so_options);
X		break;
X
X	case SO_TYPE:
X		*val = so->so_type;
X		*avalsize = sizeof(so->so_type);
X		break;
X
X	case SO_ERROR:
X		*val = 0;
X		*avalsize = sizeof(int);
X		break;
X
X	case SO_SNDBUF:
X	case SO_RCVBUF:
X	case SO_SNDLOWAT:
X	case SO_RCVLOWAT:
X	case SO_SNDTIMEO:
X	case SO_RCVTIMEO:
X		*val = 0;
X		*avalsize = sizeof(int);
X		break;
X
X	default:
X		errno = ENOPROTOOPT;
X		return -1;
X	}
X	return 0;
X}
X
SHAR_EOF
$TOUCH -am 1213151890 getsockopt.c &&
chmod 0660 getsockopt.c ||
echo "restore of getsockopt.c failed"
set `wc -c getsockopt.c`;Wc_c=$1
if test "$Wc_c" != "995"; then
	echo original size 995, current size $Wc_c
fi
# ============= listen.c ==============
echo "x - extracting listen.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > listen.c &&
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <memory.h>
X#include <prototypes.h>
X#include <errno.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xlisten(int s, int backlog)
X{
X	register struct socket *so;
X
X	if ((so = GETSOCKET(s)) == NULL)
X		return -1;
X	if (_setsolock(s, SO_ACCEPTCONN) == -1) {
X		errno = EALREADY;
X		return -1;
X	}
X	so->so_options |= SO_ACCEPTCONN;
X	return 0;
X}
X
SHAR_EOF
$TOUCH -am 1213151590 listen.c &&
chmod 0660 listen.c ||
echo "restore of listen.c failed"
set `wc -c listen.c`;Wc_c=$1
if test "$Wc_c" != "428"; then
	echo original size 428, current size $Wc_c
fi
# ============= setsockopt.c ==============
echo "x - extracting setsockopt.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > setsockopt.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <errno.h>
X#include <prototypes.h>
X#include <string.h>
X#include <memory.h>
X#include "socket.h"
X#include "socketvar.h"
X
X/*
X * Most socket options are no-ops
X * but we set them anyway, so that a getsockopt can
X * read them back.
X */
Xint
Xsetsockopt(int s, int level, int name, char *val, int valsize)
X{
X	struct socket *so;
X
X	if ((so = GETSOCKET(s)) == NULL)
X		return -1;
X	if (level != SOL_SOCKET) {
X		errno = ENOPROTOOPT;
X		return -1;
X	}
X	switch (name) {
X	case SO_LINGER:
X	case SO_DEBUG:
X	case SO_KEEPALIVE:
X	case SO_DONTROUTE:
X	case SO_USELOOPBACK:
X	case SO_BROADCAST:
X	case SO_REUSEADDR:
X	case SO_OOBINLINE:
X		if (*val)
X			so->so_options |= name;
X		else
X			so->so_options &= ~name;
X		break;
X		
X	case SO_SNDBUF:
X	case SO_RCVBUF:
X	case SO_SNDLOWAT:
X	case SO_RCVLOWAT:
X	case SO_SNDTIMEO:
X	case SO_RCVTIMEO:
X		break;
X
X	default:
X		errno = ENOPROTOOPT;
X		break;
X	}
X	return 0;
X}
X
X
SHAR_EOF
$TOUCH -am 1213151590 setsockopt.c &&
chmod 0660 setsockopt.c ||
echo "restore of setsockopt.c failed"
set `wc -c setsockopt.c`;Wc_c=$1
if test "$Wc_c" != "923"; then
	echo original size 923, current size $Wc_c
fi
# ============= socket.c ==============
echo "x - extracting socket.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > socket.c &&
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/param.h>
X#include <sys/fcntl.h>
X#include <memory.h>
X#include <malloc.h>
X#include <prototypes.h>
X#include <errno.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xstruct socket *_socktab[NOFILE];
Xfd_set _socketmap;		/* File descriptor map */
Xstatic int seq = 0;		/* Sequence number for file creation */
X
X/*
X * Sockets are emulated by named pipes. A socket is characterized
X * by a file in the "/usr/spool/socket" directory.
X * The filename is randomly generated to always be unique.
X * The actual connection consist of two other named pipe files
X * in the "/tmp" directory. Since there is only one channel
X * for the pipes, we need two pipes to simulate one socket.
X */
Xint
Xsocket(int domain, int type, int protocol)
X{
X	register struct socket *so;
X	int sofd;
X	char soname[30];
X
X	if ((domain != AF_UNIX && domain != AF_INET)
X	    || type != SOCK_STREAM || protocol != 0) {
X		 errno = EPROTONOSUPPORT;
X		 return NULL;
X	}
X	if ((so = (struct socket *)malloc(sizeof(struct socket))) == NULL)
X		return NULL;
X	so->so_options = 0;
X	so->so_state = 0;
X	so->so_type = type;
X	so->so_rfd = so->so_wfd = so->so_pfd = -1;
X	so->so_domain = domain;
X	so->so_protocol = protocol;
X	so->so_rname = so->so_wname = NULL;
X	so->so_conn = NULL;
X
X	/*
X	 * create the main socket pipe
X	 */
X	sprintf(soname, "/tmp/SO.%d.%d", getpid(), ++seq);
X	if (mknod(soname, S_IFIFO|0777, 0) == -1) {
X		free((char *)so);
X		return -1;
X	}
X	if ((sofd = open(soname, O_RDWR)) == -1) {
X		unlink(soname); free((char *)so); 
X		return -1;
X	}
X	fcntl(sofd, F_SETFD, O_RDONLY);
X	so->so_name = strdup(soname);
X	so->so_fd = sofd;
X	FD_SET(sofd, &_socketmap);
X	_socktab[sofd] = so;
X
X	/*
X	 * Indicate socket is active
X	 */
X	_setsolock(sofd, 0);
X	return sofd;
X}
X
X/*
X * To be able to have a few status bits for the pipe files
X * we use file locks, at a high address.
X * "_setsolock" can be used to set a flag, and "_checksolock" to
X * examine the state of the flag.
X */
Xint
X_setsolock(int fd, int type)
X{
X	struct flock lockblk;
X
X	lockblk.l_type = F_WRLCK;
X	lockblk.l_whence = 0;
X	lockblk.l_start = type + 10000000L;
X	lockblk.l_len = 1;
X	return fcntl(fd, F_SETLK, &lockblk);
X}
X
Xint
X_clearsolock(int fd, int type)
X{
X	struct flock lockblk;
X
X	lockblk.l_type = F_UNLCK;
X	lockblk.l_whence = 0;
X	lockblk.l_start = type + 10000000L;
X	lockblk.l_len = 1;
X	return fcntl(fd, F_SETLK, &lockblk);
X}
X
X/*
X * Check for a lock.
X * Returns:
X *	-1 if error
X *	0 if no lock
X *	1 if lock
X */
Xint
X_checksolock(int fd, long type)
X{
X	struct flock lockblk;
X
X	lockblk.l_type = F_WRLCK;
X	lockblk.l_whence = 0;
X	lockblk.l_start = type + 10000000L;
X	lockblk.l_len = 1;
X	if (fcntl(fd, F_GETLK, &lockblk) == -1)
X		return -1;
X	return lockblk.l_type != F_UNLCK;
X}
X
Xchar *
X_socketname(struct sockaddr *addr)
X{
X	static char path[108];
X
X	switch (addr->sa_family) {
X	case AF_UNIX:
X		strcpy(path, ((struct sockaddr_un *)addr)->sun_path);
X		break;
X
X	case AF_INET:
X		sprintf(path, "/usr/spool/socket/PORT.%d",
X			(unsigned)((struct sockaddr_in *)addr)->sin_port);
X		break;
X	default:
X		return NULL;
X	}
X	return path;
X}
SHAR_EOF
$TOUCH -am 1215094190 socket.c &&
chmod 0660 socket.c ||
echo "restore of socket.c failed"
set `wc -c socket.c`;Wc_c=$1
if test "$Wc_c" != "3109"; then
	echo original size 3109, current size $Wc_c
fi
# ============= soclose.c ==============
echo "x - extracting soclose.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > soclose.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <prototypes.h>
X#include <errno.h>
X#include <malloc.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xsoclose(int fildes)
X{
X	register struct socket *so;
X
X	if ((so = GETSOCKET(fildes)) == NULL)
X		return -1;
X	if (so->so_state & SS_ISCONNECTED) {
X		if (_sodisconnect(so) == -1)
X			return -1;
X	}
X	close(so->so_fd);
X	unlink(so->so_name);
X	if (so->so_name)
X		free((char *)so->so_name);
X	if (so->so_addr)
X		free((char *)so->so_addr);
X	_socktab[fildes] = NULL;
X	free((char *)so);
X	return 0;
X}
X
X/*
X * Disconnect socket connection, and notify other side.
X */
Xint
X_sodisconnect(so)
X	register struct socket *so;
X{
X	struct socket_packet msg;
X	int cc;
X
X	if ((so->so_state & SS_ISCONNECTED) == 0) {
X		errno = ENOTCONN;
X		return -1;
X	}
X	msg.scm_magic = SOCKET_MAGIC;
X	msg.scm_msg = MSG_DISCONNECT;
X	msg.scm_type = so->so_type;
X	cc = write(so->so_pfd, (char *)&msg, sizeof(msg));
X	return _sodisconnect2(so);
X}
X
X/*
X * Come here if socket should be disconnected without 
X * notifying the other side.
X */
Xint
X_sodisconnect2(register struct socket *so)
X{
X	char fname[80];
X
X	if (so->so_state & SS_ISCONNECTED) {
X		close(so->so_rfd);
X		close(so->so_wfd);
X		close(so->so_pfd);
X		sprintf(fname, "/tmp/%s", so->so_rname);
X		unlink(fname);
X		sprintf(fname, "/tmp/%s", so->so_wname);
X		unlink(fname);
X		free((char *)so->so_conn);
X		so->so_conn = NULL;
X		so->so_state &= ~SS_ISCONNECTED;
X	}
X	return 0;
X}
X
SHAR_EOF
$TOUCH -am 1215095390 soclose.c &&
chmod 0660 soclose.c ||
echo "restore of soclose.c failed"
set `wc -c soclose.c`;Wc_c=$1
if test "$Wc_c" != "1427"; then
	echo original size 1427, current size $Wc_c
fi
# ============= soread.c ==============
echo "x - extracting soread.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > soread.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <fcntl.h>
X#include <errno.h>
X#include <prototypes.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xsoread(int fildes, char *buf, int nbytes)
X{
X	register struct socket *so;
X	int cc;
X
X	if ((so = GETSOCKET(fildes)) == NULL)
X		return -1;
X	if ((so->so_state & SS_ISCONNECTED) == 0) {
X		errno = ENOTCONN;
X		return -1;
X	}
X	cc = read(so->so_rfd, buf, nbytes);
X	if (cc == 0 && (so->so_state & SS_NBIO) == 0) {
X		/*
X		 * Use may have set FNDELAY with a fcntl.
X		 * check it out here. The other solution would
X		 * be to trap the fcntls, and check the arguments.
X		 */
X		if (fcntl(so->so_rfd, F_GETFL, 0) & O_NDELAY)
X			so->so_state |= SS_NBIO;
X		else {
X			/*
X			 * Why did we come here?
X			 * Maybe connection is severed.
X			 */
X		}
X	}
X	if (so->so_state & SS_NBIO && cc == 0) {
X		errno = EWOULDBLOCK;
X		return -1;
X	}
X	return cc;
X}
SHAR_EOF
$TOUCH -am 1219124090 soread.c &&
chmod 0660 soread.c ||
echo "restore of soread.c failed"
set `wc -c soread.c`;Wc_c=$1
if test "$Wc_c" != "874"; then
	echo original size 874, current size $Wc_c
fi
# ============= sowrite.c ==============
echo "x - extracting sowrite.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > sowrite.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <errno.h>
X#include <prototypes.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xsowrite(int fildes, char *buf, int nbytes)
X{
X	register struct socket *so;
X	int cc;
X
X	if ((so = GETSOCKET(fildes)) == NULL)
X		return -1;
X	if ((so->so_state & SS_ISCONNECTED) == 0) {
X		errno = ENOTCONN;
X		return -1;
X	}
X	cc = write(so->so_wfd, buf, nbytes);
X	if (so->so_state & SS_NBIO && cc == 0) {
X		errno = EWOULDBLOCK;
X		return -1;
X	}
X	return cc;
X}
SHAR_EOF
$TOUCH -am 1213151790 sowrite.c &&
chmod 0660 sowrite.c ||
echo "restore of sowrite.c failed"
set `wc -c sowrite.c`;Wc_c=$1
if test "$Wc_c" != "483"; then
	echo original size 483, current size $Wc_c
fi
# ============= soioctl.c ==============
echo "x - extracting soioctl.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > soioctl.c &&
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/ioctl.h>
X#include <prototypes.h>
X#include <errno.h>
X#include <fcntl.h>
X#include "socket.h"
X#include "socketvar.h"
X
Xint
Xsoioctl(int fildes, int request, int *arg)
X{
X	register struct socket *so;
X	struct stat sbuf;
X
X	if ((so = GETSOCKET(fildes)) == NULL)
X		return -1;
X	switch (request) {
X	case FIOSNBIO:
X		if (*arg) {
X			if (so->so_fd != -1)
X				fcntl(so->so_fd, F_SETFL,
X				      fcntl(so->so_fd, F_GETFL, 0) | O_NDELAY);
X			if (so->so_rfd != -1)
X
X				fcntl(so->so_rfd, F_SETFL,
X				      fcntl(so->so_rfd, F_GETFL, 0) | O_NDELAY);
X			so->so_state |= SS_NBIO;
X		} else {
X			if (so->so_fd != -1)
X				fcntl(so->so_fd, F_SETFL,
X				      fcntl(so->so_fd, F_GETFL, 0) & ~O_NDELAY);
X			if (so->so_rfd != -1)
X				fcntl(so->so_rfd, F_SETFL,
X				      fcntl(so->so_rfd, F_GETFL, 0) & ~O_NDELAY);
X			so->so_state &= ~SS_NBIO;
X		}
X		break;
X		
X#ifdef FIOASYNC
X	case FIOASYNC:
X		if (*arg)
X			so->so_state |= SS_ASYNC;
X		else
X			so->so_state &= ~SS_ASYNC;
X		return (0);
X#endif
X
X	case FIONREAD:
X		if (fstat(so->so_rfd, &sbuf) == -1)
X			return -1;
X		*arg = sbuf.st_size;
X		return (0);
X
X	default:
X		errno = EOPNOTSUPP;
X		return -1;
X	}
X	return 0;
X}
X
X
SHAR_EOF
$TOUCH -am 1219123990 soioctl.c &&
chmod 0660 soioctl.c ||
echo "restore of soioctl.c failed"
set `wc -c soioctl.c`;Wc_c=$1
if test "$Wc_c" != "1211"; then
	echo original size 1211, current size $Wc_c
fi
# ============= netdb.h ==============
echo "x - extracting netdb.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > netdb.h &&
X/*
X * Copyright (c) 1980, 1983, 1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X *
X *	@(#)netdb.h	5.10 (Berkeley) 6/27/88
X */
X
X/*
X * Structures returned by network
X * data base library.  All addresses
X * are supplied in host order, and
X * returned in network order (suitable
X * for use in system calls).
X */
Xstruct	hostent {
X	char	*h_name;	/* official name of host */
X	char	**h_aliases;	/* alias list */
X	int	h_addrtype;	/* host address type */
X	int	h_length;	/* length of address */
X	char	**h_addr_list;	/* list of addresses from name server */
X#define	h_addr	h_addr_list[0]	/* address, for backward compatiblity */
X};
X
X/*
X * Assumption here is that a network number
X * fits in 32 bits -- probably a poor one.
X */
Xstruct	netent {
X	char		*n_name;	/* official name of net */
X	char		**n_aliases;	/* alias list */
X	int		n_addrtype;	/* net address type */
X	unsigned long	n_net;		/* network # */
X};
X
Xstruct	servent {
X	char	*s_name;	/* official service name */
X	char	**s_aliases;	/* alias list */
X	int	s_port;		/* port # */
X	char	*s_proto;	/* protocol to use */
X};
X
Xstruct	protoent {
X	char	*p_name;	/* official protocol name */
X	char	**p_aliases;	/* alias list */
X	int	p_proto;	/* protocol # */
X};
X
Xstruct hostent	*gethostbyname(), *gethostbyaddr(), *gethostent();
Xstruct netent	*getnetbyname(), *getnetbyaddr(), *getnetent();
Xstruct servent	*getservbyname(), *getservbyport(), *getservent();
Xstruct protoent	*getprotobyname(), *getprotobynumber(), *getprotoent();
X
X/*
X * Error return codes from gethostbyname() and gethostbyaddr()
X * (left in extern int h_errno).
X */
X
X#define	HOST_NOT_FOUND	1 /* Authoritative Answer Host not found */
X#define	TRY_AGAIN	2 /* Non-Authoritive Host not found, or SERVERFAIL */
X#define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
X#define	NO_DATA		4 /* Valid name, no data record of requested type */
X#define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
SHAR_EOF
$TOUCH -am 1213172690 netdb.h &&
chmod 0660 netdb.h ||
echo "restore of netdb.h failed"
set `wc -c netdb.h`;Wc_c=$1
if test "$Wc_c" != "2664"; then
	echo original size 2664, current size $Wc_c
fi
# ============= socket.h ==============
echo "x - extracting socket.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > socket.h &&
X/*
X * The only socket type supported is the stream socket
X */
X#define	SOCK_STREAM	1		/* stream socket */
X
X/*
X * Option flags per-socket. most are dummys
X */
X#define	SO_DEBUG	0x0001		/* turn on debugging info recording */
X#define	SO_ACCEPTCONN	0x0002		/* socket has had listen() */
X#define	SO_REUSEADDR	0x0004		/* allow local address reuse */
X#define	SO_KEEPALIVE	0x0008		/* keep connections alive */
X#define	SO_DONTROUTE	0x0010		/* just use interface addresses */
X#define	SO_BROADCAST	0x0020		/* permit sending of broadcast msgs */
X#define	SO_USELOOPBACK	0x0040		/* bypass hardware when possible */
X#define	SO_LINGER	0x0080		/* linger on close if data present */
X#define	SO_OOBINLINE	0x0100		/* leave received OOB data in line */
X
X/*
X * Additional options, not kept in so_options.
X */
X#define SO_SNDBUF	0x1001		/* send buffer size */
X#define SO_RCVBUF	0x1002		/* receive buffer size */
X#define SO_SNDLOWAT	0x1003		/* send low-water mark */
X#define SO_RCVLOWAT	0x1004		/* receive low-water mark */
X#define SO_SNDTIMEO	0x1005		/* send timeout */
X#define SO_RCVTIMEO	0x1006		/* receive timeout */
X#define	SO_ERROR	0x1007		/* get error status and clear */
X#define	SO_TYPE		0x1008		/* get socket type */
X
X/*
X * Level number for (get/set)sockopt() to apply to socket itself.
X */
X#define	SOL_SOCKET	0xffff		/* options for socket level */
X
X/*
X * Address families.
X */
X#define	AF_UNSPEC	0		/* unspecified */
X#define	AF_UNIX		1		/* local to host (pipes, portals) */
X#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
X
X#define	AF_MAX		3
X
X/*
X * Protocol families, same as address families for now.
X */
X#define	PF_UNSPEC	AF_UNSPEC
X#define	PF_UNIX		AF_UNIX
X#define	PF_INET		AF_INET
X
X/*
X * Structure used to keep socket address.
X */
Xstruct sockaddr {
X	ushort	sa_family;		/* address family */
X	char	sa_data[14];		/* up to 14 bytes of direct address */
X};
X
X/*
X *  These definitions are normally in in.h
X */
Xstruct in_addr {
X	ulong_t s_addr;
X};
X
Xstruct sockaddr_in {
X	short	sin_family;		/* AF_INET */
X	ushort	sin_port;		/* port number */
X	struct in_addr sin_addr;	/* internet address (always 0) */
X	char	sin_zero[8];		/* filler only */
X};
X
X#define	INADDR_ANY		(ulong_t)0x00000000
X#define	INADDR_BROADCAST	(ulong_t)0xffffffff	/* must be masked */
X#define	SOCKADDRLEN(A)	((A)->sa_family == AF_UNIX ? sizeof(struct sockaddr_un) : (A)->sa_family == AF_INET ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr))
X
X#define	ntohs(X)	(X)
X#define	htons(X)	(X)
X#define	htonl(X)	(X)
X
X/*
X * Since we have no networking, this routine always give the same result
X */
X#define	inet_addr(HOST)	(0)
X
X/*
X * This structure is normally in un.h
X */
Xstruct	sockaddr_un {
X	short	sun_family;		/* AF_UNIX */
X	char	sun_path[108];		/* path name */
X};
X
X#ifndef EADDRINUSE
X#define	EADDRINUSE	35	/* bind - socket is occupied or inuse */
X#define	EALREADY	36	/* connect - already connected */
X#define	ECONNABORTED	37	/* connection aborted */
X#define	ECONNREFUSED	38	/* connection refused */
X#define	ECONNRESET	39	/* ??? */
X#define	EDESTADDRREQ	40	/* destination address required */
X#define	EINPROGRESS	41	/* in progress */
X#define	EISCONN		42	/* is already connected */
X#define	ENOPROTOOPT	46	/* no protocol option */
X#define	ENOTCONN	47	/* not connected */
X#define	ENOTSOCK	48	/* not socket */
X#define	EOPNOTSUPP	49	/* operation not supported */
X#define	EPROTONOSUPPORT	50	/* protocol not supported */
X#define	EPROTOTYPE	51	/* connect - trying to connect to socket of different type */
X#define	EWOULDBLOCK	EAGAIN	/* would block */
X#endif
X
X/*
X * prototypes for the socket emulation package functions
X */
Xint accept(int s, struct sockaddr *name, int *anamelen);
Xint bind(int sofd, struct sockaddr *name, int namelen);
Xint connect(int s, struct sockaddr *name, int namelen);
Xint getpeername(int fdes, struct sockaddr *asa, int *alen);
Xint getsockname(int fdes, struct sockaddr *asa, int *alen);
Xint getsockopt(int s, int level, int name, int *val, int *avalsize);
Xstruct hostent *gethostbyname ( char *host );
Xint listen(int s, int backlog);
Xint setsockopt(int s, int level, int name, char *val, int valsize);
Xint socket(int domain, int type, int protocol);
Xint soclose(int fildes);
Xint soioctl(int fildes, int request, int *arg);
Xint soread(int fildes, char *buf, int nbytes);
Xint sowrite(int fildes, char *buf, int nbytes);
X
X	
X#ifndef SOCKET_LIBRARY_BUILD
X#define read	soread
X#define	write	sowrite
X#define	close	soclose
X#define	ioctl	soioctl
X#endif
X
X#ifndef FIOSNBIO
X#define	FIOSNBIO	((('f') << 8) | 40)
X#endif
X
X#ifndef FIONREAD
X#define	FIONREAD ((('f') << 8) | 41)
X#endif
X
X#define	S_IFSOCK	S_IFIFO
X#define	SOCKET_EMULATION
SHAR_EOF
$TOUCH -am 1219114290 socket.h &&
chmod 0620 socket.h ||
echo "restore of socket.h failed"
set `wc -c socket.h`;Wc_c=$1
if test "$Wc_c" != "4578"; then
	echo original size 4578, current size $Wc_c
fi
# ============= socketvar.h ==============
echo "x - extracting socketvar.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > socketvar.h &&
X/*
X * Socket structure used internally in the socket emulation package
X */
X
Xstruct socket {
X	short	so_options;		/* from socket call, see socket.h */
X	short	so_state;		/* internal state flags SS_*, below */
X	char	so_type;		/* socket type */
X	short	so_fd;			/* socket file descriptor */
X	char	*so_name;		/* Name of socket pipe */
X	struct sockaddr *so_addr;	/* Address of socket */
X	long	so_domain;
X	short	so_protocol;
X	/*
X	 * the following variables set for a connected socket
X	 */
X	short	so_rfd;			/* Read-side file descriptor */
X	short	so_wfd;			/* write-side file descriptor */
X	short	so_pfd;			/* Peer socket file descriptor */
X	char	*so_rname;		/* Read-side-pipe filename */
X	char	*so_wname;		/* Write-side-pipe filename */
X	struct sockaddr *so_conn;	/* Address of connected socket */
X};
X
X/*
X * Socket state bits.
X */
X#define	SS_ISCONNECTED		0x002	/* socket connected to a peer */
X#define	SS_NBIO			0x100	/* non-blocking ops */
X
X
X/*
X * Message send through the main socket channel
X */
Xstruct socket_packet {
X	unsigned short	scm_magic;	/* Magic number */
X	char	scm_msg;		/* Socket message */
X	char	scm_type;		/* socket type */
X	char	scm_rname[14];		/* name of "read" pipe */
X	char	scm_wname[14];		/* name of "write" pipe */
X	union {				/* Callers address */
X		struct sockaddr sa;
X		struct sockaddr_in in;
X		struct sockaddr_un un;
X	} scm_addr;
X};
X#define	SOCKET_MAGIC	0xc561
X/*
X * Socket message types
X */
X#define	MSG_CONNECT	1		/* Want to connect to socket */
X#define	MSG_CONNECT_OK	2		/* Connect ok message */
X#define	MSG_FAIL	3		/* General failure message */
X#define	MSG_DISCONNECT	4		/* Disconnection message */
X
X#define	GETSOCKET(sofd)	((sofd)>=0 && (sofd)<=FD_SETSIZE ? _socktab[sofd] : NULL)
Xextern struct socket *_socktab[];
Xextern fd_set _socketmap;
X
X/*
X * Internal routines in the socket package
X */
Xint _setsolock ( int fd , int type );
Xint _clearsolock ( int fd , int type );
Xint _checksolock ( int fd , long type );
Xchar *_socketname ( struct sockaddr *addr );
Xint _sodisconnect ( struct socket *so );
Xint _sodisconnect2 ( register struct socket *so );
X
SHAR_EOF
$TOUCH -am 1219125090 socketvar.h &&
chmod 0620 socketvar.h ||
echo "restore of socketvar.h failed"
set `wc -c socketvar.h`;Wc_c=$1
if test "$Wc_c" != "2068"; then
	echo original size 2068, current size $Wc_c
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
XCC = gcc
XCFLAGS = -g -Wall -I. -DSOCKET_LIBRARY_BUILD
X
XSRCFILES = accept.c bind.c connect.c hostbyaddr.c hostbyname.c getpeername.c getsockname.c getsockopt.c \
X	listen.c setsockopt.c socket.c soclose.c soread.c sowrite.c soioctl.c
X
XOBJFILES = accept.o bind.o connect.o hostbyaddr.o hostbyname.o getpeername.o getsockname.o getsockopt.o \
X	listen.o setsockopt.o socket.o soclose.o soread.o sowrite.o soioctl.o
X
XHFILES = netdb.h socket.h socketvar.h
X
XLIBS = libsocket.a
X
Xtest : libsocket.a test.o
X	$(CC) $(CFLAGS) test.o -o test libsocket.a
X	cp test testx
X
Xlibsocket.a : $(OBJFILES)
X	rm -f libsocket.a
X	ar qc libsocket.a $(OBJFILES)
X	ranlib libsocket.a
X
Xinstall: libsocket.a socket.h socketvar.h
X	cp libsocket.a /lib/386/Slibsocket.a
X	chmod 644 /lib/386/Slibsocket.a
X	cp socket.h /usr/include/sys/socket.h
X	chmod 644 /usr/include/sys/socket.h
X	cp netdb.h /usr/include/netdb.h
X	chmod 644 /usr/include/netdb.h
X
Xshar:: $(SRCFILES) $(HFILES)
X	shar -n socket-emulation -a -s $(MYNAME) README $(SRCFILES) $(HFILES) Makefile >socket.shar
SHAR_EOF
$TOUCH -am 1219205590 Makefile &&
chmod 0660 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "1030"; then
	echo original size 1030, current size $Wc_c
fi
exit 0



More information about the Alt.sources mailing list