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.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 }

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