Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,224 +0,0 @@
1
-/* 
2
- * Copyright (C) 2009 iptelorg GmbH
3
- *
4
- * Permission to use, copy, modify, and distribute this software for any
5
- * purpose with or without fee is hereby granted, provided that the above
6
- * copyright notice and this permission notice appear in all copies.
7
- *
8
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
- */
16
-
17
-/*!
18
- * \file
19
- * \brief Kamailio core ::  RPC lookup and register functions
20
- * \ingroup core
21
- * Module: \ref core
22
- */
23
-
24
-#include "rpc.h"
25
-#include "str_hash.h"
26
-#include "ut.h"
27
-#include "dprint.h"
28
-
29
-#define RPC_HASH_SIZE	32
30
-#define RPC_SARRAY_SIZE	32 /* initial size */
31
-
32
-#define RPC_COPY_EXPORT
33
-
34
-static struct str_hash_table rpc_hash_table;
35
-
36
-/* array of pointer to rpc exports, sorted after their name
37
- *  (used by listMethods) */
38
-rpc_export_t** rpc_sarray;
39
-int rpc_sarray_crt_size; /* used */
40
-static int rpc_sarray_max_size; /* number of entries alloc'ed */
41
-
42
-/** init the rpc hash table.
43
-  * @return 0 on success, -1 on error
44
-  */
45
-int init_rpcs(void)
46
-{
47
-	if (str_hash_alloc(&rpc_hash_table, RPC_HASH_SIZE)<0)
48
-		return -1;
49
-	str_hash_init(&rpc_hash_table);
50
-	rpc_sarray_max_size=RPC_SARRAY_SIZE;
51
-	rpc_sarray=pkg_malloc(sizeof(*rpc_sarray)* rpc_sarray_max_size);
52
-	rpc_sarray_crt_size=0;
53
-	return 0;
54
-}
55
-
56
-
57
-
58
-void destroy_rpcs(void)
59
-{
60
-	int r;
61
-	struct str_hash_entry* e;
62
-	struct str_hash_entry* bak;
63
-	for (r=0; r<rpc_hash_table.size; r++){
64
-		clist_foreach_safe(&rpc_hash_table.table[r], e, bak, next){
65
-			pkg_free(e);
66
-		}
67
-	}
68
-	if (rpc_hash_table.table) pkg_free(rpc_hash_table.table);
69
-	if (rpc_sarray) pkg_free(rpc_sarray);
70
-	rpc_hash_table.table=0;
71
-	rpc_hash_table.size=0;
72
-	rpc_sarray=0;
73
-	rpc_sarray_crt_size=0;
74
-	rpc_sarray_max_size=0;
75
-}
76
-
77
-
78
-
79
-/** adds a new rpc to the hash table (no checks).
80
- * @return 0 on success, -1 on error, 1 on duplicate
81
- */
82
-static int rpc_hash_add(struct rpc_export* rpc)
83
-{
84
-	struct str_hash_entry* e;
85
-	int name_len;
86
-	int doc0_len, doc1_len;
87
-	struct rpc_export* n_rpc;
88
-	struct rpc_export** r;
89
-	
90
-	name_len=strlen(rpc->name);
91
-	doc0_len=rpc->doc_str[0]?strlen(rpc->doc_str[0]):0;
92
-	doc1_len=rpc->doc_str[1]?strlen(rpc->doc_str[1]):0;
93
-	/* alloc everything into one block */
94
-	
95
-#ifdef RPC_COPY_EXPORT
96
-	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry))
97
-								+ROUND_POINTER(sizeof(*rpc))+2*sizeof(char*)+
98
-								+name_len+1+doc0_len+(rpc->doc_str[0]!=0)
99
-								+doc1_len+(rpc->doc_str[1]!=0)
100
-								);
101
-#else /* RPC_COPY_EXPORT */
102
-	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry)));
103
-#endif /* RPC_COPY_EXPORT */
104
-	
105
-	if (e==0){
106
-		ERR("out of memory\n");
107
-		goto error;
108
-	}
109
-#ifdef RPC_COPY_EXPORT
110
-	n_rpc=(rpc_export_t*)((char*)e+
111
-			ROUND_POINTER(sizeof(struct str_hash_entry)));
112
-	/* copy rpc into n_rpc */
113
-	*n_rpc=*rpc;
114
-	n_rpc->doc_str=(const char**)((char*)n_rpc+ROUND_POINTER(sizeof(*rpc)));
115
-	n_rpc->name=(char*)n_rpc->doc_str+2*sizeof(char*);
116
-	memcpy((char*)n_rpc->name, rpc->name, name_len);
117
-	*((char*)&n_rpc->name[name_len])=0;
118
-	if (rpc->doc_str[0]){
119
-		n_rpc->doc_str[0]=&n_rpc->name[name_len+1];
120
-		memcpy((char*)n_rpc->doc_str[0], rpc->doc_str[0], doc0_len);
121
-		*(char*)&(n_rpc->doc_str[0][doc0_len])=0;
122
-	}else{
123
-		n_rpc->doc_str[0]=0;
124
-	}
125
-	if (rpc->doc_str[1]){
126
-		n_rpc->doc_str[1]=n_rpc->doc_str[0]?&n_rpc->doc_str[0][doc0_len+1]:
127
-							&n_rpc->name[name_len+1];;
128
-		memcpy((char*)n_rpc->doc_str[1], rpc->doc_str[1], doc1_len);
129
-		*(char*)&(n_rpc->doc_str[1][doc1_len])=0;
130
-	}else{
131
-		n_rpc->doc_str[1]=0;
132
-	}
133
-#else /* RPC_COPY_EXPORT */
134
-	n_rpc=rpc;
135
-#endif /* RPC_COPY_EXPORT */
136
-	
137
-	e->key.s=(char*)n_rpc->name;
138
-	e->key.len=name_len;
139
-	e->flags=0;
140
-	e->u.p=n_rpc;
141
-	str_hash_add(&rpc_hash_table, e);
142
-	
143
-	/* insert it into the sorted array */
144
-	if (rpc_sarray_max_size<=rpc_sarray_crt_size){
145
-		/* array must be increased */
146
-		r=pkg_realloc(rpc_sarray, 2*rpc_sarray_max_size*sizeof(*rpc_sarray));
147
-		if (r==0){
148
-			ERR("out of memory while adding RPC to the sorted list\n");
149
-			goto error;
150
-		}
151
-		rpc_sarray=r;
152
-		rpc_sarray_max_size*=2;
153
-	};
154
-	/* insert into array, sorted */
155
-	for (r=rpc_sarray;r<(rpc_sarray+rpc_sarray_crt_size); r++){
156
-		if (strcmp(n_rpc->name, (*r)->name)<0)
157
-			break;
158
-	}
159
-	if (r!=(rpc_sarray+rpc_sarray_crt_size))
160
-		memmove(r+1, r, (int)(long)((char*)(rpc_sarray+rpc_sarray_crt_size)-
161
-											(char*)r));
162
-	rpc_sarray_crt_size++;
163
-	*r=n_rpc;
164
-	return 0;
165
-error:
166
-	return -1;
167
-}
168
-
169
-
170
-
171
-/** lookup an rpc export after its name.
172
- * @return pointer to rpc export on success, 0 on error
173
- */
174
-rpc_export_t* rpc_lookup(const char* name, int len)
175
-{
176
-	struct str_hash_entry* e;
177
-	
178
-	e=str_hash_get(&rpc_hash_table, (char*)name, len);
179
-	return e?(rpc_export_t*)e->u.p:0;
180
-}
181
-
182
-
183
-
184
-/** register a new rpc.
185
- * @return 0 on success, -1 on error, 1 on duplicate
186
- */
187
-int rpc_register(rpc_export_t* rpc)
188
-{
189
-	
190
-	/* check if the entry is already registered */
191
-	if (rpc_lookup(rpc->name, strlen(rpc->name))){
192
-		WARN("duplicate rpc \"%s\"\n", rpc->name);
193
-		return 1;
194
-	}
195
-	if (rpc_hash_add(rpc)!=0) return -1;
196
-	return 0;
197
-}
198
-
199
-
200
-
201
-/** register all the rpc in a null-terminated array.
202
-  * @return 0 on success, >0 if duplicates were found (number of 
203
-  * duplicates), -1 on error
204
-  */
205
-int rpc_register_array(rpc_export_t* rpc_array)
206
-{
207
-	rpc_export_t* rpc;
208
-	int ret,i;
209
-	
210
-	ret=0;
211
-	for (rpc=rpc_array; rpc && rpc->name; rpc++){
212
-		i=rpc_register(rpc);
213
-		if (i!=0){
214
-			if (i<0) goto error;
215
-			ret++;
216
-		}
217
-	}
218
-	return ret;
219
-error:
220
-	return -1;
221
-}
222
-
223
-
224
-/* vi: set ts=4 sw=4 tw=79:ai:cindent: */
Browse code

Core Removed history, svn $id$ and doxygen udpates on the .c files

Olle E. Johansson authored on 03/01/2015 09:53:17
Showing 1 changed files
... ...
@@ -1,6 +1,4 @@
1 1
 /* 
2
- * $Id$
3
- * 
4 2
  * Copyright (C) 2009 iptelorg GmbH
5 3
  *
6 4
  * Permission to use, copy, modify, and distribute this software for any
... ...
@@ -15,18 +13,10 @@
15 13
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 14
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 15
  */
18
-/*
19
- * SER RPC lookup and register functions
20
- */
21
-/*
22
- * History:
23
- * --------
24
- *  2009-05-11  initial version (andrei)
25
-*/
26 16
 
27 17
 /*!
28 18
  * \file
29
- * \brief SIP-router core :: 
19
+ * \brief Kamailio core ::  RPC lookup and register functions
30 20
  * \ingroup core
31 21
  * Module: \ref core
32 22
  */
Browse code

master:core Continue cleaning erroneous definition of functions with no arguments

After testing with gcc 4.5.2, seems that not prototyping function cases extra assembler code regardles of optimization level

Marius Zbihlei authored on 04/04/2012 09:51:50
Showing 1 changed files
... ...
@@ -52,7 +52,7 @@ static int rpc_sarray_max_size; /* number of entries alloc'ed */
52 52
 /** init the rpc hash table.
53 53
   * @return 0 on success, -1 on error
54 54
   */
55
-int init_rpcs()
55
+int init_rpcs(void)
56 56
 {
57 57
 	if (str_hash_alloc(&rpc_hash_table, RPC_HASH_SIZE)<0)
58 58
 		return -1;
... ...
@@ -65,7 +65,7 @@ int init_rpcs()
65 65
 
66 66
 
67 67
 
68
-void destroy_rpcs()
68
+void destroy_rpcs(void)
69 69
 {
70 70
 	int r;
71 71
 	struct str_hash_entry* e;
Browse code

Adding doxygen template to all core .c files

Please fill in after the :: to explain the function of this file.

oej authored on 10/10/2009 13:54:13
Showing 1 changed files
... ...
@@ -24,6 +24,13 @@
24 24
  *  2009-05-11  initial version (andrei)
25 25
 */
26 26
 
27
+/*!
28
+ * \file
29
+ * \brief SIP-router core :: 
30
+ * \ingroup core
31
+ * Module: \ref core
32
+ */
33
+
27 34
 #include "rpc.h"
28 35
 #include "str_hash.h"
29 36
 #include "ut.h"
Browse code

core: fix gcc 2.9x #ifdef in macro args

gcc version < 3.0 do not support compile directives in macro
arguments.

Andrei Pelinescu-Onciul authored on 30/09/2009 23:06:03
Showing 1 changed files
... ...
@@ -94,13 +94,17 @@ static int rpc_hash_add(struct rpc_export* rpc)
94 94
 	doc0_len=rpc->doc_str[0]?strlen(rpc->doc_str[0]):0;
95 95
 	doc1_len=rpc->doc_str[1]?strlen(rpc->doc_str[1]):0;
96 96
 	/* alloc everything into one block */
97
-	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry))
97
+	
98 98
 #ifdef RPC_COPY_EXPORT
99
+	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry))
99 100
 								+ROUND_POINTER(sizeof(*rpc))+2*sizeof(char*)+
100 101
 								+name_len+1+doc0_len+(rpc->doc_str[0]!=0)
101 102
 								+doc1_len+(rpc->doc_str[1]!=0)
102
-#endif /* RPC_COPY_EXPORT */
103 103
 								);
104
+#else /* RPC_COPY_EXPORT */
105
+	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry)));
106
+#endif /* RPC_COPY_EXPORT */
107
+	
104 108
 	if (e==0){
105 109
 		ERR("out of memory\n");
106 110
 		goto error;
Browse code

core: rpc more verbose when duplicates found

When duplicate rpc names are detected, print them (WARN(..)).

Andrei Pelinescu-Onciul authored on 15/07/2009 20:49:23
Showing 1 changed files
... ...
@@ -27,6 +27,7 @@
27 27
 #include "rpc.h"
28 28
 #include "str_hash.h"
29 29
 #include "ut.h"
30
+#include "dprint.h"
30 31
 
31 32
 #define RPC_HASH_SIZE	32
32 33
 #define RPC_SARRAY_SIZE	32 /* initial size */
... ...
@@ -186,8 +187,10 @@ int rpc_register(rpc_export_t* rpc)
186 187
 {
187 188
 	
188 189
 	/* check if the entry is already registered */
189
-	if (rpc_lookup(rpc->name, strlen(rpc->name)))
190
+	if (rpc_lookup(rpc->name, strlen(rpc->name))){
191
+		WARN("duplicate rpc \"%s\"\n", rpc->name);
190 192
 		return 1;
193
+	}
191 194
 	if (rpc_hash_add(rpc)!=0) return -1;
192 195
 	return 0;
193 196
 }
Browse code

core: destroy_rpcs fix: don't try to free unalloc. data

destroy_rpcs() can be called without init_rpcs() being called
first (e.g. unknown command line param) => don't blindly free
everything, check first if the arrays were allocated.

Andrei Pelinescu-Onciul authored on 29/05/2009 09:07:20
Showing 1 changed files
... ...
@@ -67,8 +67,8 @@ void destroy_rpcs()
67 67
 			pkg_free(e);
68 68
 		}
69 69
 	}
70
-	pkg_free(rpc_hash_table.table);
71
-	pkg_free(rpc_sarray);
70
+	if (rpc_hash_table.table) pkg_free(rpc_hash_table.table);
71
+	if (rpc_sarray) pkg_free(rpc_sarray);
72 72
 	rpc_hash_table.table=0;
73 73
 	rpc_hash_table.size=0;
74 74
 	rpc_sarray=0;
Browse code

rpc: added register function and switched to hash table

- rpc switched to hashtable
- added rpc register function, that can be called from modules not
using ser module interface (e.g. kamailio or future sip-router
module interface).

Andrei Pelinescu-Onciul authored on 11/05/2009 22:39:03
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,220 @@
1
+/* 
2
+ * $Id$
3
+ * 
4
+ * Copyright (C) 2009 iptelorg GmbH
5
+ *
6
+ * Permission to use, copy, modify, and distribute this software for any
7
+ * purpose with or without fee is hereby granted, provided that the above
8
+ * copyright notice and this permission notice appear in all copies.
9
+ *
10
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
+ */
18
+/*
19
+ * SER RPC lookup and register functions
20
+ */
21
+/*
22
+ * History:
23
+ * --------
24
+ *  2009-05-11  initial version (andrei)
25
+*/
26
+
27
+#include "rpc.h"
28
+#include "str_hash.h"
29
+#include "ut.h"
30
+
31
+#define RPC_HASH_SIZE	32
32
+#define RPC_SARRAY_SIZE	32 /* initial size */
33
+
34
+#define RPC_COPY_EXPORT
35
+
36
+static struct str_hash_table rpc_hash_table;
37
+
38
+/* array of pointer to rpc exports, sorted after their name
39
+ *  (used by listMethods) */
40
+rpc_export_t** rpc_sarray;
41
+int rpc_sarray_crt_size; /* used */
42
+static int rpc_sarray_max_size; /* number of entries alloc'ed */
43
+
44
+/** init the rpc hash table.
45
+  * @return 0 on success, -1 on error
46
+  */
47
+int init_rpcs()
48
+{
49
+	if (str_hash_alloc(&rpc_hash_table, RPC_HASH_SIZE)<0)
50
+		return -1;
51
+	str_hash_init(&rpc_hash_table);
52
+	rpc_sarray_max_size=RPC_SARRAY_SIZE;
53
+	rpc_sarray=pkg_malloc(sizeof(*rpc_sarray)* rpc_sarray_max_size);
54
+	rpc_sarray_crt_size=0;
55
+	return 0;
56
+}
57
+
58
+
59
+
60
+void destroy_rpcs()
61
+{
62
+	int r;
63
+	struct str_hash_entry* e;
64
+	struct str_hash_entry* bak;
65
+	for (r=0; r<rpc_hash_table.size; r++){
66
+		clist_foreach_safe(&rpc_hash_table.table[r], e, bak, next){
67
+			pkg_free(e);
68
+		}
69
+	}
70
+	pkg_free(rpc_hash_table.table);
71
+	pkg_free(rpc_sarray);
72
+	rpc_hash_table.table=0;
73
+	rpc_hash_table.size=0;
74
+	rpc_sarray=0;
75
+	rpc_sarray_crt_size=0;
76
+	rpc_sarray_max_size=0;
77
+}
78
+
79
+
80
+
81
+/** adds a new rpc to the hash table (no checks).
82
+ * @return 0 on success, -1 on error, 1 on duplicate
83
+ */
84
+static int rpc_hash_add(struct rpc_export* rpc)
85
+{
86
+	struct str_hash_entry* e;
87
+	int name_len;
88
+	int doc0_len, doc1_len;
89
+	struct rpc_export* n_rpc;
90
+	struct rpc_export** r;
91
+	
92
+	name_len=strlen(rpc->name);
93
+	doc0_len=rpc->doc_str[0]?strlen(rpc->doc_str[0]):0;
94
+	doc1_len=rpc->doc_str[1]?strlen(rpc->doc_str[1]):0;
95
+	/* alloc everything into one block */
96
+	e=pkg_malloc(ROUND_POINTER(sizeof(struct str_hash_entry))
97
+#ifdef RPC_COPY_EXPORT
98
+								+ROUND_POINTER(sizeof(*rpc))+2*sizeof(char*)+
99
+								+name_len+1+doc0_len+(rpc->doc_str[0]!=0)
100
+								+doc1_len+(rpc->doc_str[1]!=0)
101
+#endif /* RPC_COPY_EXPORT */
102
+								);
103
+	if (e==0){
104
+		ERR("out of memory\n");
105
+		goto error;
106
+	}
107
+#ifdef RPC_COPY_EXPORT
108
+	n_rpc=(rpc_export_t*)((char*)e+
109
+			ROUND_POINTER(sizeof(struct str_hash_entry)));
110
+	/* copy rpc into n_rpc */
111
+	*n_rpc=*rpc;
112
+	n_rpc->doc_str=(const char**)((char*)n_rpc+ROUND_POINTER(sizeof(*rpc)));
113
+	n_rpc->name=(char*)n_rpc->doc_str+2*sizeof(char*);
114
+	memcpy((char*)n_rpc->name, rpc->name, name_len);
115
+	*((char*)&n_rpc->name[name_len])=0;
116
+	if (rpc->doc_str[0]){
117
+		n_rpc->doc_str[0]=&n_rpc->name[name_len+1];
118
+		memcpy((char*)n_rpc->doc_str[0], rpc->doc_str[0], doc0_len);
119
+		*(char*)&(n_rpc->doc_str[0][doc0_len])=0;
120
+	}else{
121
+		n_rpc->doc_str[0]=0;
122
+	}
123
+	if (rpc->doc_str[1]){
124
+		n_rpc->doc_str[1]=n_rpc->doc_str[0]?&n_rpc->doc_str[0][doc0_len+1]:
125
+							&n_rpc->name[name_len+1];;
126
+		memcpy((char*)n_rpc->doc_str[1], rpc->doc_str[1], doc1_len);
127
+		*(char*)&(n_rpc->doc_str[1][doc1_len])=0;
128
+	}else{
129
+		n_rpc->doc_str[1]=0;
130
+	}
131
+#else /* RPC_COPY_EXPORT */
132
+	n_rpc=rpc;
133
+#endif /* RPC_COPY_EXPORT */
134
+	
135
+	e->key.s=(char*)n_rpc->name;
136
+	e->key.len=name_len;
137
+	e->flags=0;
138
+	e->u.p=n_rpc;
139
+	str_hash_add(&rpc_hash_table, e);
140
+	
141
+	/* insert it into the sorted array */
142
+	if (rpc_sarray_max_size<=rpc_sarray_crt_size){
143
+		/* array must be increased */
144
+		r=pkg_realloc(rpc_sarray, 2*rpc_sarray_max_size*sizeof(*rpc_sarray));
145
+		if (r==0){
146
+			ERR("out of memory while adding RPC to the sorted list\n");
147
+			goto error;
148
+		}
149
+		rpc_sarray=r;
150
+		rpc_sarray_max_size*=2;
151
+	};
152
+	/* insert into array, sorted */
153
+	for (r=rpc_sarray;r<(rpc_sarray+rpc_sarray_crt_size); r++){
154
+		if (strcmp(n_rpc->name, (*r)->name)<0)
155
+			break;
156
+	}
157
+	if (r!=(rpc_sarray+rpc_sarray_crt_size))
158
+		memmove(r+1, r, (int)(long)((char*)(rpc_sarray+rpc_sarray_crt_size)-
159
+											(char*)r));
160
+	rpc_sarray_crt_size++;
161
+	*r=n_rpc;
162
+	return 0;
163
+error:
164
+	return -1;
165
+}
166
+
167
+
168
+
169
+/** lookup an rpc export after its name.
170
+ * @return pointer to rpc export on success, 0 on error
171
+ */
172
+rpc_export_t* rpc_lookup(const char* name, int len)
173
+{
174
+	struct str_hash_entry* e;
175
+	
176
+	e=str_hash_get(&rpc_hash_table, (char*)name, len);
177
+	return e?(rpc_export_t*)e->u.p:0;
178
+}
179
+
180
+
181
+
182
+/** register a new rpc.
183
+ * @return 0 on success, -1 on error, 1 on duplicate
184
+ */
185
+int rpc_register(rpc_export_t* rpc)
186
+{
187
+	
188
+	/* check if the entry is already registered */
189
+	if (rpc_lookup(rpc->name, strlen(rpc->name)))
190
+		return 1;
191
+	if (rpc_hash_add(rpc)!=0) return -1;
192
+	return 0;
193
+}
194
+
195
+
196
+
197
+/** register all the rpc in a null-terminated array.
198
+  * @return 0 on success, >0 if duplicates were found (number of 
199
+  * duplicates), -1 on error
200
+  */
201
+int rpc_register_array(rpc_export_t* rpc_array)
202
+{
203
+	rpc_export_t* rpc;
204
+	int ret,i;
205
+	
206
+	ret=0;
207
+	for (rpc=rpc_array; rpc && rpc->name; rpc++){
208
+		i=rpc_register(rpc);
209
+		if (i!=0){
210
+			if (i<0) goto error;
211
+			ret++;
212
+		}
213
+	}
214
+	return ret;
215
+error:
216
+	return -1;
217
+}
218
+
219
+
220
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */