## 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] */