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>