2 * BIRD Test -- Utils for testing parsing configuration file
4 * (c) 2015 CZ.NIC z.s.p.o.
6 * Can be freely distributed and used under the terms of the GNU GPL.
13 #include "test/birdtest.h"
14 #include "test/bt-utils.h"
16 #include "nest/bird.h"
17 #include "nest/route.h"
18 #include "nest/protocol.h"
20 #include "sysdep/unix/unix.h"
21 #include "sysdep/unix/krt.h"
23 #include "nest/iface.h"
24 #include "nest/locks.h"
26 #include "filter/filter.h"
28 #define BETWEEN(a, b, c) (((a) >= (b)) && ((a) <= (c)))
30 static const byte
*bt_config_parse_pos
;
31 static uint bt_config_parse_remain_len
;
33 /* This is cf_read_hook for hard-coded text configuration */
35 cf_static_read(byte
*dest
, uint max_len
, int fd UNUSED
)
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
;
45 /* This is cf_read_hook for reading configuration files,
46 * function is copied from main.c, cf_read() */
48 cf_file_read(byte
*dest
, uint max_len
, int fd
)
50 int l
= read(fd
, dest
, max_len
);
52 cf_error("Read error");
61 log_switch(bt_verbose
!= 0, NULL
, NULL
);
72 proto_build(&proto_unix_kernel
);
73 proto_build(&proto_unix_iface
);
76 void bt_bird_cleanup(void)
78 for (int i
= 0; i
< PROTOCOL__MAX
; i
++)
79 class_to_protocol
[i
] = NULL
;
81 config
= new_config
= NULL
;
85 bt_load_file(const char *filename
, int quiet
)
87 FILE *f
= fopen(filename
, "rb");
89 bt_assert_msg(f
!= NULL
, "Open %s", filename
);
94 fseek(f
, 0, SEEK_END
);
95 long file_size_
= ftell(f
);
96 fseek(f
, 0, SEEK_SET
);
101 size_t file_size
= file_size_
;
102 size_t read_size
= 0;
104 char *file_body
= mb_allocz(&root_pool
, file_size
+1);
106 /* XXX: copied from cf-lex.c */
108 while ((read_size
+= fread(file_body
+read_size
, 1, file_size
-read_size
, f
)) != file_size
&& ferror(f
))
110 bt_debug("iteration \n");
113 bt_abort_msg("errno: %d", errno
);
122 bt_assert_msg(read_size
== file_size
, "Read %s", filename
);
128 bt_show_cfg_error(const struct config
*cfg
)
132 int lino_err
= cfg
->err_lino
;
134 const char *str
= bt_load_file(cfg
->err_file_name
, 1);
139 if (BETWEEN(lino
, lino_err
- lino_delta
, lino_err
+ lino_delta
))
140 bt_debug("%4u%s", lino
, (lino_err
== lino
? " >> " : " "));
143 if (BETWEEN(lino
, lino_err
- lino_delta
, lino_err
+ lino_delta
))
144 bt_debug("%c", *str
);
145 } while (*str
&& *(str
++) != '\n');
150 static struct config
*
151 bt_config_parse__(struct config
*cfg
)
153 bt_assert_msg(config_parse(cfg
) == 1, "Parse %s", cfg
->file_name
);
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
);
162 config_commit(cfg
, RECONFIG_HARD
, 0);
169 bt_config_parse(const char *cfg_str
)
171 struct config
*cfg
= config_alloc("configuration");
173 bt_config_parse_pos
= cfg_str
;
174 bt_config_parse_remain_len
= strlen(cfg_str
);
175 cf_read_hook
= cf_static_read
;
177 return bt_config_parse__(cfg
);
181 bt_config_file_parse(const char *filepath
)
183 struct config
*cfg
= config_alloc(filepath
);
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)
190 cf_read_hook
= cf_file_read
;
192 return bt_config_parse__(cfg
);
196 * Returns @base raised to the power of @power.
199 bt_naive_pow(uint base
, uint power
)
203 for (i
= 0; i
< power
; i
++)
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
214 * This function transforms @in_data of length @size into hexadecimal
215 * representation and writes it into @buf.
218 bt_bytes_to_hex(char *buf
, const byte
*in_data
, size_t size
)
221 for(i
= 0; i
< size
; i
++)
222 sprintf(buf
+ i
*2, "%02x", in_data
[i
]);