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_int.c
25**      Author: Kees Schuerman
26**      SccsId: "@(#)nsrv_int.c	1.26 24 Nov 1995"
27** Description: Name Service Internals
28***********************************************************************/
29
30#include "machine.h"     /* architecture specific constant definitions */
31
32#include <sys/types.h>
33#include <sys/socket.h>
34/*
35#include <sys/uio.h>
36*/
37#include <sys/stat.h>
38#include <netdb.h>
39#include <netinet/in.h>
40#include <netinet/tcp.h>
41#include <arpa/inet.h>
42#include <unistd.h>
43#include <stdlib.h>
44#include <stdio.h>
45#include <errno.h>
46#include <string.h>
47#include <rpc/rpc.h>
48#include <fcntl.h>
49
50#include "pds.types.h"
51#include "pds.error.h"
52#include "pds.mem.h"
53#include "pds.mdt.h"
54#include "pds.xdr.h"
55#include "bmsg.msg.h"
56#include "bmsg.xdr.h"
57#include "amsg.msg.h"
58#include "amsg.xdr.h"
59#include "nsrv.h"
60#include "nsrv.xdr.h"
61#include "nsrv_int.h"
62
63
64/**********************************************************************
65** Type Definitions
66***********************************************************************/
67
68typedef pds_uint32 nsrv_id_t;
69
70typedef struct ht_item {
71    struct ht_item * next;
72    void_ptr key;
73    nsrv_name_t signature;
74    void_ptr data;
75} ht_item_t;
76
77typedef struct {	    /* htd: hash table descriptor  */
78    g_mutex_t mutex;	    /* protects hash table	   */
79    unsigned int size;      /* size of hash table	   */
80    ht_item_t * * item;     /* hash table		   */
81    unsigned int count;	    /* # items in hash table  	   */
82} htd_t;
83
84#define HTD_Init(htd)   g_mutex_init(&(htd)->mutex)
85#define HTD_Lock(htd)   g_mutex_lock(&(htd)->mutex)
86#define HTD_Unlock(htd) g_mutex_unlock(&(htd)->mutex)
87
88typedef struct {
89    htd_t * domain;
90    htd_t * bport;
91    htd_t * aport;
92    htd_t * domain_id;
93    htd_t * bport_id;
94} nsrv_t;
95
96#define KEY_HT_SIZE             31
97#define DOMAIN_HT_SIZE          31
98#define BPORT_HT_SIZE           31
99#define APORT_HT_SIZE           67
100#define DOMAIN_ID_HT_SIZE       31
101#define BPORT_ID_HT_SIZE        37
102
103
104
105/**********************************************************************
106** Global Variables
107***********************************************************************/
108
109static pds_heap_descriptor_t nsrv_shd;	/* shared heap descriptor      */
110char * nsrv_data_start = (char *) 0; 	/* start of (shared) data area */
111char * nsrv_msg_start = (char *) 0; 	/* start of (shared) msg area  */
112
113static nsrv_t * * nsrv;			/* htd: hash table descriptors */
114static htd_t * domain_htd;		/* domain htd cache	       */
115static htd_t * bport_htd;		/* bport htd cache             */
116static htd_t * aport_htd;		/* htd aport cache             */
117static htd_t * domain_id_htd;		/* domain_id htd cache         */
118static htd_t * bport_id_htd;		/* bport_id htd cache          */
119
120static int nsrv_verbose = 0;
121
122msg_type_t MDT_NSRVNAME;
123msg_type_t MDT_NSRVVERSION;
124
125msg_type_t MDT_APORT_REGISTER_REQUEST;
126msg_type_t MDT_BPORT_REGISTER_REQUEST;
127msg_type_t MDT_BDOMAIN_REGISTER_REQUEST;
128msg_type_t MDT_DEREGISTER_REQUEST;
129msg_type_t MDT_LOOK_UP_REQUEST;
130msg_type_t MDT_BPORTID_REQUEST;
131msg_type_t MDT_BDOMAINID_REQUEST;
132msg_type_t MDT_VERSION_REQUEST;
133
134msg_type_t MDT_SIMPLE_REPLY;
135msg_type_t MDT_APORT_REPLY;
136msg_type_t MDT_BPORT_REPLY;
137msg_type_t MDT_BDOMAIN_REPLY;
138msg_type_t MDT_BPORTID_REPLY;
139msg_type_t MDT_BDOMAINID_REPLY;
140msg_type_t MDT_VERSION_REPLY;
141
142
143
144/**********************************************************************
145** Debugging Support
146***********************************************************************/
147
148#if !defined(NDEBUG)
149
150static void
151print_bport_id_hash_table()
152{
153    ht_item_t * item;
154    int i;
155
156    printf("\n\n");
157    printf("Bport Identifier Hash Table\n");
158    printf("===========================\n");
159    printf("\n");
160    for (i=0;i<bport_id_htd->size;i++) {
161	item = bport_id_htd->item[i];
162	while (item) {
163	    printf("      key: %d \n", * (int *) item->key);
164	    printf("signature: %s \n", item->signature);
165	    printf(" bport_id: 0x%x \n", * (int *) item->data);
166	    item = item->next;
167	    printf("\n");
168	}
169    }
170}
171
172
173static void
174print_domain_id_hash_table()
175{
176    ht_item_t * item;
177    int i;
178
179    printf("\n\n");
180    printf("Domain Identifier Hash Table\n");
181    printf("============================\n");
182    printf("\n");
183    for (i=0;i<domain_id_htd->size;i++) {
184	item = domain_id_htd->item[i];
185	while (item) {
186	    printf("       key: %d \n", * (int *) item->key);
187	    printf(" signature: %s \n", item->signature);
188	    printf("bdomain_id: 0x%x \n", * (int *) item->data);
189	    item = item->next;
190	    printf("\n");
191	}
192    }
193}
194
195
196static void
197print_bport_hash_table()
198{
199    htd_t * htd;
200    ht_item_t * item_0;
201    ht_item_t * item_1;
202    int i,j;
203
204    printf("\n\n");
205    printf("Bport Hash Table\n");
206    printf("================\n");
207    printf("\n");
208    for (i=0;i<bport_htd->size;i++) {
209	item_0 = bport_htd->item[i];
210	if (item_0)
211	    htd = (htd_t *) item_0->data;
212	else
213	    htd = (htd_t *) 0;
214	while (htd) {
215	    for (j=0;j<htd->size;j++) {
216	        item_1 = htd->item[j];
217		while (item_1) {
218	            printf("                     key: %s \n",
219			    (char *) item_1->key);
220	            printf("               signature: %s \n",
221			    item_1->signature);
222	            printf("              bport.bpid: %d \n",
223		            ((bport_t *) item_1->data)->bpid);
224	            printf("          bport.bport_id: 0x%x \n",
225		            ((bport_t *) item_1->data)->bport_id);
226	            printf("        bport.bdomain_id: 0x%x \n",
227		            ((bport_t *) item_1->data)->bdomain_id);
228	            printf("bport.bmsg_queue_address: 0x%lx \n",
229		            ((bport_t *) item_1->data)->bmsg_queue_address);
230	            printf("      bport.bnet_address: %s \n",
231		            ((bport_t *) item_1->data)->bnet_address);
232	            printf("      bport.bport_number: %u \n",
233			    ((bport_t *) item_1->data)->bport_number);
234	            item_1 = item_1->next;
235		    printf("\n");
236	        }
237	    }
238	    item_0 = item_0->next;
239	    if (item_0)
240		htd = (htd_t *) item_0->data;
241	    else
242		htd = (htd_t *) 0;
243	}
244    }
245}
246
247
248static void
249print_domain_hash_table()
250{
251    htd_t * htd;
252    ht_item_t * item_0;
253    ht_item_t * item_1;
254    int i,j;
255
256    printf("\n\n");
257    printf("Domain Hash Table\n");
258    printf("=================\n");
259    printf("\n");
260    for (i=0;i<domain_htd->size;i++) {
261	item_0 = domain_htd->item[i];
262	if (item_0)
263	    htd = (htd_t *) item_0->data;
264	else
265	    htd = (htd_t *) 0;
266	while (htd) {
267	    for (j=0;j<htd->size;j++) {
268	        item_1 = htd->item[j];
269		while (item_1) {
270	            printf("                     key: %s \n",
271			    (char *) item_1->key);
272	            printf("               signature: %s \n",
273			    item_1->signature);
274	            printf("      bdomain.bdomain_id: 0x%x \n",
275		            ((bdomain_t *) item_1->data)->bdomain_id);
276	            printf("    bdomain.bdomain_file: %s \n",
277		            ((bdomain_t *) item_1->data)->bdomain_file);
278	            printf("   bdomain.bdomain_start: 0x%lx \n",
279		            ((bdomain_t *) item_1->data)->bdomain_start);
280	            printf("    bdomain.bdomain_size: 0x%x \n",
281		            ((bdomain_t *) item_1->data)->bdomain_size);
282	            item_1 = item_1->next;
283		    printf("\n");
284	        }
285	    }
286	    item_0 = item_0->next;
287	    if (item_0)
288		htd = (htd_t *) item_0->data;
289	    else
290		htd = (htd_t *) 0;
291	}
292    }
293}
294
295
296static void
297print_aport_hash_table()
298{
299    htd_t * htd;
300    ht_item_t * item_0;
301    ht_item_t * item_1;
302    int i,j;
303
304    printf("\n\n");
305    printf("Aport Hash Table\n");
306    printf("================\n");
307    printf("\n");
308    for (i=0;i<aport_htd->size;i++) {
309	item_0 = aport_htd->item[i];
310	if (item_0)
311	    htd = (htd_t *) item_0->data;
312	else
313	    htd = (htd_t *) 0;
314	while (htd) {
315	    for (j=0;j<htd->size;j++) {
316	        item_1 = htd->item[j];
317		while (item_1) {
318	            printf("                     key: %s \n",
319			    (char *) item_1->key);
320	            printf("               signature: %s \n",
321			    item_1->signature);
322	            printf("          aport.aport_id: 0x%x \n",
323		            ((aport_t *) item_1->data)->aport_id);
324	            printf("          aport.bport_id: 0x%x \n",
325		            ((aport_t *) item_1->data)->bport_id);
326	            printf("        aport.bdomain_id: 0x%x \n",
327		            ((aport_t *) item_1->data)->bdomain_id);
328	            item_1 = item_1->next;
329		    printf("\n");
330	        }
331	    }
332	    item_0 = item_0->next;
333	    if (item_0)
334		htd = (htd_t *) item_0->data;
335	    else
336		htd = (htd_t *) 0;
337	}
338    }
339}
340
341#endif /* NDEBUG */
342
343
344
345static void
346print_nsrv_retcode(nret)
347    nsrv_ret_t nret;
348{
349    switch (nret) {
350	case NSRV_OK :
351	    printf("NSRV_OK");
352	    break;
353	case NSRV_NYI :
354	    printf("NSRV_NYI");
355	    break;
356	case NSRV_WARN :
357	    printf("NSRV_WARN");
358	    break;
359	case NSRV_ERROR :
360	    printf("NSRV_ERROR");
361	    break;
362	case NSRV_IMPLIM :
363	    printf("NSRV_IMPLIM");
364	    break;
365	case NSRV_INVAL :
366	    printf("NSRV_INVAL");
367	    break;
368	case NSRV_NORESOURCES :
369	    printf("NSRV_NORESOURCES");
370	    break;
371	case NSRV_NOMEMORY :
372	    printf("NSRV_NOMEMORY");
373	    break;
374	case NSRV_NOPORT :
375	    printf("NSRV_NOPORT");
376	    break;
377	case NSRV_NOT_READY :
378	    printf("NSRV_NOT_READY");
379	    break;
380	case NSRV_NOT_YOURS :
381	    printf("NSRV_NOT_YOURS");
382	    break;
383	case NSRV_NOT_REGISTERED :
384	    printf("NSRV_NOT_REGISTERED");
385	    break;
386	case NSRV_NODOMAIN :
387	    printf("NSRV_NODOMAIN");
388	    break;
389	case NSRV_NOSERVER :
390	    printf("NSRV_NOSERVER");
391	    break;
392	case NSRV_NOHOST :
393	    printf("NSRV_NOHOST");
394	    break;
395	case NSRV_EVERSION :
396	    printf("NSRV_EVERSION");
397	    break;
398	default :
399	    printf("NSRV_???");
400	    break;
401    }
402    printf("\n");
403}
404
405
406
407/**********************************************************************
408** Basic Hash Table Primitives
409***********************************************************************/
410
411static nsrv_ret_t
412ht_create(size,htd)
413    unsigned int size;
414    htd_t * * htd;
415{
416    int i;
417
418    *htd = (htd_t *)
419           pds_mem_alloc_size(&nsrv_shd,sizeof(htd_t));
420    if (!*htd)
421        return(NSRV_NOMEMORY);
422
423    (*htd)->item = (ht_item_t * *)
424                   pds_mem_alloc_size(&nsrv_shd,size * sizeof(ht_item_t *));
425    if (!(*htd)->item) {
426	pds_mem_free_size(&nsrv_shd,(void_ptr) *htd,sizeof(htd_t));
427        return(NSRV_NOMEMORY);
428    }
429
430    for (i=0; i<size; i++) {
431        (*htd)->item[i] = (ht_item_t *) 0;
432    }
433
434    (*htd)->size = size;
435    (*htd)->count = 0;
436
437    HTD_Init(*htd);
438
439    return(NSRV_OK);
440}
441
442
443static void
444ht_destroy(htd)
445    htd_t * htd;
446{
447    nsrv_assert(htd->count == 0);
448    pds_mem_free_size(&nsrv_shd,(void_ptr) htd->item,htd->size * sizeof(ht_item_t *));
449    pds_mem_free_size(&nsrv_shd,(void_ptr) htd,sizeof(htd_t));
450}
451
452
453static nsrv_ret_t
454ht_look_up(htd,key,index,match,item)
455    htd_t * htd;
456    void_ptr key;
457    pds_uint32 (* index) ();
458    int (* match) ();
459    ht_item_t * * * item;
460{
461    pds_uint32 indx;
462    ht_item_t * item_curr;
463    ht_item_t * item_prev;
464
465    indx = index(htd,key);
466
467    item_curr = htd->item[indx];
468    item_prev = (ht_item_t *) 0;
469    while (item_curr && (!match(key,item_curr->key))) {
470	item_prev = item_curr;
471	item_curr = item_curr->next;
472    }
473
474    if (item_prev)
475	*item = &item_prev->next;
476    else
477        *item = &htd->item[indx];
478
479    if (item_curr)
480	return(NSRV_OK);
481    else
482	return(NSRV_NOT_REGISTERED);
483}
484
485
486static nsrv_ret_t
487ht_delete(htd,key,signature,index,match,delete)
488    htd_t * htd;
489    void_ptr key;
490    nsrv_name_t signature;
491    pds_uint32 (* index) ();
492    int (* match) ();
493    void (* delete) ();
494{
495    ht_item_t * * item;
496
497    if (ht_look_up(htd,key,index,match,&item) == NSRV_OK) {
498	if (strcmp(signature,(*item)->signature))
499	    return(NSRV_NOT_YOURS);
500	else {
501	    delete(item);
502	    htd->count--;
503	    return(NSRV_OK);
504	}
505    }
506    else {
507        return(NSRV_NOT_REGISTERED);
508    }
509}
510
511
512static nsrv_ret_t
513ht_insert(htd,key,signature,data,index,match,append,replace)
514    htd_t * htd;
515    void_ptr key;
516    nsrv_name_t signature;
517    void_ptr data;
518    pds_uint32 (* index) ();
519    int (* match) ();
520    nsrv_ret_t (* append) ();
521    nsrv_ret_t (* replace) ();
522{
523    nsrv_ret_t nret;
524    ht_item_t * * item;
525
526    if (ht_look_up(htd,key,index,match,&item) == NSRV_OK) {
527	if (strcmp(signature,(*item)->signature))
528	    return(NSRV_NOT_YOURS);
529	else {
530	    return(replace(*item,data));
531	}
532    }
533    else {
534	*item = (ht_item_t *) pds_mem_alloc_size(&nsrv_shd,sizeof(ht_item_t));
535        if (!*item)
536            return(NSRV_NOMEMORY);
537
538        (*item)->next = (ht_item_t *) 0;
539
540	(*item)->key = pds_mem_alloc_size(&nsrv_shd,NSRV_NAMELEN+1);
541        if (!(*item)->key) {
542            pds_mem_free_size(&nsrv_shd,(void_ptr) *item,sizeof(ht_item_t));
543            return(NSRV_NOMEMORY);
544        }
545	strcpy((*item)->signature,signature);
546
547	nret = append(*item,key,data);
548	if (nret != NSRV_OK) {
549	    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,NSRV_NAMELEN+1);
550            pds_mem_free_size(&nsrv_shd,(void_ptr) (*item),sizeof(ht_item_t));
551	}
552	else
553	    htd->count++;
554	return(nret);
555    }
556}
557
558
559
560/**********************************************************************
561** More Local Primitives
562***********************************************************************/
563
564static pds_uint32
565nsrv_id_index(htd,key)
566    htd_t * htd;
567    void_ptr key;
568{
569    return((pds_uint32) (* (nsrv_id_t *) key % htd->size));
570}
571
572
573static int
574nsrv_id_match(key1,key2)
575    void_ptr key1;
576    void_ptr key2;
577{
578    return ((* (nsrv_id_t *) key1) == (* (nsrv_id_t *) key2));
579}
580
581
582static nsrv_ret_t
583nsrv_id_replace(item,data)
584    ht_item_t * item;
585    void_ptr data;
586{
587    return(NSRV_NOT_YOURS);
588}
589
590
591static void
592nsrv_id_delete(item)
593    ht_item_t * * item;
594{
595    ht_item_t * next;
596
597    next = (*item)->next;
598    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,sizeof(nsrv_id_t));
599    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->data,sizeof(nsrv_id_t));
600    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item),sizeof(ht_item_t));
601    *item = next;
602}
603
604
605static nsrv_ret_t
606nsrv_id_append(item,key,data)
607    ht_item_t * item;
608    void_ptr key;
609    void_ptr data;
610{
611    item->data = pds_mem_alloc_size(&nsrv_shd,sizeof(nsrv_id_t));
612    if (!item->data)
613	return(NSRV_NOMEMORY);
614
615    * (nsrv_id_t *) item->data = * (nsrv_id_t *) data;
616
617    * (nsrv_id_t *) item->key = * (nsrv_id_t *) key;
618
619    return(NSRV_OK);
620}
621
622
623static nsrv_ret_t
624nsrv_claim_bport_id(signature,port_id)
625    char * signature;
626    bport_id_t port_id;
627{
628    nsrv_ret_t nret;
629    nsrv_id_t data = port_id;
630
631    HTD_Lock(bport_id_htd);
632
633    nret = ht_insert(bport_id_htd,
634                     (void_ptr) &data,
635		     signature,
636                     (void_ptr) &data,
637                     nsrv_id_index,
638                     nsrv_id_match,
639                     nsrv_id_append,
640                     nsrv_id_replace);
641
642    HTD_Unlock(bport_id_htd);
643
644    return(nret);
645}
646
647
648static nsrv_ret_t
649nsrv_claim_domain_id(signature,domain_id)
650    char * signature;
651    bdomain_id_t domain_id;
652{
653    nsrv_ret_t nret;
654    nsrv_id_t data = domain_id;
655
656    HTD_Lock(domain_id_htd);
657
658    nret = ht_insert(domain_id_htd,
659                     (void_ptr) &data,
660		     signature,
661                     (void_ptr) &data,
662                     nsrv_id_index,
663                     nsrv_id_match,
664                     nsrv_id_append,
665                     nsrv_id_replace);
666
667    HTD_Unlock(domain_id_htd);
668
669    return(nret);
670}
671
672
673static pds_uint32
674nsrv_name_index(htd,key)
675    htd_t * htd;
676    void_ptr key;
677{
678    pds_uint32 indx = 0;
679    unsigned char * name = (unsigned char *) key;
680    int len = (int) strlen(key);
681    int shift = 8 * (sizeof(indx) - sizeof(char));
682    int i;
683
684    for (i=0;i<len;i++) {
685	indx += ((pds_uint32) name[i] << (i % shift));
686    }
687
688    return(indx % htd->size);
689}
690
691
692static int
693nsrv_name_match(name1,name2)
694    void_ptr name1;
695    void_ptr name2;
696{
697    return (!strcmp((char *) name1,(char *) name2));
698}
699
700
701static nsrv_ret_t
702bport_append(item,key,data)
703    ht_item_t * item;
704    void_ptr key;
705    void_ptr data;
706{
707    item->data = pds_mem_alloc_size(&nsrv_shd,sizeof(bport_t));
708    if (!item->data)
709        return(NSRV_NOMEMORY);
710
711    strcpy((char *) item->key,(char *) key);
712
713    * (bport_t *) item->data = * (bport_t *) data;
714
715    return(NSRV_OK);
716}
717
718
719static nsrv_ret_t
720bport_replace(item,data)
721    ht_item_t * item;
722    void_ptr data;
723{
724    * (bport_t *) item->data = * (bport_t *) data;
725    return(NSRV_OK);
726}
727
728
729static void
730bport_delete(item)
731    ht_item_t * * item;
732{
733    ht_item_t * next;
734
735    next = (*item)->next;
736    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,NSRV_NAMELEN+1);
737    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->data,sizeof(bport_t));
738    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item),sizeof(ht_item_t));
739    *item = next;
740}
741
742
743static nsrv_ret_t
744domain_append(item,key,data)
745    ht_item_t * item;
746    void_ptr key;
747    void_ptr data;
748{
749    item->data = pds_mem_alloc_size(&nsrv_shd,sizeof(bdomain_t));
750    if (!item->data)
751        return(NSRV_NOMEMORY);
752
753    strcpy((char *) item->key,(char *) key);
754
755    * (bdomain_t *) item->data = * (bdomain_t *) data;
756
757    return(NSRV_OK);
758}
759
760
761static nsrv_ret_t
762domain_replace(item,data)
763    ht_item_t * item;
764    void_ptr data;
765{
766    * (bdomain_t *) item->data = * (bdomain_t *) data;
767    return(NSRV_OK);
768}
769
770
771static void
772domain_delete(item)
773    ht_item_t * * item;
774{
775    ht_item_t * next;
776
777    next = (*item)->next;
778    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,NSRV_NAMELEN+1);
779    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->data,sizeof(bdomain_t));
780    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item),sizeof(ht_item_t));
781    *item = next;
782}
783
784
785static nsrv_ret_t
786aport_append(item,key,data)
787    ht_item_t * item;
788    void_ptr key;
789    void_ptr data;
790{
791    item->data = pds_mem_alloc_size(&nsrv_shd,sizeof(aport_t));
792    if (!item->data)
793        return(NSRV_NOMEMORY);
794
795    * (aport_t *) item->data = * (aport_t *) data;
796
797    strcpy((char *) item->key,(char *) key);
798
799    return(NSRV_OK);
800}
801
802
803static nsrv_ret_t
804aport_replace(item,data)
805    ht_item_t * item;
806    void_ptr data;
807{
808    * (aport_t *) item->data = * (aport_t *) data;
809    return(NSRV_OK);
810}
811
812
813static void
814aport_delete(item)
815    ht_item_t * * item;
816{
817    ht_item_t * next;
818
819    next = (*item)->next;
820    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,NSRV_NAMELEN+1);
821    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->data,sizeof(aport_t));
822    pds_mem_free_size(&nsrv_shd,(void_ptr) (*item),sizeof(ht_item_t));
823    *item = next;
824}
825
826
827static nsrv_ret_t
828nsrv_name_look_up(htd,key,name,item)
829    htd_t * htd;
830    nsrv_name_t key;
831    nsrv_name_t name;
832    ht_item_t * * item;
833{
834    nsrv_ret_t nret;
835    htd_t * htd1;
836    ht_item_t * * item0;
837    ht_item_t * * item1;
838
839    if (((int) strlen(key) > NSRV_NAMELEN) ||
840	((int) strlen(name) > NSRV_NAMELEN))
841	return(NSRV_INVAL);
842
843    nret = ht_look_up(htd,
844                      (void_ptr) key,
845                      nsrv_name_index,
846                      nsrv_name_match,
847                      &item0);
848    if (nret != NSRV_OK)
849	return(nret);
850    htd1 = (htd_t *) (*item0)->data;
851
852    nret = ht_look_up(htd1,
853                      name,
854                      nsrv_name_index,
855                      nsrv_name_match,
856                      &item1);
857    *item = *item1;
858    return(nret);
859}
860
861
862static nsrv_ret_t
863nsrv_name_deregister(htd,key,name,signature,delete)
864    htd_t * htd;
865    nsrv_name_t key;
866    nsrv_name_t name;
867    nsrv_name_t signature;
868    void (* delete) ();
869{
870    nsrv_ret_t nret;
871    htd_t * htd1;
872    ht_item_t * * item;
873    ht_item_t * next;
874
875    if (((int) strlen(key) > NSRV_NAMELEN) ||
876	((int) strlen(name) > NSRV_NAMELEN) ||
877	((int) strlen(signature) > NSRV_NAMELEN))
878        return(NSRV_INVAL);
879
880    nret = ht_look_up(htd,
881                      (void_ptr) key,
882                      nsrv_name_index,
883                      nsrv_name_match,
884                      &item);
885    if (nret != NSRV_OK)
886        return(nret);
887    htd1 = (htd_t *) (*item)->data;
888
889    nret = ht_delete(htd1,
890                     (void_ptr) name,
891                     signature,
892                     nsrv_name_index,
893                     nsrv_name_match,
894                     delete);
895
896    if ((nret == NSRV_OK) && (htd1->count == 0)) {
897        next = (*item)->next;
898        pds_mem_free_size(&nsrv_shd,(void_ptr) (*item)->key,NSRV_NAMELEN+1);
899        ht_destroy(htd1);
900        pds_mem_free_size(&nsrv_shd,(void_ptr) *item,sizeof(ht_item_t));
901        *item = next;
902	htd->count--;
903    }
904
905    return(nret);
906}
907
908
909static nsrv_ret_t
910nsrv_name_register(htd,key,name,signature,data,bport_id,bdomain_id,size,append,replace)
911    htd_t * htd;
912    nsrv_name_t key;
913    nsrv_name_t name;
914    nsrv_name_t signature;
915    void_ptr data;
916    bport_id_t bport_id;
917    bdomain_id_t bdomain_id;
918    unsigned int size;
919    nsrv_ret_t (* append) ();
920    nsrv_ret_t (* replace) ();
921{
922    nsrv_ret_t nret;
923    htd_t * htd1;
924    ht_item_t * item;
925    ht_item_t * * item_ext;
926
927    if (((int) strlen(key) > NSRV_NAMELEN) ||
928        ((int) strlen(name) > NSRV_NAMELEN) ||
929        ((int) strlen(signature) > NSRV_NAMELEN))
930        return(NSRV_INVAL);
931
932    if (bdomain_id != 0) {
933        nret = nsrv_claim_domain_id(signature,bdomain_id);
934        if ((nret != NSRV_NOT_YOURS) && (nret != NSRV_OK))
935            return(nret);
936    }
937    if (bport_id != 0) {
938        nret = nsrv_claim_bport_id(signature,bport_id);
939        if ((nret != NSRV_NOT_YOURS) && (nret != NSRV_OK))
940            return(nret);
941    }
942
943    nret = ht_look_up(htd,
944                      (void_ptr) key,
945                      nsrv_name_index,
946                      nsrv_name_match,
947                      &item_ext);
948    if (nret != NSRV_OK) {
949        item = (ht_item_t *)
950               pds_mem_alloc_size(&nsrv_shd,sizeof(ht_item_t));
951        if (!item)
952            return(NSRV_NOMEMORY);
953        item->next = (ht_item_t *) 0;
954        item->key = pds_mem_alloc_size(&nsrv_shd,NSRV_NAMELEN+1);
955        if (!item->key) {
956            pds_mem_free_size(&nsrv_shd,(void_ptr) item,sizeof(ht_item_t));
957            return(NSRV_NOMEMORY);
958        }
959        strcpy((char *) item->key, (char *) key);
960        nret = ht_create(size,&htd1);
961        if (nret != NSRV_OK) {
962            pds_mem_free_size(&nsrv_shd,(void_ptr) item->key,NSRV_NAMELEN+1);
963            pds_mem_free_size(&nsrv_shd,(void_ptr) item,sizeof(ht_item_t));
964            return(nret);
965	}
966	item->signature[0] = '\0';
967        item->data = (void_ptr) htd1;
968	*item_ext = item;
969	htd->count++;
970    }
971    else
972        htd1 = (htd_t *) (*item_ext)->data;
973
974    nret = ht_insert(htd1,
975                     (void_ptr) name,
976                     signature,
977                     data,
978                     nsrv_name_index,
979                     nsrv_name_match,
980                     append,
981                     replace);
982
983    return(nret);
984}
985
986
987
988
989/**********************************************************************
990************************  Exported Primitives  ************************
991***********************************************************************/
992
993nsrv_ret_t
994nsrv_types_init_i()
995{
996    pds_ret_t pret;
997
998    msg_typedef_t mdt_name[5];
999    msg_typedef_t mdt_version[6];
1000    msg_typedef_t mdt_request[10];
1001    msg_typedef_t mdt_reply[7];
1002
1003    mdt_name[0] = MDT_BEGIN;
1004    mdt_name[1] = MDT_ARRAY_OF;
1005    mdt_name[2] = NSRV_NAMELEN+1;
1006    mdt_name[3] = MDT_CHAR;
1007    mdt_name[4] = MDT_END;
1008
1009    if ((pret = pds_type_define(NSRV_INTFC,1,
1010				mdt_name,&MDT_NSRVNAME)) != PDS_OK)
1011	return((nsrv_ret_t) pret);
1012
1013    mdt_version[0] = MDT_BEGIN;
1014    mdt_version[1] = MDT_STRUCT_OPEN;
1015    mdt_version[2] = MDT_INT32;
1016    mdt_version[3] = MDT_INT32;
1017    mdt_version[4] = MDT_STRUCT_CLOSE;
1018    mdt_version[5] = MDT_END;
1019
1020    if ((pret = pds_type_define(NSRV_INTFC,2,
1021				mdt_version,&MDT_NSRVVERSION)) != PDS_OK)
1022	return((nsrv_ret_t) pret);
1023
1024    mdt_request[0] = MDT_BEGIN;
1025    mdt_request[1] = MDT_STRUCT_OPEN;
1026    mdt_request[2] = MDT_NSRVNUMBER;
1027    mdt_request[3] = MDT_APORTID;
1028    mdt_request[4] = MDT_NSRVNAME;
1029    mdt_request[5] = MDT_NSRVNAME;
1030    mdt_request[6] = MDT_NSRVNAME;
1031    mdt_request[7] = MDT_APORT;
1032    mdt_request[8] = MDT_STRUCT_CLOSE;
1033    mdt_request[9] = MDT_END;
1034
1035    if ((pret = pds_type_define(NSRV_INTFC,3,mdt_request,
1036			        &MDT_APORT_REGISTER_REQUEST)) != PDS_OK)
1037	return((nsrv_ret_t) pret);
1038
1039    mdt_request[7] = MDT_BPORT;
1040
1041    if ((pret = pds_type_define(NSRV_INTFC,4,mdt_request,
1042			        &MDT_BPORT_REGISTER_REQUEST)) != PDS_OK)
1043	return((nsrv_ret_t) pret);
1044
1045    mdt_request[7] = MDT_BDOMAIN;
1046
1047    if ((pret = pds_type_define(NSRV_INTFC,5,mdt_request,
1048			        &MDT_BDOMAIN_REGISTER_REQUEST)) != PDS_OK)
1049	return((nsrv_ret_t) pret);
1050
1051    mdt_request[0] = MDT_BEGIN;
1052    mdt_request[1] = MDT_STRUCT_OPEN;
1053    mdt_request[2] = MDT_NSRVNUMBER;
1054    mdt_request[3] = MDT_APORTID;
1055    mdt_request[4] = MDT_NSRVNAME;
1056    mdt_request[5] = MDT_NSRVNAME;
1057    mdt_request[6] = MDT_NSRVNAME;
1058    mdt_request[7] = MDT_STRUCT_CLOSE;
1059    mdt_request[8] = MDT_END;
1060
1061    if ((pret = pds_type_define(NSRV_INTFC,6,mdt_request,
1062			        &MDT_DEREGISTER_REQUEST)) != PDS_OK)
1063	return((nsrv_ret_t) pret);
1064
1065    mdt_request[0] = MDT_BEGIN;
1066    mdt_request[1] = MDT_STRUCT_OPEN;
1067    mdt_request[2] = MDT_NSRVNUMBER;
1068    mdt_request[3] = MDT_APORTID;
1069    mdt_request[4] = MDT_NSRVNAME;
1070    mdt_request[5] = MDT_NSRVNAME;
1071    mdt_request[6] = MDT_STRUCT_CLOSE;
1072    mdt_request[7] = MDT_END;
1073
1074    if ((pret = pds_type_define(NSRV_INTFC,7,mdt_request,
1075			        &MDT_LOOK_UP_REQUEST)) != PDS_OK)
1076	return((nsrv_ret_t) pret);
1077
1078    mdt_request[0] = MDT_BEGIN;
1079    mdt_request[1] = MDT_STRUCT_OPEN;
1080    mdt_request[2] = MDT_NSRVNUMBER;
1081    mdt_request[3] = MDT_APORTID;
1082    mdt_request[4] = MDT_NSRVNAME;
1083    mdt_request[5] = MDT_BPORTID;
1084    mdt_request[6] = MDT_STRUCT_CLOSE;
1085    mdt_request[7] = MDT_END;
1086
1087    if ((pret = pds_type_define(NSRV_INTFC,8,mdt_request,
1088			        &MDT_BPORTID_REQUEST)) != PDS_OK)
1089	return((nsrv_ret_t) pret);
1090
1091    mdt_request[5] = MDT_BDOMAINID;
1092
1093    if ((pret = pds_type_define(NSRV_INTFC,9,mdt_request,
1094			        &MDT_BDOMAINID_REQUEST)) != PDS_OK)
1095	return((nsrv_ret_t) pret);
1096
1097    mdt_request[0] = MDT_BEGIN;
1098    mdt_request[1] = MDT_STRUCT_OPEN;
1099    mdt_request[2] = MDT_NSRVNUMBER;
1100    mdt_request[3] = MDT_APORTID;
1101    mdt_request[4] = MDT_STRUCT_CLOSE;
1102    mdt_request[5] = MDT_END;
1103
1104    if ((pret = pds_type_define(NSRV_INTFC,10,mdt_request,
1105			        &MDT_VERSION_REQUEST)) != PDS_OK)
1106	return((nsrv_ret_t) pret);
1107
1108    mdt_reply[0] = MDT_BEGIN;
1109    mdt_reply[1] = MDT_STRUCT_OPEN;
1110    mdt_reply[2] = MDT_NSRVRET;
1111    mdt_reply[3] = MDT_STRUCT_CLOSE;
1112    mdt_reply[4] = MDT_END;
1113
1114    if ((pret = pds_type_define(NSRV_INTFC,11,mdt_reply,
1115			        &MDT_SIMPLE_REPLY)) != PDS_OK)
1116	return((nsrv_ret_t) pret);
1117
1118    mdt_reply[0] = MDT_BEGIN;
1119    mdt_reply[1] = MDT_STRUCT_OPEN;
1120    mdt_reply[2] = MDT_NSRVRET;
1121    mdt_reply[3] = MDT_APORT;
1122    mdt_reply[4] = MDT_STRUCT_CLOSE;
1123    mdt_reply[5] = MDT_END;
1124
1125    if ((pret = pds_type_define(NSRV_INTFC,12,mdt_reply,
1126			        &MDT_APORT_REPLY)) != PDS_OK)
1127	return((nsrv_ret_t) pret);
1128
1129    mdt_reply[3] = MDT_BPORT;
1130
1131    if ((pret = pds_type_define(NSRV_INTFC,13,mdt_reply,
1132			        &MDT_BPORT_REPLY)) != PDS_OK)
1133	return((nsrv_ret_t) pret);
1134
1135    mdt_reply[3] = MDT_BDOMAIN;
1136
1137    if ((pret = pds_type_define(NSRV_INTFC,14,mdt_reply,
1138			        &MDT_BDOMAIN_REPLY)) != PDS_OK)
1139	return((nsrv_ret_t) pret);
1140
1141    mdt_reply[3] = MDT_BPORTID;
1142
1143    if ((pret = pds_type_define(NSRV_INTFC,15,mdt_reply,
1144			        &MDT_BPORTID_REPLY)) != PDS_OK)
1145	return((nsrv_ret_t) pret);
1146
1147    mdt_reply[3] = MDT_BDOMAINID;
1148
1149    if ((pret = pds_type_define(NSRV_INTFC,16,mdt_reply,
1150			        &MDT_BDOMAINID_REPLY)) != PDS_OK)
1151	return((nsrv_ret_t) pret);
1152
1153    mdt_reply[3] = MDT_NSRVVERSION;
1154
1155    if ((pret = pds_type_define(NSRV_INTFC,17,mdt_reply,
1156			        &MDT_VERSION_REPLY)) != PDS_OK)
1157	return((nsrv_ret_t) pret);
1158
1159    return(NSRV_OK);
1160}
1161
1162
1163void
1164nsrv_init_port_number(port_number,property)
1165    unsigned * port_number;
1166    unsigned * property;
1167{
1168    if (!*port_number) {
1169        if (getenv(NSRV_PORT)) { /* use environment variable NSRV_PORT */
1170            int number;
1171            number = atoi(getenv(NSRV_PORT));
1172            if ((number < 1024) || (number > 0xffff)) {
1173                fprintf(stderr,
1174                        "\n nsrv: Invalid environment variable %s !\n",
1175                        NSRV_PORT);
1176                exit(-1);
1177            }
1178            else {
1179                *port_number = number;
1180		*property = NSRV_ENVIRONMENT;
1181	    }
1182        }
1183        else { /* use default port number NSRV_PORT_DEFAULT */
1184            *port_number = NSRV_PORT_DEFAULT;
1185	    *property = NSRV_DEFAULT;
1186	}
1187    }
1188    else
1189	*property = NSRV_PARAMETER;
1190}
1191
1192
1193void
1194nsrv_sock_noinherit(sock)
1195    int sock;
1196{
1197        nsrv_assert(sock > 0);
1198
1199	/* don't inherit socket on exec() */
1200        if (fcntl(sock,F_SETFD,1) == -1) {
1201            nsrv_perror_and_assert_always("fcntl()");
1202	}
1203}
1204
1205
1206void
1207nsrv_sock_linger(sock)
1208    int sock;
1209{
1210    struct linger li;
1211
1212    nsrv_assert(sock > 0);
1213
1214    li.l_onoff = 1;    /* switch lingering on     */
1215    li.l_linger = 10;  /* linger up to 10 seconds */
1216
1217    /* linger to ensure data delivery before closing socket */
1218    if (setsockopt(sock,SOL_SOCKET,SO_LINGER,
1219                   (char *) &li,sizeof(li)) == -1) {
1220        nsrv_perror_and_assert_always("setsockopt() ");
1221    }
1222}
1223
1224
1225void
1226nsrv_sock_nodelay(sock)
1227    int sock;
1228{
1229    int on = 1;
1230
1231    nsrv_assert(sock > 0);
1232
1233    /* disable the default delay of TCP data transmission */
1234    if (setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,
1235                   (char *) &on,sizeof(on)) == -1) {
1236	nsrv_perror_and_assert_always("setsockopt() ");
1237    }
1238}
1239
1240
1241nsrv_ret_t
1242nsrv_send_sock(sock,message,size)
1243    int sock;
1244    char * message;
1245    pds_uint32 size;
1246{
1247    pds_uint32 buf;
1248    char * buffer;
1249    XDR xdrs;
1250    int nbytes,tbytes;
1251    int sbytes = sizeof(pds_uint32);
1252
1253    nsrv_assert(sock > 0);
1254
1255    buffer = (char *) &buf;
1256
1257    xdrmem_create(&xdrs,(const caddr_t) buffer,
1258                  (const u_int) sizeof(pds_uint32),
1259                  XDR_ENCODE);
1260
1261    if (!xdr_pds_u_int32(&xdrs,&size)) {
1262        xdr_destroy(&xdrs);
1263        return(NSRV_XDR_ENCODE);
1264    }
1265    nsrv_assert(xdr_getpos(&xdrs) == sizeof(pds_uint32));
1266
1267    xdr_destroy(&xdrs);
1268
1269    /* write size of message */
1270    tbytes = 0;
1271    while (tbytes < sbytes) {
1272        nbytes = write(sock,
1273                       buffer + tbytes,
1274                       sbytes - tbytes);
1275        if (nbytes >= 0) /* successful write */
1276            tbytes += nbytes;
1277        else if (errno != EINTR)
1278            return(NSRV_ERROR);
1279        /* else retry */
1280    }
1281
1282    /* write message */
1283    tbytes = 0;
1284    while (tbytes < size) {
1285        nbytes = write(sock,
1286                       message + tbytes,
1287                       size - tbytes);
1288        if (nbytes >= 0) /* successful write */
1289            tbytes += nbytes;
1290        else if (errno != EINTR)
1291            return(NSRV_ERROR);
1292        /* else retry */
1293    }
1294
1295    return(NSRV_OK);
1296}
1297
1298
1299nsrv_ret_t
1300nsrv_receive_sock(sock,message,size)
1301    int sock;
1302    char * message;
1303    pds_uint32 * size;
1304{
1305    pds_uint32 buf;
1306    char * buffer;
1307    XDR xdrs;
1308    int nbytes,tbytes;
1309    int rbytes = sizeof(pds_uint32);
1310
1311    nsrv_assert(sock > 0);
1312
1313    buffer = (char *) &buf;
1314
1315    /* read size of message */
1316    tbytes = 0;
1317    while (tbytes < rbytes) {
1318        nbytes = read(sock,
1319                      buffer + tbytes,
1320                      rbytes - tbytes);
1321        if (nbytes > 0) /* successful read */
1322            tbytes += nbytes;
1323        else if (nbytes == 0) { /* End Of Stream */
1324	    if (tbytes == 0)
1325                return(NSRV_WARN);
1326	    else
1327                return(NSRV_ERROR);
1328	}
1329        else if (errno != EINTR)
1330            return(NSRV_ERROR);
1331        /* else retry */
1332    }
1333
1334    xdrmem_create(&xdrs,(const caddr_t) buffer,
1335                  (const u_int) sizeof(pds_uint32),
1336                  XDR_DECODE);
1337
1338    if (!xdr_pds_u_int32(&xdrs,size)) {
1339        xdr_destroy(&xdrs);
1340        return(NSRV_ERROR);
1341    }
1342    nsrv_assert(xdr_getpos(&xdrs) == sizeof(pds_uint32));
1343
1344    xdr_destroy(&xdrs);
1345
1346    rbytes = *size;
1347
1348    /* read message */
1349    tbytes = 0;
1350    while (tbytes < rbytes) {
1351        nbytes = read(sock,
1352                      message + tbytes,
1353                      rbytes - tbytes);
1354        if (nbytes > 0) /* successful read */
1355            tbytes += nbytes;
1356        else if (nbytes == 0) /* End Of Stream */
1357            return(NSRV_ERROR);
1358        else if (errno != EINTR)
1359            return(NSRV_ERROR);
1360        /* else retry */
1361    }
1362
1363    return(NSRV_OK);
1364}
1365
1366
1367void
1368nsrv_close_sock(sock)
1369    int sock;
1370{
1371    int ret;
1372
1373    nsrv_assert(sock > 0);
1374
1375    do {
1376        ret = close(sock);
1377    } while ((ret == -1) && (errno == EINTR));
1378}
1379
1380
1381void
1382nsrv_init_server_i(datafile,verbose)
1383    char * datafile;
1384    int verbose;
1385{
1386    nsrv_verbose = verbose;
1387
1388    if (nsrv_verbose)
1389	printf("\n\n");
1390
1391    if ((sizeof(bdomain_id_t) > sizeof(nsrv_id_t)) ||
1392        (sizeof(bport_id_t) > sizeof(nsrv_id_t))) {
1393        fprintf(stderr, "nsrv: Implementation error !\n");
1394        exit(2);
1395    }
1396
1397    /* initialise random number generator */
1398    srand((unsigned int) getpid());
1399
1400    /* init shared memory heap */
1401    nsrv = (nsrv_t * *)
1402	   pds_mem_init(datafile,pds_mem_base(),NSRV_DATA_AREA_SIZE,&nsrv_shd,1);
1403    if (nsrv - (nsrv_t * *) 0 == -1) {
1404        fprintf(stderr, "nsrv: Not enough memory !\n");
1405        exit(2);
1406    }
1407
1408    /* initialise nsrv_data_start */
1409    nsrv_data_start = nsrv_shd.shared_header->start;
1410
1411    /* allocate hash table descriptors */
1412    *nsrv = (nsrv_t *)
1413            pds_mem_alloc_size(&nsrv_shd,sizeof(nsrv_t));
1414
1415    /* create hash tables */
1416    if (!(*nsrv) ||
1417        (NSRV_OK != ht_create(KEY_HT_SIZE,&(*nsrv)->domain)) ||
1418        (NSRV_OK != ht_create(KEY_HT_SIZE,&(*nsrv)->bport)) ||
1419        (NSRV_OK != ht_create(KEY_HT_SIZE,&(*nsrv)->aport)) ||
1420        (NSRV_OK != ht_create(DOMAIN_ID_HT_SIZE,&(*nsrv)->domain_id)) ||
1421        (NSRV_OK != ht_create(BPORT_ID_HT_SIZE,&(*nsrv)->bport_id))) {
1422        pds_mem_release(&nsrv_shd);
1423        fprintf(stderr, "nsrv: Not enough memory !\n");
1424        exit(2);
1425    }
1426
1427    /* get references to hash table descriptors */
1428    domain_htd = (*nsrv)->domain;
1429    bport_htd = (*nsrv)->bport;
1430    aport_htd = (*nsrv)->aport;
1431    domain_id_htd = (*nsrv)->domain_id;
1432    bport_id_htd = (*nsrv)->bport_id;
1433}
1434
1435
1436void
1437nsrv_exit_i()
1438{
1439    pds_mem_release(&nsrv_shd);
1440}
1441
1442
1443nsrv_ret_t
1444nsrv_init_client_i(datafile)
1445    char * datafile;
1446{
1447    nsrv_assert((sizeof(bdomain_id_t) <= sizeof(nsrv_id_t)) &&
1448		(sizeof(bport_id_t) <= sizeof(nsrv_id_t)));
1449
1450    /* initialise random number generator */
1451    srand((unsigned int) getpid());
1452
1453    /* init shared memory heap */
1454    nsrv = (nsrv_t * *)
1455            pds_mem_init(datafile,(char *) 0,0,&nsrv_shd,0);
1456    if (nsrv - (nsrv_t * *) 0 == -1)
1457    	return(NSRV_NOMEMORY);
1458
1459    /* initialise nsrv_data_start */
1460    nsrv_data_start = nsrv_shd.shared_header->start;
1461
1462    /* get references to hash table descriptors */
1463    domain_htd = (*nsrv)->domain;
1464    bport_htd = (*nsrv)->bport;
1465    aport_htd = (*nsrv)->aport;
1466    domain_id_htd = (*nsrv)->domain_id;
1467    bport_id_htd = (*nsrv)->bport_id;
1468
1469    return(NSRV_OK);
1470}
1471
1472
1473nsrv_ret_t
1474nsrv_aport_register_i(key,name,signature,port)
1475    nsrv_name_t key;
1476    nsrv_name_t name;
1477    nsrv_name_t signature;
1478    aport_t * port;
1479{
1480    nsrv_ret_t nret;
1481
1482    if (nsrv_verbose)
1483	printf("nsrv: nsrv_aport_register(%s,%s) ... ",key,name);
1484
1485    if ((port->bdomain_id == (bdomain_id_t) 0) ||
1486        (port->bport_id == (bport_id_t) 0) ||
1487        (port->aport_id == (aport_id_t) 0)) {
1488	nret = NSRV_NOPORT;
1489        if (nsrv_verbose) print_nsrv_retcode(nret);
1490	return(nret);
1491    }
1492
1493    HTD_Lock(aport_htd);
1494
1495    nret = nsrv_name_register(aport_htd,
1496			      key,
1497			      name,
1498			      signature,
1499			      (void_ptr) port,
1500			      port->bport_id,
1501			      port->bdomain_id,
1502			      APORT_HT_SIZE,
1503			      aport_append,
1504			      aport_replace);
1505
1506    HTD_Unlock(aport_htd);
1507
1508    if (nsrv_verbose) print_nsrv_retcode(nret);
1509
1510    return(nret);
1511}
1512
1513
1514nsrv_ret_t
1515nsrv_aport_deregister_i(key,name,signature)
1516    nsrv_name_t key;
1517    nsrv_name_t name;
1518    nsrv_name_t signature;
1519{
1520    nsrv_ret_t nret;
1521
1522    if (nsrv_verbose)
1523	printf("nsrv: nsrv_aport_deregister(%s,%s) ... ",key,name);
1524
1525    HTD_Lock(aport_htd);
1526
1527    nret = nsrv_name_deregister(aport_htd,key,name,signature,aport_delete);
1528
1529    HTD_Unlock(aport_htd);
1530
1531    if (nsrv_verbose) print_nsrv_retcode(nret);
1532
1533    return(nret);
1534}
1535
1536
1537nsrv_ret_t
1538nsrv_aport_look_up_i(key,port_name,port)
1539    nsrv_name_t key;
1540    nsrv_name_t port_name;
1541    aport_t * port;
1542{
1543    nsrv_ret_t nret;
1544    ht_item_t * item;
1545
1546    if (nsrv_verbose)
1547	printf("nsrv: nsrv_aport_look_up(%s,%s) ... ",key,port_name);
1548
1549    if (!port) {
1550	nret = NSRV_INVAL;
1551        if (nsrv_verbose) print_nsrv_retcode(nret);
1552	return(nret);
1553    }
1554
1555    HTD_Lock(aport_htd);
1556
1557    nret = nsrv_name_look_up(aport_htd,key,port_name,&item);
1558
1559    if (nret == NSRV_OK)
1560	* port = * (aport_t *) item->data;
1561
1562    HTD_Unlock(aport_htd);
1563
1564    if (nsrv_verbose) print_nsrv_retcode(nret);
1565
1566    return(nret);
1567}
1568
1569
1570nsrv_ret_t
1571nsrv_bport_register_i(key,name,signature,port)
1572    nsrv_name_t key;
1573    nsrv_name_t name;
1574    nsrv_name_t signature;
1575    bport_t * port;
1576{
1577    nsrv_ret_t nret;
1578
1579    if (nsrv_verbose)
1580	printf("nsrv: nsrv_bport_register(%s,%s) ... ",key,name);
1581
1582    if ((port->bdomain_id == (bdomain_id_t) 0) ||
1583        (port->bport_id == (bport_id_t) 0)) {
1584	nret = NSRV_NOPORT;
1585        if (nsrv_verbose) print_nsrv_retcode(nret);
1586	return(nret);
1587    }
1588
1589    HTD_Lock(bport_htd);
1590
1591    nret = nsrv_name_register(bport_htd,
1592                              key,
1593                              name,
1594                              signature,
1595                              (void_ptr) port,
1596                              port->bport_id,
1597                              port->bdomain_id,
1598                              BPORT_HT_SIZE,
1599                              bport_append,
1600                              bport_replace);
1601
1602    HTD_Unlock(bport_htd);
1603
1604    if (nsrv_verbose) print_nsrv_retcode(nret);
1605
1606    return(nret);
1607}
1608
1609
1610nsrv_ret_t
1611nsrv_bport_deregister_i(key,name,signature)
1612    nsrv_name_t key;
1613    nsrv_name_t name;
1614    nsrv_name_t signature;
1615{
1616    nsrv_ret_t nret;
1617
1618    if (nsrv_verbose)
1619	printf("nsrv: nsrv_bport_deregister(%s,%s) ... ",key,name);
1620
1621    HTD_Lock(bport_htd);
1622
1623    nret = nsrv_name_deregister(bport_htd,key,name,signature,bport_delete);
1624
1625    HTD_Unlock(bport_htd);
1626
1627    if (nsrv_verbose) print_nsrv_retcode(nret);
1628
1629    return(nret);
1630}
1631
1632
1633nsrv_ret_t
1634nsrv_bport_look_up_i(key,port_name,port)
1635    nsrv_name_t key;
1636    nsrv_name_t port_name;
1637    bport_t * port;
1638{
1639    nsrv_ret_t nret;
1640    ht_item_t * item;
1641
1642    if (nsrv_verbose)
1643	printf("nsrv: nsrv_bport_look_up(%s,%s) ... ",key,port_name);
1644
1645    if (!port) {
1646	nret = NSRV_INVAL;
1647        if (nsrv_verbose) print_nsrv_retcode(nret);
1648	return(nret);
1649    }
1650
1651    HTD_Lock(bport_htd);
1652
1653    nret = nsrv_name_look_up(bport_htd,key,port_name,&item);
1654
1655    if (nret == NSRV_OK)
1656	*port = * (bport_t *) item->data;
1657
1658    HTD_Unlock(bport_htd);
1659
1660    if (nsrv_verbose) print_nsrv_retcode(nret);
1661
1662    return(nret);
1663}
1664
1665
1666nsrv_ret_t
1667nsrv_bdomain_register_i(key,name,signature,domain)
1668    nsrv_name_t key;
1669    nsrv_name_t name;
1670    nsrv_name_t signature;
1671    bdomain_t * domain;
1672{
1673    nsrv_ret_t nret;
1674
1675    if (nsrv_verbose)
1676	printf("nsrv: nsrv_bdomain_register(%s,%s) ... ",key,name);
1677
1678    if (domain->bdomain_id == (bdomain_id_t) 0) {
1679	nret = NSRV_NODOMAIN;
1680        if (nsrv_verbose) print_nsrv_retcode(nret);
1681	return(nret);
1682    }
1683
1684    HTD_Lock(domain_htd);
1685
1686    nret = nsrv_name_register(domain_htd,
1687                              key,
1688                              name,
1689                              signature,
1690                              (void_ptr) domain,
1691                              0,
1692                              domain->bdomain_id,
1693                              DOMAIN_HT_SIZE,
1694                              domain_append,
1695                              domain_replace);
1696
1697    HTD_Unlock(domain_htd);
1698
1699    if (nsrv_verbose) print_nsrv_retcode(nret);
1700
1701    return(nret);
1702}
1703
1704
1705nsrv_ret_t
1706nsrv_bdomain_deregister_i(key,name,signature)
1707    nsrv_name_t key;
1708    nsrv_name_t name;
1709    nsrv_name_t signature;
1710{
1711    nsrv_ret_t nret;
1712
1713    if (nsrv_verbose)
1714	printf("nsrv: nsrv_bdomain_deregister(%s,%s) ... ",key,name);
1715
1716    HTD_Lock(domain_htd);
1717
1718    nret = nsrv_name_deregister(domain_htd,key,name,signature,domain_delete);
1719
1720    HTD_Unlock(domain_htd);
1721
1722    if (nsrv_verbose) print_nsrv_retcode(nret);
1723
1724    return(nret);
1725}
1726
1727
1728nsrv_ret_t
1729nsrv_bdomain_look_up_i(key,domain_name,domain)
1730    nsrv_name_t key;
1731    nsrv_name_t domain_name;
1732    bdomain_t * domain;
1733{
1734    nsrv_ret_t nret;
1735    ht_item_t * item;
1736
1737    if (nsrv_verbose)
1738	printf("nsrv: nsrv_bdomain_look_up(%s,%s) ... ",key,domain_name);
1739
1740    if (!domain) {
1741	nret = NSRV_INVAL;
1742        if (nsrv_verbose) print_nsrv_retcode(nret);
1743        return(nret);
1744    }
1745
1746    HTD_Lock(domain_htd);
1747
1748    nret = nsrv_name_look_up(domain_htd,key,domain_name,&item);
1749
1750    if (nret == NSRV_OK) {
1751	* domain = * (bdomain_t *) item->data;
1752	strcpy(domain->bdomain_file,
1753	       ((bdomain_t *) item->data)->bdomain_file);
1754    }
1755
1756    HTD_Unlock(domain_htd);
1757
1758    if (nsrv_verbose) print_nsrv_retcode(nret);
1759
1760    return(nret);
1761}
1762
1763
1764nsrv_ret_t
1765nsrv_new_bport_id_i(signature,port_id)
1766    nsrv_name_t signature;
1767    bport_id_t * port_id;	/* in/out */
1768{
1769    int i = 0;
1770    nsrv_id_t data;
1771    nsrv_ret_t nret;
1772
1773    if (nsrv_verbose)
1774	printf("nsrv: nsrv_new_bport_id() ... ");
1775
1776    if (((int) strlen(signature) > NSRV_NAMELEN) || (!port_id)) {
1777	nret = NSRV_INVAL;
1778        if (nsrv_verbose) print_nsrv_retcode(nret);
1779	return(nret);
1780    }
1781
1782    /* first try to claim specified port_id */
1783    if ((*port_id > 0) && (*port_id <= BPORT_ID_MAX))
1784        data = (nsrv_id_t) *port_id;
1785    else
1786	data = ((nsrv_id_t) rand() % BPORT_ID_MAX + 1);
1787
1788    HTD_Lock(bport_id_htd);
1789
1790    while (((nret = ht_insert(bport_id_htd,
1791	       		      (void_ptr) &data,
1792		     	      signature,
1793			      (void_ptr) &data,
1794		  	      nsrv_id_index,
1795			      nsrv_id_match,
1796			      nsrv_id_append,
1797			      nsrv_id_replace)) == NSRV_NOT_YOURS) &&
1798	   (i < BPORT_ID_MAX)) {
1799	data = ((nsrv_id_t) rand() % BPORT_ID_MAX + 1);
1800	i++;
1801    }
1802
1803    if (i < BPORT_ID_MAX) {
1804        *port_id = data;
1805        HTD_Unlock(bport_id_htd);
1806	nret = NSRV_OK;
1807    }
1808    else {
1809        *port_id = 0;
1810        HTD_Unlock(bport_id_htd);
1811        nret = NSRV_IMPLIM;
1812    }
1813
1814    if (nsrv_verbose) print_nsrv_retcode(nret);
1815
1816    return(nret);
1817}
1818
1819
1820nsrv_ret_t
1821nsrv_free_bport_id_i(signature,port_id)
1822    nsrv_name_t signature;
1823    bport_id_t port_id;
1824{
1825    nsrv_id_t data;
1826    nsrv_ret_t nret;
1827
1828    if (nsrv_verbose)
1829	printf("nsrv: nsrv_free_bport_id(%d) ... ",port_id);
1830
1831    if ((int) strlen(signature) > NSRV_NAMELEN) {
1832	nret = NSRV_INVAL;
1833        if (nsrv_verbose) print_nsrv_retcode(nret);
1834	return(nret);
1835    }
1836
1837    data = port_id;
1838
1839    HTD_Lock(bport_id_htd);
1840
1841    nret = ht_delete(bport_id_htd,
1842	      	     (void_ptr) &data,
1843		     signature,
1844		     nsrv_id_index,
1845		     nsrv_id_match,
1846		     nsrv_id_delete);
1847
1848    HTD_Unlock(bport_id_htd);
1849
1850    if (nret == NSRV_NOT_REGISTERED)
1851	nret = NSRV_NOT_YOURS;
1852
1853    if (nsrv_verbose) print_nsrv_retcode(nret);
1854
1855    return(nret);
1856}
1857
1858
1859nsrv_ret_t
1860nsrv_new_bdomain_id_i(signature,domain_id)
1861    nsrv_name_t signature;
1862    bdomain_id_t * domain_id;	/* in/out */
1863{
1864    int i = 0;
1865    nsrv_ret_t nret;
1866    nsrv_id_t data;
1867
1868    if (nsrv_verbose)
1869	printf("nsrv: nsrv_new_bdomain_id() ... ");
1870
1871    if (((int) strlen(signature) > NSRV_NAMELEN) || (!domain_id)) {
1872	nret = NSRV_INVAL;
1873        if (nsrv_verbose) print_nsrv_retcode(nret);
1874	return(nret);
1875    }
1876
1877    /* first try to claim specified domain_id */
1878    if (*domain_id != 0)
1879        data = (nsrv_id_t) *domain_id;
1880    else
1881	data = ((nsrv_id_t) rand() % BDOMAIN_ID_MAX + 1);
1882
1883    HTD_Lock(domain_id_htd);
1884
1885    while (((nret = ht_insert(domain_id_htd,
1886	       		      (void_ptr) &data,
1887		     	      signature,
1888			      (void_ptr) &data,
1889		  	      nsrv_id_index,
1890			      nsrv_id_match,
1891			      nsrv_id_append,
1892			      nsrv_id_replace)) == NSRV_NOT_YOURS) &&
1893	   ((nsrv_id_t) i < BDOMAIN_ID_MAX)) {
1894	data = ((nsrv_id_t) rand() % BDOMAIN_ID_MAX + 1);
1895	i++;
1896    }
1897
1898    if ((nsrv_id_t) i < BDOMAIN_ID_MAX) {
1899        *domain_id = data;
1900        HTD_Unlock(domain_id_htd);
1901	nret = NSRV_OK;
1902    }
1903    else {
1904        *domain_id = 0;
1905        HTD_Unlock(domain_id_htd);
1906        nret = NSRV_IMPLIM;
1907    }
1908
1909    if (nsrv_verbose) print_nsrv_retcode(nret);
1910
1911    return(nret);
1912}
1913
1914
1915nsrv_ret_t
1916nsrv_free_bdomain_id_i(signature,domain_id)
1917    nsrv_name_t signature;
1918    bdomain_id_t domain_id;
1919{
1920    nsrv_id_t data;
1921    nsrv_ret_t nret;
1922
1923    if (nsrv_verbose)
1924	printf("nsrv: nsrv_free_bdomain_id(%d) ... ",domain_id);
1925
1926    if ((int) strlen(signature) > NSRV_NAMELEN) {
1927	nret = NSRV_INVAL;
1928        if (nsrv_verbose) print_nsrv_retcode(nret);
1929	return(nret);
1930    }
1931
1932    data = domain_id;
1933
1934    HTD_Lock(domain_id_htd);
1935
1936    nret = ht_delete(domain_id_htd,
1937	      	     (void_ptr) &data,
1938		     signature,
1939		     nsrv_id_index,
1940		     nsrv_id_match,
1941		     nsrv_id_delete);
1942
1943    HTD_Unlock(domain_id_htd);
1944
1945    if (nret == NSRV_NOT_REGISTERED)
1946	nret = NSRV_NOT_YOURS;
1947
1948    if (nsrv_verbose) print_nsrv_retcode(nret);
1949
1950    return(nret);
1951}
1952
1953
1954nsrv_ret_t
1955nsrv_version_i(version)
1956    nsrv_version_t * version;
1957{
1958    version->v_major = NSRV_VERSION_MAJOR;
1959    version->v_minor = NSRV_VERSION_MINOR;
1960
1961    if (nsrv_verbose) {
1962	printf("nsrv: nsrv_version() ... ");
1963	print_nsrv_retcode(NSRV_OK);
1964    }
1965
1966    return(NSRV_OK);
1967}
1968
1969