1 | /***************************************
2 | $Revision: 1.23 $
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 |
119 | char * const DF_get_class_code(C_Type_t index) {
120 | if( index == C_ANY ) {
121 | return "*";
122 | }
123 | else {
124 | return Class_codes[index];
125 | }
126 | } /* DF_get_class_code() */
127 | #endif
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 | }