File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / test / bt-utils.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 16:03:56 2019 UTC (4 years, 8 months ago) by misho
Branches: bird2, MAIN
CVS tags: v2_0_7p0, HEAD
bird2 ver 2.0.7

    1: /*
    2:  *	BIRD Test -- Utils for testing parsing configuration file
    3:  *
    4:  *	(c) 2015 CZ.NIC z.s.p.o.
    5:  *
    6:  *	Can be freely distributed and used under the terms of the GNU GPL.
    7:  */
    8: 
    9: #include <stdlib.h>
   10: #include <fcntl.h>
   11: #include <unistd.h>
   12: 
   13: #include "test/birdtest.h"
   14: #include "test/bt-utils.h"
   15: 
   16: #include "nest/bird.h"
   17: #include "nest/route.h"
   18: #include "nest/protocol.h"
   19: 
   20: #include "sysdep/unix/unix.h"
   21: #include "sysdep/unix/krt.h"
   22: 
   23: #include "nest/iface.h"
   24: #include "nest/locks.h"
   25: 
   26: #include "filter/filter.h"
   27: 
   28: #define BETWEEN(a, b, c)  (((a) >= (b)) && ((a) <= (c)))
   29: 
   30: static const byte *bt_config_parse_pos;
   31: static uint bt_config_parse_remain_len;
   32: 
   33: /* This is cf_read_hook for hard-coded text configuration */
   34: static int
   35: cf_static_read(byte *dest, uint max_len, int fd UNUSED)
   36: {
   37:   if (max_len > bt_config_parse_remain_len)
   38:     max_len = bt_config_parse_remain_len;
   39:   memcpy(dest, bt_config_parse_pos, max_len);
   40:   bt_config_parse_pos += max_len;
   41:   bt_config_parse_remain_len -= max_len;
   42:   return max_len;
   43: }
   44: 
   45: /* This is cf_read_hook for reading configuration files,
   46:  * function is copied from main.c, cf_read() */
   47: static int
   48: cf_file_read(byte *dest, uint max_len, int fd)
   49: {
   50:   int l = read(fd, dest, max_len);
   51:   if (l < 0)
   52:     cf_error("Read error");
   53:   return l;
   54: }
   55: 
   56: void
   57: bt_bird_init(void)
   58: {
   59:   if(bt_verbose)
   60:     log_init_debug("");
   61:   log_switch(bt_verbose != 0, NULL, NULL);
   62: 
   63:   resource_init();
   64:   olock_init();
   65:   timer_init();
   66:   io_init();
   67:   rt_init();
   68:   if_init();
   69:   config_init();
   70: 
   71:   protos_build();
   72:   proto_build(&proto_unix_kernel);
   73:   proto_build(&proto_unix_iface);
   74: }
   75: 
   76: void bt_bird_cleanup(void)
   77: {
   78:   for (int i = 0; i < PROTOCOL__MAX; i++)
   79:     class_to_protocol[i] = NULL;
   80: 
   81:   config = new_config = NULL;
   82: }
   83: 
   84: static char *
   85: bt_load_file(const char *filename, int quiet)
   86: {
   87:   FILE *f = fopen(filename, "rb");
   88:   if (!quiet)
   89:     bt_assert_msg(f != NULL, "Open %s", filename);
   90: 
   91:   if (f == NULL)
   92:     return NULL;
   93: 
   94:   fseek(f, 0, SEEK_END);
   95:   long file_size_ = ftell(f);
   96:   fseek(f, 0, SEEK_SET);
   97: 
   98:   if (file_size_ < 0)
   99:     return NULL;
  100: 
  101:   size_t file_size = file_size_;
  102:   size_t read_size = 0;
  103: 
  104:   char *file_body = mb_allocz(&root_pool, file_size+1);
  105: 
  106:   /* XXX: copied from cf-lex.c */
  107:   errno=0;
  108:   while ((read_size += fread(file_body+read_size, 1, file_size-read_size, f)) != file_size && ferror(f))
  109:   {
  110:     bt_debug("iteration \n");
  111:     if(errno != EINTR)
  112:     {
  113:       bt_abort_msg("errno: %d", errno);
  114:       break;
  115:     }
  116:     errno=0;
  117:     clearerr(f);
  118:   }
  119:   fclose(f);
  120: 
  121:   if (!quiet)
  122:     bt_assert_msg(read_size == file_size, "Read %s", filename);
  123: 
  124:   return file_body;
  125: }
  126: 
  127: static void
  128: bt_show_cfg_error(const struct config *cfg)
  129: {
  130:   int lino = 0;
  131:   int lino_delta = 5;
  132:   int lino_err = cfg->err_lino;
  133: 
  134:   const char *str = bt_load_file(cfg->err_file_name, 1);
  135: 
  136:   while (str && *str)
  137:   {
  138:     lino++;
  139:     if (BETWEEN(lino, lino_err - lino_delta, lino_err + lino_delta))
  140:       bt_debug("%4u%s", lino, (lino_err == lino ? " >> " : "    "));
  141:     do
  142:     {
  143:       if (BETWEEN(lino, lino_err - lino_delta, lino_err + lino_delta))
  144: 	bt_debug("%c", *str);
  145:     } while (*str && *(str++) != '\n');
  146:   }
  147:   bt_debug("\n");
  148: }
  149: 
  150: static struct config *
  151: bt_config_parse__(struct config *cfg)
  152: {
  153:   bt_assert_msg(config_parse(cfg) == 1, "Parse %s", cfg->file_name);
  154: 
  155:   if (cfg->err_msg)
  156:   {
  157:     bt_debug("Parse error %s, line %d: %s\n", cfg->err_file_name, cfg->err_lino, cfg->err_msg);
  158:     bt_show_cfg_error(cfg);
  159:     return NULL;
  160:   }
  161: 
  162:   config_commit(cfg, RECONFIG_HARD, 0);
  163:   new_config = cfg;
  164: 
  165:   return cfg;
  166: }
  167: 
  168: struct config *
  169: bt_config_parse(const char *cfg_str)
  170: {
  171:   struct config *cfg = config_alloc("configuration");
  172: 
  173:   bt_config_parse_pos = cfg_str;
  174:   bt_config_parse_remain_len = strlen(cfg_str);
  175:   cf_read_hook = cf_static_read;
  176: 
  177:   return bt_config_parse__(cfg);
  178: }
  179: 
  180: struct config *
  181: bt_config_file_parse(const char *filepath)
  182: {
  183:   struct config *cfg = config_alloc(filepath);
  184: 
  185:   cfg->file_fd = open(filepath, O_RDONLY);
  186:   bt_assert_msg(cfg->file_fd > 0, "Open %s", filepath);
  187:   if (cfg->file_fd < 0)
  188:     return NULL;
  189: 
  190:   cf_read_hook = cf_file_read;
  191: 
  192:   return bt_config_parse__(cfg);
  193: }
  194: 
  195: /*
  196:  * Returns @base raised to the power of @power.
  197:  */
  198: uint
  199: bt_naive_pow(uint base, uint power)
  200: {
  201:   uint result = 1;
  202:   uint i;
  203:   for (i = 0; i < power; i++)
  204:     result *= base;
  205:   return result;
  206: }
  207: 
  208: /**
  209:  * bytes_to_hex - transform data into hexadecimal representation
  210:  * @buf: preallocated string buffer
  211:  * @in_data: data for transformation
  212:  * @size: the length of @in_data
  213:  *
  214:  * This function transforms @in_data of length @size into hexadecimal
  215:  * representation and writes it into @buf.
  216:  */
  217: void
  218: bt_bytes_to_hex(char *buf, const byte *in_data, size_t size)
  219: {
  220:   size_t i;
  221:   for(i = 0; i < size; i++)
  222:     sprintf(buf + i*2, "%02x", in_data[i]);
  223: }
  224: 

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