1    | #include <stdio.h>
2    | #include "ud_int.h" 
3    | #include "protocol_mirror.h"
4    | 
5    | void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl);
6    | 
7    | /************************************************************
8    | * PM_get_minmax_serial()                                    *
9    | *                                                           *
10   | * Returns the min or max serial number.                     *
11   | *                                                           *
12   | * Returns:                                                  *
13   | *  min (max=0) or max (max=1) serial number                 *
14   | *  -1 in case of an error                                   *
15   | *                                                           *
16   | * Note:                                                     *
17   | *  min serial= MIN(serial_id)+1                             *
18   | *  MIN(serial_id) represents legacy RIPE.CURRENSERIAL       *
19   | *  of the snapshot                                          *
20   | *                                                           *
21   | *************************************************************/
22   | long PM_get_minmax_serial(SQ_connection_t *sql_connection, int max)
23   | {
24   | char query[STR_M];
25   | SQ_result_set_t *sql_result;
26   | SQ_row_t *sql_row;
27   | char *sql_str;
28   | long current_serial;
29   | char *minmax;
30   | int sql_err;
31   | 
32   | if(max==1)minmax="max"; else minmax="min";
33   | 
34   |  sprintf(query, "SELECT %s(serial_id) FROM serials ", minmax);
35   | 
36   | //fprintf(stderr, "D:<get_field_str>:query: %s\n", query);
37   |  sql_err = SQ_execute_query(sql_connection, query, &sql_result);
38   |  
39   |  if(sql_err) {
40   |     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
41   |     return(-1);
42   |  }
43   |         
44   | 	 
45   |  if ((sql_row = SQ_row_next(sql_result)) != NULL) {
46   | 	sql_str = SQ_get_column_string(sql_result, sql_row, 0);
47   | 
48   |      /* We must process all the rows of the result,*/
49   |      /* otherwise we'll have them as part of the next qry */
50   | 	while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
51   | 	  fprintf(stderr, "E:<get_field_str> error : Dupl PK[%s]\n", query);
52   | 	  if(sql_str)free(sql_str); sql_str=NULL;
53   | 	}
54   |  }
55   |  else sql_str=NULL;
56   |  
57   |  if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
58   |  
59   |  if(sql_str) {
60   |   current_serial = atol(sql_str);
61   |   if(max!=1)current_serial++; 
62   |   free(sql_str);
63   |  }
64   |  else current_serial=-1;
65   |  
66   |  return(current_serial);
67   |  
68   | }
69   | 
70   | /************************************************************
71   | * int atlast(long serial_number)
72   | * -1 - sql error
73   | *
74   | ***********************************************************/
75   | 
76   | static int atlast(SQ_connection_t *sql_connection, long serial_number)
77   | {
78   | char *sql_str;
79   | char str_id[STR_S];
80   | int atlast=-1;
81   | 
82   | 
83   |   sprintf(str_id, "%ld", serial_number);
84   |   sql_str= get_field_str(sql_connection, "atlast", "serials", "serial_id", str_id, NULL);
85   |   if(sql_str) {
86   |        	  atlast = atoi(sql_str);
87   |        	  free(sql_str);
88   |   }
89   |   
90   |   return(atlast);
91   | 
92   | }
93   | 
94   | 
95   | /************************************************************
96   | * int getop(long serial_number)
97   | * -1 - sql error
98   | *
99   | * **********************************************************/
100  | 
101  | static int getop(SQ_connection_t *sql_connection, long serial_number)
102  | {
103  | char *sql_str;
104  | char str_id[STR_S];
105  | int op=-1;
106  | 
107  | 
108  |   sprintf(str_id, "%ld", serial_number);
109  |   sql_str= get_field_str(sql_connection, "operation", "serials", "serial_id", str_id, NULL);
110  |   if(sql_str) {
111  |        	  op = atoi(sql_str);
112  |        	  free(sql_str);
113  |   }
114  |   
115  |   return(op);
116  | 
117  | }
118  | 
119  | 
120  | /************************************************************
121  | * char *PM_get_serial_object()                                 *
122  | *                                                           *
123  | * Returns text block corresponding to the requested serial  *
124  | *                                                           *
125  | * Returns:                                                  *
126  | *  operation (ADD/DEL) and text object                      *
127  | *  NULL in case of an error                                 *
128  | *                                                           *
129  | * Note:                                                     *
130  | *  returned string should be freed by the caller            *
131  | *                                                           *
132  | *************************************************************/
133  | char *PM_get_serial_object(SQ_connection_t *sql_connection, long serial_number, int *operation)
134  | {
135  | char *table;
136  | SQ_result_set_t * sql_result;
137  | SQ_row_t *sql_row;
138  | char *sql_str;
139  | char query[STR_M];
140  | int sql_err;
141  | int location;
142  | 
143  |   switch(location=atlast(sql_connection, serial_number)){
144  |   
145  |    case 0: table="history";
146  |            break;
147  |    case 1: table="last";   
148  |            break;
149  |    case 2: table="transaction";
150  |            break;	   
151  |    default: return(NULL);   
152  |       
153  |   }
154  | 
155  |   if(location == 2) 
156  |      sprintf(query, "SELECT object FROM %s "
157  |                     "WHERE serial_id=%ld ",
158  | 		    table, serial_number);
159  |   else	  
160  |      sprintf(query, "SELECT %s.object FROM %s, serials "
161  |                     "WHERE serials.serial_id=%ld "
162  |                     "AND serials.object_id=%s.object_id "
163  |                     "AND serials.sequence_id=%s.sequence_id ", table, table, serial_number, table, table);
164  |                  
165  | 
166  |  sql_err = SQ_execute_query(sql_connection, query, &sql_result);
167  |  
168  |  if(sql_err) {
169  |     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
170  |     return(NULL);
171  |  }
172  |         
173  | 	 
174  |  if ((sql_row = SQ_row_next(sql_result)) != NULL) {
175  | 	sql_str = SQ_get_column_string(sql_result, sql_row, 0);
176  | 
177  |      /* We must process all the rows of the result,*/
178  |      /* otherwise we'll have them as part of the next qry */
179  | 	while ( (sql_row = SQ_row_next(sql_result)) != NULL) {
180  | 	  fprintf(stderr, "E:<get_field_str> error : Dupl PK[%s]\n", query);
181  | 	  if(sql_str)free(sql_str); sql_str=NULL;
182  | 	}
183  |  }
184  |  else sql_str=NULL;
185  |  
186  |  if(sql_result){ SQ_free_result(sql_result); sql_result=NULL; }
187  |  
188  |  *operation=getop(sql_connection, serial_number);
189  |  
190  |  return(sql_str);
191  |  
192  | }
193  | 
194  | /************************************************************
195  | * void pm_get_source_info()                                 *
196  | *                                                           *
197  | * Fills supplied buffer with information about the source   *
198  | *                                                           *
199  | * Returns text block corresponding to the requested source  *
200  | * Format:                                                   *
201  | * <source>:<can_mirror>:min_serial-max_serial               *
202  | * source - name of the source (e.g. RIPE, RADB, etc.)       *
203  | * can_mirror                                                * 
204  | *    'Y' if the client is allowed to mirror the source      *
205  | *    'N' if not                                             *
206  | *    'N' if there is no serials (then the range starts at 0)*    
207  | *                                                           * 
208  | *                                                           *
209  | *************************************************************/
210  | void pm_get_source_info(GString *gbuff, ip_addr_t *client_address, char *source, ca_dbSource_t *source_hdl)
211  | {
212  | 
213  | char *db_host = ca_get_srcdbmachine(source_hdl);
214  | int   db_port = ca_get_srcdbport(source_hdl);
215  | char *db_name = ca_get_srcdbname(source_hdl);
216  | char *db_user = ca_get_srcdbuser(source_hdl);
217  | char *db_passwd = ca_get_srcdbpassword(source_hdl);
218  | SQ_connection_t *db_connection;
219  | long min_serial, max_serial;
220  | char can_mirror;
221  |   
222  |       /* Connect to the database */
223  |        db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
224  |        min_serial=PM_get_oldest_serial(db_connection);
225  |        max_serial=PM_get_current_serial(db_connection);
226  |        
227  |        /* If it cannot be morrored at all - N, but range starts with 0 */
228  |        /* If the client is allowed to mirror - Y         */
229  |        /* Otherwise - N                                  */
230  |        if(min_serial>max_serial) {
231  | 	       can_mirror='N';
232  | 	       min_serial=0;
233  |        }
234  |        else {
235  | 	       if(AA_can_mirror(client_address, source )) can_mirror='Y';
236  |                else can_mirror='N';
237  |        }	
238  |        g_string_sprintfa(gbuff, "%s:%c:%lu-%lu\n", source, can_mirror, min_serial, max_serial);
239  |        
240  |        free(db_host);
241  |        free(db_name);
242  |        free(db_user);
243  |        free(db_passwd);
244  |        SQ_close_connection(db_connection);
245  | }
246  | 
247  | /************************************************************
248  | * GString *PM_get_nrtm_sources()                            *
249  | *                                                           *
250  | * Fills supplied buffer with information about the sources  *
251  | *                                                           *
252  | *                                                           * 
253  | * Note:                                                     *
254  | *  returned GString should be freed by the caller           *
255  | *                                                           *
256  | *************************************************************/
257  | GString *PM_get_nrtm_sources(ip_addr_t *client_address, char *source)
258  | {
259  | GString *gbuff=g_string_sized_new(STR_L);
260  | int nsource;
261  | ca_dbSource_t *source_hdl;
262  | 
263  |    if(source){
264  |       source_hdl = ca_get_SourceHandleByName(source);
265  |       if (source_hdl)pm_get_source_info(gbuff, client_address, source, source_hdl);
266  |    } else 
267  |       for(nsource=0; (source_hdl = ca_get_SourceHandleByPosition(nsource))!=NULL ; nsource++){
268  |        source=ca_get_srcname(source_hdl);
269  |        pm_get_source_info(gbuff, client_address, source, source_hdl);
270  |        free(source);
271  |    }
272  |    
273  |    g_string_sprintfa(gbuff, "\n\n");
274  |    return(gbuff);
275  | }