modules/up/UP_extrnl_syntax.cc

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

FUNCTIONS

This source file includes following functions.
  1. up_get_dates
  2. up_changed_has_date
  3. up_get_current_date
  4. up_add_dates
  5. up_check_date_order
  6. up_check_changed_attr
  7. up_check_an_auth_attr
  8. up_check_auth_attr
  9. up_get_attribute_list
  10. up_reconstruct_object
  11. UP_check_external_syntax

   1 /***************************************
   2   $Revision: 1.4 $
   3 
   4   UP external syntax checks
   5 
   6   Status: NOT REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (15/12/2000) Created.
  13   ******************/ /******************
  14   Copyright (c) 2001                              RIPE NCC
  15  
  16   All Rights Reserved
  17   
  18   Permission to use, copy, modify, and distribute this software and its
  19   documentation for any purpose and without fee is hereby granted,
  20   provided that the above copyright notice appear in all copies and that
  21   both that copyright notice and this permission notice appear in
  22   supporting documentation, and that the name of the author not be
  23   used in advertising or publicity pertaining to distribution of the
  24   software without specific, written prior permission.
  25   
  26   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  27   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  28   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  29   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  30   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  31   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  32  ***************************************/
  33 
  34 
  35 #include "rpsl/object.hh"
  36 #include "UP_extrnl_syntax.h"
  37 #include "dbupdate.h"
  38 
  39 
  40 extern int tracing;
  41 
  42 
  43 
  44 
  45 /* obtains a list of dates in the given 
  46    list of attributes (GSList of attribute_struct) */
  47 GSList * up_get_dates(GSList * attribute_list){
     /* [<][>][^][v][top][bottom][index][help] */
  48 
  49   GSList * next;
  50   char * temp, * str; 
  51   int i;
  52   //char * date;
  53   GSList * list = NULL;
  54 
  55   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
  56     /* is this a 'changed' attribute? */
  57     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "changed") == 0){
  58       temp = strdup(((attribute_struct *)(next->data))->content);
  59 
  60       /* delete the part after '#', inclusive */
  61       if(index(temp,'#') != NULL){
  62         temp[index(temp, '#') - temp] = '\0';
  63       }
  64       /* replace \n, \r & \t's with " " */
  65       for(i = 0; i < strlen(temp) ;i++){
  66         if(temp[i] == '\n' || temp[i] == '\r' || temp[i] == '\t' ){
  67           temp[i] = ' ';
  68         }
  69       }
  70       g_strstrip(temp);
  71       /* delete multiple spaces */
  72       str = (char *)malloc(strlen(temp) + 1);
  73       up_string_pack(str, temp);
  74       free(temp); 
  75 
  76       /* now, we have the 'changed' attribute's content in "normalized" form 
  77          We are sure it contains a date. So, it must be the second (and last)
  78          word in the attrib. */
  79       assert(index(str,' ') != NULL);
  80       temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
  81       temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
  82       temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
  83       list = g_slist_append (list, temp);   
  84     }
  85   }
  86   
  87   return list;
  88 }
  89 
  90 
  91 
  92 
  93 /* Does the 'changed' attribute we got have a date already?
  94    Returns 1 if it does, 0 if not. */
  95 int up_changed_has_date(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
  96   
  97   int i;
  98   char * str;
  99   char * temp;
 100   
 101   str = strdup(arg);
 102 
 103   /* cut off the EOL comments */
 104   if(index(str, '#')){
 105     str[index(str, '#') - str - 1 ] = '\0';
 106   }
 107   
 108   /* replace \n, \r & \t's with " " */
 109   for(i = 0; i < strlen(str) ;i++){
 110     if(str[i] == '\n' || str[i] == '\r' || str[i] == '\t' ){
 111       str[i] = ' ';
 112     }
 113   }
 114   g_strstrip(str);
 115   /* delete multiple spaces */
 116   temp = (char *)malloc(strlen(str) + 1);
 117   up_string_pack(temp, str);
 118   
 119   free(str);
 120   str = temp;
 121   
 122   /* now, if there is still a white space, then we have a date in the string
 123      (it has to be something like "ripe-dbm@ripe.net 20001210") */
 124   if(index(str, ' ') != NULL){
 125     return 1; 
 126   }else{
 127     return 0;
 128   }
 129 }
 130 
 131 
 132 
 133 
 134 /* supplies the current date in YYYYMMDD format (for example 20011010) */
 135 char * up_get_current_date(){
     /* [<][>][^][v][top][bottom][index][help] */
 136   /* We will use Glib's functions here */
 137 
 138   char * date;
 139   struct tm * time_struct;
 140   
 141   time_t * time_loc;
 142 
 143   time_loc = (time_t *)malloc(sizeof(time_t));
 144   time(time_loc);
 145   
 146   time_struct = localtime(time_loc);
 147 
 148 
 149   date = (char *)malloc(9);
 150   sprintf(date, "%04i%02i%02i", 
 151           time_struct->tm_year + 1900, 
 152           time_struct->tm_mon + 1,
 153           time_struct->tm_mday);
 154   return date;
 155 }
 156 
 157 
 158 
 159 
 160 
 161 
 162 
 163 
 164 /* void add_dates: adds dates to 'changed' attributes which 
 165      are missing one.
 166      Returns 1 if no problems encountered
 167      Returns 0 if a problem encountered, and the error string is set */
 168 int up_add_dates(GSList * attribute_list, char ** warning_str, char ** error_str){
     /* [<][>][^][v][top][bottom][index][help] */
 169   
 170   GSList * next;
 171   char * attribute, * current_date;
 172   int count_no_date = 0; 
 173   char * temp;
 174   
 175   *warning_str = NULL;
 176   *error_str   = NULL;
 177 
 178   /* get the current date in YYYYMMDD format (for example 20011010) */
 179   current_date = up_get_current_date();
 180   
 181   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
 182     /* is this a 'changed' attribute? */
 183     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "changed") == 0){
 184       /* if this attribute does not have a date in it, add it. Also add 
 185           a warning message about this */
 186       if( !up_changed_has_date((char *)(((attribute_struct *)(next->data))->content))){
 187         count_no_date++;
 188         attribute = (char *)(((attribute_struct *)(next->data))->content);
 189         temp = (char *)malloc(strlen(attribute) + strlen(current_date) + 2 );
 190         if(index(attribute, '#')){/* cut off the EOL comments */
 191           attribute[index(attribute, '#') - attribute - 1] = '\0';
 192         }
 193         sprintf(temp, "%s %s", attribute, current_date);
 194         ((attribute_struct *)(next->data))->content = temp;
 195         free(attribute);
 196         /* add a warning message */
 197         if( *warning_str == NULL){
 198           *warning_str = (char *)malloc(strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 199           sprintf(*warning_str, "WARNING  date '%s' added to 'changed' attribute", current_date);
 200         }else{
 201           temp = (char *)malloc(strlen(*warning_str) + 1 
 202                                        + strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 203           sprintf(temp, "%s\nWARNING  date '%s' added to 'changed' attribute", 
 204                               *warning_str, current_date);
 205           free(*warning_str);
 206           *warning_str = temp; 
 207         }
 208       }
 209     }
 210   }
 211   
 212   if(count_no_date > 1){ 
 213     *error_str = strdup("***Error: More than one 'changed' attributes without dates");
 214     return 0;
 215   }else{
 216     return 1;
 217   }
 218   
 219 
 220 }
 221 
 222 
 223 
 224 
 225 
 226 
 227 /* Checks the order of dates in the given list. 
 228    If they are in order, returns 1, 
 229    if not, returns 0 */
 230 int up_check_date_order(GSList * list){
     /* [<][>][^][v][top][bottom][index][help] */
 231    
 232   GSList * next;
 233   char * previous;
 234 
 235   /* if list is empty, return 1 immediately */
 236   if(list == NULL){
 237     return 1;
 238   }
 239 
 240   /* initialize the 'previous' date */
 241   previous = strdup("00000000");
 242    
 243   for( next = list; next != NULL ; next = g_slist_next(next)){
 244     assert((next->data) != NULL);
 245     /* if the new date is smaller than the previous */
 246     if(strcmp((char *)(next->data), previous) < 0 ){
 247       free(previous);
 248       return 0;
 249     }
 250     free(previous);
 251     previous = strdup((char *)(next->data));
 252   }
 253    
 254   free(previous);
 255   /* Reached the end, without finding out-of-order date. Return 1, then */
 256   return 1; 
 257    
 258 }
 259 
 260 
 261 
 262 
 263 
 264 
 265 
 266 /* void up_check_changed_attr 
 267    checks the order of dates in the 'changed' attributes */
 268 void up_check_changed_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
     /* [<][>][^][v][top][bottom][index][help] */
 269 
 270   GSList * date_list;
 271   int res;
 272   char ** warning, **error;
 273   char * temp;
 274 
 275   warning = (char **)malloc(sizeof(char **));
 276   error   = (char **)malloc(sizeof(char **));
 277    
 278 
 279   /* Now, add dates to the "changed" attributes */
 280   res = up_add_dates(/*changed_list*/attribute_list, warning, error);
 281   if(!res){
 282     /* so, add the error string to result's error string */
 283     if(result->error_str == NULL){
 284       result->error_str = strdup(*error);
 285     }else{
 286       temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
 287       sprintf(temp, "%s\n%s", result->error_str, *error);
 288       free(result->error_str);
 289       result->error_str = temp;
 290     }
 291   }
 292 
 293   /* and get the list of dates, we must check their order */
 294   date_list = up_get_dates(attribute_list);
 295   /* and check the order */ 
 296   res = up_check_date_order(date_list);
 297   if(!res){
 298     /* so, add the error string to result's error string */
 299     if(result->error_str == NULL){
 300       result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
 301     }else{
 302       temp = (char *)malloc(strlen(result->error_str) 
 303               + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
 304       sprintf(temp, "%s\n%s", result->error_str, 
 305               "***Error: The dates in the 'changed' attributes should be in order");
 306       free(result->error_str);
 307       result->error_str = temp;
 308     }
 309     /* and here we have to change the result code of "result" here ... */
 310     switch(result->result){
 311       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 312       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 313       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 314       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 315       default: ;
 316     }
 317   }
 318 }
 319 
 320 
 321 
 322 
 323 
 324 int up_check_an_auth_attr(const char * arg, char ** error){
     /* [<][>][^][v][top][bottom][index][help] */
 325 
 326   char * attr;
 327   int ret = 1;
 328   char * cryptpw, * key;
 329 
 330 
 331   attr = strdup(arg);
 332   /*  chop the whitespace in hte beginning and end */
 333   g_strstrip(attr);
 334 
 335   /* Convert to uppercase  */
 336   g_strup(attr);
 337 
 338   /* chop the EOL comment off */
 339   if(index(attr, '#') != NULL){
 340     attr[index(attr, '#') - attr ] = '\0';
 341   }
 342 
 343   if(strstr(attr, "MAIL-FROM ") == attr){
 344     /* It must have somethings after "MAIL-FROM ", which are
 345       supposed to be a regexp */
 346     if(strlen(attr) <= strlen("MAIL-FROM ")){
 347       ret = 0;
 348     }
 349   }else if(strstr(attr, "NONE") == attr){
 350     /* We mustn't have anything after "NONE"  */
 351     if(strlen(attr) != strlen("NONE")){
 352       *error = strdup("***Error: There mustn't be anything after NONE in 'auth' attribute");
 353       ret = 0;
 354     }
 355   }else if(strstr(attr, "CRYPT-PW ") == attr){
 356     /* The string after CRYPT-PW must be of length 13 and must consist of certain
 357        characters */
 358     cryptpw = strdup(attr + strlen("CRYPT-PW "));
 359     g_strstrip(cryptpw);
 360     if(strlen(cryptpw) != 13){
 361       *error = strdup("***Error: The crypted password must be 13-character long in 'auth' attribute");
 362       free(cryptpw);
 363       ret = 0;
 364     }
 365   }else if(strstr(attr, "PGPKEY-") == attr){
 366     /* The string after CRYPT-PW must be of length 13 and must consist of certain
 367        characters */
 368     key = strdup(attr + strlen("PGPKEY-"));
 369     g_strchomp(key);
 370     if(strlen(key) != 8){
 371       *error = strdup("***Error: The PGP key must be 8-character long in 'auth' attribute");
 372       
 373       free(key);
 374       ret = 0;
 375     }
 376 
 377   }else{
 378     *error = strdup("***Error: 'auth' attribute must start with MAIL-FROM, NONE, PGPKEY- or CRYPT-PW");
 379     ret = 0;
 380   }
 381 
 382   free(attr);
 383   return ret;
 384 }
 385 
 386 
 387 
 388 
 389 
 390 
 391 
 392 /* void up_check_auth_attr 
 393    checks the syntax of 'auth' attributes */
 394 void up_check_auth_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
     /* [<][>][^][v][top][bottom][index][help] */
 395 
 396   //GSList * date_list;
 397   int res;
 398   char /* ** warning,*/ **error;
 399   char * temp;
 400   GSList * next;
 401 
 402   //warning = (char **)malloc(sizeof(char **));
 403   error   = (char **)malloc(sizeof(char **));
 404 
 405   /* loop in the attribute_list, find the 'auth' attribs, and check their syntax */
 406   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
 407     /* is this an 'auth' attribute? */
 408     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "auth") == 0){
 409       /* chech its syntax */
 410       res = up_check_an_auth_attr((char *)(((attribute_struct *)(next->data))->content), error);
 411       if(!res){
 412         /* so, add the error string to result's error string */
 413         if(result->error_str == NULL){
 414           result->error_str = strdup(*error);
 415         }else{
 416           temp = (char *)malloc(strlen(result->error_str) 
 417                   + strlen(*error) + 2);
 418           sprintf(temp, "%s\n%s", result->error_str, 
 419                   *error);
 420           free(result->error_str);
 421           result->error_str = temp;
 422         }
 423         /* and here we have to change the result code of "result" here ... */
 424         switch(result->result){
 425           case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 426           case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 427           case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 428           case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 429           default: ;
 430         }
 431       }
 432     }
 433   }
 434 }
 435 
 436 
 437 
 438 
 439 
 440 
 441 
 442 
 443 
 444 
 445 
 446 /* Constructs a list of all attributes of an object, and returns it
 447    as a list of attribute_struct */
 448 GSList * up_get_attribute_list(Object * o, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 449 
 450   char * value = NULL;
 451   Attr *attr;
 452   GSList *list_of_attributes = NULL;
 453   attribute_struct * attribute;
 454   
 455   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 456     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 457     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 458         attr->len - strlen(attr->type->name()) -2 );
 459     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 460       if(tracing) {
 461         cout << "TRACING: up_get_attributes: adding " << g_strstrip(value) << endl;
 462       }
 463       attribute = (attribute_struct *)malloc(sizeof(attribute_struct)); 
 464       attribute->content = value;
 465       attribute->type = strdup(attr->type->name());
 466       list_of_attributes = g_slist_append(list_of_attributes, attribute);
 467   }
 468 
 469   
 470   return list_of_attributes; 
 471 
 472 }
 473 
 474 
 475 
 476 
 477 
 478 void up_reconstruct_object(GSList * attr_list, external_syntax_struct *result){
     /* [<][>][^][v][top][bottom][index][help] */
 479 
 480   char * recons_obj = NULL;
 481   char * temp;
 482   char * content, * type;
 483   GSList * next;
 484 
 485 
 486 
 487 
 488   for( next = attr_list; next != NULL ; next = g_slist_next(next) ){
 489 
 490     content = strdup((char *)(((attribute_struct *)(next->data))->content));
 491     type = strdup((char *)(((attribute_struct *)(next->data))->type));
 492 
 493     if(tracing){
 494       printf("TRACING: up_reconstruct_object:[%s:%s]\n", type, content);
 495     }
 496     
 497     if(recons_obj == NULL){
 498       recons_obj = (char *)malloc(13 + strlen(content) + 1 );
 499       /* trim the white spaces in the beginning */
 500       g_strchug(content);
 501 
 502       /* add ':' at the end of 'type' */
 503       temp = (char *)malloc(strlen(type) + 2);
 504       sprintf(temp, "%s:", type);
 505       free(type);
 506       type = temp;
 507 
 508       sprintf(recons_obj, "%-13s%s", type, content);
 509     }else{
 510       /* trim the white spaces in the beginning */
 511       g_strchug(content);
 512 
 513       /* add ':' at the end of 'type' */
 514       temp = (char *)malloc(strlen(type) + 2);
 515       sprintf(temp, "%s:", type);
 516       free(type);
 517       type = temp;
 518       
 519       temp = (char *)malloc(strlen(recons_obj) + 13 + strlen(content) + 3 );
 520       sprintf(temp, "%s\n%-13s%s", recons_obj, type, content);
 521       free(recons_obj);
 522       recons_obj = temp;
 523     }
 524     
 525   }
 526   
 527   result->new_obj = recons_obj;
 528   
 529 }
 530 
 531 
 532 
 533 
 534 
 535 external_syntax_struct * UP_check_external_syntax(Object * arg, char * obj_text){
     /* [<][>][^][v][top][bottom][index][help] */
 536   
 537   external_syntax_struct *result;
 538   GSList * attribute_list;
 539   
 540  
 541 
 542 
 543   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
 544 
 545   /* initialize the struct */
 546   result->result = 0;
 547   result->error_str = strdup(""); 
 548   result->warning_str = strdup("");
 549 
 550   /* get a list of all attributes */
 551   attribute_list = up_get_attribute_list(arg, obj_text);
 552 
 553   up_check_changed_attr(arg, obj_text, attribute_list, result);
 554   up_check_auth_attr   (arg, obj_text, attribute_list, result);  
 555 
 556   
 557   up_reconstruct_object(attribute_list, result);
 558 
 559   if(tracing){
 560     printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
 561     printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
 562   }
 563 
 564   return result;  
 565 }

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