Source File modules/rp/rp_load.c

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