Annotation of libaitrpc/src/lists.c, revision 1.4.2.4
1.2 misho 1: /*************************************************************************
2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
3: * by Michael Pounov <misho@openbsd-bg.org>
4: *
5: * $Author: misho $
1.4.2.4 ! misho 6: * $Id: lists.c,v 1.4.2.3 2011/09/01 11:39:26 misho Exp $
1.2 misho 7: *
8: **************************************************************************
9: The ELWIX and AITNET software is distributed under the following
10: terms:
11:
12: All of the documentation and software included in the ELWIX and AITNET
13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
14:
15: Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
16: by Michael Pounov <misho@elwix.org>. All rights reserved.
17:
18: Redistribution and use in source and binary forms, with or without
19: modification, are permitted provided that the following conditions
20: are met:
21: 1. Redistributions of source code must retain the above copyright
22: notice, this list of conditions and the following disclaimer.
23: 2. Redistributions in binary form must reproduce the above copyright
24: notice, this list of conditions and the following disclaimer in the
25: documentation and/or other materials provided with the distribution.
26: 3. All advertising materials mentioning features or use of this software
27: must display the following acknowledgement:
28: This product includes software developed by Michael Pounov <misho@elwix.org>
29: ELWIX - Embedded LightWeight unIX and its contributors.
30: 4. Neither the name of AITNET nor the names of its contributors
31: may be used to endorse or promote products derived from this software
32: without specific prior written permission.
33:
34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37: ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44: SUCH DAMAGE.
45: */
46: #include "global.h"
47:
48:
49: /*
1.4 misho 50: * rpc_srv_allocVars() Allocate array for call variables,
51: if already allocated memory for RPC call reallocate used space
1.2 misho 52: * @call = RPC function call
1.4 misho 53: * @varnum = Number of variables, if ==0 free previous allocated variables
54: * return: -1 error, !=-1 return varnum value
1.2 misho 55: */
56: inline int
1.4 misho 57: rpc_srv_allocVars(rpc_func_t * __restrict call, int varnum)
1.2 misho 58: {
1.4.2.2 misho 59: register int i;
60: ait_val_t *v;
1.2 misho 61:
1.4 misho 62: if (!call || varnum < 0) {
63: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t allocate variables for RPC call...\n");
1.2 misho 64: return -1;
1.4.2.2 misho 65: }
1.2 misho 66:
1.4.2.2 misho 67: if (varnum) {
1.4.2.3 misho 68: call->func_vars = io_arrayInit(varnum);
69: if (!call->func_vars)
1.2 misho 70: return -1;
1.4.2.2 misho 71:
1.4.2.3 misho 72: /* allocate ait_val_t elements & add to array */
1.4.2.2 misho 73: for (i = 0; i < io_arraySize(call->func_vars); i++) {
74: v = malloc(sizeof(ait_val_t));
75: if (!v) {
76: LOGERR;
1.4.2.3 misho 77: rpc_srv_destroyVars(call);
1.4.2.2 misho 78: return -1;
79: } else {
80: memset(v, 0, sizeof(ait_val_t));
81: io_arraySet(call->func_vars, i, v);
82: }
83: }
1.4.2.3 misho 84: }
85:
86: return io_arraySize(call->func_vars);
87: }
88:
89: /*
90: * rpc_srv_destroyVars() Destroy variables of array & array
91: * @call = RPC function call
92: * return: -1 error, !=-1 Returne remained variables
93: */
94: inline int
95: rpc_srv_destroyVars(rpc_func_t * __restrict call)
96: {
97: if (!call) {
98: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete variables ...\n");
99: return -1;
100: }
101:
102: if (call->func_vars) {
103: rpc_srv_freeVals(call);
1.4.2.2 misho 104:
1.4.2.3 misho 105: io_arrayFree(call->func_vars);
106: io_arrayDestroy(&call->func_vars);
1.2 misho 107: }
108:
1.4.2.3 misho 109: return io_arraySize(call->func_vars);
1.2 misho 110: }
111:
112: /*
1.4.2.3 misho 113: * rpc_srv_freeVals() Clean values from variables of array
1.2 misho 114: * @call = RPC function call
1.4.2.3 misho 115: * return: -1 error, !=-1 Returned number of cleaned variables
1.2 misho 116: */
117: inline int
1.4.2.3 misho 118: rpc_srv_freeVals(rpc_func_t * __restrict call)
1.2 misho 119: {
1.4.2.3 misho 120: register int i;
121:
1.2 misho 122: if (!call) {
1.4 misho 123: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete variables ...\n");
1.2 misho 124: return -1;
125: }
126:
1.4.2.3 misho 127: if (call->func_vars) {
128: for (i = 0; i < io_arraySize(call->func_vars); i++)
129: if (io_arrayGet(call->func_vars, i))
130: AIT_FREE_VAL(io_array(call->func_vars, i, ait_val_t*));
131: }
132:
1.4.2.2 misho 133: return io_arraySize(call->func_vars);
1.2 misho 134: }
135:
136: /*
1.4 misho 137: * rpc_srv_copyVars() Copy variables for RPC call to new variable array
1.2 misho 138: * @call = RPC function call
1.4 misho 139: * @newvars = New allocated variables array, must be free after use
1.2 misho 140: * return: -1 error, !=-1 Returned number of copied RPC variables
141: */
142: inline int
1.4.2.2 misho 143: rpc_srv_copyVars(rpc_func_t * __restrict call, array_t ** __restrict newvars)
1.2 misho 144: {
1.4 misho 145: if (!call || !newvars) {
146: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy variables to new array\n");
1.2 misho 147: return -1;
148: }
149:
1.4.2.2 misho 150: if (io_arrayCopy(newvars, call->func_vars) == -1)
1.2 misho 151: return -1;
152:
1.4.2.2 misho 153: return io_arraySize(*newvars);
1.2 misho 154: }
155:
156: /*
1.4 misho 157: * rpc_srv_getVars() Get variables array for RPC call
1.2 misho 158: * @call = RPC function call
1.4 misho 159: * @vars = Returned variables array, may be NULL
1.2 misho 160: * return: -1 error, !=-1 Number of returned variables
161: */
162: inline int
1.4.2.2 misho 163: rpc_srv_getVars(rpc_func_t * __restrict call, array_t ** __restrict vars)
1.2 misho 164: {
165: if (!call) {
1.4 misho 166: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variables ...\n");
1.2 misho 167: return -1;
168: }
169:
1.4 misho 170: if (vars)
171: *vars = call->func_vars;
1.4.2.3 misho 172: return io_arraySize(call->func_vars);
1.2 misho 173: }
174:
175: // ---------------------------------------------------------
176:
177: /*
178: * rpc_srv_registerCall() Register call to RPC server
179: * @srv = RPC Server instance
180: * @csModule = Module name, if NULL self binary
181: * @csFunc = Function name
182: * @args = Number of return function arguments, use for restriction case!
183: * return: -1 error or 0 register ok
184: */
185: int
1.4.2.2 misho 186: rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_short args)
1.2 misho 187: {
188: rpc_func_t *func;
189: u_char str[MAXPATHLEN + UCHAR_MAX + 1];
190:
1.4 misho 191: memset(str, 0, sizeof str);
1.2 misho 192: if (!srv || !csFunc) {
193: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n");
194: return -1;
195: }
196: if (!(func = malloc(sizeof(rpc_func_t)))) {
197: LOGERR;
198: return -1;
199: } else {
200: memset(func, 0, sizeof(rpc_func_t));
1.4 misho 201: strlcpy((char*) func->func_name, csFunc, sizeof func->func_name);
1.2 misho 202: }
203: if (csModule) {
1.4 misho 204: strlcpy((char*) func->func_file, csModule, sizeof func->func_file);
205: strlcpy((char*) str, csModule, sizeof str);
1.2 misho 206: }
1.4 misho 207: strlcat((char*) str, "__", sizeof str);
208: strlcat((char*) str, csFunc, sizeof str);
1.2 misho 209:
1.4 misho 210: func->func_tag = crcFletcher16((u_short*) str, sizeof str / 2);
211: func->func_hash = hash_fnv((char*) str, sizeof str);
1.2 misho 212:
213: func->func_parent = srv;
214:
1.4 misho 215: if (args > 0 && rpc_srv_allocVars(func, args) == -1) {
1.2 misho 216: free(func);
217: return -1;
218: }
219:
220: pthread_mutex_lock(&srv->srv_mtx);
221: func->func_next = srv->srv_funcs;
222: srv->srv_funcs = func;
223: pthread_mutex_unlock(&srv->srv_mtx);
1.4.2.4 ! misho 224: printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<func(%s)=%p\n", func->func_name, func);
1.2 misho 225: return 0;
226: }
227:
228: /*
229: * rpc_srv_unregisterCall() Unregister call from RPC server
230: * @srv = RPC Server instance
231: * @csModule = Module name, if NULL self binary
232: * @csFunc = Function name
233: * return: -1 error, 0 not found call, 1 unregister ok
234: */
235: int
236: rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
237: {
238: rpc_func_t func, *f, *curr;
239: u_char str[MAXPATHLEN + UCHAR_MAX + 1];
240:
241: memset(&func, 0, sizeof(rpc_func_t));
1.4 misho 242: memset(str, 0, sizeof str);
1.2 misho 243: if (!srv || !csFunc) {
244: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n");
245: return -1;
246: } else
1.4 misho 247: strlcpy((char*) func.func_name, csFunc, sizeof func.func_name);
1.2 misho 248: if (csModule) {
1.4 misho 249: strlcpy((char*) func.func_file, csModule, sizeof func.func_file);
250: strlcpy((char*) str, csModule, sizeof str);
1.2 misho 251: }
1.4 misho 252: strlcat((char*) str, "__", sizeof str);
253: strlcat((char*) str, csFunc, sizeof str);
1.2 misho 254:
1.4 misho 255: func.func_tag = crcFletcher16((u_short*) str, sizeof str / 2);
256: func.func_hash = hash_fnv((char*) str, sizeof str);
1.2 misho 257:
1.4.2.4 ! misho 258: pthread_mutex_lock(&srv->srv_mtx);
1.2 misho 259: f = rpc_srv_getCall(srv, func.func_tag, func.func_hash);
1.3 misho 260: if (!f) /* not found element for unregister */
1.2 misho 261: return 0;
262:
1.4.2.4 ! misho 263: printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>func(%s)=%p\n", f->func_name, f);
1.3 misho 264: if (srv->srv_funcs == f) { /* if is 1st element */
1.2 misho 265: srv->srv_funcs = srv->srv_funcs->func_next;
266:
1.4.2.4 ! misho 267: rpc_srv_destroyVars(f);
1.2 misho 268: free(f);
1.4.2.4 ! misho 269: f = NULL;
1.2 misho 270: } else {
271: for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next);
272: curr->func_next = curr->func_next->func_next;
273:
1.4.2.4 ! misho 274: rpc_srv_destroyVars(f);
1.2 misho 275: free(f);
1.4.2.4 ! misho 276: f = NULL;
1.2 misho 277: }
278: pthread_mutex_unlock(&srv->srv_mtx);
279:
280: return 1;
281: }
282:
283: /*
284: * rpc_srv_getCall() Get registered call from RPC server
285: * @srv = RPC Server instance
286: * @tag = tag for function
287: * @hash = hash for function
288: * return: NULL not found call, !=NULL return call
289: */
290: inline rpc_func_t *
291: rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)
292: {
293: rpc_func_t *f;
294:
295: if (!srv) {
296: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
297: return NULL;
298: }
299:
300: for (f = srv->srv_funcs; f; f = f->func_next)
301: if (f->func_tag == tag && f->func_hash == hash)
302: break;
303:
304: return f;
305: }
306:
307: /*
308: * rpc_srv_getFunc() Get registered call from RPC server by Name
309: * @srv = RPC Server instance
310: * @csModule = Module name, if NULL self binary
311: * @csFunc = Function name
312: * return: NULL not found call, !=NULL return call
313: */
314: rpc_func_t *
315: rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
316: {
317: rpc_func_t func;
318: u_char str[MAXPATHLEN + UCHAR_MAX + 1];
319:
320: memset(&func, 0, sizeof(rpc_func_t));
1.4 misho 321: memset(str, 0, sizeof str);
1.2 misho 322: if (!srv || !csFunc) {
323: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
324: return NULL;
325: } else
1.4 misho 326: strlcpy((char*) func.func_name, csFunc, sizeof func.func_name);
1.2 misho 327: if (csModule) {
1.4 misho 328: strlcpy((char*) func.func_file, csModule, sizeof func.func_file);
329: strlcpy((char*) str, csModule, sizeof str);
1.2 misho 330: }
1.4 misho 331: strlcat((char*) str, "__", sizeof str);
332: strlcat((char*) str, csFunc, sizeof str);
1.2 misho 333:
1.4 misho 334: func.func_tag = crcFletcher16((u_short*) str, sizeof str / 2);
335: func.func_hash = hash_fnv((char*) str, sizeof str);
1.2 misho 336:
337: return rpc_srv_getCall(srv, func.func_tag, func.func_hash);
338: }
339:
340: // ---------------------------------------------------------
341:
342: /*
343: * rpc_srv_getBLOB() Get registered BLOB
344: * @srv = RPC Server instance
345: * @var = hash for variable
346: * return: NULL not found, !=NULL return blob var
347: */
348: inline rpc_blob_t *
349: rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
350: {
351: rpc_blob_t *b;
352:
353: if (!srv) {
354: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n");
355: return NULL;
356: }
357:
358: pthread_mutex_lock(&srv->srv_blob.mtx);
359: for (b = srv->srv_blob.blobs; b; b = b->blob_next) {
360: if (b->blob_var == var)
361: break;
362: }
363: pthread_mutex_unlock(&srv->srv_blob.mtx);
364:
365: return b;
366: }
367:
368: /*
369: * rpc_srv_registerBLOB() Register new BLOB to server
370: * @srv = RPC Server instance
371: * @len = BLOB length
372: * return: NULL error or new registered BLOB
373: */
374: rpc_blob_t *
375: rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)
376: {
377: rpc_blob_t *blob = NULL;
378:
379: if (!srv || !len) {
380: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register BLOB to server ...\n");
381: return blob;
382: }
383:
384: blob = rpc_srv_blobCreate(srv, len);
385: if (blob) {
386: pthread_mutex_lock(&srv->srv_blob.mtx);
387: blob->blob_next = srv->srv_blob.blobs;
388: srv->srv_blob.blobs = blob;
389: pthread_mutex_unlock(&srv->srv_blob.mtx);
390: }
391:
392: return blob;
393: }
394:
395: /*
396: * rpc_srv_unregisterBLOB() Unregister BLOB from server
397: * @srv = RPC Server instance
398: * @var = BLOB Variable for unregister
399: * return: -1 error, 0 not found call, 1 unregister ok
400: */
401: int
402: rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
403: {
404: rpc_blob_t *b, *curr;
405:
406: if (!srv) {
407: rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister BLOB from server ...\n");
408: return -1;
409: }
410:
411: b = rpc_srv_getBLOB(srv, var);
1.3 misho 412: if (!b) /* not found element for unregister */
1.2 misho 413: return 0;
414:
415: pthread_mutex_lock(&srv->srv_blob.mtx);
1.3 misho 416: if (srv->srv_blob.blobs == b) { /* if is 1st element */
1.2 misho 417: srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next;
418: } else {
419: for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next);
420: curr->blob_next = curr->blob_next->blob_next;
421: }
422: rpc_srv_blobFree(srv, b);
423: free(b);
424: pthread_mutex_unlock(&srv->srv_blob.mtx);
425:
426: return 1;
427: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>