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