Statistics
| Branch: | Revision:

iof-bird / bird-2.0.1 / test / bt-utils.c @ 6b3f1a54

History | View | Annotate | Download (4.59 KB)

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 < EAP_MAX; i++)
79
    attr_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