1/* BEGIN LICENSE BLOCK
2 * Version: CMPL 1.1
3 *
4 * The contents of this file are subject to the Cisco-style Mozilla Public
5 * License Version 1.1 (the "License"); you may not use this file except
6 * in compliance with the License.  You may obtain a copy of the License
7 * at www.eclipse-clp.org/license.
8 *
9 * Software distributed under the License is distributed on an "AS IS"
10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11 * the License for the specific language governing rights and limitations
12 * under the License.
13 *
14 * The Original Code is  The ECLiPSe Constraint Logic Programming System.
15 * The Initial Developer of the Original Code is  Cisco Systems, Inc.
16 * Portions created by the Initial Developer are
17 * Copyright (C) 1994-2006 Cisco Systems, Inc.  All Rights Reserved.
18 *
19 * Contributor(s): Kees Schuerman, ECRC
20 *
21 * END LICENSE BLOCK */
22/**********************************************************************
23**      System: Parallel Distributed System
24**        File: nsrv_server.c
25**      Author: Kees Schuerman
26**      SccsId: "@(#)nsrv_server.c	1.37 14 Nov 1995"
27** Description: Name Server
28***********************************************************************/
29
30#include "machine.h"     /* architecture specific constant definitions */
31
32#include <sys/types.h>
33#include <sys/time.h>
34#include <sys/stat.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <netinet/tcp.h>
39#include <netdb.h>
40#include <arpa/inet.h>
41#include <signal.h>
42#include <malloc.h>
43#include <errno.h>
44#include <string.h>
45#include <unistd.h>
46#include <stdlib.h>
47#include <stdio.h>
48#include <fcntl.h>
49#include <rpc/rpc.h>
50
51#include "pds.types.h"
52#include "pds.error.h"
53#include "pds.mem.h"
54#include "pds.mdt.h"
55#include "pds.xdr.h"
56#include "bmsg.msg.h"
57#include "bmsg.xdr.h"
58#include "amsg.msg.h"
59#include "amsg.xdr.h"
60#include "nsrv.h"
61#include "nsrv.xdr.h"
62#include "nsrv_int.h"
63
64
65/**********************************************************************
66** Some Constants
67***********************************************************************/
68
69#define NSRV_SIGNATURE		"h^lX*7$;@cLfgEg#}+G@!"
70#define NSRV_SOCK_BACKLOG	32
71
72
73
74/**********************************************************************
75** Global Variables
76***********************************************************************/
77
78static char * nsrv_path = (char *) 0; /* path                            */
79static int nsrv_shared = 1;           /* allow shared memory interaction */
80static int nsrv_pds = 1;              /* allow PDS based interaction     */
81static int nsrv_verbose = 0;	      /* verbose option			 */
82
83static char * datafile = (char *) 0;
84static char * msgfile = (char *) 0;
85
86static unsigned nsrv_port_number = 0;
87static int nsrv_ctrl_sock = 0;        /* control socket                  */
88static bport_t nsrv_port;
89
90
91
92/**********************************************************************
93** A-Layer Primitives
94***********************************************************************/
95
96void
97amsg_warn(msg_warn,culprit)
98    amsg_warn_t msg_warn;
99    aport_id_t culprit;
100{
101}
102
103
104void
105amsg_error(msg_error,culprit)
106    amsg_error_t msg_error;
107    aport_id_t culprit;
108{
109}
110
111
112void
113amsg_panic(msg_panic,culprit)
114    amsg_panic_t msg_panic;
115    aport_id_t culprit;
116{
117}
118
119
120/**********************************************************************
121** B-Layer Primitives
122***********************************************************************/
123
124void
125bport_ack(port_id, port_primitive, ret)
126    bport_id_t port_id;
127    bport_primitive_t port_primitive;
128    bmsg_ret_t ret;
129{
130}
131
132
133void
134bport_notify(port_id,port_primitive)
135    bport_id_t port_id;
136    bport_primitive_t port_primitive;
137{
138}
139
140
141void
142bmem_ack(mem_id,mem_primitive,ret)
143    bmem_id_t mem_id;
144    bmem_primitive_t mem_primitive;
145    bmsg_ret_t ret;
146{
147}
148
149
150void
151bmem_notify(port_id,mem_primitive,mem_address,mem_data_size)
152    bport_id_t port_id;
153    bmem_primitive_t mem_primitive;
154    bmem_address_t mem_address;
155    bmem_size_t mem_data_size;
156{
157}
158
159
160void
161bmsg_warn(msg_warn,culprit)
162    bmsg_warn_t msg_warn;
163    bport_id_t culprit;
164{
165}
166
167
168void
169bmsg_error(msg_error,culprit)
170    bmsg_error_t msg_error;
171    bport_id_t culprit;
172{
173}
174
175
176void
177bmsg_panic(msg_panic,culprit)
178    bmsg_panic_t msg_panic;
179    bport_id_t culprit;
180{
181}
182
183
184void
185bproc_trigger(port)
186    bport_t * port;
187{
188#if defined(SIGIO)
189    kill((int) port->bpid,SIGIO);
190#else
191    nsrv_assert_always();
192#endif
193}
194
195
196/**********************************************************************
197** Primitives
198***********************************************************************/
199
200static void
201nsrv_warn(culprit)
202    char * culprit;
203{
204    fprintf(stderr,"nsrv: warning : %s !!! \n", culprit);
205}
206
207
208static void
209nsrv_pds_exit()
210{
211    if (amsg_ready())
212	amsg_exit();
213    if (bmsg_ready())
214	bmsg_exit();
215}
216
217
218static void
219nsrv_panic(culprit)
220    char * culprit;
221{
222    fprintf(stderr,"nsrv: panic : %s !!! \n", culprit);
223    nsrv_pds_exit();
224    nsrv_exit_i();
225    exit(-1);
226}
227
228
229static void
230nsrv_send_reply(reply_port_id,msg,msg_type)
231    aport_id_t reply_port_id;
232    amsg_t msg;
233    amsg_type_t msg_type;
234{
235    amsg_ret_t aret;
236
237    do {
238        aret = amsg_send(reply_port_id,msg,msg_type,
239			 (amsg_count_t) 1,(amsg_option_t) 0);
240    } while (aret == AMSG_PNOTAVAILABLE);
241    switch (aret) {
242	case AMSG_OK :
243	    break;
244	case AMSG_NOPORT :
245	case AMSG_PDYING :
246	case AMSG_NOSENDRIGHTS :
247	    aret = amsg_free(msg);
248	    nsrv_assert(aret == AMSG_OK);
249	    break;
250	case AMSG_PBLOCKED :
251	    /*
252	    ** Currently we throw the reply messag away. Should be changed
253	    ** such that they are remembered so that they can be sent at
254	    ** a later time, i.e. when the port is unblocked.
255	    */
256    	    fprintf(stderr,"nsrv: Losing reply !!! \n");
257	    aret = amsg_free(msg);
258	    nsrv_assert(aret == AMSG_OK);
259	    break;
260	case AMSG_NORESOURCES :
261	case AMSG_NOMEMORY :
262	    nsrv_panic("Not enough memory");
263	    break;
264	default :
265	    nsrv_panic("AMSG system error");
266	    break;
267    }
268}
269
270
271static void
272nsrv_send_simple_reply(reply_port_id,ret)
273    aport_id_t reply_port_id;
274    nsrv_ret_t ret;
275{
276    amsg_ret_t aret;
277    amsg_t msg;
278    simple_reply_t * reply;
279
280    aret = amsg_alloc((amsg_size_t) sizeof(simple_reply_t),
281		      (amsg_data_t * *) &reply,
282		      &msg);
283    if (aret != AMSG_OK)
284	nsrv_panic("Not enough memory");
285    reply->ret = ret;
286    nsrv_send_reply(reply_port_id,msg,MDT_SIMPLE_REPLY);
287}
288
289
290static void
291nsrv_aport_register_s(port_id)
292    aport_id_t port_id;
293{
294    amsg_ret_t aret;
295    nsrv_ret_t nret;
296    amsg_t request_msg;
297    amsg_type_t msg_type;
298    amsg_count_t msg_count;
299    aport_register_request_t * request;
300
301    while ((aret = amsg_receive(port_id,
302                                &request_msg,
303                                (amsg_data_t * *) &request,
304                                &msg_type,
305                                &msg_count,
306                                (amsg_option_t) 0)) == AMSG_OK) {
307	nsrv_assert(msg_type == MDT_APORT_REGISTER_REQUEST);
308	nsrv_assert(msg_count == 1);
309	nret = nsrv_aport_register_i(request->key,
310				     request->name,
311				     request->signature,
312				     &request->port);
313	nsrv_send_simple_reply(request->reply_port_id,nret);
314	aret = amsg_free(request_msg);
315	nsrv_assert(aret == AMSG_OK);
316    }
317    nsrv_assert(aret == AMSG_NOMESSAGE);
318}
319
320
321static void
322nsrv_deregister_s(port_id,deregister_i)
323    aport_id_t port_id;
324    nsrv_ret_t (* deregister_i) ();
325{
326    amsg_ret_t aret;
327    nsrv_ret_t nret;
328    amsg_t request_msg;
329    amsg_type_t msg_type;
330    amsg_count_t msg_count;
331    deregister_request_t * request;
332
333    while ((aret = amsg_receive(port_id,
334                                &request_msg,
335                                (amsg_data_t * *) &request,
336                                &msg_type,
337                                &msg_count,
338                                (amsg_option_t) 0)) == AMSG_OK) {
339	nsrv_assert(msg_type == MDT_DEREGISTER_REQUEST);
340	nsrv_assert(msg_count == 1);
341	nret = deregister_i(request->key,
342			    request->name,
343			    request->signature);
344	nsrv_send_simple_reply(request->reply_port_id,nret);
345	aret = amsg_free(request_msg);
346	nsrv_assert(aret == AMSG_OK);
347    }
348    nsrv_assert(aret == AMSG_NOMESSAGE);
349}
350
351
352static void
353nsrv_aport_deregister_s(port_id)
354    aport_id_t port_id;
355{
356    nsrv_deregister_s(port_id,nsrv_aport_deregister_i);
357}
358
359
360static void
361nsrv_aport_look_up_s(port_id)
362    aport_id_t port_id;
363{
364    amsg_ret_t aret;
365    nsrv_ret_t nret;
366    amsg_t request_msg;
367    amsg_t reply_msg;
368    amsg_type_t msg_type;
369    amsg_count_t msg_count;
370    look_up_request_t * request;
371    aport_reply_t * reply;
372
373    while ((aret = amsg_receive(port_id,
374                                &request_msg,
375                                (amsg_data_t * *) &request,
376                                &msg_type,
377                                &msg_count,
378                                (amsg_option_t) 0)) == AMSG_OK) {
379	nsrv_assert(msg_type == MDT_LOOK_UP_REQUEST);
380	nsrv_assert(msg_count == 1);
381	aret = amsg_alloc((amsg_size_t) sizeof(aport_reply_t),
382                          (amsg_data_t * *) &reply,
383			  &reply_msg);
384	if (aret != AMSG_OK)
385	    nsrv_panic("Not enough memory");
386	nret = nsrv_aport_look_up_i(request->key,
387				    request->name,
388				    &reply->port);
389	reply->ret = nret;
390	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_APORT_REPLY);
391	aret = amsg_free(request_msg);
392	nsrv_assert(aret == AMSG_OK);
393    }
394    nsrv_assert(aret == AMSG_NOMESSAGE);
395}
396
397
398static void
399nsrv_bport_register_s(port_id)
400    aport_id_t port_id;
401{
402    amsg_ret_t aret;
403    nsrv_ret_t nret;
404    amsg_t request_msg;
405    amsg_type_t msg_type;
406    amsg_count_t msg_count;
407    bport_register_request_t * request;
408
409    while ((aret = amsg_receive(port_id,
410                                &request_msg,
411                                (amsg_data_t * *) &request,
412                                &msg_type,
413                                &msg_count,
414                                (amsg_option_t) 0)) == AMSG_OK) {
415	nsrv_assert(msg_type == MDT_BPORT_REGISTER_REQUEST);
416	nsrv_assert(msg_count == 1);
417
418	nret = nsrv_bport_register_i(request->key,
419				     request->name,
420				     request->signature,
421				     &request->port);
422	nsrv_send_simple_reply(request->reply_port_id,nret);
423	aret = amsg_free(request_msg);
424	nsrv_assert(aret == AMSG_OK);
425    }
426    nsrv_assert(aret == AMSG_NOMESSAGE);
427}
428
429
430static void
431nsrv_bport_deregister_s(port_id)
432    aport_id_t port_id;
433{
434    nsrv_deregister_s(port_id,nsrv_bport_deregister_i);
435}
436
437
438static void
439nsrv_bport_look_up_s(port_id)
440    aport_id_t port_id;
441{
442    amsg_ret_t aret;
443    nsrv_ret_t nret;
444    amsg_t request_msg;
445    amsg_type_t msg_type;
446    amsg_count_t msg_count;
447    amsg_t reply_msg;
448    look_up_request_t * request;
449    bport_reply_t * reply;
450
451    while ((aret = amsg_receive(port_id,
452                                &request_msg,
453                                (amsg_data_t * *) &request,
454                                &msg_type,
455                                &msg_count,
456                                (amsg_option_t) 0)) == AMSG_OK) {
457	nsrv_assert(msg_type == MDT_LOOK_UP_REQUEST);
458	nsrv_assert(msg_count == 1);
459	aret = amsg_alloc((amsg_size_t) sizeof(bport_reply_t),
460                          (amsg_data_t * *) &reply,
461			  &reply_msg);
462	if (aret != AMSG_OK)
463	    nsrv_panic("Not enough memory");
464	nret = nsrv_bport_look_up_i(request->key,
465				    request->name,
466				    &reply->port);
467	reply->ret = nret;
468	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_BPORT_REPLY);
469	aret = amsg_free(request_msg);
470	nsrv_assert(aret == AMSG_OK);
471    }
472    nsrv_assert(aret == AMSG_NOMESSAGE);
473}
474
475
476static void
477nsrv_bdomain_register_s(port_id)
478    aport_id_t port_id;
479{
480    amsg_ret_t aret;
481    nsrv_ret_t nret;
482    amsg_t request_msg;
483    amsg_type_t msg_type;
484    amsg_count_t msg_count;
485    bdomain_register_request_t * request;
486
487    while ((aret = amsg_receive(port_id,
488                                &request_msg,
489                                (amsg_data_t * *) &request,
490                                &msg_type,
491                                &msg_count,
492                                (amsg_option_t) 0)) == AMSG_OK) {
493	nsrv_assert(msg_type == MDT_BDOMAIN_REGISTER_REQUEST);
494	nsrv_assert(msg_count == 1);
495	nret = nsrv_bdomain_register_i(request->key,
496				       request->name,
497				       request->signature,
498				       &request->domain);
499	nsrv_send_simple_reply(request->reply_port_id,nret);
500	aret = amsg_free(request_msg);
501	nsrv_assert(aret == AMSG_OK);
502    }
503    nsrv_assert(aret == AMSG_NOMESSAGE);
504}
505
506
507static void
508nsrv_bdomain_deregister_s(port_id)
509    aport_id_t port_id;
510{
511    nsrv_deregister_s(port_id,nsrv_bdomain_deregister_i);
512}
513
514
515static void
516nsrv_bdomain_look_up_s(port_id)
517    aport_id_t port_id;
518{
519    amsg_ret_t aret;
520    nsrv_ret_t nret;
521    amsg_t request_msg;
522    amsg_type_t msg_type;
523    amsg_count_t msg_count;
524    amsg_t reply_msg;
525    look_up_request_t * request;
526    bdomain_reply_t * reply;
527
528    while ((aret = amsg_receive(port_id,
529                                &request_msg,
530                                (amsg_data_t * *) &request,
531                                &msg_type,
532                                &msg_count,
533                                (amsg_option_t) 0)) == AMSG_OK) {
534	nsrv_assert(msg_type == MDT_LOOK_UP_REQUEST);
535	nsrv_assert(msg_count == 1);
536	aret = amsg_alloc((amsg_size_t) sizeof(bdomain_reply_t),
537                          (amsg_data_t * *) &reply,
538			  &reply_msg);
539	if (aret != AMSG_OK)
540	    nsrv_panic("Not enough memory");
541	nret = nsrv_bdomain_look_up_i(request->key,
542				      request->name,
543				      &reply->domain);
544	reply->ret = nret;
545	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_BDOMAIN_REPLY);
546	aret = amsg_free(request_msg);
547	nsrv_assert(aret == AMSG_OK);
548    }
549    nsrv_assert(aret == AMSG_NOMESSAGE);
550}
551
552
553static void
554nsrv_new_bport_id_s(port_id)
555    aport_id_t port_id;
556{
557    amsg_ret_t aret;
558    nsrv_ret_t nret;
559    amsg_t request_msg;
560    amsg_type_t msg_type;
561    amsg_count_t msg_count;
562    amsg_t reply_msg;
563    bport_id_request_t * request;
564    bport_id_reply_t * reply;
565    bport_id_t bport_id;
566
567    while ((aret = amsg_receive(port_id,
568                                &request_msg,
569                                (amsg_data_t * *) &request,
570                                &msg_type,
571                                &msg_count,
572                                (amsg_option_t) 0)) == AMSG_OK) {
573	nsrv_assert(msg_type == MDT_BPORTID_REQUEST);
574	nsrv_assert(msg_count == 1);
575	aret = amsg_alloc((amsg_size_t) sizeof(bport_id_reply_t),
576                          (amsg_data_t * *) &reply,
577			  &reply_msg);
578	if (aret != AMSG_OK)
579	    nsrv_panic("Not enough memory");
580	bport_id = reply->port_id;
581	nret = nsrv_new_bport_id_i(request->signature,&bport_id);
582	reply->port_id = bport_id;
583	reply->ret = nret;
584	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_BPORTID_REPLY);
585	aret = amsg_free(request_msg);
586	nsrv_assert(aret == AMSG_OK);
587    }
588    nsrv_assert(aret == AMSG_NOMESSAGE);
589}
590
591
592static void
593nsrv_free_bport_id_s(port_id)
594    aport_id_t port_id;
595{
596    amsg_ret_t aret;
597    nsrv_ret_t nret;
598    amsg_t request_msg;
599    amsg_type_t msg_type;
600    amsg_count_t msg_count;
601    bport_id_request_t * request;
602
603    while ((aret = amsg_receive(port_id,
604                                &request_msg,
605                                (amsg_data_t * *) &request,
606                                &msg_type,
607                                &msg_count,
608                                (amsg_option_t) 0)) == AMSG_OK) {
609	nsrv_assert(msg_type == MDT_BPORTID_REQUEST);
610	nsrv_assert(msg_count == 1);
611	nret = nsrv_free_bport_id_i(request->signature,
612				    request->port_id);
613	nsrv_send_simple_reply(request->reply_port_id,nret);
614	aret = amsg_free(request_msg);
615	nsrv_assert(aret == AMSG_OK);
616    }
617    nsrv_assert(aret == AMSG_NOMESSAGE);
618}
619
620
621static void
622nsrv_new_bdomain_id_s(port_id)
623    aport_id_t port_id;
624{
625    amsg_ret_t aret;
626    nsrv_ret_t nret;
627    amsg_t request_msg;
628    amsg_type_t msg_type;
629    amsg_count_t msg_count;
630    amsg_t reply_msg;
631    bdomain_id_request_t * request;
632    bdomain_id_reply_t * reply;
633    bdomain_id_t domain_id;
634
635    while ((aret = amsg_receive(port_id,
636                                &request_msg,
637                                (amsg_data_t * *) &request,
638                                &msg_type,
639                                &msg_count,
640                                (amsg_option_t) 0)) == AMSG_OK) {
641	nsrv_assert(msg_type == MDT_BDOMAINID_REQUEST);
642	nsrv_assert(msg_count == 1);
643	aret = amsg_alloc((amsg_size_t) sizeof(bdomain_id_reply_t),
644                          (amsg_data_t * *) &reply,
645			  &reply_msg);
646	if (aret != AMSG_OK)
647	    nsrv_panic("Not enough memory");
648	domain_id = reply->domain_id;
649	nret = nsrv_new_bdomain_id_i(request->signature,&domain_id);
650	reply->domain_id = domain_id;
651	reply->ret = nret;
652	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_BDOMAINID_REPLY);
653	aret = amsg_free(request_msg);
654	nsrv_assert(aret == AMSG_OK);
655    }
656    nsrv_assert(aret == AMSG_NOMESSAGE);
657}
658
659
660static void
661nsrv_free_bdomain_id_s(port_id)
662    aport_id_t port_id;
663{
664    amsg_ret_t aret;
665    nsrv_ret_t nret;
666    amsg_t request_msg;
667    amsg_type_t msg_type;
668    amsg_count_t msg_count;
669    bdomain_id_request_t * request;
670
671    while ((aret = amsg_receive(port_id,
672                                &request_msg,
673                                (amsg_data_t * *) &request,
674                                &msg_type,
675                                &msg_count,
676                                (amsg_option_t) 0)) == AMSG_OK) {
677	nsrv_assert(msg_type == MDT_BDOMAINID_REQUEST);
678	nsrv_assert(msg_count == 1);
679	nret = nsrv_free_bdomain_id_i(request->signature,
680				      request->domain_id);
681	nsrv_send_simple_reply(request->reply_port_id,nret);
682	aret = amsg_free(request_msg);
683	nsrv_assert(aret == AMSG_OK);
684    }
685    nsrv_assert(aret == AMSG_NOMESSAGE);
686}
687
688
689static void
690nsrv_version_s(port_id)
691    aport_id_t port_id;
692{
693    amsg_ret_t aret;
694    nsrv_ret_t nret;
695    amsg_t request_msg;
696    amsg_type_t msg_type;
697    amsg_count_t msg_count;
698    amsg_t reply_msg;
699    version_request_t * request;
700    version_reply_t * reply;
701
702    while ((aret = amsg_receive(port_id,
703                                &request_msg,
704                                (amsg_data_t * *) &request,
705                                &msg_type,
706                                &msg_count,
707                                (amsg_option_t) 0)) == AMSG_OK) {
708	nsrv_assert(msg_type == MDT_VERSION_REQUEST);
709	nsrv_assert(msg_count == 1);
710	aret = amsg_alloc((amsg_size_t) sizeof(version_reply_t),
711                          (amsg_data_t * *) &reply,
712			  &reply_msg);
713	if (aret != AMSG_OK)
714	    nsrv_panic("Not enough memory");
715	nret = nsrv_version_i(&reply->version);
716	reply->ret = nret;
717	nsrv_send_reply(request->reply_port_id,reply_msg,MDT_VERSION_REPLY);
718	aret = amsg_free(request_msg);
719	nsrv_assert(aret == AMSG_OK);
720    }
721    nsrv_assert(aret == AMSG_NOMESSAGE);
722}
723
724
725static void
726nsrv_exit_s()
727{
728    if (datafile && unlink(datafile)) {
729	fprintf(stderr,"nsrv: Lost track of file %s.\n",datafile);
730	fprintf(stderr,"If still existing, please remove it !\n");
731    }
732
733    fprintf(stderr, "nsrv: Name Server Died !\n");
734    nsrv_pds_exit();
735    exit(-1);
736}
737
738
739static void
740handle_signal(sig)
741    int sig;
742{
743    sigset_t sigset;
744
745    switch (sig) {
746#if defined(SIGUSR1)
747        case SIGUSR1 :
748#endif
749#if defined(SIGUSR2)
750        case SIGUSR2 :
751#endif
752#if defined(SIGIO)
753        case SIGIO :
754#if (defined(SIGPOLL) && (SIGIO != SIGPOLL))
755        case SIGPOLL :
756#endif
757#else
758#if defined(SIGPOLL)
759        case SIGPOLL :
760#endif
761#endif
762#if defined(SIGPIPE)
763        case SIGPIPE :
764#endif
765#if defined(SIGURG)
766        case SIGURG :
767#endif
768            /* unblock signal */
769            sigemptyset(&sigset);
770            sigaddset(&sigset,sig);
771            sigprocmask(SIG_UNBLOCK,&sigset,(sigset_t *) 0);
772	    if ( 0 ||
773#if defined(SIGUSR1)
774	        (sig == SIGUSR1) ||
775#endif
776#if defined(SIGUSR2)
777	 	(sig == SIGUSR2) ||
778#endif
779		 0
780				)
781               (void) bmsg_trigger(BMSG_INTRA_DOMAIN);
782	    else
783               (void) bmsg_trigger(BMSG_INTRA_DOMAIN | BMSG_INTER_DOMAIN);
784            break;
785#ifdef SIGINT
786	case SIGINT :
787	    nsrv_exit_s();
788            break;
789#endif /* SIGINT */
790#ifdef SIGTERM
791	case SIGTERM :
792	    nsrv_exit_s();
793            break;
794#endif /* SIGTERM */
795#ifdef SIGILL
796	case SIGILL :
797    	    fprintf(stderr, "nsrv: Illegal instruction !\n");
798	    nsrv_exit_s();
799            break;
800#endif /* SIGILL */
801#ifdef SIGFPE
802	case SIGFPE :
803    	    fprintf(stderr, "nsrv: Arithmetic exception !\n");
804	    nsrv_exit_s();
805            break;
806#endif /* SIGFPE */
807#ifdef SIGSEGV
808	case SIGSEGV :
809    	    fprintf(stderr, "nsrv: Segmentation violation !\n");
810	    nsrv_exit_s();
811            break;
812#endif /* SIGSEGV */
813#ifdef SIGBUS
814	case SIGBUS :
815    	    fprintf(stderr, "nsrv: Bus error !\n");
816	    nsrv_exit_s();
817            break;
818#endif /* SIGBUS */
819#ifdef SIGXCPU
820	case SIGXCPU :
821    	    fprintf(stderr, "nsrv: CPU time limit exceeded !\n");
822	    nsrv_exit_s();
823            break;
824#endif /* SIGXCPU */
825#ifdef SIGXFSZ
826	case SIGXFSZ :
827    	    fprintf(stderr, "nsrv: File size limit exceeded !\n");
828	    nsrv_exit_s();
829            break;
830#endif /* SIGXFSZ */
831#ifdef SIGWINCH
832	case SIGWINCH :
833            break;
834#endif /* SIGWINCH */
835        default :
836    	    fprintf(stderr, "nsrv: Catched unexpected signal %d !\n", sig);
837	    nsrv_exit_s();
838            break;
839    }
840}
841
842
843static void
844signal_handler(sig)
845    int sig;
846{
847    if ((InterruptsDisabled) && (0 ||
848#if defined(SIGIO)
849				 (sig == SIGIO) ||
850#if (defined(SIGPOLL) && (SIGIO != SIGPOLL))
851				 (sig == SIGPOLL) ||
852#endif
853#else
854#if defined(SIGPOLL)
855				 (sig == SIGPOLL) ||
856#endif
857#endif
858#if defined(SIGPIPE)
859				 (sig == SIGPIPE) ||
860#endif
861#if defined(SIGURG)
862				 (sig == SIGURG) ||
863#endif
864#if defined(SIGUSR1)
865				 (sig == SIGUSR1) ||
866#endif
867#if defined(SIGUSR2)
868				 (sig == SIGUSR2) ||
869#endif
870				 0
871						 )) {
872        Set_Interrupts_Pending();
873    }
874    else {
875        handle_signal(sig);
876    }
877}
878
879
880static void
881delayed_signal_handler()
882{
883    int errno_main;
884
885    /* save errno */
886    errno_main = errno;
887
888    Clr_Interrupts_Pending();
889#if defined(SIGIO)
890    handle_signal(SIGIO);
891#else
892    nsrv_assert_always();
893#endif
894
895    /* restore errno */
896    errno = errno_main;
897}
898
899
900static void
901install_sighandler(sig)
902    int sig;
903{
904    struct sigaction act;
905
906    act.sa_handler = signal_handler;
907    sigemptyset(&act.sa_mask);
908    act.sa_flags = 0;
909
910    (void) sigaction(sig,
911                     &act,
912                     (struct sigaction *) 0);
913}
914
915
916static void
917install_sighandlers()
918{
919    int sig;
920
921    for (sig=0; sig<NSIG; sig++) {
922	if (1
923#if defined(SIGTSTP)
924	    && (sig != SIGTSTP)
925#endif
926#if defined(SIGCONT)
927	    && (sig != SIGCONT)
928#endif
929#if defined(SIGCHLD)
930	    && (sig != SIGCHLD)
931#endif
932			       )
933	    install_sighandler(sig);
934    }
935}
936
937
938static void
939usage(program_name)
940    char *program_name;
941{
942    fprintf(stderr,
943            "\nUsage: %s [-v] [-s port_number] [-p path] [-n[shm]] [-npds] [-h]\n",
944            program_name);
945
946    fprintf(stderr, "       -v: verbose \n");
947    fprintf(stderr, "       -s port_number: port number \n");
948    fprintf(stderr, "       -p path: path name \n");
949    fprintf(stderr, "       -nshm: disable shared memory interaction \n");
950    fprintf(stderr, "       -npds: disable PDS interaction \n");
951    fprintf(stderr, "       -h: help \n");
952    fprintf(stderr, "\n");
953    exit(0);
954}
955
956
957static void
958args(argc, argv)
959    int argc;
960    char *argv[];
961{
962    int i;
963
964    for (i = 1; i < argc; i++) {
965        if (argv[i][0] == '-')
966            switch (argv[i][1]) {
967		case 'h': /* help */
968                    usage(argv[0]); /* exit with usage message */
969                    break;
970		case 'v': /* verbose */
971		    nsrv_verbose = 1;
972		    break;
973		case 'n':
974		    if ((strcmp(argv[i],"-n") == 0) ||
975		        (strcmp(argv[i],"-nshm") == 0)) {
976			/* disable shared memory interaction */
977			nsrv_shared = 0;
978		    }
979		    else if (strcmp(argv[i],"-npds") == 0) {
980			/* disable PDS interaction */
981			nsrv_pds = 0;
982		    }
983		    else
984                        usage(argv[0]); /* exit with usage message */
985                    break;
986		case 'p': /* path */
987		    if (++i >= argc) {
988                        fprintf(stderr,
989                                "\npath parameter expected !\n");
990                        usage(argv[0]);
991			break;
992                    }
993		    else
994		        nsrv_path = argv[i];
995		    break;
996		case 's': /* port number */
997		    if (++i >= argc) {
998                        fprintf(stderr,
999                                "\nport number parameter expected !\n");
1000                        usage(argv[0]);
1001			break;
1002                    }
1003		    else {
1004			int port_number;
1005		        port_number = atoi(argv[i]);
1006			if ((port_number < 1024) ||
1007			    (port_number > 0xffff)) {
1008                            fprintf(stderr,
1009                                    "\n Invalid port number !\n");
1010                            usage(argv[0]);
1011			    break;
1012			}
1013			else
1014			    nsrv_port_number = port_number;
1015		    }
1016		    break;
1017		default :
1018		    usage(argv[0]); /* exit with usage message */
1019		    break;
1020	}
1021    }
1022}
1023
1024
1025static int
1026nsrv_path_ok(hostname)
1027    char * hostname;
1028{
1029    char filename[NSRV_FILENAMELEN_MAX+1];
1030    int fd;
1031
1032    if ((int)
1033	(strlen(nsrv_path) + 1 +
1034	 strlen(NSRV_DATAFILE) + 1 +
1035	 strlen(hostname) + 1 + 6) > NSRV_FILENAMELEN_MAX) {
1036	fprintf(stderr,
1037		"nsrv: Implementation limit reached at \"%s:%d\" !\n",
1038		__FILE__, __LINE__ );
1039        fprintf(stderr,
1040		"      Consult an expert !\n");
1041	exit(-1);
1042    }
1043
1044    (void) sprintf(filename, "%s/%s.%s.%d",
1045		   nsrv_path,NSRV_DATAFILE,hostname,getpid() % 1000000 );
1046
1047    fd = open(filename,O_RDWR|O_CREAT,0700);
1048    if (fd == -1)
1049	return(0);
1050
1051    (void) unlink(filename);
1052    return(~0);
1053}
1054
1055
1056static void
1057nsrv_bmsg_init(nsrv_port)
1058    bport_t * nsrv_port;
1059{
1060    bdomain_t nsrv_domain;
1061    bmsg_ret_t bret;
1062    nsrv_ret_t nret;
1063    int ret;
1064
1065    /* initialise b-layer of message passing system */
1066    nsrv_domain.bdomain_id = NSRV_BDOMAIN_ID;
1067    strcpy(nsrv_domain.bdomain_file,msgfile);
1068    if (!pds_mem_base())
1069    	nsrv_domain.bdomain_start = (bmem_address_t) 0;
1070    else
1071    	nsrv_domain.bdomain_start = (bmem_address_t)
1072				    (nsrv_data_start + NSRV_DATA_AREA_SIZE);
1073    nsrv_domain.bdomain_size = NSRV_MSG_AREA_SIZE;
1074    bret = bmsg_init(NSRV_BPORT_ID,&nsrv_domain, BDOMAIN_CREATE);
1075    if (bret == BMSG_OK) {
1076        if (bport_port(NSRV_BPORT_ID,nsrv_port) != BMSG_OK) {
1077    	    fprintf(stderr,"nsrv: panic : bport_port() !!! \n");
1078            bmsg_exit();
1079            nsrv_exit_i();
1080            exit(-1);
1081	}
1082        /* adjust access restrictions of msgfile */
1083        ret = chmod(msgfile,
1084                    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
1085        if (ret) {
1086    	    fprintf(stderr,"nsrv: panic : chmod() !!! \n");
1087            bmsg_exit();
1088            nsrv_exit_i();
1089            exit(-1);
1090        }
1091    }
1092    else {
1093    	fprintf(stderr,"nsrv: panic : bmsg_init() !!! \n");
1094        bmsg_exit();
1095        nsrv_exit_i();
1096        exit(-1);
1097    }
1098    nsrv_msg_start = (char *) nsrv_domain.bdomain_start;
1099
1100    nret = nsrv_bdomain_register_i(NSRV_KEY,NSRV_DOMAIN_NAME,NSRV_SIGNATURE,
1101				   &nsrv_domain);
1102    if (nret == NSRV_OK)
1103	nret = nsrv_bport_register_i(NSRV_KEY,NSRV_PORT_NAME,NSRV_SIGNATURE,
1104				     nsrv_port);
1105    if (nret != NSRV_OK) {
1106    	fprintf(stderr,"nsrv: panic : nsrv_bport_register_i() !!! \n");
1107	bmsg_exit();
1108	nsrv_exit_i();
1109	exit(-1);
1110    }
1111}
1112
1113
1114static void
1115nsrv_amsg_init()
1116{
1117    amsg_ret_t aret;
1118    void (* nsrv_notify [NSRV_NOF_APORTS]) ();
1119    aport_id_t nsrv_aport_id[NSRV_NOF_APORTS];
1120
1121    /* install amsg notification procedures */
1122    nsrv_notify[NSRV_APORT_REGISTER] = nsrv_aport_register_s;
1123    nsrv_notify[NSRV_APORT_DEREGISTER] = nsrv_aport_deregister_s;
1124    nsrv_notify[NSRV_APORT_LOOK_UP] = nsrv_aport_look_up_s;
1125    nsrv_notify[NSRV_BPORT_REGISTER] = nsrv_bport_register_s;
1126    nsrv_notify[NSRV_BPORT_DEREGISTER] = nsrv_bport_deregister_s;
1127    nsrv_notify[NSRV_BPORT_LOOK_UP] = nsrv_bport_look_up_s;
1128    nsrv_notify[NSRV_BDOMAIN_REGISTER] = nsrv_bdomain_register_s;
1129    nsrv_notify[NSRV_BDOMAIN_DEREGISTER] = nsrv_bdomain_deregister_s;
1130    nsrv_notify[NSRV_BDOMAIN_LOOK_UP] = nsrv_bdomain_look_up_s;
1131    nsrv_notify[NSRV_NEW_BPORT_ID] = nsrv_new_bport_id_s;
1132    nsrv_notify[NSRV_FREE_BPORT_ID] = nsrv_free_bport_id_s;
1133    nsrv_notify[NSRV_NEW_BDOMAIN_ID] = nsrv_new_bdomain_id_s;
1134    nsrv_notify[NSRV_FREE_BDOMAIN_ID] = nsrv_free_bdomain_id_s;
1135    nsrv_notify[NSRV_VERSION] = nsrv_version_s;
1136
1137    /* initialise a-layer of message passing system */
1138    aret = amsg_init(NSRV_NOF_APORTS,nsrv_notify,nsrv_aport_id,0);
1139
1140    if (aret == AMSG_OK)
1141        aret = aport_set_option(nsrv_aport_id[NSRV_APORT_REGISTER],
1142			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1143    if (aret == AMSG_OK)
1144        aret = aport_set_option(nsrv_aport_id[NSRV_APORT_DEREGISTER],
1145			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1146    if (aret == AMSG_OK)
1147        aret = aport_set_option(nsrv_aport_id[NSRV_BPORT_REGISTER],
1148			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1149    if (aret == AMSG_OK)
1150        aret = aport_set_option(nsrv_aport_id[NSRV_BPORT_DEREGISTER],
1151			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1152    if (aret == AMSG_OK)
1153        aret = aport_set_option(nsrv_aport_id[NSRV_BDOMAIN_REGISTER],
1154			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1155    if (aret == AMSG_OK)
1156        aret = aport_set_option(nsrv_aport_id[NSRV_BDOMAIN_DEREGISTER],
1157			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1158    if (aret == AMSG_OK)
1159        aret = aport_set_option(nsrv_aport_id[NSRV_NEW_BPORT_ID],
1160			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1161    if (aret == AMSG_OK)
1162        aret = aport_set_option(nsrv_aport_id[NSRV_FREE_BPORT_ID],
1163			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1164    if (aret == AMSG_OK)
1165        aret = aport_set_option(nsrv_aport_id[NSRV_NEW_BDOMAIN_ID],
1166			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1167    if (aret == AMSG_OK)
1168        aret = aport_set_option(nsrv_aport_id[NSRV_FREE_BDOMAIN_ID],
1169			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1170    if (aret == AMSG_OK)
1171        aret = aport_set_option(nsrv_aport_id[NSRV_VERSION],
1172			        APORT_NOTIFY_LEVEL,(aport_optval_t) 1);
1173
1174    if (aret != AMSG_OK) {
1175        bmsg_exit();
1176        nsrv_exit_i();
1177        exit(-1);
1178    }
1179}
1180
1181
1182static void
1183nsrv_server_loop()
1184{
1185    bport_id_t bport_id;
1186    bdomain_id_t bdomain_id;
1187    bdomain_t bdomain;
1188    bport_t bport;
1189    aport_t aport;
1190    nsrv_name_t signature;
1191    nsrv_name_t key;
1192    nsrv_name_t name;
1193    nsrv_version_t version;
1194    nsrv_mode_t mode;
1195    nsrv_ret_t nret;
1196    char * nsrv_signature;
1197    char * nsrv_key;
1198    char * nsrv_name;
1199
1200    sigset_t sigset_old;
1201    sigset_t sigset;
1202
1203    int nsrv_msg_sock;
1204    fd_set fdset;
1205    long fdset_size;
1206    XDR xdrs;
1207    int ret;
1208
1209    pds_uint32 reply_size;
1210    pds_uint32 request_size;
1211    pds_uint32 nsrv_request[NSRV_BUF_SIZE];
1212    pds_uint32 nsrv_reply[NSRV_BUF_SIZE];
1213    nsrv_number_t nsrv_request_number;
1214    int errno_accept;
1215
1216    fdset_size = sysconf(_SC_OPEN_MAX);
1217
1218    nsrv_signature = signature;
1219    nsrv_key = key;
1220    nsrv_name = name;
1221
1222    /* disable delivery of PDS related signals */
1223    sigemptyset(&sigset);
1224#if defined(SIGIO)
1225    sigaddset(&sigset,SIGIO);
1226#if (defined(SIGPOLL) && (SIGIO != SIGPOLL))
1227    sigaddset(&sigset,SIGPOLL);
1228#endif
1229#else
1230#if defined(SIGPOLL)
1231    sigaddset(&sigset,SIGPOLL);
1232#endif
1233#endif
1234#if defined(SIGURG)
1235    sigaddset(&sigset,SIGURG);
1236#endif
1237#if defined(SIGPIPE)
1238    sigaddset(&sigset,SIGPIPE);
1239#endif
1240#if defined(SIGUSR1)
1241    sigaddset(&sigset,SIGUSR1);
1242#endif
1243#if defined(SIGUSR2)
1244    sigaddset(&sigset,SIGUSR2);
1245#endif
1246    sigprocmask(SIG_BLOCK,&sigset,&sigset_old);
1247    Disable_Int();
1248
1249    do {
1250
1251	do {
1252
1253	    /*
1254	    ** We do not allow PDS based nsrv request to
1255	    ** interrupt the handling of a socket based
1256	    ** request. This is done mainly because on
1257	    ** some platforms accept() and possibly some
1258	    ** other system calls and socket related
1259	    ** primitives are not fully interrupt safe.
1260	    */
1261
1262            /* reenable PDS related signal delivery */
1263	    Enable_Int();
1264            sigprocmask(SIG_SETMASK,&sigset_old,(sigset_t *) 0);
1265
1266            do {
1267                FD_ZERO(&fdset);
1268                FD_SET(nsrv_ctrl_sock,&fdset);
1269
1270                ret = select(fdset_size,
1271                             &fdset,
1272                             (fd_set *) 0,
1273                             (fd_set *) 0,
1274                             (struct timeval *) 0);
1275            } while ((!ret) || ((ret == -1) &&
1276			        ((errno == EINTR) || (errno == EAGAIN))));
1277	    if (ret == -1)
1278                nsrv_perror_and_assert_always("select()");
1279            nsrv_assert(ret == 1);
1280
1281            /* disable PDS related signal delivery */
1282            sigemptyset(&sigset);
1283#if defined(SIGIO)
1284            sigaddset(&sigset,SIGIO);
1285#if (defined(SIGPOLL) && (SIGIO != SIGPOLL))
1286            sigaddset(&sigset,SIGPOLL);
1287#endif
1288#else
1289#if defined(SIGPOLL)
1290            sigaddset(&sigset,SIGPOLL);
1291#endif
1292#endif
1293#if defined(SIGURG)
1294            sigaddset(&sigset,SIGURG);
1295#endif
1296#if defined(SIGPIPE)
1297            sigaddset(&sigset,SIGPIPE);
1298#endif
1299#if defined(SIGUSR1)
1300            sigaddset(&sigset,SIGUSR1);
1301#endif
1302#if defined(SIGUSR2)
1303            sigaddset(&sigset,SIGUSR2);
1304#endif
1305            sigprocmask(SIG_BLOCK,&sigset,&sigset_old);
1306	    Disable_Int();
1307
1308	    nsrv_msg_sock = accept(nsrv_ctrl_sock,
1309                                   (struct sockaddr *) 0,
1310                                   (int *) 0);
1311	    errno_accept = errno;
1312
1313	    if (nsrv_msg_sock == -1) { /* accept() failed */
1314	        switch (errno_accept) {
1315                    case ENOMEM :
1316            	        nsrv_panic("Not enough memory");
1317		        break;
1318                    case ENOSR :
1319                    case ENOBUFS :
1320                    case EMFILE :
1321                    case ENFILE :
1322	    	        nsrv_panic("Not enough resources");
1323		        break;
1324                    case EINTR :
1325                        break;
1326                    default :
1327        		nsrv_perror_and_assert_always("accept()");
1328                        break;
1329	        }
1330	    }
1331	}
1332	while ((nsrv_msg_sock == -1) && (errno_accept == EINTR));
1333
1334	nsrv_sock_linger(nsrv_msg_sock);
1335	nsrv_sock_nodelay(nsrv_msg_sock);
1336
1337	nret = nsrv_receive_sock(nsrv_msg_sock,(char *) nsrv_request,&request_size);
1338	if (nret != NSRV_OK) {
1339	    nsrv_close_sock(nsrv_msg_sock);
1340	    if (nret != NSRV_WARN)
1341	        nsrv_warn("Lost request");
1342	    continue;
1343	}
1344
1345	xdrmem_create(&xdrs,(const caddr_t) nsrv_request,
1346                      (const u_int) request_size,
1347                      XDR_DECODE);
1348
1349	/* unpack request number */
1350	if (!(xdr_nsrv_number(&xdrs,&nsrv_request_number))) {
1351	    xdr_destroy(&xdrs);
1352	    nsrv_close_sock(nsrv_msg_sock);
1353	    nsrv_warn("Interface violation");
1354	    continue;
1355	}
1356
1357	switch (nsrv_request_number) {
1358
1359	    case NSRV_APORT_REGISTER :
1360	    case NSRV_BPORT_REGISTER :
1361	    case NSRV_BDOMAIN_REGISTER :
1362	    case NSRV_APORT_DEREGISTER :
1363	    case NSRV_BPORT_DEREGISTER :
1364	    case NSRV_BDOMAIN_DEREGISTER :
1365
1366		/* unpack key, name and signature */
1367		if (!(xdr_nsrv_name(&xdrs,&nsrv_key) &&
1368                     xdr_nsrv_name(&xdrs,&nsrv_name) &&
1369                     xdr_nsrv_name(&xdrs,&nsrv_signature))) {
1370		    nret = NSRV_XDR_DECODE;
1371		    break;
1372		}
1373
1374		/* unpack data to be registered */
1375		switch (nsrv_request_number) {
1376	    	    case NSRV_APORT_REGISTER :
1377		        if (!(xdr_aport(&xdrs,&aport)))
1378			    nret = NSRV_XDR_DECODE;
1379			break;
1380	    	    case NSRV_BPORT_REGISTER :
1381		        if (!(xdr_bport(&xdrs,&bport)))
1382			    nret = NSRV_XDR_DECODE;
1383			break;
1384	    	    case NSRV_BDOMAIN_REGISTER :
1385		        if (!(xdr_bdomain(&xdrs,&bdomain)))
1386			    nret = NSRV_XDR_DECODE;
1387			break;
1388		    default :
1389			break;
1390		}
1391		if (nret == NSRV_XDR_DECODE)
1392		    break;
1393
1394		/* process request */
1395		switch (nsrv_request_number) {
1396	    	    case NSRV_APORT_REGISTER :
1397		        nret = nsrv_aport_register_i(key,name,signature,&aport);
1398			break;
1399	    	    case NSRV_BPORT_REGISTER :
1400		    	nret = nsrv_bport_register_i(key,name,signature,&bport);
1401			break;
1402	    	    case NSRV_BDOMAIN_REGISTER :
1403			nret = nsrv_bdomain_register_i(key,name,signature,&bdomain);
1404			break;
1405	    	    case NSRV_APORT_DEREGISTER :
1406			nret = nsrv_aport_deregister_i(key,name,signature);
1407			break;
1408	    	    case NSRV_BPORT_DEREGISTER :
1409			nret = nsrv_bport_deregister_i(key,name,signature);
1410			break;
1411	    	    case NSRV_BDOMAIN_DEREGISTER :
1412			nret = nsrv_bdomain_deregister_i(key,name,signature);
1413			break;
1414		    default :
1415			break;
1416		}
1417
1418		/* pack nret */
1419		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1420                      	      (const u_int) 4*NSRV_BUF_SIZE,
1421                      	      XDR_ENCODE);
1422		if (!(xdr_nsrv_ret(&xdrs,&nret)))
1423		    nret = NSRV_XDR_ENCODE;
1424
1425		break;
1426
1427	    case NSRV_APORT_LOOK_UP :
1428	    case NSRV_BPORT_LOOK_UP :
1429    	    case NSRV_BDOMAIN_LOOK_UP :
1430
1431		/* unpack key and name */
1432		if (!(xdr_nsrv_name(&xdrs,&nsrv_key) &&
1433                     xdr_nsrv_name(&xdrs,&nsrv_name))) {
1434		    nret = NSRV_XDR_DECODE;
1435		    break;
1436		}
1437
1438		/* process request */
1439		switch (nsrv_request_number) {
1440	    	    case NSRV_APORT_LOOK_UP :
1441			nret = nsrv_aport_look_up_i(key,name,&aport);
1442			break;
1443	    	    case NSRV_BPORT_LOOK_UP :
1444			nret = nsrv_bport_look_up_i(key,name,&bport);
1445			break;
1446    	    	    case NSRV_BDOMAIN_LOOK_UP :
1447			nret = nsrv_bdomain_look_up_i(key,name,&bdomain);
1448			break;
1449		    default :
1450			break;
1451		}
1452
1453		/* pack nret */
1454		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1455                      	      (const u_int) 4*NSRV_BUF_SIZE,
1456                      	      XDR_ENCODE);
1457		if (!(xdr_nsrv_ret(&xdrs,&nret))) {
1458		    nret = NSRV_XDR_ENCODE;
1459		    break;
1460		}
1461
1462		/* pack data that has been looked up */
1463		if (nret != NSRV_OK)
1464		    break;
1465		switch (nsrv_request_number) {
1466	    	    case NSRV_APORT_LOOK_UP :
1467			if (!(xdr_aport(&xdrs,&aport)))
1468			    nret = NSRV_XDR_ENCODE;
1469			break;
1470	    	    case NSRV_BPORT_LOOK_UP :
1471			if (!(xdr_bport(&xdrs,&bport)))
1472			    nret = NSRV_XDR_ENCODE;
1473			break;
1474    	    	    case NSRV_BDOMAIN_LOOK_UP :
1475			if (!(xdr_bdomain(&xdrs,&bdomain)))
1476			    nret = NSRV_XDR_ENCODE;
1477			break;
1478		    default :
1479			break;
1480		}
1481
1482		break;
1483
1484	    case NSRV_NEW_BPORT_ID :
1485	    case NSRV_FREE_BPORT_ID :
1486	    case NSRV_NEW_BDOMAIN_ID :
1487	    case NSRV_FREE_BDOMAIN_ID :
1488
1489		/* unpack signature */
1490		if (!(xdr_nsrv_name(&xdrs,&nsrv_signature))) {
1491		    nret = NSRV_XDR_DECODE;
1492		    break;
1493		}
1494
1495		/* unpack data */
1496		switch (nsrv_request_number) {
1497	    	    case NSRV_NEW_BPORT_ID :
1498		    case NSRV_FREE_BPORT_ID :
1499		        if (!(xdr_bport_id(&xdrs,&bport_id)))
1500			    nret = NSRV_XDR_DECODE;
1501			break;
1502	    	    case NSRV_NEW_BDOMAIN_ID :
1503	    	    case NSRV_FREE_BDOMAIN_ID :
1504		        if (!(xdr_bdomain_id(&xdrs,&bdomain_id)))
1505			    nret = NSRV_XDR_DECODE;
1506			break;
1507		    default :
1508			break;
1509		}
1510		if (nret == NSRV_XDR_DECODE)
1511		    break;
1512
1513		/* process request */
1514		switch (nsrv_request_number) {
1515	    	    case NSRV_NEW_BPORT_ID :
1516			nret = nsrv_new_bport_id_i(signature,&bport_id);
1517			break;
1518	    	    case NSRV_FREE_BPORT_ID :
1519			nret = nsrv_free_bport_id_i(signature,bport_id);
1520			break;
1521	    	    case NSRV_NEW_BDOMAIN_ID :
1522			nret = nsrv_new_bdomain_id_i(signature,&bdomain_id);
1523			break;
1524	    	    case NSRV_FREE_BDOMAIN_ID :
1525			nret = nsrv_free_bdomain_id_i(signature,bdomain_id);
1526			break;
1527		    default :
1528			break;
1529		}
1530
1531		/* pack nret */
1532		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1533                      	      (const u_int) 4*NSRV_BUF_SIZE,
1534                      	      XDR_ENCODE);
1535		if (!(xdr_nsrv_ret(&xdrs,&nret))) {
1536		    nret = NSRV_XDR_ENCODE;
1537		    break;
1538		}
1539
1540		/* pack identifier */
1541		if (nret != NSRV_OK)
1542		    break;
1543		switch (nsrv_request_number) {
1544	    	    case NSRV_NEW_BPORT_ID :
1545			if (!(xdr_bport_id(&xdrs,&bport_id)))
1546			    nret = NSRV_XDR_ENCODE;
1547			break;
1548	    	    case NSRV_NEW_BDOMAIN_ID :
1549			if (!(xdr_bdomain_id(&xdrs,&bdomain_id)))
1550			    nret = NSRV_XDR_ENCODE;
1551			break;
1552		    default :
1553			break;
1554		}
1555
1556		break;
1557
1558	    case NSRV_VERSION :
1559
1560		nret = nsrv_version_i(&version);
1561
1562		/* pack nret */
1563		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1564                      	      (const u_int) 4*NSRV_BUF_SIZE,
1565                      	      XDR_ENCODE);
1566		if (!(xdr_nsrv_ret(&xdrs,&nret))) {
1567		    nret = NSRV_XDR_ENCODE;
1568		    break;
1569		}
1570
1571		/* pack version */
1572		if (nret != NSRV_OK)
1573		    break;
1574		if (!(xdr_nsrv_version(&xdrs,&version)))
1575		    nret = NSRV_XDR_ENCODE;
1576
1577		break;
1578
1579	    case NSRV_PING :
1580
1581		nret = NSRV_OK;
1582
1583		/* pack nret */
1584		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1585                      	      (const u_int) 4*NSRV_BUF_SIZE,
1586                      	      XDR_ENCODE);
1587		if (!(xdr_nsrv_ret(&xdrs,&nret)))
1588		    nret = NSRV_XDR_ENCODE;
1589
1590		break;
1591
1592	    case NSRV_GET_MODE :
1593
1594		nret = NSRV_OK;
1595
1596		/* pack nret */
1597		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1598                      	      (const u_int) 4*NSRV_BUF_SIZE,
1599                      	      XDR_ENCODE);
1600		if (!(xdr_nsrv_ret(&xdrs,&nret)))
1601		    nret = NSRV_XDR_ENCODE;
1602
1603		/* pack mode */
1604		if (nret != NSRV_OK)
1605		    break;
1606		mode = 0;
1607		if (nsrv_shared)
1608		    mode = NSRV_SHM;
1609		if (nsrv_pds)
1610		    mode |= NSRV_PDS;
1611		if (!(xdr_nsrv_mode(&xdrs,&mode)))
1612		    nret = NSRV_XDR_ENCODE;
1613
1614		break;
1615
1616	    case NSRV_GET_PATH :
1617
1618		nret = NSRV_OK;
1619
1620		/* pack nret */
1621		xdrmem_create(&xdrs,(const caddr_t) nsrv_reply,
1622                      	      (const u_int) 4*NSRV_BUF_SIZE,
1623                      	      XDR_ENCODE);
1624		if (!(xdr_nsrv_ret(&xdrs,&nret)))
1625		    nret = NSRV_XDR_ENCODE;
1626
1627		/* pack path */
1628		if (nret != NSRV_OK)
1629		    break;
1630		if (!(xdr_string(&xdrs,&nsrv_path,NSRV_FILENAMELEN_MAX)))
1631		    nret = NSRV_XDR_ENCODE;
1632
1633		break;
1634
1635	    default :
1636		nret = NSRV_XDR_DECODE;
1637		break;
1638	}
1639
1640       	/* send reply */
1641	if ((nret != NSRV_XDR_DECODE) && (nret != NSRV_XDR_ENCODE)) {
1642	    reply_size = (pds_uint32) xdr_getpos(&xdrs);
1643	    nret = nsrv_send_sock(nsrv_msg_sock,(char *) nsrv_reply,
1644				  reply_size);
1645	    if (nret != NSRV_OK)
1646	        nsrv_warn("Lost reply");
1647	}
1648
1649	xdr_destroy(&xdrs);
1650        nsrv_close_sock(nsrv_msg_sock);
1651
1652	if (nret == NSRV_XDR_DECODE)
1653	    nsrv_warn("Interface violation");
1654	else if (nret == NSRV_XDR_ENCODE)
1655	    nsrv_panic("XDR encoding error");
1656
1657    } while (1);
1658}
1659
1660
1661int
1662main(argc, argv)
1663    int argc;
1664    char *argv[];
1665{
1666    struct sockaddr_in ctrl_sock_name;
1667    char hostname[MAXHOSTNAMELEN+1];
1668    unsigned property;
1669
1670    int on = 1;
1671    int ret;
1672
1673    /* disable interrupts */
1674    pds_disable_int();
1675
1676    /* install signal handlers */
1677    install_sighandlers();
1678    irq_lock_init(delayed_signal_handler);
1679
1680    /* get arguments */
1681    args(argc, argv);
1682
1683    /* get hostname */
1684    if (gethostname(hostname,MAXHOSTNAMELEN) != 0)
1685	nsrv_perror_and_assert_always("gethostname()");
1686
1687    /* ping existing name server */
1688    if (nsrv_ping(hostname,&nsrv_port_number) == NSRV_OK) {
1689        fprintf(stderr, "nsrv: Name server already up and running !\n");
1690	exit(0);
1691    }
1692
1693    /* initialise nsrv_port_number */
1694    nsrv_init_port_number(&nsrv_port_number,&property);
1695
1696    /* initialise nsrv_path */
1697    if (!nsrv_path) /* use environment variable NSRV_PATH */
1698        nsrv_path = getenv(NSRV_PATH);
1699
1700    if (!nsrv_path) { /* try current working directory */
1701	nsrv_path = getcwd((char *) 0, NSRV_FILENAMELEN_MAX+2);
1702	if (!nsrv_path || !nsrv_path_ok(hostname)) { /* try /tmp */
1703	    nsrv_path = (char *) malloc(strlen("/tmp")+1);
1704	    if (!nsrv_path) {
1705                fprintf(stderr, "nsrv: Not enough memory !\n");
1706	        exit(-1);
1707	    }
1708	    strcpy(nsrv_path,"/tmp");
1709	}
1710    }
1711
1712    if (!nsrv_path_ok(hostname)) {
1713	fprintf(stderr, "nsrv: Problems accessing %s ! \n",
1714	        nsrv_path);
1715	fprintf(stderr,
1716		"      Select another path by, for example, (re)defining\n");
1717	fprintf(stderr,
1718		"      the environment variable %s.\n", NSRV_PATH);
1719	exit(-1);
1720    }
1721
1722    /* create control socket */
1723    do {
1724        nsrv_ctrl_sock = socket(PF_INET,SOCK_STREAM,0);
1725    }
1726    while ((nsrv_ctrl_sock == -1) && (errno == EINTR));
1727    if (nsrv_ctrl_sock == -1) {
1728        switch (errno) {
1729            case EMFILE :
1730            case ENFILE :
1731            case ENOBUFS :
1732        	fprintf(stderr, "nsrv: Not enough resources !\n");
1733		exit(-1);
1734            default :
1735		nsrv_perror_and_assert_always("socket()");
1736        }
1737    }
1738    /* disable the default delay of TCP data transmission */
1739    if (setsockopt(nsrv_ctrl_sock,IPPROTO_TCP,TCP_NODELAY,
1740		   (char *) &on,sizeof(on)) == -1)
1741	nsrv_perror_and_assert_always("setsockopt()");
1742
1743    /* name control socket */
1744    ctrl_sock_name.sin_family = AF_INET;
1745    ctrl_sock_name.sin_addr.s_addr = htonl(INADDR_ANY);
1746    do {
1747        ctrl_sock_name.sin_port = htons((u_short) nsrv_port_number);
1748        if (bind(nsrv_ctrl_sock,
1749                 (struct sockaddr *) &ctrl_sock_name,
1750                 sizeof(ctrl_sock_name)) < 0) {
1751	    switch (errno) {
1752	        case EACCES :
1753	        case EADDRINUSE :
1754	        case EADDRNOTAVAIL :
1755		    if ((property == NSRV_DEFAULT) &&
1756			(nsrv_port_number >= NSRV_PORT_DEFAULT) &&
1757			(nsrv_port_number < (NSRV_PORT_DEFAULT + NSRV_DEFAULT_PORTS - 1))) {
1758			nsrv_port_number++;
1759			break;
1760		    }
1761		    fprintf(stderr,
1762                            "nsrv: Failed to start name server !\n");
1763		    if (property == NSRV_DEFAULT) {
1764        	        fprintf(stderr,
1765			        "      Default ports not available.\n");
1766		        fprintf(stderr,
1767                                "      Select another port by, for example, (re)defining\n");
1768		        fprintf(stderr,
1769                                "             the environment variable %s.\n", NSRV_PORT);
1770		    }
1771		    else {
1772        	        fprintf(stderr,
1773			        "      Port %d not available.\n",
1774			        nsrv_port_number);
1775		        fprintf(stderr,
1776                                "      Select another port by, for example, (re)defining\n");
1777		        fprintf(stderr,
1778                                "             the environment variable %s.\n", NSRV_PORT);
1779		    }
1780		    exit(-1);
1781	        default :
1782	            nsrv_perror_and_assert_always("bind()");
1783	    }
1784        }
1785	else
1786	    break;
1787    } while (1);
1788
1789    datafile = malloc(strlen(nsrv_path) + 1 +
1790		      strlen(NSRV_DATAFILE) + 1 +
1791		      strlen(hostname) + 1 + 10);
1792    if (!datafile) {
1793        fprintf(stderr, "nsrv: Not enough memory !\n");
1794	exit(-1);
1795    }
1796    sprintf(datafile,"%s/%s.%s.%d",
1797	    nsrv_path,NSRV_DATAFILE,hostname,nsrv_port_number % 1000000);
1798
1799    msgfile = malloc(strlen(nsrv_path) + 1 +
1800		     strlen(NSRV_MSGFILE) + 1 +
1801		     strlen(hostname) + 1 + 10);
1802    if (!msgfile) {
1803        fprintf(stderr, "nsrv: Not enough memory !\n");
1804	exit(-1);
1805    }
1806    sprintf(msgfile, "%s/%s.%s.%d",
1807	    nsrv_path,NSRV_MSGFILE,hostname,nsrv_port_number % 1000000);
1808
1809    /* check existence of nsrv files */
1810    if (!access(msgfile,F_OK) || !access(datafile,F_OK)) {
1811	fprintf(stderr,
1812                "nsrv: Failed to start name server !\n");
1813	fprintf(stderr,
1814                "      Before retrying, remove the following file(s):\n");
1815        if (!access(msgfile,F_OK))
1816	    fprintf(stderr, "          %s\n",msgfile);
1817        if (!access(datafile,F_OK))
1818	    fprintf(stderr, "          %s\n",datafile);
1819        exit(-1);
1820    }
1821
1822    /* initialise name server for internal use (create datafile) */
1823    nsrv_init_server_i(datafile,nsrv_verbose);
1824
1825    /* adjust access restrictions of datafile */
1826    if (nsrv_shared)
1827        ret = chmod(datafile,
1828                    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
1829    else
1830        ret = chmod(datafile,S_IRUSR|S_IWUSR);
1831    if (ret) {
1832        fprintf(stderr,"nsrv: panic : chmod() !!! \n");
1833	nsrv_exit_i();
1834        exit(-1);
1835    }
1836
1837    /* initialise message passing system */
1838    nsrv_bmsg_init(&nsrv_port);
1839    nsrv_amsg_init();
1840    if (nsrv_types_init_i() != NSRV_OK)
1841	nsrv_panic("Not enough resources");
1842
1843    /* listen for connections on control socket */
1844    if (listen(nsrv_ctrl_sock,NSRV_SOCK_BACKLOG) == -1)
1845	nsrv_perror_and_assert_always("listen()");
1846
1847    /* enable interrupts */
1848    pds_enable_int();
1849
1850    nsrv_server_loop();
1851
1852    return(0);
1853}
1854
1855