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.2 $
   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       /*printf("DEBUG: up_get_dates: adding [%s] to the list of dates\n", temp);*/
  84       list = g_slist_append (list, temp);   
  85     }
  86   }
  87   
  88   return list;
  89 }
  90 
  91 
  92 
  93 
  94 /* Does the 'changed' attribute we got have a date already?
  95    Returns 1 if it does, 0 if not. */
  96 int up_changed_has_date(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
  97   
  98   int i;
  99   char * str;
 100   char * temp;
 101   
 102   /*printf("DEBUG: up_changed_has_date: [%s]\n", arg);*/
 103   str = strdup(arg);
 104 
 105   /* cut off the EOL comments */
 106   if(index(str, '#')){
 107     str[index(str, '#') - str - 1 ] = '\0';
 108   }
 109   
 110   /* replace \n, \r & \t's with " " */
 111   for(i = 0; i < strlen(str) ;i++){
 112     if(str[i] == '\n' || str[i] == '\r' || str[i] == '\t' ){
 113       str[i] = ' ';
 114     }
 115   }
 116   g_strstrip(str);
 117   /* delete multiple spaces */
 118   temp = (char *)malloc(strlen(str) + 1);
 119   up_string_pack(temp, str);
 120   
 121   free(str);
 122   str = temp;
 123   
 124   /* now, if there is still a white space, then we have a date in the string
 125      (it has to be something like "ripe-dbm@ripe.net 20001210") */
 126   if(index(str, ' ') != NULL){
 127     /*printf("DEBUG: has date\n");*/
 128     return 1; 
 129   }else{
 130     /*printf("DEBUG: has NOT date\n");*/
 131     return 0;
 132   }
 133 }
 134 
 135 
 136 
 137 
 138 /* supplies the current date in YYYYMMDD format (for example 20011010) */
 139 char * up_get_current_date(){
     /* [<][>][^][v][top][bottom][index][help] */
 140   /* We will use Glib's functions here */
 141 
 142   char * date;
 143   struct tm * time_struct;
 144   
 145   time_t * time_loc;
 146 
 147   time_loc = (time_t *)malloc(sizeof(time_t));
 148   time(time_loc);
 149   
 150   time_struct = localtime(time_loc);
 151 
 152   /*printf("DEBUG: Current time is: tm_mday=[%02i], tm_mon=[%02i], tm_year=[%04i]\n",
 153                 time_struct->tm_mday, time_struct->tm_mon, time_struct->tm_year);*/
 154 
 155   date = (char *)malloc(9);
 156   sprintf(date, "%04i%02i%02i", 
 157           time_struct->tm_year + 1900, 
 158           time_struct->tm_mon + 1,
 159           time_struct->tm_mday);
 160   return date;
 161 }
 162 
 163 
 164 
 165 
 166 
 167 
 168 
 169 
 170 /* void add_dates: adds dates to 'changed' attributes which 
 171      are missing one.
 172      Returns 1 if no problems encountered
 173      Returns 0 if a problem encountered, and the error string is set */
 174 int up_add_dates(GSList * attribute_list, char ** warning_str, char ** error_str){
     /* [<][>][^][v][top][bottom][index][help] */
 175   
 176   GSList * next;
 177   char * attribute, * current_date;
 178   int count_no_date = 0; 
 179   char * temp;
 180   
 181   *warning_str = NULL;
 182   *error_str   = NULL;
 183 
 184   /* get the current date in YYYYMMDD format (for example 20011010) */
 185   current_date = up_get_current_date();
 186   /*printf("DEBUG: got current_date=[%s] from up_get_current_date()\n", current_date);*/
 187   
 188   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
 189     /* is this a 'changed' attribute? */
 190     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "changed") == 0){
 191       /* if this attribute does not have a date in it, add it. Also add 
 192           a warning message about this */
 193       if( !up_changed_has_date((char *)(((attribute_struct *)(next->data))->content))){
 194         count_no_date++;
 195         attribute = (char *)(((attribute_struct *)(next->data))->content);
 196         temp = (char *)malloc(strlen(attribute) + strlen(current_date) + 2 );
 197         if(index(attribute, '#')){/* cut off the EOL comments */
 198           attribute[index(attribute, '#') - attribute - 1] = '\0';
 199         }
 200         sprintf(temp, "%s %s", attribute, current_date);
 201         ((attribute_struct *)(next->data))->content = temp;
 202         free(attribute);
 203         /* add a warning message */
 204         if( *warning_str == NULL){
 205           *warning_str = (char *)malloc(strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 206           sprintf(*warning_str, "WARNING  date '%s' added to 'changed' attribute", current_date);
 207         }else{
 208           temp = (char *)malloc(strlen(*warning_str) + 1 
 209                                        + strlen("WARNING  date '' added to 'changed' attribute") + 9 );
 210           sprintf(temp, "%s\nWARNING  date '%s' added to 'changed' attribute", 
 211                               *warning_str, current_date);
 212           free(*warning_str);
 213           *warning_str = temp; 
 214         }
 215       }
 216     }
 217   }
 218   
 219   /* debugging */
 220   /*for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
 221     printf("DEBUG: A new changed attr is: [%s]\n", (char *)(((attribute_struct *)(next->data))->content));
 222   }
 223   if(*warning_str != NULL){
 224     printf("DEBUG: And *warning_str is: [%s]\n", *warning_str);
 225   }
 226   */
 227   if(count_no_date > 1){ 
 228     *error_str = strdup("***Error: More than one 'changed' attributes without dates");
 229     return 0;
 230   }else{
 231     return 1;
 232   }
 233   
 234 
 235 }
 236 
 237 
 238 
 239 
 240 
 241 
 242 /* Checks the order of dates in the given list. 
 243    If they are in order, returns 1, 
 244    if not, returns 0 */
 245 int up_check_date_order(GSList * list){
     /* [<][>][^][v][top][bottom][index][help] */
 246    
 247   GSList * next;
 248   char * previous;
 249 
 250   /* if list is empty, return 1 immediately */
 251   if(list == NULL){
 252     return 1;
 253   }
 254 
 255   /* initialize the 'previous' date */
 256   previous = strdup("00000000");
 257    
 258   for( next = list; next != NULL ; next = g_slist_next(next)){
 259     assert((next->data) != NULL);
 260     /* if the new date is smaller than the previous */
 261     /*printf("DEBUG: up_check_date_order: will compare 'this'=[%s] and 'previous'=[%s]\n",
 262            (char *)(next->data), previous);*/
 263     if(strcmp((char *)(next->data), previous) < 0 ){
 264       free(previous);
 265       return 0;
 266     }
 267     free(previous);
 268     previous = strdup((char *)(next->data));
 269   }
 270    
 271   free(previous);
 272   /* Reached the end, without finding out-of-order date. Return 1, then */
 273   /*printf("DEBUG: up_check_date_order: will return 1\n"); */
 274   return 1; 
 275    
 276 }
 277 
 278 
 279 
 280 
 281 
 282 
 283 
 284 /* void up_check_changed_attr 
 285    checks the order of dates in the 'changed' attributes */
 286 void up_check_changed_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
     /* [<][>][^][v][top][bottom][index][help] */
 287 
 288   GSList * date_list;
 289   int res;
 290   char ** warning, **error;
 291   char * temp;
 292 
 293   warning = (char **)malloc(sizeof(char **));
 294   error   = (char **)malloc(sizeof(char **));
 295    
 296 
 297   /* Now, add dates to the "changed" attributes */
 298   res = up_add_dates(/*changed_list*/attribute_list, warning, error);
 299   if(!res){
 300     /* so, add the error string to result's error string */
 301     if(result->error_str == NULL){
 302       result->error_str = strdup(*error);
 303     }else{
 304       temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
 305       sprintf(temp, "%s\n%s", result->error_str, *error);
 306       free(result->error_str);
 307       result->error_str = temp;
 308     }
 309   }
 310 
 311   /* and get the list of dates, we must check their order */
 312   date_list = up_get_dates(attribute_list);
 313   /* and check the order */ 
 314   res = up_check_date_order(date_list);
 315   if(!res){
 316     /* so, add the error string to result's error string */
 317     if(result->error_str == NULL){
 318       result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
 319     }else{
 320       temp = (char *)malloc(strlen(result->error_str) 
 321               + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
 322       sprintf(temp, "%s\n%s", result->error_str, 
 323               "***Error: The dates in the 'changed' attributes should be in order");
 324       free(result->error_str);
 325       result->error_str = temp;
 326     }
 327     /* and here we have to change the result code of "result" here ... */
 328     switch(result->result){
 329       case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 330       case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 331       case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 332       case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 333       default: ;
 334     }
 335   }
 336   /*printf("DEBUG: up_check_changed_attr: the return code is=[%i]\n", result->result);    */
 337 }
 338 
 339 
 340 
 341 
 342 
 343 int up_check_an_auth_attr(const char * arg, char ** error){
     /* [<][>][^][v][top][bottom][index][help] */
 344 
 345   char * attr;
 346   int ret = 1;
 347   char * cryptpw, * key;
 348 
 349 
 350   attr = strdup(arg);
 351   /*  chop the whitespace in hte beginning and end */
 352   g_strstrip(attr);
 353 
 354   /* Convert to uppercase  */
 355   g_strup(attr);
 356 
 357   /* chop the EOL comment off */
 358   if(index(attr, '#') != NULL){
 359     attr[index(attr, '#') - attr ] = '\0';
 360   }
 361 
 362   if(strstr(attr, "MAIL-FROM ") == attr){
 363     /* It must have somethings after "MAIL-FROM ", which are
 364       supposed to be a regexp */
 365     if(strlen(attr) <= strlen("MAIL-FROM ")){
 366       /*printf("DEBUG: Error: A regular expression is missing after MAIL-FROM in 'auth' attribute\n");*/
 367       ret = 0;
 368     }
 369   }else if(strstr(attr, "NONE") == attr){
 370     /* We mustn't have anything after "NONE"  */
 371     if(strlen(attr) != strlen("NONE")){
 372       *error = strdup("***Error: There mustn't be anything after NONE in 'auth' attribute");
 373       /*printf("DEBUG: Error: There mustn't be anything after NONE in 'auth' attribute\n");*/
 374       ret = 0;
 375     }
 376   }else if(strstr(attr, "CRYPT-PW ") == attr){
 377     /* The string after CRYPT-PW must be of length 13 and must consist of certain
 378        characters */
 379     cryptpw = strdup(attr + strlen("CRYPT-PW "));
 380     g_strstrip(cryptpw);
 381     if(strlen(cryptpw) != 13){
 382       *error = strdup("***Error: The crypted password must be 13-character long in 'auth' attribute");
 383       /*printf("DEBUG: Error: The crypted password must be 13-character long in 'auth' attribute [%s]\n", cryptpw);*/
 384       free(cryptpw);
 385       ret = 0;
 386     }
 387   }else if(strstr(attr, "PGPKEY-") == attr){
 388     /* The string after CRYPT-PW must be of length 13 and must consist of certain
 389        characters */
 390     key = strdup(attr + strlen("PGPKEY-"));
 391     g_strchomp(key);
 392     if(strlen(key) != 8){
 393       *error = strdup("***Error: The PGP key must be 8-character long in 'auth' attribute");
 394       /*printf("DEBUG: Error: The PGP key must be 8-character long in 'auth' attribute\n");*/
 395       
 396       free(key);
 397       ret = 0;
 398     }
 399 
 400   }else{
 401     *error = strdup("***Error: 'auth' attribute must start with MAIL-FROM, NONE, PGPKEY- or CRYPT-PW");
 402     /*printf("DEBUG: Error: 'auth' attribute must start with MAIL-FROM, NONE, PGPKEY- or CRYPT-PW\n");*/
 403     ret = 0;
 404   }
 405 
 406   free(attr);
 407   return ret;
 408 }
 409 
 410 
 411 
 412 
 413 
 414 
 415 
 416 /* void up_check_auth_attr 
 417    checks the syntax of 'auth' attributes */
 418 void up_check_auth_attr(Object * obj, char * obj_text, GSList * attribute_list, external_syntax_struct * result){
     /* [<][>][^][v][top][bottom][index][help] */
 419 
 420   //GSList * date_list;
 421   int res;
 422   char /* ** warning,*/ **error;
 423   char * temp;
 424   GSList * next;
 425 
 426   //warning = (char **)malloc(sizeof(char **));
 427   error   = (char **)malloc(sizeof(char **));
 428 
 429   /* loop in the attribute_list, find the 'auth' attribs, and check their syntax */
 430   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
 431     /* is this an 'auth' attribute? */
 432     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "auth") == 0){
 433       /* chech its syntax */
 434       res = up_check_an_auth_attr((char *)(((attribute_struct *)(next->data))->content), error);
 435       if(!res){
 436         /* so, add the error string to result's error string */
 437         if(result->error_str == NULL){
 438           result->error_str = strdup(*error);
 439         }else{
 440           temp = (char *)malloc(strlen(result->error_str) 
 441                   + strlen(*error) + 2);
 442           sprintf(temp, "%s\n%s", result->error_str, 
 443                   *error);
 444           free(result->error_str);
 445           result->error_str = temp;
 446         }
 447         /* and here we have to change the result code of "result" here ... */
 448         switch(result->result){
 449           case UP_EXTSYN_OK:       result->result = UP_EXTSYN_ERR; break;
 450           case UP_EXTSYN_ERR:      result->result = UP_EXTSYN_ERR; break;
 451           case UP_EXTSYN_WARN:     result->result = UP_EXTSYN_ERR_WARN; break;
 452           case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
 453           default: ;
 454         }
 455       }
 456     }
 457   }
 458   /*printf("DEBUG: up_check_auth_attr: the return code is=[%i]\n", result->result);    */
 459 }
 460 
 461 
 462 
 463 
 464 
 465 
 466 
 467 
 468 
 469 
 470 
 471 /* Constructs a list of all attributes of an object, and returns it
 472    as a list of attribute_struct */
 473 GSList * up_get_attribute_list(Object * o, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 474 
 475   char * value = NULL;
 476   Attr *attr;
 477   GSList *list_of_attributes = NULL;
 478   attribute_struct * attribute;
 479   
 480   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 481     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 482     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 483         attr->len - strlen(attr->type->name()) -2 );
 484     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 485       if(tracing) {
 486         cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
 487       }
 488       attribute = (attribute_struct *)malloc(sizeof(attribute_struct)); 
 489       attribute->content = value;
 490       attribute->type = strdup(attr->type->name());
 491       list_of_attributes = g_slist_append(list_of_attributes, attribute);
 492   }
 493 
 494   
 495   return list_of_attributes; 
 496 
 497 }
 498 
 499 
 500 
 501 
 502 
 503 void up_reconstruct_object(GSList * attr_list, external_syntax_struct *result){
     /* [<][>][^][v][top][bottom][index][help] */
 504 
 505   char * recons_obj = NULL;
 506   char * temp;
 507   char * content, * type;
 508   GSList * next;
 509 
 510   for( next = attr_list; next != NULL ; next = g_slist_next(next) ){
 511 
 512     content = strdup((char *)(((attribute_struct *)(next->data))->content));
 513     type = strdup((char *)(((attribute_struct *)(next->data))->type));
 514 
 515     if(recons_obj == NULL){
 516       recons_obj = (char *)malloc(12 + strlen(content) + 1 );
 517       /* trim the white spaces in the beginning */
 518       g_strchug(content);
 519 
 520       /* add ':' at the end of 'type' */
 521       temp = (char *)malloc(strlen(type) + 2);
 522       sprintf(temp, "%s:", type);
 523       free(type);
 524       type = temp;
 525 
 526       sprintf(recons_obj, "%-12s%s", type, content);
 527     }else{
 528       /* trim the white spaces in the beginning */
 529       g_strchug(content);
 530 
 531       /* add ':' at the end of 'type' */
 532       temp = (char *)malloc(strlen(type) + 2);
 533       sprintf(temp, "%s:", type);
 534       free(type);
 535       type = temp;
 536       
 537       temp = (char *)malloc(strlen(recons_obj) + 12 + strlen(content) + 3 );
 538       sprintf(temp, "%s\n%-12s%s", recons_obj, type, content);
 539       free(recons_obj);
 540       recons_obj = temp;
 541     }
 542     
 543   }
 544   
 545   /*printf("DEBUG: The reconstructed object is=[%s]\n", recons_obj);*/
 546   result->new_obj = recons_obj;
 547   
 548 }
 549 
 550 
 551 
 552 
 553 
 554 external_syntax_struct * UP_check_external_syntax(Object * arg, char * obj_text){
     /* [<][>][^][v][top][bottom][index][help] */
 555   
 556   external_syntax_struct *result;
 557   GSList * attribute_list;
 558   
 559  
 560 
 561   /*printf("DEBUG: check_external_syntax is running\n"); */
 562 
 563   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
 564 
 565   /* initialize the struct */
 566   result->result = 0;
 567   result->error_str = strdup(""); 
 568   result->warning_str = strdup("");
 569 
 570   /* get a list of all attributes */
 571   attribute_list = up_get_attribute_list(arg, obj_text);
 572 
 573   up_check_changed_attr(arg, obj_text, attribute_list, result);
 574   up_check_auth_attr   (arg, obj_text, attribute_list, result);  
 575 
 576   
 577   up_reconstruct_object(attribute_list, result);
 578   /*printf("DEBUG: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);*/
 579   /*printf("DEBUG: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);*/
 580   return result;  
 581 }

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