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