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
/***************************************
$Revision: 1.12 $
Radix payload (rp) - user level functions for storing data in radix trees
rp_load = loading the radix trees with data on startup
Status: NOT REVIEWED, TESTED
Design and implementation by: Marek Bukowy
******************/ /******************
Copyright (c) 1999 RIPE NCC
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the author not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
***************************************/
#include <rp.h>
#include <mysql_driver.h>
#include <constants.h>
static
er_ret_t
make_sql2pack(SQ_result_set_t *result, SQ_row_t *row,
/* [<][>][^][v][top][bottom][index][help] */
rp_upd_pack_t *pack, rp_attr_t attr)
{
er_ret_t conv = RP_OK;
rp_uni_t *uniptr = &(pack->uni);
char *idptr; /* initially set to the 0'th column */
char *col[4];
int i;
for(i=0; i<4; i++) {
col[i] = SQ_get_column_string(result, row, i);
if (col[i] == NULL) {
die;
}
}
idptr = col[0];
pack->type = attr;
pack->d.origin = NULL;
switch( attr ) {
case A_IN:
/*
read 0-2 from inetnum
0 - objectid
1 - begin
2 - end
*/
uniptr->space = IP_V4;
conv = IP_rang_f2b_v4( &(uniptr->u.in), col[1], col[2] );
break;
case A_RT:
/*
read 0-3 from route
0 - objectid
1 - prefix
2 - prefix_length
3 - origin
*/
uniptr->space = IP_V4;
if( NOERR(conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] ))) {
dieif(wr_malloc( (void **) &(pack->d.origin), strlen(col[3])+1)
!= UT_OK);
strcpy(pack->d.origin, col[3]);
}
break;
case A_DN:
/*
read 0-3 from inaddr
0 - objectid
1 - prefix
2 - prefix_length
3 - domain
*/
conv = IP_pref_f2b_v4( &(uniptr->u.rt), col[1], col[2] );
uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
dieif(wr_malloc( (void **) &(pack->d.domain), strlen(col[3])+1)
!= UT_OK);
strcpy(pack->d.domain, col[3]);
break;
case A_I6:
/*
read 0-3 from inaddr
0 - objectid
1 - msb
2 - lsb
3 - prefix_length
*/
conv = IP_pref_f2b_v6( &(uniptr->u.rt), col[1], col[2], col[3]);
uniptr->space = IP_pref_b2_space( &(uniptr->u.rt) );
break;
default:
/* die; / * shouldn't have got here */
conv = IP_INVARG;
}
if( sscanf(idptr, "%lu", &(pack->key) ) < 1 ) {
conv = IP_INVARG;
}
for(i=0; i<4; i++) {
wr_free(col[i]);
}
return conv;
}
er_ret_t
RP_sql_load_attr_space( int maxobj, int operation,
/* [<][>][^][v][top][bottom][index][help] */
char *qry,
rp_attr_t attr, ip_space_t space,
rp_regid_t reg_id, SQ_connection_t *con
)
{
SQ_row_t *row;
SQ_result_set_t *result;
int objnr=0;
rx_tree_t *mytree;
rp_upd_pack_t pack;
dieif( RP_tree_get ( &mytree, reg_id, space, attr ) != RP_OK );
ER_inf_va(FAC_RP, ASP_RP_LOAD, "loading %s", qry);
if ( SQ_execute_query(con, qry, &result) == -1 ) {
fprintf(stderr, "ERROR %d: %s\n", SQ_errno(con), SQ_error(con));
die;
}
else {
/* XXX LOCKED when created */
/*TH_acquire_write_lock( &(mytree->rwlock) );*/
while ( (row = SQ_row_next(result)) != NULL
&& SQ_errno(con) == 0
&& objnr<=maxobj) {
dieif( ! NOERR(make_sql2pack(result, row, &pack, attr)) );
if( ! NOERR(RP_pack_node_l(operation, &pack, mytree))) {
fprintf(stderr,"%d:\t%ld\n", objnr, pack.key);
die;
}
objnr++;
}
/* XXX UNLOCK */
TH_release_write_lock( &(mytree->rwlock) );
}
if( SQ_errno(con) == 0 ) {
SQ_free_result(result);
} else {
die;
}
ER_inf_va(FAC_RP, ASP_RP_LOAD, "loaded %d objects into %s", objnr,
DF_get_attribute_code(attr) );
return RP_OK;
}
er_ret_t
RP_sql_load_reg(rp_regid_t reg_id)
/* [<][>][^][v][top][bottom][index][help] */
{
unsigned maxline = 999999999;
er_ret_t err;
SQ_connection_t *con;
/* Make connection */
/*
con = SQ_get_connection(HOST, DATABASE_PORT, DATABASE, USER, PASSWD);
*/
con = SQ_get_connection(CO_get_host(),
CO_get_database_port(),
CO_get_database(), /* XXX for this regid */
CO_get_user(),
CO_get_password());
dieif ( SQ_execute_query(con, "LOCK TABLES "
"route READ, inetnum READ, inet6num READ, inaddr_arpa READ, domain READ ",
NULL) == -1 );
do {
if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
"SELECT object_id,prefix,prefix_length,origin FROM route ",
A_RT, IP_V4, reg_id, con))) {
break;
}
if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
"SELECT object_id,begin_in,end_in FROM inetnum ",
A_IN, IP_V4, reg_id, con))) {
break;
}
#if 1
if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
"SELECT object_id,i6_msb,i6_lsb,prefix_length FROM inet6num",
A_I6, IP_V6, reg_id, con))) {
break;
}
if( !NOERR(err=RP_sql_load_attr_space(maxline, RX_OPER_CRE,
"SELECT domain.object_id,prefix,prefix_length,domain FROM inaddr_arpa,domain WHERE domain.object_id = inaddr_arpa.object_id",
A_DN, IP_V4, reg_id, con))) {
break;
}
#endif
/* CONSTCOND */
}while(0);
dieif ( SQ_execute_query(con, "UNLOCK TABLES ", NULL) == -1 );
/* Close connection */
SQ_close_connection(con);
return err;
}
er_ret_t
RP_asc_load(char *filename, int maxobj, int operation,
/* [<][>][^][v][top][bottom][index][help] */
rp_regid_t reg_id)
{
er_ret_t err;
FILE *fp;
char buf[1024];
char fulltext[65536];
int objnr = 0;
int len, oldlen=0;
int ranlen;
char rangstr[IP_RANGSTR_MAX];
int parsed = 0;
int eor; /* end of record */
if( (fp = fopen(filename,"r")) == NULL ) {
perror(filename);
die;
}
do {
fgets(buf, 128, fp);
eor = ( strlen(buf) <= 1 || feof(fp) );
if( strlen(buf) > 1 ) {
len = strlen(buf);
dieif( oldlen+len+1 > 65536 ); /* object too long */
memcpy( fulltext+oldlen, buf, len);
oldlen+=len;
fulltext[oldlen]=0;
}
if( eor ) { /* end of object: put into the database. */
parsed++;
/* see if it was just some whitespace junk and nothing more */
if( *fulltext==0 ) {
continue; /* discard */
}
/* check if it's a radix object */
do {
char attrname[3];
A_Type_t attrcode;
if( fulltext[0] == '*' && fulltext[3] == ':' ) {
strncpy(attrname, fulltext+1, 2);
attrname[2]=0;
if(strcmp(attrname, "XX") == 0 ) {
/* object deleted */
break;
}
if( (attrcode = DF_attribute_code2type( attrname )) == -1 ) {
fprintf(stderr,"discarding a non-object:\n%s\n", fulltext);
break;
}
if( DF_attrcode_has_radix_lookup(attrcode) == 0 ) {
/* no interest to radix */
break;
}
/* copy and translate the range */
ranlen = index(fulltext+5,'\n')-fulltext-5;
strncpy(rangstr, fulltext+5, ranlen);
rangstr[ranlen]=0;
if( NOERR(err=RP_asc_node(operation, rangstr, attrcode, reg_id,
fulltext, strlen(fulltext)+1, 0L )) ) {
objnr++;
}
else {
die; /* error putting into the radix tree */
return err;
}
}
/* CONSTCOND */
} while(0);
*fulltext=0;
oldlen=0;
}
}
while(!feof(fp) && objnr<maxobj);
return RP_OK;
}