modules/up/UP_extrnl_syntax.c

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

DEFINITIONS

This source file includes following functions.
  1. up_check_source_attr
  2. up_check_country_attr
  3. up_check_nicsuffixes
  4. up_get_dates
  5. up_changed_has_date
  6. UP_get_current_date
  7. up_add_dates
  8. up_check_date_order
  9. up_check_date
  10. up_check_dates_syntax
  11. up_check_changed_attr
  12. up_check_an_inetnum_attr
  13. up_add_keycert_attrs
  14. up_reconstruct_object
  15. UP_check_external_syntax
  16. UP_generate_kc_attrs
  17. up_assign_i6_status
  18. up_add_inet6num_attrs

   1 /***************************************
   2   $Revision: 1.16 $
   3 
   4   UP external syntax checks
   5 
   6   Status: REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (15/12/2000) Created.
  13         denis (31/08/2001) Modified for new API
  14   ******************/ /******************
  15   Copyright (c) 2001,2002                         RIPE NCC
  16  
  17   All Rights Reserved
  18   
  19   Permission to use, copy, modify, and distribute this software and its
  20   documentation for any purpose and without fee is hereby granted,
  21   provided that the above copyright notice appear in all copies and that
  22   both that copyright notice and this permission notice appear in
  23   supporting documentation, and that the name of the author not be
  24   used in advertising or publicity pertaining to distribution of the
  25   software without specific, written prior permission.
  26   
  27   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  28   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  29   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  30   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  31   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  32   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33  ***************************************/
  34 
  35 
  36 /*#include "rpsl/object.hh"*/
  37 #include "UP_extrnl_syntax.h"
  38 #include "dbupdate.h"
  39 
  40 #define UP_DATE_OK      0
  41 #define UP_DATE_SYNERR  1
  42 #define UP_DATE_FUTURE  2
  43 #define UP_DATE_TOOSMALL        3
  44 #define UP_DATE_INVMONTH        4
  45 #define UP_DATE_INVDAY  5
  46 #define UP_DATE_WRONGFORMAT 6
  47 #define UP_DATE_NOK    7
  48 
  49 char * up_date_errmsgs[]=
  50 {
  51 
  52   "OK",
  53   "Syntax error in date of 'changed' attribute",
  54   "Date in the future in 'changed' attribute",
  55   "Date is older than the database itself in 'changed' attribute",
  56   "Invalid month in date in 'changed' attribute",
  57   "Invalid day in date in 'changed' attribute",
  58   "Date must be in YYYYMMDD format in 'change' attribute",
  59   "Syntax error in date of 'changed' attribute"
  60 };
  61 
  62 
  63 extern int tracing;
  64 
  65 extern char * fingerprint;
  66 extern char * keyowner;
  67 
  68 extern int      num_sources;
  69 extern char    *countries[];
  70 extern char    *nicsuffixes[];
  71 extern ca_updDbSource_t **upd_source_hdl;
  72 
  73 
  74 /* void up_check_source_attr 
  75    checks for a valid source in the 'source' attributes */
  76 void up_check_source_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
  77 {
  78   int valid,i ;
  79   char *source_name;
  80   char *temp;
  81   GList *source_list;
  82 
  83   if (tracing)
  84   {
  85     printf("TRACING: up_check_source_attr running\n");
  86   }
  87  
  88   source_list = rpsl_object_get_attr(external_syntax_obj, "source");
  89 
  90   valid = i = 0 ;
  91   if ( source_list )
  92   {
  93     source_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(source_list->data) );
  94     for ( i=0; i<num_sources; i++ )
  95     {
  96       if ( ! strcasecmp( source_name, upd_source_hdl[i]->name) )
  97       {
  98         valid = 1;
  99         break;
 100       }
 101     }
 102 
 103 /*    while(sources[i])
 104     {
 105       if(strcasecmp(sources[i++],source_name) == 0)
 106       {
 107         valid = 1;
 108         break;
 109       }
 110     } */
 111 
 112     g_list_free(source_list);
 113   }
 114 
 115   if (!valid)
 116   {
 117     /* the source is not recognised */
 118 
 119     if (tracing)
 120     {
 121       printf("TRACING: invalid source [%s]\n", source_name );
 122     }
 123 
 124     if (result->error_str == NULL)
 125         {
 126       result->error_str = strdup("***Error: No such source");
 127     }
 128         else
 129         {
 130       temp = (char *)malloc(strlen(result->error_str) 
 131               + strlen("***Error: No such source") + 2);
 132       sprintf(temp, "%s\n%s", result->error_str, 
 133               "***Error: No such source");
 134       free(result->error_str);
 135       result->error_str = temp;
 136     }
 137     /* and here we have to change the result code of "result" here ... */
 138     switch (result->result)
 139         {
 140       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 141       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 142       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 143       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 144       default:                 result->result = UP_EXTSYN_ERR; break;
 145     }
 146   }
 147   
 148   free(source_name);
 149 }
 150 
 151 
 152 /* void up_check_country_attr 
 153    checks for a valid country in the 'country' attributes */
 154 void up_check_country_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 155 {
 156   int valid,i, matched ;
 157   char *country_name;
 158   char *temp;
 159   GList *country_list = NULL;
 160   GList *country_item = NULL;
 161  
 162   country_list = rpsl_object_get_attr(external_syntax_obj, "country");
 163   rpsl_attr_split_multiple(&country_list);
 164   
 165   if ( country_list == NULL )
 166     return;             /* only check if there is one */
 167 
 168   valid = 1 ;
 169   for ( country_item = country_list; country_item != NULL ; country_item = g_list_next(country_item) )
 170   {
 171     country_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(country_item->data) );
 172     matched = 0 ;
 173     i = 0 ;
 174     while(countries[i])
 175     {
 176       if(strcasecmp(countries[i++],country_name) == 0)
 177       {
 178         matched = 1;
 179         break;
 180       }
 181     }
 182 
 183     if ( ! matched )
 184     {
 185       valid = 0 ;
 186       break;
 187     }
 188     free(country_name);
 189   }
 190   g_list_free(country_list);
 191 
 192   if (!valid)
 193   {
 194     /* the country is not recognised */
 195     if (result->error_str == NULL)
 196         {
 197       result->error_str = malloc(strlen("***Error: No such country []") + strlen(country_name) +2);
 198       sprintf(result->error_str, "***Error: No such country [%s]", country_name);
 199     }
 200         else
 201         {
 202       temp = (char *)malloc(strlen(result->error_str) 
 203               + strlen("***Error: No such country []") + strlen(country_name) + 2);
 204       sprintf(temp, "%s\n***Error: No such country [%s]", result->error_str, 
 205               country_name);
 206       free(result->error_str);
 207       result->error_str = temp;
 208     }
 209 
 210     free(country_name);
 211 
 212     /* and here we have to change the result code of "result" here ... */
 213     switch (result->result)
 214         {
 215       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 216       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 217       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 218       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 219       default: ;
 220     }
 221   }
 222 }
 223 
 224 /* void up_check_nicsuffixes 
 225    checks for a valid suffix at the end of a 'nic-hdl' attributes */
 226 void up_check_nicsuffixes(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 227 {
 228   int valid,i ;
 229   char *name;
 230   char *temp;
 231   GList *list;
 232 
 233   if (tracing)
 234   {
 235     printf("TRACING: up_check_nicsuffixes running\n");
 236   }
 237  
 238   list = rpsl_object_get_attr(external_syntax_obj, "nic-hdl");
 239 
 240   valid = i = 0 ;
 241   if ( list )
 242   {
 243     name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(list->data) );
 244     if ( !strchr(name,'-') || strncasecmp(name,"AUTO-",strlen("AUTO-")) == 0 )
 245     {
 246       valid = 1;
 247     }
 248     else
 249     {
 250       while (nicsuffixes[i])
 251       {
 252         if ( strcasecmp(nicsuffixes[i++],strchr(name,'-')+1) == 0 )
 253         {
 254           valid = 1;
 255           break;
 256         }
 257       }
 258       if ( ! valid )
 259       {
 260         i = 0;
 261         for ( i=0; i<num_sources; i++ )
 262         {
 263           if ( ! strcasecmp( upd_source_hdl[i]->name, strchr(name,'-')+1) )
 264           {
 265             valid = 1;
 266             break;
 267           }
 268         }
 269 
 270 /*        while (sources[i])
 271         {
 272           if (strcasecmp(sources[i++],strchr(name,'-')+1) == 0 )
 273           {
 274             valid = 1;
 275             break;
 276           }
 277         } */
 278 
 279         if ( ! valid )
 280         {
 281           i = 0;
 282           while (countries[i])
 283           {
 284             if ( strcasecmp(countries[i++],strchr(name,'-')+1) == 0 )
 285             {
 286               valid = 1;
 287               break;
 288             }
 289           }
 290         }
 291       }
 292     }
 293     free(name);
 294     g_list_free(list);
 295 
 296     if (!valid)
 297     {
 298       /* the nicsuffix is not recognised */
 299       if (result->error_str == NULL)
 300           {
 301         result->error_str = strdup("***Error: Invalid nic-hdl suffix");
 302       }
 303           else
 304           {
 305         temp = (char *)malloc(strlen(result->error_str) 
 306                 + strlen("***Error: Invalid nic-hdl suffix") + 2);
 307         sprintf(temp, "%s\n%s", result->error_str, 
 308                 "***Error: Invalid nic-hdl suffix");
 309         free(result->error_str);
 310         result->error_str = temp;
 311       }
 312       /* and here we have to change the result code of "result" here ... */
 313       switch (result->result)
 314           {
 315         case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 316         case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 317         case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 318         case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 319         default: ;
 320       }
 321     }
 322   }
 323 }
 324 
 325 
 326 /* obtains a list of dates in the given 
 327    list of attributes  */
 328 GList * up_get_dates(GList * attribute_list)
     /* [<][>][^][v][top][bottom][index][help] */
 329 {
 330   GList * item;
 331   char * str, *temp; 
 332   GList * list = NULL;
 333 
 334   for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
 335   {
 336     /* is this a 'changed' attribute? */
 337     if ( strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0 )
 338         {
 339       str = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 340 
 341 
 342       /* now, we have the 'changed' attribute's content in "normalized" form 
 343          We are sure it contains a date. So, it must be the second (and last)
 344          word in the attrib. */
 345       assert(index(str,' ') != NULL);
 346       temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
 347       temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
 348       temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
 349       list = g_list_append (list, temp);   
 350     }
 351   }
 352   
 353   return list;
 354 }
 355 
 356 
 357 
 358 
 359 /* Does the 'changed' attribute we got have a date already?
 360    Returns 1 if it does, 0 if not. */
 361 int up_changed_has_date(char * value)
     /* [<][>][^][v][top][bottom][index][help] */
 362 {
 363   /* now, if there is still a white space, then we have a date in the string
 364      (it has to be something like "ripe-dbm@ripe.net 20001210") */
 365   if (index(value, ' ') != NULL)
 366   {
 367     return 1; 
 368   }
 369   else
 370   {
 371     return 0;
 372   }
 373 }
 374 
 375 
 376 
 377 
 378 /* supplies the current date in YYYYMMDD format (for example 20011010) */
 379 char * UP_get_current_date()
     /* [<][>][^][v][top][bottom][index][help] */
 380 {
 381   /* We will use Glib's functions here */
 382 
 383   char * date;
 384   struct tm * time_struct;
 385   
 386   time_t * time_loc;
 387 
 388   time_loc = (time_t *)malloc(sizeof(time_t));
 389   time(time_loc);
 390   
 391   time_struct = localtime(time_loc);
 392 
 393 
 394   date = (char *)malloc(9);
 395   sprintf(date, "%04i%02i%02i", 
 396           time_struct->tm_year + 1900, 
 397           time_struct->tm_mon + 1,
 398           time_struct->tm_mday);
 399   return date;
 400 }
 401 
 402 
 403 
 404 
 405 /* int up_add_dates: adds dates to 'changed' attributes which 
 406      are missing one.
 407      Returns 1 if no problems encountered
 408      Returns 0 if a problem encountered, and the error string is set */
 409 int up_add_dates(rpsl_object_t *external_syntax_obj, GList *attribute_list, char ** warning_str, char ** error_str)
     /* [<][>][^][v][top][bottom][index][help] */
 410 {
 411   GList * item;
 412   char * current_date;
 413   int count_no_date = 0; 
 414   char * temp;
 415   rpsl_attr_t *changed;
 416   char *value;
 417   int pos;
 418   
 419   *warning_str = NULL;
 420   *error_str   = NULL;
 421 
 422   /* get the current date in YYYYMMDD format (for example 20011010) */
 423   current_date = UP_get_current_date();
 424   
 425   for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
 426   {
 427     /* is this a 'changed' attribute? */
 428     if (strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0)
 429         {
 430       /* if this attribute does not have a date in it, add it. Also add 
 431           a warning message about this */
 432           value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 433       if ( !up_changed_has_date(value) )
 434           {
 435         count_no_date++;
 436                 /* create a copy of this changed attribute and add the date to the value */
 437                 changed = rpsl_attr_copy((rpsl_attr_t *)(item->data));
 438         temp = (char *)malloc(strlen(value) + strlen(current_date) + 2 );
 439         sprintf(temp, "%s %s", value, current_date);
 440         rpsl_attr_replace_value(changed, temp);
 441         free(temp);
 442                 /* delete the original attribute from the object */
 443                 pos = rpsl_attr_get_ofs(changed);
 444                 rpsl_object_remove_attr(external_syntax_obj, pos, NULL);
 445                 /* add the new changed attribute in the same position */
 446                 rpsl_object_add_attr(external_syntax_obj, changed, pos, NULL);
 447         /* add a warning message */
 448         if ( *warning_str == NULL)
 449                 {
 450           *warning_str = (char *)malloc(strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 451           sprintf(*warning_str, "WARNING  date '%s' added to 'changed' attribute", current_date);
 452         }
 453                 else
 454                 {
 455           temp = (char *)malloc(strlen(*warning_str) + 1 
 456                                        + strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 457           sprintf(temp, "%s\nWARNING  date '%s' added to 'changed' attribute", 
 458                               *warning_str, current_date);
 459           free(*warning_str);
 460           *warning_str = temp; 
 461         }
 462       }
 463           free(value);
 464     }
 465   }
 466   
 467   if (count_no_date > 1)
 468   { 
 469     *error_str = strdup("***Error: More than one 'changed' attributes without dates");
 470     return 0;
 471   }
 472   else
 473   {
 474     return 1;
 475   }
 476 }
 477 
 478 
 479 
 480 
 481 /* Checks the order of dates in the given list. 
 482    If they are in order, returns 1, 
 483    if not, returns 0 */
 484 int up_check_date_order(GList * list)
     /* [<][>][^][v][top][bottom][index][help] */
 485 {
 486   GList * item;
 487   char * previous;
 488   char *value;
 489 
 490   /* if list is empty, return 1 immediately */
 491   if (list == NULL)
 492   {
 493     return 1;
 494   }
 495 
 496   /* initialize the 'previous' date */
 497   previous = strdup("00000000");
 498    
 499   for ( item = list; item != NULL ; item = g_list_next(item))
 500   {
 501     assert((item->data) != NULL);
 502     /* if the new date is smaller than the previous */
 503         value = (char *)(item->data);
 504     if ( strcmp(value, previous) < 0 )
 505         {
 506       free(previous);
 507       return 0;
 508     }
 509     free(previous);
 510     previous = strdup(value);
 511   }
 512    
 513   free(previous);
 514   /* Reached the end, without finding out-of-order date. Return 1, then */
 515   return 1; 
 516 }
 517 
 518 
 519 
 520 
 521 
 522 /* up_check_date: checks the syntax of the date, given as the only
 523    argument (char *). The argument is checked if it is in YYYYMMDD
 524    format, and returns an error code accordingly */
 525 int up_check_date(const char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 526 {
 527   int date_int; /* integer representation of the date (arg) */
 528   char * current_date;
 529   int year, month, day; /* integers for the components of the date */
 530 
 531   errno = 0;
 532   date_int = atoi(arg);
 533       
 534   if (errno != 0)
 535   { /* there was an error in the conversion, syntax error */
 536     return UP_DATE_SYNERR;
 537   }
 538     
 539   /* wrong format */
 540   if (date_int <= 10000000 )
 541   { /* the date is not in YYYYMMDD format */
 542     return UP_DATE_WRONGFORMAT;
 543   }
 544 
 545   /* check if it is too small */  
 546   if (date_int <= 19840000 )
 547   { /* the date is older than the DB itself! */
 548     return UP_DATE_TOOSMALL;
 549   }
 550 
 551   /* check if it is too big */
 552   if (date_int >= 100000000 )
 553   {/* too big: syntax error */
 554     return UP_DATE_SYNERR;
 555   }
 556 
 557   /* and now check year, month and day components */
 558   year = date_int / 10000;
 559   month = (date_int - (year * 10000) ) / 100;
 560   day = (date_int % 100);
 561   
 562   /* check year */
 563   if (year < 1984 )
 564   {
 565     return UP_DATE_TOOSMALL;
 566   }
 567 
 568   /* check month */
 569   if (month < 1 || month > 12)
 570   {
 571     return UP_DATE_INVMONTH;
 572   }
 573 
 574   /* check day */
 575   if (day < 1 || day > 31)
 576   {
 577     return UP_DATE_INVDAY;
 578   }
 579 
 580   switch ( month )
 581   {
 582     case 1: case 3: case 5: case 7:
 583     case 8: case 10: case 12:
 584          if (day > 31)
 585                  {
 586            return UP_DATE_INVDAY;
 587          };
 588          break;
 589     case 2: 
 590          if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 ))
 591                  { /* leap year */
 592            return UP_DATE_INVDAY;
 593          }
 594                  else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) )
 595                  { /* non-leap year */
 596            return UP_DATE_INVDAY;
 597          };
 598          break;
 599     case 4: case 6: case 9: case 11:
 600          if (day > 30)
 601                  {
 602            return UP_DATE_INVDAY;
 603          };
 604          break;
 605     default: return UP_DATE_INVMONTH;
 606   }
 607 
 608   /* check if the arg is in the future or not */
 609   current_date = UP_get_current_date();
 610   if (strcmp(current_date, arg) < 0 )
 611   { /* arg is in the future */
 612     free(current_date);
 613     return UP_DATE_FUTURE;
 614   }
 615   free(current_date);
 616     
 617   return UP_DATE_OK;
 618 }
 619 
 620 
 621 
 622 /* Checks the syntax of the dates in the list */
 623 date_syntax_struct * up_check_dates_syntax(GList * list)
     /* [<][>][^][v][top][bottom][index][help] */
 624 {
 625   GList * item;
 626   date_syntax_struct * result;
 627   int res;
 628 
 629   /* initialize the result struct */
 630   result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
 631   result->result = UP_DATE_OK;
 632   result->error_str = NULL;
 633 
 634   /* if list is empty, return immediately */
 635   if (list == NULL)
 636   {
 637     return result;
 638   }
 639 
 640   /* loop through the members of the list, check each of them */
 641   for ( item = list; item != NULL ; item = g_list_next(item))
 642   {
 643     assert((item->data) != NULL);
 644     
 645     /* check the date */
 646     res = up_check_date((char *)(item->data));
 647     switch (res)
 648         {
 649       case UP_DATE_OK: break;
 650       
 651       case UP_DATE_FUTURE:
 652       case UP_DATE_TOOSMALL:
 653       case UP_DATE_INVDAY:
 654       case UP_DATE_INVMONTH:
 655       case UP_DATE_WRONGFORMAT:
 656 
 657              if (result->error_str == NULL)
 658                          {
 659                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res]) 
 660                                                   + strlen(": ") + strlen((char *)(item->data)) + 1);
 661                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
 662                        (char *)(item->data));
 663              }
 664                          else
 665                          {
 666                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1 
 667                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[res]) 
 668                                                    + strlen(": ") + strlen((char *)(item->data)) + 1);
 669                sprintf(result->error_str, "%s\n***Error: %s: %s",
 670                        result->error_str, up_date_errmsgs[res], (char *)(item->data));
 671              }
 672              result->result = UP_DATE_NOK; /* Not OK */
 673 
 674              break;
 675              
 676              
 677       case UP_DATE_SYNERR: /* syntax error in the date */
 678 
 679       default:
 680              if (result->error_str == NULL)
 681                          {
 682                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR]) 
 683                                                   + strlen(": ") + strlen((char *)(item->data)) + 1);
 684                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
 685                        (char *)(item->data));
 686              }
 687                          else
 688                          {
 689                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1 
 690                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR]) 
 691                                                    + strlen(": ") + strlen((char *)(item->data)) + 1);
 692                sprintf(result->error_str, "%s\n***Error: %s: %s",
 693                        result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)(item->data));
 694              }
 695              result->result = UP_DATE_NOK; /* Not OK */
 696              break;
 697     }
 698   }
 699   
 700   return result;
 701 }
 702 
 703 
 704 
 705 /* void up_check_changed_attr 
 706    checks the order of dates in the 'changed' attributes */
 707 void up_check_changed_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 708 {
 709   GList * date_list;
 710   int res;
 711   char ** warning, **error;
 712   char * temp;
 713   date_syntax_struct * date_check_res;
 714   GList *changed_list;
 715 
 716   warning = (char **)malloc(sizeof(char **));
 717   error   = (char **)malloc(sizeof(char **));
 718   changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
 719 
 720   /* Now, add dates to the "changed" attributes */
 721   res = up_add_dates(external_syntax_obj, changed_list, warning, error);
 722   if (!res)
 723   {
 724     /* so, add the error string to result's error string */
 725     if (result->error_str == NULL)
 726         {
 727       result->error_str = strdup(*error);
 728     }
 729         else
 730         {
 731       temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
 732       sprintf(temp, "%s\n%s", result->error_str, *error);
 733       free(result->error_str);
 734       result->error_str = temp;
 735     }
 736   }
 737 
 738   /* and get the list of dates, we must check their order */
 739   /* we may have added a date to one of the changed attrs so get the list again */
 740   rpsl_attr_delete_list(changed_list);
 741   changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
 742   date_list = up_get_dates(changed_list);
 743   /* and check the order */ 
 744   res = up_check_date_order(date_list);
 745   if (!res)
 746   {
 747     /* so, add the error string to result's error string */
 748     if (result->error_str == NULL)
 749         {
 750       result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
 751     }
 752         else
 753         {
 754       temp = (char *)malloc(strlen(result->error_str) 
 755               + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
 756       sprintf(temp, "%s\n%s", result->error_str, 
 757               "***Error: The dates in the 'changed' attributes should be in order");
 758       free(result->error_str);
 759       result->error_str = temp;
 760     }
 761     /* and here we have to change the result code of "result" here ... */
 762     switch (result->result)
 763         {
 764       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 765       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 766       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 767       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 768       default: ;
 769     }
 770   }
 771 
 772   /* check the syntax of dates */
 773   date_check_res = up_check_dates_syntax(date_list);
 774   if (date_check_res->result != UP_DATE_OK)
 775   {
 776     /* so, add the error string to result's error string */
 777     if (result->error_str == NULL)
 778         {
 779       result->error_str = strdup(date_check_res->error_str);
 780     }
 781         else
 782         {
 783       temp = (char *)malloc(strlen(result->error_str) 
 784               + strlen(date_check_res->error_str) + 2);
 785       sprintf(temp, "%s\n%s", result->error_str, 
 786               date_check_res->error_str);
 787       free(result->error_str);
 788       result->error_str = temp;
 789     }
 790     /* and here we have to change the result code of "result" here ... */
 791     switch (result->result)
 792         {
 793       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 794       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 795       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 796       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 797       default: ;
 798     }
 799   }
 800 }
 801 
 802 
 803 /* performs a simple check on a inetnum attribute. Assumes that
 804    the RPSL parser has already checked it. Tries to see if the attr
 805    is a range or not  */
 806 int up_check_an_inetnum_attr(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 807   
 808 
 809   char * str;
 810   char * pos;
 811 
 812   str = strdup(arg);
 813 
 814   while((pos = index(str, '\n')) != NULL){
 815     *pos = ' ';
 816   }
 817 
 818   /* strip off the comment */
 819   if((pos = index(str, '#')) != NULL){
 820     *pos = '\0';
 821   }
 822    
 823    
 824   /* Most of the syntax check is done by RPSL parser. We only need to check
 825      that the argument is a _range_ of IPv4 addresses. So it suffices to
 826      check the existence of '-' in the arg */
 827   if(index(str, '-') != NULL){
 828     
 829     free(str);
 830     return 1;
 831     
 832   }else{
 833 
 834     free(str);
 835     return 0;
 836 
 837   }
 838 }
 839 
 840 
 841 /* void up_add_keycert_attrs
 842    adds the generated attrs of key-cert objects */
 843 void up_add_keycert_attrs(rpsl_object_t *generated_obj)
     /* [<][>][^][v][top][bottom][index][help] */
 844 {
 845   const char *type;
 846   char *attr_str;
 847   rpsl_attr_t *method_attr;
 848   rpsl_attr_t *owner_attr;
 849   rpsl_attr_t *fingerpr_attr;
 850 
 851   if (tracing)
 852   {
 853     printf("TRACING: UP_add_keycert_attrs: is running\n");
 854   }
 855   
 856   /* if this is a key-cert object */
 857   type = rpsl_object_get_class(generated_obj);
 858   if ( strcmp(type, "key-cert") == 0 )
 859   {
 860       method_attr = rpsl_attr_init("method: PGP", type);
 861           if ( method_attr )
 862       {
 863         rpsl_object_add_attr(generated_obj, method_attr, 1, NULL);
 864           }
 865 
 866       attr_str = (char *)malloc( sizeof("owner: ") + strlen(keyowner) +1 );
 867           strcpy(attr_str, "owner: ");
 868           strcat(attr_str, keyowner);
 869       if (tracing)
 870       {
 871         printf("TRACING: UP_add_keycert_attrs: owner attr_str [%s]\n", attr_str);
 872       }
 873       owner_attr = rpsl_attr_init(attr_str, "key-cert");
 874           if ( owner_attr )
 875       {
 876         rpsl_object_add_attr(generated_obj, owner_attr, 2, NULL);
 877           }
 878       free(attr_str);
 879 
 880       attr_str = (char *)malloc( sizeof("fingerpr: ") + strlen(fingerprint) +1 );
 881           strcpy(attr_str, "fingerpr: ");
 882           strcat(attr_str, fingerprint);
 883       if (tracing)
 884       {
 885         printf("TRACING: UP_add_keycert_attrs: fingerprint attr_str [%s]\n", attr_str);
 886       }
 887       fingerpr_attr = rpsl_attr_init(attr_str, "key-cert");
 888           if ( fingerpr_attr )
 889       {
 890         rpsl_object_add_attr(generated_obj, fingerpr_attr, 3, NULL);
 891           }
 892       free(attr_str);
 893   }
 894 }
 895 
 896 
 897 /* up_reconstruct_object: Reconstructs the object's text representation
 898      using the parsed object */
 899 void up_reconstruct_object(rpsl_object_t *external_syntax_obj, external_syntax_struct *result)
     /* [<][>][^][v][top][bottom][index][help] */
 900 {
 901   char * recons_obj = NULL;
 902   
 903   recons_obj = rpsl_object_get_text(external_syntax_obj,RPSL_STD_COLUMN);
 904 
 905   result->new_obj = recons_obj;
 906 }
 907 
 908 
 909 
 910 /*  UP_check_external_syntax: Checks the syntax of attributes which are not checked
 911        by the api parser module. */
 912 external_syntax_struct * UP_check_external_syntax(rpsl_object_t *external_syntax_obj)
     /* [<][>][^][v][top][bottom][index][help] */
 913 {
 914   external_syntax_struct *result;
 915   
 916   if (tracing)
 917   {                                
 918         printf("TRACING: UP_check_external_syntax running\n");
 919   }
 920 
 921   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
 922 
 923   /* initialize the struct */
 924   result->result = 0;
 925   result->error_str = strdup(""); 
 926   result->warning_str = strdup("");
 927 
 928   up_check_source_attr(external_syntax_obj, result);
 929 
 930   up_check_country_attr(external_syntax_obj, result);
 931 
 932   up_check_nicsuffixes(external_syntax_obj, result);
 933 
 934   up_check_changed_attr(external_syntax_obj, result);
 935     
 936   up_reconstruct_object(external_syntax_obj, result);
 937 
 938   if (tracing)
 939   {
 940     printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
 941     printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
 942   }
 943 
 944   return result;  
 945 }
 946 
 947 
 948 
 949 /* generates the "generated" attributes of a key-cert object. Returns the 
 950    new object string*/
 951 char *UP_generate_kc_attrs(rpsl_object_t *generated_obj)
     /* [<][>][^][v][top][bottom][index][help] */
 952 {
 953   external_syntax_struct *result;
 954   char *obj_str;
 955 
 956   if (tracing)
 957   {
 958     printf("TRACING: UP_generate_kc_attrs: is running\n");
 959   }
 960 
 961   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
 962 
 963   /* initialize the struct */
 964   result->result = 0;
 965   result->error_str = strdup(""); 
 966   result->warning_str = strdup("");
 967 
 968   up_check_changed_attr(generated_obj, result);
 969   up_add_keycert_attrs(generated_obj); 
 970   
 971   up_reconstruct_object(generated_obj, result);
 972 
 973   if (tracing)
 974   {
 975     printf("TRACING: UP_generate_kc_attrs: the reconstructed object is=[%s]\n", result->new_obj);
 976     printf("TRACING: UP_generate_kc_attrs: ... and the result code is=[%i]\n", result->result);
 977   }
 978 
 979   obj_str = strdup(result->new_obj);
 980   free(result);
 981   return obj_str;  
 982 }
 983 
 984 
 985 
 986 /* char * up_assign_i6_status: Determines the status attribute of
 987     an inet6num object. It takes the inet6num attribute of the
 988     object as its only argument. If prefix length is less than
 989     4, then returns NULL */
 990 char * up_assign_i6_status(const char * inet6num_attr)
     /* [<][>][^][v][top][bottom][index][help] */
 991 {
 992 
 993   char ** split_str;
 994   int prefix_length;
 995   int result;
 996 
 997   /* we need the prefix length here.*/
 998   split_str = g_strsplit(inet6num_attr, "/", 0);
 999   if(split_str[1] != NULL){
1000 
1001     result = sscanf(split_str[1], "%i", &prefix_length);
1002     if(result != 0 && result != EOF){
1003 
1004       if(prefix_length >= 0 && prefix_length <= 3){
1005 
1006         g_strfreev(split_str); 
1007         return NULL;
1008         
1009       }else if(prefix_length >= 4 && prefix_length <= 15){
1010 
1011         g_strfreev(split_str); 
1012         return strdup("TLA");
1013         
1014       }else if(prefix_length >= 16 && prefix_length <= 35){
1015 
1016         g_strfreev(split_str); 
1017         return strdup("SUBTLA");
1018         
1019       }else if(prefix_length >= 36 && prefix_length <= 48){
1020 
1021         g_strfreev(split_str); 
1022         return strdup("NLA");
1023    
1024       }else if(prefix_length >= 48 && prefix_length <= 64){
1025 
1026         g_strfreev(split_str); 
1027         return strdup("SLA");
1028         
1029       }else{
1030 
1031         /* "default" status */
1032         g_strfreev(split_str); 
1033         return strdup("SLA");
1034         
1035       }
1036       
1037     }else{
1038       
1039       /* return "default" status */
1040       g_strfreev(split_str);
1041       return strdup("SLA");
1042       
1043     }
1044   }else{
1045     
1046     /* return "default" status */
1047     g_strfreev(split_str);
1048     return strdup("SLA");
1049 
1050   }
1051   
1052 }
1053 
1054 
1055 
1056 /* GSList * up_add_inet6num_attrs
1057    adds the generated attrs of inet6num objects */
1058 /*GSList * up_add_inet6num_attrs(Object * obj, char * obj_text, GSList * attribute_list, 
1059                                external_syntax_struct * result)*/
1060 void up_add_inet6num_attrs(rpsl_object_t *generated_obj)                               
     /* [<][>][^][v][top][bottom][index][help] */
1061 {
1062 
1063   int attribute_no;
1064   char *status_value;
1065   rpsl_attr_t * status_attr;
1066   char *inet6num_attr_str, *status_attr_str;
1067   const char *type;
1068   GList *attributes_changed;
1069   
1070 
1071 
1072   /* if this is an inet6num  object */
1073   type = rpsl_object_get_class(generated_obj);
1074   if( ! strcmp(type, "inet6num") )
1075   {
1076       inet6num_attr_str = get_search_key(generated_obj, "inet6num");
1077       status_value = up_assign_i6_status(inet6num_attr_str);
1078       status_attr_str = (char *)UT_malloc(strlen("status: ") + strlen(status_value) + 1);
1079       strcpy(status_attr_str, "status: ");
1080       strcat(status_attr_str, status_value);
1081       status_attr = rpsl_attr_init(status_attr_str, type);
1082           free(status_attr_str);
1083           if ( status_attr )
1084       {
1085         /* we will put the status attribute before the first 'changed' attribute */
1086         attribute_no = 1; /* a default position (the second attribute) in case we cannot find
1087                                  a 'changed' attribute */    
1088         attributes_changed = rpsl_object_get_attr(generated_obj, "changed");    
1089         if ( attributes_changed != NULL )
1090                 {
1091           attribute_no = ((rpsl_attr_t *)(attributes_changed->data))->num;
1092         }
1093         rpsl_object_add_attr(generated_obj, status_attr, attribute_no, NULL);
1094       }
1095   }
1096 }
1097 

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