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