Annotation of embedaddon/bird2/test/bt-utils.c, revision 1.1

1.1     ! misho       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>