## 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.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,
         /* [<][>][^][v][top][bottom][index][help] */
      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,
         /* [<][>][^][v][top][bottom][index][help] */
     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)
         /* [<][>][^][v][top][bottom][index][help] */
     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,
         /* [<][>][^][v][top][bottom][index][help] */
     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 }

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