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