data.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:13k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2.  * data.c :
  3.  *  Primitives for an opaque data storage struct which is bound to
  4.  *  eventually replace the arglists and harglsts
  5.  *
  6.  * The advantages of this structure compared to the arglists are :
  7.  *
  8.  *  - Data is typed. We won't mistake a pointer for an int and vice versa
  9.  *  - Memory is managed. This means that strings are actually copied in
  10.  *    the structure, not just their address. This caused a lot of problems
  11.  *    with the arglists
  12.  *  - No ambiguity when fetching data. There were problems with the arglists
  13.  *    where we would do an arg_get_value("foo"), obtain 0 as a result
  14.  *    and could not differenciate that from an error or the fact that foo
  15.  *    is actually equal to zero
  16.  *  - Full opacity. This will allow us to move to a more suited data
  17.  *    structure in the future (probably hash table)
  18.  */
  19. #include <includes.h>
  20. #include "data.h"
  21. /*
  22.  * name_cache :
  23.  * 
  24.  * A lot of entries in our arglists have the same name.
  25.  * We use a caching system to avoid to allocate twice the same name
  26.  * 
  27.  * This saves about 300Kb of memory, with minimal performance impact
  28.  */
  29. struct name_cache {
  30. char * name;
  31. int occurences;
  32. struct name_cache * next;
  33. };
  34. static struct name_cache *cache = NULL;
  35. static struct name_cache * 
  36. cache_get_name(name)
  37.  char * name;
  38. {
  39.  struct name_cache * nc = cache;
  40.  
  41.  if(name == NULL)
  42.   return NULL;
  43.   
  44.  while(nc != NULL)
  45.  {
  46.   if(nc->name != NULL && strcmp(nc->name, name) == 0 )
  47.      return nc;
  48.   else 
  49.      nc = nc->next;
  50.  }
  51.  return NULL;
  52. }
  53. static struct name_cache *
  54. cache_add_name(name)
  55.  char * name;
  56. {
  57.  struct name_cache * nc = cache;
  58.  while(nc != NULL)
  59.  {
  60.   if(nc->name == NULL)
  61.     break;
  62.   else 
  63.     nc = nc->next;
  64.  }
  65.  
  66.  
  67.  if(nc == NULL)
  68.  {
  69.   nc = malloc(sizeof(struct name_cache));
  70.   nc->next = cache;
  71.   cache = nc;
  72.  }
  73.  
  74.  nc->name = strdup(name);
  75.  nc->occurences = 1;
  76.  return nc;
  77. }
  78. static char *
  79. cache_inc(name)
  80.  char * name;
  81. {
  82.  struct name_cache * nc = cache_get_name(name);
  83.  if(nc)
  84.   nc->occurences ++;
  85.  else
  86.    nc = cache_add_name(name);  
  87.  return nc->name;
  88. }
  89. static void 
  90. cache_dec(name)
  91.  char * name;
  92. {
  93.  struct name_cache* nc;
  94.  if(name == NULL)
  95.   return;
  96.  nc  = cache_get_name(name);
  97.  if(nc == NULL)
  98.  {
  99.   /*
  100.   fprintf(stderr, "libnessus: cache_dec(): non-existant namen");
  101.   */
  102.   return;
  103.  }
  104.  
  105.  nc->occurences --;
  106.  if(nc->occurences == 0)
  107.  {
  108.    if(nc->name == name)
  109.    {
  110. #ifdef DEBUG
  111.     memset(nc->name, 'X', strlen(nc->name));
  112. #endif   
  113.     free(nc->name);
  114.     nc->name = NULL;
  115.    }
  116.    else 
  117.     fprintf(stderr, "libnessus: cache_dec(): invalid ptrn");
  118.   }
  119. }
  120. /*----------------------------------------------------------------------------*/
  121. struct data * data_init()
  122. {
  123.  struct data *data = malloc(sizeof(struct data));
  124.  data->list = data->current = NULL;
  125.  return data;
  126. }
  127. int data_add_str(struct data * data, char* name, char * str)
  128. {
  129.  int len;
  130.  struct elem * elem;
  131.  
  132.  if(data == NULL)
  133.   return -1;
  134.   
  135.  if(str == NULL)
  136.   return -1; /* Or shall have an empty entry ? XXX */
  137.  
  138.  len = strlen(str);
  139.  elem = malloc(sizeof(struct elem));
  140.  
  141.  elem->name = cache_inc(name);
  142.  elem->size = len + 1;
  143.  elem->type = DATA_STR;
  144.  elem->v.v_str = strdup(str);
  145.  elem->next = data->list;
  146.  data->list = elem;
  147.  return 0;
  148. }
  149. int data_add_blob(struct data * data, char* name, u_char * blob, int len)
  150. {
  151.  struct elem * elem;
  152.  
  153.  if(data == NULL)
  154.   return -1;
  155.   
  156.  if(blob == NULL)
  157.   return -1; /* Or shall have an empty entry ? XXX */
  158.  
  159.  elem = malloc(sizeof(struct elem));
  160.  
  161.  elem->name = cache_inc(name);
  162.  elem->size = len + 1;
  163.  elem->type = DATA_BLOB;
  164.  elem->v.v_blob = malloc(len);
  165.  memcpy(elem->v.v_blob, blob, len);
  166.  elem->next = data->list;
  167.  data->list = elem;
  168.  return 0;
  169. }
  170. int data_add_int(struct data * data, char * name, int value)
  171. {
  172.  struct elem * elem;
  173.  
  174.  if(data == NULL)
  175.   return -1;
  176.   
  177.  elem = malloc(sizeof(struct elem));
  178.  
  179.  elem->name = cache_inc(name);
  180.  elem->size = 0;
  181.  elem->type = DATA_INT;
  182.  elem->v.v_int = value;
  183.  elem->next = data->list;
  184.  data->list = elem;
  185.  return 0;
  186. }
  187. int data_add_ptr(struct data * data, char * name, void * ptr)
  188. {
  189.  struct elem * elem;
  190.  
  191.  if(data == NULL)
  192.   return -1;
  193.  
  194.  elem = malloc(sizeof(struct elem));
  195.  
  196.  elem->name = cache_inc(name);
  197.  elem->size = 0;
  198.  elem->type = DATA_PTR;
  199.  elem->v.v_ptr = ptr;
  200.  elem->next = data->list;
  201.  data->list = elem;
  202.  return 0;
  203. }
  204. int data_add_data(struct data * data, char * name, struct data * val)
  205. {
  206.  struct elem * elem;
  207.  
  208.  if(data == NULL)
  209.   return -1;
  210.  
  211.  elem = malloc(sizeof(struct elem));
  212.  
  213.  elem->name = cache_inc(name);
  214.  elem->size = 0;
  215.  elem->type = DATA_DATA;
  216.  elem->v.v_data = data_copy(val);
  217.  elem->next = data->list;
  218.  data->list = elem;
  219.  return 0;
  220. }
  221. static struct elem * elem_search(struct elem * elem, char * name, int type)
  222. {
  223.  while(elem != NULL)
  224.  {
  225.   if((type == 0 || elem->type == type)  && strcmp(elem->name, name) == 0)
  226.    return elem;
  227.   else
  228.    elem = elem->next;
  229.  }
  230.  return NULL;
  231. }
  232. int data_get_int(struct data * data, char * name, int * value)
  233. {
  234.  struct elem * e;
  235.  if(data == NULL || 
  236.     name == NULL || 
  237.     value == NULL)
  238.   return -1;
  239.   
  240.  e = elem_search(data->list, name, DATA_INT);
  241.  if(e == NULL)
  242.   return 1;
  243.   
  244.  *value = e->v.v_int;
  245.   return 0;
  246. }
  247. int data_get_str(struct data * data, char * name, char ** value)
  248. {
  249.  struct elem * e;
  250.  if(data == NULL || 
  251.     name == NULL || 
  252.     value == NULL)
  253.   return -1;
  254.   
  255.  e = elem_search(data->list, name, DATA_STR);
  256.  if(e == NULL)
  257.   return 1;
  258.   
  259.  *value = e->v.v_str;
  260.  return 0;
  261. }
  262. int data_get_blob(struct data * data, char * name, u_char ** value)
  263. {
  264.  struct elem * e;
  265.  if(data == NULL || 
  266.     name == NULL || 
  267.     value == NULL)
  268.   return -1;
  269.   
  270.  e = elem_search(data->list, name, DATA_BLOB);
  271.  if(e == NULL)
  272.   return 1;
  273.   
  274.  *value = e->v.v_blob;
  275.   return 0;
  276. }
  277. int data_get_ptr(struct data * data, char * name, void ** value)
  278. {
  279.  struct elem * e;
  280.  if(data == NULL || 
  281.     name == NULL || 
  282.     value == NULL)
  283.   return -1;
  284.   
  285.  e = elem_search(data->list, name, DATA_PTR);
  286.  if(e == NULL)
  287.   return 1;
  288.   
  289.  *value = e->v.v_ptr;
  290.  return 0;
  291. }
  292. int data_get_data(struct data * data, char * name, struct data ** value)
  293. {
  294.  struct elem * e;
  295.  if(data == NULL || 
  296.     name == NULL || 
  297.     value == NULL)
  298.   return -1;
  299.   
  300.  e = elem_search(data->list, name, DATA_DATA);
  301.  if(e == NULL)
  302.   return 1;
  303.   
  304.  *value = e->v.v_data;
  305.  return 0;
  306. }
  307. int data_set_int(struct data * data, char * name, int value)
  308. {
  309.   struct elem * e;
  310.   if(data == NULL || 
  311.      name == NULL)
  312.     return -1;
  313.  
  314.   e = elem_search(data->list, name, DATA_INT);
  315.   if(e == NULL)
  316.     return 1;
  317.   e->v.v_int = value;
  318.   return 0;
  319. }
  320. int data_set_str(struct data * data, char * name, char * value)
  321. {
  322.   struct elem * e;
  323.   if(data == NULL || 
  324.      name == NULL)
  325.     return -1;
  326.  
  327.   e = elem_search(data->list, name, DATA_STR);
  328.   if(e == NULL)
  329.     return 1;
  330.   free(e->v.v_str);
  331.   e->size = strlen(value) + 1;
  332.   e->v.v_str = estrdup(value);
  333.   return 0;
  334. }
  335. int data_set_ptr(struct data * data, char * name, void * value)
  336. {
  337.   struct elem * e;
  338.   if(data == NULL || 
  339.      name == NULL)
  340.     return -1;
  341.  
  342.   e = elem_search(data->list, name, DATA_PTR);
  343.   if(e == NULL)
  344.     return 1;
  345.   e->v.v_ptr = value;
  346.   return 0;
  347. }
  348. int data_set_blob(struct data * data, char * name, u_char * value, int sz)
  349. {
  350.  struct elem * e;
  351.   if(data == NULL || 
  352.      name == NULL)
  353.     return -1;
  354.  
  355.   e = elem_search(data->list, name, DATA_BLOB);
  356.   if(e == NULL)
  357.     return 1;
  358.   free(e->v.v_blob);
  359.   e->size = sz;
  360.   e->v.v_blob = malloc(sz);
  361.   memcpy(e->v.v_blob, value, sz);
  362.   return 0;
  363. }
  364. int data_set_data(struct data * data, char * name, struct data * value)
  365. {
  366.   struct elem * e;
  367.   if(data == NULL || 
  368.      name == NULL)
  369.     return -1;
  370.  
  371.   e = elem_search(data->list, name, DATA_DATA);
  372.   if(e == NULL)
  373.     return 1;
  374.     data_free(e->v.v_data);
  375.     e->v.v_data = data_copy(value);
  376.   return 0;
  377. }
  378. int data_addset_int(struct data * data, char * name, int value)
  379. {
  380.  int old;
  381.  if(data_get_int(data, name, &old) != 0)
  382.   return data_set_int(data, name, value);
  383.  else
  384.   return data_add_int(data, name, value);
  385. }
  386. int data_addset_str(struct data * data, char * name, char * value)
  387. {
  388.  char * old;
  389.  if(data_get_str(data, name, &old) != 0)
  390.   return data_set_str(data, name, value);
  391.  else
  392.   return data_add_str(data, name, value);
  393. }
  394. int data_addset_ptr(struct data * data, char * name, void * value)
  395. {
  396.  void * old;
  397.  if(data_get_ptr(data, name, &old) != 0)
  398.   return data_set_ptr(data, name, value);
  399.  else
  400.   return data_add_ptr(data, name, value);
  401. }
  402. int data_addset_blob(struct data * data, char * name, u_char * value, size_t sz)
  403. {
  404.  u_char * old;
  405.  if(data_get_blob(data, name, &old) != 0)
  406.   return data_set_blob(data, name, value, sz);
  407.  else
  408.   return data_add_blob(data, name, value, sz);
  409. }
  410. int data_addset_data(struct data * data, char * name, struct data * value)
  411. {
  412.  struct data * old;
  413.  if(data_get_data(data, name, &old) != 0)
  414.   return data_set_data(data, name, value);
  415.  else
  416.   return data_add_data(data, name, value);
  417. }
  418. int data_get_size(struct data * data, char * name, int * size)
  419. {
  420.  struct elem * e;
  421.  if(data == NULL || name == NULL || size == NULL)
  422.   return -1;
  423.  
  424.  e = elem_search(data->list, name, 0);
  425.  if(e == NULL)
  426.   return 1;
  427.  *size = e->size;
  428.  return 0;
  429. }
  430. int data_get_type(struct data * data, char * name, int * type)
  431. {
  432.   struct elem * e;
  433.  if(data == NULL || name == NULL || type == NULL)
  434.   return -1;
  435.  
  436.  e = elem_search(data->list, name, 0);
  437.  if(e == NULL)
  438.   return 1;
  439.  *type = e->type;
  440.  return 0;
  441. }
  442. struct data * data_copy(struct data * data)
  443. {
  444.   struct data * cop;
  445.   struct elem * e;
  446.   if( data == NULL )
  447.     return NULL;
  448.   cop = data_init();
  449.   cop->walktype = data->walktype;
  450.   e = data->list;
  451.   while ( e != NULL )
  452.     {
  453.       switch(e->type)
  454. {
  455. case DATA_INT:
  456.   data_add_int(cop, e->name, e->v.v_int);
  457.   break;
  458. case DATA_STR:
  459.   data_add_str(cop, e->name, e->v.v_str);
  460.   break;
  461. case DATA_PTR:
  462.   data_add_ptr(cop, e->name, e->v.v_ptr);
  463.   break;
  464. case DATA_BLOB:
  465.   data_add_blob(cop, e->name, e->v.v_blob, e->size);
  466.   break;
  467. case DATA_DATA:
  468.   data_add_data(cop, e->name, e->v.v_data);
  469.   break;
  470. }
  471.       e = e->next;
  472.     }
  473.   cop->current = NULL;
  474.   return cop;
  475. }
  476. int data_free(struct data * data)
  477. {
  478.  struct elem * e = data->list;
  479.  while ( e != NULL )
  480.  {
  481.   struct elem * nxt;
  482.   if(e->type == DATA_BLOB)
  483.    free(e->v.v_blob);
  484.   if(e->type == DATA_STR)
  485.    free(e->v.v_str);
  486.   nxt = e->next;
  487.   cache_dec(e->name);
  488.   free(e);
  489.   e = nxt;
  490.  }
  491.  return 0;
  492. }
  493. int data_free_all(struct data * data)
  494. {
  495.  struct elem * e = data->list;
  496.  while ( e != NULL )
  497.  {
  498.   struct elem * nxt;
  499.   if(e->type == DATA_BLOB)
  500.    free(e->v.v_blob);
  501.   if(e->type == DATA_STR)
  502.    free(e->v.v_str);
  503.   if(e->type == DATA_DATA)
  504.    data_free_all(e->v.v_data);
  505.   nxt = e->next;
  506.   cache_dec(e->name);
  507.   free(e);
  508.   e = nxt;
  509.  }
  510.  free(data);
  511.  return 0;
  512. }
  513. int data_walk_init(struct data * data)
  514. {
  515.   if(data == NULL)
  516.     return -1;
  517.  data->current = data->list;
  518.  return 0;
  519. }
  520. static struct elem * data_walk_next(struct data * data)
  521. {
  522.  if(data->current == NULL)
  523.   return NULL;
  524.  else
  525.  {
  526.   struct elem  * ret;
  527.   ret = data->current;
  528.   data->current = data->current->next;
  529.   return ret;
  530.  }
  531. }
  532. int data_walk_next_str(struct data * data, char ** name, char ** value)
  533. {
  534.  struct elem * e;
  535.  
  536.  for(;;)
  537.  {
  538.  e = data_walk_next(data);
  539.  if(e == NULL)
  540.   return -1;
  541.  if(e->type == DATA_STR)
  542.   {
  543.    if(name) 
  544.     *name = e->name;
  545.    if(value)
  546.     *value = e->v.v_str;
  547.    return 0;
  548.   }
  549.  }
  550. }
  551. int data_walk_next_int(struct data * data, char ** name, int * value)
  552. {
  553.  struct elem * e;
  554.  
  555.  for(;;)
  556.  {
  557.  e = data_walk_next(data);
  558.  if(e == NULL)
  559.   return -1;
  560.  if(e->type == DATA_INT)
  561.   {
  562.    if(name) 
  563.     *name = e->name;
  564.    if(value)
  565.     *value = e->v.v_int;
  566.    return 0;
  567.   }
  568.  }
  569. }
  570. int data_walk_next_ptr(struct data * data, char ** name, void ** value)
  571. {
  572.  struct elem * e;
  573.  
  574.  for(;;)
  575.  {
  576.  e = data_walk_next(data);
  577.  if(e == NULL)
  578.   return -1;
  579.  if(e->type == DATA_PTR)
  580.   {
  581.    if(name) 
  582.     *name = e->name;
  583.    if(value)
  584.     *value = e->v.v_ptr;
  585.    return 0;
  586.   }
  587.  }
  588. }
  589. int data_walk_next_blob(struct data * data, char ** name, u_char ** value)
  590. {
  591.  struct elem * e;
  592.  
  593.  for(;;)
  594.  {
  595.  e = data_walk_next(data);
  596.  if(e == NULL)
  597.   return -1;
  598.  if(e->type == DATA_BLOB)
  599.   {
  600.    if(name) 
  601.     *name = e->name;
  602.    if(value)
  603.     *value = e->v.v_blob;
  604.    return 0;
  605.   }
  606.  }
  607. }
  608. int data_walk_next_data(struct data * data, char ** name, struct data **value)
  609. {
  610.  struct elem * e;
  611.  
  612.  for(;;)
  613.  {
  614.  e = data_walk_next(data);
  615.  if(e == NULL)
  616.   return -1;
  617.  if(e->type == DATA_DATA)
  618.   {
  619.    if(name) 
  620.     *name = e->name;
  621.    if(value)
  622.     *value = e->v.v_data;
  623.    return 0;
  624.   }
  625.  }
  626. }
  627. static void printspc(int level)
  628. {
  629.   while(level != 0)
  630.     {
  631.       printf(" ");level--;
  632.     }
  633. }
  634. static int _data_dump(struct data * data, int level)
  635. {
  636.   struct elem * e;
  637.   if(data == NULL)
  638.     return 0;
  639.   e = data->list;
  640.   while(e != NULL)
  641.     {
  642.       switch(e->type)
  643. {
  644. case DATA_INT:
  645.   printspc(level);
  646.   printf("[int] %s->%dn",e->name, e->v.v_int);
  647.   break;
  648. case DATA_STR:
  649.   printspc(level);
  650.   printf("[str] %s->'%s'n",e->name, e->v.v_str);
  651.   break;
  652. case DATA_BLOB:
  653.   printspc(level);
  654.   printf("[blob] %s->0x%xn",e->name, (int)e->v.v_blob);
  655.   break;
  656. case DATA_PTR:
  657.   printspc(level);
  658.   printf("[ptr] %s->0x%xn", e->name, (int)e->v.v_ptr);
  659.   break;
  660. case DATA_DATA:
  661.   printspc(level);
  662.   printf("[data] %s : n", e->name);
  663.   _data_dump(e->v.v_data, level + 1);
  664.   break;
  665. }
  666.       e = e->next;
  667.     }
  668.   return 0;
  669. }
  670. int data_dump(struct data * data)
  671. {
  672.   return _data_dump(data, 0);
  673. }
  674.