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 | }