|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 7776 (0x1e60)
Types: TextFile
Names: »ts2cons.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
└─⟦eba4602b1⟧ »./isode-5.0.tar.Z«
└─⟦d3ac74d73⟧
└─⟦this⟧ »isode-5.0/tsap/ts2cons.c«
/* ts2cons.c - TPM: CONS interface */
#ifndef lint
static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2cons.c,v 6.0 89/03/18 23:45:18 mrose Rel $";
#endif
/*
* $Header: /f/osi/tsap/RCS/ts2cons.c,v 6.0 89/03/18 23:45:18 mrose Rel $
*
* Contributed by Keith Ruttle, CAMTEC Electronics Ltd
*
*
* $Log: ts2cons.c,v $
* Revision 6.0 89/03/18 23:45:18 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"
#ifdef CONS
#include "cons.h"
#include <sys/uio.h>
#include <sys/ioctl.h>
#include "tailor.h"
static fd_set inprogress;
static CONN_DB *peers = NULL;
extern int errno;
/* \f
N-CONNECT.REQUEST */
int consopen (tb, dummy1, local, dummy2, remote, td, async)
register struct tsapblk *tb;
struct NSAPaddr *local,
*remote;
struct TSAPaddr *dummy1, *dummy2;
struct TSAPdisconnect *td;
{
register int fd;
int onoff;
if ((fd = start_cons_client (local)) == NOTOK)
return tsaplose (td, DR_CONGEST, "socket", "unable to start");
if (async) {
if (ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)) < 0) {
(void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
(void) close_cons_socket (fd);
return NOTOK;
}
}
tb -> tb_fd = fd;
(void) nTService (tb);
if (join_cons_server (fd, remote) == NOTOK) {
if (async)
switch (errno) {
case EINPROGRESS:
if (peers == NULL) {
peers = (CONN_DB *)
calloc ((unsigned) getdtablesize (),
sizeof *peers);
if (peers == NULL) {
(void) tsaplose (td, DR_CONGEST, NULLCP,
"out of memory");
(void) close_cons_socket (fd);
return (tb -> tb_fd = NOTOK);
}
FD_ZERO (&inprogress);
}
FD_SET (fd, &inprogress);
(void) gen2if(remote, &peers[fd], ADDR_REMOTE);/* struct copy */
return OK;
case EISCONN:
goto done;
default:
break;
}
(void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
(void) close_cons_socket (fd);
return (tb -> tb_fd = NOTOK);
}
done: ;
if (async)
if (ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)) < 0) {
(void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
(void) close_cons_socket (fd);
return NOTOK;
}
return DONE;
}
/* \f
*/
static int consretry (tb, td)
struct tsapblk *tb;
struct TSAPdisconnect *td;
{
int onoff;
int fd = tb -> tb_fd;
fd_set mask;
CONN_DB *nsock = &peers[fd];
struct NSAPaddr remote;
(void) if2gen(&remote, nsock, ADDR_REMOTE);
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;
nsock = &peers[fd];
if (join_cons_server (fd, &remote) == 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_cons_socket (fd);
return (tb -> tb_fd = NOTOK);
}
done: ;
(void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
FD_CLR (fd, &inprogress);
return DONE;
}
/* \f
init for read from network/write to network */
/* \f
init for read from network */
static char nsdu[MAXNSDU];
static char *np;
static int bl;
static int consinit (fd, t)
int fd;
register struct tsapkt *t;
{
register int cc;
int need_header;
/* XXX: cc should be set to the maximum acceptable NSDU length.
Longer NSDUs will be truncated without notification.
Should be configurable (or set during N-CONNECT and remembered) */
cc = MAXNSDU;
switch (cc = read_cons_socket (fd, nsdu, cc)) {
case OK: /* no data ? */
case NOTOK:
return DR_NETWORK;
default:
t -> t_length = cc + sizeof t -> t_pkthdr;
break;
}
if (t -> t_length < TPKT_HDRLEN (t))
return DR_LENGTH;
t -> t_li = nsdu[0];
t -> t_code = nsdu[1];
np = nsdu + 2;
bl = t -> t_length - TPKT_HDRLEN (t);
t -> t_vrsn = TPKT_VRSN; /* Not really needed! */
return OK;
}
static int read_nsdu_buffer (fd, buffer, cc)
int fd;
register char *buffer;
register int cc;
{
if (cc > bl)
cc = bl;
if (cc > 0) {
bcopy (np, buffer, cc);
np += cc;
bl -= cc;
}
return cc;
}
/* \f
write to network */
static int conswrite (fd, t, cp, n)
int fd;
register struct tsapkt *t;
char *cp;
int n;
{
register int cc;
register struct udvec *uv;
char *p;
cc = sizeof t -> t_li + sizeof t -> t_code + n;
if (t -> t_vdata)
cc += t -> t_vlen;
for (uv = t -> t_udvec; uv -> uv_base; uv++)
cc += uv -> uv_len;
p = malloc ((unsigned) cc);
cc = 0;
bcopy ((char *) &t -> t_li, p + cc, sizeof t -> t_li);
cc += sizeof t -> t_li;
bcopy ((char *) &t -> t_code, p + cc, sizeof t -> t_code);
cc += sizeof t -> t_code;
bcopy (cp, p + cc, n);
cc += n;
if (t -> t_vdata) {
bcopy (t -> t_vdata, p + cc, t -> t_vlen);
cc += t -> t_vlen;
}
for (uv = t -> t_udvec; uv -> uv_base; uv++) {
bcopy (uv -> uv_base, p + cc, uv -> uv_len);
cc += uv -> uv_len;
}
if (write_cons_socket (fd, p, cc) != cc) {
cc = NOTOK;
}
free (p);
return cc;
}
/* \f
*/
/* ARGSUSED */
char *conssave (fd, nsap1, l1, nsap2, l2, td)
int fd;
char *nsap1;
int l1;
char *nsap2;
int l2;
struct TSAPdisconnect *td;
{
static char buffer[BUFSIZ];
(void) sprintf (buffer, "%c%d %*s %*s",
NT_CONS, fd, l1, nsap1, l2, nsap2);
return buffer;
}
int consrestore (tb, buffer, td)
register struct tsapblk *tb;
char *buffer;
struct TSAPdisconnect *td;
{
int fd;
char nsap1[NASIZE + 1],
nsap2[NASIZE + 1];
register struct NSAPaddr *na;
register struct TSAPaddr *ta;
if (sscanf (buffer, "%d %s %s", &fd, nsap1, nsap2) != 3 || fd < 0)
return tsaplose (td, DR_PARAMETER, NULLCP,
"bad initialization vector \"%s\"", buffer);
ta = &tb -> tb_initiating;
ta -> ta_naddr = 1;
na = ta -> ta_addrs;
na -> na_type = NA_NSAP;
bcopy(nsap1, na -> na_address, strlen(nsap1));
na -> na_addrlen = strlen (na -> na_address);
tb -> tb_fd = fd;
(void) nTService (tb);
ta = &tb -> tb_responding;
ta -> ta_naddr = 1;
na = ta -> ta_addrs;
na -> na_type = NA_NSAP;
bcopy(nsap1, na -> na_address, strlen(nsap2));
na -> na_addrlen = strlen (na -> na_address);
return OK;
}
/* \f
*/
int nTService (tb)
register struct tsapblk *tb;
{
tb -> tb_flags |= TB_CONS;
tb -> tb_tsdusize = MAXNSDU - (tb -> tb_tpduslop = DT_MAGIC);
tb -> tb_retryfnx = consretry;
tb -> tb_initfnx = consinit;
tb -> tb_readfnx = read_nsdu_buffer;
tb -> tb_writefnx = conswrite;
tb -> tb_closefnx = close_cons_socket;
tb -> tb_selectfnx = select_cons_socket;
tp0init (tb);
}
#endif