added API for rpc lists;
This commit is contained in:
		
							parent
							
								
									f32b2ed49b
								
							
						
					
					
						commit
						bc6f33ca29
					
				| @ -181,8 +181,8 @@ int connections_subsystem_setrpclist_function(usrtc_t* (*get_rpc_typed_list_tree | |||||||
| #define connections_subsystem_set_rpctlist_call(c, fuu)  (c)->set_typed_list_callback = fuu | #define connections_subsystem_set_rpctlist_call(c, fuu)  (c)->set_typed_list_callback = fuu | ||||||
| 
 | 
 | ||||||
| /* connection */ | /* connection */ | ||||||
| int connection_initiate (conn_t *co, const char *host, int port,  | int connection_initiate (conn_t *co, const char *host, int port, | ||||||
|         const char *SSL_cert, perm_ctx_t *pctx); |                          const char *SSL_cert, perm_ctx_t *pctx); | ||||||
| 
 | 
 | ||||||
| int connection_create(conn_t *co, int sck); | int connection_create(conn_t *co, int sck); | ||||||
| 
 | 
 | ||||||
| @ -212,5 +212,20 @@ int msg_send_pulse_timed(chnl_t *ch, sexp_t *sx, struct timespec *tio); | |||||||
| 
 | 
 | ||||||
| int msg_send_pulse_nowait(chnl_t *ch, sexp_t *sx); | int msg_send_pulse_nowait(chnl_t *ch, sexp_t *sx); | ||||||
| 
 | 
 | ||||||
|  | /* RPC List API */ | ||||||
|  | #define SNTL_FILTER_INC  0xa | ||||||
|  | #define SNTL_FILTER_EXC  0xb | ||||||
|  | #define SNTL_FILTER_END  -1 | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_init(usrtc_t *tree); | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_add(usrtc_t *tree, int type, const char *description, | ||||||
|  |                      const char *version); | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name, | ||||||
|  |                               int (*rpcf)(void *, sexp_t *)); | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter); | ||||||
|  | 
 | ||||||
| #endif	/* __ESXC_CONNECTION_H_ */ | #endif	/* __ESXC_CONNECTION_H_ */ | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										149
									
								
								lib/rpclist.c
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								lib/rpclist.c
									
									
									
									
									
								
							| @ -32,13 +32,160 @@ static long __cmp_int(const void *a, const void *b) | |||||||
|   return *(int *)a - *(int *)b; |   return *(int *)a - *(int *)b; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static long __cmp_cstr(const void *a, const void *b) | ||||||
|  | { | ||||||
|  |   return strcmp((char *)a, (char *)b); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int sntl_rpclist_init(usrtc_t *tree) | int sntl_rpclist_init(usrtc_t *tree) | ||||||
| { | { | ||||||
|   usrtc_init(tree, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int); |   usrtc_init(tree, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int); | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int sntl_rpclist_add(usrtc_t *tree, int type, const char *description) | int sntl_rpclist_add(usrtc_t *tree, int type, const char *description, | ||||||
|  |                      const char *version) | ||||||
| { | { | ||||||
|  |   rpc_typed_list_t *nlist = NULL; | ||||||
|  |   cx_rpc_list_t *rpc_list = NULL; | ||||||
|  |   usrtc_t *rtree = NULL; | ||||||
|  |   usrtc_node_t *node = NULL; | ||||||
|  |   int r = ENOMEM; | ||||||
|  | 
 | ||||||
|  |   /* check for existing one */ | ||||||
|  |   node = usrtc_lookup(tree, &type); | ||||||
|  |   if(node) return EEXIST; | ||||||
|  | 
 | ||||||
|  |   /* allocate all */ | ||||||
|  |   if(!(nlist = malloc(sizeof(rpc_typed_list_t)))) goto __fail; | ||||||
|  |   else memset(nlist, 0, sizeof(rpc_typed_list_t)); | ||||||
|  |   if(!(rpc_list = malloc(sizeof(cx_rpc_list_t)))) goto __fail; | ||||||
|  |   else memset(rpc_list, 0, sizeof(cx_rpc_list_t)); | ||||||
|  |   if(!(rtree = malloc(sizeof(usrtc_t)))) goto __fail; | ||||||
|  | 
 | ||||||
|  |   /* version and description */ | ||||||
|  |   if(!(nlist->description = strdup(description))) goto __fail_a; | ||||||
|  |   if(version) { /* in case of existing version */ | ||||||
|  |     if(!(rpc_list->opt_version = strdup(version))) goto __fail_a; | ||||||
|  |   } | ||||||
|  |   /* initialize all */ | ||||||
|  |   nlist->type_id = type; | ||||||
|  |   nlist->rpc_list = rpc_list; | ||||||
|  |   rpc_list->rpc_tree = rtree; | ||||||
|  |   usrtc_node_init(&(nlist->lnode), nlist); | ||||||
|  |   usrtc_init(rtree, USRTC_SPLAY, MAX_RPC_LIST, __cmp_cstr); | ||||||
|  |   node = &(nlist->lnode); | ||||||
|  |   /* insert it */ | ||||||
|  |   usrtc_insert(tree, node, &(nlist->type_id)); | ||||||
|  | 
 | ||||||
|  |   return 0; | ||||||
|  |  __fail_a: | ||||||
|  |   if(nlist->description) free(nlist->description); | ||||||
|  |   if(rpc_list->opt_version) free(rpc_list->opt_version); | ||||||
|  |  __fail: | ||||||
|  |   if(nlist) free(nlist); | ||||||
|  |   if(rpc_list) free(rpc_list); | ||||||
|  |   if(rtree) free(rtree); | ||||||
|  |   return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_add_function(usrtc_t *tree, int type, const char *fu_name, | ||||||
|  |                               int (*rpcf)(void *, sexp_t *)) | ||||||
|  | { | ||||||
|  |   usrtc_node_t *node; | ||||||
|  |   rpc_typed_list_t *tlist; | ||||||
|  |   cx_rpc_list_t *rlist; | ||||||
|  |   cx_rpc_t *rentry = NULL; | ||||||
|  | 
 | ||||||
|  |   node = usrtc_lookup(tree, &type); | ||||||
|  |   if(!node) return ENOENT; | ||||||
|  |   else tlist = (rpc_typed_list_t *)usrtc_node_getdata(node); | ||||||
|  |   rlist = tlist->rpc_list; /* get rpc list */ | ||||||
|  | 
 | ||||||
|  |   /* ok, we don't allow dupes */ | ||||||
|  |   node = usrtc_lookup(rlist->rpc_tree, fu_name); | ||||||
|  |   if(node) return EEXIST; | ||||||
|  |   if(!(rentry = malloc(sizeof(cx_rpc_t)))) return ENOMEM; | ||||||
|  |   else if(!(rentry->name = strdup(fu_name))) { | ||||||
|  |     free(rentry); | ||||||
|  |     return ENOMEM; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   /* init */ | ||||||
|  |   usrtc_node_init(&(rentry->node), rentry); | ||||||
|  |   rentry->rpcf = rpcf; | ||||||
|  |   node = &(rentry->node); | ||||||
|  |   usrtc_insert(rlist->rpc_tree, node, rentry->name); /* insert it */ | ||||||
|  | 
 | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | int sntl_rpclist_filter(usrtc_t *source, usrtc_t **dest, int flag, int *filter) | ||||||
|  | { | ||||||
|  |   int r = 0, *f = filter, i; | ||||||
|  |   usrtc_t *destination = NULL; | ||||||
|  |   usrtc_node_t *node; | ||||||
|  |   rpc_typed_list_t *tlist, *tlist_filter; | ||||||
|  | 
 | ||||||
|  |   if(!filter) return EINVAL; | ||||||
|  |   if(!(destination = malloc(sizeof(usrtc_t)))) return ENOMEM; | ||||||
|  |   else usrtc_init(destination, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int); | ||||||
|  | 
 | ||||||
|  |   switch(flag) { | ||||||
|  |   case SNTL_FILTER_EXC: | ||||||
|  |     for(node = usrtc_first(source); ; node = usrtc_next(source, node)) { | ||||||
|  |       tlist = (rpc_typed_list_t *)usrtc_node_getdata(node); | ||||||
|  |       r = ENOENT; | ||||||
|  |       for(i = *f; i != SNTL_FILTER_END; f++, i = *f) { | ||||||
|  |         if(tlist->type_id == i) { | ||||||
|  |           r = 0; break; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       if(r) { /* we should clone it */ | ||||||
|  |         if(!(tlist_filter = malloc(sizeof(rpc_typed_list_t)))) continue; /* skip */ | ||||||
|  |         else { | ||||||
|  |           tlist_filter->type_id = tlist->type_id; | ||||||
|  |           tlist_filter->description = tlist->description; | ||||||
|  |           tlist_filter->rpc_list = tlist->rpc_list; | ||||||
|  |           usrtc_node_init(&(tlist_filter->lnode), tlist_filter); | ||||||
|  |           usrtc_insert(destination, &(tlist_filter->lnode), &(tlist_filter->type_id)); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       if(node == usrtc_last(source)) break; | ||||||
|  |     } | ||||||
|  |     r = 0; | ||||||
|  |     break; | ||||||
|  |   case SNTL_FILTER_INC: | ||||||
|  |     for(i = *f; i != SNTL_FILTER_END; f++, i = *f) { | ||||||
|  |       node = usrtc_lookup(source, &i); | ||||||
|  |       if(!node) continue; /* skip it at all */ | ||||||
|  |       else tlist = (rpc_typed_list_t *)usrtc_node_getdata(node); | ||||||
|  |       /* clone tlist */ | ||||||
|  |       if(!(tlist_filter = malloc(sizeof(rpc_typed_list_t)))) continue; /* skip */ | ||||||
|  |       else { | ||||||
|  |         tlist_filter->type_id = tlist->type_id; | ||||||
|  |         tlist_filter->description = tlist->description; | ||||||
|  |         tlist_filter->rpc_list = tlist->rpc_list; | ||||||
|  |         usrtc_node_init(&(tlist_filter->lnode), tlist_filter); | ||||||
|  |         usrtc_insert(destination, &(tlist_filter->lnode), &(tlist_filter->type_id)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     break; | ||||||
|  |   default: | ||||||
|  |     r = EINVAL; | ||||||
|  |     goto __fail; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if(!usrtc_count(destination)) { /* we have an empty list */ | ||||||
|  |     r = EINVAL; | ||||||
|  |     goto __fail; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   *dest = destination; | ||||||
|  | 
 | ||||||
|  |   return 0; | ||||||
|  |  __fail: | ||||||
|  |   if(destination) free(destination); | ||||||
|  |   return r; | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user