DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T t

⟦9aa8fa7e5⟧ TextFile

    Length: 9189 (0x23e5)
    Types: TextFile
    Names: »ts2tcp.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/tsap/ts2tcp.c« 

TextFile

/* ts2tcp.c - TPM: TCP interface */

#ifndef	lint
static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 6.0 89/03/18 23:45:22 mrose Rel $";
#endif

/* 
 * $Header: /f/osi/tsap/RCS/ts2tcp.c,v 6.0 89/03/18 23:45:22 mrose Rel $
 *
 *
 * $Log:	ts2tcp.c,v $
 * Revision 6.0  89/03/18  23:45:22  mrose
 * Release 5.0
 * 
 */

/*
 *				  NOTICE
 *
 *    Acquisition, use, and distribution of this module and related
 *    materials are subject to the restrictions of a license agreement.
 *    Consult the Preface in the User's Manual for the full terms of
 *    this agreement.
 *
 */


/* LINTLIBRARY */

#include <stdio.h>
#include "tpkt.h"
#include "tailor.h"

#ifdef	TCP
#include "internet.h"
#include <errno.h>
#ifdef	BSD42
#include <sys/ioctl.h>
#include <sys/time.h>
#endif
#ifdef	WRITEV
#include <sys/uio.h>
#endif

/* \f

   DATA */

#ifdef	FIONBIO
#define	NODELAY
#endif

#ifdef	NODELAY
static  fd_set  inprogress;
static struct sockaddr_in *peers = NULL;
#endif


extern int  errno;

/* \f

   N-CONNECT.REQUEST */

int	tcpopen (tb, local, remote, td, async)
register struct tsapblk *tb;
struct NSAPaddr *local,
		*remote;
struct TSAPdisconnect *td;
int	async;
{
    int     fd;
#ifdef	FIONBIO
    int	    onoff;
#endif
    struct sockaddr_in  lo_socket,
                        in_socket;
    register struct sockaddr_in *lsock = &lo_socket,
                               *isock = &in_socket;
    register struct hostent *hp;
    register struct servent *sp;

#ifndef	NODELAY
    if (async)
	return tsaplose (td, DR_PARAMETER, NULLCP,
			 "asynchronous not supported");
#endif

    bzero ((char *) isock, sizeof *isock);

    if (remote -> na_port == 0) {
	if ((sp = getservbyname ("tsap", "tcp")) == NULL)
		return tsaplose (td, DR_ADDRESS, NULLCP,
			"tcp/tsap: unknown service");
	isock -> sin_port = sp -> s_port;
    }
    else
	isock -> sin_port = remote -> na_port;

    if ((hp = gethostbystring (remote -> na_domain)) == NULL)
	return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
		    remote -> na_domain);
    (void) strncpy (remote -> na_domain, hp -> h_name,
			sizeof remote -> na_domain);

    isock -> sin_family = hp -> h_addrtype;
    inaddr_copy (hp, isock);

    if (local && local -> na_domain[0]) {
	bzero ((char *) lsock, sizeof *lsock);

	if ((hp = gethostbystring (local -> na_domain)) == NULL)
	    return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
		    local -> na_domain);

	if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
	    return tsaplose (td, DR_ADDRESS, NULLCP,
		    "address family mismatch");

	inaddr_copy (hp, lsock);
    }
    else
	lsock = NULL;

    if ((fd = start_tcp_client (lsock, 0)) == NOTOK)
	return tsaplose (td, DR_CONGEST, "socket", "unable to start");

#ifdef	FIONBIO
    if (async)
	(void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
#endif
    tb -> tb_fd = fd;
    (void) TTService (tb);

    if (join_tcp_server (fd, isock) == NOTOK) {
#ifdef	NODELAY
	if (async)
	    switch (errno) {
		case EINPROGRESS: 
		    if (peers == NULL) {
			peers = (struct sockaddr_in *)
					calloc ((unsigned) getdtablesize (),
						sizeof *peers);
			if (peers == NULL) {
			    (void) tsaplose (td, DR_CONGEST, NULLCP,
					     "out of memory");
			    (void) close_tcp_socket (fd);
			    return (tb -> tb_fd = NOTOK);
			}

			FD_ZERO (&inprogress);
		    }
		    FD_SET (fd, &inprogress);
		    peers[fd] = *isock;/* struct copy */
		    return OK;

		case EISCONN: 
		    goto done;

		default: 
		    break;
	    }
#endif

	(void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
	(void) close_tcp_socket (fd);
	return (tb -> tb_fd = NOTOK);
    }
#ifdef	NODELAY
done: ;
#endif

#ifdef	FIONBIO
    if (async)
	(void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
#endif

    return DONE;
}

/* \f

 */

#ifndef	NODELAY
/* ARGSUSED */
#endif

static int  tcpretry (tb, td)
struct tsapblk *tb;
struct TSAPdisconnect *td;
{
#ifdef	NODELAY
#ifdef	FIONBIO
    int	    onoff;
#endif
    int	    fd = tb -> tb_fd;
    fd_set  mask;
    struct sockaddr_in *isock = &peers[fd];

    FD_ZERO (&mask);
    FD_SET (fd, &mask);
    if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
	return OK;

    if (!FD_ISSET (fd, &inprogress))
	return DONE;

    isock = &peers[fd];
    if (join_tcp_server (fd, isock) == NOTOK) {
	switch (errno) {
	    case EINPROGRESS:
		return OK;

	    case EISCONN:
		goto done;

	    case EINVAL:	/* UNIX bug: could be any socket errno, e.g.,
				   ETIMEDOUT */
		errno = ECONNREFUSED;
		/* and fall */
	    default:
		break;
	}

	(void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
	FD_CLR (fd, &inprogress);
	(void) close_tcp_socket (fd);
	return (tb -> tb_fd = NOTOK);
    }
done: ;

#ifdef	FIONBIO
    (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
#endif

    FD_CLR (fd, &inprogress);

    return DONE;
#else
    return tsaplose (td, DR_OPERATION, NULLCP, "connection not in progress");
#endif
}

/* \f

   init for read from network */

#ifndef	BRIDGE_X25
static
#endif
int	tcpinit (fd, t)
int	fd;
register struct tsapkt *t;
{
    register int    cc,
                    i;
    register char  *bp;

    for (bp = (char *) &t -> t_pkthdr, i = TPKT_HDRLEN (t);
	    i > 0;
	    bp += cc, i -= cc)
	switch (cc = read_tcp_socket (fd, bp, i)) {
	    case NOTOK: 
	    case OK: 
		return DR_NETWORK;

	    default: 
		break;
	}

    if (t -> t_vrsn != TPKT_VRSN)
	return DR_PROTOCOL;

    if ((t -> t_length = ntohs (t -> t_length)) < TPKT_HDRLEN (t))
	return DR_LENGTH;

    return OK;
}

/* \f

   write to network */

#ifndef	BRIDGE_X25
static
#endif
int	tcpwrite (fd, t, cp, n)
int	fd;
register struct tsapkt *t;
char   *cp;
int	n;
{
    register int    cc;
    register struct udvec  *uv;
#ifdef	WRITEV
    struct iovec iovs[NTPUV + 4];
    register struct iovec *iov;
#else
    register char   *p,
		    *q;
#endif

#ifdef	WRITEV
    iov = iovs;
    cc = 0;

    iov -> iov_base = (char *) &t -> t_pkthdr;
    cc += (iov -> iov_len = TPKT_HDRLEN (t));
    iov++;

    iov -> iov_base = cp;
    cc += (iov -> iov_len = n);
    iov++;

    if (t -> t_vdata) {
	iov -> iov_base = t -> t_vdata;
	cc += (iov -> iov_len = t -> t_vlen);
	iov++;
    }

    for (uv = t -> t_udvec; uv -> uv_base; uv++) {
	iov -> iov_base = uv -> uv_base;
	cc += (iov -> iov_len = uv -> uv_len);
	iov++;
    }

    if (writev (fd, iovs, iov - iovs) != cc)
	cc = NOTOK;
#else
    cc = TPKT_HDRLEN (t) + n;
    if (t -> t_vdata)
	cc += t -> t_vlen;
    for (uv = t -> t_udvec; uv -> uv_base; uv++)
	cc += uv -> uv_len;
    if (p = malloc ((unsigned) cc)) {
	bcopy ((char *) &t -> t_pkthdr, q = p, TPKT_HDRLEN (t));
	q += TPKT_HDRLEN (t);

	bcopy (cp, q, n);
	q += n;

	if (t -> t_vdata) {
	    bcopy (t -> t_vdata, q, t -> t_vlen);
	    q += t -> t_vlen;
	}

	for (uv = t -> t_udvec; uv -> uv_base; uv++) {
	    bcopy (uv -> uv_base, q, uv -> uv_len);
	    q += uv -> uv_len;
	}

	if (write_tcp_socket (fd, p, cc) != cc)
	    cc = NOTOK;

	free (p);
	goto out;
    }
    SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
	  ("unable to malloc %d octets for pseudo-writev, continuing...",
	   cc));

    cc = TPKT_HDRLEN (t);
    if (write_tcp_socket (fd, (char *) &t -> t_pkthdr, cc) != cc) {
err: 	;
	cc = NOTOK;
	goto out;
    }

    if (write_tcp_socket (fd, cp, n) != n)
	goto err;
    cc += n;

    if (t -> t_vdata
	    && write_tcp_socket (fd, t -> t_vdata, t -> t_vlen) != t -> t_vlen)
	goto err;
    cc += t -> t_vlen;

    for (uv = t -> t_udvec; uv -> uv_base; uv++) {
	if (write_tcp_socket (fd, uv -> uv_base, uv -> uv_len) != uv -> uv_len)
	    goto err;
	cc += uv -> uv_len;
    }

out: ;
#endif

    return cc;
}

/* \f

 */

/* ARGSUSED */

char   *tcpsave (fd, sin, cp1, cp2, td)
int	fd;
struct sockaddr_in *sin;
char   *cp1,
       *cp2;
struct TSAPdisconnect *td;
{
    static char buffer[BUFSIZ];

    (void) sprintf (buffer, "%c%d %s %s", NT_TCP, fd, cp1, cp2);

    return buffer;
}

/* \f

 */

int	tcprestore (tb, buffer, td)
register struct tsapblk *tb;
char   *buffer;
struct TSAPdisconnect *td;
{
    int     fd;
    char    domain[NSAP_DOMAINLEN + 1];
    register struct NSAPaddr *na;
    register struct TSAPaddr *ta;
    
    ta = &tb -> tb_initiating;
    ta -> ta_naddr = 1;
    na = ta -> ta_addrs;
    na -> na_type = NA_TCP;

    if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3
		|| fd < 0)
	return tsaplose (td, DR_PARAMETER, NULLCP,
			 "bad initialization vector \"%s\"", buffer);

    tb -> tb_fd = fd;
    (void) TTService (tb);
    
    ta = &tb -> tb_responding;
    ta -> ta_naddr = 1;
    na = ta -> ta_addrs;
    na -> na_type = NA_TCP;
    (void) strncpy (na -> na_domain, domain, sizeof na -> na_domain);
    
    return OK;
}

/* \f

 */

int	TTService (tb)
register struct tsapblk *tb;
{
    struct tsapkt *t;

    tb -> tb_flags |= TB_TCP;

    tb -> tb_tsdusize = TPKT_MAXLEN
		    - (tb -> tb_tpduslop = sizeof t -> t_pkthdr + DT_MAGIC);

    tb -> tb_retryfnx = tcpretry;

    tb -> tb_initfnx = tcpinit;
    tb -> tb_readfnx = read_tcp_socket;
    tb -> tb_writefnx = tcpwrite;
    tb -> tb_closefnx = close_tcp_socket;
    tb -> tb_selectfnx = select_tcp_socket;


    tp0init (tb);
}
#endif