modules/up/UP_extrnl_syntax.c

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

FUNCTIONS

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_check_a_status_attr
  14. up_check_status_attr
  15. up_add_keycert_attrs
  16. up_reconstruct_object
  17. UP_check_external_syntax
  18. UP_generate_kc_attrs
  19. up_assign_i6_status
  20. up_add_inet6num_attrs
  21. UP_generate_i6_attrs

   1 /***************************************
   2   $Revision: 1.12 $
   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 char * allocmnt;
  69 
  70 extern char    *sources[];
  71 extern char    *countries[];
  72 extern char    *nicsuffixes[];
  73 
  74 
  75 /* void up_check_source_attr 
  76    checks for a valid source in the 'source' attributes */
  77 void up_check_source_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
  78 {
  79   int valid,i ;
  80   char *source_name;
  81   char *temp;
  82   GList *source_list;
  83  
  84   source_list = rpsl_object_get_attr(external_syntax_obj, "source");
  85 
  86   valid = i = 0 ;
  87   if ( source_list )
  88   {
  89     source_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(source_list->data) );
  90     while(sources[i])
  91     {
  92       if(strcasecmp(sources[i++],source_name) == 0)
  93       {
  94         valid = 1;
  95         break;
  96       }
  97     }
  98     free(source_name);
  99     g_list_free(source_list);
 100   }
 101 
 102   if (!valid)
 103   {
 104     /* the source is not recognised */
 105     if (result->error_str == NULL)
 106         {
 107       result->error_str = strdup("***Error: No such source");
 108     }
 109         else
 110         {
 111       temp = (char *)malloc(strlen(result->error_str) 
 112               + strlen("***Error: No such source") + 2);
 113       sprintf(temp, "%s\n%s", result->error_str, 
 114               "***Error: No such source");
 115       free(result->error_str);
 116       result->error_str = temp;
 117     }
 118     /* and here we have to change the result code of "result" here ... */
 119     switch (result->result)
 120         {
 121       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 122       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 123       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 124       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 125       default: ;
 126     }
 127   }
 128 }
 129 
 130 
 131 /* void up_check_country_attr 
 132    checks for a valid country in the 'country' attributes */
 133 void up_check_country_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 134 {
 135   int valid,i, matched ;
 136   char *country_name;
 137   char *temp;
 138   GList *country_list = NULL;
 139   GList *country_item = NULL;
 140  
 141   country_list = rpsl_object_get_attr(external_syntax_obj, "country");
 142   
 143   if ( country_list == NULL )
 144     return;             /* only check if there is one */
 145 
 146   valid = 1 ;
 147   for ( country_item = country_list; country_item != NULL ; country_item = g_list_next(country_item) )
 148   {
 149     country_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(country_item->data) );
 150     matched = 0 ;
 151     i = 0 ;
 152     while(countries[i])
 153     {
 154       if(strcasecmp(countries[i++],country_name) == 0)
 155       {
 156         matched = 1;
 157         break;
 158       }
 159     }
 160 
 161     if ( ! matched )
 162     {
 163       valid = 0 ;
 164       break;
 165     }
 166     free(country_name);
 167   }
 168   g_list_free(country_list);
 169 
 170   if (!valid)
 171   {
 172     /* the country is not recognised */
 173     if (result->error_str == NULL)
 174         {
 175       result->error_str = malloc(strlen("***Error: No such country []") + strlen(country_name) +2);
 176       sprintf(result->error_str, "***Error: No such country [%s]", country_name);
 177     }
 178         else
 179         {
 180       temp = (char *)malloc(strlen(result->error_str) 
 181               + strlen("***Error: No such country []") + strlen(country_name) + 2);
 182       sprintf(temp, "%s\n***Error: No such country [%s]", result->error_str, 
 183               country_name);
 184       free(result->error_str);
 185       result->error_str = temp;
 186     }
 187 
 188     free(country_name);
 189 
 190     /* and here we have to change the result code of "result" here ... */
 191     switch (result->result)
 192         {
 193       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 194       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 195       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 196       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 197       default: ;
 198     }
 199   }
 200 }
 201 
 202 /* void up_check_nicsuffixes 
 203    checks for a valid suffix at the end of a 'nic-hdl' attributes */
 204 void up_check_nicsuffixes(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 205 {
 206   int valid,i ;
 207   char *name;
 208   char *temp;
 209   GList *list;
 210  
 211   list = rpsl_object_get_attr(external_syntax_obj, "nic-hdl");
 212 
 213   valid = i = 0 ;
 214   if ( list )
 215   {
 216     name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(list->data) );
 217     if ( !strchr(name,'-') || strncasecmp(name,"AUTO-",strlen("AUTO-")) == 0 )
 218     {
 219       valid = 1;
 220     }
 221     else
 222     {
 223       while (nicsuffixes[i])
 224       {
 225         if ( strcasecmp(nicsuffixes[i++],strchr(name,'-')+1) == 0 )
 226         {
 227           valid = 1;
 228           break;
 229         }
 230       }
 231       if ( ! valid )
 232       {
 233         i = 0;
 234         while (sources[i])
 235         {
 236           if (strcasecmp(sources[i++],strchr(name,'-')+1) == 0 )
 237           {
 238             valid = 1;
 239             break;
 240           }
 241         }
 242         if ( ! valid )
 243         {
 244           i = 0;
 245           while (countries[i])
 246           {
 247             if ( strcasecmp(countries[i++],strchr(name,'-')+1) == 0 )
 248             {
 249               valid = 1;
 250               break;
 251             }
 252           }
 253         }
 254       }
 255     }
 256     free(name);
 257     g_list_free(list);
 258 
 259     if (!valid)
 260     {
 261       /* the nicsuffix is not recognised */
 262       if (result->error_str == NULL)
 263           {
 264         result->error_str = strdup("***Error: Invalid nic-hdl suffix");
 265       }
 266           else
 267           {
 268         temp = (char *)malloc(strlen(result->error_str) 
 269                 + strlen("***Error: Invalid nic-hdl suffix") + 2);
 270         sprintf(temp, "%s\n%s", result->error_str, 
 271                 "***Error: Invalid nic-hdl suffix");
 272         free(result->error_str);
 273         result->error_str = temp;
 274       }
 275       /* and here we have to change the result code of "result" here ... */
 276       switch (result->result)
 277           {
 278         case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 279         case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 280         case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 281         case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 282         default: ;
 283       }
 284     }
 285   }
 286 }
 287 
 288 
 289 /* obtains a list of dates in the given 
 290    list of attributes  */
 291 GList * up_get_dates(GList * attribute_list)
     /* [<][>][^][v][top][bottom][index][help] */
 292 {
 293   GList * item;
 294   char * str, *temp; 
 295   GList * list = NULL;
 296 
 297   for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
 298   {
 299     /* is this a 'changed' attribute? */
 300     if ( strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0 )
 301         {
 302       str = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 303 
 304 
 305       /* now, we have the 'changed' attribute's content in "normalized" form 
 306          We are sure it contains a date. So, it must be the second (and last)
 307          word in the attrib. */
 308       assert(index(str,' ') != NULL);
 309       temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
 310       temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
 311       temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
 312       list = g_list_append (list, temp);   
 313     }
 314   }
 315   
 316   return list;
 317 }
 318 
 319 
 320 
 321 
 322 /* Does the 'changed' attribute we got have a date already?
 323    Returns 1 if it does, 0 if not. */
 324 int up_changed_has_date(char * value)
     /* [<][>][^][v][top][bottom][index][help] */
 325 {
 326   /* now, if there is still a white space, then we have a date in the string
 327      (it has to be something like "ripe-dbm@ripe.net 20001210") */
 328   if (index(value, ' ') != NULL)
 329   {
 330     return 1; 
 331   }
 332   else
 333   {
 334     return 0;
 335   }
 336 }
 337 
 338 
 339 
 340 
 341 /* supplies the current date in YYYYMMDD format (for example 20011010) */
 342 char * UP_get_current_date()
     /* [<][>][^][v][top][bottom][index][help] */
 343 {
 344   /* We will use Glib's functions here */
 345 
 346   char * date;
 347   struct tm * time_struct;
 348   
 349   time_t * time_loc;
 350 
 351   time_loc = (time_t *)malloc(sizeof(time_t));
 352   time(time_loc);
 353   
 354   time_struct = localtime(time_loc);
 355 
 356 
 357   date = (char *)malloc(9);
 358   sprintf(date, "%04i%02i%02i", 
 359           time_struct->tm_year + 1900, 
 360           time_struct->tm_mon + 1,
 361           time_struct->tm_mday);
 362   return date;
 363 }
 364 
 365 
 366 
 367 
 368 /* int up_add_dates: adds dates to 'changed' attributes which 
 369      are missing one.
 370      Returns 1 if no problems encountered
 371      Returns 0 if a problem encountered, and the error string is set */
 372 int up_add_dates(rpsl_object_t *external_syntax_obj, GList *attribute_list, char ** warning_str, char ** error_str)
     /* [<][>][^][v][top][bottom][index][help] */
 373 {
 374   GList * item;
 375   char * current_date;
 376   int count_no_date = 0; 
 377   char * temp;
 378   rpsl_attr_t *changed;
 379   char *value;
 380   int pos;
 381   
 382   *warning_str = NULL;
 383   *error_str   = NULL;
 384 
 385   /* get the current date in YYYYMMDD format (for example 20011010) */
 386   current_date = UP_get_current_date();
 387   
 388   for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
 389   {
 390     /* is this a 'changed' attribute? */
 391     if (strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0)
 392         {
 393       /* if this attribute does not have a date in it, add it. Also add 
 394           a warning message about this */
 395           value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 396       if ( !up_changed_has_date(value) )
 397           {
 398         count_no_date++;
 399                 /* create a copy of this changed attribute and add the date to the value */
 400                 changed = rpsl_attr_copy((rpsl_attr_t *)(item->data));
 401         temp = (char *)malloc(strlen(value) + strlen(current_date) + 2 );
 402         sprintf(temp, "%s %s", value, current_date);
 403         rpsl_attr_replace_value(changed, temp);
 404         free(temp);
 405                 /* delete the original attribute from the object */
 406                 pos = rpsl_attr_get_ofs(changed);
 407                 rpsl_object_remove_attr(external_syntax_obj, pos, NULL);
 408                 /* add the new changed attribute in the same position */
 409                 rpsl_object_add_attr(external_syntax_obj, changed, pos, NULL);
 410         /* add a warning message */
 411         if ( *warning_str == NULL)
 412                 {
 413           *warning_str = (char *)malloc(strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 414           sprintf(*warning_str, "WARNING  date '%s' added to 'changed' attribute", current_date);
 415         }
 416                 else
 417                 {
 418           temp = (char *)malloc(strlen(*warning_str) + 1 
 419                                        + strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 420           sprintf(temp, "%s\nWARNING  date '%s' added to 'changed' attribute", 
 421                               *warning_str, current_date);
 422           free(*warning_str);
 423           *warning_str = temp; 
 424         }
 425       }
 426           free(value);
 427     }
 428   }
 429   
 430   if (count_no_date > 1)
 431   { 
 432     *error_str = strdup("***Error: More than one 'changed' attributes without dates");
 433     return 0;
 434   }
 435   else
 436   {
 437     return 1;
 438   }
 439 }
 440 
 441 
 442 
 443 
 444 /* Checks the order of dates in the given list. 
 445    If they are in order, returns 1, 
 446    if not, returns 0 */
 447 int up_check_date_order(GList * list)
     /* [<][>][^][v][top][bottom][index][help] */
 448 {
 449   GList * item;
 450   char * previous;
 451   char *value;
 452 
 453   /* if list is empty, return 1 immediately */
 454   if (list == NULL)
 455   {
 456     return 1;
 457   }
 458 
 459   /* initialize the 'previous' date */
 460   previous = strdup("00000000");
 461    
 462   for ( item = list; item != NULL ; item = g_list_next(item))
 463   {
 464     assert((item->data) != NULL);
 465     /* if the new date is smaller than the previous */
 466         value = (char *)(item->data);
 467     if ( strcmp(value, previous) < 0 )
 468         {
 469       free(previous);
 470       return 0;
 471     }
 472     free(previous);
 473     previous = strdup(value);
 474   }
 475    
 476   free(previous);
 477   /* Reached the end, without finding out-of-order date. Return 1, then */
 478   return 1; 
 479 }
 480 
 481 
 482 
 483 
 484 
 485 /* up_check_date: checks the syntax of the date, given as the only
 486    argument (char *). The argument is checked if it is in YYYYMMDD
 487    format, and returns an error code accordingly */
 488 int up_check_date(const char * arg)
     /* [<][>][^][v][top][bottom][index][help] */
 489 {
 490   int date_int; /* integer representation of the date (arg) */
 491   char * current_date;
 492   int year, month, day; /* integers for the components of the date */
 493 
 494   errno = 0;
 495   date_int = atoi(arg);
 496       
 497   if (errno != 0)
 498   { /* there was an error in the conversion, syntax error */
 499     return UP_DATE_SYNERR;
 500   }
 501     
 502   /* wrong format */
 503   if (date_int <= 10000000 )
 504   { /* the date is not in YYYYMMDD format */
 505     return UP_DATE_WRONGFORMAT;
 506   }
 507 
 508   /* check if it is too small */  
 509   if (date_int <= 19880000 )
 510   { /* the date is older than the DB itself! */
 511     return UP_DATE_TOOSMALL;
 512   }
 513 
 514   /* check if it is too big */
 515   if (date_int >= 100000000 )
 516   {/* too big: syntax error */
 517     return UP_DATE_SYNERR;
 518   }
 519 
 520   /* and now check year, month and day components */
 521   year = date_int / 10000;
 522   month = (date_int - (year * 10000) ) / 100;
 523   day = (date_int % 100);
 524   
 525   /* check year */
 526   if (year < 1988 )
 527   {
 528     return UP_DATE_TOOSMALL;
 529   }
 530 
 531   /* check month */
 532   if (month < 1 || month > 12)
 533   {
 534     return UP_DATE_INVMONTH;
 535   }
 536 
 537   /* check day */
 538   if (day < 1 || day > 31)
 539   {
 540     return UP_DATE_INVDAY;
 541   }
 542 
 543   switch ( month )
 544   {
 545     case 1: case 3: case 5: case 7:
 546     case 8: case 10: case 12:
 547          if (day > 31)
 548                  {
 549            return UP_DATE_INVDAY;
 550          };
 551          break;
 552     case 2: 
 553          if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 ))
 554                  { /* leap year */
 555            return UP_DATE_INVDAY;
 556          }
 557                  else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) )
 558                  { /* non-leap year */
 559            return UP_DATE_INVDAY;
 560          };
 561          break;
 562     case 4: case 6: case 9: case 11:
 563          if (day > 30)
 564                  {
 565            return UP_DATE_INVDAY;
 566          };
 567          break;
 568     default: return UP_DATE_INVMONTH;
 569   }
 570 
 571   /* check if the arg is in the future or not */
 572   current_date = UP_get_current_date();
 573   if (strcmp(current_date, arg) < 0 )
 574   { /* arg is in the future */
 575     free(current_date);
 576     return UP_DATE_FUTURE;
 577   }
 578   free(current_date);
 579     
 580   return UP_DATE_OK;
 581 }
 582 
 583 
 584 
 585 /* Checks the syntax of the dates in the list */
 586 date_syntax_struct * up_check_dates_syntax(GList * list)
     /* [<][>][^][v][top][bottom][index][help] */
 587 {
 588   GList * item;
 589   date_syntax_struct * result;
 590   int res;
 591 
 592   /* initialize the result struct */
 593   result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
 594   result->result = UP_DATE_OK;
 595   result->error_str = NULL;
 596 
 597   /* if list is empty, return immediately */
 598   if (list == NULL)
 599   {
 600     return result;
 601   }
 602 
 603   /* loop through the members of the list, check each of them */
 604   for ( item = list; item != NULL ; item = g_list_next(item))
 605   {
 606     assert((item->data) != NULL);
 607     
 608     /* check the date */
 609     res = up_check_date((char *)(item->data));
 610     switch (res)
 611         {
 612       case UP_DATE_OK: break;
 613       
 614       case UP_DATE_FUTURE:
 615       case UP_DATE_TOOSMALL:
 616       case UP_DATE_INVDAY:
 617       case UP_DATE_INVMONTH:
 618       case UP_DATE_WRONGFORMAT:
 619 
 620              if (result->error_str == NULL)
 621                          {
 622                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res]) 
 623                                                   + strlen(": ") + strlen((char *)(item->data)) + 1);
 624                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
 625                        (char *)(item->data));
 626              }
 627                          else
 628                          {
 629                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1 
 630                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[res]) 
 631                                                    + strlen(": ") + strlen((char *)(item->data)) + 1);
 632                sprintf(result->error_str, "%s\n***Error: %s: %s",
 633                        result->error_str, up_date_errmsgs[res], (char *)(item->data));
 634              }
 635              result->result = UP_DATE_NOK; /* Not OK */
 636 
 637              break;
 638              
 639              
 640       case UP_DATE_SYNERR: /* syntax error in the date */
 641 
 642       default:
 643              if (result->error_str == NULL)
 644                          {
 645                result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR]) 
 646                                                   + strlen(": ") + strlen((char *)(item->data)) + 1);
 647                sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
 648                        (char *)(item->data));
 649              }
 650                          else
 651                          {
 652                result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1 
 653                                                    + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR]) 
 654                                                    + strlen(": ") + strlen((char *)(item->data)) + 1);
 655                sprintf(result->error_str, "%s\n***Error: %s: %s",
 656                        result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)(item->data));
 657              }
 658              result->result = UP_DATE_NOK; /* Not OK */
 659              break;
 660     }
 661   }
 662   
 663   return result;
 664 }
 665 
 666 
 667 
 668 /* void up_check_changed_attr 
 669    checks the order of dates in the 'changed' attributes */
 670 void up_check_changed_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 671 {
 672   GList * date_list;
 673   int res;
 674   char ** warning, **error;
 675   char * temp;
 676   date_syntax_struct * date_check_res;
 677   GList *changed_list;
 678 
 679   warning = (char **)malloc(sizeof(char **));
 680   error   = (char **)malloc(sizeof(char **));
 681   changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
 682 
 683   /* Now, add dates to the "changed" attributes */
 684   res = up_add_dates(external_syntax_obj, changed_list, warning, error);
 685   if (!res)
 686   {
 687     /* so, add the error string to result's error string */
 688     if (result->error_str == NULL)
 689         {
 690       result->error_str = strdup(*error);
 691     }
 692         else
 693         {
 694       temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
 695       sprintf(temp, "%s\n%s", result->error_str, *error);
 696       free(result->error_str);
 697       result->error_str = temp;
 698     }
 699   }
 700 
 701   /* and get the list of dates, we must check their order */
 702   /* we may have added a date to one of the changed attrs so get the list again */
 703   rpsl_attr_delete_list(changed_list);
 704   changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
 705   date_list = up_get_dates(changed_list);
 706   /* and check the order */ 
 707   res = up_check_date_order(date_list);
 708   if (!res)
 709   {
 710     /* so, add the error string to result's error string */
 711     if (result->error_str == NULL)
 712         {
 713       result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
 714     }
 715         else
 716         {
 717       temp = (char *)malloc(strlen(result->error_str) 
 718               + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
 719       sprintf(temp, "%s\n%s", result->error_str, 
 720               "***Error: The dates in the 'changed' attributes should be in order");
 721       free(result->error_str);
 722       result->error_str = temp;
 723     }
 724     /* and here we have to change the result code of "result" here ... */
 725     switch (result->result)
 726         {
 727       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 728       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 729       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 730       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 731       default: ;
 732     }
 733   }
 734 
 735   /* check the syntax of dates */
 736   date_check_res = up_check_dates_syntax(date_list);
 737   if (date_check_res->result != UP_DATE_OK)
 738   {
 739     /* so, add the error string to result's error string */
 740     if (result->error_str == NULL)
 741         {
 742       result->error_str = strdup(date_check_res->error_str);
 743     }
 744         else
 745         {
 746       temp = (char *)malloc(strlen(result->error_str) 
 747               + strlen(date_check_res->error_str) + 2);
 748       sprintf(temp, "%s\n%s", result->error_str, 
 749               date_check_res->error_str);
 750       free(result->error_str);
 751       result->error_str = temp;
 752     }
 753     /* and here we have to change the result code of "result" here ... */
 754     switch (result->result)
 755         {
 756       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 757       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 758       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 759       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 760       default: ;
 761     }
 762   }
 763 }
 764 
 765 
 766 /* performs a simple check on a inetnum attribute. Assumes that
 767    the RPSL parser has already checked it. Tries to see if the attr
 768    is a range or not  */
 769 int up_check_an_inetnum_attr(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 770   
 771 
 772   char * str;
 773   char * pos;
 774 
 775   str = strdup(arg);
 776 
 777   while((pos = index(str, '\n')) != NULL){
 778     *pos = ' ';
 779   }
 780 
 781   /* strip off the comment */
 782   if((pos = index(str, '#')) != NULL){
 783     *pos = '\0';
 784   }
 785    
 786    
 787   /* Most of the syntax check is done by RPSL parser. We only need to check
 788      that the argument is a _range_ of IPv4 addresses. So it suffices to
 789      check the existence of '-' in the arg */
 790   if(index(str, '-') != NULL){
 791     
 792     free(str);
 793     return 1;
 794     
 795   }else{
 796 
 797     free(str);
 798     return 0;
 799 
 800   }
 801 }
 802 
 803 
 804 
 805 /* Performs a check on status attribute. It can be
 806    ALLOCATED PI or ALLOCATED PA only if the maintainers in the
 807    mnt-by attribute contain at least one of the names mentioned in
 808    ALLOCMNT config variable. 
 809 */
 810 int up_check_a_status_attr(const char * arg, GList * mnt_by_list)
     /* [<][>][^][v][top][bottom][index][help] */
 811 {
 812   GList * item;
 813   int result;
 814   char * status, * mnt_by_attrib;
 815   char ** allocmnt_list;
 816   int i;
 817 
 818   status = strdup(arg);
 819   g_strdown(status);
 820  
 821   /* construct a list of mntners that are in allocmnt */
 822   allocmnt_list = g_strsplit(allocmnt, " ", 0); /* delimited by " " */
 823    
 824   if (strstr(status, "allocated") != NULL)
 825   { 
 826     result = 1; /* initialize */
 827     
 828     for ( item = mnt_by_list; item != NULL ; item = g_list_next(item) )
 829         {
 830       mnt_by_attrib = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 831       for (i=0; allocmnt_list[i] != NULL; i++)
 832           { /* loop thru the list of allocmnt maintainers */
 833         if ((strlen(allocmnt_list[i]) != 0) && strcasecmp(mnt_by_attrib, allocmnt_list[i]) == 0)
 834                 {
 835           result = 0; 
 836         }
 837       }  
 838       free(mnt_by_attrib);
 839     }
 840     
 841     free(status);
 842     g_strfreev(allocmnt_list);
 843     return result;
 844  
 845   }
 846   else
 847   {  /* the status attribute is not allocated */
 848     free(status);
 849     g_strfreev(allocmnt_list);
 850     return 0; /* so there is no problem */
 851 
 852   }
 853 
 854 }
 855 
 856 
 857 
 858 
 859 
 860 /* check for status attribute here: The status attribute can be
 861    ALLOCATED PI or ALLOCATED PA only if the maintainers in the
 862    mnt-by attribute contain at least one of the names mentioned in
 863    ALLOCMNT config variable. 
 864 */
 865 void up_check_status_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
     /* [<][>][^][v][top][bottom][index][help] */
 866 {
 867   int res;
 868   char * temp;
 869   char *value;
 870   GList * item;
 871   GList * mnt_by_list = NULL;
 872   GList *status_list = NULL;
 873 
 874   /* Gather a list of mnt-by attributes */
 875   mnt_by_list = rpsl_object_get_attr(external_syntax_obj, "mnt-by");
 876   status_list = rpsl_object_get_attr(external_syntax_obj, "status");
 877 
 878   /* check the syntax */
 879   for ( item = status_list; item != NULL ; item = g_list_next(item) )
 880   {
 881       value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
 882       res = up_check_a_status_attr(value, mnt_by_list);
 883       if (res != 0)
 884           { /* there was a problem */
 885         /* so, add the error string to result's error string */
 886         if (result->error_str == NULL)
 887                 {
 888           result->error_str = (char *)UT_malloc(strlen("***Error: Status ALLOCATED can be set only by the following mntner(s):\n")
 889                                                 +strlen("***Error:    ") + strlen(allocmnt) + 2);
 890           sprintf(result->error_str, "%s%s%s", "***Error: Status ALLOCATED can be set only by the following mntner(s):\n",
 891                                                "***Error:    ", allocmnt);
 892         }
 893                 else
 894                 {
 895           temp = (char *)malloc(strlen(result->error_str) 
 896                   + strlen("***Error: Status ALLOCATED can be set only by the following mntner(s):\n") 
 897                   + strlen("***Error:    ") + strlen(allocmnt) + 2);
 898           sprintf(temp, "%s\n%s%s%s", result->error_str, 
 899                   "***Error: Status ALLOCATED can be set only by the following mntner(s):\n",
 900                   "***Error:    ", allocmnt);
 901           free(result->error_str);
 902           result->error_str = temp;
 903         }
 904         /* and here we have to change the result code of "result" here ... */
 905         switch (result->result)
 906                 {
 907           case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 908           case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 909           case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 910           case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 911           default: ;
 912         }
 913       }
 914           free(value);
 915   }
 916   rpsl_attr_delete_list(mnt_by_list);
 917   rpsl_attr_delete_list(status_list);
 918 }
 919 
 920 
 921 
 922 
 923 /* void up_add_keycert_attrs
 924    adds the generated attrs of key-cert objects */
 925 void up_add_keycert_attrs(rpsl_object_t *generated_obj)
     /* [<][>][^][v][top][bottom][index][help] */
 926 {
 927   const char *type;
 928   char *attr_str;
 929   rpsl_attr_t *method_attr;
 930   rpsl_attr_t *owner_attr;
 931   rpsl_attr_t *fingerpr_attr;
 932 
 933   if (tracing)
 934   {
 935     printf("TRACING: UP_add_keycert_attrs: is running\n");
 936   }
 937   
 938   /* if this is a key-cert object */
 939   type = rpsl_object_get_class(generated_obj);
 940   if ( strcmp(type, "key-cert") == 0 )
 941   {
 942       method_attr = rpsl_attr_init("method: PGP", type);
 943           if ( method_attr )
 944       {
 945         rpsl_object_add_attr(generated_obj, method_attr, 1, NULL);
 946           }
 947 
 948       attr_str = (char *)malloc( sizeof("owner: ") + strlen(keyowner) +1 );
 949           strcpy(attr_str, "owner: ");
 950           strcat(attr_str, keyowner);
 951       if (tracing)
 952       {
 953         printf("TRACING: UP_add_keycert_attrs: owner attr_str [%s]\n", attr_str);
 954       }
 955       owner_attr = rpsl_attr_init(attr_str, "key-cert");
 956           if ( owner_attr )
 957       {
 958         rpsl_object_add_attr(generated_obj, owner_attr, 2, NULL);
 959           }
 960       free(attr_str);
 961 
 962       attr_str = (char *)malloc( sizeof("fingerpr: ") + strlen(fingerprint) +1 );
 963           strcpy(attr_str, "fingerpr: ");
 964           strcat(attr_str, fingerprint);
 965       if (tracing)
 966       {
 967         printf("TRACING: UP_add_keycert_attrs: fingerprint attr_str [%s]\n", attr_str);
 968       }
 969       fingerpr_attr = rpsl_attr_init(attr_str, "key-cert");
 970           if ( fingerpr_attr )
 971       {
 972         rpsl_object_add_attr(generated_obj, fingerpr_attr, 3, NULL);
 973           }
 974       free(attr_str);
 975   }
 976 }
 977 
 978 
 979 
 980 /* Constructs a list of all attributes of an object, and returns it
 981    as a list of attribute_struct */
 982 /*GSList * up_get_attribute_list(Object * o, char * text){
 983 
 984   char * value = NULL;
 985   char * type = NULL;
 986   Attr *attr;
 987   GSList *list_of_attributes = NULL;
 988   attribute_struct * attribute;
 989   
 990   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 991     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 992     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 993         attr->len - strlen(attr->type->name()) -2 );
 994     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 995       if(tracing) {
 996         cout << "TRACING: up_get_attributes: adding " << g_strstrip(value) << endl;
 997       }
 998       attribute = (attribute_struct *)malloc(sizeof(attribute_struct)); 
 999       attribute->content = value;
1000       type = strdup(attr->type->name());
1001       g_strdown(type);
1002       attribute->type = type;
1003       list_of_attributes = g_slist_append(list_of_attributes, attribute);
1004   }
1005 
1006   
1007   return list_of_attributes; 
1008 
1009 }
1010 */
1011 
1012 
1013 /* up_reconstruct_object: Reconstructs the object's text representation
1014      using the parsed object */
1015 void up_reconstruct_object(rpsl_object_t *external_syntax_obj, external_syntax_struct *result)
     /* [<][>][^][v][top][bottom][index][help] */
1016 {
1017   char * recons_obj = NULL;
1018   
1019   recons_obj = rpsl_object_get_text(external_syntax_obj,RPSL_STD_COLUMN);
1020 
1021   result->new_obj = recons_obj;
1022 }
1023 
1024 
1025 
1026 /*  UP_check_external_syntax: Checks the syntax of attributes which are not checked
1027        by RAToolSet syntax checker. */
1028 external_syntax_struct * UP_check_external_syntax(rpsl_object_t *external_syntax_obj)
     /* [<][>][^][v][top][bottom][index][help] */
1029 {
1030   external_syntax_struct *result;
1031   
1032   if (tracing)
1033   {                                
1034         printf("TRACING: UP_check_external_syntax running\n");
1035   }
1036 
1037   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1038 
1039   /* initialize the struct */
1040   result->result = 0;
1041   result->error_str = strdup(""); 
1042   result->warning_str = strdup("");
1043 
1044   up_check_source_attr(external_syntax_obj, result);
1045 
1046   up_check_country_attr(external_syntax_obj, result);
1047 
1048   up_check_nicsuffixes(external_syntax_obj, result);
1049 
1050   up_check_changed_attr(external_syntax_obj, result);
1051 
1052 /* this will be done by the new API parser */
1053 /*  up_check_auth_attr   (arg, obj_text, attribute_list, result);  */ 
1054 
1055 /* this will be done by the new API parser */
1056 /*  up_check_inetnum_attr(arg, obj_text, attribute_list, result); */
1057 
1058   up_check_status_attr(external_syntax_obj, result);
1059   
1060   
1061   up_reconstruct_object(external_syntax_obj, result);
1062 
1063   if (tracing)
1064   {
1065     printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
1066     printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
1067   }
1068 
1069   return result;  
1070 }
1071 
1072 
1073 
1074 /* generates the "generated" attributes of a key-cert object. Returns the 
1075    new object string*/
1076 char *UP_generate_kc_attrs(rpsl_object_t *generated_obj)
     /* [<][>][^][v][top][bottom][index][help] */
1077 {
1078   external_syntax_struct *result;
1079   char *obj_str;
1080 
1081   if (tracing)
1082   {
1083     printf("TRACING: UP_generate_kc_attrs: is running\n");
1084   }
1085 
1086   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1087 
1088   /* initialize the struct */
1089   result->result = 0;
1090   result->error_str = strdup(""); 
1091   result->warning_str = strdup("");
1092 
1093   up_check_changed_attr(generated_obj, result);
1094   up_add_keycert_attrs(generated_obj); 
1095   
1096   up_reconstruct_object(generated_obj, result);
1097 
1098   if (tracing)
1099   {
1100     printf("TRACING: UP_generate_kc_attrs: the reconstructed object is=[%s]\n", result->new_obj);
1101     printf("TRACING: UP_generate_kc_attrs: ... and the result code is=[%i]\n", result->result);
1102   }
1103 
1104   obj_str = strdup(result->new_obj);
1105   free(result);
1106   return obj_str;  
1107 }
1108 
1109 
1110 
1111 /* char * up_assign_i6_status: Determines the status attribute of
1112     an inet6num object. It takes the inet6num attribute of the
1113     object as its only argument. If prefix length is less than
1114     4, then returns NULL */
1115 char * up_assign_i6_status(const char * inet6num_attr)
     /* [<][>][^][v][top][bottom][index][help] */
1116 {
1117 
1118   char ** split_str;
1119   int prefix_length;
1120   int result;
1121 
1122   /* we need the prefix length here.*/
1123   split_str = g_strsplit(inet6num_attr, "/", 0);
1124   if(split_str[1] != NULL){
1125 
1126     result = sscanf(split_str[1], "%i", &prefix_length);
1127     if(result != 0 && result != EOF){
1128 
1129       if(prefix_length >= 0 && prefix_length <= 3){
1130 
1131         g_strfreev(split_str); 
1132         return NULL;
1133         
1134       }else if(prefix_length >= 4 && prefix_length <= 15){
1135 
1136         g_strfreev(split_str); 
1137         return strdup("TLA");
1138         
1139       }else if(prefix_length >= 16 && prefix_length <= 35){
1140 
1141         g_strfreev(split_str); 
1142         return strdup("SUBTLA");
1143         
1144       }else if(prefix_length >= 36 && prefix_length <= 48){
1145 
1146         g_strfreev(split_str); 
1147         return strdup("NLA");
1148    
1149       }else if(prefix_length >= 48 && prefix_length <= 64){
1150 
1151         g_strfreev(split_str); 
1152         return strdup("SLA");
1153         
1154       }else{
1155 
1156         /* "default" status */
1157         g_strfreev(split_str); 
1158         return strdup("SLA");
1159         
1160       }
1161       
1162     }else{
1163       
1164       /* return "default" status */
1165       g_strfreev(split_str);
1166       return strdup("SLA");
1167       
1168     }
1169   }else{
1170     
1171     /* return "default" status */
1172     g_strfreev(split_str);
1173     return strdup("SLA");
1174 
1175   }
1176   
1177 }
1178 
1179 
1180 
1181 /* GSList * up_add_inet6num_attrs
1182    adds the generated attrs of inet6num objects */
1183 /*GSList * up_add_inet6num_attrs(Object * obj, char * obj_text, GSList * attribute_list, 
1184                                external_syntax_struct * result)*/
1185 void up_add_inet6num_attrs(rpsl_object_t *generated_obj)                               
     /* [<][>][^][v][top][bottom][index][help] */
1186 {
1187 
1188   int attribute_no;
1189   char *status_value;
1190   rpsl_attr_t * status_attr;
1191   char *inet6num_attr_str, *status_attr_str;
1192   const char *type;
1193   GList *attributes_changed;
1194   
1195 
1196 
1197   /* if this is an inet6num  object */
1198   type = rpsl_object_get_class(generated_obj);
1199   if( ! strcmp(type, "inet6num") )
1200   {
1201       inet6num_attr_str = get_search_key(generated_obj, "inet6num");
1202       status_value = up_assign_i6_status(inet6num_attr_str);
1203       status_attr_str = (char *)UT_malloc(strlen("status: ") + strlen(status_value) + 1);
1204       strcpy(status_attr_str, "status: ");
1205       strcat(status_attr_str, status_value);
1206       status_attr = rpsl_attr_init(status_attr_str, type);
1207           free(status_attr_str);
1208           if ( status_attr )
1209       {
1210         /* we will put the status attribute before the first 'changed' attribute */
1211         attribute_no = 1; /* a default position (the second attribute) in case we cannot find
1212                                  a 'changed' attribute */    
1213         attributes_changed = rpsl_object_get_attr(generated_obj, "changed");    
1214         if ( attributes_changed != NULL )
1215                 {
1216           attribute_no = ((rpsl_attr_t *)(attributes_changed->data))->num;
1217         }
1218         rpsl_object_add_attr(generated_obj, status_attr, attribute_no, NULL);
1219       }
1220   }
1221 }
1222 
1223 
1224 
1225 /* generates the "generated" attribute (status) of an inet6num object. Returns the 
1226    new object as a char * */
1227 char *UP_generate_i6_attrs(rpsl_object_t *generated_obj)
     /* [<][>][^][v][top][bottom][index][help] */
1228 {
1229   
1230   external_syntax_struct *result;
1231   char *obj_str; 
1232 
1233   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
1234 
1235   /* initialize the struct */
1236   result->result = 0;
1237   result->error_str = strdup("");
1238   result->warning_str = strdup("");
1239 
1240 
1241   up_check_changed_attr(generated_obj, result);
1242   up_add_inet6num_attrs(generated_obj);
1243   
1244   up_reconstruct_object(generated_obj, result);
1245 
1246   if (tracing)
1247   {
1248     printf("TRACING: UP_generate_i6_attrs: the reconstructed object is=[%s]\n", result->new_obj);
1249     printf("TRACING: UP_generate_i6_attrs: ... and the result code is=[%i]\n", result->result);
1250   }
1251 
1252   obj_str = strdup(result->new_obj);
1253   free(result->error_str);
1254   free(result->warning_str);
1255   free(result->new_obj);
1256   free(result);
1257   return obj_str;
1258 }
1259 

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