modules/rp/rp_load.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. make_sql2pack
  2. RP_sql_load_attr_space
  3. RP_sql_load_reg
  4. RP_asc_load

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

/* [<][>][^][v][top][bottom][index][help] */