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