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