File:  [ELWIX - Embedded LightWeight unIX -] / libaitrpc / src / lists.c
Revision 1.1.2.5: download - view: text, annotated - select for diffs - revision graph
Wed Jul 7 12:29:50 2010 UTC (13 years, 11 months ago) by misho
Branches: rpc1_0
correct comment info
and fix permissions

    1: #include "global.h"
    2: 
    3: 
    4: /*
    5:  * rpc_srv_retValsCall() Declare return variables for RPC call and zeroed values
    6: 					(for safe handling return values, use this!)
    7:  * @call = RPC function call
    8:  * @return_vals = Number of return variables
    9:  * return: NULL error, !=NULL array with return values for RPC call with return_vals items
   10:  */
   11: inline rpc_val_t *
   12: rpc_srv_retValsCall(rpc_func_t * __restrict call, int return_vals)
   13: {
   14: 	rpc_val_t *v = NULL;
   15: 
   16: 	if (rpc_srv_declValsCall(call, return_vals) == -1)
   17: 		return NULL;
   18: 	else
   19: 		rpc_srv_zeroValsCall(call);
   20: 	if (rpc_srv_getValsCall(call, &v) == -1)
   21: 		return NULL;
   22: 
   23: 	return v;
   24: }
   25: 
   26: /*
   27:  * rpc_srv_freeValsCall() Free return variables for RPC call
   28:  * @call = RPC function call
   29:  * return: none
   30:  */
   31: inline void
   32: rpc_srv_freeValsCall(rpc_func_t * __restrict call)
   33: {
   34: 	rpc_srv_declValsCall(call, 0);
   35: }
   36: 
   37: /*
   38:  * rpc_srv_declValsCall() Declare return variables for RPC call, 
   39: 				if already allocated memory for RPC call return values 
   40: 				function reallocate used space with return_vals count elements
   41:  * @call = RPC function call
   42:  * @return_vals = Number of return variables
   43:  * return: -1 error, !=-1 ok
   44:  */
   45: inline int
   46: rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals)
   47: {
   48: 	void *ptr;
   49: 
   50: 	if (!call || return_vals < 0) {
   51: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t declare return variables for RPC call...\n");
   52: 		return -1;
   53: 	} else
   54: 		call->func_args = return_vals;
   55: 
   56: 	if (!return_vals) {
   57: 		if (call->func_vals) {
   58: 			free(call->func_vals);
   59: 			call->func_vals = NULL;
   60: 		}
   61: 	} else {
   62: 		ptr = realloc(call->func_vals, return_vals * sizeof(rpc_val_t));
   63: 		if (!ptr) {
   64: 			LOGERR;
   65: 			return -1;
   66: 		} else
   67: 			call->func_vals = ptr;
   68: 	}
   69: 
   70: 	return call->func_args;
   71: }
   72: 
   73: /*
   74:  * rpc_srv_zeroValsCall() Clean values from return variables of RPC call
   75:  * @call = RPC function call
   76:  * return: -1 error, !=-1 Returned number of cleaned RPC variables
   77:  */
   78: inline int
   79: rpc_srv_zeroValsCall(rpc_func_t * __restrict call)
   80: {
   81: 	if (!call) {
   82: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete return variables ...\n");
   83: 		return -1;
   84: 	}
   85: 
   86: 	memset(call->func_vals, 0, call->func_args * sizeof(rpc_val_t));
   87: 	return call->func_args;
   88: }
   89: 
   90: /*
   91:  * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
   92:  * @call = RPC function call
   93:  * @newvals = New allocated variables array, must be free after use
   94:  * return: -1 error, !=-1 Returned number of copied RPC variables
   95:  */
   96: inline int
   97: rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals)
   98: {
   99: 	if (!call || !newvals) {
  100: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy return variables to new array\n");
  101: 		return -1;
  102: 	}
  103: 
  104: 	*newvals = calloc(call->func_args, sizeof(rpc_val_t));
  105: 	if (!*newvals) {
  106: 		LOGERR;
  107: 		return -1;
  108: 	} else
  109: 		memcpy(*newvals, call->func_vals, call->func_args * sizeof(rpc_val_t));
  110: 
  111: 	return call->func_args;
  112: }
  113: 
  114: /*
  115:  * rpc_srv_getValsCall() Get return variables for RPC call
  116:  * @call = RPC function call
  117:  * @vals = Returned variables, may be NULL
  118:  * return: -1 error, !=-1 Number of returned variables
  119:  */
  120: inline int
  121: rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals)
  122: {
  123: 	if (!call) {
  124: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get return variables ...\n");
  125: 		return -1;
  126: 	}
  127: 
  128: 	if (vals)
  129: 		*vals = call->func_vals;
  130: 	return call->func_args;
  131: }
  132: 
  133: // ---------------------------------------------------------
  134: 
  135: /*
  136:  * rpc_srv_registerCall() Register call to RPC server
  137:  * @srv = RPC Server instance
  138:  * @csModule = Module name, if NULL self binary
  139:  * @csFunc = Function name
  140:  * @args = Number of function arguments
  141:  * return: -1 error or 0 register ok
  142:  */
  143: int
  144: rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_char args)
  145: {
  146: 	rpc_func_t *func;
  147: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  148: 
  149: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  150: 	if (!srv || !csFunc) {
  151: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n");
  152: 		return -1;
  153: 	}
  154: 	if (!(func = malloc(sizeof(rpc_func_t)))) {
  155: 		LOGERR;
  156: 		return -1;
  157: 	} else {
  158: 		memset(func, 0, sizeof(rpc_func_t));
  159: 		strlcpy((char*) func->func_name, csFunc, UCHAR_MAX + 1);
  160: 	}
  161: 	if (csModule) {
  162: 		strlcpy((char*) func->func_file, csModule, MAXPATHLEN);
  163: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  164: 	}
  165: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  166: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  167: 
  168: 	func->func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  169: 	func->func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  170: 
  171: 	func->func_parent = srv;
  172: 
  173: 	if (rpc_srv_declValsCall(func, args) == -1) {
  174: 		free(func);
  175: 		return -1;
  176: 	}
  177: 
  178: 	pthread_mutex_lock(&srv->srv_mtx);
  179: 	func->func_next = srv->srv_funcs;
  180: 	srv->srv_funcs = func;
  181: 	pthread_mutex_unlock(&srv->srv_mtx);
  182: 	return 0;
  183: }
  184: 
  185: /*
  186:  * rpc_srv_unregisterCall() Unregister call from RPC server
  187:  * @srv = RPC Server instance
  188:  * @csModule = Module name, if NULL self binary
  189:  * @csFunc = Function name
  190:  * return: -1 error, 0 not found call, 1 unregister ok
  191:  */
  192: int
  193: rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
  194: {
  195: 	rpc_func_t func, *f, *curr;
  196: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  197: 
  198: 	memset(&func, 0, sizeof(rpc_func_t));
  199: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  200: 	if (!srv || !csFunc) {
  201: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n");
  202: 		return -1;
  203: 	} else
  204: 		strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
  205: 	if (csModule) {
  206: 		strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
  207: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  208: 	}
  209: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  210: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  211: 
  212: 	func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  213: 	func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  214: 
  215: 	f = rpc_srv_getCall(srv, func.func_tag, func.func_hash);
  216: 	if (!f)		// not found element for unregister
  217: 		return 0;
  218: 
  219: 	pthread_mutex_lock(&srv->srv_mtx);
  220: 	if (srv->srv_funcs == f) {	// if is 1st element
  221: 		srv->srv_funcs = srv->srv_funcs->func_next;
  222: 
  223: 		if (f->func_args && f->func_vals)
  224: 			free(f->func_vals);
  225: 		free(f);
  226: 	} else {
  227: 		for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next);
  228: 		curr->func_next = curr->func_next->func_next;
  229: 
  230: 		if (f->func_args && f->func_vals)
  231: 			free(f->func_vals);
  232: 		free(f);
  233: 	}
  234: 	pthread_mutex_unlock(&srv->srv_mtx);
  235: 
  236: 	return 1;
  237: }
  238: 
  239: /*
  240:  * rpc_srv_getCall() Get registered call from RPC server
  241:  * @srv = RPC Server instance
  242:  * @tag = tag for function
  243:  * @hash = hash for function
  244:  * return: NULL not found call, !=NULL return call
  245:  */
  246: inline rpc_func_t *
  247: rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)
  248: {
  249: 	rpc_func_t *f;
  250: 
  251: 	if (!srv) {
  252: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
  253: 		return NULL;
  254: 	}
  255: 
  256: 	for (f = srv->srv_funcs; f; f = f->func_next)
  257: 		if (f->func_tag == tag && f->func_hash == hash)
  258: 			break;
  259: 
  260: 	return f;
  261: }
  262: 
  263: /*
  264:  * rpc_srv_getFunc() Get registered call from RPC server by Name
  265:  * @srv = RPC Server instance
  266:  * @csModule = Module name, if NULL self binary
  267:  * @csFunc = Function name
  268:  * return: NULL not found call, !=NULL return call
  269:  */
  270: rpc_func_t *
  271: rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
  272: {
  273: 	rpc_func_t func;
  274: 	u_char str[MAXPATHLEN + UCHAR_MAX + 1];
  275: 
  276: 	memset(&func, 0, sizeof(rpc_func_t));
  277: 	memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
  278: 	if (!srv || !csFunc) {
  279: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
  280: 		return NULL;
  281: 	} else
  282: 		strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
  283: 	if (csModule) {
  284: 		strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
  285: 		strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
  286: 	}
  287: 	strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
  288: 	strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
  289: 
  290: 	func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
  291: 	func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
  292: 
  293: 	return rpc_srv_getCall(srv, func.func_tag, func.func_hash);
  294: }
  295: 
  296: // ---------------------------------------------------------
  297: 
  298: /*
  299:  * rpc_srv_getBLOB() Get registered BLOB 
  300:  * @srv = RPC Server instance
  301:  * @var = hash for variable
  302:  * return: NULL not found, !=NULL return blob var
  303:  */
  304: inline rpc_blob_t *
  305: rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
  306: {
  307: 	rpc_blob_t *b;
  308: 
  309: 	if (!srv) {
  310: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n");
  311: 		return NULL;
  312: 	}
  313: 
  314: 	for (b = srv->srv_blob.blobs; b; b = b->blob_next)
  315: 		if (b->blob_var == var)
  316: 			break;
  317: 
  318: 	return b;
  319: }
  320: 
  321: /*
  322:  * rpc_srv_registerBLOB() Register new BLOB to server
  323:  * @srv = RPC Server instance
  324:  * @len = BLOB length
  325:  * return: NULL error or new registered BLOB
  326:  */
  327: rpc_blob_t *
  328: rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)
  329: {
  330: 	rpc_blob_t *blob = NULL;
  331: 
  332: 	if (!srv || !len) {
  333: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register BLOB to server ...\n");
  334: 		return blob;
  335: 	}
  336: 
  337: 	blob = rpc_srv_blobCreate(srv, len);
  338: 	if (blob) {
  339: 		pthread_mutex_lock(&srv->srv_blob.mtx);
  340: 		blob->blob_next = srv->srv_blob.blobs;
  341: 		srv->srv_blob.blobs = blob;
  342: 		pthread_mutex_unlock(&srv->srv_blob.mtx);
  343: 	}
  344: 
  345: 	return blob;
  346: }
  347: 
  348: /*
  349:  * rpc_srv_unregisterBLOB() Unregister BLOB from server
  350:  * @srv = RPC Server instance
  351:  * @var = BLOB Variable for unregister
  352:  * return: -1 error, 0 not found call, 1 unregister ok
  353:  */
  354: int
  355: rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
  356: {
  357: 	rpc_blob_t *b, *curr;
  358: 
  359: 	if (!srv) {
  360: 		rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister BLOB from server ...\n");
  361: 		return -1;
  362: 	}
  363: 
  364: 	b = rpc_srv_getBLOB(srv, var);
  365: 	if (!b)		// not found element for unregister
  366: 		return 0;
  367: 
  368: 	pthread_mutex_lock(&srv->srv_blob.mtx);
  369: 	if (srv->srv_blob.blobs == b) {	// if is 1st element
  370: 		srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next;
  371: 	} else {
  372: 		for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next);
  373: 		curr->blob_next = curr->blob_next->blob_next;
  374: 	}
  375: 	rpc_srv_blobFree(srv, b);
  376: 	free(b);
  377: 	pthread_mutex_unlock(&srv->srv_blob.mtx);
  378: 
  379: 	return 1;
  380: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>