Annotation of libaitrpc/src/lists.c, revision 1.1.2.9

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

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