|
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