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