1 | /*************************************** 2 | $Revision: 1.28 $ 3 | 4 | Definitions module (df) 5 | 6 | Status: NOT REVUED, NOT TESTED 7 | 8 | ******************/ /****************** 9 | Filename : defs.c 10 | Authors : ottrey@ripe.net 11 | marek@ripe.net 12 | ******************/ /****************** 13 | Copyright (c) 1999,2000,2001,2002 RIPE NCC 14 | 15 | All Rights Reserved 16 | 17 | Permission to use, copy, modify, and distribute this software and its 18 | documentation for any purpose and without fee is hereby granted, 19 | provided that the above copyright notice appear in all copies and that 20 | both that copyright notice and this permission notice appear in 21 | supporting documentation, and that the name of the author not be 22 | used in advertising or publicity pertaining to distribution of the 23 | software without specific, written prior permission. 24 | 25 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 26 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 27 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 28 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 29 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 30 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 31 | ***************************************/ 32 | #define DEFS_IMPL 33 | #include "rip.h" 34 | 35 | #include <stdio.h> 36 | #include <stdlib.h> 37 | #include <stdarg.h> 38 | #include <strings.h> 39 | #include <glib.h> 40 | #include <pthread.h> 41 | 42 | #include "DF_class_names.def" 43 | #include "DF_class_codes.def" 44 | #include "DF_class_aliases.def" 45 | #include "DF_class_aliases_map.def" 46 | #include "DF_class_dbase_code_map.def" 47 | #include "DF_class_templates.def" 48 | #include "DF_class_templates_v.def" 49 | 50 | #include "DF_attribute_names.def" 51 | #include "DF_attribute_codes.def" 52 | #include "DF_attribute_aliases.def" 53 | #include "DF_attribute_aliases_map.def" 54 | 55 | #include "UD_queries.def" 56 | 57 | 58 | 59 | /* getsubopt requires a vector of pointers to a list of possible options 60 | It's used for parsing the source list. 61 | Therefore a quick 62 | XXX !!!! 63 | hack: hardcode it. Will be initialised from the Sources array 64 | once the config module is defined 65 | */ 66 | 67 | char * const Server_queries[] = { 68 | "sources", 69 | "version", 70 | NULL 71 | }; /* Server_queries */ 72 | 73 | /* Filtered names of classes (only "public" objects, no person or role). 74 | 75 | XXX this also should be generated from XML... 76 | */ 77 | char * const Filter_names[] = { 78 | "as-block", 79 | "as-set", 80 | "aut-num", 81 | "domain", 82 | "inet-rtr", 83 | "inet6num", 84 | "inetnum", 85 | "key-cert", 86 | "limerick", 87 | "mntner", 88 | "route", 89 | "origin", 90 | "route-set", 91 | "members", 92 | "filter-set", 93 | "peering-set", 94 | "rtr-set", 95 | "irt", 96 | NULL 97 | }; /* Filter_names */ 98 | 99 | char * const *DF_get_filter_names(void) { 100 | return Filter_names; 101 | } /* DF_get_filter_names() */ 102 | 103 | char * const *DF_get_class_names(void) { 104 | return Class_names; 105 | } /* DF_get_class_names() */ 106 | 107 | char * const *DF_get_class_aliases(void) { 108 | return Class_aliases; 109 | } /* DF_get_class_aliases() */ 110 | 111 | int DF_get_class_index(int alias_index) { 112 | return Class_aliases_map[alias_index]; 113 | } /* DF_get_class_index() */ 114 | 115 | #if 0 116 | char * const DF_get_class_name(int alias_index) { 117 | return Class_names[Class_aliases_map[alias_index]]; 118 | } /* DF_get_class_name() */ 119 | #endif 120 | 121 | char * const DF_get_class_code(C_Type_t index) { 122 | if( index == C_ANY ) { 123 | return "*"; 124 | } 125 | else { 126 | return Class_codes[index]; 127 | } 128 | } /* DF_get_class_code() */ 129 | 130 | int DF_get_class_dbase_code(int class_index) { 131 | return Class_dbase_code_map[class_index]; 132 | } /* DF_get_class_dbase_code() */ 133 | 134 | /* Main tables names for object types */ 135 | /*XXX thsi should be modified according to class ordser */ 136 | char * const Type2main[] = { 137 | "as_block", 138 | "as_set", 139 | "aut_num", 140 | "domain", 141 | "inet_rtr", 142 | "inet6num", 143 | "inetnum", 144 | "key_cert", 145 | "limerick", 146 | "mntner", 147 | "person_role", 148 | "person_role", 149 | "route", 150 | "route_set", 151 | "filter_set", 152 | "peering_set", 153 | "rtr_set", 154 | "irt", 155 | NULL 156 | }; 157 | 158 | char * const DF_get_class_sql_table(C_Type_t index) { 159 | return Type2main[index]; 160 | } /* DF_get_class_sql_table() */ 161 | 162 | 163 | 164 | char * const *DF_get_attribute_aliases(void) { 165 | return Attribute_aliases; 166 | } /* DF_get_attribute_aliases() */ 167 | 168 | const char *DF_get_attribute_name(A_Type_t index) { 169 | return Attribute_names[index]; 170 | } /* DF_get_attribute_name() */ 171 | 172 | const char *DF_get_attribute_code(A_Type_t index) { 173 | return Attribute_codes[index]; 174 | } /* DF_get_attribute_code() */ 175 | 176 | char * const *DF_get_attribute_names(void) { 177 | return Attribute_names; 178 | } /* DF_get_attribute_names() */ 179 | 180 | int DF_get_attribute_index(int alias_index) { 181 | return Attribute_aliases_map[alias_index]; 182 | } /* DF_get_attribute_index() */ 183 | 184 | const char *DF_get_class_template(C_Type_t index) { 185 | return Templates[index]; 186 | } /* DF_get_class_template() */ 187 | 188 | const char *DF_get_class_template_v(C_Type_t index) { 189 | return Templates_v[index]; 190 | } /* DF_get_class_template_v() */ 191 | 192 | char * const *DF_get_server_queries(void) { 193 | return Server_queries; 194 | } /* DF_get_server_queries() */ 195 | 196 | const char *DF_get_update_query(A_Type_t index){ 197 | return Update[index].qry; 198 | } /* DF_get_update_query() */ 199 | 200 | UD_qtype DF_get_update_query_type(A_Type_t index){ 201 | return Update[index].qtype; 202 | } /* DF_get_update_query_type() */ 203 | 204 | const char *DF_get_insert_query(A_Type_t index){ 205 | return Insert[index].qry; 206 | } /* DF_get_insert_query() */ 207 | 208 | UD_qtype DF_get_insert_query_type(A_Type_t index){ 209 | return Insert[index].qtype; 210 | } /* DF_get_insert_query_type() */ 211 | 212 | const char *DF_get_select_query(A_Type_t index){ 213 | return Select[index].qry; 214 | } /* DF_get_select_query() */ 215 | 216 | UD_qtype DF_get_select_query_type(A_Type_t index){ 217 | return Select[index].qtype; 218 | } /* DF_get_select_query_type() */ 219 | 220 | const char *DF_get_dummy_query(A_Type_t index){ 221 | return Dummy[index].qry; 222 | } /* DF_get_dummy_query() */ 223 | 224 | UD_qtype DF_get_dummy_query_type(A_Type_t index){ 225 | return Dummy[index].qtype; 226 | } /* DF_get_dummy_query_type() */ 227 | 228 | 229 | #if 0 /* not used anywhere */ 230 | const char *DF_get_attribute_desc(A_Type_t index) { 231 | /* 232 | return (char *)Attributes_details[attr_index][0]; 233 | */ 234 | return NULL; 235 | } /* DF_get_attribute_desc() */ 236 | 237 | const char *DF_get_attribute_frmt(A_Type_t index) { 238 | /* 239 | return (char *)Attributes_details[attr_index][1]; 240 | */ 241 | return NULL; 242 | } /* DF_get_attribute_frmt() */ 243 | 244 | /* DF_attributes_to_string() */ 245 | /*++++++++++++++++++++++++++++++++++++++ 246 | Returns a string of all the attributes. Only there for debugging and tracing purposes. 247 | 248 | More: 249 | +html+ <PRE> 250 | Authors: 251 | ottrey 252 | 253 | +html+ </PRE><DL COMPACT> 254 | +html+ <DT>Online References: 255 | +html+ <DD><UL> 256 | +html+ </UL></DL> 257 | 258 | ++++++++++++++++++++++++++++++++++++++*/ 259 | char *DF_attributes_to_string(void) { 260 | int i; 261 | char *str; 262 | char str_buffer[4096]; 263 | unsigned str_len; 264 | 265 | strcpy(str_buffer, "{\""); 266 | for (i=0; Attribute_names[i] != NULL; i++) { 267 | strcat(str_buffer, Attribute_names[i]); 268 | strcat(str_buffer, "\", \""); 269 | } 270 | str_len = strlen(str_buffer); 271 | str_buffer[str_len-3] = '}'; 272 | str_buffer[str_len-2] = '\0'; 273 | str_len--; 274 | 275 | /* str = (char *)calloc(1, str_len); */ 276 | /*dieif( wr_malloc((void **)&str, str_len ) != UT_OK); 277 | strcpy(str, str_buffer); */ 278 | 279 | return UT_strdup(str_buffer); 280 | 281 | } /* DF_attributes_to_string() */ 282 | #endif /* not used */ 283 | 284 | 285 | /* XXX This could be done MUCH more efficiently (with a hash) */ 286 | A_Type_t DF_attribute_code2type(const gchar *token) { 287 | A_Type_t result=-1; 288 | 289 | int i; 290 | for (i=0; Attribute_aliases[i] != NULL; i++) { 291 | if (strcmp(Attribute_aliases[i], token) == 0) { 292 | result = Attribute_aliases_map[i]; 293 | break; 294 | } 295 | } 296 | 297 | return result; 298 | } /* DF_attribute_code2type() */ 299 | 300 | /* 301 | Description: 302 | 303 | Find the type identifier for the given long attribute name. This can 304 | be used to get the attribute code via the DF_get_attribute_code() 305 | function. 306 | 307 | Arguments: 308 | 309 | const gchar *token; attribute name, e.g. "person", "aut-num", or "limerick" 310 | 311 | Returns: 312 | 313 | A_Type_t with the attribute's code, or -1 on error (bad attribute name). 314 | 315 | Notes: 316 | 317 | Uses a hash table for speedy conversion. The first time this is called, 318 | the hash table will be built. Subsequent calls use that table. 319 | 320 | It might be better to provide a single function to translate from an 321 | attribute name to the attribute code, but for now, just use 322 | DF_get_attribute_code() with the value returned here. - SK 323 | */ 324 | static GHashTable *name2type_hash = NULL; 325 | 326 | static void init_name2type_hash() 327 | { 328 | A_Type_t *val; 329 | int i; 330 | 331 | name2type_hash = g_hash_table_new(g_str_hash, g_str_equal); 332 | for (i=0; Attribute_aliases[i] != NULL; i++) { 333 | /*wr_malloc((void *)&val, sizeof(A_Type_t));*/ 334 | val = UT_malloc(sizeof(A_Type_t)); 335 | *val = Attribute_aliases_map[i]; 336 | g_hash_table_insert(name2type_hash, Attribute_aliases[i], val); 337 | } 338 | } 339 | 340 | A_Type_t DF_attribute_name2type (const gchar *token) 341 | { 342 | static pthread_once_t once_control = { PTHREAD_ONCE_INIT }; 343 | A_Type_t *result; 344 | 345 | /* build table on first call */ 346 | pthread_once(&once_control, init_name2type_hash); 347 | 348 | /* find the type in our has table, returning if found */ 349 | result = g_hash_table_lookup(name2type_hash, token); 350 | if (result != NULL) { 351 | return *result; 352 | } else { 353 | return -1; 354 | } 355 | } /* DF_attribute_name2type() */ 356 | 357 | /* XXX This could be done MUCH more efficiently (with a hash) */ 358 | C_Type_t DF_class_code2type(const gchar *token) { 359 | C_Type_t result=-1; 360 | 361 | int i; 362 | for (i=0; Class_aliases[i] != NULL; i++) { 363 | if (strcmp(Class_aliases[i], token) == 0) { 364 | result = Class_aliases_map[i]; 365 | break; 366 | } 367 | } 368 | 369 | return result; 370 | } /* DF_class_code2type() */ 371 | 372 | /* XXX This could be done MUCH more efficiently (with a hash) */ 373 | C_Type_t DF_class_name2type(const gchar *token) { 374 | C_Type_t result=-1; 375 | 376 | int i; 377 | for (i=0; Class_aliases[i] != NULL; i++) { 378 | if (strcmp(Class_aliases[i], token) == 0) { 379 | result = Class_aliases_map[i]; 380 | break; 381 | } 382 | } 383 | 384 | return result; 385 | } /* DF_class_name2type() */ 386 | 387 | /* Returns class name for a given type */ 388 | const char *DF_class_type2name(C_Type_t class) { 389 | return(Class_names[class]); 390 | }/* DF_class_type2name() */ 391 | 392 | 393 | /* check in the queries if this attribute can trigger a radix lookup */ 394 | int DF_attrcode_has_radix_lookup(A_Type_t attr) 395 | { 396 | int i; 397 | 398 | for (i=0; Query[i].query != NULL; i++) { 399 | if( Query[i].refer == R_RADIX && 400 | Query[i].attribute == attr ) { 401 | return 1; 402 | } 403 | } 404 | return 0; 405 | } 406 | 407 | /* return the sql query to load the radix ipv4 tree for this attribute 408 | or NULL if no ipv4 radix is used for this attribute */ 409 | char * DF_attrcode_radix_load_v4(A_Type_t attr) 410 | { 411 | int i; 412 | 413 | for(i=0; 414 | DF_radix_load[i].attr != -1 && DF_radix_load[i].family != -1; 415 | i++) { 416 | 417 | if( DF_radix_load[i].attr == attr ) { 418 | return DF_radix_load[i].ipv4_load; 419 | } 420 | } 421 | return NULL; 422 | } 423 | 424 | /* return the sql query to load the radix ipv4 tree for this attribute 425 | or NULL if no ipv4 radix is used for this attribute */ 426 | char * DF_attrcode_radix_load_v6(A_Type_t attr) 427 | { 428 | int i; 429 | 430 | for(i=0; 431 | DF_radix_load[i].attr != -1 && DF_radix_load[i].family != -1; 432 | i++) { 433 | 434 | if( DF_radix_load[i].attr == attr ) { 435 | return DF_radix_load[i].ipv6_load; 436 | } 437 | } 438 | return NULL; 439 | } 440 | 441 | /* return the family of the radix tree(s) used for this attribute 442 | or -1 if no radix is used for this attribute */ 443 | rx_fam_t DF_attrcode_radix_family(A_Type_t attr) { 444 | int i; 445 | 446 | for(i=0; 447 | DF_radix_load[i].attr != -1 && DF_radix_load[i].family != -1; 448 | i++) { 449 | 450 | if( DF_radix_load[i].attr == attr ) { 451 | return DF_radix_load[i].family; 452 | } 453 | } 454 | return -1; 455 | }