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
 | 
			
		||||
 | 
			
		||||
/* connection */
 | 
			
		||||
int connection_initiate (conn_t *co, const char *host, int port, 
 | 
			
		||||
        const char *SSL_cert, perm_ctx_t *pctx);
 | 
			
		||||
int connection_initiate (conn_t *co, const char *host, int port,
 | 
			
		||||
                         const char *SSL_cert, perm_ctx_t *pctx);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
/* 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_ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static long __cmp_cstr(const void *a, const void *b)
 | 
			
		||||
{
 | 
			
		||||
  return strcmp((char *)a, (char *)b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sntl_rpclist_init(usrtc_t *tree)
 | 
			
		||||
{
 | 
			
		||||
  usrtc_init(tree, USRTC_REDBLACK, MAX_RPC_LIST, __cmp_int);
 | 
			
		||||
  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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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