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

Telnet服务器

开发平台:

Unix_Linux

  1. /* Nessuslib -- the Nessus Library
  2.  * Copyright (C) 1998 Renaud Deraison
  3.  *
  4.  * This library is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU Library General Public
  6.  * License as published by the Free Software Foundation; either
  7.  * version 2 of the License, or (at your option) any later version.
  8.  *
  9.  * This library is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * Library General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU Library General Public
  15.  * License along with this library; if not, write to the Free
  16.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  *
  18.  * Arglists management
  19.  */
  20. #define EXPORTING
  21. #include <includes.h>
  22. /* 
  23.  * We use a hash of the argument name to speed up the lookups
  24.  * when calling arg_get_value()
  25.  */
  26. #define HASH_MAX 2713
  27. static int mkhash(const char * name)
  28. {
  29.  int h = 0;
  30.  int i;
  31.  
  32.  for(i=0;name[i] != '';i++)
  33.  {
  34.   h = ((h * 128) + name[i]) % HASH_MAX;
  35.  }
  36.  return h;
  37. }
  38. /*
  39.  * name_cache :
  40.  * 
  41.  * A lot of entries in our arglists have the same name.
  42.  * We use a caching system to avoid to allocate twice the same name
  43.  * 
  44.  * This saves about 300Kb of memory, with minimal performance impact
  45.  */
  46. struct name_cache {
  47. char * name;
  48. int occurences;
  49. struct name_cache * next;
  50. struct name_cache * prev;
  51. };
  52. static int cache_inited = 0;
  53. static struct name_cache cache[HASH_MAX+1];
  54. static void cache_init()
  55. {
  56.  int i;
  57.  for(i=0;i<HASH_MAX+1;i++)
  58.   {
  59. bzero(&(cache[i]), sizeof(cache[i]));
  60. }
  61.  cache_inited = 1;
  62. }
  63. static struct name_cache * 
  64. cache_get_name(name)
  65.  char * name;
  66. {
  67.  struct name_cache * nc;
  68.  int h;
  69.  
  70.  if(cache_inited == 0)
  71.   cache_init();
  72.  if(!name)
  73.   return NULL;
  74.   
  75.  h = mkhash(name);
  76.  nc = cache[h].next;
  77.   
  78.  while(nc != NULL)
  79.  {
  80.   if(nc->name != NULL && 
  81.     !strcmp(nc->name, name))
  82.      return nc;
  83.   else 
  84.    nc = nc->next;
  85.  }
  86.  return NULL;
  87. }
  88. static struct name_cache *
  89. cache_add_name(name)
  90.  char * name;
  91. {
  92.  struct name_cache * nc;
  93.  int h;
  94.  
  95.  if(name == NULL)
  96.   return NULL;
  97.  
  98.  
  99.  h = mkhash(name);
  100.  
  101.  
  102.  nc = emalloc(sizeof(struct name_cache));
  103.  nc->next = cache[h].next;
  104.  nc->prev = NULL;
  105.  nc->name = estrdup(name);
  106.  nc->occurences = 1;
  107.  if ( cache[h].next != NULL )
  108.   cache[h].next->prev = nc;
  109.  
  110.  cache[h].next = nc;
  111.  
  112.  return nc;
  113. }
  114. static char *
  115. cache_inc(name)
  116.  char * name;
  117. {
  118.  struct name_cache * nc = cache_get_name(name);
  119.  if(nc != NULL)
  120.   nc->occurences ++;
  121.  else
  122.    nc = cache_add_name(name);  
  123.  return nc->name;
  124. }
  125. static void 
  126. cache_dec(name)
  127.  char * name;
  128. {
  129.  struct name_cache* nc;
  130.  if(!name)
  131.   return;
  132.  nc  = cache_get_name(name);
  133.  if( nc == NULL)
  134.  {
  135.   /*
  136.   fprintf(stderr, "libnessus: cache_dec(): non-existant namen");
  137.   */
  138.   return;
  139.  }
  140.  
  141.  nc->occurences --;
  142.  if( nc->occurences == 0 ){
  143.    int h = mkhash(name);
  144.    efree(&nc->name);
  145.  if(nc->next != NULL)
  146.   nc->next->prev = nc->prev;
  147.   
  148.  if(nc->prev != NULL)
  149.   nc->prev->next = nc->next;
  150.  else
  151.   cache[h].next = nc->next;
  152.  
  153.  efree(&nc);
  154. }
  155. }
  156. ExtFunc void 
  157. arg_free_name(name)
  158.  char * name;
  159. {
  160.  cache_dec(name);
  161. }
  162.  
  163. ExtFunc void 
  164. arg_add_value(arglst, name, type, length, value)
  165.   struct arglist * arglst;
  166.   const char * name;
  167.   int type;
  168.   long length;
  169.   void * value;
  170. {
  171. if(!arglst)return;
  172. while(arglst->next)arglst = arglst->next;
  173. if (type == ARG_STRUCT) {
  174.       void* new_val = emalloc(length);
  175.        memcpy(new_val, value, length);
  176.       value = new_val;
  177.     }
  178. arglst->name = cache_inc(name);
  179. arglst->value = value;
  180. arglst->length = length;
  181. arglst->type = type;
  182. arglst->next = emalloc(sizeof(struct arglist));
  183. arglst->hash = mkhash(arglst->name);
  184. }
  185. static struct arglist * arg_get(struct arglist * arg, const char * name)
  186. {
  187.  int h = mkhash(name);
  188.  if(arg == NULL)
  189.   return NULL;
  190.  
  191.  while(arg->next != NULL)
  192.  {
  193.   if(arg->hash == h && strcmp(arg->name, name) == 0)
  194.     return arg;
  195.   else
  196.    arg = arg->next;
  197.  }
  198.  return NULL;
  199. }
  200. ExtFunc int 
  201. arg_set_value(arglst, name, length, value)
  202.  struct arglist * arglst;
  203.  const char * name;
  204.  long length;
  205.  void *value;
  206. {
  207.  
  208.  if(name == NULL)
  209.   return -1;
  210.   
  211.  arglst = arg_get(arglst, name);
  212.   
  213.   if(arglst != NULL)
  214.     {
  215.       if (arglst->type == ARG_STRUCT) {
  216. void* new_val = emalloc(length);
  217. if (arglst->value) efree(&arglst->value);
  218. memcpy(new_val, value, length);
  219. value = new_val;
  220.       }
  221.       arglst->value = value;
  222.       arglst->length = length;
  223.       return 0;
  224.     }
  225.   else return -1; 
  226. }
  227. ExtFunc int 
  228. arg_set_type(arglst, name, type)
  229.  struct arglist * arglst;
  230.  const char * name;
  231.  int type;
  232. {
  233.   arglst = arg_get(arglst, name);
  234.   if(arglst == NULL)
  235.    return -1;
  236.    
  237.   if (arglst->type == ARG_STRUCT  &&  type != ARG_STRUCT) {
  238.     efree(&arglst->value);
  239.   }
  240.   arglst->type = type;
  241.   return 0;
  242. }
  243.   
  244.   
  245. ExtFunc void * 
  246. arg_get_value(args, name)
  247.  struct arglist * args;
  248.  const char * name;
  249. {
  250.   if(args == NULL)
  251.    return NULL;
  252.   
  253.   args = arg_get(args, name);
  254.   if(args == NULL)
  255.    return NULL;
  256.   else  
  257.   return(args->value);
  258. }
  259. ExtFunc int 
  260. arg_get_length(args,name)
  261.  struct arglist * args;
  262.  const char * name;
  263. {
  264.   args = arg_get(args, name);
  265.   if(args != NULL)
  266.     return(args->length);
  267.   else 
  268.     return 0;
  269. }
  270. ExtFunc int 
  271. arg_get_type(args,name)
  272.  struct arglist * args;
  273.  const char * name;
  274. {
  275.  args = arg_get(args, name);
  276.  if( args != NULL )
  277.     return(args->type);
  278.   else 
  279.     return -1;
  280. }
  281. ExtFunc void arg_dup(dst, src)
  282.  struct arglist * dst;
  283.  struct arglist * src;
  284. {
  285.  if(!src)
  286.   return;
  287.   
  288.  while(src->next)
  289.  {
  290.   dst->name = cache_inc(src->name);
  291.   dst->type = src->type;
  292.   dst->length = src->length;
  293.   dst->hash = src->hash;
  294.   switch(src->type)
  295.   {
  296.    case ARG_INT :
  297.    case ARG_PTR : 
  298.     dst->value = src->value;
  299.     break;
  300.     
  301.    case ARG_STRING :
  302.     if(src->value){
  303.      dst->value = estrdup((char*)src->value);
  304.     }
  305.     break;
  306.     
  307.    case ARG_STRUCT :
  308.      if (src->value) {
  309.        dst->value = emalloc(src->length);
  310.        memcpy(dst->value, src->value, src->length);
  311.        dst->length = src->length;
  312.      }
  313.      break;
  314.  
  315.   case ARG_ARGLIST :
  316.     dst->value = emalloc(sizeof(struct arglist));
  317.     arg_dup((struct arglist *)dst->value, (struct arglist *)src->value);
  318.     break;
  319.   }
  320.   dst->next = emalloc(sizeof(struct arglist));
  321.   dst = dst->next;
  322.   src = src->next;
  323.  }
  324. }
  325. ExtFunc void 
  326. arg_dump(args, level)
  327.  struct arglist * args;
  328.  int level;
  329. {
  330. const char * spaces = "--------------------";
  331. if(!args)
  332. {
  333. printf("Error ! args == NULLn");
  334. return;
  335. }
  336. if(args)
  337.  while(args->next)
  338.  {
  339. switch(args->type)
  340. {
  341. case ARG_STRING :
  342. fprintf(stderr, "%sargs->%s : %sn",spaces+(20-level),
  343. args->name,
  344. (char *)args->value);
  345. break;
  346. case ARG_ARGLIST :
  347. fprintf(stderr, "%sargs->%s :n", spaces+(20-level),
  348. args->name);
  349. arg_dump(args->value, level+1);
  350. break;
  351. case ARG_INT :
  352. fprintf(stderr, "%sargs->%s : %dn",spaces+(20-level),
  353. args->name,
  354. (int)args->value);
  355. break;
  356. default :
  357. fprintf(stderr, "%sargs->%s : %dn",spaces+(20-level),
  358. args->name,
  359. (int)args->value);
  360. break;
  361. }
  362. args = args->next;
  363. }
  364. }
  365. ExtFunc void
  366. arg_free(arg)
  367.  struct arglist* arg;
  368. {
  369.  while(arg)
  370.  {
  371.   struct arglist * next = arg->next;
  372.   cache_dec(arg->name);
  373.   efree(&arg);
  374.   arg = next;
  375.  }
  376. }
  377. ExtFunc void arg_free_all(arg)
  378.  struct arglist* arg;
  379. {
  380.  while(arg)
  381.  {
  382.   struct arglist * next = arg->next;
  383.   switch(arg->type)
  384.   {
  385.    case ARG_ARGLIST :
  386.     arg_free_all(arg->value);
  387.     break;
  388.    case ARG_STRING :
  389.     efree(&arg->value);
  390.     break;
  391.    case ARG_STRUCT :
  392.     efree(&arg->value);
  393.     break;
  394.   }
  395.   cache_dec(arg->name);
  396.   efree(&arg);
  397.   arg = next;
  398.  }
  399. }