Diff for /libaitrpc/src/lists.c between versions 1.1.2.1 and 1.1.2.9

version 1.1.2.1, 2010/06/23 11:34:48 version 1.1.2.9, 2011/03/15 16:48:31
Line 1 Line 1
 #include "global.h"  #include "global.h"
   
   
   /*
    * rpc_srv_retValsCall() Declare return variables for RPC call and zeroed values
                                           (for safe handling return values, use this!)
    * @call = RPC function call
    * @return_vals = Number of return variables
    * return: NULL error, !=NULL array with return values for RPC call with return_vals items
    */
   inline rpc_val_t *
   rpc_srv_retValsCall(rpc_func_t * __restrict call, int return_vals)
   {
           rpc_val_t *v = NULL;
   
           if (rpc_srv_declValsCall(call, return_vals) == -1)
                   return NULL;
           else
                   rpc_srv_zeroValsCall(call);
           if (rpc_srv_getValsCall(call, &v) == -1)
                   return NULL;
   
           return v;
   }
   
   /*
    * rpc_srv_freeValsCall() Free return variables for RPC call
    * @call = RPC function call
    * return: none
    */
   inline void
   rpc_srv_freeValsCall(rpc_func_t * __restrict call)
   {
           rpc_srv_declValsCall(call, 0);
   }
   
   /*
    * rpc_srv_declValsCall() Declare return variables for RPC call, 
                                   if already allocated memory for RPC call return values 
                                   function reallocate used space with return_vals count elements
    * @call = RPC function call
    * @return_vals = Number of return variables
    * return: -1 error, !=-1 ok
    */
   inline int
   rpc_srv_declValsCall(rpc_func_t * __restrict call, int return_vals)
   {
           void *ptr;
   
           if (!call || return_vals < 0) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t declare return variables for RPC call...\n");
                   return -1;
           } else
                   call->func_args = return_vals;
   
           if (!return_vals) {
                   if (call->func_vals) {
                           free(call->func_vals);
                           call->func_vals = NULL;
                   }
           } else {
                   ptr = realloc(call->func_vals, return_vals * sizeof(rpc_val_t));
                   if (!ptr) {
                           LOGERR;
                           call->func_args = 0;
                           return -1;
                   } else
                           call->func_vals = ptr;
           }
   
           return return_vals;
   }
   
   /*
    * rpc_srv_zeroValsCall() Clean values from return variables of RPC call
    * @call = RPC function call
    * return: -1 error, !=-1 Returned number of cleaned RPC variables
    */
   inline int
   rpc_srv_zeroValsCall(rpc_func_t * __restrict call)
   {
           if (!call) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t delete return variables ...\n");
                   return -1;
           }
   
           memset(call->func_vals, 0, call->func_args * sizeof(rpc_val_t));
           return call->func_args;
   }
   
   /*
    * rpc_srv_copyValsCall() Copy return variables for RPC call to new variable
    * @call = RPC function call
    * @newvals = New allocated variables array, must be free after use
    * return: -1 error, !=-1 Returned number of copied RPC variables
    */
   inline int
   rpc_srv_copyValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict newvals)
   {
           if (!call || !newvals) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t copy return variables to new array\n");
                   return -1;
           }
   
           *newvals = calloc(call->func_args, sizeof(rpc_val_t));
           if (!*newvals) {
                   LOGERR;
                   return -1;
           } else
                   memcpy(*newvals, call->func_vals, call->func_args * sizeof(rpc_val_t));
   
           return call->func_args;
   }
   
   /*
    * rpc_srv_getValsCall() Get return variables for RPC call
    * @call = RPC function call
    * @vals = Returned variables, may be NULL
    * return: -1 error, !=-1 Number of returned variables
    */
   inline int
   rpc_srv_getValsCall(rpc_func_t * __restrict call, rpc_val_t ** __restrict vals)
   {
           if (!call) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get return variables ...\n");
                   return -1;
           }
   
           if (vals)
                   *vals = call->func_vals;
           return call->func_args;
   }
   
   // ---------------------------------------------------------
   
   /*
    * rpc_srv_registerCall() Register call to RPC server
    * @srv = RPC Server instance
    * @csModule = Module name, if NULL self binary
    * @csFunc = Function name
    * @args = Number of return function arguments, use for restriction case!
    * return: -1 error or 0 register ok
    */
   int
   rpc_srv_registerCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc, u_char args)
   {
           rpc_func_t *func;
           u_char str[MAXPATHLEN + UCHAR_MAX + 1];
   
           memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
           if (!srv || !csFunc) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register function to RPC server ...\n");
                   return -1;
           }
           if (!(func = malloc(sizeof(rpc_func_t)))) {
                   LOGERR;
                   return -1;
           } else {
                   memset(func, 0, sizeof(rpc_func_t));
                   strlcpy((char*) func->func_name, csFunc, UCHAR_MAX + 1);
           }
           if (csModule) {
                   strlcpy((char*) func->func_file, csModule, MAXPATHLEN);
                   strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
           }
           strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
           strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
   
           func->func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
           func->func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
   
           func->func_parent = srv;
   
           if (args > 0 && rpc_srv_declValsCall(func, args) == -1) {
                   free(func);
                   return -1;
           }
   
           pthread_mutex_lock(&srv->srv_mtx);
           func->func_next = srv->srv_funcs;
           srv->srv_funcs = func;
           pthread_mutex_unlock(&srv->srv_mtx);
           return 0;
   }
   
   /*
    * rpc_srv_unregisterCall() Unregister call from RPC server
    * @srv = RPC Server instance
    * @csModule = Module name, if NULL self binary
    * @csFunc = Function name
    * return: -1 error, 0 not found call, 1 unregister ok
    */
   int
   rpc_srv_unregisterCall(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
   {
           rpc_func_t func, *f, *curr;
           u_char str[MAXPATHLEN + UCHAR_MAX + 1];
   
           memset(&func, 0, sizeof(rpc_func_t));
           memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
           if (!srv || !csFunc) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister function from RPC server ...\n");
                   return -1;
           } else
                   strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
           if (csModule) {
                   strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
                   strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
           }
           strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
           strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
   
           func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
           func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
   
           f = rpc_srv_getCall(srv, func.func_tag, func.func_hash);
           if (!f)         // not found element for unregister
                   return 0;
   
           pthread_mutex_lock(&srv->srv_mtx);
           if (srv->srv_funcs == f) {      // if is 1st element
                   srv->srv_funcs = srv->srv_funcs->func_next;
   
                   if (f->func_args && f->func_vals)
                           free(f->func_vals);
                   free(f);
           } else {
                   for (curr = srv->srv_funcs; curr->func_next != f; curr = curr->func_next);
                   curr->func_next = curr->func_next->func_next;
   
                   if (f->func_args && f->func_vals)
                           free(f->func_vals);
                   free(f);
           }
           pthread_mutex_unlock(&srv->srv_mtx);
   
           return 1;
   }
   
   /*
    * rpc_srv_getCall() Get registered call from RPC server
    * @srv = RPC Server instance
    * @tag = tag for function
    * @hash = hash for function
    * return: NULL not found call, !=NULL return call
    */
   inline rpc_func_t *
   rpc_srv_getCall(rpc_srv_t * __restrict srv, uint16_t tag, uint32_t hash)
   {
           rpc_func_t *f;
   
           if (!srv) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
                   return NULL;
           }
   
           for (f = srv->srv_funcs; f; f = f->func_next)
                   if (f->func_tag == tag && f->func_hash == hash)
                           break;
   
           return f;
   }
   
   /*
    * rpc_srv_getFunc() Get registered call from RPC server by Name
    * @srv = RPC Server instance
    * @csModule = Module name, if NULL self binary
    * @csFunc = Function name
    * return: NULL not found call, !=NULL return call
    */
   rpc_func_t *
   rpc_srv_getFunc(rpc_srv_t * __restrict srv, const char *csModule, const char *csFunc)
   {
           rpc_func_t func;
           u_char str[MAXPATHLEN + UCHAR_MAX + 1];
   
           memset(&func, 0, sizeof(rpc_func_t));
           memset(str, 0, MAXPATHLEN + UCHAR_MAX + 1);
           if (!srv || !csFunc) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get function from RPC server ...\n");
                   return NULL;
           } else
                   strlcpy((char*) func.func_name, csFunc, UCHAR_MAX + 1);
           if (csModule) {
                   strlcpy((char*) func.func_file, csModule, MAXPATHLEN);
                   strlcpy((char*) str, csModule, MAXPATHLEN + UCHAR_MAX + 1);
           }
           strlcat((char*) str, "__", MAXPATHLEN + UCHAR_MAX + 1);
           strlcat((char*) str, csFunc, MAXPATHLEN + UCHAR_MAX + 1);
   
           func.func_tag = crcFletcher16((u_short*) str, (MAXPATHLEN + UCHAR_MAX + 1) / 2);
           func.func_hash = hash_fnv((char*) str, MAXPATHLEN + UCHAR_MAX + 1);
   
           return rpc_srv_getCall(srv, func.func_tag, func.func_hash);
   }
   
   // ---------------------------------------------------------
   
   /*
    * rpc_srv_getBLOB() Get registered BLOB 
    * @srv = RPC Server instance
    * @var = hash for variable
    * return: NULL not found, !=NULL return blob var
    */
   inline rpc_blob_t *
   rpc_srv_getBLOB(rpc_srv_t * __restrict srv, uint32_t var)
   {
           rpc_blob_t *b;
   
           if (!srv) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t get variable from BLOB server ...\n");
                   return NULL;
           }
   
           pthread_mutex_lock(&srv->srv_blob.mtx);
           for (b = srv->srv_blob.blobs; b; b = b->blob_next) {
                   if (b->blob_var == var)
                           break;
           }
           pthread_mutex_unlock(&srv->srv_blob.mtx);
   
           return b;
   }
   
   /*
    * rpc_srv_registerBLOB() Register new BLOB to server
    * @srv = RPC Server instance
    * @len = BLOB length
    * return: NULL error or new registered BLOB
    */
   rpc_blob_t *
   rpc_srv_registerBLOB(rpc_srv_t * __restrict srv, size_t len)
   {
           rpc_blob_t *blob = NULL;
   
           if (!srv || !len) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t register BLOB to server ...\n");
                   return blob;
           }
   
           blob = rpc_srv_blobCreate(srv, len);
           if (blob) {
                   pthread_mutex_lock(&srv->srv_blob.mtx);
                   blob->blob_next = srv->srv_blob.blobs;
                   srv->srv_blob.blobs = blob;
                   pthread_mutex_unlock(&srv->srv_blob.mtx);
           }
   
           return blob;
   }
   
   /*
    * rpc_srv_unregisterBLOB() Unregister BLOB from server
    * @srv = RPC Server instance
    * @var = BLOB Variable for unregister
    * return: -1 error, 0 not found call, 1 unregister ok
    */
   int
   rpc_srv_unregisterBLOB(rpc_srv_t * __restrict srv, uint32_t var)
   {
           rpc_blob_t *b, *curr;
   
           if (!srv) {
                   rpc_SetErr(EINVAL, "Error:: Invalid parameter can`t unregister BLOB from server ...\n");
                   return -1;
           }
   
           b = rpc_srv_getBLOB(srv, var);
           if (!b)         // not found element for unregister
                   return 0;
   
           pthread_mutex_lock(&srv->srv_blob.mtx);
           if (srv->srv_blob.blobs == b) { // if is 1st element
                   srv->srv_blob.blobs = srv->srv_blob.blobs->blob_next;
           } else {
                   for (curr = srv->srv_blob.blobs; curr->blob_next != b; curr = curr->blob_next);
                   curr->blob_next = curr->blob_next->blob_next;
           }
           rpc_srv_blobFree(srv, b);
           free(b);
           pthread_mutex_unlock(&srv->srv_blob.mtx);
   
           return 1;
   }

Removed from v.1.1.2.1  
changed lines
  Added in v.1.1.2.9


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