modules/rp/rp_load.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- make_sql2pack
- RP_sql_load_attr_space
- RP_sql_load_reg
- RP_asc_load
1 /***************************************
2 $Revision: 1.14 $
3
4 Radix payload (rp) - user level functions for storing data in radix trees
5
6 rp_load = loading the radix trees with data on startup
7
8 Status: NOT REVIEWED, TESTED
9
10 Design and implementation by: Marek Bukowy
11
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 <rp.h>
33 #include <mysql_driver.h>
34 #include <constants.h>
35
36 static
37 er_ret_t
38 make_sql2pack(SQ_result_set_t *result, SQ_row_t *row,
/* [<][>][^][v][top][bottom][index][help] */
39 rp_upd_pack_t *pack, rp_attr_t attr, int colcount)
40 {
41 er_ret_t conv = RP_OK;
42 rp_uni_t *uniptr = &(pack->uni);
43 char *idptr; /* initially set to the 0'th column */
44 char *col[4];
45 int i;
46
47 dieif(colcount>4); /* size of the col array */
48
49 for(i=0; i<colcount; i++) {
50 col[i] = SQ_get_column_string_nocopy(result, row, i);
51 if (col[i] == NULL) {
52 die;
53 }
54 }
55
56 idptr = col[0];
57
58 pack->type = attr;
59 pack->d.origin = NULL;
60 switch( attr ) {
61 case A_IN:
62 /*
63 read 0-2 from inetnum
64 0 - objectid
65 1 - begin
66 2 - end
67 */
68 uniptr->space = IP_V4;
69 conv = IP_rang_f2b_v4( &(uniptr->u.in), col[1], col[2] );
70 break;
71 case A_RT:
72 /*
73 read 0-3 from route
74 0 - objectid
75 1 - prefix
76 2 - prefix_length
77 3 - origin
78 */
79 uniptr->space = IP_V4;
80 if( NOERR(conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] ))) {
81 dieif(wr_malloc( (void **) &(pack->d.origin), strlen(col[3])+1)
82 != UT_OK);
83
84 strcpy(pack->d.origin, col[3]);
85 }
86 break;
87 case A_DN:
88 /*
89 read 0-3 from inaddr
90 0 - objectid
91 1 - prefix
92 2 - prefix_length
93 3 - domain
94 */
95 conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] );
96 uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
97 dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[3])+1)
98 != UT_OK);
99
100 strcpy(pack->d.domain, col[3]);
101 break;
102 case A_I6:
103 /*
104 read 0-3 from inaddr
105 0 - objectid
106 1 - msb
107 2 - lsb
108 3 - prefix_length
109 */
110 conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3]);
111 uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
112 break;
113 default:
114 /* die; / * shouldn't have got here */
115 conv = IP_INVARG;
116 }
117
118 if( sscanf(idptr, "%lu", &(pack->key) ) < 1 ) {
119 conv = IP_INVARG;
120 }
121
122
123 for(i=0; i<colcount; i++) {
124 /* wr_free(col[i]);*/ ;
125 }
126
127 return conv;
128 }
129
130 er_ret_t
131 RP_sql_load_attr_space( int maxobj, int operation,
/* [<][>][^][v][top][bottom][index][help] */
132 char *qry,
133 rp_attr_t attr, ip_space_t space,
134 rp_regid_t reg_id, SQ_connection_t *con
135 )
136 {
137 SQ_row_t *row;
138 SQ_result_set_t *result;
139 int objnr=0;
140 rx_tree_t *mytree;
141 rp_upd_pack_t pack;
142 int colcount;
143 int sizedebug = ER_is_traced(FAC_RP, ASP_RP_LOAD_DET);
144
145 dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
146
147
148 ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loading %s", qry);
149
150 ER_dbg_va(FAC_RP, ASP_RP_LOAD_GEN, "size before query = %x", sbrk(0));
151
152 if ( SQ_execute_query(con, qry, &result) == -1 ) {
153 fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
154 die;
155 }
156 else {
157 colcount = SQ_get_column_count(result);
158
159 ER_dbg_va(FAC_RP, ASP_RP_LOAD_GEN,
160 "size after query = %x; columns = %d", sbrk(0), colcount);
161
162 /* XXX LOCKED when created */
163 /*TH_acquire_write_lock( &(mytree->rwlock) );*/
164
165 while ( (row = SQ_row_next(result)) != NULL
166 && SQ_errno(con) == 0
167 && objnr<=maxobj) {
168
169 dieif( ! NOERR(make_sql2pack(result, row, &pack, attr, colcount)) );
170
171 if( ! NOERR(RP_pack_node_l(operation, &pack, mytree))) {
172 fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
173 die;
174 }
175
176 objnr++;
177
178 if( sizedebug ) {
179 ER_dbg_va(FAC_RP, ASP_RP_LOAD_DET, "size after object %d = %x",
180 objnr, sbrk(0));
181 }
182
183 }
184 /* XXX UNLOCK */
185 TH_release_write_lock( &(mytree->rwlock) );
186 }
187
188 if( SQ_errno(con) == 0 ) {
189 SQ_free_result(result);
190 } else {
191 die;
192 }
193
194 ER_inf_va(FAC_RP, ASP_RP_LOAD_GEN, "loaded %d objects into %s", objnr,
195 DF_get_attribute_code(attr) );
196
197
198 return RP_OK;
199 }
200
201 er_ret_t
202 RP_sql_load_reg(rp_regid_t reg_id)
/* [<][>][^][v][top][bottom][index][help] */
203 {
204 unsigned maxline = 999999999;
205 er_ret_t err;
206 SQ_connection_t *con;
207
208 /* Make connection */
209 /*
210 con = SQ_get_connection(HOST, DATABASE_PORT, DATABASE, USER, PASSWD);
211 */
212
213 con = SQ_get_connection(CO_get_host(),
214 CO_get_database_port(),
215 CO_get_database(), /* XXX for this regid */
216 CO_get_user(),
217 CO_get_password());
218
219 dieif ( SQ_execute_query(con, "LOCK TABLES "
220 "route READ, inetnum READ, inet6num READ, inaddr_arpa READ, domain READ ",
221 NULL) == -1 );
222
223 do {
224
225 if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
226 "SELECT object_id,prefix,prefix_length,origin FROM route ",
227 A_RT, IP_V4, reg_id, con))) {
228 break;
229 }
230
231 #if 0
232 {
233 er_path_t erlogstr;
234
235 erlogstr.fdes = stderr;
236 erlogstr.asp = 0xffff0000;
237 erlogstr.fac = FAC_RP; /* FAC_QI; */
238 erlogstr.sev = ER_SEV_I;
239 erlogstr.mode = ER_M_SEVCHAR | ER_M_FACSYMB | ER_M_TEXTLONG;
240
241 ER_setpath(& erlogstr);
242
243 wr_log_set(0);
244 }
245 #endif
246
247 if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
248 "SELECT object_id,begin_in,end_in FROM inetnum ",
249 A_IN, IP_V4, reg_id, con))) {
250 break;
251 }
252 if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
253
254 "SELECT object_id,i6_msb,i6_lsb,prefix_length FROM inet6num",
255
256 A_I6, IP_V6, reg_id, con))) {
257 break;
258 }
259 if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
260
261 "SELECT domain.object_id,prefix,prefix_length,domain FROM inaddr_arpa,domain WHERE domain.object_id = inaddr_arpa.object_id",
262
263 A_DN, IP_V4, reg_id, con))) {
264 break;
265 }
266
267 /* CONSTCOND */
268 }while(0);
269
270 dieif ( SQ_execute_query(con, "UNLOCK TABLES ", NULL) == -1 );
271
272 /* Close connection */
273 SQ_close_connection(con);
274
275 return err;
276 }
277
278
279 er_ret_t
280 RP_asc_load(char *filename, int maxobj, int operation,
/* [<][>][^][v][top][bottom][index][help] */
281 rp_regid_t reg_id)
282 {
283 er_ret_t err;
284 FILE *fp;
285 char buf[1024];
286 char fulltext[65536];
287 int objnr = 0;
288 int len, oldlen=0;
289 int ranlen;
290 char rangstr[IP_RANGSTR_MAX];
291 int parsed = 0;
292 int eor; /* end of record */
293
294
295 if( (fp = fopen(filename,"r")) == NULL ) {
296 perror(filename);
297 die;
298 }
299
300 do {
301 fgets(buf, 128, fp);
302
303 eor = ( strlen(buf) <= 1 || feof(fp) );
304
305 if( strlen(buf) > 1 ) {
306 len = strlen(buf);
307 dieif( oldlen+len+1 > 65536 ); /* object too long */
308 memcpy( fulltext+oldlen, buf, len);
309 oldlen+=len;
310
311 fulltext[oldlen]=0;
312 }
313
314 if( eor ) { /* end of object: put into the database. */
315 parsed++;
316
317 /* see if it was just some whitespace junk and nothing more */
318 if( *fulltext==0 ) {
319 continue; /* discard */
320 }
321
322 /* check if it's a radix object */
323 do {
324 char attrname[3];
325 A_Type_t attrcode;
326
327 if( fulltext[0] == '*' && fulltext[3] == ':' ) {
328 strncpy(attrname, fulltext+1, 2);
329 attrname[2]=0;
330
331 if(strcmp(attrname, "XX") == 0 ) {
332 /* object deleted */
333 break;
334 }
335
336 if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
337 fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
338 break;
339 }
340
341 if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
342 /* no interest to radix */
343 break;
344 }
345
346 /* copy and translate the range */
347 ranlen = index(fulltext+5,'\n')-fulltext-5;
348 strncpy(rangstr, fulltext+5, ranlen);
349 rangstr[ranlen]=0;
350
351 if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,
352 fulltext, strlen(fulltext)+1, 0L )) ) {
353 objnr++;
354 }
355 else {
356 die; /* error putting into the radix tree */
357 return err;
358 }
359
360 }
361 /* CONSTCOND */
362 } while(0);
363
364 *fulltext=0;
365 oldlen=0;
366 }
367 }
368 while(!feof(fp) && objnr<maxobj);
369
370 return RP_OK;
371 }