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