1#include "check_confuse.h" 2#include <string.h> 3#include <stdlib.h> 4#include <sys/types.h> 5#include <sys/socket.h> 6#include <netinet/in.h> 7#include <arpa/inet.h> 8 9static cfg_t *cfg; 10 11int parse_ip_address(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) 12{ 13 struct in_addr *addr = (struct in_addr *)malloc(sizeof(struct in_addr)); 14 if(inet_aton(value, addr) == 0) 15 { 16 /*cfg_error(cfg, "invalid IP address %s in section %s", value, cfg->name);*/ 17 free(addr); 18 return 1; 19 } 20 *(void **)result = (void *)addr; 21 return 0; 22} 23 24static unsigned char *my_ether_aton(const char *addr) 25{ 26 int i; 27 static unsigned int e[6]; 28 static unsigned char ec[6]; 29 if(sscanf(addr, "%x:%x:%x:%x:%x:%x", &e[0], &e[1], &e[2], &e[3], &e[4], &e[5]) != 6) 30 { 31 return NULL; 32 } 33 for(i = 0; i < 6; i++) 34 { 35 if(e[i] <= 0xff) 36 ec[i] = e[i]; 37 else 38 return NULL; 39 } 40 return ec; 41} 42 43static char *my_ether_ntoa(unsigned char *addr) 44{ 45 static char buf[18]; 46 sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", 47 addr[0], addr[0], addr[0], addr[0], addr[0], addr[0]); 48 return buf; 49} 50 51int parse_ether_address(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) 52{ 53 unsigned char *tmp; 54 55 tmp = my_ether_aton(value); 56 if(tmp == 0) 57 { 58 /*cfg_error(cfg, "invalid Ethernet address %s in section %s", value, cfg->name);*/ 59 return 1; 60 } 61 *(void **)result = malloc(6); 62 memcpy(*(void **)result, tmp, 6); 63 return 0; 64} 65 66void single_setup(void) 67{ 68 cfg_opt_t subsec_opts[] = 69 { 70 CFG_STR("subsubstring", "subsubdefault", CFGF_NONE), 71 CFG_INT("subsubinteger", -42, CFGF_NONE), 72 CFG_FLOAT("subsubfloat", 19923.1234, CFGF_NONE), 73 CFG_BOOL("subsubbool", cfg_false, CFGF_NONE), 74 CFG_END() 75 }; 76 77 cfg_opt_t sec_opts[] = 78 { 79 CFG_STR("substring", "subdefault", CFGF_NONE), 80 CFG_INT("subinteger", 17, CFGF_NONE), 81 CFG_FLOAT("subfloat", 8.37, CFGF_NONE), 82 CFG_BOOL("subbool", cfg_true, CFGF_NONE), 83 CFG_SEC("subsection", subsec_opts, CFGF_NONE), 84 CFG_END() 85 }; 86 87 cfg_opt_t nodef_opts[] = 88 { 89 CFG_STR("string", "defvalue", CFGF_NONE), 90 CFG_INT("int", -17, CFGF_NODEFAULT), 91 CFG_END() 92 }; 93 94 cfg_opt_t opts[] = 95 { 96 CFG_STR("string", "default", CFGF_NONE), 97 CFG_INT("integer", 4711, CFGF_NONE), 98 CFG_FLOAT("float", 0.42, CFGF_NONE), 99 CFG_BOOL("bool", cfg_false, CFGF_NONE), 100 CFG_PTR_CB("ip-address", 0, CFGF_NONE, parse_ip_address, free), 101 CFG_PTR_CB("ethernet-address", 0, CFGF_NONE, parse_ether_address, free), 102 CFG_SEC("section", sec_opts, CFGF_NONE), 103 CFG_STR("nodefstring", "not used", CFGF_NODEFAULT), 104 CFG_SEC("nodefsec", nodef_opts, CFGF_NODEFAULT), 105 CFG_END() 106 }; 107 108 cfg = cfg_init(opts, 0); 109 110 memset(opts, 0, sizeof(opts)); 111 memset(sec_opts, 0, sizeof(sec_opts)); 112 memset(subsec_opts, 0, sizeof(subsec_opts)); 113} 114 115void single_teardown(void) 116{ 117 cfg_free(cfg); 118} 119 120void single_string_test(void) 121{ 122 char *buf; 123 124 fail_unless(cfg_size(cfg, "string") == 1); 125 fail_unless(cfg_opt_size(cfg_getopt(cfg, "string")) == 1); 126 fail_unless(strcmp(cfg_getstr(cfg, "string"), "default") == 0); 127 fail_unless(cfg_getnstr(cfg, "string", 0) == cfg_getstr(cfg, "string")); 128 fail_unless(cfg_getnstr(cfg, "string", 1) == 0); 129 buf = "string = 'set'"; 130 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 131 fail_unless(strcmp(cfg_getstr(cfg, "string"), "set") == 0); 132 cfg_setstr(cfg, "string", "manually set"); 133 fail_unless(strcmp(cfg_getstr(cfg, "string"), "manually set") == 0); 134} 135 136void single_integer_test(void) 137{ 138 char *buf; 139 140 fail_unless(cfg_size(cfg, "integer") == 1); 141 fail_unless(cfg_opt_size(cfg_getopt(cfg, "integer")) == 1); 142 fail_unless(cfg_getint(cfg, "integer") == 4711); 143 fail_unless(cfg_getnint(cfg, "integer", 0) == cfg_getint(cfg, "integer")); 144 fail_unless(cfg_getnint(cfg, "integer", 1) == 0); 145 buf = "integer = -46"; 146 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 147 fail_unless(cfg_getint(cfg, "integer") == -46); 148 cfg_setint(cfg, "integer", 999999); 149 fail_unless(cfg_getint(cfg, "integer") == 999999); 150} 151 152void single_float_test(void) 153{ 154 char *buf; 155 156 fail_unless(cfg_size(cfg, "float") == 1); 157 fail_unless(cfg_opt_size(cfg_getopt(cfg, "float")) == 1); 158 fail_unless(cfg_getfloat(cfg, "float") == 0.42); 159 fail_unless(cfg_getnfloat(cfg, "float", 0) == cfg_getfloat(cfg, "float")); 160 fail_unless(cfg_getnfloat(cfg, "float", 1) == 0); 161 buf = "float = -46.777"; 162 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 163 fail_unless(cfg_getfloat(cfg, "float") == -46.777); 164 cfg_setfloat(cfg, "float", 5.1234e2); 165 fail_unless(cfg_getfloat(cfg, "float") == 5.1234e2); 166} 167 168void single_bool_test(void) 169{ 170 char *buf; 171 172 fail_unless(cfg_size(cfg, "bool") == 1); 173 fail_unless(cfg_opt_size(cfg_getopt(cfg, "bool")) == 1); 174 fail_unless(cfg_getbool(cfg, "bool") == cfg_false); 175 176 buf = "bool = yes"; 177 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 178 fail_unless(cfg_getbool(cfg, "bool") == cfg_true); 179 buf = "bool = no"; 180 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 181 fail_unless(cfg_getbool(cfg, "bool") == cfg_false); 182 buf = "bool = true"; 183 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 184 fail_unless(cfg_getbool(cfg, "bool") == cfg_true); 185 buf = "bool = false"; 186 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 187 fail_unless(cfg_getbool(cfg, "bool") == cfg_false); 188 buf = "bool = on"; 189 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 190 fail_unless(cfg_getbool(cfg, "bool") == cfg_true); 191 buf = "bool = off"; 192 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 193 fail_unless(cfg_getbool(cfg, "bool") == cfg_false); 194 195 cfg_setbool(cfg, "bool", cfg_true); 196 fail_unless(cfg_getbool(cfg, "bool") == cfg_true); 197 cfg_setbool(cfg, "bool", cfg_false); 198 fail_unless(cfg_getbool(cfg, "bool") == cfg_false); 199} 200 201void single_section_test(void) 202{ 203 char *buf; 204 cfg_t *sec, *subsec; 205 206 fail_unless(cfg_size(cfg, "section") == 1); 207 fail_unless(cfg_opt_size(cfg_getopt(cfg, "section")) == 1); 208 209 fail_unless(cfg_size(cfg, "section|subsection") == 1); 210 fail_unless(cfg_opt_size(cfg_getopt(cfg, "section|subsection")) == 1); 211 212 fail_unless(cfg_size(cfg, "section|subsection|subsubstring") == 1); 213 fail_unless(cfg_opt_size(cfg_getopt(cfg, "section|subsection|subsubinteger")) == 1); 214 215 fail_unless(cfg_title(cfg_getsec(cfg, "section")) == 0); 216 fail_unless(cfg_title(cfg_getsec(cfg, "section|subsection")) == 0); 217 218 fail_unless(strcmp(cfg_getstr(cfg, "section|substring"), "subdefault") == 0); 219 sec = cfg_getsec(cfg, "section|subsection"); 220 fail_unless(sec != 0); 221 fail_unless(cfg_getint(sec, "subsubinteger") == -42); 222 223 fail_unless(cfg_getnsec(cfg, "section", 0) == cfg_getsec(cfg, "section")); 224 fail_unless(cfg_getnsec(cfg, "section", 1) == 0); 225 226 sec = cfg_getsec(cfg, "section"); 227 fail_unless(sec != 0); 228 subsec = cfg_getsec(sec, "subsection"); 229 fail_unless(subsec != 0); 230 fail_unless(cfg_getfloat(subsec, "subsubfloat") == 19923.1234); 231 232 buf = "section { substring = \"foo\" subsection { subsubstring = \"bar\"} }"; 233 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 234} 235 236void single_ptr_test(void) 237{ 238 char *buf; 239 struct in_addr *ipaddr; 240 unsigned char *etheraddr, *cmpether; 241 242 fail_unless(cfg_size(cfg, "ip-address") == 0); 243 244 buf = "ip-address = 192.168.0.1"; 245 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 246 ipaddr = cfg_getptr(cfg, "ip-address"); 247 fail_unless(ipaddr != 0); 248 fail_unless(strcmp("192.168.0.1", inet_ntoa(*ipaddr)) == 0); 249 250 buf = "ip-address = 192.168.0.325"; 251 fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR); 252 253 buf = "ethernet-address = '00:03:93:d4:05:58'"; 254 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 255 etheraddr = cfg_getptr(cfg, "ethernet-address"); 256 fail_unless(etheraddr != 0); 257 fail_unless(my_ether_ntoa(etheraddr) != 0); 258 cmpether = my_ether_aton("00:03:93:d4:05:58"); 259 fail_unless(memcmp(etheraddr, cmpether, 6) == 0); 260 261 buf = "ethernet-address = '00:03:93:d4:05'"; 262 fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR); 263} 264 265void parse_buf_test(void) 266{ 267 char *buf; 268 269 fail_unless(cfg_parse_buf(cfg, 0) == CFG_SUCCESS); 270 fail_unless(cfg_parse_buf(cfg, "") == CFG_SUCCESS); 271 272 buf = "bool = wrong"; 273 fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR); 274 275 buf = "string = "; 276 fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR); 277 278 buf = "option = 'value'"; 279 fail_unless(cfg_parse_buf(cfg, buf) == CFG_PARSE_ERROR); 280} 281 282void nonexistent_option_test(void) 283{ 284 fail_unless(cfg_getopt(cfg, "nonexistent") == 0); 285 fail_unless(cfg_getopt(cfg, "section|subnonexistent") == 0); 286} 287 288void nodefault_test(void) 289{ 290 char *buf; 291 cfg_t *nodefsec; 292 293 fail_unless(cfg_size(cfg, "nodefstring") == 0); 294 cfg_setstr(cfg, "nodefstring", "manually set"); 295 fail_unless(cfg_size(cfg, "nodefstring") == 1); 296 fail_unless(cfg_size(cfg, "nodefsec") == 0); 297 298 buf = "nodefsec {}"; 299 fail_unless(cfg_parse_buf(cfg, buf) == CFG_SUCCESS); 300 nodefsec = cfg_getsec(cfg, "nodefsec"); 301 fail_unless(nodefsec != 0); 302 fail_unless(cfg_size(nodefsec, "string") == 1); 303 fail_unless(cfg_size(nodefsec, "int") == 0); 304} 305 306int 307main(void) 308{ 309 single_setup(); 310 311 single_string_test(); 312 single_integer_test(); 313 single_float_test(); 314 single_bool_test(); 315 single_section_test(); 316 single_ptr_test(); 317 parse_buf_test(); 318 nonexistent_option_test(); 319 nodefault_test(); 320 321 single_teardown(); 322 323 return 0; 324} 325 326