Annotation of embedaddon/bird2/test/bt-utils.c, revision 1.1.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>