1 /* $NCDId: @(#)Astreams.c,v 1.2 1994/04/20 22:34:53 greg Exp $ */
2 /*
3  * $XConsortium: Xstreams.c,v 1.26 91/07/23 12:15:13 rws Exp $
4  */
5 
6 #ifdef STREAMSCONN
7 
8 /*
9  * Copyright 1991 USL, Inc.
10  * Copyright 1991 Massachusetts Institute of Technology
11  * Copyright 1988, 1989 AT&T, Inc.
12  *
13  * Permission to use, copy, modify, and distribute this software and
14  * its documentation for any purpose and without fee is hereby
15  * granted, provided that the above copyright notice appear in all
16  * copies and that both that copyright notice and this permission
17  * notice appear in supporting documentation, and that the name of
18  * AT&T, USL, or MIT not be used in advertising or publicity
19  * pertaining to distribution of the software without specific,
20  * written prior permission.  AT&T, USL, and MIT make no
21  * representations about the suitability of this software for any
22  * purpose.  It is provided "as is" without express or implied
23  * warranty.
24  *
25  * AT&T, USL, AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
27  * NO EVENT SHALL AT&T, USL, OR MIT BE LIABLE FOR ANY SPECIAL,
28  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
29  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
30  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
31  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
32  */
33 
34 #define _USHORT_H	/* prevent conflicts between BSD sys/types.h and
35                            interlan/il_types.h */
36 
37 #define NEED_REPLIES
38 #include <audio/Alibint.h>
39 #include <audio/Aos.h>
40 #include "Alibnet.h"
41 #include <X11/Xauth.h>
42 
43 
44 #include <stdio.h>
45 #include <tiuser.h>		/* TLI user defs */
46 #include <sys/param.h>
47 #include <sys/utsname.h>
48 #include <signal.h>
49 
50 #include <sys/stat.h>
51 #include <errno.h>
52 #include <sys/stropts.h>
53 
54 /* stolen from <X11/Xproto.h> */
55 typedef struct {
56     CARD8 family;
57     BYTE pad;
58     CARD16 length B16;
59 } xHostEntry;
60 
61 #define sz_xReply 32
62 /* --- */
63 
64 
65 
66 #ifdef SVR4
67 #include <netdir.h>
68 #include <netconfig.h>
69 #ifndef __STDC__
70 /* buggy SVR4 include file */
71 char *setnetpath();
72 struct netconfig *getnetconfigent();
73 struct netconfig *getnetpath();
74 int endnetpath();
75 #endif
76 #endif
77 
78 
79 #include "Astreams.h"
80 
81 
82 #ifdef DEBUG
83 #define PRMSG(x,a,b)	fprintf(stderr, x,a,b); fflush(stderr)
84 #else
85 #define PRMSG(x,a,b)
86 #endif
87 
88 
89 #define	LISTEN_QUE_SIZE	8	/* maximum # of connections for gen. listen */
90 #define	CLEAR		1
91 /*
92  * Ridiculously high value for maximum number of connects per stream.
93  * Transport Provider will determine actual maximum to be used.
94  */
95 
96 #define	MAXCONNECTIONS	100	/* maximum # of connections for gen. listen */
97 
98 
99 #define MAXLEN	80
100 #define BUFFERSIZE 2048
101 #define NOBUFFERNEEDED 512
102 
103 /* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
104  * systems are broken and return EWOULDBLOCK when they should return EAGAIN
105  */
106 #if defined(EAGAIN) && defined(EWOULDBLOCK)
107 #define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
108 #else
109 #ifdef EAGAIN
110 #define ETEST(err) (err == EAGAIN)
111 #else
112 #define ETEST(err) (err == EWOULDBLOCK)
113 #endif
114 #endif
115 
116 typedef struct {
117 	char *DataBuffer;
118 	int   FirstBytePtr;
119 	int   LastBytePtr;
120 	} InputBuffer;
121 
122 #ifdef SVR4
123 InputBuffer _AusInputBuffer[MAXCONNECTIONS] = {NULL};
124 #else
125 #ifndef NOFILES_MAX
126 #define NOFILES_MAX	128
127 #endif
128 InputBuffer _AusInputBuffer[NOFILES_MAX] = {NULL};
129 #endif /* SVR4*/
130 
131 
132 static char	*ptmx = "/dev/ptmx";
133 static char	*dispno = "0";
134 
135 #ifdef  att
136 extern char *GetAuWINHome ();
137 #endif
138 
139 static  char _dispno[MAX_DISP_DIGITS];
140 
141 extern int t_errno;
142 
143 static char	** addheader();
144 static char	** addtliheader();
145 
146 static	struct	t_bind bind_ret, bind_req;
147 static	struct	t_call call;
148 static  char	ret_buf[MAXLEN], req_buf[MAXLEN], call_buf[MAXLEN];
149 
150 
151 static int named = 0;	/* not using named streams connection */
152 
153 #ifdef USL_SHARELIB
154 #define fopen (*_libX_fopen)
155 extern FILE *fopen();
156 #define t_bind (*_libX_t_bind)
157 extern int t_bind();
158 #undef t_bind
159 #define _iob (*_libX__iob)
160 extern FILE _iob[];
161 #endif /* USL_SHARELIB */
162 
163 extern int t_errno;
164 
165 #define SIGNAL_T void
166 typedef SIGNAL_T (*PFV)();
167 #ifndef SVR4
168 extern PFV signal();
169 #endif
170 
171 #define SUCCESS		"1"
172 
173 extern char _AusTypeOfStream[];
174 extern Austream _AusStream[];
175 
176 static networkInfo Network;
177 static int NameServer = -1;
178 static int CallTheNameServer();
179 static void checkNewEvent();
180 static int OpenVirtualCircuit();
181 static void LookForEvents();
182 static int CheckListenQue();
183 static void ClearCall(), RemoveCall();
184 static int OpenLocalServer();
185 static int OpenNamedServer();
186 static int nameserver();
187 
188 /* Routines everybody shares */
189 
190 
191 
_AusErrorCall()192 _AusErrorCall()
193 {
194 	fprintf(stderr, "ErrorCall: invalid or unsupported subroutine call\n");
195 	return(-1);
196 }
197 
198 /*
199  * Following are some general queueing routines.  The call list head contains
200  * a pointer to the head of the queue and to the tail of the queue.  Normally,
201  * calls are added to the tail and removed from the head to ensure they are
202  * processed in the order received, however, because of the possible interruption
203  * of an acceptance with the resulting requeueing, it is necessary to have a
204  * way to do a "priority queueing" which inserts at the head of the queue for
205  * immediate processing
206  */
207 
208 /*
209  * Que:
210  *
211  * add calls to tail of queue
212  */
213 
214 
215 static	void
Que(struct listenQue * head,struct listenCall * lc,char flag)216 Que(struct listenQue *head, struct listenCall *lc, char flag)
217 {
218 	if(flag == CLEAR)
219 		ClearCall(lc->CurrentCall);
220 
221 	if (head->QueTail == (struct listenCall *) NULL) {
222 		lc->NextCall = (struct listenCall *) NULL;
223 		head->QueHead = head->QueTail = lc;
224 	}
225 	else {
226 		lc->NextCall = head->QueTail->NextCall;
227 		head->QueTail->NextCall = lc;
228 		head->QueTail = lc;
229 	}
230 }
231 
232 
233 /*
234  * pQue:
235  *
236  * priority queuer, add calls to head of queue
237  */
238 
239 static void
pQue(struct listenQue * head,struct listenCall * lc)240 pQue(struct listenQue *head, struct listenCall *lc)
241 {
242 	if (head->QueHead == (struct listenCall *) NULL) {
243 		lc->NextCall = (struct listenCall *) NULL;
244 		head->QueHead = head->QueTail = lc;
245 	}
246 	else {
247 		lc->NextCall = head->QueHead;
248 		head->QueHead = lc;
249 	}
250 }
251 
252 
253 /*
254  * dequeue:
255  *
256  * remove a call from the head of queue
257  */
258 
259 
260 static struct listenCall *
deQue(struct listenQue * head)261 deQue(struct listenQue *head)
262 {
263 	struct listenCall *ret;
264 
265 	if (head->QueHead == (struct listenCall *) NULL){
266 		PRMSG("Fatal error. Queue is empty (shouldn't happen)\n",0,0);
267 		exit(1);
268 		}
269 	ret = head->QueHead;
270 	head->QueHead = ret->NextCall;
271 	if (head->QueHead == (struct listenCall *) NULL)
272 		head->QueTail = (struct listenCall *) NULL;
273 	return(ret);
274 }
275 
276 /* Routines for handling local Named streams  */
277 
278 #ifdef SVR4
_AusSetupNamedStream(char * display,char * stype)279 _AusSetupNamedStream(char *display, char *stype)
280 {
281 	int 	munix, sunix;
282 	char *	slave;
283 	char	buf[MAX_AUTO_BUF_LEN];
284 	int	type = Au_NAMED_STREAM;
285 	int 	fld[2], ret;
286 	struct stat sbuf;
287 
288 	PRMSG("Calling SetupNamedStream()\n",0,0);
289 
290 /* if file not there create it, depends on SetupLocalStream to decide whether
291    server already running  , no checking is done here */
292 
293 	munix = atoi(display);
294 	sprintf(buf, "%s.%d", NAMED_LISTENER, munix);
295 	PRMSG("Calling SetupNamedStream()-(%s)\n",buf,0);
296 
297 	if(stat(buf,  &sbuf)!= 0)	{
298 	   if(errno ==ENOENT)	{
299 		if(( munix = creat(buf, (mode_t) 0666) ) == -1)	{
300 		    PRMSG(" Can't create: %s\n", buf,0);
301 		    return(-1);
302 		}
303 		close(munix);
304 		if(chmod(buf,(mode_t) 0666)<0)	{
305 		    PRMSG( "Cannot chmod %s", buf,0);
306 		    perror(" ");
307 		    return(-1);
308 		}
309 	   }
310 	   else	{
311 		PRMSG("stat err=%d,-%s\n", errno, strerror(errno));
312 		return(-1);
313 	   }
314 	}
315 
316 	if(pipe(fld) != 0)
317 	  {
318 	    fprintf(stderr,"pipe failed, errno=%d:%s\n", errno,
319 		    strerror(errno));
320 	    return(-1);
321 	  }
322 
323 	if((ret=ioctl(fld[0], I_PUSH,"connld")) != 0)	{
324 	    fprintf(stderr,"ioctl error:%s\n", strerror(errno));
325 	    return(-1);
326 	}
327 
328 	if((fattach(fld[0], buf)) !=0)	{
329 	    fprintf(stderr,"fattach failed:%s\n", strerror(errno));
330 	    return(-1);
331 	}
332 
333 	_AusTypeOfStream[fld[1]] = type;
334 	NetworkInfo->_nnets++;
335 
336 	return(fld[1]);
337 }
338 
339 /* Enhanced Application Compatibility Support */
340 
341 int
_AusSetupSpStream(char * display,char * stype)342 _AusSetupSpStream (char *display, char *stype)
343 {
344   return 0;
345 }
346 
347 int
_AusConnectSpClient(int connmaster)348 _AusConnectSpClient (int connmaster)		/* Add connection to new slave */
349 {
350   return 0;
351 }
352 /* End Enhanced Application Compatibility Support */
353 
354 #endif /* SVR4 */
355 
356 
357 
358 
359 /* Routines for handling local streams (streams-pipes) */
360 int
_AusSetupLocalStream(char * display,char * stype)361 _AusSetupLocalStream(char *display, char *stype)
362 {
363 	int 	munix, sunix;
364 	char *	slave;
365 	char	buf[MAX_AUTO_BUF_LEN];
366 	int	type = Au_LOCAL_STREAM;
367 	int 	nameserver();
368 
369 	PRMSG("Calling SetupLocalStream()\n",0,0);
370 
371 	SetupNetworkInfo();
372 	dispno = display;
373 
374 	NetworkInfo->_nnets = NetworkInfo->_npeers = 0;
375 	NetworkInfo->_peer = NULL;
376 	NetworkInfo->_peerlen = NULL;
377 
378 #ifdef SVR4
379 	NetworkInfo->_net[0] = (struct netconfig *) 0;
380 #else
381 	NetworkInfo->_net[0] = (char *) 0;
382 #endif
383 	NetworkInfo->_nnets++;
384 
385 
386 	munix = atoi(display);
387 /*
388 	if(munix != 0){
389 		fprintf(stderr, "Only display # 0 can be used on this server\n");
390 		return(-1);
391 		}
392 */
393 
394 	sprintf(buf, "%s.%d", LOCAL_LISTENER, munix);
395 /*
396 	if(open(buf, O_RDWR) >= 0){
397 		fprintf(stderr, "Server is already running\n");
398 		return(-1);
399 		}
400 */
401 	if( (munix = open(ptmx, O_RDWR)) < 0 ){
402 		fprintf(stderr,"Cannot open %s", ptmx);
403 		perror(" ");
404 		return(-1);
405 	}
406 	grantpt(munix);
407 	unlockpt(munix);
408 
409 	if(unlink(buf) < 0 && errno != ENOENT){
410 		fprintf(stderr, "Cannot unlink %s", buf);
411 		perror(" ");
412 		return(-1);
413 		}
414 
415         if(! (slave = (char *) ptsname(munix))) {
416 		close(munix);
417 		perror("Cannot get slave pt-name");
418 		return(-1);
419 		}
420 
421 	if( link(slave, buf) <0 ){
422 		fprintf(stderr, "Cannot link %s to %s", slave, buf);
423 		perror(" ");
424 		return(-1);
425 		}
426 	if( chmod(buf, 0666) < 0){
427 		close(munix);
428 		fprintf(stderr, "Cannot chmod %s", buf);
429 		perror(" ");
430 		return(-1);
431 		}
432 
433 	sunix = open(buf, O_RDWR);
434 	if(sunix < 0){
435 		fprintf(stderr, "Cannot open %s", buf);
436 		perror(" ");
437 		close(munix);
438 		return(-1);
439 		}
440 
441 	_AusTypeOfStream[munix] = type;
442 	_AusTypeOfStream[sunix] = CLOSED_STREAM;
443 
444 	return(munix);
445 }
446 
447 int
_AusConnectLocalClient(int ufd,char * MoreConnections)448 _AusConnectLocalClient(int ufd, char *MoreConnections)
449 {
450 
451 	int fd;
452 	int read_in;
453 	unsigned char length;
454 	char buf[MAX_AUTO_BUF_LEN];
455 #ifdef SVR4
456 	struct strrecvfd str;
457 #endif
458 
459 
460 	PRMSG("Calling ConnectLocalClient(%d)\n", ufd,0);
461 
462 /* MoreConnections is set to zero because if any more connections are underway
463  * select() will return immediately. It is nicer if we can process all connections
464  * that exist the way we handle TLI connections by setting MoreConnections.
465  * May be I will end up doing it later.
466  */
467 	*MoreConnections = 0;
468 
469 #ifdef SVR4
470 
471     if( _AusTypeOfStream[ufd] == Au_NAMED_STREAM)		{
472 	PRMSG("Calling ConnectLocalClient(%d) - thru named streams\n", ufd,0);
473 	if (ioctl(ufd, I_RECVFD, &str) < 0)	{
474             fprintf(stderr,"I_RECVFD failed\n");
475             return(-1);
476 	}
477 
478 	_AusTypeOfStream[str.fd] = _AusTypeOfStream[ufd];
479 	PRMSG("ConnectNamedClient(%d) return success\n", str.fd,0);
480 	return(str.fd);
481     }
482 
483 /* Enhanced Application Compatibility Support */
484 
485 /* End Enhanced Application Compatibility Support */
486 
487 #endif /* SVR4 */
488 
489 	PRMSG("Calling ConnectLocalClient(%d) - thru psuedo tty\n", ufd,0);
490 
491 	if( (read_in = read(ufd, &length, 1)) <= 0 ){
492 		if( !read_in )  /* client closed fd */
493 			perror("0 bytes read");
494 		else	perror("Error in reading the local connection msg length");
495 		return(-1);
496 		}
497 
498 
499 	if( (read_in = read(ufd, buf, length)) <= 0 ){
500 		if( !read_in )  /* client closed fd */
501 			perror("0 bytes read");
502 		else	perror("Error in reading the local connection slave name");
503 		return(-1);
504 		}
505 
506 	buf[ length ] = '\0';
507 
508 	if( (fd = open(buf,O_RDWR)) < 0 ){
509 		strcat(buf," open fail, clientfd");
510 		perror(buf);
511 		return(-1);
512 		}
513 
514 	write(fd,SUCCESS,1);
515 
516 	_AusTypeOfStream[fd] = _AusTypeOfStream[ufd];
517 	PRMSG("ConnectLocalClient(%d) return success\n", ufd,0);
518 	return(fd);
519 }
520 
dummy(int sig)521 static void dummy (int sig)
522 {
523   return;
524 }
525 
526 int
527 _AusCallLocalServer(char *host, int idisplay,
528 #ifdef SVR4
529                     struct netconfig *nettype,
530 #else
531                     char *nettype,
532 #endif
533                     )
534 {
535 	char	buf[MAX_AUTO_BUF_LEN];
536 	char    *listener;
537 	int	type = Au_LOCAL_STREAM;
538 	int	fd;
539 
540 
541 	PRMSG("Calling CallLocalServer(%s)\n", host,0);
542 
543         sprintf(_dispno, "%d", idisplay);
544 	dispno = _dispno;
545 
546 	/*
547 	 * Open channel to server
548 	 */
549 
550 
551 #ifdef SVR4
552 	if (strncmp("NAMED", (char *) getenv("XLOCAL"),	 5) == 0)	{
553                     named = 1;
554                     type = Au_NAMED_STREAM;
555                     listener = NAMED_LISTENER;
556                     sprintf(buf, "%s.%d", listener, idisplay);
557                     if((fd = OpenNamedServer(buf)) < 0)
558                     {
559 			PRMSG("Cannot open %s\n", buf,0);
560 	#ifdef DEBUG
561 			perror("AuIO");	/* Sorry, but I don't have the dpy handy */
562 	#endif
563 			return(-1);
564                     }
565 	}
566 
567 /* Enhanced Application Compatibility Support */
568 
569 /* End Enhanced Application Compatibility Support */
570 #endif
571 
572 
573 	if(!named)	{
574             type = Au_LOCAL_STREAM;
575             listener = LOCAL_LISTENER;
576             sprintf(buf, "%s.%d", listener, idisplay);
577 	PRMSG("buf for local listener %s\n",buf,0);
578             if((fd = OpenLocalServer(buf)) < 0)
579             {
580 		PRMSG("Cannot open %s\n", buf,0);
581 #ifdef DEBUG
582 		perror("AuIO");	/* Sorry, but I don't have the dpy handy */
583 #endif
584 		return(-1);
585             }
586 	}
587 
588 
589 	_AusTypeOfStream[fd] = type;
590         if (_AusInputBuffer[fd].DataBuffer == NULL)
591 		if ((_AusInputBuffer[fd].DataBuffer = (char *) malloc(BUFFERSIZE)) == NULL)
592         	{
593 	               errno = ENOMEM;
594                        perror("Client can't connect to local server");
595                        return (-1);
596         	}
597 	_AusInputBuffer[fd].LastBytePtr = 0;
598 	_AusInputBuffer[fd].FirstBytePtr = 0;
599 
600 	PRMSG("Calling CallLocalServer(%s) return success\n", host,fd);
601 
602 	return(fd);
603 }
604 
605 
606 
607 
608 #ifdef SVR4
609 static int
610 OpenNamedServer(char *node)
611 char *node;
612 {
613 	int fld;
614 
615 	PRMSG("Calling 4.0 -- opening (%s)\n", node,0);
616 
617 	fld = open(node, O_RDWR);
618 	if(fld <0)	{
619 	    fprintf(stderr,"OpenNamedServer failed:%s\n", strerror(errno));
620 	    return(-1);
621 	}
622 
623 	if(isastream(fld) != 1)	{
624 	    fprintf(stderr,"OpenNamedServer failed: %s is not a NamedStream\n",
625 			node);
626 	    return(-1);
627 	}
628 
629 	return (fld);
630 }
631 
632 /* Enhanced Application Compatibility Support */
633 
634 static int
_AusOpenSpServer(char * node)635 _AusOpenSpServer(char *node)
636 {
637   return 0;
638 }
639 /* End Enhanced Application Compatibility Support */
640 
641 #endif /* SVR4 */
642 
643 static int
OpenLocalServer(char * node)644 OpenLocalServer(char *node)
645 {
646 	int 	server, fd, c;
647 	char	buf[MAX_AUTO_BUF_LEN], *slave;
648 	PFV	savef;
649 
650 	if ((server = open (node, O_RDWR)) < 0)
651 	{
652 #ifdef DEBUG
653 		fprintf(stderr, "open(%s) failed\n", node);
654 		perror(" ");
655 #endif
656 		return(-1);
657 	}
658 
659 	/*
660 	 * Open streams based pipe and get slave name
661 	 */
662 
663 
664 	if ((fd = open (ptmx, O_RDWR)) < 0) {
665 		close (server);
666 		PRMSG("Cannot open %s\n", ptmx, 0);
667 		return(-1);
668 	}
669 
670 	grantpt (fd);
671 
672 	unlockpt (fd);
673 
674         if (! (slave = (char *) ptsname(fd))) {
675 		close(fd);
676 		close(server);
677 		PRMSG("Cannot get slave pt-name", 0, 0);
678 		return(-1);
679 	}
680 
681 
682 	if (chmod(slave, 0666) < 0)
683 	{
684 		close(fd);
685 		close(server);
686 		PRMSG("Cannot chmod %s\n", buf,0);
687 		return(-1);
688 	}
689 
690 	c = strlen (slave);
691 
692 	buf[0] = c;
693 	sprintf(&buf[1], slave);
694 
695 	/*
696 	 * write slave name to server
697 	 */
698 
699 	write(server, buf, c+1);
700 	close (server);
701 	/*
702 	 * wait for server to respond
703 	 */
704 	savef = signal (SIGALRM, dummy);
705 	alarm (CONNECT_TIMEOUT);
706 
707 	if (read (fd, &c, 1) != 1)
708 	{
709 		fprintf(stderr, "No reply from the server.\n");
710 		close(fd);
711 		fd = -1;
712 	}
713 	alarm (0);
714 	signal (SIGALRM, savef);
715 
716 	return(fd);
717 }
718 
719 #ifdef DEBUG
dumpBytes(int len,char * data)720 static void dumpBytes (int len, char *data)
721 {
722   int i;
723 
724   fprintf(stderr, "%d: ", len);
725   for (i = 0; i < len; i++)
726     fprintf(stderr, "%02x ", data[i] & 0377);
727   fprintf(stderr, "\n");
728 
729   return;
730 }
731 #endif
732 
733 #define AuSTREAMS_COMPILE /* magic symbol to avoid lint problems */
734 #ifdef SVR4
735 #include "nameaddr.c"
736 #else
737 #include "nameserver.c"
738 #endif
739 #undef AuSTREAMS_COMPILE
740 
741 int
_AusReadLocalStream(int fd,char * buf,int count,int do_buffering)742 _AusReadLocalStream(int fd, char *buf, int count, int do_buffering)
743 {
744 	int	amount;
745 	InputBuffer *ioptr = &_AusInputBuffer[fd];
746 
747 	if (do_buffering == NO_BUFFERING){
748 		amount = read(fd, buf, count);
749 
750   		return (amount);
751 	}
752 
753         if (ioptr->LastBytePtr <= ioptr->FirstBytePtr)
754 	{
755            errno = 0;
756            if(count > BUFFERSIZE)
757            {
758             	ioptr->LastBytePtr = ioptr->FirstBytePtr = 0;
759 		amount = read(fd, buf, count);
760 
761                 return(amount);
762            }
763 
764 	   /* JET - 5/8/99 - hmmm, this buffer may not be allocated yet,
765 	      if it's not there, allocate it */
766 	   if (ioptr->DataBuffer == NULL)
767 	     if ((ioptr->DataBuffer = (char *) malloc(BUFFERSIZE)) == NULL)
768 	       {
769 		 errno = ENOMEM;
770 		 perror("Client can't connect to remote server");
771 		 return (-1);
772 	       }
773 
774            ioptr->LastBytePtr = read(fd, ioptr->DataBuffer, BUFFERSIZE);
775 
776 	   ioptr->FirstBytePtr = 0;
777 	}
778 
779 	if (ioptr->LastBytePtr > 0)
780 	{
781            amount = ioptr->LastBytePtr - ioptr->FirstBytePtr;
782            amount = amount > count ? count : amount;
783            memcpy(buf, &ioptr->DataBuffer[ioptr->FirstBytePtr], amount);
784            ioptr->FirstBytePtr += amount;
785            return amount;
786 	}
787 	else	{
788 	  return (ioptr->LastBytePtr);
789 	}
790 
791 }
792 
793 int
_AusWriteLocalStream(int fd,char * buf,int count)794 _AusWriteLocalStream(int fd, char *buf, int count)
795 {
796   /* obsolete code */
797   return (write(fd, buf, count));
798 }
799 
800 int
_AusCloseLocalStream(int fd)801 _AusCloseLocalStream(int fd)
802 {
803   /* obsolete code */
804   return (close(fd));
805 }
806 
807 
808 
809 int
_AusConnectTliClient(int sfd,char * MoreConnections)810 _AusConnectTliClient(int sfd, char *MoreConnections)
811 {
812   register	char	type = _AusTypeOfStream[sfd];
813   register	struct  listenQue *freeq, *pendq;
814 
815   freeq = &Network.FreeList[type];
816   pendq = &Network.PendingQue[type];
817 
818   PRMSG("Calling ConnectTliClient(%d)\n", sfd,0);
819   LookForEvents(freeq, pendq, sfd);
820   return (CheckListenQue(freeq, pendq, sfd, MoreConnections));
821 }
822 
823 
824 static void
checkNewEvent(int fd)825 checkNewEvent(int fd)
826 {
827 	int	t;
828 
829         t = t_look(fd);
830         switch(t)
831         {
832         case T_DATA	  :
833 	        fprintf(stderr, "T_DATA received\n");
834 		break;
835   	case T_EXDATA	  :
836        		fprintf(stderr, "T_EXDATA received\n");
837 		break;
838   	case T_DISCONNECT :
839 	        t_rcvdis(fd, NULL);
840        		fprintf(stderr, "T_DISCONNECT received\n");
841 		break;
842  	case T_ERROR	  :
843         	fprintf(stderr, "T_ERROR received\n");
844 		break;
845   	case T_UDERR	  :
846         	fprintf(stderr, "T_UDERR received\n");
847 		break;
848   	case T_ORDREL	  :
849         	fprintf(stderr, "T_ORDREL received\n");
850 		break;
851   	}
852 }
853 
854 int
_AusReadTliStream(int fd,char * buf,int count,int do_buffering)855 _AusReadTliStream(int fd, char *buf, int count, int do_buffering)
856 {
857   /* obsolete code */
858   return 0;
859 }
860 
_AusWriteTliStream(int fd,char * buf,int count)861 _AusWriteTliStream(int fd, char *buf, int count)
862 {
863   return 0;
864   /* obsolete code */
865 }
866 
867 static void
868 OnError(int sig)
869 int	sig;
870 {
871   return;
872 }
873 
874 int
_AusCloseTliStream(int fd)875 _AusCloseTliStream(int fd)
876 {
877   /* obsolete code */
878   return 0;
879 }
880 
881 /*
882  * LookForEvents:	handle an asynchronous event
883  */
884 
885 static void
LookForEvents(struct listenQue * FreeHead,struct listenQue * PendHead,int fd)886 LookForEvents(struct listenQue *FreeHead, struct listenQue *PendHead, int fd)
887 {
888 	int	address;
889 	short	port, nf;
890 	struct t_discon disc;
891 	struct listenCall *current;
892 	struct t_call *call;
893 	int t;
894 	char	buf[MAX_AUTO_BUF_LEN];
895 	int	flag, i;
896 
897 	if((t = t_look(fd)) < 0) {
898 		PRMSG("t_look failed. t_errno %d\n", t_errno,0);
899 		return;
900 		}
901 	switch (t) {
902 	case 0:
903 		PRMSG("t_look 0\n",0,0);
904 		break;
905 		/* no return */
906 	case T_LISTEN:
907 		PRMSG("t_look T_LISTEN\n",0,0);
908 		current = deQue(FreeHead);
909 		call = current->CurrentCall;
910 
911 		if (t_listen(fd, call) < 0) {
912 			PRMSG("t_listen failed\n",0,0);
913 			return;
914 		}
915 
916 		Que(PendHead, current, ~CLEAR);
917 		PRMSG("incoming call seq # %d", call->sequence,0);
918 		break;
919 	case T_DISCONNECT:
920 		PRMSG("t_look T_DISCONNECT\n",0,0);
921 		if (t_rcvdis(fd, &disc) < 0) {
922 			PRMSG("Received T_DISCONNECT but t_rcvdis failed\n",0,0);
923 			exit(1);
924 		}
925 		PRMSG("incoming disconnect seq # %d", disc.sequence,0);
926 		RemoveCall(FreeHead, PendHead, &disc);
927 		t_close(fd);
928 		_AusTypeOfStream[fd] = -1;
929 		break;
930 	case T_DATA :
931 		if((i = t_rcv(fd, buf, MAX_AUTO_BUF_LEN, &flag)) > 0)
932 		break;
933 	default:
934 		PRMSG("t_look default %o %x\n", t, t);
935 		break;
936 	}
937 }
938 
939 
940 /*
941  * CheckListenQue:	try to accept a connection
942  */
943 
944 static int
CheckListenQue(struct listenQue * FreeHead,struct listenQue * PendHead,int fd,char * MoreConnections)945 CheckListenQue(struct listenQue *FreeHead, struct listenQue *PendHead,
946                int fd, char *MoreConnections)
947 {
948 	struct listenCall *current;
949 	struct t_call *call;
950 	int pid, nfd, n;
951 	char	*retptr, *ptr;
952 
953 	int	address;
954 	short	port, nf;
955 
956 	PRMSG( "in CheckListenQue",0,0);
957 	if (!(EMPTY(PendHead)))
958 	{
959 		current = deQue(PendHead);
960 		call = current->CurrentCall;
961 		PRMSG( "try to accept #%d", call->sequence,0);
962 		if((nfd = OpenVirtualCircuit(fd)) < 0)
963 		{
964 			PRMSG( "OpenVirtualCircuit failed\n",0,0);
965 			Que(FreeHead, current, CLEAR);
966 			*MoreConnections = !EMPTY(PendHead);
967 			return(-1);  /* let transport provider generate disconnect */
968 		}
969 
970 		n = t_accept(fd, nfd, call);
971 		if (n < 0){
972 
973 			PRMSG( "t_accept failed\n",0,0);
974 			if (t_errno == TLOOK) {
975 				t_close(nfd);
976 				PRMSG( "t_accept collision",0,0);
977 				PRMSG( "save call #%d", call->sequence,0);
978 				pQue(PendHead, current);
979 				*MoreConnections = !EMPTY(PendHead);
980 				return(-1);
981 			}
982 			else {
983 				PRMSG( "t_accept failed but not t_look\n",0,0);
984 				t_close(nfd);
985 				Que(FreeHead, current, CLEAR);
986 				*MoreConnections = !EMPTY(PendHead);
987 				return(-1);
988 			}
989 		}
990 		_AusTypeOfStream[nfd] = _AusTypeOfStream[fd];
991 		retptr = NULL;
992 
993 
994 
995 
996 		if( GetNetworkInfo (nfd, Network._net[_AusTypeOfStream[fd]],
997 		 ConvertTliCallToName, addtliheader(call),  &retptr, NULL) <= 0)
998 
999 		{
1000 			retptr = NULL;
1001 
1002 		}
1003 		ptr = NULL;
1004 		if(retptr != NULL)
1005 		{
1006 			ptr = retptr;
1007 			retptr += sizeof(xHostEntry);
1008 		}
1009 		GetNetworkInfo (nfd, Network._net[_AusTypeOfStream[fd]], PEER_ALLOC, &retptr, NULL);
1010 		if(ptr != NULL)
1011 			Aufree(ptr);
1012 		PRMSG( "Accepted call %d", call->sequence,0);
1013 		PRMSG("Channel %d is opened\n", nfd,0);
1014 
1015 		Que(FreeHead, current, CLEAR);
1016 
1017 
1018                 (void) ioctl(nfd, I_POP, "timod");
1019 		if(ioctl(nfd, I_PUSH, "tirdwr") < 0)
1020 		{
1021                  	t_close(nfd);
1022                         return(-1);
1023 		}
1024 
1025 		PRMSG( "Accepted call %d", call->sequence,0);
1026 		PRMSG("Channel %d is opened\n", nfd,0);
1027 
1028 		*MoreConnections = !EMPTY(PendHead);
1029 		return(nfd);
1030 	}
1031 
1032 	*MoreConnections = !EMPTY(PendHead);
1033 	return(-1);
1034 }
1035 
1036 
1037 /*
1038  * ClearCall:	clear out a call structure
1039  */
1040 
1041 static void
ClearCall(struct t_call * call)1042 ClearCall(struct t_call *call)
1043 {
1044 	call->sequence = 0;
1045 	call->addr.len = 0;
1046 	call->opt.len = 0;
1047 	call->udata.len = 0;
1048 	memset(call->addr.buf, 0, call->addr.maxlen);
1049 	memset(call->opt.buf, 0, call->opt.maxlen);
1050 	memset(call->udata.buf, 0, call->udata.maxlen);
1051 }
1052 
1053 
1054 /*
1055  * RemoveCall: remove call from pending list
1056  */
1057 
1058 static void
RemoveCall(struct listenQue * freeq,struct listenQue * pendq,struct t_discon * disc)1059 RemoveCall(struct listenQue *freeq, struct listenQue *pendq,
1060            struct t_discon *disc)
1061 {
1062 	struct listenCall *p, *oldp;
1063 
1064 	PRMSG( "Removing call, sequence # is %d", disc->sequence,0);
1065 	if (EMPTY(pendq)) {
1066 		disc->sequence = -1;
1067 		return;
1068 	}
1069 	p = pendq->QueHead;
1070 	oldp = (struct listenCall *) NULL;
1071 	while (p) {
1072 		if (p->CurrentCall->sequence == disc->sequence) {
1073 			if (oldp == (struct listenCall *) NULL) {
1074 				pendq->QueHead = p->NextCall;
1075 				if (pendq->QueHead == (struct listenCall *) NULL) {
1076 					pendq->QueTail = (struct listenCall *) NULL;
1077 				}
1078 			}
1079 			else if (p == pendq->QueTail) {
1080 				oldp->NextCall = p->NextCall;
1081 				pendq->QueTail = oldp;
1082 			}
1083 			else {
1084 				oldp->NextCall = p->NextCall;
1085 			}
1086 			Que(freeq, p, CLEAR);
1087 			disc->sequence = -1;
1088 			return;
1089 		}
1090 		oldp = p;
1091 		p = p->NextCall;
1092 	}
1093 	disc->sequence = -1;
1094 	return;
1095 }
1096 
1097 
1098 static int
1099 nameserver(int fd,
1100 #ifdef SVR4
1101            struct netconfig *nettype;
1102 #else
1103            char *nettype;
1104 #endif
1105            int service;
1106            char **arg1, **arg2;
1107            int  *arg3;
1108            }
1109 {
1110 
1111     char	*ptr;
1112     int	n;
1113     int	type;
1114 
1115 	if (fd >= 0)
1116 	    type = _AusTypeOfStream[fd];
1117 	else
1118 	    type = Au_TLI_STREAM;
1119 
1120 	if(type < Au_TLI_STREAM || type >= Network._nnets)
1121 	{
1122 		if(type == Au_LOCAL_STREAM || type == Au_NAMED_STREAM)
1123 			return(0);
1124 		if(fd >= 0)
1125 
1126     		{
1127 		PRMSG("in nameserver type %d unknown d\n", type, fd);
1128 		return(-1);
1129 		}
1130     	}
1131 
1132     if(nettype == NULL)
1133 	nettype = Network._net[type];
1134 
1135 
1136     switch(service){
1137       case	OpenDaemonConnection :
1138 #ifdef SVR4
1139 	return(InitializeNetPath());
1140 #else
1141 	if(NameServer < 0 )
1142 	    NameServer = OpenLocalServer(NAME_SERVER_NODE);
1143 	return(NameServer);
1144 #endif /* SVR4 */
1145 
1146       case	ConvertTliCallToName :
1147       case	ConvertNetAddrToName :
1148       case	ConvertNameToNetAddr :
1149       case	ConvertNameToTliBind :
1150       case	ConvertNameToTliCall :
1151 	if((n = CallTheNameServer(service, nettype, arg1, arg2, arg3)) < 0)
1152 	    return(-1);
1153 	return(n);
1154 
1155       case	PEER_NAME  :
1156 	if( fd < Network._npeers )
1157 	{
1158 	    *arg2 = Network._peer[fd];
1159 	    return(1);
1160 	}
1161 	return(-1);
1162       case	PEER_ALLOC :
1163 	if(fd >= Network._npeers)
1164 	    return(-1);
1165 
1166 	if(*arg1 == NULL){
1167 	    n = 0;
1168 	}
1169 	else	n = strlen(*arg1);
1170 
1171 	Network._peerlen[fd] = n;
1172 
1173 	if(n > 0){
1174 	    if(Network._peerlen[fd] > UNAME_LENGTH)
1175 		Network._peerlen[fd] = UNAME_LENGTH;
1176 	    bcopy(*arg1, Network._peer[fd], Network._peerlen[fd]);
1177 	    Network._peer[fd][Network._peerlen[fd]] = '\0';
1178 	}
1179 	else {
1180 	    Network._peer[fd][0] = '\0';
1181 	}
1182 	return(1);
1183 
1184       case	PEER_FREE  :
1185 	if(fd < Network._npeers && Network._peer[fd] != NULL)
1186 	{
1187 	    Network._peer[fd][0] = '\0';
1188 	    Network._peerlen[fd] = 0;
1189 	}
1190 	return(1);
1191     }
1192 }
1193 
1194 
1195 static	int	_hlen = 0;
1196 static	char	*_hptr = NULL;
1197 
1198 static char	**
1199 addheader(char *string, int len)
1200 {
1201 
1202 	int	n, m, p;
1203 	char	*ptr;
1204 
1205 	n = len;
1206 	m = n + sizeof(xHostEntry);
1207 	p = m + 2 * sizeof(int);
1208 
1209 	if(p > _hlen){
1210 		if(_hptr == NULL)
1211 			_hptr = malloc(p);
1212 		else	_hptr = realloc(_hptr, p);
1213 		}
1214 	if(_hptr == NULL){
1215 		fprintf(stderr, "addheader(): malloc failed\n");
1216 		exit(1);
1217 		}
1218 	else if(p > _hlen)
1219 		_hlen = p;
1220 
1221 	ptr = _hptr;
1222 
1223 	*(int *) ptr = m;
1224 	ptr += sizeof(int);
1225 	*(int *) ptr = 1;
1226 	ptr += sizeof(int);
1227 
1228 	((xHostEntry *) ptr)-> length = n;
1229 	ptr += sizeof(xHostEntry);
1230 	memcpy(ptr, string, n);
1231 
1232 	return(&_hptr);
1233 }
1234 
1235 static char **
1236 addtliheader(struct t_call *call)
1237 {
1238 
1239 
1240 	char	*ptr;
1241 	int	a, o, u;
1242 	int	ra, ro, ru, rentlen;
1243 
1244 
1245 	a = call->addr.len;
1246 	o = call->opt.len;
1247 	u = call->udata.len;
1248 
1249 	ra = ((a + sizeof(xHostEntry) +3) >>2) << 2;
1250 	ro = ((o + sizeof(xHostEntry) +3) >>2) << 2;
1251 	ru = ((u + sizeof(xHostEntry) +3) >>2) << 2;
1252 
1253 	rentlen = ra + ro + ru + 2 * sizeof(int);
1254 
1255 	if(rentlen > _hlen){
1256 		if(_hptr == NULL)
1257                         _hptr = malloc(rentlen);
1258 		else	_hptr = realloc(_hptr, rentlen);
1259 		}
1260 	if(_hptr == NULL){
1261 		fprintf(stderr, "addheader(): malloc failed\n");
1262 		exit(1);
1263 		}
1264 	else if(rentlen > _hlen)
1265 		_hlen = rentlen;
1266 
1267         ptr = _hptr;
1268 
1269         *(int *) ptr = rentlen - 2 * sizeof(int);
1270 	ptr += sizeof(int);
1271 	*(int *) ptr = 1;
1272 	ptr += sizeof(int);
1273 
1274 	((xHostEntry *) ptr)-> length = a;
1275 	if(a > 0){
1276 		memcpy(ptr + sizeof(xHostEntry), call->addr.buf, a);
1277 		}
1278 
1279 
1280 	ptr += ra;
1281 	((xHostEntry *) ptr)-> length = o;
1282 	if(o > 0)
1283 		memcpy(ptr + sizeof(xHostEntry), call->opt.buf, o);
1284 
1285 	ptr += ro;
1286 	((xHostEntry *) ptr)-> length = u;
1287 	if(u > 0){
1288 		memcpy(ptr + sizeof(xHostEntry), call->udata.buf, u);
1289                 }
1290 
1291 	return(&_hptr);
1292 }
1293 
1294 
1295 int _AuBytesReadable (int fd, int *ptr)
1296 {
1297 	int inbuf;
1298 	int n;
1299 	int flg;
1300 	InputBuffer *ioptr = &_AusInputBuffer[fd];
1301 
1302 	inbuf = ioptr->LastBytePtr - ioptr->FirstBytePtr;
1303 
1304         if (inbuf >= SIZEOF(xReply))
1305 	{
1306 		*ptr = inbuf;
1307 		return (0);
1308 	}
1309 
1310 	if (ioptr->FirstBytePtr > 0)
1311 	{
1312 		/* move tidbit to front of buffer */
1313 		bcopy(&ioptr->DataBuffer[ioptr->FirstBytePtr],
1314 		      ioptr->DataBuffer, inbuf);
1315 
1316 		/* Adjust pointers in buffer to reflect move */
1317 		ioptr->LastBytePtr = inbuf;
1318 		ioptr->FirstBytePtr = 0;
1319 	}
1320 
1321 	if (inbuf < 0)
1322 	{
1323 		inbuf = 0;
1324 		ioptr->LastBytePtr = 0;
1325 	}
1326 	/* Read no more than number of bytes left in buffer */
1327 
1328         errno = 0;
1329 
1330 
1331    	n = read(fd, &ioptr->DataBuffer[inbuf], BUFFERSIZE-inbuf);
1332 	if (n > 0)
1333 	{
1334 		ioptr->LastBytePtr += n;
1335 		*ptr = ioptr->LastBytePtr;
1336 		return (0);
1337 	}
1338 	else
1339 	{
1340 		if (ETEST(errno))
1341 		{
1342 			*ptr = ioptr->LastBytePtr;
1343 			return (0);
1344 		}
1345 		else
1346 		{
1347 			if (n == 0 )
1348 			{
1349 				errno = EPIPE;
1350 				return (-1);
1351 			}
1352 			else
1353 			{
1354 				if (errno != EINTR)
1355 					return (-1);
1356 				else
1357 				{
1358 					*ptr = ioptr->LastBytePtr;
1359 					return (0);
1360 				}
1361 			}
1362 		}
1363 	}
1364 }
1365 
1366 
1367 
1368 
1369 #ifndef SVR4
1370 
1371 #include <sys/poll.h>
1372 
1373 #define POLLERROR		(POLLHUP | POLLNVAL | POLLERR)
1374 #define PFD(fds, i, x) { 	if (fds) 		if (ev & (x)) 			BITSET (fds, i); 		else 			BITCLEAR (fds, i); }
1375 #define ERROR(x) { 	errno = x; 	return -1; }
1376 /*
1377 	simulate BSD select system call with SYSV poll system call
1378 	note that efds parameter is not fully supported (or understood)
1379 */
1380 
1381 extern long ulimit();
1382 
1383 int
1384 pollselect (int nfds, unsigned long *rfds, unsigned long *wfds,
1385             unsigned long *efds, struct timeval *timeout)
1386 {
1387 	int i, rc, ev, timevalue;
1388 	struct pollfd pfds[NOFILES_MAX];
1389 	static long _NOFILE = 0;
1390 
1391 	PRMSG("in pollselect\n", 0,0);
1392 
1393 	if (_NOFILE == 0) {
1394 		_NOFILE = ulimit(4, (long)0);
1395 		if (_NOFILE > NOFILES_MAX)
1396 			_NOFILE = NOFILES_MAX;
1397 	}
1398 
1399  	if (nfds > _NOFILE)
1400 		nfds = _NOFILE;   /* make poll happy */
1401 
1402 	for (i = 0; i < nfds; i++)
1403 	{
1404 		ev = 0;
1405 
1406 		if (rfds && GETBIT (rfds, i)) ev |= POLLIN;
1407 		if (wfds && GETBIT (wfds, i)) ev |= POLLOUT;
1408 		if (ev || (efds && GETBIT (efds, i)))
1409 			pfds[i].fd = i;
1410 		else
1411 			pfds[i].fd = -1;
1412 		pfds[i].events = ev;
1413 	}
1414 	if (timeout)
1415 		timevalue = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
1416 	else
1417 		timevalue = -1;
1418 
1419 	while (1)	{
1420 	   rc = poll (pfds, (unsigned long)nfds, timevalue);
1421 
1422 	   if(rc<0 && errno == EAGAIN)
1423 		continue;
1424 	   else	break;
1425 	}
1426 	if(rc>0)	{
1427 		if (!efds)
1428 			for (i = 0; i < nfds; ++i)
1429 			{
1430 				ev = pfds[i].revents;
1431 				if (ev & POLLERROR)
1432 					ERROR (EBADF);
1433 			}
1434 
1435 		for (i = 0; i < nfds; ++i)
1436 		{
1437 			ev = pfds[i].revents;
1438 			PFD (rfds, i, POLLIN);
1439 			PFD (wfds, i, POLLOUT);
1440 			PFD (efds, i, POLLERROR);
1441 		}
1442 	}
1443 
1444 	if(rc==0)	{
1445 		i = (nfds+ 7)/8;
1446 		if ( rfds != NULL)
1447 			memset((char *) rfds, 0, i);
1448 		if ( wfds != NULL)
1449 			memset((char *) wfds, 0, i);
1450 		if ( efds != NULL)
1451 			memset((char *) efds, 0, i);
1452 
1453 	}
1454 
1455 	return rc;
1456 }
1457 #define SELECT	pollselect
1458 
1459 
1460 #else
1461 #define SELECT	select
1462 #endif	/* ndef SVR4 */
1463 
1464 
1465 /*	The following routine is used for USL Compatibility between
1466  *	Operating System versions of SVR4.0 and SVR3.2. In System
1467  *	V Release 3.2 the select call is not available, and the
1468  *	pollselect is used to poll for connections. In SVR4.0 the
1469  * 	system supplies select and it is used. However, the arguments
1470  *	to these routines are  not identical so this routine
1471  * 	takes care of operating system differences by calling the
1472  * 	proper os dependent routine. It is called (by USL) from the
1473  *	server, Xlib  and Xt.
1474 */
1475 
1476 int
1477 _AuSelect(int nfds, unsigned long *r_mask, unsigned long *w_mask,
1478           unsigned long *e_mask, struct timeval *timeout)
1479 {
1480   int			retval = 0;
1481   int			count = 0;
1482   int			i;
1483   unsigned long		save_mask[MSKCNT];
1484   static struct timeval	notime;
1485 
1486 /*PRMSG("IN AuSelect from Austreams nfds=%d r_mask=%0x\n",nfds ,r_mask);*/
1487   if (r_mask) {
1488     CLEARBITS(save_mask);
1489 
1490     for (i = 0; i < nfds; ++i) {
1491       if (GETBIT(r_mask, i)
1492       && (_AusInputBuffer[i].LastBytePtr - _AusInputBuffer[i].FirstBytePtr) > 0) {
1493         BITCLEAR(r_mask, i);
1494         BITSET(save_mask, i);
1495         ++count;
1496       }
1497     }
1498   }
1499   if (count) {
1500     if (_AuANYSET((AuInt32 *)r_mask)
1501     || (w_mask && _AuANYSET((AuInt32 *)w_mask))
1502     || (e_mask && _AuANYSET((AuInt32 *)e_mask))) {
1503       retval = SELECT(nfds, r_mask, w_mask, e_mask, &notime);
1504     }
1505 
1506     for (i = 0; i < nfds; ++i) {
1507       if (GETBIT(save_mask, i)) {
1508         BITSET(r_mask, i);
1509       }
1510     }
1511     return retval < 0 ? retval : retval + count;
1512   } else {
1513     return SELECT(nfds, r_mask, w_mask, e_mask, timeout);
1514 
1515   }
1516 } 	/* AuSelect() */
1517 
1518 
1519 
1520 #else /* not STREAMSCONN */
1521 #ifndef lint
1522 static int dummy;	/* prevent ranlibs from complaining */
1523 #endif
1524 #endif /* STREAMSCONN */
1525