1 /* $NCDId: @(#)nameserver.c,v 1.3 1994/07/05 18:59:37 greg Exp $ */
2 /* $XConsortium: nameserver.c,v 1.3 91/07/23 11:50:04 rws Exp $ */
3 /*	nameserver.c - included by Xstreams.c			*/
4 /*	Used for System V Release 3.2 networking code ONLY	*/
5 
6 /* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc.
7  * Copyright 1991 Massachusetts Institute of Technology
8  * Copyright 1988, 1989 AT&T, Inc.
9  *
10  * Permission to use, copy, modify, and distribute this software and
11  * its documentation for any purpose and without fee is hereby
12  * granted, provided that the above copyright notice appear in all
13  * copies and that both that copyright notice and this permission
14  * notice appear in supporting documentation, and that the name of
15  * AT&T, USL, or MIT not be used in advertising or publicity
16  * pertaining to distribution of the software without specific,
17  * written prior permission.  AT&T, USL, and MIT make no
18  * representations about the suitability of this software for any
19  * purpose.  It is provided "as is" without express or implied
20  * warranty.
21  *
22  * AT&T, USL, AND MIT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
23  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
24  * NO EVENT SHALL AT&T, USL, OR MIT BE LIABLE FOR ANY SPECIAL,
25  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
26  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
27  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
28  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29  */
30 
31 #ifdef AuSTREAMS_COMPILE /* magic symbol to avoid lint problems */
32 
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 
36 static int svr4plus = 0;
37 static char clonedev[MAX_AUTO_BUF_LEN];
38 static int  *tcpfamilyp = NULL;
39 static char **tcpremoteaddrp = NULL;
40 static int  *tcpremoteaddrlenp = NULL;
41 
42 static int OpenAndBind();
43 static int Read();
44 
45 /* Routines for handling TLI streams */
46 
_AusSetupTliStream(char * display,char * stype)47 _AusSetupTliStream(
48                    char *display,
49                    char *stype
50                    )
51 {
52 	int	i, n;
53 	int	fd, type;
54 	struct	utsname  machine;
55 	struct listenCall *tmp;
56 	int	nameserver();
57 	static int first=1;
58 
59 	PRMSG("Calling SetupTliStream()\n",0,0);
60 
61         if(NameServer < 0 &&
62 		 (NameServer = OpenLocalServer(NAME_SERVER_NODE)) < 0)
63 	{
64                         return(-1);
65 	}
66 
67 	dispno = display;
68 
69 	if(uname(&machine) < 0){
70 		t_error("Cannot get nodename");
71 		return(-2);
72 		}
73 
74 	bind_req.addr.buf = req_buf;
75 	n = strlen(stype) +1;
76 
77 /* pcc */
78 	if(first)	{
79 		Network._nnets = Au_TLI_STREAM;
80 		first = 0;
81 	}
82 	type = Network._nnets++;
83 
84 	if((Network._net[type] = malloc(n)) == NULL){
85              		PRMSG( "malloc failed\n",0,0);
86 			return(-2);
87 			}
88 
89 	bcopy(stype, Network._net[type], n);
90 
91 	bind_ret.addr.buf = ret_buf;
92 	call.addr.buf	  = call_buf;
93 	bind_req.addr.maxlen = MAXLEN;
94 	bind_ret.addr.maxlen = MAXLEN;
95 	call.addr.maxlen     = MAXLEN;
96 
97 	fd = OpenAndBind(machine.nodename, atoi(display), MAXCONNECTIONS, Network._net[type], type);
98 
99 	if( fd < 0){
100 		PRMSG("Cannot OpenAndBind %s", machine.nodename,0);
101 		free(Network._net[type]);
102 		return(-2);
103 		}
104 
105 
106 	_AusTypeOfStream[fd] = type;
107 
108 /*
109  * set up call save list for general network listen service
110  */
111 	for (i = 0; i < LISTEN_QUE_SIZE; ++i)
112 	{
113 	    if((tmp = (struct listenCall *) malloc(sizeof(struct listenCall))) == NULL)
114 	    {
115 			PRMSG( "malloc failed\n",0,0);
116 			return(-1);
117 	    }
118 	    if((tmp->CurrentCall = (struct t_call *) t_alloc(fd,T_CALL,T_ALL)) == NULL)
119             {
120 			PRMSG( "t_alloc failed\n",0,0);
121 			return(-1);
122 	    }
123 	    Que(&Network.FreeList[type], tmp, CLEAR);
124 	}
125 
126 	if(Network._npeers > 0 && Network._peer == NULL)
127 	{
128 		register	i;
129 		register	char	*ptr;
130 		int		n;
131 
132 		n =  (Network._npeers + 1) *
133 			(sizeof(int) + sizeof(char *) + (1 + UNAME_LENGTH));
134 
135 		PRMSG("Allocating %d chars for %d peeers names",
136 							n, Network._npeers);
137 
138 		if((ptr = malloc(n)) == NULL){
139 			fprintf(stderr,"Cannot malloc space for peers names\n");
140 			exit(1);
141 		}
142 
143 		Network._peerlen = (int *) ptr;
144 		ptr += Network._npeers * sizeof(int);
145 		Network._peer = (char **) ptr;
146 		ptr += Network._npeers * sizeof(char *);
147 		for(i= 0; i< Network._npeers; i++)
148 		{
149 			Network._peerlen[i] = 0;
150 			Network._peer[i]    = ptr;
151 #ifdef DEBUG
152 			fprintf(stderr, "peer[%d] is %u; peerlen[%d] is %u\n",
153 				i, Network._peer[i], i, &Network._peerlen[i]);
154 #endif
155 			ptr += (1 + UNAME_LENGTH);
156 		}
157 	}
158 	PRMSG("SetupTliStream () (success) fd = %d\n", fd,0);
159 	return(fd);
160 }
161 
_AusCallTliServer(char * host,int idisplay,char * nettype)162 _AusCallTliServer(
163                   char *host,
164                   int	idisplay,
165                   char *nettype
166                   )
167 {
168 	int	fd, i, t;
169 	PFV	savef;
170 	int	netlen, type;
171 	char	*retptr, *ptr;
172 	char	first = 1;
173 	char	netbuffer[MAX_AUTO_BUF_LEN];
174 	static	char	firstime = 1;
175 
176 	PRMSG("Calling CallTliServer()\n",0,0);
177 
178         if(NameServer<0 && (NameServer = OpenLocalServer(NAME_SERVER_NODE)) < 0)
179 	{
180 			return(-1);
181 	}
182 
183 	if(firstime)
184 	{
185 		SetupNetworkInfo();
186 		Network._nnets = Au_TLI_STREAM;
187 		firstime = 0;
188 	}
189 
190 	sprintf(_dispno, "%d", idisplay - AU_DEFAULT_TCP_PORT);
191 	dispno = _dispno;
192 
193 	savef = signal (SIGALRM, dummy);
194 
195 /*
196  * Give up after MAX_TRIES tries or for CONNECT_TIME seconds or an error
197  * occurred which comes first.
198 */
199 
200 	retptr = NULL;
201 
202 #define MAX_TRIES	3
203 #define CONNECT_TIME    10
204 
205 	alarm (CONNECT_TIME);
206 
207 	if(svr4plus)
208 	{
209 		int	naddrs, n, j;
210 
211 		if(GetNetworkInfo (-1, nettype, ConvertNameToTliCall,
212                       addheader(host, strlen(host)), &retptr, &naddrs) <= 0)
213 		{
214                 	fprintf(stderr, "Cannot create address for system %s \n",
215 			host);
216 			t = -1;
217 			goto outofloop;
218 		}
219 
220                 call.opt.len = 0;
221                 call.opt.maxlen = 0;
222                 call.opt.buf = NULL;
223 
224                 call.udata.len = 0;
225                 call.udata.maxlen = 0;
226                 call.udata.buf = NULL;
227 #ifdef DEBUG
228 fprintf(stderr, "We got %d addresses for host %s\n", naddrs, host);
229 fprintf(stderr, "NETPATH sent to daemon is %s\n", nettype);
230 #endif
231 		ptr = retptr;
232 		for(i=0; i< naddrs; i++)
233 		{
234                         call.addr.len = ((xHostEntry *) ptr)->length;
235                         call.addr.maxlen = ((xHostEntry *) ptr)->length;
236                         call.addr.buf = (ptr+sizeof(xHostEntry));
237 
238 			call.addr.buf[call.addr.len] = '\0';
239 #ifdef DEBUG
240 			fprintf(stderr, "ADDRESS LENGTH IS %d\n", call.addr.len);
241 			fprintf(stderr, "Address returned is <%s>\n",call.addr.buf);
242 #endif
243 			ptr += (((sizeof(xHostEntry) + call.addr.len+3) >> 2) << 2);
244 
245 			n =  ((xHostEntry *) ptr)->length;
246 			if(n > 0)
247                                 nettype = (ptr+sizeof(xHostEntry));
248 			else	nettype = NULL;
249 
250 			ptr += (((sizeof(xHostEntry) + n+3) >> 2) << 2);
251 			n = ((xHostEntry *) ptr)->length;
252 			sprintf(clonedev, "%s", (ptr+sizeof(xHostEntry)));
253 
254 			ptr += (((sizeof(xHostEntry) + n+3) >> 2) << 2);
255 #ifdef DEBUG
256             		fprintf(stderr, "Clonedev is %s\n", clonedev);
257             		fprintf(stderr, "netid is %s\n", nettype);
258 #endif
259 
260 			fd = OpenAndBind(NULL, -1, 0, nettype, Au_TLI_STREAM);
261 			if(fd  < 0)
262 			{
263 				PRMSG("Openandbind failed\n",0,0);
264 				continue;
265 			}
266 			t = -1;
267 
268 	                PRMSG("Connecting to %s ... \n", host, 0);
269 			if((t = t_connect(fd, &call, NULL)) < 0)
270 			{
271        	          		if(t_errno == TLOOK)
272        	                 	{
273        	                  		checkNewEvent(fd);
274        	                         	t_close(fd);
275        	                 	}
276        	                 	else
277        	                 	{
278        	                  		t_error("t_connect failed");
279        	                         	t_close(fd);
280        	                 	}
281 			} else break;
282 
283 		}
284 	}
285 	else
286 	for(i=0; i < MAX_TRIES;i++)
287 	{
288 
289 		if((fd = OpenAndBind(NULL, -1, 0, nettype, Au_TLI_STREAM)) < 0)
290 		{
291 				PRMSG("Openandbind failed\n",0,0);
292 				break;
293 		}
294 	 	if(first)
295 		{
296 			first = 0;
297 
298 	   		if( GetNetworkInfo (-1, nettype, ConvertNameToTliCall,
299 				 addheader(host, strlen(host)),  &retptr, NULL) <= 0)
300 			{
301 				fprintf(stderr,
302 					"Cannot create address for system %s\n",host);
303 				t = -1;
304 				goto outofloop;
305 	   		}
306 
307 			ptr = retptr;
308 
309 	   		call.addr.len = ((xHostEntry *) ptr)->length;
310 	   		call.addr.maxlen = ((xHostEntry *) ptr)->length;
311 			call.addr.buf = (ptr+sizeof(xHostEntry));
312 
313 			call.addr.buf[call.addr.len] = '\0';
314 #ifdef DEBUG
315 			fprintf(stderr, "ADDRESS LENGTH IS %d\n", call.addr.len);
316 			fprintf(stderr, "Address returned is <%s>\n",call.addr.buf);
317 #endif
318 			ptr += (((sizeof(xHostEntry) + call.addr.len+3) >> 2) << 2);
319 
320 			call.opt.len = ((xHostEntry *) ptr)->length;
321 			call.opt.maxlen = ((xHostEntry *) ptr)->length;
322 			if(call.opt.len > 0)
323 				call.opt.buf = (ptr+sizeof(xHostEntry));
324 			else	call.opt.buf = NULL;
325 
326 			ptr += (((sizeof(xHostEntry) + call.opt.len+3) >> 2) << 2);
327 
328 			call.udata.len = ((xHostEntry *) ptr)->length;
329 			call.udata.maxlen = ((xHostEntry *) ptr)->length;
330 			if(call.udata.len > 0){
331 				call.udata.buf = (ptr+sizeof(xHostEntry));
332 #ifdef DEBUG
333 			fprintf(stderr, "ADDRESS LENGTH IS %d\n", call.udata.len);
334                         fprintf(stderr, "Address returned is <%s>\n",call.udata.buf);
335 #endif
336 			}
337 			else	call.udata.buf = NULL;
338 #ifdef DEBUG
339 			fprintf(stderr, "addrlen %d optlen %d udatalen %d\n",
340 					call.addr.len,
341 					call.opt.len,
342 					call.udata.len);
343 #endif
344 		}
345 
346 		t = -1;
347 
348 		PRMSG("Connecting to %s ... \n", host, 0);
349 
350 		/*
351 		 * override whatever the X name server says is the port number
352 		 * with what we asked for for the audio server.
353 		 */
354 		{
355 		struct sockaddr_in *x = (struct sockaddr_in *)call.addr.buf;
356 
357 		if(x->sin_family == AF_INET) {
358 			x->sin_port = htons(idisplay);
359 			if (tcpfamilyp != NULL) {
360 				*tcpfamilyp = AuNetworkInternet;
361 				*tcpremoteaddrlenp = 4;
362 				*tcpremoteaddrp = Aumalloc(*tcpremoteaddrlenp);
363 				/* This is a kludge.  What is the right way
364 				 * to get this info out? */
365 				memcpy(*tcpremoteaddrp, (char *)&x->sin_addr,
366 				       *tcpremoteaddrlenp);
367 			}
368 		}
369 		else {
370 			/* XXX anybody willing can fix this... */
371 			fprintf(stderr,
372 			"_AusCallTliServer: non-TCP/IP not supported (yet)\n");
373 		}
374 		}
375 
376 		if((t = t_connect(fd, &call, NULL)) < 0)
377 		{
378 			if(t_errno == TLOOK)
379 			{
380 				checkNewEvent(fd);
381 		        	t_close(fd);
382 				continue;
383 			}
384 			else
385 			{
386 				t_error("t_connect failed");
387 				t_close(fd);
388 				break;
389 			}
390 		} else break;
391 	}
392 
393 outofloop:
394 
395 #undef MAX_TRIES
396 #undef CONNECT_TIME
397 
398 	alarm (0);
399 	signal (SIGALRM, savef);
400 
401 	close(NameServer);
402 	NameServer = -1;
403 	netlen = strlen(nettype);
404 	if(netlen > 127)
405 	{
406 		netlen = 127;
407 		nettype[netlen] = '\0';
408 	}
409 	memcpy(netbuffer, nettype, netlen + 1);
410 	if(retptr != NULL)
411 		free(retptr);
412 	if(t < 0)
413 	{
414 		close(fd);
415 		return(-1);
416 	}
417 
418 /*
419 	if (t_rcvconnect (fd, &call) < 0) {
420 		if(t_errno == TLOOK)
421 			checkNewEvent(fd);
422 		t_close(fd);
423 		t_error ("t_rcvconnect failed!");
424 		return(-1);
425 	}
426 */
427 
428 	if(ioctl(fd, I_POP, "timod") < 0)
429 	{
430 	PRMSG("failed to pop timod\n", 0, 0);
431 	}
432 	if(ioctl(fd, I_PUSH, "tirdwr") < 0)
433 	{
434          	t_close(fd);
435 		return(-1);
436 	}
437 
438         if (_AusInputBuffer[fd].DataBuffer == NULL)
439             if ((_AusInputBuffer[fd].DataBuffer = (char *) malloc(BUFFERSIZE)) == NULL)
440                {
441 		        errno = ENOMEM;
442                		perror("Client can't connect to remote server");
443 			close(fd);
444                		return (-1);
445                }
446 	_AusInputBuffer[fd].LastBytePtr = 0;
447 	_AusInputBuffer[fd].FirstBytePtr = 0;
448 	type = -1;
449 	for(i= Au_TLI_STREAM; i< Network._nnets; i++)
450 	{
451 		if(strcmp(nettype, Network._net[i]) == 0)
452 		{
453 			type = i;
454 			break;
455 		}
456 	}
457 	if(type < 0)
458 	{
459 		Network._net[Network._nnets] = malloc(netlen+1);
460 		if(Network._net[Network._nnets] == NULL)
461 		{
462 		        errno = ENOMEM;
463                		perror("Client can't connect to remote server");
464 			close(fd);
465                		return (-1);
466                }
467 	       memcpy(Network._net[Network._nnets], netbuffer, netlen+1);
468 	       type = Network._nnets++;
469 	}
470 	_AusTypeOfStream[fd] = type;
471 	PRMSG("A Connection has been established to %s ... \n", host,0);
472 	PRMSG("CallTliServer() returns success\n",0,0);
473 
474 	return(fd);
475 }
476 
477 static int
OpenAndBind(char * name,int port,int maxcon,int type,char * nettype)478 OpenAndBind(
479             char *name,
480             int	port,
481             int maxcon,
482             int type,
483             char *nettype
484             )
485 {
486 	char	bind_buf[MAX_AUTO_BUF_LEN];
487 	int	i, fd;
488 	char	*retptr;
489 
490 	if(!svr4plus)
491 		sprintf(clonedev, "/dev/%s", nettype);
492 	if(name != NULL)
493 		PRMSG("OpenAndBind name %s, clonedev is %s \n",
494 				 name, clonedev);
495 
496 	/* point to the virtual circuit */
497 
498 	if ((fd = t_open(clonedev,  O_RDWR, NULL)) < 0)
499 	{
500 		fprintf(stderr, "Cannot open %s\n", clonedev);
501 #ifdef DEBUG
502 		t_error("t_open 1 failed");
503 #endif
504 		return(-1);
505 	}
506 
507 	_AusTypeOfStream[fd] = type;
508 	/* fill in the request call structure with necessary infomation */
509 
510 	if(name != NULL)
511 	{
512 	   if(GetNetworkInfo (-1, nettype, ConvertNameToTliBind,
513 		addheader(name, strlen(name)), &retptr, NULL)<0)
514 	   {
515 		PRMSG("Cannot create address for system %s \n", name, 0);
516 		return(-1);
517 	   }
518 	   bind_req.addr.buf = bind_buf;
519 	   bind_req.addr.len = ((xHostEntry *) retptr)->length;
520 	   bcopy (retptr+sizeof(xHostEntry), bind_buf, bind_req.addr.len);
521 	   free(retptr);
522 	   bind_buf[bind_req.addr.len] = '\0';
523 #ifdef DEBUG
524 	   fprintf(stderr, "ADDRESS LENGTH IS %d\n", bind_req.addr.len);
525 	   fprintf(stderr, "Address returned is <%s>\n", bind_buf);
526 #endif
527 	   bind_req.qlen = maxcon;
528 
529 	/* bind the name to the transport endpoint.  This operation will */
530 	/* take some time if the name is not already in the local name  */
531 	/* table or if the name is not a group name   */
532 #ifdef SHARELIB
533 #define t_bind (*_libAu_t_bind)
534 #endif
535 		i = t_bind (fd, &bind_req, NULL) ;
536 	}
537 	else 	i = t_bind (fd, NULL, NULL);
538 
539 	if(i < 0)
540 	{
541 		t_error("t_bind failed");
542 		close(fd);
543 		return(-1);
544 	}
545 
546 #ifdef SHARELIB
547 #undef t_bind
548 #endif
549 	if(name != NULL)
550 		PRMSG("OpenAndBind(%s, %d) (success)\n", name, maxcon);
551 	return(fd);
552 }
553 
erazeComment(char * line)554 static char *erazeComment(char *line)
555 {
556  	char	*ptr = line;
557 
558         while(*ptr <= ' ' && *ptr != '\0')
559                         ptr++;
560 /*
561  *	If you want to check the version do it here
562  *if( strncmp(ptr, "#VERSION", 8) == 0)
563  *			return(NULL);
564  */
565    	if(*ptr == '\0' || *ptr == '#'){
566                         return(NULL);
567                         }
568 	line = ptr;
569 	while(*ptr != '\0' && *ptr != '#')
570                         ptr++;
571 	*ptr = '\0';
572 	return(line);
573 }
574 
575 
576 #define AuNETDB "lib/Xconnections"
577 
578 #ifdef NEED_FAKE_XWIN
579 static char *
GetXWINHome(char * with)580 GetXWINHome(char *with)
581 {
582 	static char buf[50];
583 
584 	(void) strcpy(buf, "/usr/X/");
585 	(void) strcat(buf, with);
586 	return(buf);
587 }
588 #endif /* NEED_FAKE_XWIN */
589 
590 int _AuMakeStreamsConnection (
591                               char	*name,
592                               int	*iserverp,		/* can be RETURN */
593                               AuBool xname,
594                               int	retries,
595                               int	*familyp,		/* return */
596                               int	*serveraddrlenp,	/* return */
597                               char **serveraddrp,		/* return */
598                               )
599 {
600 	struct	utsname	 machine;
601 	register	i;
602 	FILE	*file;
603 	char	*line, *ptr,buf[160];
604 	int	fd, nfound = 0, n;
605 	static  char	netype[MAX_AUTO_BUF_LEN], nodname[MAX_AUTO_BUF_LEN];
606 	char *home;
607 	char	sysname[128] ;
608 	char	*procname = "Aulib/_XMakeStreamsConnection";
609 
610 
611 
612 	PRMSG("GetConnectionType(%s)\n", name, 0);
613 
614         if(uname(&machine) < 0){
615 		t_error("Cannot get nodename");
616 		return(-1);
617 		}
618 
619 	if(
620 		name == NULL ||
621 		strcmp(name, "") == 0 ||
622 		strcmp(name, "unix") == 0 ||
623 		strcmp(name, "local") == 0 ||
624 		strcmp(name, machine.nodename) == 0
625 	  )	{
626 
627 	    /*
628 	     * auth information for local connection set above
629 	     */
630 
631 	    fd = ((*_AusStream[Au_LOCAL_STREAM].CallTheListener)
632 		  ("unix", *iserverp, "local"));
633 	    if (fd >= 0) {
634 		*familyp = FamilyLocal;
635 		*serveraddrlenp = strlen (machine.nodename);
636 		*serveraddrp = (char *) Aumalloc ((*serveraddrlenp) + 1);
637 		if (!*serveraddrp) {
638 		    *serveraddrlenp = 0;
639 		} else {
640 		    strcpy (*serveraddrp, machine.nodename);
641 		}
642 	    }
643 	    return fd;
644 	}
645 
646 	if(xname)				/* name came from X */
647 		*iserverp += AU_DEFAULT_TCP_PORT;
648 
649 	tcpfamilyp = familyp;
650 	tcpremoteaddrp = serveraddrp;
651 	tcpremoteaddrlenp = serveraddrlenp;
652 
653         if(machine.release[0] !=  '3')
654 	{
655 		char	*netpath;
656 
657 		svr4plus = 1;
658 #ifdef DEBUG
659 		fprintf(stderr,
660 "sysname <%s>, nodename <%s>, release <%s>, version <%s>, machine <%s>\n",
661 			machine.sysname ,
662 			machine.nodename,
663 			machine.release,
664 			machine.version,
665 			machine.machine);
666 #endif
667 
668 		if((netpath = (char *) getenv("NETPATH")) == NULL)
669 				netpath = "";
670 		return (*_AusStream[Au_TLI_STREAM].CallTheListener)
671 				(name, *iserverp, netpath);
672 	}
673 
674 	file = fopen(home = GetXWINHome(AuNETDB), "r");
675 	if(file == NULL){
676 		fprintf(stderr, "Cannot open %s\n", home);
677 		return(-1);
678 		}
679 	while((line = fgets(buf, 160, file)) != NULL)
680 	{
681                	if((n = strlen(line)) > 1)
682                               line[n-1] = '\0';
683 		if((ptr = erazeComment(line)) == NULL)
684 			continue;
685 
686 		n = sscanf(ptr, "%s%s%s", sysname, nodname, netype);
687 		if(
688 			n >= 3 &&
689 			strcmp(name, sysname) == 0
690 		  ){
691 			nfound++;
692 		        fd = (*_AusStream[Au_TLI_STREAM].CallTheListener)
693 						(nodname, *iserverp, netype);
694 			if(fd >= 0)
695 			{
696 				fclose(file);
697 				return(fd);
698 			}
699 		   }
700 		else if(strcmp(sysname, "*") == 0 || strcmp(nodname, "*") == 0)
701 		   {
702 			sprintf(nodname, name);
703 			fd = (*_AusStream[Au_TLI_STREAM].CallTheListener)
704                                                 (nodname, *iserverp, netype);
705 			fclose(file);
706                         return(fd);
707 		   }
708 	}
709 	fclose(file);
710 	if(!nfound)
711 	{
712 		fprintf(stderr, "There is no entry for %s in %s\n",
713 					name, home);
714 	}
715 	return(-1);
716 }
717 
718 
719 #ifdef DEBUG
dump(char * buf,int len)720 dump(char *buf, int len)
721 {
722  	int	i;
723 	if(buf != NULL)
724 		for(i=0; i< len; i++)
725                         fprintf(stderr, "<%o> ", buf[i]);
726 	fprintf(stderr, "\n");
727 	fflush(stderr);
728 }
729 
730 #endif
731 
732 
733 #define	NSECONDS	60
734 
735 static int	_errflag = 0;
736 
737 /* ARGSUSED */
OnAlarm(i)738 static SIGNAL_T OnAlarm(i)
739     int i;
740 {
741 	_errflag = 1;
742 }
743 
744 static int
CallTheNameServer(char * nettype,char ** arg1,char ** arg2,int service,int * arg3)745 CallTheNameServer(
746                   char	*nettype,
747                   char **arg1,
748                   char **arg2,
749                   int	service,
750                   int *arg3
751                   )
752 {
753 	int	m, n, ret;
754 	char   *ptr, *p;
755 	char	buf[MAX_AUTO_BUF_LEN];
756 
757 PRMSG("In CallTheNameServer, \n", 0, 0);
758 
759 	if(NameServer < 0)
760 		return(-1);
761 	if(_errflag)
762 	{
763 		int	flags;
764 
765 		if((flags = fcntl(NameServer, F_GETFL)) == -1)
766 			flags = O_RDWR;
767 		fcntl (NameServer, F_SETFL, O_NDELAY);
768 		while(read (NameServer, buf, MAX_AUTO_BUF_LEN) > 0);
769 		if(errno != EAGAIN && errno != EINTR)
770 		{
771 			fprintf(stderr, "errno %d while reading the nameserver\n",
772 					errno);
773 			close(NameServer);
774 			NameServer = -1;
775 			return(-1);
776 		}
777 		fcntl (NameServer, F_SETFL, flags);
778 		_errflag = 0;
779 	}
780 
781 	ret = n = (* (int *) (*arg1)) + 2*sizeof(int);
782 
783         ptr = buf;
784 	m = HEADERSIZE + strlen(nettype)+ 1;
785 	m = (((m +3) >>2)<<2);
786 
787 	*(int *) ptr = n+m;
788 	ptr += sizeof(int);
789 	*(int *) ptr = m;
790 	ptr += sizeof(int);
791 	*(int *) ptr = service;
792 	ptr += sizeof(int);
793 	*(int *) ptr = atoi(dispno);
794 	ptr += sizeof(int);
795 	*(int *) ptr = strlen(nettype);
796 	ptr += sizeof(int);
797 	sprintf(ptr, nettype);
798 
799   	p = malloc(m + n);
800 	if(p == NULL)
801 		return(-1);
802 	memcpy(p, buf, m);
803 	memcpy(p+m, *arg1, n);
804 
805 	signal(SIGALRM, OnAlarm);
806 	alarm(NSECONDS);
807 
808 	if(write(NameServer, p, m+n) != m+n){
809 		fprintf(stderr, "write error\n");
810 		ret = -1;
811 		close(NameServer);
812 		NameServer = -1;
813 		}
814 	else if(Read(NameServer, buf, 2*sizeof(int)) == 0)
815 	{
816 		ret = -1;
817 #ifdef DEBUG
818 		fprintf(stderr, "Server fails to read header from nameserver\n");
819 #endif
820 	}
821 	else {
822 		ptr = buf;
823 		ret = *(int *) buf;
824 		ptr += sizeof(int);
825 		if(*(int *) ptr <= 0)
826 		{
827 #ifdef DEBUG
828 			fprintf(stderr, "No Of entries returned <= 0\n");
829 #endif
830 			ret = -1;
831 			goto theend;
832 		}
833 		if(arg3 != NULL){
834 			*arg3 = *(int *) ptr;
835 #ifdef DEBUG
836 			fprintf(stderr, "No Of Entries returned {%d}\n", *arg3);
837 #endif
838 			}
839 		ptr = *arg2 = (char *) malloc(ret );
840 #ifdef DEBUG
841 		if(ptr == NULL)
842 			fprintf(stderr, "MALLOC returns NULL\n");
843 #endif
844 		if(ptr == NULL)
845 		{
846 			errno = ENOMEM;
847 			ret = -1;
848 		}
849 		else {
850 			if(Read(NameServer, ptr, ret) == 0)
851 			{
852 				fprintf(stderr,
853 					"Server fails to read %d chars\n", ret);
854 				free(*arg2);
855 				ret = -1;
856 			}
857 		}
858 	}
859 theend:
860 	alarm(0);
861 	free(p);
862 	return(ret);
863 }
864 
865 
866 static int
Read(int fd,char * buf,int count)867 Read(int fd, char *buf, int count)
868 {
869 	int	n;
870 	while((n = read(fd, buf, count)) > 0)
871 	{
872 		if(n == count)
873 		{
874 			return(1);
875 		}
876 		buf += n;
877 		count -= n;
878 	}
879 	return(0);
880 }
881 
882 static int
OpenVirtualCircuit(int lfd)883 OpenVirtualCircuit(int lfd)
884 {
885 	return(OpenAndBind(NULL, -1, 0,
886 		 	Network._net[_AusTypeOfStream[lfd]], _AusTypeOfStream[lfd]));
887 }
888 
889 #endif /* AuSTREAMS_COMPILE */
890