|
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 p
Length: 7229 (0x1c3d) Types: TextFile Names: »ps2tcp.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/psap2-lpp/ps2tcp.c«
/* psaptcp.c - PPM: TCP backing */ #ifndef lint static char *rcsid = "$Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.0 89/11/23 22:15:50 mrose Rel $"; #endif /* * $Header: /f/osi/psap2-lpp/RCS/ps2tcp.c,v 7.0 89/11/23 22:15:50 mrose Rel $ * * Contributed by The Wollongong Group, Inc. * * * $Log: ps2tcp.c,v $ * Revision 7.0 89/11/23 22:15:50 mrose * Release 6.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> #define LPP #include "PS-types.h" #include "ppkt.h" #include "tsap.h" #include "tailor.h" #include "internet.h" #include <errno.h> #ifdef BSD42 #include <sys/ioctl.h> #endif /* \f DATA */ #ifdef FIONBIO static fd_set inprogress; static struct sockaddr_in *peers = NULL; #endif extern int errno; /* \f */ int tcpopen (pb, calling, called, pi, async) register struct psapblk *pb; struct NSAPaddr *calling, *called; struct PSAPindication *pi; 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; #ifndef FIONBIO if (async) return psaplose (pi, PC_PARAMETER, NULLCP, "asynchronous not supported"); #endif bzero ((char *) isock, sizeof *isock); if (called -> na_port == 0) return psaplose (pi, PC_ADDRESS, NULLCP, "TCP port of called address not specified"); else isock -> sin_port = called -> na_port; if ((hp = gethostbystring (called -> na_domain)) == NULL) return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", called -> na_domain); #ifdef notanymore (void) strncpy (called -> na_domain, hp -> h_name, sizeof called -> na_domain); #endif isock -> sin_family = hp -> h_addrtype; inaddr_copy (hp, isock); #ifndef notanymore (void) strcpy (called -> na_domain, inet_ntoa (isock -> sin_addr)); #endif if (calling && calling -> na_domain[0]) { bzero ((char *) lsock, sizeof *lsock); if ((hp = gethostbystring (calling -> na_domain)) == NULL) return psaplose (pi, PC_ADDRESS, NULLCP, "%s: unknown host", calling -> na_domain); if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family) return psaplose (pi, PC_ADDRESS, NULLCP, "address family mismatch"); inaddr_copy (hp, lsock); } else lsock = NULL; if ((fd = start_tcp_client (lsock, 0)) == NOTOK) return psaplose (pi, PC_CONGEST, "socket", "unable to start"); #ifdef FIONBIO if (async) (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)); #endif PTservice (pb, fd); if (join_tcp_server (fd, isock) == NOTOK) { #ifdef FIONBIO if (async) switch (errno) { case EINPROGRESS: if (peers == NULL) { peers = (struct sockaddr_in *) calloc ((unsigned) getdtablesize (), sizeof *peers); if (peers == NULL) { (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory"); (void) close_tcp_socket (fd); return (pb -> pb_fd = NOTOK); } FD_ZERO (&inprogress); } FD_SET (fd, &inprogress); peers[fd] = *isock;/* struct copy */ return OK; case EISCONN: goto done; default: break; } #endif (void) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); (void) close_tcp_socket (fd); return (pb -> pb_fd = NOTOK); } #ifdef FIONBIO done: ; if (async) (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); #endif if (tcpready (pb, pi) == NOTOK) { (void) close_tcp_socket (fd); pb -> pb_fd = NOTOK; } return DONE; } /* \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", PT_TCP, fd, cp1, cp2); return buffer; } int tcprestore (pb, buffer, pi) register struct psapblk *pb; char *buffer; struct PSAPindication *pi; { int fd; char domain[NSAP_DOMAINLEN + 1]; register struct NSAPaddr *na; na = &pb -> pb_initiating; na -> na_type = NA_TCP; na -> na_subnet = ts_comm_tcp_default; if (sscanf (buffer, "%d %s %s", &fd, na -> na_domain, domain) != 3 || fd < 0) return psaplose (pi, PC_PARAMETER, NULLCP, "bad initialization vector"); PTservice (pb, fd); na = pb -> pb_responding.pa_addr.sa_addr.ta_addrs; na -> na_type = NA_TCP; na -> na_subnet = ts_comm_tcp_default; (void) strncpy (na -> na_domain, domain, sizeof na -> na_domain); if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); return OK; } /* \f */ static int tcpretry (pb, pi) register struct psapblk *pb; struct PSAPindication *pi; { #ifdef FIONBIO int onoff; int fd = pb -> pb_fd; fd_set mask; struct sockaddr_in *isock = &peers[fd]; if (!FD_SET (fd, &inprogress)) return psaplose (pi, PC_PARAMETER, NULLCP, "connection not in progress"); FD_ZERO (&mask); FD_SET (fd, &mask); if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1) return OK; 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) psaplose (pi, PC_REFUSED, "connection", "unable to establish"); FD_CLR (fd, &inprogress); (void) close_tcp_socket (fd); return (pb -> pb_fd = NOTOK); } done: ; (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)); FD_CLR (fd, &inprogress); if (tcpready (pb, pi) == NOTOK) { (void) close_tcp_socket (fd); return (pb -> pb_fd = NOTOK); } return DONE; #else return psaplose (pi, PC_OPERATION, NULLCP, "connection not in progress"); #endif } /* \f */ static int tcpready (pb, pi) register struct psapblk *pb; struct PSAPindication *pi; { PS ps; if ((pb -> pb_stream = ps_alloc (fdx_open)) == NULLPS || fdx_setup (pb -> pb_stream, pb -> pb_fd) == NOTOK) return psaplose (pi, PC_CONGEST, NULLCP, NULLCP); PLOG (psap2_log, print_PS_PDUs, pb -> pb_retry, "ConnectRequest-PDU", 0); if (pe2ps (ps = pb -> pb_stream, pb -> pb_retry) == NOTOK) return pslose (pi, ps -> ps_errno); pe_free (pb -> pb_retry); pb -> pb_retry = NULLPE; if ((pb -> pb_response = ps2pe (pb -> pb_stream)) == NULLPE) return pslose (pi, ps -> ps_errno); return OK; } /* \f */ #define tcpclose close_tcp_socket #define tcpselect select_tcp_socket static int PTservice (pb, fd) register struct psapblk *pb; int fd; { pb -> pb_fd = fd; pb -> pb_reliability = HIGH_QUALITY; pb -> pb_retryfnx = tcpretry; pb -> pb_closefnx = tcpclose; pb -> pb_selectfnx = tcpselect; }