home *** CD-ROM | disk | FTP | other *** search
- /* Emulation of 4.2 UNIX socket interface routines */
- /* includes drivers for Wollongong ,CMU-TEK, UCX tcp/ip interface */
- /* and also emulates the SUN version of X.25 sockets */
- /* */
- /* outstanding problems are: */
- /* we have to use the awful fiddle.h to get stream io to work */
- /* with file descriptor based sockets. (instead of rewriting */
- /* the standard library, which we don't have access to) */
-
- #include <stdio.h>
- #include <errno.h>
- #include <ssdef.h>
- #include <dvidef.h>
- #include <signal.h>
- #include <fcntl.h>
- #include <msgdef.h>
- #include <psicodes.h>
- #include <iodef.h>
- #include <ttdef.h>
- #include <tt2def.h>
- #include <sgtty.h>
- #include <netdb.h>
- #include <sys/types.h>
- #ifndef FD_SET
- #define FD_SET(f,s) ((s)->fds_bits[0] |= (1 << (f)))
- #define FD_CLR(f,s) ((s)->fds_bits[0] &= ~(1 << (f)))
- #define FD_ISSET(f,s) ((s)->fds_bits[0] & (1 << (f)))
- #define FD_ZERO(s) ((s)->fds_bits[0] = 0)
- #endif
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <sys/uio.h>
- #include <netinet/in.h>
- #include <netx25/x25_ctl.h>
- #include <netx25/x25_ioctl.h>
- #include <netx25/x25_pk.h>
- #include <sys/time.h>
- #include <sys/termio.h>
- #include <ucxcodes.h>
- #include <ctype.h>
-
- /* actually an itemlist_3, but can be used for itemlist_2's */
- struct itemlist {
- short length;
- short code;
- char *dataptr;
- short *retlenptr;
- };
-
- union socket_addr {struct sockaddr_in in;CONN_DB x25;};
- union ioctl_arg {CONN_DB x25;MASK_DATA_DB mask;FACILITY_DB fac;
- X25_CAUSE_DIAG diag;int i;struct sgttyb sg;struct ltchars t;
- struct termio te;};
-
- #define TCP$SEND (IO$_WRITEVBLK)
- #define TCP$RECEIVE (IO$_READVBLK)
- #define TCP$OPEN (IO$_CREATE)
- #define TCP$CLOSE (IO$_DELETE)
- #define TCP$ABORT (IO$_DEACCESS)
- #define TCP$STATUS (IO$_ACPCONTROL)
- #define TCP$INFO (IO$_MODIFY)
- #define GTHST (IO$_SKIPFILE)
-
- #define IO$_SEND (IO$_WRITEVBLK)
- #define IO$_RECEIVE (IO$_READVBLK)
- #ifndef IO$S_FCODE
- #define IO$S_FCODE 0x0006
- #endif
- #define IO$_SOCKET (IO$_ACCESS | (0 << IO$S_FCODE))
- #define IO$_BIND (IO$_ACCESS | (1 << IO$S_FCODE))
- #define IO$_LISTEN (IO$_ACCESS | (2 << IO$S_FCODE))
- #define IO$_ACCEPT (IO$_ACCESS | (3 << IO$S_FCODE))
- #define IO$_CONNECT (IO$_ACCESS | (4 << IO$S_FCODE))
- #define IO$_SETSOCKOPT (IO$_ACCESS | (5 << IO$S_FCODE))
- #define IO$_GETSOCKOPT (IO$_ACCESS | (6 << IO$S_FCODE))
- #define IO$_IOCTL (IO$_ACCESS | (8 << IO$S_FCODE))
- #define IO$_ACCEPT_WAIT (IO$_ACCESS | (10 << IO$S_FCODE))
- #define IO$_NETWORK_PTY (IO$_ACCESS | (11 << IO$S_FCODE))
- #define IO$_SHUTDOWN (IO$_ACCESS | (12 << IO$S_FCODE))
- #define IO$_GETSOCKNAME (IO$_ACCESS | (13 << IO$S_FCODE))
- #define SETCHAR_HANDOFF (1<<2)
-
- #define NFB$C_DECLNAME 0x15
-
- #define TRACE(x) if (trace__) {\
- fprintf(ftrace__,x);\
- fprintf(ftrace__," failed %d %d\n",st,p[s].iosb[0]);\
- }
- #define TRACE1(x) if (trace__) {\
- fprintf(ftrace__,x);\
- fprintf(ftrace__," ast called %d %d %d\n",p->s,p->iosb[0],p->iosb[1]);\
- }
- FILE *ftrace__;
- int trace__ = 0;
-
- #define TIMER_EFN 1
- #define TERM_EFN 2
- #define BUF_SIZE 5000
-
- #define INITIALISED 0
- #define ACTIVE_CONNECTION 1
- #define PASSIVE_CONNECTION 2
- #define LISTENING 3
- #define HANDED_OFF 4
-
- static struct fd_entry {
- unsigned short int channel; /* vms channel assigned to this socket */
- unsigned short int iosb[4]; /* returned status block */
- int fd_buff_size; /* number of chrs in buffer still to be read */
- int accept_pending; /* a call is waiting to be accepted */
- int connect_pending; /* a connect is outstanding*/
- int connected; /* this descriptor is connected */
- unsigned char *fd_buff; /* pointer to buffer dyn assigned */
- unsigned char *fd_leftover; /* pointer to any chrs still to be read */
- FILE *fptr; /* we need to assgn a file ptr for stream io */
- int s; /* socket number - needed in the ast's */
- int namelen; /* our socket address name */
- union socket_addr name;
- short int fromdummy; /* wg - accept wants an int - recvfrom wants a short!!*/
- short int fromlen; /* the from socket address name */
- union socket_addr from;
- int tolen; /* wg - sendto wants an int*/
- union socket_addr to; /* the to socket address name */
- int passive; /* still needed because of x25 close ambig */
- int backlog; /* backlog - not handled well! */
- int domain; /* domain of socket AF_INET or AF_X25 */
- int type; /* type of socket stream or datagram */
- int protocol; /* protocol of socket - ignored */
- int mbx_channel; /* mailbox channel - needed for x25 */
- unsigned char mbx_buff[255]; /* mailbox buffer */
- unsigned short int miosb[4]; /* mailbox status block */
- int ncb_size; /* x25 connection information */
- unsigned char ncb[128];
- unsigned char masklen; /* x25 user data mask */
- unsigned char mask[16];
- int need_header; /* x25 header field gives data status if req*/
- int send_type; /* x25 data packet type eg more bit set etc */
- int status; /* status of socket */
- int closed_by_remote; /* flag for remote dropouts */
- int read_outstanding; /* flag so we don't hang two reads */
- int cmu_open; /* flag to say whether a cmu open was hung */
- int x25_listener; /* flag to say we are an x25 listener */
- int oob_type; /* handles interrupt messages */
- int mother; /* mother socket for X25 accepts */
- int child; /* child socket for X25 accepts */
- int no_more_accepts; /* don't accept anymore calls */
- char int_data; /* interrupt data - only 1 char supported */
- int non_blocking; /* don't block on a read if no data */
- int sig_req; /* generate SIGIO on data ready */
- struct itemlist rhost; /* descriptor pointing to "p[].from" info for UCX */
- unsigned short ucx_accept_chan; /* Channel returned by a UCX accept via hang_an_accept */
- } p[32];
-
- static struct term_entry{ /* so we can handle select on terminal input */
- int chan;
- short int iosb[4];
- short int char_available;
- short int read_outstanding;
- char c[1];
- } terminal = {-1,0,0,0,0,0,0};
-
- static struct sgttyb def_tty = {13, 13, 0x7f, 0x18, 0000010};
- static struct termio def_te = {0x2526,0x1805,0x1ad,0x8a3b,0x0,0x3,0x1c,0x7f,0x15,0x4,0,0,0};
-
- #define CMU 1
- #define WG 2
- #define NONE 3
- #define TGV 4
- #define UCX 5
- static int tcp_make = 0;
-
- struct descriptor{
- int size;
- char *ptr;
- };
-
- static int p_initialised = 0; /* initialise certain things 1st time thru */
- static int si_dummy(){} /* a routine to point SIGALRM and SIGURG at */
- static int (*alarm_function)() = si_dummy;
- static int (*sigurg_function)() = si_dummy;
- static int (*remembered_alarm_function)();
-
- FILE *fdopen();
- static set_tcp_make();
- static char *getdevicename();
-
- /************************************************************/
- /* socket routine */
- /************************************************************/
- int socket(domain,type,protocol)
- int domain,type,protocol;
- {
- struct descriptor inetdesc,x25desc,mbxdesc;
- extern int mailbox_ast();
- int i, st, s, p_initialise();
- long ucx_sock_def;
- char mailbox_logical_name[16];
- char *getenv();
-
- if ( ! tcp_make) set_tcp_make();
-
- if (p_initialised == 0) {
- for (i=0;i<32;i++) p_initialise(i);
- if ((getenv("PACKET_TRACE") != NULL) &&
- (strcmp(getenv("PACKET_TRACE"),"TRUE") == 0)) {
- trace__ = 1;
- ftrace__ = fopen("packet_trace.log","w");
- }
- p_initialised = 1;
- }
-
- if (trace__) fprintf(ftrace__,"socket called domain = %d ",domain);
-
- /* first of all get a file descriptor and file pointer we can associate */
- /* with the socket, allocate a buffer and remember the socket details */
- s = dup(0);
- if (s >31 ) {
- errno = EMFILE;
- close(s);
- if (trace__) fprintf(ftrace__,"socket failed errno = %d\n",errno);
- return(-1);
- }
-
- p[s].fptr = fdopen(s,"r");
- p[s].fd_buff = (unsigned char *)malloc(BUF_SIZE);
- p[s].domain = domain;
- p[s].type = type;
- p[s].protocol = protocol;
-
- /* handle the case of INET and X.25 separately */
- if (domain == AF_INET) {
-
- if (tcp_make == NONE) {
- printf("Trying to obtain a TCP socket when we don't have TCP!\n");
- exit(1);
- }
- if (tcp_make == CMU) {
- /* for CMU we need only assign a channel */
- inetdesc.size = 3;
- inetdesc.ptr = "IP:";
- if (sys$assign(&inetdesc,&p[s].channel,0,0) != SS$_NORMAL) return(-1);
- } /* end of if CMU */
- else if (tcp_make == UCX) {
-
- /* for UCX assign channel and associate a socket with it */
- inetdesc.size = 3;
- inetdesc.ptr = "BG:";
- if (sys$assign(&inetdesc,&p[s].channel,0,0) != SS$_NORMAL)
- return(-1);
-
- ucx_sock_def = (domain << 24) + (type << 16) + protocol;
- if ((st=sys$qiow(0,p[s].channel,IO$_SETMODE,p[s].iosb,0,0,
- &ucx_sock_def,0,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- return(-1);
- }
- } /* end of if UCX */
- else { /* TWG */
- /* for WG we assign the channel and associate a socket with it */
- inetdesc.size = 7;
- inetdesc.ptr = "_INET0:";
- if (sys$assign(&inetdesc,&p[s].channel,0,0) != SS$_NORMAL) {
- if (trace__) fprintf(ftrace__,"socket failed couldn't assign channel\n");
- return(-1);
- }
- if ((st=sys$qiow(0,p[s].channel,IO$_SOCKET,p[s].iosb,0,0,
- domain,type,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- if (trace__) fprintf(ftrace__,"socket failed 1 st=%d\n",st);
- return(-1);
- }
- } /* end of if TWG */
- }
- else if (domain == AF_X25) {
- /* for X.25 we have to assign a channel with a mailbox */
- x25desc.size = 5;
- x25desc.ptr = "NWA0:";
- strcpy(mailbox_logical_name, "X25_MBXn"); /* we need a unique name */
- mailbox_logical_name[7] = 'A'+s;
- mbxdesc.size = 8;
- mbxdesc.ptr = mailbox_logical_name;
- if ((st=sys$crembx(0,&p[s].mbx_channel,0,0,0,0,&mbxdesc)) != SS$_NORMAL) {
- if (trace__) fprintf(ftrace__,"socket failed couldn't assign mailbox\n");
- return(-1);
- }
- if ((st=sys$assign(&x25desc,&p[s].channel,0,&mbxdesc)) != SS$_NORMAL) {
- if (trace__) fprintf(ftrace__,"socket failed couldn't assign channel\n");
- return(-1);
- }
- /* set the initial read on the mailbox - the ast will keep this going */
- if ((st=sys$qio(0,p[s].mbx_channel,IO$_READVBLK,p[s].miosb,mailbox_ast,&p[s],
- p[s].mbx_buff,255,0,0,0,0)) != SS$_NORMAL){
- if (trace__) fprintf(ftrace__,"socket failed 1 st=%d\n",st);
- return(-1);
- }
- }
- else return(-1); /* we don't handle any other domain yet */
-
- /* for each case if we are successful we return the descriptor */
- if (trace__) fprintf(ftrace__,"socket succeeded s=%d\n",s);
- return(s);
- }
-
- /************************************************************/
- /* bind routine */
- /************************************************************/
- bind(s,name,namelen)
- int s;
- union socket_addr *name;
- int namelen;
- {
- char infobuff[1024], lhost[32];
- int st;
-
- if (trace__) fprintf(ftrace__,"bind called s=%d name->in.sin_port=%d ",s,ntohs(name->in.sin_port));
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].domain == AF_INET) {
- /* one main problem with bind is that if we are given a 0 port number */
- /* then we are expected to return a unique port number, which we don't*/
- /* know! So we return 1050+s and hope! */
-
- if (tcp_make == CMU) {
- if (name->in.sin_port == 0 && p[s].type != SOCK_DGRAM)
- name->in.sin_port = 1050+s;
- p[s].namelen = namelen;
- bcopy(name,&(p[s].name),namelen);
-
- if (p[s].type == SOCK_DGRAM) {
- /* another problem is that CMU still needs an OPEN request */
- /* even if its a datagram socket. */
- if ((st=sys$qiow(0,p[s].channel,TCP$OPEN,p[s].iosb,0,0,
- 0,0,ntohs(p[s].name.in.sin_port),0,1,0)) != SS$_NORMAL) return(-1);
- p[s].cmu_open = 1;
- sys$qiow(0,p[s].channel,TCP$INFO,p[s].iosb,0,0,&infobuff,1024,0,0,0,0);
- bcopy(infobuff+264,&(p[s].name.in.sin_port),2);
- p[s].name.in.sin_port = htons(p[s].name.in.sin_port);
- /* bcopy(infobuff+268,&(p[s].name.in.sin_addr),4); /*doesn't work!*/
- bcopy(infobuff+136,lhost,infobuff[1]); /* so get it another way */
- lhost[infobuff[1]] = '\0';
- sys$qiow(0,p[s].channel,GTHST,p[s].iosb,0,0,&infobuff,1024,1,lhost,0,0);
- bcopy(infobuff+4,&(p[s].name.in.sin_addr),4);
- hang_a_read(s); /* be prepared to receive a message */
- }
- }
- else if (tcp_make == UCX) {
- /* UCX will select a port for you if port number is 0 */
- /* translate "name" into an item_2 list */
- struct itemlist lhost;
- lhost.length = namelen;
- lhost.code = 0;
- lhost.dataptr = (char *)name;
-
- if ((st = sys$qiow(0,p[s].channel,IO$_SETMODE,p[s].iosb,0,0,
- 0,0,&lhost,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("bind")
- return(-1);
- }
- if (p[s].type == SOCK_DGRAM)
- hang_a_read(s);
-
- }
- else {
- /* WG is more straightforward */
- if ((st=sys$qiow(0,p[s].channel,IO$_BIND,p[s].iosb,0,0,
- name,namelen,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL){
- TRACE("bind")
- return(-1);
- }
- if (p[s].type == SOCK_DGRAM) hang_a_read(s); /* be prepared for msg */
- }
- }
-
- else if (p[s].domain == AF_X25) {
- /* for x.25 we can only remember the details */
- p[s].namelen = namelen;
- bcopy(name,&(p[s].name),namelen);
- }
-
- else return(-1); /* we don't handle any other domain yet */
- if (trace__) fprintf(ftrace__," succeeded\n");
-
- return(0);
- }
-
- /************************************************************/
- /* connect routine */
- /************************************************************/
- connect(s,name,namelen)
- int s;
- union socket_addr *name;
- int namelen;
- {
- int pr, fl, st;
- char *inet_ntoa();
- static struct {int len; char name[128];} gethostbuf;
- extern int connect_ast();
-
- if (trace__) fprintf(ftrace__,"connect called s=%d %s port %d non_blocking = %d",
- s,inet_ntoa(name->in.sin_addr.s_addr),ntohs(name->in.sin_port),p[s].non_blocking);
- if ( ! tcp_make) set_tcp_make();
-
- /* for datagrams we need to remember who*/
- /* the name was so we can send all msgs */
- /* to that address without having to */
- /* specify it all the time */
- if (p[s].connected) {
- if (p[s].connected == 1) errno = EISCONN;
- else {
- errno = ECONNREFUSED;
- p[s].connected = 0;
- }
- if (trace__) fprintf(ftrace__," p[s].connected is true errno = %d\n",errno);
- return(-1);
- }
- if (p[s].connect_pending) {
- errno = EALREADY;
- if (trace__) fprintf(ftrace__," p[s].connect_pending is true errno = %d\n",errno);
- return(-1);
- }
-
- p[s].passive = 0;
- p[s].tolen = namelen;
- bcopy(name,&(p[s].to),namelen);
-
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
-
- /* Get the info about the remote host and open up a connection */
-
- if ((st=sys$qiow(0,p[s].channel,GTHST,p[s].iosb,0,0,&gethostbuf,132,2,
- name->in.sin_addr.s_addr,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL){
- /*
- TRACE("connect")
- return(-1);
- */
- strcpy(gethostbuf.name,inet_ntoa(name->in.sin_addr.s_addr));
- gethostbuf.len = strlen(gethostbuf.name);
- }
- gethostbuf.name[gethostbuf.len] = 0;
- pr = 0; /*TCP*/
- fl = 1; /*active*/
- if (p[s].type == SOCK_DGRAM) return(0); /* nothing else for datagrams*/
- if ((st=sys$qio(s,p[s].channel,TCP$OPEN,p[s].iosb,connect_ast,&p[s],
- &(gethostbuf.name),
- ntohs(name->in.sin_port),ntohs(p[s].name.in.sin_port),fl,pr,0))
- != SS$_NORMAL) {
- TRACE("connect")
- return(-1);
- }
- } /* end of CMU */
- else if (tcp_make == UCX) {
- /* both UDP and TCP can use a connect - IO$_ACCESS */
- p[s].rhost.length = namelen;
- p[s].rhost.code = 0;
- p[s].rhost.dataptr = (char *)name;
-
- if ((st=sys$qio(s,p[s].channel,IO$_ACCESS,p[s].iosb,connect_ast,&p[s],
- 0,0,&p[s].rhost,0,0,0)) != SS$_NORMAL) {
- TRACE("connect");
- return(-1);
- }
- } /* end of UCX */
- else { /* TWG */
- if (p[s].type == SOCK_DGRAM) return(0);
- if ((st=sys$qio(s,p[s].channel,IO$_CONNECT,p[s].iosb,connect_ast,&p[s],
- name,namelen,0,0,0,0)) != SS$_NORMAL){
- TRACE("connect")
- return(-1);
- }
- }
- }
- else if (p[s].domain == AF_X25) {
- struct descriptor ncbdesc;
- int i;
- i = setup_ncb(s,name);
- ncbdesc.size = i;
- ncbdesc.ptr = (char *)&(p[s].ncb);
- if ((st=sys$qio(s,p[s].channel,IO$_ACCESS,p[s].iosb,connect_ast,&p[s],
- 0,&ncbdesc,0,0,0,0)) != SS$_NORMAL){
- TRACE("connect")
- errno = ECONNABORTED;
- return(-1);
- }
- }
-
- else return(-1); /* we don't handle any other domain yet */
-
- if (p[s].non_blocking) {
- if (p[s].connected) {
- if (p[s].connected == 1) {
- if (trace__) fprintf(ftrace__," succeeded\n");
- return(0);
- }
- else {
- p[s].connected = 0;
- errno = ECONNREFUSED;
- if (trace__) fprintf(ftrace__," failed 1 errno=%d\n",errno);
- return(-1);
- }
- }
- else {
- p[s].connect_pending = 1;
- errno = EINPROGRESS;
- if (trace__) fprintf(ftrace__," failed 2 errno=%d\n",errno);
- return(-1);
- }
- }
- else {
- /* wait for the connection to occur */
- if (p[s].connected) {
- if (p[s].connected == 1) {
- if (trace__) fprintf(ftrace__," succeeded\n");
- return(0);
- }
- else {
- p[s].connected = 0;
- errno = ECONNREFUSED;
- if (trace__) fprintf(ftrace__," failed 3 errno=%d\n",errno);
- return(-1);
- }
- }
- if (wait_efn(s) == -1) return(-1); /* time out*/
- if (p[s].connected != SS$_NORMAL){
- errno = ECONNREFUSED;
- if (trace__) fprintf(ftrace__," failed 4 errno=%d\n",errno);
- return(-1);
- }
- if (trace__) fprintf(ftrace__," succeeded\n");
- return(0);
- }
- }
-
- /************************************************************/
- /* listen routine */
- /************************************************************/
- listen(s,backlog)
- int s;
- int backlog;
- {
- int st;
-
- if (trace__) fprintf(ftrace__,"listen called s=%d backlog=%d",s,backlog);
- if ( ! tcp_make) set_tcp_make();
-
- p[s].passive = 1;
- p[s].backlog = backlog;
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- /* For the CMU sockets we can't do the open call in listen we */
- /* have to do it in hang_an_accept, because when we close off */
- /* the connection we have to be ready to accept another one. */
- /* accept also calls hang_an_accept on the old descriptor */
- } /* end of CMU */
- else if (tcp_make == UCX) {
- /*
- * doc verbage sez backlog is descriptor of byte.
- * doc examples and common sense sez backlog is value
- * value don't work, so lets try descriptor of byte after all
- */
- struct descriptor bl;
- unsigned char ucx_backlog;
-
- ucx_backlog =(unsigned char) backlog;
- bl.size = sizeof (ucx_backlog);
- bl.ptr = (char *)&ucx_backlog;
-
- if ((st=sys$qiow(0,p[s].channel,IO$_SETMODE,p[s].iosb,0,0,
- 0,0,0, &bl,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("listen")
- return(-1);
- }
- } /* end of UCX */
- else { /* TWG */
- if ((st=sys$qiow(0,p[s].channel,IO$_LISTEN,p[s].iosb,0,0,backlog,
- 0,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("listen")
- if (trace__) fprintf(ftrace__," failed\n",st);
- return(-1);
- }
- }
- }
- else if (p[s].domain == AF_X25) {
- /* for x25 we have to declare ourselves as a process wanting to*/
- /* accept calls with the acpcontrol command */
- struct descriptor funcdesc, npbdesc;
- char funcblock[5];
- unsigned char npb_blk[64];
- int i;
- if (p[s].x25_listener == 0) {
- p[s].x25_listener = 1;
- funcblock[0] = NFB$C_DECLNAME;
- for (i=1;i<5;i++) funcblock[i] = 0;
- funcdesc.size = 5;
- funcdesc.ptr = funcblock;
- i = setup_npb(s,npb_blk);
- npbdesc.size = i;
- npbdesc.ptr = (char *)npb_blk;
- if ((st=sys$qiow(0,p[s].channel,IO$_ACPCONTROL,p[s].iosb,0,0,&funcdesc,
- &npbdesc,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("listen")
- return(-1);
- }
- }
- }
-
- else return(-1); /* we don't handle any other domain yet */
-
- if (trace__) fprintf(ftrace__," succeeded\n");
- p[s].status = LISTENING;
- hang_an_accept(s);
- return(0);
- }
-
- /************************************************************/
- /* accept routine */
- /************************************************************/
- int accept(s,addr,addrlen)
- int s;
- union socket_addr *addr;
- int *addrlen;
- {
- int news, st;
- struct descriptor inetdesc;
-
- if (trace__) fprintf(ftrace__,"accept called s=%d port=%d ",
- s,htons(addr->in.sin_port));
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].non_blocking && !p[s].accept_pending) {
- if (trace__) fprintf(ftrace__," failed errno=%d\n",errno);
- errno = EWOULDBLOCK;
- return(-1);
- }
-
- /* we still have an unresolved problem in this routine for x25*/
- /* accept should return a new socket descriptor, yet this seems*/
- /* rather tricky as our mailbox is connected with the previous */
- /* descriptor. Sooner or later I'll get my mind round to thinking*/
- /* it out so that its right */
-
- /* hang_an_accept set up an incoming connection request so we */
- /* have first to hang around until one appears or we time out */
-
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- char infobuff[1024];
-
- if (wait_efn(s) == -1) return(-1); /* time out*/
-
- news = dup(0); /* ok get a new descriptor */
- if (news >31 ) {
- errno = EMFILE;
- close(news);
- return(-1);
- }
- bcopy(&p[s],&p[news],sizeof(p[0])); /* and copy all our data across */
- p[news].s = news; /* but not of course this field!*/
- sys$qiow(0,p[news].channel,TCP$INFO,p[news].iosb,0,0,&infobuff,1024,0,0,0,0);
- if (addr != 0) { /* do we need to return the connection info?*/
- *addrlen = sizeof(struct sockaddr_in); /* yes so copy across the info */
- bcopy(infobuff+132,&(addr->in.sin_port),2);
- addr->in.sin_port = htons(addr->in.sin_port);
- addr->in.sin_family = AF_INET;
- bcopy(infobuff+272,&(addr->in.sin_addr),4);
- p[news].fromlen = *addrlen;
- bcopy(addr,&(p[news].from),*addrlen);
- }
- p[news].status = PASSIVE_CONNECTION;
- p[news].fptr = fdopen(news,"r"); /* get a new file ptr for the socket*/
- p[news].accept_pending = 0; /* reset this field */
- p[news].fd_buff = (unsigned char *)malloc(BUF_SIZE); /*allocate a buffer*/
- p[news].fd_leftover = 0;
- hang_a_read(news); /* be prepared to get msgs */
- inetdesc.size = 3; /* now fix up our previous socket */
- inetdesc.ptr = "IP:"; /* so it is again listening for conns*/
- if (sys$assign(&inetdesc,&p[s].channel,0,0) != SS$_NORMAL) return(-1);
- p[s].status = LISTENING;
- hang_an_accept(s);
- return(news); /* return the new socket descriptor */
- }
- else if (tcp_make == UCX) {
- /*
- * UCX does the actual accept from hang_an_accept. The accept info
- * is put into the data structure for the "listening" socket.
- * These just need to be copied into a newly allocated socket for
- * the connect and the listening socket re-started.
- */
-
- /* wait for event flag from accept being received in hang_an_accept() */
- if (wait_efn(s) == -1)
- return(-1); /* time out */
-
- news = dup(0); /* get new descriptor */
- if (news >31 ) {
- errno = EMFILE;
- close(news);
- return(-1);
- }
- bcopy(&p[s], &p[news], sizeof(p[0])); /* and copy all our data across */
- p[news].s = news; /* but not this field */
- p[news].channel = p[s].ucx_accept_chan;
-
- /* initialize the remote host address item_list_3 struct */
- p[news].rhost.length = sizeof(struct sockaddr_in);
- p[news].rhost.code = 0;
- p[news].rhost.dataptr = (char *)&p[news].from;
- p[news].rhost.retlenptr = &p[news].fromdummy;
-
- if (addr != 0) { /* return the callers info, if requested */
- *addrlen = p[news].fromdummy;
- bcopy(&p[news].from, addr, p[news].fromdummy);
- }
-
- /* finish fleshing out the new structure */
- p[news].status = PASSIVE_CONNECTION;
- p[news].fptr = fdopen(news,"r"); /* get a new file pointer for the socket */
- p[news].accept_pending = 0; /* reset this field */
- p[news].fd_buff = (unsigned char *)malloc(BUF_SIZE); /* allocate a buffer */
- p[news].fd_leftover = 0;
-
- hang_a_read(news); /* get it started reading */
-
- p[s].status = LISTENING;
- hang_an_accept(s);
-
- return(news);
-
- } /* end of UCX */
- else { /* TWG */
- struct descriptor inetdesc;
- int size;
-
- if (wait_efn(s) == -1) return(-1); /* time out*/
-
- news = dup(0); /* get new descriptor */
- if (news >31 ) {
- errno = EMFILE;
- close(news);
- return(-1);
- }
- inetdesc.size = 7; /* assign a new channel */
- inetdesc.ptr = "_INET0:";
- if ((st=sys$assign(&inetdesc,&p[news].channel,0,0)) != SS$_NORMAL){
- TRACE("assign new channel")
- p[s].accept_pending = 0;
- sys$clref(s);
- if (trace__) fprintf(ftrace__," failed to assign new channel st=%d\n",st);
- return(-1);
- }
- size = sizeof(p[s].from)+4; /* from info needs an int length field!*/
- if ((st=sys$qiow(0,p[news].channel,IO$_ACCEPT,p[news].iosb,0,0,
- &p[s].fromdummy,size,p[s].channel,0,0,0))
- != SS$_NORMAL || p[news].iosb[0] != SS$_NORMAL) {
- TRACE("accept")
- p[s].accept_pending = 0;
- sys$clref(s);
- return(-1);
- }
- if (addr != 0) { /* return the callers info if requested */
- *addrlen = p[s].fromdummy;
- bcopy(&p[s].from,addr,*addrlen);
- }
- p[news].status = PASSIVE_CONNECTION; /*fix up our new data structure */
- p[news].domain = AF_INET;
- p[news].passive = 1;
- p[news].fptr = fdopen(news,"r");
- p[news].fd_buff = (unsigned char *)malloc(BUF_SIZE); /*allocate a buffer*/
- hang_a_read(news); /* be prepared to accept msgs */
- hang_an_accept(s); /* get the old descriptor back onto accepting */
- if (trace__) fprintf(ftrace__," succeeded returning news=%d\n",news);
- return(news);
- }
- }
- else if (p[s].domain == AF_X25) {
- struct descriptor accept_ncb;
-
- if (wait_efn(s) == -1) return(-1); /* time out*/
-
- news = dup(0); /* ok get a new descriptor */
- if (news >31 ) {
- errno = EMFILE;
- close(news);
- return(-1);
- }
- bcopy(&p[s],&p[news],sizeof(p[0])); /* and copy all our data across */
- p[news].s = news; /* but not of course this field!*/
-
- accept_ncb.size = p[s].ncb_size; /* accept the call */
- accept_ncb.ptr = (char *)&(p[s].ncb);
- if ((st=sys$qiow(0,p[s].channel,IO$_ACCESS | IO$M_ACCEPT,p[s].iosb,0,0,
- 0,&accept_ncb,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("accept")
- p[s].accept_pending = 0;
- sys$clref(s);
- return(-1);
- }
- if (addr != 0) { /* return the callers info if requested */
- decode_ncb(&(p[s].mbx_buff[20]),addr);
- *addrlen = 10+addr->x25.datalen;
- p[news].fromlen = *addrlen;
- bcopy(addr,&(p[news].from),*addrlen);
- }
- p[news].status = PASSIVE_CONNECTION;
- p[news].fptr = fdopen(news,"r"); /* get a new file ptr for the socket*/
- p[news].accept_pending = 0; /* reset this field */
- p[news].fd_buff = (unsigned char *)malloc(BUF_SIZE); /*allocate a buffer*/
- p[news].fd_leftover = 0;
- p[news].mother = s;
- hang_a_read(news);
- p[s].status = LISTENING; /* fix up our data structure */
- p[s].child = news;
- hang_an_accept(s);
- return(news);
- }
-
- else return(-1); /* we don't handle any other domain yet */
- }
-
- /************************************************************/
- /* recv routine */
- /************************************************************/
- int recv(s,buf,len,flags)
- int s;
- char *buf;
- int len, flags;
- {
- return(recvfrom(s,buf,len,flags,0,0)); /* its just a subset */
- }
-
- /************************************************************/
- /* recvfrom routine */
- /************************************************************/
- int recvfrom(s,buf,len,flags,from,fromlen)
- int s;
- char *buf;
- int len, flags;
- union socket_addr *from;
- int *fromlen;
- {
- int number;
-
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].domain != AF_INET && p[s].domain != AF_X25) return(-1);
-
- /* if we are not onto datagrams, then its possible that a previous */
- /* call to recvfrom didn't read all the data, and left some behind */
- /* so first of all look in our data buffer for any leftovers that */
- /* will satisfy this read */
- if (p[s].type != SOCK_DGRAM) {
- if (flags == MSG_OOB) { /* return any interrupt data requested */
- if (p[s].oob_type == INT_DATA) {
- *buf = p[s].int_data;
- p[s].oob_type = 0;
- return(1);
- }
- else return(-1);
- }
- if (p[s].fd_leftover != 0) { /* we have some data left over */
- if (from != NULL) { /* say who its from */
- if (tcp_make == UCX) {
- *fromlen = p[s].fromdummy;
- bcopy(&p[s].from,from,p[s].fromdummy);
- }
- else {
- *fromlen = p[s].fromlen;
- bcopy(&p[s].from,from,p[s].fromlen);
- }
- }/* from != NULL */
- if (p[s].fd_buff_size <= len) { /* if we don't have enough then */
- number = p[s].fd_buff_size; /* just return what we have */
- bcopy(p[s].fd_leftover,buf,number);
- p[s].fd_leftover = 0;
- hang_a_read(s); /* and then be prepared to accept more */
- return(number);
- }
- else {
- bcopy(p[s].fd_leftover,buf,len); /* if we have more than enough */
- p[s].fd_leftover += len; /* just copy as much is necessary */
- p[s].fd_buff_size -= len; /* fix up our ptrs and return */
- return(len);
- }
- }
- }
-
- /* we couldn't satisfy the request from previous calls so we must now */
- /* wait for a message to come through */
- if (wait_efn(s) == -1) return(-1); /* time out*/
-
- while ((p[s].fd_buff_size == -1) && (tcp_make == CMU)) {
- hang_a_read(s);
- if (wait_efn(s) == -1) return(-1);
- }
-
- if (p[s].closed_by_remote == 1) { /* this could have happened!*/
- errno = ECONNRESET;
- return(-1);
- }
- if (p[s].oob_type == INT_DATA) { /* or we could have been sent an interrupt*/
- errno = 39;
- return(-1);
- }
-
- if (from != NULL) {
- if (tcp_make == CMU) {
- if (p[s].type == SOCK_DGRAM) {
- /* not documented but we get the from data from the beginning of */
- /* the data buffer */
- *fromlen = sizeof(p[s].from.in);
- from->in.sin_family = AF_INET;
- bcopy(&p[s].fd_buff[8],&(from->in.sin_port),2);
- from->in.sin_port = htons(from->in.sin_port);
- bcopy(&p[s].fd_buff[0],&(from->in.sin_addr),4);
- }
- else {
- *fromlen = p[s].fromlen;
- bcopy(&p[s].from,from,p[s].fromlen);
- }
- }
- else if (tcp_make == UCX) {
- *fromlen = p[s].fromdummy;
- bcopy(&p[s].from,from,p[s].fromdummy);
- } /* end of if UCX */
- else {
- *fromlen = p[s].fromlen;
- bcopy(&p[s].from,from,p[s].fromlen);
- }
- }
-
- if ((tcp_make == CMU) && (p[s].type == SOCK_DGRAM)) {
- /* remove the address data from front of data buffer */
- bcopy(p[s].fd_buff+12,p[s].fd_buff,p[s].fd_buff_size);
- }
-
- number = p[s].fd_buff_size; /* we may have received too much */
- if (number <= len) { /* if we haven't give back all the data available */
- bcopy(p[s].fd_buff,buf,number);
- p[s].fd_leftover = 0;
- hang_a_read(s);
- return(number);
- }
- else { /* if we have too much data then split it up */
- p[s].fd_leftover = p[s].fd_buff;
- bcopy(p[s].fd_leftover,buf,len);
- p[s].fd_leftover += len; /* and change the pointers */
- p[s].fd_buff_size -= len;
- return(len);
- }
- }
-
- /************************************************************/
- /* send routine */
- /************************************************************/
- int send(s,msg,len,flags)
- int s;
- char *msg;
- int len, flags;
- {
- return(sendto(s,msg,len,flags,0,0)); /* just a subset of sendto */
- }
-
- /************************************************************/
- /* sendto routine */
- /************************************************************/
- int sendto(s,msg,len,flags,to,tolen)
- int s;
- unsigned char *msg;
- int len, flags;
- union socket_addr *to;
- int tolen;
- {
- int i, j, st, size;
- unsigned char udpbuf[BUF_SIZE+12];
- char infobuff[1024], lhost[32];
- unsigned short int temp;
-
- if ( ! tcp_make) set_tcp_make();
-
- /* first remember who we sent it to and set the value of size */
- if (to != 0) {
- p[s].tolen = tolen;
- bcopy(to,&(p[s].to),tolen);
- size = tolen;
- }
- else size = 0;
- if (trace__){
- fprintf(ftrace__,"Sending to stream %d (%d):\n",s,len);
- dmphx(ftrace__,msg,len);
- }
-
- if (p[s].domain == AF_INET) {
- /*we might never have started a read for udp (socket/sendto) so put one here*/
- if (p[s].type == SOCK_DGRAM) hang_a_read(s);
- if (tcp_make == CMU) {
- if (p[s].type == SOCK_DGRAM) {
- /* we might never have opened up a udp connection yet so check */
- if (p[s].cmu_open != 1) {
- if ((st=sys$qiow(0,p[s].channel,TCP$OPEN,p[s].iosb,0,0,
- 0,0,0,0,1,0)) != SS$_NORMAL) return(-1);
- p[s].cmu_open = 1;
- sys$qiow(0,p[s].channel,TCP$INFO,p[s].iosb,0,0,&infobuff,1024,0,0,0,0);
- bcopy(infobuff+264,&(p[s].name.in.sin_port),2);
- p[s].name.in.sin_port = htons(p[s].name.in.sin_port);
- /* bcopy(infobuff+268,&(p[s].name.in.sin_addr),4); /*doesn't work!*/
- bcopy(infobuff+136,lhost,infobuff[1]);
- lhost[infobuff[1]] = '\0';
- sys$qiow(0,p[s].channel,GTHST,p[s].iosb,0,0,&infobuff,1024,1,lhost,0,0);
- bcopy(infobuff+4,&(p[s].name.in.sin_addr),4);
- }
- /* this is not well documented! but to send to a udp socket */
- /* we need to put the address info at the beginning of the */
- /* buffer. */
- bcopy(msg,udpbuf+12,len);
- bcopy(&p[s].to.in.sin_addr,udpbuf+4,4);
- temp = ntohs(p[s].to.in.sin_port);
- bcopy(&temp,udpbuf+10,2);
- bcopy(&p[s].name.in.sin_addr,udpbuf,4);
- temp = ntohs(p[s].name.in.sin_port);
- bcopy(&temp,udpbuf+8,2);
- temp = len+12;
- if ((st=sys$qiow(0,p[s].channel,TCP$SEND,p[s].iosb,0,0,
- udpbuf,temp,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send")
- return(-1);
- }
- }
- else { /* TCP (! UDP) */
- if ((st=sys$qiow(0,p[s].channel,TCP$SEND,p[s].iosb,0,0,
- msg,len,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send")
- return(-1);
- }
- }
- return(len);
- }
- else if (tcp_make == UCX) {
- struct itemlist rhost;
- rhost.length = sizeof(struct sockaddr_in);
- rhost.code = 0;
- rhost.dataptr = (char *)&p[s].to;
-
- if ((st=sys$qiow(0,p[s].channel,IO$_WRITEVBLK,p[s].iosb,0,0,
- msg,len,&rhost,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send");
- return(-1);
- }
- return(len);
- }
- else { /* TWG */
- if ((st=sys$qiow(0,p[s].channel,IO$_WRITEVBLK,p[s].iosb,0,0,msg,len,
- 0,&p[s].to,size,0))!= SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send")
- return(-1);
- }
- return(len);
- }
- }
- else if (p[s].domain == AF_X25) {
- int qual;
-
- /* first check whether the connection is still open */
- if (p[s].closed_by_remote == 1){
- sys$clref(s);
- errno = ECONNRESET;
- return(-1);
- }
- /* now check if we are being asked to send interrupt data */
- if (flags == MSG_OOB) {
- if ((st=sys$qiow(0,p[s].channel,IO$_NETCONTROL,p[s].iosb,0,0,msg,len,
- 0,psi$k_interrupt,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send")
- return(-1);
- }
- return(1);
- }
- /* now fix up the qualifier and send the data */
- qual = 0;
- if ((p[s].send_type & (1<<M_BIT)) == (1<<M_BIT)) qual |= IO$M_MORE;
- if ((p[s].send_type & (1<<Q_BIT)) == (1<<Q_BIT)) qual |= IO$M_QUALIFIED;
- if ((st=sys$qiow(0,p[s].channel,IO$_WRITEVBLK | qual,p[s].iosb,0,0,
- msg,len,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("send")
- return(-1);
- }
- return(len);
- }
- else return(-1); /* we don't handle any other domain yet */
- }
-
- /************************************************************/
- /* getsockname routine */
- /************************************************************/
- int getsockname(s,name,namelen)
- int s;
- union socket_addr *name;
- int *namelen;
- {
- int st;
-
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- /* for CMU we just return values held in our data structure */
- *namelen = p[s].namelen;
- bcopy(&(p[s].name),name,*namelen);
- return(0);
- } /* end of if CMU */
- else if (tcp_make == UCX) {
- struct itemlist lhost; /* an item_list_3 descriptor */
-
- lhost.length = *namelen;
- lhost.code = 0;
- lhost.dataptr = (char *)name;
- lhost.retlenptr = (short int *)namelen;/*?pkay*/ /* fill in namelen with actual ret len value */
-
- if ((st=sys$qiow(0,p[s].channel,IO$_SENSEMODE,p[s].iosb,0,0,
- 0,0,&lhost,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("getsockname")
- return(-1);
- }
- return(0);
- } /* end of if UCX */
- else { /* TWG */
- /* WG gives us the information */
- if ((st=sys$qiow(0,p[s].channel,IO$_GETSOCKNAME,p[s].iosb,0,0,name,
- namelen,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("getsockname")
- return(-1);
- }
- return(0);
- }
- }
- else if (p[s].domain == AF_X25) {
- /* doesn't make sense here ? */
- }
- else return(-1); /* we don't handle any other domain yet */
- }
-
- /************************************************************/
- /* select routine */
- /************************************************************/
- int select(nfds,readfds,writefds,exceptfds,timeout)
- int nfds;
- fd_set *readfds,*writefds,*exceptfds;
- struct timeval *timeout;
- {
- int timer,fd,alarm_set,total,end;
- long mask,cluster;
- struct descriptor termdesc;
- static fd_set new_readfds,new_writefds,new_exceptfds;
-
- if (trace__) fprintf(ftrace__,"select called nfds = %d\n",nfds);
- remembered_alarm_function = alarm_function;
- alarm_function = si_dummy;
-
- FD_ZERO(&new_readfds);
- FD_ZERO(&new_writefds);
- FD_ZERO(&new_exceptfds);
- total = 0;
- if (terminal.chan == -1) { /* assign a terminal channel if we haven't */
- termdesc.size = 10; /* already */
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
- alarm_set = 0;
- if (timeout != NULL) { /* if a timeout is given then set the alarm */
- end = timeout->tv_sec;
- if (timer != 0) {
- alarm_set = 1; /* we need to reset the alarm if it didn't fire */
- si_alarm(end); /* but we set it */
- if (trace__) fprintf(ftrace__,"select setting alarm of %d\n",end);
- }
- }
- else end = 1;
-
- do {
- if (exceptfds) {
- }
-
- if (writefds) {
- for(fd=0;fd<nfds;fd++)
- if(FD_ISSET(fd,writefds)) {
- if (p[fd].connect_pending) ;
- else if ((p[fd].status == ACTIVE_CONNECTION) ||
- (p[fd].status == PASSIVE_CONNECTION)) {
- FD_SET(fd,&new_writefds);
- total++;
- }
- /* CRW -- make stdout available*/
- if (fd == 1) {
- FD_SET(fd,&new_writefds);
- total++;
- }
- /* CRW -- end*/
- }
- }
-
- if (readfds) {
- /* check the terminal for any pending */
- if (FD_ISSET(0,readfds) && (terminal.char_available == 1 )) {
- FD_SET(0,&new_readfds);
- total++;
- }
- /* CRW -- make stdin available*/
- if (FD_ISSET(0,readfds) && (type_ahead() != 0 )) {
- FD_SET(0,&new_readfds);
- total++;
- }
- /* CRW -- end*/
-
- for (fd=3;fd<nfds;fd++) /* true if data pending or an accept */
- if (FD_ISSET(fd,readfds)) {
- if ((p[fd].fd_buff_size != -1) || (p[fd].accept_pending == 1)) {
- FD_SET(fd,&new_readfds);
- total++;
- }
- }
- }
-
- if (end == 0) break;
- if (total) break;
-
- /* otherwise wait on an event flag */
- /* it is possible that the wait can be stopped by a spuriuous event */
- /* flag being set - ie one that has a status not normal. So we have */
- /* to be prepared to loop round the wait until a valid reason happens */
-
- /* set up the wait mask */
- cluster = 0;
- mask = 0;
- for (fd=3;fd<nfds;fd++) {
- sys$clref(fd);
- if (readfds) if FD_ISSET(fd,readfds) mask |= (1<<fd);
- if (writefds) if FD_ISSET(fd,writefds) mask |= (1<<fd);
- if (exceptfds) if FD_ISSET(fd,exceptfds) mask |= (1<<fd);
- if ((FD_ISSET(fd,readfds)) && (tcp_make == CMU) &&
- (p[fd].fd_buff_size == -1) && (p[fd].read_outstanding == 0) &&
- (p[fd].status != LISTENING)) hang_a_read(fd);
- }
- mask |= (1<<TIMER_EFN);
- if (readfds) if (FD_ISSET(0,readfds)) {
- hang_a_terminal_read();
- mask |= (1<<TERM_EFN);
- mask &= 0xfffe;
- }
- sys$clref(TIMER_EFN); /* clear it off just in case */
- sys$wflor(cluster,mask); /* wait around */
-
- mask = 0;
- if (read_efn(TIMER_EFN)) {
- errno = EINTR;
- break;
- }
- } while (1);
-
- if (alarm_set == 1) alarm(0); /* unset the alarm if we set it */
- if (readfds) *readfds = new_readfds;
- if (writefds) *writefds = new_writefds;
- if (exceptfds) *exceptfds = new_exceptfds;
- alarm_function = remembered_alarm_function;
- if (trace__) fprintf(ftrace__,"select returns total = %d\n",total);
- return(total);
- }
-
- /************************************************************/
- /* ioctl routine */
- /************************************************************/
- ioctl(s,request,argp)
- int s;
- unsigned long request;
- union ioctl_arg *argp;
- {
- int i;
- if (p[s].channel != 0) {
- if (request == X25_RD_HOSTADR) {
- myx25_address(argp);
- return(0);
- }
- if (request == X25_WR_MASK_DATA) {
- bcopy(argp,&(p[s].masklen),17);
- return(0);
- }
- if (request == X25_HEADER) {
- p[s].need_header = argp->i;
- return(0);
- }
- if (request == X25_SEND_TYPE) {
- p[s].send_type = argp->i;
- return(0);
- }
- if (request == X25_OOB_TYPE) {
- argp->i = p[s].oob_type;
- return(0);
- }
- if (request == X25_CALL_ACPT_APPROVAL) {
- p[s].need_header = argp->i;
- return(0);
- }
- if (request == X25_WR_CAUSE_DIAG) {
- printf("Reset requests are not handled at present!\n");
- return(0);
- }
- if (request == X25_RD_CAUSE_DIAG) {
- argp->diag.flags = 0;
- return(0);
- }
- if (request == X25_RD_FACILITY) {
- argp->fac.reverse_charge = 0;
- argp->fac.recvpktsize = 128;
- argp->fac.sendpktsize = 128;
- argp->fac.recvwndsize = 2;
- argp->fac.sendwndsize = 2;
- argp->fac.recvthruput = 10;
- argp->fac.sendthruput = 10;
- argp->fac.cug_req = 0;
- argp->fac.cug_index = 0;
- argp->fac.fast_select_type = 0;
- argp->fac.rpoa_req = 0;
- argp->fac.rpoa = 0;
- return(0);
- }
- if (request == X25_RECORD_SIZE) {
- argp->i = 128;
- return(0);
- }
- if (request == X25_SEND_CALL_ACPT) {
- return(0);
- }
- if (request == SIOCSPGRP) {
- return(0);
- }
- if (request == FIONBIO) {
- p[s].non_blocking = 1;
- return(0);
- }
- printf("ioctl call on socket - not handled yet, request =%x\n",request);
- return(0);
- }
- else if (s == 0) {
- if (request == FIONREAD) {
- argp->i = type_ahead();
- return(0);
- }
- if (request == TIOCGETP) {
- argp->sg.sg_ispeed = def_tty.sg_ispeed;
- argp->sg.sg_ospeed = def_tty.sg_ospeed;
- argp->sg.sg_erase = def_tty.sg_erase;
- argp->sg.sg_kill = def_tty.sg_kill;
- argp->sg.sg_flags = def_tty.sg_flags;
- return(0);
- }
- if (request == TIOCSETP) {
- def_tty.sg_ispeed = argp->sg.sg_ispeed;
- def_tty.sg_ospeed = argp->sg.sg_ospeed;
- def_tty.sg_erase = argp->sg.sg_erase;
- def_tty.sg_kill = argp->sg.sg_kill;
- def_tty.sg_flags = argp->sg.sg_flags;
- if ( (def_tty.sg_flags & ECHO) == ECHO ) set_echo();
- else set_noecho();
- return(0);
- }
- if (request == TIOCGLTC) {
- argp->t.t_suspc = 0x19;
- argp->t.t_dsuspc = 0x19;
- argp->t.t_rprntc = 0xff;
- argp->t.t_flushc = 0xff;
- argp->t.t_werasc = 0xff;
- argp->t.t_lnextc = 0x0;
- return(0);
- }
- if (request == TIOCSLTC) {
- return(0);
- }
- if (request == TCGETA) {
- argp->te.c_iflag = def_te.c_iflag;
- argp->te.c_oflag = def_te.c_oflag;
- argp->te.c_cflag = def_te.c_cflag;
- argp->te.c_lflag = def_te.c_lflag;
- argp->te.c_line = def_te.c_line;
- for (i=0;i<NCC;i++) argp->te.c_cc[i] = def_te.c_cc[i];
- return(0);
- }
- if (request == TCSETA) {
- def_te.c_iflag = argp->te.c_iflag;
- def_te.c_oflag = argp->te.c_oflag;
- def_te.c_cflag = argp->te.c_cflag;
- def_te.c_lflag = argp->te.c_lflag;
- def_te.c_line = argp->te.c_line;
- for (i=0;i<NCC;i++) def_te.c_cc[i] = argp->te.c_cc[i];
- if ( (def_te.c_lflag & ECHO) == ECHO ) set_echo();
- else set_noecho();
- return(0);
- }
- printf("ioctl call on terminal - not handled yet, request =%d\n",request);
- return(-1);
- }
- else {
- printf("ioctl call on file - not handled yet, request =%d\n",request);
- return(0);
- }
- }
-
- /************************************************************/
- /* shutdown routine */
- /************************************************************/
- shutdown(s,how)
- int s,how;
- {
- int st;
- int ucx_how;
-
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- /* for CMU we just close off */
- si_close(s);
- return(0);
- } /* end of if CMU */
- else if (tcp_make == UCX) {
- if ((st=sys$qiow(0,p[s].channel,IO$_DEACCESS | IO$M_SHUTDOWN,p[s].iosb,0,0,
- 0,0,0,how,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("shutdown")
- return(-1);
- }
- return(0);
- } /* end of if UCX */
- else { /* TWG */
- /* WG lets us do it */
- if ((st=sys$qiow(0,p[s].channel,IO$_SHUTDOWN,p[s].iosb,0,0,how,
- 0,0,0,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("shutdown")
- return(-1);
- }
- return(0);
- }
- }
- else if (p[s].domain == AF_X25) {
- /* for X25 we just close off */
- si_close(s);
- return(0);
- }
- else return(-1); /* not a socket */
- }
-
- /************************************************************/
- /* getsockopt routine */
- /************************************************************/
- getsockopt(s,level,optname,optval,optlen)
- int s, level, optname;
- char *optval;
- int *optlen;
- {
- }
-
- /************************************************************/
- /* setsockopt routine */
- /************************************************************/
- setsockopt(s,level,optname,optval,optlen)
- int s, level, optname;
- char *optval;
- int optlen;
- {
- int st;
- unsigned int on = 1;
-
- if ( ! tcp_make) set_tcp_make();
-
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- /* for CMU don't know what to do yet */
- return(0);
- } /* end of if CMU */
- else if (tcp_make == UCX) {
- struct itemlist topdesc;
- struct itemlist optitem;
-
- /* set up the item lists */
- topdesc.length = sizeof(optitem);
- topdesc.code = UCX$C_SOCKOPT;
- topdesc.dataptr = (char *)&optitem;
-
- optitem.length = optlen;
- optitem.code = optname;
- optitem.dataptr = optval;
-
- if ((st=sys$qiow(0,p[s].channel,IO$_SETMODE, p[s].iosb,0,0,
- 0,0,0,0,&topdesc,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("shutdown")
- return(-1);
- }
- return(0);
- } /* end of if UCX */
- else { /* TWG */
- /* WG lets us do it */
- if (optval == NULL) {
- optval = (char *)&on;
- optlen = sizeof(on);
- }
- if ((st=sys$qiow(0,p[s].channel,IO$_SETSOCKOPT,p[s].iosb,0,0,level,
- optname,optval,optlen,0,0)) != SS$_NORMAL || p[s].iosb[0] != SS$_NORMAL) {
- TRACE("setsockopt")
- return(-1);
- }
- return(0);
- }
- }
- else if (p[s].domain == AF_X25) {
- /* doesn't make sense */
- return(-1);
- }
- else return(-1); /* not a socket */
- }
-
- /*********************************************************************/
- /* The following routines are used by the above socket calls */
- /*********************************************************************/
-
- /************************************************************/
- /* hang a read sets up a read to be finished at some later time*/
- /************************************************************/
- hang_a_read(s)
- int s;
- {
- extern int read_ast();
- int size, st;
-
- if (p[s].read_outstanding == 1) return; /* don't bother if we already */
- p[s].read_outstanding = 1; /* have a read outstanding */
- size = sizeof(p[s].from)+4;
- sys$clref(s); /* clear off the event flag just in case */
- p[s].fd_buff_size = -1; /* and reset the buffer size */
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- if ((st=sys$qio(s,p[s].channel,TCP$RECEIVE,p[s].iosb,read_ast,&p[s],
- p[s].fd_buff,BUF_SIZE,0,0,0,0)) != SS$_NORMAL) {
- TRACE("hang a read")
- return(-1);
- }
- } /* end of if CMU */
- else if (tcp_make == UCX) {
-
- p[s].rhost.length = sizeof (struct sockaddr_in);
- p[s].rhost.code = 0;
- p[s].rhost.dataptr = (char *)&p[s].from;
- p[s].rhost.retlenptr = &p[s].fromdummy;
-
- if ((st=sys$qio(s,p[s].channel,IO$_READVBLK,p[s].iosb,read_ast,&p[s],
- p[s].fd_buff,BUF_SIZE,&p[s].rhost,0,0,0)) != SS$_NORMAL) {
- TRACE("hang a read")
- return(-1);
- }
- }
- else { /* TWG */
- if ((st=sys$qio(s,p[s].channel,IO$_READVBLK,p[s].iosb,read_ast,&p[s],
- p[s].fd_buff,BUF_SIZE,0,&p[s].fromlen,size,0)) != SS$_NORMAL) {
- TRACE("hang a read")
- return(-1);
- }
- }
- }
- else if (p[s].domain == AF_X25) {
- if (p[s].need_header == 1) { /* do we need m, q bits */
- if ((st=sys$qio(s,p[s].channel,IO$_READVBLK,p[s].iosb,read_ast,&p[s],
- p[s].fd_buff+1,BUF_SIZE-1,0,0,0,0)) != SS$_NORMAL) {
- TRACE("hang a read")
- return(-1);
- }
- }
- else {
- if ((st=sys$qio(s,p[s].channel,IO$_READVBLK,p[s].iosb,read_ast,&p[s],
- p[s].fd_buff,BUF_SIZE,0,0,0,0)) != SS$_NORMAL) {
- TRACE("hang a read")
- return(-1);
- }
- }
- }
- else return(-1); /* we don't handle any other domain yet */
- }
-
- /************************************************************/
- /* hang an accept waits for a connection request to come in */
- /************************************************************/
- hang_an_accept(s)
- int s;
- {
- extern int accept_ast();
- int st;
-
- sys$clref(s); /* clear the event flag just in case */
- p[s].accept_pending = 0; /* reset our own flag */
- p[s].fd_buff_size = -1; /* and buffer size */
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- if ((st=sys$qio(s,p[s].channel,TCP$OPEN,p[s].iosb,accept_ast,&p[s],
- 0,0,ntohs(p[s].name.in.sin_port),0,0,0)) != SS$_NORMAL) return(-1);
- }
- else if (tcp_make == UCX) {
- struct descriptor inetdesc;
- /* Assign channel for actual connection off listener */
- inetdesc.size = 3;
- inetdesc.ptr = "BG:";
- if (sys$assign(&inetdesc,&p[s].ucx_accept_chan,0,0) != SS$_NORMAL)
- return(-1);
-
- /*
- * UCX's accept returns remote host info and the channel for a new socket
- * to perform reads/writes on, so a sys$assign is not necessary
- */
- p[s].rhost.length = sizeof(struct sockaddr_in);
- p[s].rhost.dataptr = (char *)&p[s].from;
- p[s].fromdummy = 0;
- p[s].rhost.retlenptr = &p[s].fromdummy;
-
- if ((st=sys$qio(s,p[s].channel,IO$_ACCESS|IO$M_ACCEPT,p[s].iosb,accept_ast, &p[s],
- 0,0,&p[s].rhost,&p[s].ucx_accept_chan,0,0)) != SS$_NORMAL) { /* since QIO, don't check IOSB */
- TRACE("hang an accept")
- return(-1);
- }
- }
- else { /* TWG */
- if ((st=sys$qio(s,p[s].channel,IO$_ACCEPT_WAIT,p[s].iosb,accept_ast,&p[s],
- 0,0,0,0,0,0)) != SS$_NORMAL){
- TRACE("hang a wait")
- return(-1);
- }
- }
- }
- else if (p[s].domain == AF_X25) { /* all taken care of by the mailbox */
- }
- else return(-1); /* we don't handle any other domain yet */
- }
-
- /************************************************************/
- /* hang a terminal read sets up a read on the term with no */
- /* character filtering or echo. Only ctrl-Y ctrl-C get thru */
- /************************************************************/
- hang_a_terminal_read()
- {
- extern int term_ast();
- if (terminal.read_outstanding == 1) return;
- terminal.char_available = 0;
- terminal.read_outstanding = 1;
- sys$clref(TERM_EFN);
- sys$qio(0,terminal.chan,IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR,
- terminal.iosb,term_ast,0,terminal.c,1,0,0,0,0);
- }
-
- /************************************************************/
- /* wait_efn just sets up a wait on either an event or the timer */
- /************************************************************/
- wait_efn(s)
- int s;
- {
- long mask,cluster;
-
- cluster = 0;
- sys$clref(TIMER_EFN);
- mask = (1<<s) | (1<<TIMER_EFN);
- sys$wflor(cluster,mask);
- if (read_efn(TIMER_EFN)) {
- errno = EINTR;
- return(-1);
- }
- return(0);
- }
-
- /************************************************************/
- /* read_ast is called by the system whenever a read is done */
- /************************************************************/
- read_ast(p)
- struct fd_entry *p; /* pointer to data array, the data includes the */
- { /* array element number */
- int i, j;
- unsigned char *v, *w;
-
- TRACE1("read")
- p->read_outstanding = 0; /* reset the outstanding flag */
- if (p->iosb[0] == SS$_NORMAL) { /* check no errors */
- p->fd_buff_size = p->iosb[1];
- if (tcp_make == CMU) {
- if (p->type == SOCK_DGRAM) p->fd_buff_size -= 12; /* fiddle for DGRMs*/
- }
- if (p->need_header == 1) { /* x25 sometimes needs this info */
- *(p->fd_buff) = 0;
- if (p->iosb[2] == psi$m_qualified) *(p->fd_buff) |= 1<<Q_BIT;
- if (p->iosb[2] == psi$m_moredata) *(p->fd_buff) |= 1<<M_BIT;
- }
- if (p->sig_req == 1) gsignal(SIGIO);
- if (trace__) {
- fprintf(ftrace__,"Received from stream %d (%d):\n",p->s,p->iosb[1]);
- dmphx(ftrace__,p->fd_buff,p->iosb[1]);
- }
- }
-
- else if (p->iosb[0] == SS$_CLEARED) {
- p->closed_by_remote = 1;
- }
- else if (tcp_make == UCX) {
- if (p->iosb[0] == SS$_LINKDISCON) {
- p->closed_by_remote = 1;
- }
- }
- }
-
- /************************************************************/
- /* accept_ast is called whenever a incoming call is detected*/
- /************************************************************/
- accept_ast(p)
- struct fd_entry *p;
- {
- TRACE1("accept")
- if (p->iosb[0] == SS$_NORMAL) p->accept_pending = 1;
- else {
- listen(p->s,p[p->s].backlog); /* if it failed set up another listen */
- }
- }
-
- /************************************************************/
- /* connect_ast is called whenever an async connect is made */
- /************************************************************/
- connect_ast(p)
- struct fd_entry *p;
- {
- TRACE1("connect")
- p->connect_pending = 0;
- if ((p->connected = p->iosb[0]) == SS$_NORMAL) {
- p->status = ACTIVE_CONNECTION; /* we made the connection */
- hang_a_read(p->s); /* be prepared to accept a msg */
- }
- }
-
- /************************************************************/
- /* mailbox_ast is called whenever the x25 state changes */
- /************************************************************/
- mailbox_ast(p)
- struct fd_entry *p;
- {
- int st;
- struct descriptor accept_ncb;
- if (trace__) {
- fprintf(ftrace__,"mailbox ast called message type %d\n",p->mbx_buff[0]);
- fprintf(ftrace__,"stream s=%d status=%d state is %d\n",p->s,p->iosb[0],p->status);
- }
-
- /* if we just connected to another DTE we will get a message confirming
- the call which we just discard */
- if (p->status == ACTIVE_CONNECTION) {
- if (p->mbx_buff[0] == MSG$_DISCON) {
- p->closed_by_remote = 1;
- sys$setef(p->s);
- }
- else if (p->mbx_buff[0] == MSG$_RESET) {
- p->closed_by_remote = 1;
- p->oob_type = VC_RESET;
- sys$setef(p->s);
- (*sigurg_function)();
- }
- else if (p->mbx_buff[0] == MSG$_INTMSG) {
- p->oob_type = INT_DATA;
- p->int_data = p->mbx_buff[21];
- sys$setef(p->s);
- (*sigurg_function)();
- }
- }
- else if (p->child != 0) {
- if (p->mbx_buff[0] == MSG$_DISCON) {
- p[p->child].closed_by_remote = 1;
- sys$setef(p->child);
- p->child = 0; /* in case the child doesn't close!*/
- }
- else if (p->mbx_buff[0] == MSG$_RESET) {
- p[p->child].closed_by_remote = 1;
- p[p->child].oob_type = VC_RESET;
- sys$setef(p->child);
- p->child = 0; /* in case the child doesn't close!*/
- (*sigurg_function)();
- }
- else if (p->mbx_buff[0] == MSG$_INTMSG) {
- p[p->child].oob_type = INT_DATA;
- p[p->child].int_data = p->mbx_buff[21];
- sys$setef(p->child);
- (*sigurg_function)();
- }
- }
-
- /* if we get a disconnect message when we have already disconnected then
- ignore it */
- else if (p->mbx_buff[0] == MSG$_DISCON) {
- }
-
- else if ((p->status == LISTENING) && (p->mbx_buff[0] == MSG$_CONNECT)) {
- if (p->no_more_accepts == 1) {
- p->ncb_size = p->mbx_buff[20];
- bcopy(p->mbx_buff+21,p->ncb,p->ncb_size);
- accept_ncb.size = p->ncb_size; /* accept the call */
- accept_ncb.ptr = (char *)p->ncb;
- sys$qiow(0,p->channel,IO$_ACCESS | IO$M_ABORT,p->iosb,0,0,
- 0,&accept_ncb,0,0,0,0);
- }
- else {
- /* copy the ncb into p[s] and signal the event flag s to unhang the wait*/
- p->ncb_size = p->mbx_buff[20];
- bcopy(p->mbx_buff+21,p->ncb,p->ncb_size);
- p->accept_pending = 1;
- sys$setef(p->s);
- }
- }
-
- /* set up another read*/
- if ((st=sys$qio(0,p->mbx_channel,IO$_READVBLK,p->miosb,mailbox_ast,p,
- p->mbx_buff,255,0,0,0,0)) != SS$_NORMAL){
- return(-1);
- }
- }
-
- /************************************************************/
- /* terminal_ast is called whenever a char is typed at the kbd*/
- /************************************************************/
- term_ast()
- {
- if (trace__) {
- fprintf(ftrace__,"term ast called %d\n",terminal.iosb[0]);
- }
- terminal.read_outstanding = 0;
- if (terminal.iosb[0] == SS$_NORMAL) {
- terminal.char_available = 1;
- sys$setef(TERM_EFN);
- }
- }
-
- /************************************************************/
- /* now we get to the fiddled routines to handle stream io */
- /************************************************************/
-
- /************************************************************/
- /* si_close - must close off any connection in progress */
- /************************************************************/
- si_close(s)
- int s;
- {
- if ( ! tcp_make) set_tcp_make();
-
- if ( (s<0) || (s>31) ) return(-1);
- if (trace__) fprintf(ftrace__,"close called s=%d\n",s);
- if (p[s].channel != 0) {/* was it one of our descriptors*/
- if (p[s].domain == AF_INET) {
- if (tcp_make == CMU) {
- sys$qiow(0,p[s].channel,TCP$CLOSE,p[s].iosb,0,0,0,0,0,0,0,0);
- }
- if (p[s].status != HANDED_OFF) sys$dassgn(p[s].channel);
- close(s);
- free(p[s].fd_buff);
- p_initialise(s);
- }
- else if (p[s].domain == AF_X25) {
- if (p[s].status == ACTIVE_CONNECTION) {
- sys$qiow(0,p[s].channel,IO$_DEACCESS,p[s].iosb,0,0,0,0,0,0,0,0);
- if (p[s].status != HANDED_OFF) sys$dassgn(p[s].channel);
- close(s);
- free(p[s].fd_buff);
- p_initialise(s);
- }
- else if ((p[s].status == LISTENING) && (p[s].child != 0)) {
- /* mother is being closed - child still lives */
- p[s].no_more_accepts = 1;
- }
- else if ((p[s].status == LISTENING) && (p[s].child == 0)) {
- /* mother didn't have any childs so close her off */
- sys$qiow(0,p[s].channel,IO$_DEACCESS,p[s].iosb,0,0,0,0,0,0,0,0);
- sys$dassgn(p[s].channel);
- close(s);
- free(p[s].fd_buff);
- p_initialise(s);
- }
- else if ((p[s].status == PASSIVE_CONNECTION) && (p[p[s].mother].no_more_accepts == 1)){
- /* child and mother can now be closed */
- sys$qiow(0,p[s].channel,IO$_DEACCESS,p[s].iosb,0,0,0,0,0,0,0,0);
- sys$dassgn(p[s].channel);
- close(s);
- free(p[s].fd_buff);
- close(p[s].mother);
- free(p[p[s].mother].fd_buff);
- p_initialise(p[s].mother);
- p_initialise(s);
- }
- else if ((p[s].status == PASSIVE_CONNECTION) && (p[p[s].mother].no_more_accepts == 0)){
- /* close off child but leave mother alone for more accepts */
- p[p[s].mother].child = 0;
- sys$qiow(0,p[s].channel,IO$_DEACCESS,p[s].iosb,0,0,0,0,0,0,0,0);
- close(s);
- free(p[s].fd_buff);
- p_initialise(s);
- }
- }
- return(0);
- }
- else {
- p[s].fd_buff_size = -1; /* re-initialise data structure just in case */
- p[s].accept_pending = 0;
- p[s].status = INITIALISED;
- if (s == 0) return(0);
- return(close(s));
- }
- }
-
- /************************************************************/
- /* si_signal - must remember name of function to be called */
- /************************************************************/
- si_signal(sig,func)
- int sig;
- int (*func)();
- {
- int pre_alarm();
-
- /* we need to catch calls to signal for conditions SIGALRM and SIGURG */
- /* we divert them through our own routine before running the one the */
- /* user wants, so this routine just grabs the name of the function and*/
- /* stores it away */
- if (sig == SIGALRM){
- if (func == SIG_IGN) {
- alarm_function = si_dummy;
- signal(sig,func);
- }
- else if (func == SIG_DFL) {
- alarm_function = si_dummy;
- }
- else {
- alarm_function = func;
- }
- }
- else if (sig == SIGURG){
- if (func == SIG_IGN) {
- sigurg_function = si_dummy;
- signal(sig,func);
- }
- else if (func == SIG_DFL) {
- sigurg_function = si_dummy;
- }
- else {
- sigurg_function = func;
- }
- }
- else signal(sig,func);
- }
-
- /************************************************************/
- /* si_sigvec - must remember name of function to be called */
- /************************************************************/
- si_sigvec(sig,vec,ovec)
- int sig;
- struct sigvec *vec, *ovec;
- {
- int pre_alarm();
-
- /* we need to catch calls to signal for conditions SIGALRM and SIGURG */
- /* we divert them through our own routine before running the one the */
- /* user wants, so this routine just grabs the name of the function and*/
- /* stores it away */
- if (sig == SIGALRM){
- if (vec->sv_handler == SIG_IGN) {
- alarm_function = si_dummy;
- sigvec(sig,vec,ovec);
- }
- else if (vec->sv_handler == SIG_DFL) {
- alarm_function = si_dummy;
- }
- else {
- alarm_function = vec->sv_handler;
- }
- }
- else if (sig == SIGURG){
- if (vec->sv_handler == SIG_IGN) {
- sigurg_function = si_dummy;
- sigvec(sig,vec,ovec);
- }
- else if (vec->sv_handler == SIG_DFL) {
- sigurg_function = si_dummy;
- }
- else {
- sigurg_function = vec->sv_handler;
- }
- }
- else sigvec(sig,vec,ovec);
- }
-
- /************************************************************/
- /* si_alarm - insert a call to our own alarm function */
- /************************************************************/
- si_alarm(i)
- int i;
- {
- extern int pre_alarm();
-
- if (trace__) fprintf(ftrace__,"si_alarm called time = %d\n",i);
- /* make the call to pre_alarm instead of what the user wants */
- /* pre_alarm will call his routine when it finishes */
- signal(SIGALRM,pre_alarm); /*vax needs this call each time!*/
- alarm(i);
- }
-
- /************************************************************/
- /* pre_alarm - gets called first on an alarm signal */
- /************************************************************/
- pre_alarm()
- {
- /* come here first so we can set our timer event flag */
- sys$setef(TIMER_EFN);
- (*alarm_function)();
- }
-
- /************************************************************/
- /* si_write - trap system write calls */
- /************************************************************/
- int si_write(s,buf,nbytes)
- int s;
- char *buf;
- int nbytes;
- {
- if ( (s<1) || (s>31) ) return(-1); /*can't write to stdin as well*/
- /* if its our socket then call sendto instead of write */
- /*fprintf(stderr,"write called s=%d nbytes=%d\n",s,nbytes);*/
- if (p[s].channel != 0) return(sendto(s,buf,nbytes,0,0,0));
- return(write(s,buf,nbytes));
- }
-
- /************************************************************/
- /* writev - system writev calls */
- /* */
- /* Revised 2/17/91 Louisa Thomson */
- /* Rewrote the code to handle large iov entries and to */
- /* flush data out at 512 bytes. This */
- /* appears to be the atomic session data unit, however */
- /* I was unable to find the symbol for it. Therefore, */
- /* 512 is hardcoded in there. */
- /************************************************************/
-
- int writev(s,iov,iovcnt)
- int s;
- struct iovec *iov;
- int iovcnt;
- {
- int cnt, cc, i, j, bufflen, iovlen;
- char buffer[1024];
- char *ptr;
-
- if ( (s<0) || (s>31) ) return(-1); /* check channels */
- cnt = 0; /* total character count */
- j = 0; /* index into the iov entries */
- i = 0; bufflen = 512;
- ptr = iov[j].iov_base;
- iovlen = iov[j].iov_len;
-
-
- while (j < iovcnt) { /* do all the iov blocks */
-
- if (bufflen < iovlen) cc = bufflen;
- else cc = iovlen;
- bcopy(ptr, buffer+i, cc); /* copy from iov to buffer */
-
- /* increment everything */
- ptr += cc;
- i += cc;
- iovlen -= cc;
- bufflen -= cc;
-
- if (i >= 512){ /* if buffer is full--flush */
- if (p[s].channel != 0) cnt += sendto(s, buffer, i, 0, 0, 0);
- else cnt += write(s, buffer, i);
- i=0; bufflen = 512; /* reinitialize variables */
- }
-
- if (iovlen <= 0){ /* if iov block is done...get next one */
- j += 1;
- if (j < iovcnt){
- ptr = iov[j].iov_base;
- iovlen = iov[j].iov_len;
- }
- }
-
- }
-
- if (bufflen != 512){ /* output any partial buffer */
- if (p[s].channel != 0) cnt += sendto(s,buffer,i,0,0,0);
- else cnt += write(s, buffer, i);
- }
-
- return(cnt); /* return total character count */
- }
-
- /************************************************************/
- /* si_read - trap system read calls */
- /************************************************************/
- int si_read(s,buf,nbytes)
- int s;
- char *buf;
- int nbytes;
- {
- if ( (s<0) || (s>31) ) return(-1);
- /* if its our socket then call recvfrom instead of read */
- if (p[s].channel != 0) return(recvfrom(s,buf,nbytes,0,0,0));
- return(read(s,buf,nbytes));
-
- }
-
- /************************************************************/
- /* fcntl - trap system fcntl calls */
- /************************************************************/
- int fcntl(s,cmd,arg)
- int s, cmd, arg;
- {
- int flags;
- if ( (s<0) || (s>31) ) return(-1);
- if (p[s].channel != 0) {
- if (cmd == F_SETFL) {
- if ( (arg & FNDELAY) == FNDELAY) p[s].non_blocking = 1;
- else p[s].non_blocking = 0;
- if ( (arg & FASYNC) == FASYNC) p[s].sig_req = 1;
- else p[s].sig_req = 0;
- return(0);
- }
- if (cmd == F_GETFL) {
- flags = 0;
- if (p[s].non_blocking == 1) flags |= FNDELAY;
- if (p[s].sig_req == 1) flags |= FASYNC;
- return(flags);
- }
- printf("Unexpected cmd to fcntl - %d\n",cmd);
- return(-1);
- }
- printf("Fcntl called on a descriptor!\n");
- return(-1);
-
- }
-
- /************************************************************/
- /* si_fdopen - return a file ptr for a descriptor */
- /************************************************************/
- FILE *si_fdopen(fildes,type)
- int fildes;
- char *type;
- {
- if (p[fildes].channel != 0) return(p[fildes].fptr);
- return(fdopen(fildes,type));
- }
-
- /************************************************************/
- /* si_fprintf - printf to a stream */
- /************************************************************/
- int si_fprintf(stream,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16)
- FILE *stream;
- char *format;
- int *a1,*a2,*a3,*a4,*a5,*a6,*a7,*a8,*a9,*a10,*a11,*a12,*a13,*a14,*a15,*a16;
- {
- char buf[1024];
- int fd;
-
- /* this is not pretty but how else can we handle variable number of */
- /* arguments except declare lots of them, no checking is done if we */
- /* supply to few. Of course if more than 16 are passed we get into */
- /* awful trouble */
- if ((fd=get_fd_fptr(stream)) != -1) {
- sprintf(buf,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16);
- return(send(fd,buf,strlen(buf),0));
- }
- return(fprintf(stream,format,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16));
- }
-
- /************************************************************/
- /* si_fclose - close of a stream */
- /************************************************************/
- si_fclose(stream)
- FILE *stream;
- {
- int fd;
-
- if ((fd=get_fd_fptr(stream)) != -1) return(si_close(fd));
- return(fclose(stream));
- }
-
- /************************************************************/
- /* si_rewind - rewind a stream */
- /************************************************************/
- si_rewind(stream)
- FILE *stream;
- {
- int fd;
-
- /* don't do anything if its one of ours */
- if ((fd=get_fd_fptr(stream)) != -1) return(0);
- return(rewind(stream));
- }
-
- /************************************************************/
- /* si_fflush - flush a stream */
- /************************************************************/
- si_fflush(stream)
- FILE *stream;
- {
- int fd;
-
- /* don't do anything if its one of ours */
- if ((fd=get_fd_fptr(stream)) != -1) return(0);
- return(fflush(stream));
- }
-
- /************************************************************/
- /* si_fgets - get a string from a stream */
- /************************************************************/
- char *si_fgets(s,n,stream)
- char *s;
- int n;
- FILE *stream;
- {
- int fd, i;
- char buf[1], *t;
-
- /* we need to read a character string from the socket which is */
- /* terminated by a nl. Do this the hard way by reading 1 char */
- /* at a time and testing it */
- if ((fd=get_fd_fptr(stream)) != -1) {
- t = s;
- for (i=1;i<n;i++) {
- if (recvfrom(fd,buf,1,0,0) == 0) {
- return(0);
- }
- *t++ = buf[0];
- if (buf[0] == '\n') break;
- }
- *t = '\0';
- return(s);
- }
- return(fgets(s,n,stream));
- }
-
- /*************************************************************/
- /* si_fgetc - get a character from a stream */
- /*************************************************************/
- si_fgetc(stream)
- FILE *stream;
- {
- char buf[1];
- int fd;
-
- if ((fd=get_fd_fptr(stream)) != -1) {
- if (recvfrom(fd,buf,1,0,0) == 0) {
- return(EOF); /* EOF */
- }
- return(buf[0]);
- }
-
- return(fgetc(stream));
- }
-
- /************************************************************/
- /* si_fputc - put a char to a stream */
- /************************************************************/
- si_fputc(c,stream)
- char c;
- FILE *stream;
- {
- int fd;
-
- if ((fd=get_fd_fptr(stream)) != -1) return(sendto(fd,&c,1,0,0,0));
- return(fputc(c,stream));
- }
-
- /************************************************************/
- /* si_fputs - put a string to a stream */
- /************************************************************/
- si_fputs(s,stream)
- char *s;
- FILE *stream;
- {
- int fd;
-
- if ((fd=get_fd_fptr(stream)) != -1) return(sendto(fd,s,strlen(s),0,0,0));
- if (strlen(s) <= 0x800) return(fputs(s,stream));
- while (*s != '\0') fputc(*s++,stream);
- }
-
- /************************************************************/
- /* getpeername */
- /************************************************************/
- getpeername(s,from,fromlen)
- int s;
- struct sockaddr *from;
- int *fromlen;
- {
- if (p[s].status != 0) {
- *fromlen = p[s].fromlen;
- bcopy(from,&(p[s].from),p[s].fromlen);
- return(0);
- }
- return(-1);
- }
-
- /************************************************************/
- /* gethostbyname */
- /************************************************************/
- gethostname(name, namelen)
- char *name;
- int namelen;
- {
- char p[24], *t, *getenv();
-
- if ( ! tcp_make) set_tcp_make();
-
- if (tcp_make == CMU) {
- t = getenv("INTERNET_HOST_NAME");
- }
- else if (tcp_make == UCX) {
- t = getenv("UCX$INET_HOST");
- }
- else {
- t = getenv("ARPANET_HOST_NAME");
- }
- if (t == NULL) {
- printf("What is your internet name\n");
- t = (char *)malloc(24);
- gets(t);
- }
- strcpy(name,t);
- }
-
- /************************************************************/
- /* now some useful internal routines */
- /************************************************************/
-
- /************************************************************/
- /* get_fd_fptr - get the file pointer given the descriptor */
- /************************************************************/
- int get_fd_fptr(fptr)
- FILE *fptr;
- {
- int i;
- for (i=1;i<32;i++) if (fptr == p[i].fptr) return(i);
- return(-1);
- }
-
- /************************************************************/
- /* get a line of text from a file */
- /************************************************************/
- int getl(fp,s,lim)
- FILE *fp;
- char s[];
- int lim;
- {
- int c,i;
- i = 0;
- while (--lim>0 && (c=getc(fp)) != EOF && c != '\n') s[i++] = c;
- if (c == '\n') s[i++] = c;
- s[i] = '\0';
- return(i);
- }
-
- /************************************************************/
- /* myx25_address - tell me who I am */
- /************************************************************/
- myx25_address(s)
- CONN_DB *s;
- {
- char p[24], *t, *getenv();
- t = getenv("X25_ADDRESS");
- if (t == NULL) {
- printf("What is your x25 address\n");
- t = (char *)malloc(24);
- gets(t);
- }
- p[0] = strlen(t) &0xff;
- strcpy(p+1,t);
- s->hostlen = strlen(t);
- ascic_to_bcd(p,s->host);
- return;
- }
-
- /************************************************************/
- /* myx25_subaddress - tell me who I am */
- /************************************************************/
- myx25_subaddress(i)
- int *i;
- {
- char *z, *getenv();
- z = getenv("X25_SUBADDRESS");
- if (z == NULL) *i = -1;
- else if (sscanf(z,"%d",i) == -1) *i = -1;
- }
-
- /************************************************************/
- /* bcd_to_ascic - convert bcd to counted ascii string */
- /************************************************************/
- bcd_to_ascic(b,a,len)
- char *b,*a;
- int len;
- {
- int i;
- *a++ = len & 0xff;
- for (i=0;i<len;i++){
- if ((i%2) == 0) *a = ( (*b>>4)&0x0f ) +'0';
- else {
- *a = ( (*b)&0x0f ) +'0';
- b++;
- }
- a++;
- }
- }
-
- /************************************************************/
- /* ascic_to_bcd - convert counted ascii string to bcd */
- /************************************************************/
- ascic_to_bcd(a,b)
- char *a, *b;
- {
- int i, len;
- for (i=0;i<8;i++) *b++ = '\0';
- b -= 8;
- len = *a++;
- for (i=0;i<len;i++) {
- if ((i%2) == 0) *b = ( ((*a-'0')<<4)&0x00f0 );
- else {
- *b = *b | ( (*a-'0')&0x000f );
- b++;
- }
- a++;
- }
- }
-
- /************************************************************/
- /* p_initialise - initialise our data array */
- /************************************************************/
- p_initialise(s)
- int s;
- {
- int j;
- for (j=0;j<4;j++) p[s].iosb[j] = 0;
- p[s].channel = 0;
- p[s].fd_buff_size = -1;
- p[s].accept_pending = 0;
- p[s].connect_pending = 0;
- p[s].connected = 0;
- p[s].fd_buff = NULL;
- p[s].fd_leftover = NULL;
- p[s].fptr = NULL;
- p[s].s = s;
- p[s].name.in.sin_port = 0;
- p[s].masklen = 4;
- for (j=0;j<16;j++) p[s].mask[j] = 0xff;
- p[s].need_header = 0;
- p[s].status = INITIALISED;
- p[s].read_outstanding = 0;
- p[s].cmu_open = 0;
- p[s].x25_listener = 0;
- p[s].mother = s;
- p[s].child = 0;
- p[s].no_more_accepts = 0;
- p[s].closed_by_remote = 0;
- p[s].non_blocking = 0;
- p[s].sig_req = 0;
- sys$clref(s);
- }
-
- /************************************************************/
- /* decode_ncb - decode a network control block */
- /************************************************************/
- decode_ncb(ncb,addr)
- char *ncb;
- union socket_addr *addr;
- {
- int maxm,j;
- maxm = *ncb;
- ncb++;
- j = 0;
- addr->x25.hostlen = 0;
- addr->x25.datalen = 0;
- while (j<maxm) {
- if (*(ncb+2) == psi$c_ncb_incoming_dte) {
- addr->x25.hostlen = *(ncb+4);
- ascic_to_bcd(ncb+4,addr->x25.host);
- }
- if (*(ncb+2) == psi$c_ncb_userdata) {
- addr->x25.datalen = *(ncb+4);
- bcopy(ncb+5,addr->x25.data,addr->x25.datalen);
- }
- j += *ncb;
- ncb += *ncb;
- }
- }
-
- /************************************************************/
- /* setup_npb - configure our network parameter block */
- /************************************************************/
- setup_npb(s,npb_blk)
- int s;
- char *npb_blk;
- {
- int i, subaddress;
- myx25_subaddress(&subaddress);
- for (i=0;i<64;i++) npb_blk[i] = 0;
- i = 0;
- npb_blk[0] = 10;
- npb_blk[2] = psi$c_ntd_acclvl;
- strcpy(npb_blk+4,"\5X25L3");
- i += npb_blk[i];
- if (p[s].name.x25.datalen != 0) {
- npb_blk[i] = p[s].name.x25.datalen + 5;
- npb_blk[i+2] = psi$c_ntd_usrdata;
- bcopy(&(p[s].name.x25.datalen),npb_blk+i+4,p[s].name.x25.datalen+1);
- i += npb_blk[i];
- npb_blk[i] = p[s].masklen + 5;
- npb_blk[i+2] = psi$c_ntd_datmsk;
- bcopy(&(p[s].masklen),npb_blk+i+4,p[s].masklen+1);
- i += npb_blk[i];
- }
- if (subaddress != -1) {
- npb_blk[i] = 6;
- npb_blk[i+2] = psi$c_ntd_salo;
- npb_blk[i+4] = subaddress;
- i += npb_blk[i];
- npb_blk[i] = 6;
- npb_blk[i+2] = psi$c_ntd_sahi;
- npb_blk[i+4] = subaddress;
- i += npb_blk[i];
- }
- return(i);
- }
-
- /************************************************************/
- /* setup_ncb - configure our network control block */
- /************************************************************/
- setup_ncb(s,name)
- int s;
- union socket_addr *name;
- {
- char *t, *z, *getenv();
- int i;
- i = 0;
- t = getenv("X25_ADDRESS");
- z = getenv("X25_SUBADDRESS");
- p[s].ncb[0] = name->x25.hostlen+5;
- p[s].ncb[1] = 0;
- p[s].ncb[2] = psi$c_ncb_remdte;
- p[s].ncb[3] = 0;
- bcd_to_ascic(&(name->x25.host),p[s].ncb+4,name->x25.hostlen);
- /* i += p[s].ncb[i];
- p[s].ncb[i] = strlen(t)+strlen(z)+5;
- p[s].ncb[i+1] = 0;
- p[s].ncb[i+2] = psi$c_ncb_locsubadr;
- p[s].ncb[i+3] = 0;
- p[s].ncb[i+4] = strlen(t)+strlen(z);
- bcopy(t,p[s].ncb+i+5,strlen(t));
- bcopy(z,p[s].ncb+i+5+strlen(t),strlen(z));*/
- i += p[s].ncb[i];
- if (name->x25.datalen != 0) {
- p[s].ncb[i] = name->x25.datalen+5;
- p[s].ncb[i+1] = 0;
- p[s].ncb[i+2] = psi$c_ncb_userdata;
- p[s].ncb[i+3] = 0;
- bcopy(&(name->x25.datalen),p[s].ncb+i+4,name->x25.datalen+1);
- i += p[s].ncb[i];
- }
- return(i);
- }
-
- /************************************************************/
- /* type_ahead - returns number of chars to be read */
- /************************************************************/
- type_ahead()
- {
- int st;
- short int buf[4];
- short int iosb[4];
- struct descriptor termdesc;
-
- if (terminal.chan == -1) {
- termdesc.size = 10;
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
- st = sys$qiow(0,terminal.chan,IO$_SENSEMODE | IO$M_TYPEAHDCNT,iosb,0,0,
- buf,8,0,0,0,0);
- /* remember we may have already pre-read one of the chars!*/
- if (st != SS$_NORMAL || iosb[0] != SS$_NORMAL) return(0);
- return(buf[0]+terminal.char_available);
- }
-
- /************************************************************/
- /* stty - obsolete form of ioctl */
- /************************************************************/
- stty(fd,buf)
- int fd;
- struct sgttyb *buf;
- {
- ioctl(fd, TIOCSETP, buf);
- }
-
- /************************************************************/
- /* gtty - obsolete form of ioctl */
- /************************************************************/
- gtty(fd,buf)
- int fd;
- struct sgttyb *buf;
- {
- ioctl(fd, TIOCGETP, buf);
- }
-
- /************************************************************/
- /* set_noecho - just a utility routine to cancel term echo */
- /************************************************************/
- set_noecho()
- {
- int st;
- int buf[3];
- short int iosb[4];
- struct descriptor termdesc;
-
- if (terminal.chan == -1) {
- termdesc.size = 10;
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
- st = sys$qiow(0,terminal.chan,IO$_SENSEMODE,iosb,0,0,buf,12,0,0,0,0);
- buf[1] |= TT$M_NOECHO;
- st = sys$qiow(0,terminal.chan,IO$_SETMODE,iosb,0,0,buf,12,0,0,0,0);
- }
-
- /************************************************************/
- /* set_echo - just a utility routine to start term echo */
- /************************************************************/
- set_echo()
- {
- int st;
- int buf[3];
- short int iosb[4];
- struct descriptor termdesc;
-
- if (terminal.chan == -1) {
- termdesc.size = 10;
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
- st = sys$qiow(0,terminal.chan,IO$_SENSEMODE,iosb,0,0,buf,12,0,0,0,0);
- buf[1] &= ~TT$M_NOECHO;
- st = sys$qiow(0,terminal.chan,IO$_SETMODE,iosb,0,0,buf,12,0,0,0,0);
- }
-
- /************************************************************/
- /* get1c - get 1 char from term without echoing it */
- /************************************************************/
- int get1c()
- {
- int i;
- char q[4];
- short int iosb[4];
- struct descriptor termdesc;
-
- if (terminal.chan == -1) {
- termdesc.size = 10;
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
-
- if (terminal.char_available == 1) {
- /* CRW add */
- terminal.char_available = 0;
- /* CRW end */
- i = terminal.c[0];
- if (i == 13) i = 10;
- return(i);
- }
-
- sys$qiow(0,terminal.chan,IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR,
- terminal.iosb,0,0,q,1,0,0,0,0);
- i = q[0];
- if (i == 13) i = 10;
- return(i);
- }
-
- /************************************************************/
- /* getnc - get n chars from term without echoing them */
- /************************************************************/
- getnc(s,i)
- char *s;
- int i;
- {
- int j, k;
- char *q;
- short int iosb[4];
- struct descriptor termdesc;
-
- j = 0;
- q = s;
- if (terminal.chan == -1) {
- termdesc.size = 10;
- termdesc.ptr = "SYS$INPUT:";
- sys$assign(&termdesc,&terminal.chan,0,0);
- }
- if (i == 0) {
- sys$cancel(terminal.chan);
- sys$dassgn(terminal.chan);
- terminal.chan = -1;
- return(0);
- }
- if (terminal.char_available == 1) {
- *q = terminal.c[0];
- /* CRW add */
- terminal.char_available = 0;
- /* CRW end */
- if (*q == 13) *q = 10;
- q++;
- i--;
- j++;
- }
- if (i == 0) return(j);
- sys$qiow(0,terminal.chan,IO$_READVBLK | IO$M_NOECHO | IO$M_NOFILTR,
- terminal.iosb,0,0,q,i,0,0,0,0);
- for (q=s,k=0; k<i+j; k++,q++) if (*q == 13) *q = 10;
- return(i+j);
- }
-
- /************************************************************/
- /* read_efn - see whether an event flag is set */
- /************************************************************/
- read_efn(i)
- int i;
- {
- int j;
- sys$readef(i,&j);
- j = j&(1<<i);
- return(j);
- }
-
- /************************************************************/
- /* dmphx - dump a buffer to the debug log in hex and ascii */
- /************************************************************/
- dmphx(f,msg,len)
- FILE *f;
- unsigned char *msg;
- int len;
- {
- int i, j;
- unsigned char *v, *w;
-
- v = w = msg;
- j = len;
- while (j>0) {
- if (j>16) i = 16; else i=j;
- for(;i>0;i--,v++) fprintf(f," %02x",*v);
- if (j<16) for(i=16-j;i>0;i--) fprintf(f," ");
- fprintf(f," ");
- if (j>16) i = 16; else i=j;
- for(;i>0;i--,w++) fprintf(f,"%c",(*w>0x1f && *w<0x80)? *w : '.');
- fprintf(f,"\n");
- j -= 16;
- }
- }
-
- static set_tcp_make()
- {
- struct descriptor inetdesc;
- int channel;
- /* first try CMU */
- inetdesc.size = 3;
- inetdesc.ptr = "IP:";
- if (sys$assign(&inetdesc,&channel,0,0) == SS$_NORMAL) {
- sys$dassgn(channel);
- tcp_make = CMU;
- return;
- }
- /* next try WG */
- inetdesc.size = 7;
- inetdesc.ptr = "_INET0:";
- if (sys$assign(&inetdesc,&channel,0,0) == SS$_NORMAL) {
- sys$dassgn(channel);
- tcp_make = WG;
- return;
- }
- /* next try UCX */
- inetdesc.size = 4;
- inetdesc.ptr = "BG0:";
- if (sys$assign(&inetdesc,&channel,0,0) == SS$_NORMAL) {
- sys$dassgn(channel);
- tcp_make = UCX;
- return;
- }
-
- /* nothing there oh dear!*/
- tcp_make = NONE;
- return;
- }
-
- stricmp(s1,s2)
- char *s1;
- char *s2;
- {
- int diff = 'a' - 'A';
-
- while ((*s1 != '\0') && (*s2 != '\0')) {
- if (((islower(*s1)) ? (*s1 - diff) : (*s1)) !=
- ((islower(*s2)) ? (*s2 - diff) : (*s2)))
- return(((islower(*s1)) ? (*s1 - diff) : (*s1)) -
- ((islower(*s2)) ? (*s2 - diff) : (*s2)));
- s1++, s2++;
- }
-
- return(0);
- }
-
- static char *getdevicename(channel)
- unsigned short int channel;
- {
- int st;
- struct {
- struct itemlist id;
- int eol;
- } itmlst;
- static char name[64];
- short int lgth;
-
- name[0] = '\0';
- itmlst.id.code = DVI$_DEVNAM;
- itmlst.id.length = 64;
- itmlst.id.dataptr = name;
- itmlst.id.retlenptr = &lgth;
- itmlst.eol = 0;
- if ((st=sys$getdvi(0,channel,0,&itmlst,0,0,0,0)) != SS$_NORMAL) {
- fprintf(stderr, "error getting device name %d\n",st);
- }
- return(name);
- }
-
- #define inpipe 18
- #define outpipe 19
- get_socket_info()
- {
- int i, st, domain, type;
- char buffer[64];
- struct descriptor inetdesc;
- char *getenv();
-
- if ( ! tcp_make) set_tcp_make();
- if (tcp_make != WG) return(-1);
- if (p_initialised == 0) {
- for (i=0;i<32;i++) p_initialise(i);
- if ((getenv("PACKET_TRACE") != NULL) &&
- (strcmp(getenv("PACKET_TRACE"),"TRUE") == 0)) {
- trace__ = 1;
- ftrace__ = fopen("packet_trace.log","w");
- }
- p_initialised = 1;
- }
-
- i = 0;
- read(inpipe, &i, sizeof(int));
- while (i != 0) {
- read(inpipe, &domain, sizeof(int));
- read(inpipe, &type, sizeof(int));
- read(inpipe, buffer, 64);
- inetdesc.size = strlen(buffer);
- inetdesc.ptr = buffer;
- if ((st=sys$assign(&inetdesc,&p[i].channel,0,0)) != SS$_NORMAL){
- fprintf(stderr,"assign new channel %s - %d\n",buffer,st);
- return(-1);
- }
- p[i].status = PASSIVE_CONNECTION;
- p[i].domain = domain;
- p[i].type = type;
- p[i].passive = 1;
- p[i].fptr = fdopen(i,"r");
- p[i].fd_buff = (unsigned char *)malloc(BUF_SIZE);
- hang_a_read(i);
- read(inpipe, &i, sizeof(int));
- }
- return(0);
- }
-
- send_socket_info()
- {
- int pipes[2], i, st, dummy;
-
- if (tcp_make == WG) {
- /*we need to search through our fd_entry structure to find which entries
- to hand on to the child*/
- pipe(pipes);
- dup2(pipes[0], inpipe);
- dup2(pipes[1], outpipe);
- close(pipes[0]);close(pipes[1]);
- for (i=0;i<32;i++) {
- if (p[i].status == PASSIVE_CONNECTION) {
- p[i].status = HANDED_OFF;
- write(outpipe, (char *)&i, sizeof(int));
- write(outpipe, (char *)&(p[i].domain), sizeof(int));
- write(outpipe, (char *)&(p[i].type), sizeof(int));
- write(outpipe, getdevicename(p[i].channel), 64);
- dummy = SETCHAR_HANDOFF;
- st = sys$qiow(0,p[i].channel,IO$_SETCHAR,p[i].iosb,0,0,&dummy,0,0,0,0,0);
- sys$dassgn(p[i].channel);
- }
- }
- i = 0;
- write(outpipe, (char *)&i, sizeof(int));
- }
- }
-