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