modules/up/UP_util.cc

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

FUNCTIONS

This source file includes following functions.
  1. authorise
  2. error_msg_cat
  3. interpret_ripdb_result
  4. get_assigned_nic
  5. delete_override
  6. up_get_transaction_id
  7. send_object_db
  8. get_class_type
  9. get_search_key
  10. send_and_get
  11. count_objects
  12. strip_lines
  13. take_objects
  14. take_object
  15. get_as_block
  16. get_aut_num_object
  17. get_less_specific_domain
  18. get_less_specific_set
  19. get_less_specific
  20. get_less_spec_inetnum
  21. get_exact_match_inetnum
  22. get_exact_match_routes
  23. get_less_spec_routes
  24. get_mntners
  25. get_attributes
  26. get_attribute
  27. strstr_in_list
  28. get_auths
  29. get_attr_list
  30. get_mnt_lowers
  31. get_mnt_routes
  32. get_mnt_routes_from_list
  33. get_mnt_lowers_from_list
  34. get_override
  35. check_override
  36. add_to_auth_vector
  37. get_auth_vector
  38. get_mntnfy_vector
  39. get_updto_vector
  40. filter_out_diff_origins
  41. filter_out_same_origins
  42. check_auth
  43. get_old_version
  44. process_mail_header
  45. up_string_pack
  46. delete_delete_attrib
  47. UP_replace_strings
  48. UP_replace_GStrings
  49. identical
  50. find_initials
  51. get_combination_from_autonic
  52. replace_AUTO_NIC_hdl
  53. replace_refs_to_AUTO_NIC_hdl
  54. UP_put_assigned_NIC
  55. has_AUTO_NIC_hdl
  56. has_ref_to_AUTO_nic_hdl
  57. find_email_address
  58. UP_remove_EOLs
  59. UP_replace_globals
  60. get_class_type_char
  61. UP_add_to_upd_log
  62. UP_log_networkupdate

   1 /***************************************
   2   $Revision: 1.71 $
   3 
   4   UP module utilities
   5 
   6   Status: NOT REVIEWED, NOT TESTED
   7 
   8   Author(s):       Engin Gunduz
   9 
  10   ******************/ /******************
  11   Modification History:
  12         engin (17/01/2000) Created.
  13   ******************/ /******************
  14   Copyright (c) 2000                              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 #include <time.h>
  35 #include "dbupdate.h"
  36 #include "UP_extrnl_syntax.h"
  37 #include "ud.h"
  38 
  39 int error = 0; // a global variable to store the errors
  40 char * error_msg = NULL; // a global variable to store the error messages
  41 extern int tracing;
  42 extern char * overridecryptedpw;
  43 extern int test_mode;
  44 extern char * updlog;
  45 extern char * update_host;
  46 extern int update_port;
  47 extern char * query_host;
  48 extern int query_port;
  49 extern char * humailbox;
  50 extern char * autobox;
  51 extern char * netupdclientIP;
  52 
  53 extern int reading_from_mail;
  54 extern int networkupdate;
  55  
  56 
  57 extern char *update_mail_sender;
  58 extern char *update_mail_subject;
  59 extern char *update_mail_date;
  60 extern char *update_mail_ID;
  61 extern char *update_mail_cc;
  62 
  63 extern char *DBhost;
  64 extern int  DBport;
  65 extern char *DBuser;
  66 extern char *DBname;
  67 extern char *DBpasswd;
  68 
  69 
  70 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
  71    variable. If overriden == 1, then it immediately returns UP_AUTH_OK 
  72    (because this means that the update contained a valid override attribute).
  73    Else, it goes through the auth_vector and when it finds a an "auth:"
  74    attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
  75    UP_AUF (authorisation failed) */
  76    
  77 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden){
     /* [<][>][^][v][top][bottom][index][help] */
  78 
  79   int result = 0;
  80 
  81   if(tracing){
  82     printf("TRACING: authorise started with override: %i\n", overriden);
  83   }
  84     
  85   /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
  86   if(overriden == 1){
  87     return UP_AUTH_OK;
  88   }
  89   
  90   else{
  91     result = AU_authorise(auth_vector, credentials);
  92     if(tracing){
  93       printf("TRACING: authorise: AU_authorise returned %i\n", result);
  94     }
  95     if(result > 0){
  96       return UP_AUTH_OK;
  97     }
  98     else{
  99       return UP_AUF; /* authorisation failed */
 100     }
 101   }
 102 }
 103 
 104 /* concatanates the string at the end of error_msg */
 105 void error_msg_cat(const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
 106 
 107   if(string == NULL){
 108     return;
 109   }
 110   if(error_msg == NULL){
 111     error_msg = strdup(string);
 112   }else{
 113     error_msg = (char *)realloc(error_msg, strlen(error_msg) + strlen(string) + 2);
 114     error_msg = strcat(error_msg, "\n");
 115     error_msg = strcat(error_msg, string); 
 116   }
 117 }
 118 
 119 
 120 /* interprets the result string coming from RIPupd
 121    It is called by send_object_db.
 122    It returns the error no returned from RIPupd.  */
 123    
 124 int interpret_ripdb_result(const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
 125    char * error_no = NULL;
 126    char ** temp = NULL, ** temp2 = NULL;
 127    int i;
 128    int err = 0;
 129      
 130   /* if the string is NULL or empty, then return error */
 131   if(string == NULL || strlen(string) == 0){
 132     error = UP_INT; /* internal error, RIPupd should return something */
 133     error_msg_cat("Internal error. RIPupd didn't return anything.");
 134     return 0; 
 135   }
 136 
 137   /* split the string into lines */
 138   temp = g_strsplit(string , "\n", 0);
 139   for(i = 0; temp[i] != NULL; i++){
 140     if(i == 0){/* this line must contain "%ERROR " string in the beginning */
 141       temp2 = g_strsplit(temp[0], " ", 0);
 142       error_no = strdup(temp2[1]);
 143       g_strfreev(temp2);
 144       err = atoi(error_no);
 145       if(tracing){
 146         printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
 147       }
 148     }else if(error_no != NULL && strcmp(error_no, "0") != 0){
 149       error_msg_cat(temp[i]);
 150     }
 151   }
 152   g_strfreev(temp);
 153   if(error_no != NULL){
 154     free(error_no);
 155   }
 156   return err; /* 0 means no error in this context */
 157 }
 158 
 159 
 160 
 161 /* Gets assigned NIC hdl from the string that is returned from 
 162    RIPupdate */
 163 void get_assigned_nic(char * nic_hdl, const char * string){
     /* [<][>][^][v][top][bottom][index][help] */
 164    char * error_no = NULL;
 165    char ** temp = NULL, ** temp2 = NULL;
 166    int i;
 167      
 168   /* if the string is NULL or empty, then return error */
 169   if(string == NULL || strlen(string) == 0){
 170     error = UP_INT; /* internal error, RIPupd should return something */
 171     error_msg_cat("Internal error. RIPupd didn't return anything.");
 172     return; 
 173   }
 174 
 175   /* split the string into lines */
 176   temp = g_strsplit(string , "\n", 0);
 177   for(i = 0; temp[i] != NULL; i++){
 178     if(i == 0){/* this line must contain "%ERROR " string in the beginning */
 179       temp2 = g_strsplit(temp[0], " ", 0);
 180       error_no = strdup(temp2[1]);
 181       g_strfreev(temp2);
 182       if(tracing){
 183         printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
 184       }
 185     }else if(error_no != NULL && strcmp(error_no, "0") != 0){
 186       error_msg_cat(temp[i]);
 187     }else if(error_no != NULL && strcmp(error_no, "0") == 0 && i == 1){/* look for assigned NIC hdl */
 188       /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
 189          need to extract EK3-RIPE part */
 190       //to_be_returned = (char *)malloc(128); /* 128 should be enough for a NIC hdl */
 191       nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,  
 192                                  rindex(temp[i],']') - rindex(temp[i],'[') - 1);
 193       nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
 194       if(tracing && nic_hdl != NULL){
 195         printf("TRACING: get_assigned_nic will return [%s]\n", nic_hdl);
 196       }
 197       g_strfreev(temp);
 198       return;
 199     }
 200   }
 201   g_strfreev(temp);
 202   if(tracing && error_no != NULL && error_msg != NULL){
 203     printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);  
 204   }
 205   return;
 206 }
 207 
 208 
 209 
 210 
 211 
 212 
 213 /* strips lines beginning with "override:" off  */
 214 char * delete_override(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 215 
 216     char ** temp = NULL;
 217     char * string = NULL;
 218     int i;
 219 
 220     if(arg == NULL){
 221        return NULL;
 222     }
 223 
 224     /* split the string into lines */
 225     temp = g_strsplit (arg, "\n", 0);
 226 
 227     for(i=0; temp[i] != NULL; i++){
 228       /* if the line begins with "override:", then do not copy it */
 229       if(strstr(temp[i], "override:") != temp[i]){
 230         if(string == NULL){
 231           string = strdup(temp[i]);
 232         }else{
 233           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
 234           string = strcat(string, "\n");
 235           string = strcat(string, temp[i]);
 236         }
 237       }
 238     }
 239     g_strfreev(temp);
 240     return string;
 241 }
 242 
 243 
 244 
 245 
 246 
 247 /* Obtains a transaction ID for an object. Will be called from send_object_db */
 248 int up_get_transaction_id(){
     /* [<][>][^][v][top][bottom][index][help] */
 249 
 250   SQ_connection_t * sql_connection;
 251   SQ_result_set_t *result;
 252   int error;
 253   long new_id;
 254 
 255   sql_connection = SQ_get_connection(DBhost, DBport, DBname, DBuser, DBpasswd); 
 256   if(!sql_connection){
 257     fprintf(stderr, "No SQL connection\n");
 258     exit(1);
 259   }
 260   error = SQ_execute_query(sql_connection, "INSERT INTO tid VALUES(NULL)", &result);
 261   if(error){
 262     fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
 263     exit(1);
 264   }
 265 
 266   new_id = mysql_insert_id(sql_connection);
 267 
 268   SQ_close_connection(sql_connection);  
 269 
 270   return new_id;
 271 }
 272 
 273 
 274 
 275 
 276 
 277 
 278 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
 279    assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl 
 280    assigned_NIC must be allocated enough memory before send_object_db is called 
 281    
 282    If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
 283    */
 284 up_ripupd_result_struct * send_object_db(char * arg, char * assigned_NIC, char * operation){
     /* [<][>][^][v][top][bottom][index][help] */
 285 
 286         int sockfd, numbytes;  
 287         char buf[MAXDATASIZE + 1];
 288         struct hostent *he;
 289         struct sockaddr_in their_addr; /* connector's address information */
 290         char *result_string = NULL;
 291         char *to_be_returned = NULL;
 292         int err = 0;
 293         char *to_be_sent = NULL;
 294         int tr_id;
 295         char * tr_id_str;
 296         char * tempstr;
 297 
 298         up_ripupd_result_struct * return_struct;
 299 
 300         return_struct = (up_ripupd_result_struct *)malloc(sizeof(up_ripupd_result_struct));
 301         return_struct->error_str = NULL;
 302         
 303         to_be_sent = delete_override(arg);
 304 
 305         /* get the transaction ID, to be sent to RIPupdate*/
 306         tr_id = up_get_transaction_id();
 307 
 308         /* convert it into a string */
 309         tr_id_str = (char *)malloc(64);
 310         sprintf(tr_id_str, "%d", tr_id);
 311 
 312         if ((he=gethostbyname(update_host)) == NULL) {  /* get the host info */
 313             perror("gethostbyname");
 314             exit(1);
 315         }
 316 
 317         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 318             perror("socket");
 319             exit(1);
 320         }
 321 
 322         their_addr.sin_family = AF_INET;      /* host byte order */
 323         their_addr.sin_port = htons(update_port);    /* short, network byte order */
 324         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 325         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 326 
 327 
 328         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 329                                               sizeof(struct sockaddr)) == -1) {
 330             perror("connect");
 331             exit(1);
 332         }
 333 
 334         if (send(sockfd, operation , strlen(operation), 0) == -1)
 335             perror("send");
 336         if (send(sockfd, " ", strlen(" "), 0) == -1)
 337             perror("send");    
 338         if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
 339             perror("send");    
 340         if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
 341             perror("send");
 342         if (send(sockfd, to_be_sent, strlen(to_be_sent), 0) == -1)
 343             perror("send");
 344         if (send(sockfd, "\n\n", 2, 0)  == -1)
 345             perror("send");
 346         /* send the ACK now */
 347         if (send(sockfd, "ACK ",strlen("ACK "), 0)  == -1)
 348             perror("send");
 349         if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
 350             perror("send");    
 351         if (send(sockfd, "\n\n",strlen("\n\n"), 0)  == -1)
 352             perror("send");
 353             
 354 
 355         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 356             buf[numbytes] = '\0';
 357             if(tracing){
 358               printf("%s",buf);
 359             }
 360             if(result_string == NULL){
 361               result_string = strdup(buf);
 362             }else{
 363               result_string = (char *)realloc(result_string, 
 364                                  strlen(result_string) + strlen(buf) + 1);
 365               result_string = strcat(result_string, buf);
 366             }
 367             if(strstr(result_string,"\n\n") != NULL){/* if the result_string contains
 368                                                         an empty line at the end, we will close */
 369               break;
 370             };
 371         }
 372 
 373         err = interpret_ripdb_result(result_string);
 374         if(assigned_NIC != NULL){ /* if the caller of the function expected to get a NIC handle */
 375           get_assigned_nic(assigned_NIC, result_string);
 376         }
 377         close(sockfd);
 378         free(to_be_sent);
 379         return_struct->result = err;
 380         
 381         //return_struct->error_str = strdup(result_string); 
 382         /* According to the error no got from RIPupdate, construct an error string  */
 383         switch (return_struct->result){
 384           case 0: break; 
 385           case ERROR_U_MEM: 
 386           case ERROR_U_DBS:
 387           case ERROR_U_BADOP:
 388           case ERROR_U_COP:
 389           case ERROR_U_NSUP:
 390           case ERROR_U_BUG:
 391             tempstr = (char *)malloc(1024);
 392             snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
 393                 return_struct->result);
 394             return_struct->error_str = tempstr;
 395             break; 
 396           case ERROR_U_OBJ:
 397             tempstr = (char *)malloc(1024);
 398             /* if the object contains refs to unknown objects */
 399             if(strstr(result_string, "dummy") != NULL){
 400               
 401               /* if the response from RIPupd contains "dummy not allowed" string */
 402               snprintf(tempstr, 1024, "***Error: Unknown object referenced");
 403               
 404             }else{
 405 
 406               snprintf(tempstr, 1024, "***Error: Object is referenced from other objects");
 407               
 408             }
 409             return_struct->error_str = tempstr;
 410             break; 
 411           case ERROR_U_AUT:
 412             tempstr = (char *)malloc(1024);
 413             snprintf(tempstr, 1024, "***Error: Membership authorisation failure");
 414             return_struct->error_str = tempstr;
 415             break; 
 416           default: 
 417             tempstr = (char *)malloc(1024);
 418             snprintf(tempstr, 1024, "***Error: Please contact database admin: Error no %i",
 419                 return_struct->result);
 420             return_struct->error_str = tempstr;
 421             break; 
 422         }
 423         return return_struct; 
 424 }
 425 
 426 
 427 
 428 
 429 
 430 
 431 /* takes a pre-parsed object, and returns its type */
 432 char * get_class_type(Object *arg){
     /* [<][>][^][v][top][bottom][index][help] */
 433     
 434     char * be_returned = NULL;
 435     if(arg == NULL) return NULL;
 436     be_returned = strdup(arg->type->getName());  
 437     return g_strstrip(be_returned);
 438 }
 439 
 440 
 441 
 442 
 443 
 444 
 445 /* takes an object (pre-parsed) and returns its first attrib if it is not
 446    a person, and returns the nic-hdl if it is a person object */
 447 char * get_search_key(Object *arg, char * type, const char * text){
     /* [<][>][^][v][top][bottom][index][help] */
 448 
 449     
 450     Attr *attr;    
 451     char *primary_key = NULL, *value = NULL;
 452 
 453     if(arg == NULL) return NULL;
 454 
 455     for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
 456        if(attr->type != NULL ){
 457          value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 458          strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
 459              attr->len - strlen(attr->type->name()) -2 );
 460              value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 461          if(strcmp(attr->type->name(),type) == 0 &&
 462                 strcmp(type,"person") != 0 && strcmp(type,"role") != 0  ){
 463            primary_key = strdup(value);
 464            free(value);
 465            break;
 466          }
 467          if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
 468               (strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )){
 469            primary_key = strdup(value);
 470            free(value);
 471            break;
 472          }
 473          free(value);
 474        }
 475     }
 476     if(primary_key != NULL){ 
 477       return g_strstrip(primary_key);
 478     }else{
 479       return NULL;
 480     }
 481 }
 482 
 483 
 484 
 485 
 486 /* sends char * arg to the specified host's specified port, and
 487    returns the reply as a string. This is used to query the
 488    whois host. Probably we must use WC (whois client) module here,
 489    but it must be extented */
 490 char * send_and_get(char * host, int port, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 491 
 492         int sockfd, numbytes; 
 493         char * result = NULL; 
 494         char buf[MAXDATASIZE + 1];
 495         struct hostent *he;
 496         struct sockaddr_in their_addr; /* connector's address information */
 497   
 498         if(tracing) { 
 499           printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
 500         }
 501 
 502         if ((he=gethostbyname(host)) == NULL) {  /* get the host info */
 503             perror("gethostbyname");
 504             exit(1);
 505         }
 506 
 507         if(tracing) { 
 508           printf("TRACING: send_and_get: called gethostbyname\n");
 509         }
 510 
 511         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 512             perror("socket");
 513             exit(1);
 514         }
 515 
 516         if(tracing) { 
 517           printf("TRACING: send_and_get: called socket\n");
 518         }
 519 
 520 
 521         their_addr.sin_family = AF_INET;      /* host byte order */
 522         their_addr.sin_port = htons(port);    /* short, network byte order */
 523         their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 524         bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
 525 
 526         if (connect(sockfd, (struct sockaddr *)&their_addr, 
 527                                               sizeof(struct sockaddr)) == -1) {
 528             perror("connect");
 529             exit(1);
 530         }
 531         if (send(sockfd, arg , strlen(arg), 0) == -1)
 532                perror("send");
 533         if (send(sockfd, "\n",1,0)  == -1)
 534                perror("send");
 535 
 536 
 537         while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
 538             buf[numbytes] = '\0';
 539             if(result == NULL){
 540               result = strdup(buf);
 541             }else{
 542               result = (char *)realloc(result, strlen(result) + strlen(buf) + 1);
 543               result = strcat(result, buf);
 544             }
 545         }
 546 
 547         close(sockfd);
 548         return result;
 549 
 550 
 551 }
 552 
 553 
 554 
 555 /* counts the number of objects in a string */
 556 int count_objects(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 557     int count = 0;
 558     char *pos = NULL;
 559     char *temp = NULL;
 560 
 561     if(tracing) {
 562       printf("TRACING: count_objects running\n");
 563     }
 564     
 565     if(arg != NULL){
 566       temp = strdup(arg);
 567     }else{
 568       return 0;
 569     }
 570     
 571     if(isalpha(arg[0])){
 572       count++;
 573     }else if(arg[0] == '\n' && isalpha(arg[1])){
 574       count++;
 575     }
 576     while(pos = strstr(temp,"\n\n")){
 577       pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
 578       if(isalpha(pos[2])){
 579         count++;
 580       }
 581     }
 582     if(tracing) {
 583       cout << "TRACING: count_objects returning " << count << endl;
 584     }
 585     free(temp);
 586     return count;
 587 }
 588 
 589 
 590 /* strips lines beginning with '%' off  */
 591 char * strip_lines(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 592 
 593     char ** temp = NULL;
 594     char * string = NULL;
 595     int i;
 596 
 597     if(arg == NULL){
 598        return NULL;
 599     }
 600 
 601     /* split the string into lines */
 602     temp = g_strsplit (arg, "\n", 0);
 603 
 604     for(i=0; temp[i] != NULL; i++){
 605       if(temp[i][0] != '%'){
 606         if(string == NULL){
 607           string = strdup(temp[i]);
 608         }else{
 609           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
 610           string = strcat(string, "\n");
 611           string = strcat(string, temp[i]);
 612         }
 613       }
 614     }
 615     return string;
 616 }
 617 
 618 /* Separates the objects in the given char * arg using "\n\n" as
 619    separator. Returns a linked list whose data consist of separated
 620    objects as  char *  */
 621 
 622 GSList * take_objects(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 623     char ** objects=NULL;
 624     char ** temp = NULL;
 625     GSList * tobereturned = NULL;
 626     int i;
 627 
 628     arg = strip_lines(arg);
 629 
 630     objects =  g_strsplit(arg, "\n\n", 1000);
 631     temp = objects;
 632     for(i=0; temp[i] != NULL; i++){
 633       /* stripe off the trailing and leading white spaces-eols*/
 634       g_strstrip(temp[i]);
 635       if(strlen(temp[i]) > 0){/* if not an empty string */
 636         tobereturned = g_slist_append(tobereturned, temp[i]);
 637       }
 638     }
 639     return tobereturned;
 640 }
 641 
 642 
 643 
 644 
 645 
 646 /* takes the first object in the given char *, using empty lines as
 647    separator */
 648 char * take_object(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 649     GSList * objects;
 650     char * object;
 651 
 652     objects = take_objects(arg);
 653     if(g_slist_length(objects) > 0){
 654       object = strdup((char *)(g_slist_nth_data(objects, 0)));
 655     }else{
 656       return NULL;
 657     }
 658     g_slist_free(objects);
 659     return object;
 660 
 661 }
 662 
 663 
 664 
 665 
 666 
 667 /* Takes an autnum_object, and returns the as-block containing this aut-num */
 668 char * get_as_block(char *autnum_object){
     /* [<][>][^][v][top][bottom][index][help] */
 669   bool code;
 670   char * search_key = NULL, * query_string = NULL;
 671   char * result = NULL;
 672   Object * o = new Object();
 673   
 674   code = o->scan_silent(autnum_object, strlen(autnum_object));
 675   search_key = get_search_key(o,"aut-num",autnum_object);
 676   
 677   query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
 678   sprintf(query_string, "-Tas-block -r %s",search_key);
 679   result = send_and_get(query_host, query_port, query_string);
 680   if(count_objects(result) == 0){
 681     if(tracing){
 682       cout << "No such as-block" << endl;
 683     }
 684     return NULL;
 685   }else if(count_objects(result) > 1){
 686     if(tracing){
 687       cout << "More than one as-block returned" << endl;
 688     }
 689     return NULL;
 690   }else{ /* count_objects(result) == 1 */
 691     return take_object(result);
 692   }
 693   
 694 }
 695 
 696 
 697 /* Takes a route_object, and returns the aut-num mentioned in origin
 698    attribute of this route */
 699 char * get_aut_num_object(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 700   bool code;
 701   char * search_key = NULL, * query_string = NULL;
 702   char * result = NULL;
 703   Object * o = new Object();
 704   
 705   code = o->scan_silent(route_object, strlen(route_object));
 706   search_key = get_search_key(o,"origin",route_object);
 707   
 708   query_string = (char *)malloc(strlen("-Taut-num  -r ")+strlen(search_key)+1);
 709   sprintf(query_string, "-Taut-num -r %s",search_key);
 710   result = send_and_get(query_host, query_port, query_string);
 711   if(count_objects(result) == 0){
 712     if(tracing){
 713       cout << "No such aut-num" << endl;
 714     }
 715     return NULL;
 716   }else if(count_objects(result) > 1){
 717     if(tracing){
 718       cout << "More than one aut-num returned" << endl;
 719     }
 720     return NULL;
 721   }else{ /* count_objects(result) == 1 */
 722     return take_object(result);
 723   }
 724   
 725 }
 726 
 727 
 728 
 729 
 730 /* Takes a domain_object, and returns the less specific domain of it */
 731 char * get_less_specific_domain(char *domain_object){
     /* [<][>][^][v][top][bottom][index][help] */
 732   bool code;
 733   char * search_key = NULL, * query_string = NULL;
 734   char * result = NULL, * domain = NULL;
 735   Object * o = new Object();
 736   int i,j, length;
 737   char * temp = NULL;
 738   char ** splitted;
 739 
 740   code = o->scan_silent(domain_object, strlen(domain_object));
 741   domain = get_search_key(o,"domain",domain_object);
 742 
 743   /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
 744   splitted =   g_strsplit((char *)strdup(domain), ".", 50);
 745 
 746   for(i=1; splitted[i] != NULL; i++){
 747     /* in the following for loop, we will construct the 'less spec' domains
 748        to be looked up in the DB */ 
 749     for(j=i; splitted[j] !=NULL; j++){
 750       length = 0;
 751       if(temp!=NULL){
 752         length = strlen(temp); 
 753       }
 754       temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2); 
 755       if(j==i){
 756         temp = (char *)strdup(splitted[j]);
 757       }else{
 758         sprintf(temp, "%s.%s", temp, splitted[j]);
 759       }
 760     }
 761     query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
 762     sprintf(query_string, "-Tdomain -r -R %s", temp);
 763     result = send_and_get(query_host, query_port, query_string);
 764     if(count_objects(result) == 0){
 765     }else if(count_objects(result) > 1){
 766       if(tracing){
 767         cout << "TRACING: get_less_specific_domain: More than one domains returned" << endl;
 768       }
 769       return NULL; /* error condition */
 770     }else{ /* count_objects(result) == 1 */
 771       return take_object(result);
 772     }
 773     
 774   }
 775   /* release the memory allocated to **splitted */
 776   for(i=0; splitted[i] != NULL; i++){ 
 777     free(splitted[i]);
 778   }  
 779   /* so, we couldn't  find any 'less specific' domain */
 780   return NULL;
 781 }
 782 
 783 
 784 
 785 
 786 
 787 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
 788    by striping down the object's name ( eg, for as35:rs-trial:rs-myset, 
 789    as35:rs-trial is tried ) */
 790 char * get_less_specific_set(char *set_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 791   bool code;
 792   char * search_key = NULL, * query_string = NULL;
 793   char * result = NULL;
 794   Object * o = new Object();
 795   int i;
 796   
 797   code = o->scan_silent(set_object, strlen(set_object));
 798   search_key = get_search_key(o, type, set_object);
 799   delete(o);
 800 
 801   for(i = strlen(search_key) -1; i > -1; i--){
 802     if(search_key[i] == ':'){
 803       search_key[i] = '\0'; /* truncate the string */
 804       break;
 805     }
 806     if(i == 0){/* if we've reached the beginning of the string 
 807                 (this means there wasn't any ';' in the string) */
 808       free(search_key);
 809       search_key = NULL;
 810     }
 811   }
 812   if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since 
 813                                                         we make sure that the name of the 
 814                                                         set_object contains a ':' in a proper place */
 815     return NULL;
 816   }
 817 
 818    
 819   query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
 820   sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r  %s", search_key);
 821   result = send_and_get(query_host, query_port, query_string);
 822   if(count_objects(result) == 0){
 823     cout << "No such object"  << endl;
 824     return NULL;
 825   }else if(count_objects(result) > 1){
 826     cout << "More than one objects returned" << endl;
 827     return NULL;
 828   }else{ /* count_objects(result) == 1 */
 829     return take_object(result);
 830   }
 831   
 832 }
 833 
 834 
 835 
 836 
 837 
 838 
 839 
 840 /* Takes an inetnum or inet6num object and returns one less specific of it */
 841 char * get_less_specific(char *inetnum_object, char *type){
     /* [<][>][^][v][top][bottom][index][help] */
 842   bool code;
 843   char * search_key = NULL, * query_string = NULL;
 844   char * result = NULL;
 845   Object * o = new Object();
 846   
 847   code = o->scan_silent(inetnum_object, strlen(inetnum_object));
 848   search_key = get_search_key(o, type, inetnum_object);
 849   
 850   query_string = (char *)malloc(strlen("-Tinet6num -r -l ") + strlen(search_key) + 1);
 851   sprintf(query_string, "-T%s -r -l %s",type, search_key);
 852   result = send_and_get(query_host, query_port, query_string);
 853   if(count_objects(result) == 0){
 854     cout << "No such " << type << endl;
 855     return NULL;
 856   }else if(count_objects(result) > 1){
 857     cout << "More than one " << type << " returned" << endl;
 858     return NULL;
 859   }else{ /* count_objects(result) == 1 */
 860     return take_object(result);
 861   }
 862   
 863 }
 864 
 865 
 866 
 867 /* Takes a route object and returns one less specific inetnum */
 868 char * get_less_spec_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 869   bool code;
 870   char * search_key = NULL, * query_string = NULL;
 871   char * result = NULL;
 872   Object * o = new Object();
 873   
 874   code = o->scan_silent(route_object, strlen(route_object));
 875   search_key = get_search_key(o, "route", route_object);
 876   
 877   query_string = (char *)malloc(strlen("-Tinetnum -r -l ") + strlen(search_key) + 1);
 878   sprintf(query_string, "-Tinetnum -r -l %s", search_key);
 879   result = send_and_get(query_host, query_port, query_string);
 880   if(count_objects(result) == 0){
 881     cout << "No such inetnum" << endl;
 882     return NULL;
 883   }else if(count_objects(result) > 1){
 884     cout << "More than one inetnums returned" << endl;
 885     return NULL;
 886   }else{ /* count_objects(result) == 1 */
 887     return take_object(result);
 888   }
 889   
 890 }
 891 
 892 
 893 /* Takes a route object and returns exact match inetnum */
 894 char * get_exact_match_inetnum(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 895   bool code;
 896   char * search_key = NULL, * query_string = NULL;
 897   char * result = NULL;
 898   Object * o = new Object();
 899   
 900   code = o->scan_silent(route_object, strlen(route_object));
 901   search_key = get_search_key(o, "route", route_object);
 902   
 903   query_string = (char *)malloc(strlen("-Tinetnum -r -x ") + strlen(search_key) + 1);
 904   sprintf(query_string, "-Tinetnum -r -x %s", search_key);
 905   result = send_and_get(query_host, query_port, query_string);
 906   if(count_objects(result) == 0){
 907     cout << "No such inetnum" << endl;
 908     return NULL;
 909   }else if(count_objects(result) > 1){
 910     cout << "More than one inetnums returned" << endl;
 911     return NULL;
 912   }else{ /* count_objects(result) == 1 */
 913     return take_object(result);
 914   }
 915   
 916 }
 917 
 918 
 919 
 920 /* Takes a route object and returns exact matches of this route */
 921 GSList * get_exact_match_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 922   bool code;
 923   char * search_key = NULL, * query_string = NULL;
 924   char * result = NULL;
 925   Object * o = new Object();
 926   
 927   code = o->scan_silent(route_object, strlen(route_object));
 928   search_key = get_search_key(o, "route", route_object);
 929   
 930   query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(search_key) + 1);
 931   sprintf(query_string, "-Troute -r -x %s", search_key);
 932   result = send_and_get(query_host, query_port, query_string);
 933   if(count_objects(result) == 0){
 934     //cout << "get_exact_match_routes: No such route" << endl;
 935     return NULL;
 936   }else{ /* count_objects(result) == 1 */
 937     return take_objects(result);
 938   }
 939   
 940 }
 941 
 942 
 943 
 944 
 945 
 946 /* Takes a route object and returns (immediate) less specifics of this route */
 947 GSList * get_less_spec_routes(char *route_object){
     /* [<][>][^][v][top][bottom][index][help] */
 948   bool code;
 949   char * search_key = NULL, * query_string = NULL;
 950   char * result = NULL;
 951   Object * o = new Object();
 952   
 953   code = o->scan_silent(route_object, strlen(route_object));
 954   search_key = get_search_key(o, "route", route_object);
 955   
 956   query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(search_key) + 1);
 957   sprintf(query_string, "-Troute -r -l %s", search_key);
 958   result = send_and_get(query_host, query_port, query_string);
 959   if(count_objects(result) == 0){
 960     cout << "get_less_spec_routes: No such route" << endl;
 961     return NULL;
 962   }else{ /* count_objects(result) == 1 */
 963     return take_objects(result);
 964   }
 965   
 966 }
 967 
 968 
 969 
 970 /* Gets an object as a string and returns its 'mnt-by' attributes as a 
 971    GSList (linked list)   */
 972 
 973 GSList *get_mntners(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
 974   bool code;
 975   Object * o;
 976   Attr *attr;
 977   char *value  = NULL;
 978   GSList *list_of_mntners = NULL;
 979   char * object; 
 980 
 981   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
 982    (no harm in having more than one) */
 983   object = (char *)malloc(strlen(arg) + 2);
 984   sprintf(object, "%s\n", arg);
 985 
 986   if(tracing) {
 987     printf("TRACING: get_mntners is running\n");
 988   }
 989   o = new Object;
 990   code = o->scan_silent(object,strlen(object));
 991   
 992   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
 993     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
 994     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
 995         attr->len - strlen(attr->type->name()) -2 );
 996     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
 997     if(strcmp(attr->type->name(),"mnt-by") == 0){
 998       if(tracing) {
 999         cout << "TRACING: get_mntners: adding " << g_strstrip(value) << endl;
1000       }
1001       list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
1002     }
1003     free(value);
1004   }
1005 
1006   free(object);
1007   return list_of_mntners; 
1008 }
1009 
1010 
1011 
1012 
1013 
1014 
1015 /* Gets a preparsed object, its text and an attribute name. Returns a list of
1016    attribute values */
1017 GSList *get_attributes(Object * o, const char * attrib, const char * text){
     /* [<][>][^][v][top][bottom][index][help] */
1018 
1019   char * value = NULL;
1020   Attr *attr;
1021   GSList *list_of_attributes = NULL;
1022 
1023   
1024   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1025     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1026     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
1027         attr->len - strlen(attr->type->name()) -2 );
1028     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1029     if(strcmp(attr->type->name(), attrib) == 0){
1030       if(tracing) {
1031         cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
1032       }
1033       list_of_attributes = g_slist_append(list_of_attributes, g_strstrip(value));
1034     }
1035   }
1036 
1037   
1038   return list_of_attributes; 
1039 }
1040 
1041 
1042 /* Gets a preparsed object, an attribute name. Returns the value of first occurence
1043    of this attribute */
1044 char *get_attribute(Object * o, const char * attrib, char * text){
     /* [<][>][^][v][top][bottom][index][help] */
1045 
1046   char * value = NULL;
1047   Attr *attr;
1048 
1049   if(tracing) {
1050     printf("TRACING: get_attributes is running\n");
1051   }
1052   
1053   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1054     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1055     strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
1056         attr->len - strlen(attr->type->name()) -2 );
1057     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1058     if(strcmp(attr->type->name(), attrib) == 0){
1059       if(tracing) {
1060         cout << "TRACING: get_attribute: will return " << value << endl;
1061       }
1062       return value;
1063     }else{
1064       free(value);
1065     }
1066   }
1067 
1068   if(tracing) {
1069     printf("TRACING: get_attribute is returning\n");
1070   }
1071   
1072   return NULL; 
1073 }
1074 
1075 
1076 
1077 /* Gets a GSList of strings and returns 1 if one of them starts with substr, 0 otherwise */
1078 int strstr_in_list(GSList * list, const char * substr){
     /* [<][>][^][v][top][bottom][index][help] */
1079 
1080  GSList * next = NULL;
1081  char * word; 
1082 
1083   if(tracing) {
1084     printf("TRACING: strstr_in_list is running\n");
1085   }
1086  
1087  for( next = list; next != NULL ; next = g_slist_next(next) ){
1088    word = strdup((char *)next->data);
1089    g_strup(word);
1090    if(strstr(word, substr) == word){
1091      free(word);
1092      return 1;
1093    }
1094    free(word);
1095  }
1096  /* none of them matched, so return 0 */
1097  return 0; 
1098 }
1099 
1100 
1101 
1102 
1103 
1104 /* Gets a (maintainer) object as a string and returns its 'auth' attributes 
1105    as a GSList (linked list) */
1106 
1107 GSList *get_auths(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1108   bool code;
1109   Object * o;
1110   Attr *attr;
1111   char *value  = NULL;
1112   GSList *list_of_auths = NULL;
1113 
1114   if(tracing){
1115     printf("TRACING: get_auths is running\n");
1116   }
1117   o = new Object;
1118   code = o->scan_silent(object,strlen(object));
1119   
1120   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1121     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1122     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1123         attr->len - strlen(attr->type->name()) -2 );
1124     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1125     if(strcmp(attr->type->name(),"auth") == 0){
1126       if(tracing) {
1127         cout << "TRACING: get_auths: adding " << g_strstrip(value) << endl;
1128       }
1129       list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
1130       if(tracing) {
1131         cout << "TRACING: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
1132       }
1133     }
1134   }
1135 
1136   if(tracing) {
1137     cout << "TRACING: get_auths: returning (with " << g_slist_length(list_of_auths) << " nodes)" << endl;
1138   }
1139   return list_of_auths; 
1140 }
1141 
1142 
1143 
1144 
1145 /* Gets an object as a string an returns its 'attr_type' attributes as a 
1146    GSList (linked list) */
1147 
1148 GSList *get_attr_list(char * arg, char * attr_type){
     /* [<][>][^][v][top][bottom][index][help] */
1149   bool code;
1150   Object * o;
1151   Attr *attr;
1152   char *value  = NULL;
1153   GSList *list_of_attrs = NULL;
1154   char * object;
1155 
1156   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
1157    (no harm in having more than one) */
1158   object = (char *)malloc(strlen(arg) + 2);
1159   sprintf(object, "%s\n", arg);
1160 
1161   if(tracing) {
1162     printf("TRACING: get_attr_list is running, object is \n#%s#\n", object);
1163   }
1164   o = new Object;
1165   code = o->scan_silent(object,strlen(object));
1166   
1167   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1168     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1169     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1170         attr->len - strlen(attr->type->name()) -2 );
1171     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1172     if(strcmp(attr->type->name(), attr_type) == 0){
1173       if(tracing) {
1174         cout << "TRACING: get_attr_list: adding " << g_strstrip(value) << endl;
1175       }
1176       list_of_attrs = g_slist_append(list_of_attrs, g_strstrip(value));
1177     }
1178   }
1179 
1180   free(object);
1181   return list_of_attrs; 
1182 }
1183 
1184 
1185 
1186 
1187 
1188 
1189 /* Gets an object as a string an returns its mnt_lower attributes as a 
1190    GSList (linked list) */
1191 
1192 GSList *get_mnt_lowers(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1193   bool code;
1194   Object * o;
1195   Attr *attr;
1196   char *value  = NULL;
1197   GSList *list_of_mnt_lowers = NULL;
1198 
1199 
1200   if(tracing) {
1201     printf("TRACING: get_mnt_lowers is running\n");
1202   }
1203   o = new Object;
1204   code = o->scan_silent(object,strlen(object));
1205   
1206   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1207     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1208     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1209         attr->len - strlen(attr->type->name()) -2 );
1210     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1211     if(strcmp(attr->type->name(),"mnt-lower") == 0){
1212       if(tracing) {
1213         cout << "TRACING: get_mnt_lowers: adding " << g_strstrip(value) << endl;
1214       }
1215       list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
1216     }
1217   }
1218 
1219 
1220   return list_of_mnt_lowers; 
1221 }
1222 
1223 
1224 /* Gets an object as a string an returns its mnt_routes attributes as a 
1225    GSList (linked list) */
1226 
1227 GSList *get_mnt_routes(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1228   bool code;
1229   Object * o;
1230   Attr *attr;
1231   char *value  = NULL;
1232   GSList *list_of_mnt_routes = NULL;
1233 
1234   if(tracing) {
1235   cout << "TRACING: get_mnt_routes is running" << endl;
1236   }
1237   o = new Object;
1238   code = o->scan_silent(object,strlen(object));
1239   
1240   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1241     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1242     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1243         attr->len - strlen(attr->type->name()) -2 );
1244     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1245     if(strcmp(attr->type->name(),"mnt-routes") == 0){
1246       if(tracing) {
1247         cout << "TRACING: get_mnt_routes: adding " << g_strstrip(value) << endl;
1248       }
1249       list_of_mnt_routes = g_slist_append(list_of_mnt_routes, strdup(g_strstrip(value)));
1250     }
1251   }
1252 
1253   return list_of_mnt_routes; 
1254 }
1255 
1256 
1257 /* Gets a linked list of objects and returns the mnt_routes attribs of
1258    them in a linked list */
1259 GSList *get_mnt_routes_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1260   GSList *next = NULL;
1261   GSList *list_of_mnt_routes = NULL;
1262   
1263   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1264     list_of_mnt_routes = g_slist_concat(list_of_mnt_routes, get_mnt_routes((char *)next->data));
1265   }
1266 
1267   return list_of_mnt_routes;
1268 }
1269 
1270 
1271 
1272 /* Gets a linked list of objects and returns the mnt_routes attribs of
1273    them in a linked list */
1274 GSList *get_mnt_lowers_from_list(GSList * objects){
     /* [<][>][^][v][top][bottom][index][help] */
1275   GSList *next = NULL;
1276   GSList *list_of_mnt_lowers = NULL;
1277   
1278   for( next = objects; next != NULL ; next = g_slist_next(next) ){
1279     list_of_mnt_lowers = g_slist_concat(list_of_mnt_lowers, get_mnt_lowers((char *)next->data));
1280   }
1281 
1282   return list_of_mnt_lowers;
1283 }
1284 
1285 
1286 
1287 /* retrieves the override password from the 'override' attribute  
1288    of the object. If none, it returns NULL   */
1289 char *get_override(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1290   bool code;
1291   Object * o;
1292   Attr *attr;
1293   char *value  = NULL;
1294 
1295   if(tracing){
1296     printf("TRACING: get_override is running\n");
1297   }
1298   o = new Object;
1299   code = o->scan_silent(object,strlen(object));
1300   
1301   for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1302     value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1303     strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1304         attr->len - strlen(attr->type->name()) -2 );
1305     value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1306     if(strcmp(attr->type->name(),"override") == 0){
1307       if(tracing) {
1308         cout << "TRACING: get_override: returning " << g_strstrip(value) << endl;
1309       }
1310       return  strdup(g_strstrip(value));
1311     }
1312   }
1313   /* there was no 'override' attrib, so return NULL */
1314   return NULL; 
1315 }
1316 
1317 
1318 
1319 
1320 
1321 
1322 /* checks override string (password) 
1323    returns OVR_OK if it is correct password */
1324 int check_override(char * string){
     /* [<][>][^][v][top][bottom][index][help] */
1325    char ** temp;
1326    int i;
1327    char * crypted_password = strdup(overridecryptedpw);
1328    if(string == NULL) {
1329      if(tracing) {
1330        printf("TRACING: check_override is returning FAILED\n");
1331      }
1332      return UP_OVF; /* override attempt failed */ 
1333    }else{
1334     /* split the string */
1335      temp = g_strsplit (string, " ", 0);
1336 
1337      for(i=0; temp[i] != NULL; i++){
1338        if(strlen(temp[i]) != 0){
1339          if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0){
1340            g_strfreev(temp);
1341            if(tracing) {
1342              printf("TRACING: check_override is returning OK\n", string);
1343            }
1344            return OVR_OK; 
1345          }
1346        }
1347      }
1348 
1349      g_strfreev(temp);         
1350      /* we couldn't find a word matching the override password */ 
1351           return UP_OVF; /* override attempt failed */
1352    }
1353 }
1354 
1355 
1356 
1357 
1358 
1359 
1360 
1361 
1362 
1363 
1364 
1365 
1366 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
1367    add new elements to GSList of struct auth_struct and  returns the new
1368    GSList of struct auth_struct  */
1369 
1370 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
     /* [<][>][^][v][top][bottom][index][help] */
1371    GSList * next;
1372    char * auth_attrib = NULL;
1373    char * auth_attrib_uppercase = NULL, * argument = NULL;
1374    auth_struct * temp = NULL;
1375    int index = 1;
1376       
1377    for(next = auths; next != NULL; next = g_slist_next(next)){
1378      auth_attrib = strdup((char *)next->data);
1379      auth_attrib = g_strstrip(auth_attrib);
1380      if(tracing) {
1381        cout << "TRACING: add_to_auth_vector: " << auth_attrib << endl;
1382      }
1383      /* Take the auth attribute and convert it into uppercase for comparisons */
1384      auth_attrib_uppercase = strdup(auth_attrib);
1385      g_strup(auth_attrib_uppercase);
1386      
1387      if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
1388        /* take the argument of the auth attribute */
1389        argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1390        g_strstrip(argument);
1391        if(tracing) {
1392          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1393        }
1394        temp = (auth_struct *)malloc(sizeof(auth_struct));
1395        temp->type = AU_CRYPT_PW;
1396        temp->auth = argument;
1397        temp->mntner_name = mntner_name;
1398        temp->index = index++;
1399        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1400      }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
1401        /* take the argument of the auth attribute */
1402        argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1403        g_strstrip(argument);
1404        if(tracing) {
1405          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1406        }
1407        temp = (auth_struct *)malloc(sizeof(auth_struct));
1408        temp->type = AU_MAIL_FROM;
1409        temp->auth = argument;
1410        temp->mntner_name = mntner_name;
1411        temp->index = index++;
1412        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1413      }else if(strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase){
1414        /* take the argument of the auth attribute */
1415        temp = (auth_struct *)malloc(sizeof(auth_struct));
1416        temp->type = AU_NONE;
1417        temp->auth = NULL;
1418        temp->mntner_name = mntner_name;
1419        temp->index = index++;
1420        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1421     }else if(strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase){
1422        argument = strdup(auth_attrib + strlen("PGPKEY-"));
1423        g_strstrip(argument);
1424        if(tracing) {
1425          cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1426        }
1427        temp = (auth_struct *)malloc(sizeof(auth_struct));
1428        temp->type = AU_PGP;
1429        temp->mntner_name = mntner_name;
1430        temp->index = index++;
1431        temp->auth = argument;
1432        list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1433      }else{
1434        if(tracing){
1435          cout << "TRACING: Error: invalid auth attrib: " << auth_attrib << endl;
1436        }
1437        return NULL;
1438      }
1439    }
1440    free(auth_attrib_uppercase);
1441    free(auth_attrib); 
1442    return list_of_auth_struct;
1443 
1444 }
1445 
1446 
1447 
1448 
1449 
1450 
1451 
1452 
1453 
1454 /* Gets a list of mntner names, retrieves those mntners from
1455    the database and extracts the 'auth' attributes, and
1456    constructs the authorisation vector, which is a GSList of
1457    struct auth_struct */
1458 
1459 GSList * get_auth_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1460   GSList * list_of_auths = NULL;
1461   GSList * next = NULL;
1462   GSList * to_be_returned = NULL;
1463   char * query_string = NULL, * result = NULL, * object = NULL;
1464   GSList * temp;
1465 
1466   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1467     if(tracing) {
1468       cout << "=====" << endl << "Got a mntner" << endl;
1469       cout << (char *)next->data << endl;
1470     }
1471     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1472     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1473     result = send_and_get(query_host, query_port, query_string);
1474     if(count_objects(result) == 0){
1475       /* no such maintainer */
1476       return NULL;
1477     }else if(count_objects(result) > 1){
1478       if(tracing) {
1479         cout << "More than one objects returned" << endl;
1480       }
1481     }else{ /* count_objects(result) == 1 */
1482       object = take_object(result);
1483       if(tracing) {
1484         printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1485       }
1486       temp = get_auths(object);
1487       if(tracing) {
1488         cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1489       }
1490       list_of_auths = g_slist_concat(list_of_auths, temp);
1491       if(tracing) {
1492         cout << "TRACING: get_auth_vector: list_of_auths has now " <<  g_slist_length(list_of_auths) << " nodes" << endl;
1493       }
1494       /* add this to the auth_vector. ( next->data is the name of the maintainer  ) */
1495       if(tracing) {
1496        cout << "TRACING: get_auth_vector: to_be_returned has now " <<  g_slist_length(to_be_returned) << " nodes" << endl;
1497       }
1498       to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1499     }
1500   }
1501   
1502   if(tracing) {  
1503     printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned)); 
1504   }
1505   return to_be_returned; 
1506 }
1507 
1508 
1509 
1510 
1511 
1512 
1513 
1514 /* Gets a list of mntner names, retrieves those mntners from
1515    the database and extracts the 'mnt-by' attributes, and
1516    returns them as a GSList */
1517 
1518 GSList * get_mntnfy_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1519   GSList * list_of_mntnfy = NULL;
1520   GSList * next = NULL;
1521   //GSList * to_be_returned = NULL;
1522   char * query_string = NULL, * result = NULL, * object = NULL;
1523   GSList * temp;
1524   
1525   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1526     if(tracing) {
1527       cout << "=====" << endl << "Got a mntner" << endl;
1528       cout << (char *)next->data << endl;
1529     }
1530     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1531     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1532     result = send_and_get(query_host, query_port, query_string);
1533     if(count_objects(result) == 0){
1534       /* no such maintainer */
1535     }else if(count_objects(result) > 1){
1536       if(tracing) {
1537         cout << "More than one objects returned" << endl;
1538       }
1539     }else{ /* count_objects(result) == 1 */
1540       object = take_object(result);
1541       if(tracing) {
1542         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1543       }
1544       temp = get_attr_list(object, "mnt-nfy");
1545       if(tracing) {
1546         cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1547       }
1548       list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1549       if(tracing) {
1550         cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_mntnfy) << " nodes" << endl;
1551       }
1552     }
1553   }
1554   
1555   if(tracing) {  
1556     printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy)); 
1557   }
1558   return list_of_mntnfy; 
1559 }
1560 
1561 
1562 
1563 
1564 
1565 
1566 /* Gets a list of mntner names, retrieves those mntners from
1567    the database and extracts the 'upd-to' attributes, and
1568    returns them as a GSList */
1569 
1570 GSList * get_updto_vector(GSList * mntners){
     /* [<][>][^][v][top][bottom][index][help] */
1571   GSList * list_of_updto = NULL;
1572   GSList * next = NULL;
1573   char * query_string = NULL, * result = NULL, * object = NULL;
1574   GSList * temp;
1575   
1576   for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1577     if(tracing) {
1578       cout << "=====" << endl << "Got a mntner" << endl;
1579       cout << (char *)next->data << endl;
1580     }
1581     query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1582     sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1583     result = send_and_get(query_host, query_port, query_string);
1584     if(count_objects(result) == 0){
1585       /* no such maintainer */
1586     }else if(count_objects(result) > 1){
1587       if(tracing) {
1588         cout << "More than one objects returned" << endl;
1589       }
1590     }else{ /* count_objects(result) == 1 */
1591       object = take_object(result);
1592       if(tracing) {
1593         printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1594       }
1595       temp = get_attr_list(object, "upd-to");
1596       if(tracing) {
1597         cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1598       }
1599       list_of_updto = g_slist_concat(list_of_updto, temp);
1600       if(tracing) {
1601         cout << "TRACING: get_updto_vector: list_of_mntnfy has now " <<  g_slist_length(list_of_updto) << " nodes" << endl;
1602       }
1603     }
1604   }
1605   
1606   if(tracing) {  
1607     printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto)); 
1608   }
1609   return list_of_updto; 
1610 }
1611 
1612 
1613 
1614 
1615 
1616 
1617 
1618 
1619 
1620 
1621 /* gets one or more route objects filters out the ones which don't have the same
1622    origin as 'char * origin' argument */
1623 char * filter_out_diff_origins(char * objects, char * origin){
     /* [<][>][^][v][top][bottom][index][help] */
1624   GSList * object_list = NULL, * next =NULL;
1625   char * objects_to_be_returned = NULL;
1626   bool code;
1627   char * key = NULL;
1628   Object * o = new Object();
1629   
1630   
1631   if(tracing) {
1632     printf("TRACING: filter_out_diff_origins\n");
1633   }
1634 
1635   /* strip the lines beginning with '%' off */
1636   objects = strip_lines(objects);
1637   
1638   /* separate the objects, store them in a linked list */
1639   object_list = take_objects(objects);
1640 
1641   for(next = object_list; next != NULL; next = g_slist_next(next)){
1642     code = o->scan_silent((char *)next->data, strlen((char *)next->data));
1643     key = get_search_key(o, "origin", (char *)next->data);
1644     if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1645       if(objects_to_be_returned == NULL){
1646         objects_to_be_returned = strdup((char *)next->data);
1647       }else{
1648         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
1649                       strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1650         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1651         objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1652       }
1653     }
1654   }
1655 
1656   delete(o);
1657   if(tracing) {
1658     if(objects_to_be_returned != NULL){
1659       printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1660     }else {
1661       printf("TRACING: filter_out_diff_origins: returning NULL\n");
1662       
1663     }
1664   }
1665   return objects_to_be_returned; 
1666   
1667 }
1668 
1669 
1670 
1671 
1672 
1673 
1674 
1675 
1676 /* gets one or more route objects, filters out the ones which have the same
1677    origin as 'char * origin' argument */
1678 char * filter_out_same_origins(char * objects, char * object){
     /* [<][>][^][v][top][bottom][index][help] */
1679   GSList * object_list = NULL, * next =NULL;
1680   char * objects_to_be_returned = NULL;
1681   bool code;
1682   char * key = NULL;
1683   Object * o = new Object();
1684   Object * o2 = new Object();
1685   char * origin;
1686 
1687     
1688   if(tracing) {
1689     printf("TRACING: filter_out_diff_origins\n");
1690   }
1691 
1692   code = o2->scan_silent(object, strlen(object));
1693   origin = get_search_key(o2, "origin", object);
1694 
1695 
1696   /* strip the lines beginning with '%' off */
1697   objects = strip_lines(objects);
1698   
1699   /* separate the objects, store them in a linked list */
1700   object_list = take_objects(objects);
1701 
1702   for(next = object_list; next != NULL; next = g_slist_next(next)){
1703     code = o->scan_silent((char *)next->data, strlen((char *)next->data));
1704     key = get_search_key(o, "origin", (char *)next->data);
1705     if(key != NULL && strcasecmp(g_strstrip(origin), key) != 0){
1706       if(objects_to_be_returned == NULL){
1707         objects_to_be_returned = strdup((char *)next->data);
1708       }else{
1709         objects_to_be_returned = (char *)realloc(objects_to_be_returned, 
1710                       strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1711         objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1712         objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1713       }
1714     }
1715   }
1716 
1717   delete(o);
1718   if(tracing) {
1719     if(objects_to_be_returned != NULL){
1720       printf("TRACING: filter_out_same_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1721     }else {
1722       printf("TRACING: filter_out_same_origins: returning NULL\n");
1723       
1724     }
1725   }
1726   return objects_to_be_returned; 
1727   
1728 }
1729 
1730 
1731 
1732 
1733 
1734 
1735 
1736 
1737 /* Check authorisation
1738    Applies authorisation rules according to the object type 
1739    
1740    Arguments:
1741       char *new_object: the new object,
1742       char *old_object: the old object, as found in the database,
1743       char *type: type of the object
1744       credentials_struct credentials: a struct which
1745         contains credentials of the update, such as 'From:' field of
1746         the e-mail header and passwords in the update   */
1747 
1748 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
     /* [<][>][^][v][top][bottom][index][help] */
1749    
1750    GSList *old_mntners = NULL, *new_mntners = NULL;
1751    GSList *old_auths = NULL, *new_auths = NULL;
1752    GSList *as_block_mnt_lowers = NULL;
1753    GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1754    GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1755    GSList *less_specific_mntners = NULL;
1756    GSList *aut_num_maintainers = NULL;
1757    GSList *aut_num_auth_vector = NULL;
1758    GSList *exact_match_routes = NULL;  
1759    GSList *exact_match_routes_maintainers = NULL;
1760    GSList *exact_match_routes_auth_vector = NULL;
1761    GSList *less_spec_routes = NULL;
1762    GSList *less_spec_routes_mntners = NULL;
1763    GSList *less_spec_routes_auth_vector = NULL;
1764    GSList *exact_match_inetnum_mnt_routes = NULL;
1765    GSList *exact_match_inetnum_auth_vector = NULL;
1766    GSList *less_spec_inetnum_mntners = NULL;
1767    GSList *less_spec_inetnum_auth_vector = NULL;
1768    GSList *exact_match_intenum_auth_vector = NULL;
1769    GSList *exact_match_auth_vector = NULL;
1770 
1771    GSList *old_name = NULL;
1772    GSList *new_name = NULL;
1773     
1774    char *as_block_object = NULL, *less_specific_object = NULL;
1775    char *less_specific_domain = NULL;
1776    char *less_spec_inetnum = NULL;
1777    char *exact_match_inetnum = NULL;
1778    char *less_specific_object_type = NULL;
1779    char *override_string = NULL;
1780    char *set_name = NULL;
1781    char * aut_num_object = NULL;
1782    char * name_old = NULL;
1783    char * name_new = NULL;
1784    Object *set_object = new Object();
1785    Object *temp_obj;
1786    bool code;
1787    bool aut_num_auth_OK = false;
1788 
1789    int overriden = 0;
1790    
1791    /* first check if it is overriden or not. if overriden, check the override
1792       password. If it is correct, continue, setting "overriden" to 1. If not,   
1793       immediately exit returning ERR_UP_OVF                                   */
1794    override_string = get_override((new_object == NULL) ? old_object : new_object );
1795    if(override_string == NULL){ 
1796      overriden = 0;
1797    }else if(check_override(override_string) == OVR_OK){
1798      overriden = 1; /* authorisation is overriden */
1799      free(override_string);override_string = NULL;
1800    }else if(check_override(override_string) == UP_OVS){
1801      free(override_string);override_string = NULL;
1802      return UP_OVS; /* override syntax error --it must have at least two words */
1803    }else{
1804      free(override_string);override_string = NULL;
1805      return UP_OVF; /* override failed! */
1806    }
1807 
1808 
1809    /*  
1810     *  Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types 
1811     */
1812    if(strcmp(type,"person")   == 0 || strcmp(type,"role")     == 0 ||
1813       strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
1814       strcmp(type,"key-cert") == 0 ){
1815      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1816        old_mntners = get_mntners(old_object);
1817        old_auth_vector = get_auth_vector(old_mntners);
1818        return authorise(old_auth_vector, credentials, overriden);
1819      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1820        new_mntners = get_mntners(new_object);
1821        new_auth_vector = get_auth_vector(new_mntners);
1822        if(new_mntners != NULL && new_auth_vector == NULL){
1823          /* then, the mntners in 'new_mntners' do not exist. Problem. */
1824          return UP_AUF; /* auth failed */
1825        }
1826        return authorise(new_auth_vector, credentials, overriden);
1827      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1828        /* check name change of person */
1829        if(strcmp(type,"person") == 0){
1830          old_name = get_attr_list(old_object, "person");
1831          new_name = get_attr_list(new_object, "person");
1832          if(old_name != NULL && new_name != NULL
1833              && g_slist_nth(old_name, 0) != NULL && g_slist_nth(new_name, 0) != NULL
1834              && (g_slist_nth(old_name, 0)->data) != NULL
1835              && (g_slist_nth(new_name, 0)->data) != NULL)
1836            {
1837 
1838            name_old = strdup((char *)(g_slist_nth(old_name, 0)->data));
1839            name_new = strdup((char *)(g_slist_nth(new_name, 0)->data));
1840            if(!identical(name_old, name_new)){
1841              return UP_AUF; /* names were different!  (XXX return a proper error code here!) */
1842            }
1843            
1844          }else{
1845            return UP_INT; /* there was a problem with obtaining the name of person obj */
1846          }
1847        }
1848       
1849        /* check name change of role */
1850        if(strcmp(type,"role") == 0){
1851          old_name = get_attr_list(old_object, "role");
1852          new_name = get_attr_list(new_object, "role");
1853          if(old_name != NULL && new_name != NULL
1854              && g_slist_nth(old_name, 0) != NULL && g_slist_nth(new_name, 0) != NULL
1855              && (g_slist_nth(old_name, 0)->data) != NULL
1856              && (g_slist_nth(new_name, 0)->data) != NULL)
1857            {
1858 
1859            name_old = strdup((char *)(g_slist_nth(old_name, 0)->data));
1860            name_new = strdup((char *)(g_slist_nth(new_name, 0)->data));
1861            if(!identical(name_old, name_new)){
1862              return UP_AUF; /* names were different! */
1863            }
1864            
1865          }else{
1866            return UP_INT; /* there was a problem with obtaining the name of role obj */
1867          }
1868        }
1869                 
1870        old_mntners = get_mntners(old_object);
1871        old_auth_vector = get_auth_vector(old_mntners);
1872        if(old_mntners != NULL && old_auth_vector == NULL){
1873          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1874          return UP_AUF; /* auth failed */
1875        }
1876        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1877          return authorise(old_auth_vector, credentials, overriden);
1878        }else{
1879          new_mntners = get_mntners(new_object);
1880          new_auth_vector = get_auth_vector(new_mntners);
1881          if(new_mntners != NULL && new_auth_vector == NULL){
1882            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1883            return UP_AUF; /* auth failed */
1884          }
1885          return authorise(new_auth_vector, credentials, overriden);
1886        }
1887      }else{ // both are NULL, mustn't happen
1888          if(tracing){
1889            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1890          }
1891          return UP_INT; /* internal error */
1892      }
1893    }
1894 
1895    /*  
1896     *  Handle the "aut-num" type 
1897     */
1898    else if(strcmp(type,"aut-num")  == 0 ){
1899      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1900        old_mntners = get_mntners(old_object);
1901        old_auth_vector = get_auth_vector(old_mntners);
1902        if(old_mntners != NULL && old_auth_vector == NULL){
1903          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1904          return UP_AUF; /* auth failed */
1905        }
1906        return authorise(old_auth_vector, credentials, overriden);
1907      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1908        as_block_object = get_as_block(new_object);
1909        if(as_block_object == NULL ){
1910          return UP_ABN; /* As-block does not exist */
1911          }else{
1912            as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1913            as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1914            if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1915              /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1916              return UP_AUF; /* auth failed */
1917            }
1918          if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1919            new_mntners = get_mntners(new_object);
1920            new_auth_vector = get_auth_vector(new_mntners);
1921            if(new_mntners != NULL && new_auth_vector == NULL){
1922              /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1923              return UP_AUF; /* auth failed */
1924            }
1925            return authorise(new_auth_vector, credentials, overriden);
1926          }else{
1927            return UP_HOF; /* hierarchical auth failed */
1928          }
1929        }
1930      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1931        old_mntners = get_mntners(old_object);
1932        old_auth_vector = get_auth_vector(old_mntners);
1933        if(old_mntners != NULL && old_auth_vector == NULL){
1934          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1935          return UP_AUF; /* auth failed */
1936        }
1937        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1938          return authorise(old_auth_vector, credentials, overriden);
1939        }else{
1940          new_mntners = get_mntners(new_object);
1941          new_auth_vector = get_auth_vector(new_mntners);
1942          if(new_mntners != NULL && new_auth_vector == NULL){
1943            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1944            return UP_AUF; /* auth failed */
1945          }
1946          return authorise(new_auth_vector, credentials, overriden);
1947        }
1948      }else{ /* both are NULL, mustn't happen */
1949          if(tracing) {
1950            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1951          } 
1952          return UP_INT; /* internal error */
1953      }
1954    } 
1955 
1956    /*  
1957     *  Handle the "mntner/as-block" types 
1958     */
1959    else if(strcmp(type,"mntner")  == 0 || strcmp(type,"as-block")  == 0 ){
1960      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1961        old_mntners = get_mntners(old_object);
1962        old_auth_vector = get_auth_vector(old_mntners);
1963        if(old_mntners != NULL && old_auth_vector == NULL){
1964          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1965          return UP_AUF; /* auth failed */
1966        }
1967        return authorise(old_auth_vector, credentials, overriden);
1968      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1969        if(overriden || test_mode){
1970          return UP_AUTH_OK; 
1971        }else{/* If not overriden, must be forwarded to <HUMAILBOX> */
1972          if(tracing) {
1973            cout << "TRACING: check_auth: '" << type << "' creation requested" << endl;
1974          }
1975          return UP_FWD; /* must be forwarded to <HUMAILBOX> */
1976        }
1977      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1978        old_mntners = get_mntners(old_object);
1979        old_auth_vector = get_auth_vector(old_mntners);
1980        if(old_mntners != NULL && old_auth_vector == NULL){
1981          /* then, the mntners in 'old_mntners' do not exist. Problem. */
1982          return UP_AUF; /* auth failed */
1983        }
1984        if(old_auth_vector){ /* if we have mntners in the old object, use them */
1985          return authorise(old_auth_vector, credentials, overriden);
1986        }else{
1987          new_mntners = get_mntners(new_object);
1988          new_auth_vector = get_auth_vector(new_mntners);
1989          if(new_mntners != NULL && new_auth_vector == NULL){
1990            /* then, the mntners in 'new_mntners' do not exist. Problem. */
1991            return UP_AUF; /* auth failed */
1992          }
1993          return authorise(new_auth_vector, credentials, overriden);
1994        }
1995      }else{ // both are NULL, mustn't happen
1996          if(tracing){
1997            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1998          }
1999          return UP_INT; /* internal error */
2000      }
2001    }
2002 
2003    /*  
2004     *  Handle the "inetnum/inet6num" types 
2005     */
2006    else if(strcmp(type,"inetnum")  == 0 || strcmp(type,"inet6num")  == 0 ){
2007      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2008        old_mntners = get_mntners(old_object);
2009        old_auth_vector = get_auth_vector(old_mntners);
2010        if(old_mntners != NULL && old_auth_vector == NULL){
2011          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2012          return UP_AUF; /* auth failed */
2013        }
2014        return authorise(old_auth_vector, credentials, overriden);
2015      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2016        less_specific_object = get_less_specific(new_object, type);
2017        if(less_specific_object == NULL){
2018          if(overriden){
2019            return UP_AUTH_OK; 
2020          }else{
2021            return UP_HOF; /* hierarchical authorisation failed */
2022          }
2023        }else{ /* if we got an inet(6)num object */
2024          less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2025          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2026          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2027            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
2028            return UP_AUF; /* auth failed */
2029          }
2030          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
2031            new_mntners = get_mntners(new_object);
2032            new_auth_vector = get_auth_vector(new_mntners);
2033            if(new_mntners != NULL && new_auth_vector == NULL){
2034              /* then, the mntners in 'new_mntners' do not exist. Problem. */
2035              return UP_AUF; /* auth failed */
2036            }
2037            return authorise(new_auth_vector, credentials, overriden);
2038          }else{
2039            return UP_HOF; /* hierarchical authorisation failed */
2040          }
2041        }
2042      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2043        old_mntners = get_mntners(old_object);
2044        old_auth_vector = get_auth_vector(old_mntners);
2045        if(old_mntners != NULL && old_auth_vector == NULL){
2046          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2047          return UP_AUF; /* auth failed */
2048        }
2049        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2050          return authorise(old_auth_vector, credentials, overriden);
2051        }else{
2052          new_mntners = get_mntners(new_object);
2053          new_auth_vector = get_auth_vector(new_mntners);
2054          if(new_mntners != NULL && new_auth_vector == NULL){
2055            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2056            return UP_AUF; /* auth failed */
2057          }
2058          return authorise(new_auth_vector, credentials, overriden);
2059        }
2060      }else{ /* both are NULL, mustn't happen */
2061          if(tracing){
2062            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2063          }
2064          return UP_INT; /* internal error */
2065      }
2066    }
2067 
2068 
2069    
2070    /*  
2071     *  Handle the "domain" type 
2072     */
2073    else if(strcmp(type,"domain")  == 0){
2074      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2075        old_mntners = get_mntners(old_object);
2076        old_auth_vector = get_auth_vector(old_mntners);
2077        if(old_mntners != NULL && old_auth_vector == NULL){
2078          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2079          return UP_AUF; /* auth failed */
2080        }
2081        return authorise(old_auth_vector, credentials, overriden);
2082      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2083        /* now, we have to find a 'less specific domain object' for this. 
2084           If there is no less specific object, then creation is possible
2085           only with overriding. */
2086       less_specific_domain = get_less_specific_domain(new_object);
2087       if(less_specific_domain == NULL){
2088         if(overriden){/* we didn't get a 'less specific' domain object */
2089            return UP_AUTH_OK; 
2090          }else{
2091            return UP_HOF; /* hierarchical authorisation failed */
2092          }
2093       }else{ /* we get a 'less specific' domain object */
2094          less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
2095          less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2096          if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2097            /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
2098            return UP_AUF; /* auth failed */
2099          }
2100          if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
2101            new_mntners = get_mntners(new_object);
2102            new_auth_vector = get_auth_vector(new_mntners);
2103            if(new_mntners != NULL && new_auth_vector == NULL){
2104              /* then, the mntners in 'new_mntners' do not exist. Problem. */
2105              return UP_AUF; /* auth failed */
2106            }
2107            return authorise(new_auth_vector, credentials, overriden);
2108          }else{
2109            return UP_HOF; /* hierarchical authorisation failed */
2110          }
2111         
2112       }
2113      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2114        old_mntners = get_mntners(old_object);
2115        old_auth_vector = get_auth_vector(old_mntners);
2116        if(old_mntners != NULL && old_auth_vector == NULL){
2117          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2118          return UP_AUF; /* auth failed */
2119        }
2120        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2121          return authorise(old_auth_vector, credentials, overriden);
2122        }else{
2123          new_mntners = get_mntners(new_object);
2124          new_auth_vector = get_auth_vector(new_mntners);
2125          if(new_mntners != NULL && new_auth_vector == NULL){
2126            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2127            return UP_AUF; /* auth failed */
2128          }
2129          return authorise(new_auth_vector, credentials, overriden);
2130        }
2131      }else{ /* both are NULL, mustn't happen */
2132          if(tracing){
2133            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2134          }
2135          return UP_INT; /* internal error */
2136      }
2137    }
2138    
2139 
2140    /*  
2141     *  Handle the "route" type 
2142     */
2143    else if(strcmp(type,"route")  == 0){
2144      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2145        old_mntners = get_mntners(old_object);
2146        old_auth_vector = get_auth_vector(old_mntners);
2147        if(old_mntners != NULL && old_auth_vector == NULL){
2148          /* then, the mntners in 'old_mntners' do not exist. Problem. */
2149          return UP_AUF; /* auth failed */
2150        }
2151        return authorise(old_auth_vector, credentials, overriden);
2152      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2153        /* first we have to find the aut-num object mentioned in the 
2154           origin attribute */
2155 
2156        aut_num_object = get_aut_num_object(new_object); 
2157        if(aut_num_object == NULL){
2158          if(overriden){
2159            return UP_AUTH_OK; 
2160          }else{
2161            return UP_HOF; /* hierarchical authorisation failed */
2162          }
2163        }else{/* there is a corresponding aut-num in the db */
2164          if(tracing){
2165            printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
2166          }
2167          aut_num_maintainers = get_mnt_routes(aut_num_object);
2168          if(aut_num_maintainers != NULL){
2169            aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
2170            if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
2171              aut_num_auth_OK = true;
2172            }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2173              return UP_HOF;
2174            }
2175          }else{/* aut_num_maintainers is NULL */
2176             aut_num_maintainers = get_mnt_lowers(aut_num_object);
2177             if(aut_num_maintainers != NULL){
2178               aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
2179               if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
2180                 aut_num_auth_OK = TRUE;
2181               }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2182                 return UP_HOF; /* hierarchical authorisation failed */
2183               }
2184             }else{/* aut_num_maintainers is NULL */
2185               aut_num_maintainers = get_mntners(aut_num_object);
2186               if(aut_num_maintainers != NULL){
2187                 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
2188                 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
2189                   aut_num_auth_OK = TRUE;
2190                 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2191                   return UP_HOF; /* hierarchical authorisation failed */
2192                 }
2193               }else{/* aut_num_maintainers is NULL */
2194                 aut_num_auth_OK = TRUE;
2195               }
2196               
2197             }
2198          }
2199          if(aut_num_auth_OK){
2200            /* now, we have to find an exact match for this route object. 
2201               If there is no exact match object, then we will go on to find
2202               less specific. */
2203            exact_match_routes = get_exact_match_routes(new_object);
2204            if(exact_match_routes != NULL){
2205              exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
2206              exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
2207              if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
2208                /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
2209                return UP_AUF; /* auth failed */
2210               }
2211              if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2212                /* then, check mnt_bys of the route itself */
2213                new_mntners = get_mntners(new_object);
2214                new_auth_vector = get_auth_vector(new_mntners);
2215                if(new_mntners != NULL && new_auth_vector == NULL){
2216                  /* then, the mntners in 'new_mntners' do not exist. Problem. */
2217                  return UP_AUF; /* auth failed */
2218                }
2219                return authorise(new_auth_vector, credentials, overriden);
2220              }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2221                return UP_HOF; /* hierarchical authorisation failed */
2222              }
2223            }else{ /* exact_match_routes == NULL */
2224              /* then we have to look for less specific route objs */
2225              less_spec_routes = get_less_spec_routes(new_object);
2226              if(less_spec_routes != NULL){
2227                less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
2228                less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners, 
2229                                              get_mnt_lowers_from_list(less_spec_routes));
2230                less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
2231                if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
2232                  /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
2233                  return UP_AUF; /* auth failed */
2234                }
2235                if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2236                  /* then, check mnt_bys of the route itself */
2237                  new_mntners = get_mntners(new_object);
2238                  new_auth_vector = get_auth_vector(new_mntners);
2239                  if(new_mntners != NULL && new_auth_vector == NULL){
2240                    /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2241                    return UP_AUF; /* auth failed */
2242                  }
2243                  return authorise(new_auth_vector, credentials, overriden);
2244                }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2245                  return UP_HOF; /* hierarchical authorisation failed */
2246                }
2247             }else{/* less_spec_routes == NULL */
2248                /* so, we have to get the exact match inetnum */
2249                exact_match_inetnum = get_exact_match_inetnum(new_object);
2250                if(exact_match_inetnum != NULL){
2251                  exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
2252                  exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
2253                  if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
2254                    /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
2255                    return UP_AUF; /* auth failed */
2256                  }
2257                  if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
2258                    /* then, check mnt_bys of the route itself */
2259                    new_mntners = get_mntners(new_object);
2260                    new_auth_vector = get_auth_vector(new_mntners);
2261                    if(new_mntners != NULL && new_auth_vector == NULL){
2262                      /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2263                      return UP_AUF; /* auth failed */
2264                    }
2265                    return authorise(new_auth_vector, credentials, overriden);
2266                  }else{
2267                    return UP_HOF; /* hierarchical authorisation failed */
2268                  }
2269                }else{/* exact_match_inetnum == NULL */
2270                  /* then, we will try to find less spec inetnums */
2271                  less_spec_inetnum = get_less_spec_inetnum(new_object);
2272                  if(less_spec_inetnum != NULL){
2273                    less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2274                    less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners, 
2275                                   get_mnt_lowers(less_spec_inetnum));
2276                    less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2277                    if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2278                      /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2279                      return UP_AUF; /* auth failed */
2280                    }
2281                    if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2282                      /* then, check mnt_bys of the route itself */
2283                      new_mntners = get_mntners(new_object);
2284                      new_auth_vector = get_auth_vector(new_mntners);
2285                      if(new_mntners != NULL && new_auth_vector == NULL){
2286                        /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2287                        return UP_AUF; /* auth failed */
2288                      }
2289                      return authorise(new_auth_vector, credentials, overriden);
2290                    }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2291                      return UP_HOF; /* hierarchical authorisation failed */
2292                    }
2293                  }else{/* less_spec_inetnum == NULL */
2294                    /* now that we couldn't find any route or inetnum object
2295                       to be used in authentication. So, only if the auth is
2296                       overriden the object will be created. */
2297                    if(overriden){
2298                      return UP_AUTH_OK; 
2299                    }else{
2300                      return UP_HOF; /* hierarchical authorisation failed */
2301                    }
2302                  }
2303                }
2304              }
2305            }
2306          }else{/* ! aut_num_auth_OK */
2307            return UP_HOF; /* hierarchical auth failed */
2308          }
2309 
2310        }
2311           
2312      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2313        old_mntners = get_mntners(old_object);
2314        old_auth_vector = get_auth_vector(old_mntners);
2315        if(old_mntners != NULL && old_auth_vector == NULL){
2316          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2317          return UP_AUF; /* auth failed */
2318        }
2319        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2320          return authorise(old_auth_vector, credentials, overriden);
2321        }else{
2322          new_mntners = get_mntners(new_object);
2323          new_auth_vector = get_auth_vector(new_mntners);
2324          if(new_mntners != NULL && new_auth_vector == NULL){
2325            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2326            return UP_AUF; /* auth failed */
2327          }
2328          return authorise(new_auth_vector, credentials, overriden);
2329        }
2330      }else{ /* both are NULL, mustn't happen */
2331          if(tracing){
2332            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2333          }
2334          return UP_INT; /* internal error */
2335      }
2336    }
2337 
2338 
2339    /*  
2340     *  Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types 
2341     */
2342    else if(strcmp(type,"as-set")       == 0 || strcmp(type,"rtr-set")     == 0 ||
2343            strcmp(type,"peering-set")  == 0 || strcmp(type,"filter-set")  == 0 ||
2344            strcmp(type,"route-set")    == 0 ){
2345      if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2346        old_mntners = get_mntners(old_object);
2347        old_auth_vector = get_auth_vector(old_mntners);
2348        if(old_mntners != NULL && old_auth_vector == NULL){
2349          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2350          return UP_AUF; /* auth failed */
2351        }
2352        return authorise(old_auth_vector, credentials, overriden);
2353      }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2354         code = set_object->scan_silent(new_object, strlen(new_object));
2355         set_name = get_search_key(set_object, type, new_object);
2356        if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2357          new_mntners = get_mntners(new_object);
2358          new_auth_vector = get_auth_vector(new_mntners);
2359          if(new_mntners != NULL && new_auth_vector == NULL){
2360            /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2361            return UP_AUF; /* auth failed */
2362          }
2363          return authorise(new_auth_vector, credentials, overriden);
2364        }else{/* the name is hierarchical */
2365          less_specific_object = get_less_specific_set(new_object, type);
2366          if(less_specific_object != NULL){/* such an object exists */
2367            temp_obj = new Object();
2368            code = temp_obj->scan_silent(less_specific_object, strlen(less_specific_object));
2369            less_specific_object_type = get_class_type(temp_obj);
2370            delete(temp_obj);
2371            if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2372              less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2373              less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2374              if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2375                /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2376               return UP_AUF; /* auth failed */
2377              }
2378              if(less_specific_auth_vector != NULL){
2379                return authorise(less_specific_auth_vector, credentials, overriden);
2380              }else{/* the less specific object doesn't contain any mnt-lower */
2381                less_specific_mntners = get_mntners(less_specific_object);
2382                less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2383                if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2384                  /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2385                  return UP_AUF; /* auth failed */
2386                }
2387                if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs, 
2388                                                         use them  */
2389                    return authorise(less_specific_auth_vector, credentials, overriden);
2390                }else{/* the less specific object doesn't contain any mnt-by either */
2391                  if(overriden){
2392                    return UP_AUTH_OK; 
2393                  }else{
2394                    return UP_HOF; /* hierarchical authorisation failed */
2395                  }
2396                }
2397              }
2398            }else{ /* this is _not_ an aut-num object*/
2399              less_specific_mntners = get_mntners(less_specific_object);
2400              less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2401              if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2402                /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2403                return UP_AUF; /* auth failed */
2404              }
2405              if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2406                return authorise(less_specific_auth_vector, credentials, overriden);
2407              }else{
2408                if(overriden){
2409                  return UP_AUTH_OK; 
2410                }else{
2411                  return UP_HOF; /* hierarchical authorisation failed */
2412                }
2413              }
2414            }
2415 
2416          }else{/* we don't have a less specific of this set object in the DB  */
2417            return UP_HOF; /* hierarchical authorisation failed */
2418          }
2419        }
2420      }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2421        old_mntners = get_mntners(old_object);
2422        old_auth_vector = get_auth_vector(old_mntners);
2423        if(old_mntners != NULL && old_auth_vector == NULL){
2424          /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2425          return UP_AUF; /* auth failed */
2426        }
2427        if(old_auth_vector){ /* if we have mntners in the old object, use them */
2428          return authorise(old_auth_vector, credentials, overriden);
2429        }else{
2430          new_mntners = get_mntners(new_object);
2431          new_auth_vector = get_auth_vector(new_mntners);
2432          if(new_mntners != NULL && new_auth_vector == NULL){
2433            /* then, the mntners in 'new_mntners' do not exist. Problem. */
2434            return UP_AUF; /* auth failed */
2435          }
2436          return authorise(new_auth_vector, credentials, overriden);
2437        }
2438      }else{ /* both are NULL, mustn't happen */
2439          if(tracing){
2440            cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2441          }
2442          return UP_INT; /* internal error */
2443      }
2444    
2445 
2446 
2447 
2448 
2449    }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2450      cout << "check_auth: This type '" << type << "' is unknown" << endl;
2451      return UP_NIY; /* not implemented yet */
2452    }
2453    return UP_AUF; /* if we come to this point, then auth failed */ 
2454 }
2455 
2456 
2457 
2458 
2459 
2460 
2461 /* Gets the old version of the given "arg" object, which is in char * format
2462    and returns the old version again in char * format */
2463 
2464 char * get_old_version(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2465 
2466     bool code = true;
2467     char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2468     Object *o;
2469     o = new Object;
2470     char *result = NULL, *origin = NULL;
2471     
2472     error = 0; 
2473     code = o->scan_silent(arg,strlen(arg));
2474     type = get_class_type(o);
2475     primary_search_key = get_search_key(o, type, arg);
2476     if(tracing) {
2477       cout << "type=" << type << endl;
2478       cout << "primary_search_key=" << primary_search_key << endl;
2479     }
2480     /* if the object is a pn ro a ro object, then get all pn/ro's with the
2481        same NIC hdl */
2482     if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2483       /* prepare the search string */
2484       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2485                                           + strlen("person,role") + 2);
2486       sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2487     }else{
2488       /* prepare the search string */
2489       search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2490                                           + strlen(type) + 2);
2491       sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2492     }
2493     result = send_and_get(query_host, query_port, search_string);
2494     if(tracing) {
2495       cout << "TRACING: send_and_get has returned" << endl;
2496       cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl 
2497            << result << endl;
2498     }
2499     /* XXX and here, we must filter the 'result' with NIC handle */
2500 
2501     if(strcmp(type,"route") == 0){
2502       if(tracing) {
2503         printf("TRACING: This is a route\n");
2504       }
2505       /* if this is a route, then we must filter out the routes with different
2506          origin attributes */
2507       origin = get_search_key(o, "origin", arg);
2508       if(tracing) {
2509         printf("TRACING: Got origin of route: %s\n", origin);
2510       }
2511       result = filter_out_diff_origins(result, origin);  
2512       if(tracing) {
2513         printf("TRACING: Filtered routes\n");
2514       }
2515     }
2516     
2517     /* count the objects */
2518     if(count_objects(result) == 0){
2519       result = NULL; /* we don't have such an object */
2520     }else if(count_objects(result) == 1){
2521       result = take_object(result);
2522       if(tracing) {
2523       cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2524       }
2525     }else{ /* we have more than one objects, error! */
2526       error = UP_MOR;
2527       return NULL;
2528     }
2529     return result;
2530 }
2531 
2532 
2533 
2534 
2535 /* Gets a credentials_struct whose 'from' field will be filled in and
2536    the mail header. Finds the 'From:' line in the header and sets
2537    the 'from' field to this line (all line, including the 'From:' string,
2538    since some users have put regexps which match the whole line in their
2539    'auth' attributes.) */
2540 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2541   char * header = strdup(arg);
2542   char * temp = (char *)malloc(strlen(header));
2543   while(index(header, '\n') != NULL){
2544     temp = strdup(header);
2545     temp[index(temp, '\n') - temp] = '\0';
2546     if(strstr(temp, "From:") == temp){
2547       if(tracing) {
2548         printf("TRACING: process_mail_header: Assigning %s\n", temp);
2549       }
2550       credentials_ptr->from = strdup(temp);
2551       free(temp);
2552       return;
2553     }
2554     header = header + (index(header, '\n') - header + 1);
2555   }
2556   free(temp);
2557 }
2558 
2559 
2560 
2561 
2562 
2563 
2564 void up_string_pack(char *dest, const char *source){
     /* [<][>][^][v][top][bottom][index][help] */
2565    
2566   if(tracing) {
2567     printf("TRACING: up_string_pack running\n");
2568   }
2569         
2570 
2571 
2572 /*----------------------------------------------------------------------*\
2573 
2574 *  Function to rewrite a line of text with only one blankspace between  *
2575 *  each word.
2576 *
2577 
2578 \*----------------------------------------------------------------------*/
2579 
2580 
2581 /*
2582  * This while loop continues until the NULL character is copied into
2583  * the destination string.  If a tab character is copied into the
2584  * destination string, it is replaced with a blank-space character.
2585  *
2586  * Multiple blank-space and/or tab characters are skipped in the source
2587  * string until any other character is found.
2588  */
2589 
2590         while (1)
2591                 {
2592                 *dest = *source;
2593 
2594                 if (*dest == '\t')
2595                         (*dest = ' ');
2596 
2597                 /* Exit if have copied the end of the string. */
2598                 if (*dest == '\0')
2599                         return;
2600 
2601 /*
2602  * If the source character was a blank-space or a tab, move to the next
2603  * source character.  While the source character is a blank-space or a
2604  * tab, move to the next character (i.e. ignore these characters).  When
2605  * any other character is found in the source string, move to the next
2606  * element of the destination string.
2607  *
2608  * Otherwise, simultaneously, move to the next elements of the destination
2609  * and the source strings.
2610  */
2611 
2612 
2613 
2614                 if ( (*source == ' ') || (*source == '\t') )
2615                         {
2616                         ++source;
2617                         while ( (*source == ' ') || (*source == '\t') )
2618                                 {
2619                                 ++source;
2620                                 }
2621 
2622                         ++dest;
2623                         }
2624                 else
2625                         {
2626                         ++dest;
2627                         ++source;
2628                         }
2629                 }
2630 }
2631 
2632 
2633 
2634 
2635 
2636 
2637 
2638 
2639 /* strips lines beginning with "delete:" off  */
2640 char * delete_delete_attrib(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2641 
2642     char ** temp = NULL;
2643     char * string = NULL;
2644     int i;
2645 
2646     if(arg == NULL){
2647        return NULL;
2648     }
2649 
2650     /* split the string into lines */
2651     temp = g_strsplit (arg, "\n", 0);
2652 
2653     for(i=0; temp[i] != NULL; i++){
2654       /* if the line begins with "delete:", then do not copy it */
2655       if(strstr(temp[i], "delete:") != temp[i]){
2656         if(string == NULL){
2657           string = strdup(temp[i]);
2658         }else{
2659           string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
2660           string = strcat(string, "\n");
2661           string = strcat(string, temp[i]);
2662         }
2663       }
2664     }
2665     g_strfreev(temp);
2666     return string;
2667 }
2668 
2669 
2670 
2671 
2672 
2673 
2674 /* replaces the erase_str occurences with insert_str in str (which is a ptr to GString) */
2675 char * UP_replace_strings(char * str, const char * erase_str, const char * insert_str){
     /* [<][>][^][v][top][bottom][index][help] */
2676 
2677   GString * g_str;  
2678   int pos;
2679   char * result_str;
2680   
2681   /* erase_str mustn't be NULL */
2682   assert(erase_str != NULL);
2683   
2684   /* if insert str is NULL, make it empty string */
2685   if(insert_str == NULL){
2686     insert_str = strdup(""); 
2687   }
2688   
2689   g_str = g_string_new(str);
2690   
2691   /* replace erase_str with insert_str */
2692   while(strstr(g_str->str, erase_str) != NULL){
2693     pos = strstr(g_str->str, erase_str) - g_str->str;
2694     g_str = g_string_erase(g_str, pos, strlen(erase_str));
2695     if(insert_str != NULL){
2696       g_str = g_string_insert(g_str, pos, insert_str);
2697     }
2698   }
2699   
2700 
2701   /* save the result string */
2702   result_str = strdup(g_str->str);
2703 
2704   /* free the GString structure (TRUE means 'also free the char string') */
2705   g_string_free(g_str, TRUE);
2706 
2707   return result_str;
2708 
2709 }
2710 
2711 
2712 
2713 
2714 
2715 
2716 
2717 
2718 
2719 
2720 /* replaces the erase_str occurences with insert_str in g_str (which is a ptr to GString) */
2721 GString * UP_replace_GStrings(GString * g_str, const char * erase_str, const char * insert_str){
     /* [<][>][^][v][top][bottom][index][help] */
2722 
2723   int pos;
2724   
2725   if(insert_str == NULL){/* then don't do anything */
2726     return g_str;
2727   }
2728    
2729   /* replace erase_str with insert_str */
2730   while(strstr(g_str->str, erase_str) != NULL){
2731     pos = strstr(g_str->str, erase_str) - g_str->str;
2732     g_str = g_string_erase(g_str, pos, strlen(erase_str));
2733     g_str = g_string_insert(g_str, pos, insert_str);
2734   }
2735   return g_str;
2736   
2737 }
2738 
2739 
2740 
2741 
2742 
2743 
2744 
2745 
2746 /* looks if two objects are identical or not.
2747     Takes two objects as char *, and returns 1 if
2748     they are identical, returns 0 if not.
2749 
2750     Algorithm is very simple: All strings of tabs and 
2751     white spaces are collapsed into a single white space,
2752     and then the strings are compared (strcmp) */
2753 int identical(const char * old_version, const char * new_version){
     /* [<][>][^][v][top][bottom][index][help] */
2754   char * arg1 = strdup(old_version);
2755   char * arg2 = strdup(new_version);
2756   int result = 0;
2757   char *temp1, *temp2; 
2758   char *temp;
2759   
2760 
2761   arg1 = g_strstrip(arg1);
2762   arg2 = g_strstrip(arg2);
2763 
2764   /* delete the 'delete:' attrib */
2765   arg2 = delete_delete_attrib(arg2);
2766 
2767   /* also delete 'override' attrib */
2768   arg2 = delete_override(arg2);
2769   
2770   /* convert tabs to white spaces */
2771   arg1 = g_strdelimit(arg1, "\t", ' ');
2772   arg2 = g_strdelimit(arg2, "\t", ' ');
2773   
2774   temp1 = (char *)malloc(strlen(arg1) + 1); 
2775   temp2 = (char *)malloc(strlen(arg2) + 1);
2776   up_string_pack(temp1, arg1);
2777   up_string_pack(temp2, arg2);
2778 
2779   /* if there are still \r's at the end of strings, remove them */
2780   if((temp1[strlen(temp1) - 1]) == '\r'){
2781     temp1[strlen(temp1) - 1] = '\0';
2782   }
2783   if((temp2[strlen(temp2) - 1]) == '\r'){
2784     temp2[strlen(temp2) - 1] = '\0';
2785   }
2786 
2787   /* there may be white spaces at the end of the strings now, remove them */
2788   if((temp1[strlen(temp1) - 1]) == ' '){
2789     temp1[strlen(temp1) - 1] = '\0';
2790   }
2791   if((temp2[strlen(temp2) - 1]) == ' '){
2792     temp2[strlen(temp2) - 1] = '\0';
2793   }
2794 
2795   /* remove the white spaces just before the EOLs (since this is not taken care of by
2796      the up_string_pack func) */
2797   temp = UP_replace_strings(temp1, " \n", "\n");
2798   free(temp1);
2799   temp1 = temp;
2800 
2801   temp = UP_replace_strings(temp2, " \n", "\n");
2802   free(temp2);
2803   temp2 = temp;
2804   
2805       
2806 
2807   result = strcmp(temp1, temp2);
2808   if(tracing){
2809     printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2810     printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
2811   }
2812   free(arg1);
2813   free(arg2);
2814   free(temp1);
2815   free(temp2);
2816   if(result  == 0){
2817     if(tracing) {
2818       printf("TRACING: identical returning 1\n");
2819     }
2820     return 1;
2821   }else{
2822     if(tracing) {
2823       printf("TRACING: identical returning 0\n");
2824     }
2825     return 0;
2826   }
2827 }
2828 
2829 
2830 
2831 
2832 
2833 
2834 /* constructs an initials string from a given name (for NIC hdl generation) */
2835 char * find_initials(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
2836 
2837    char * temp, * temp2;
2838    char * initials = NULL;
2839    int len, i;
2840    char ** vector;
2841 
2842    temp = strdup(arg);
2843    g_strstrip(temp);
2844    temp2 = (char *)malloc(strlen(temp) + 1);
2845    up_string_pack(temp2, temp);
2846    vector = g_strsplit(temp2, " ", 0);
2847    for(i = 0; vector[i] != NULL && i < 4; i++){
2848      if((strlen(vector[i]) > 0 )&& isalpha(vector[i][0]) ){
2849        if(initials == NULL){
2850          initials = (char *)malloc(2);
2851          initials[0] = vector[i][0]; initials[1] = '\0';
2852        }else{
2853          len = strlen(initials);
2854          initials = (char *)realloc(initials, len + 2 );
2855          initials[len] = vector[i][0];
2856          initials[len + 1] = '\0';
2857        }
2858      }
2859    }
2860    free(temp);free(temp2);g_strfreev(vector);
2861    return initials;
2862 }
2863 
2864 
2865 
2866 
2867 
2868 /*  Gets the letter combination to be used in the automatically
2869     generated NIc handle. It the letter combination is specified
2870     in the AUTO NIC handle, return that. If not, return NULL
2871     (in which case the initials of the name must be used) */
2872 char * get_combination_from_autonic(const char * autonic){
     /* [<][>][^][v][top][bottom][index][help] */
2873 
2874   GString * temp;
2875   char * str = NULL;
2876 
2877   temp = g_string_new(autonic);
2878   temp = g_string_up(temp);
2879   temp = g_string_erase(temp, 0, strlen("AUTO-"));
2880   /* delete all digits from the beginning of the string */
2881   while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2882     temp = g_string_erase(temp, 0, 1);
2883   }
2884 
2885 
2886   if(temp->len < 2 ){
2887     g_string_free(temp, TRUE);
2888     return NULL;
2889   }else{
2890     str = temp->str;
2891     g_string_free(temp, FALSE);
2892     g_strup(str);
2893     if(strlen(str) > 4){
2894       str[4] = '\0'; 
2895     }
2896     return str;
2897   }
2898 
2899 }
2900 
2901 
2902 
2903 
2904 
2905 
2906 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2907    and  modifies the nic-hdl: attribute, returns the new object.
2908    For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2909    auto_nic is set to "AUTO-1"
2910    auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2911 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
     /* [<][>][^][v][top][bottom][index][help] */
2912 
2913   GString* temp_string; 
2914   char * to_be_returned = NULL;
2915   char * person_role_name= NULL;
2916   char * initials = NULL;
2917   char ** temp = NULL;
2918   int i, pos;
2919   Object * o = new Object;
2920 
2921   temp = g_strsplit(arg, "\n", 0);
2922 
2923   for(i = 0; temp[i] != NULL; i++){
2924     if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2925       temp_string = g_string_new(temp[i]);
2926       temp_string = g_string_down(temp_string);
2927       if(strstr(temp_string->str, "auto-") != NULL){
2928         auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"), 
2929             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2930         auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2931         g_strstrip(auto_nic_hdl);
2932         if(tracing){
2933           printf("TRACING: auto_nic is [%s]\n", auto_nic_hdl);
2934         }
2935         pos = strstr(temp_string->str, "auto-") - temp_string->str;
2936         temp_string = g_string_erase(temp_string,
2937             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2938         /* as the suffix to the AUTO nic handle we use the first updatable
2939            source. Since currently we don't support multiple sources,
2940            this is not a problem but when we support it, we must change this */ 
2941         temp_string = g_string_insert(temp_string, pos, sources[0]);
2942         temp_string = g_string_insert(temp_string, pos, "*-");
2943         o->scan_silent(arg, strlen(arg));
2944         person_role_name = get_attribute(o, get_class_type(o), arg);
2945         delete(o);
2946         /* if the letter combination is already specified, get it */
2947         initials = get_combination_from_autonic(auto_nic_hdl);
2948         /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2949         if(initials == NULL){
2950           initials = find_initials(person_role_name);
2951         }
2952         free(person_role_name);
2953         temp_string = g_string_insert(temp_string, pos, initials);
2954         free(initials);
2955         
2956         if(to_be_returned == NULL){
2957           to_be_returned = strdup(temp_string->str);
2958           g_string_free(temp_string, TRUE);
2959         }else{
2960           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2961           to_be_returned = strcat(to_be_returned, "\n");
2962           to_be_returned = strcat(to_be_returned, temp_string->str);
2963           g_string_free(temp_string, TRUE);
2964         }
2965       }else{
2966         if(to_be_returned == NULL){
2967           to_be_returned = strdup(temp[i]);
2968         }else{
2969           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2970           to_be_returned = strcat(to_be_returned, "\n");
2971           to_be_returned = strcat(to_be_returned, temp[i]);
2972         }
2973       }
2974     }else{/* if it doesn't begin with nic-hdl */
2975         if(to_be_returned == NULL){
2976           to_be_returned = strdup(temp[i]);
2977         }else{
2978           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2979           strcat(to_be_returned, "\n");
2980           strcat(to_be_returned, temp[i]);
2981         }
2982 
2983     }
2984 
2985   }
2986   g_strfreev (temp);
2987   return to_be_returned;
2988 }
2989 
2990 
2991 
2992 
2993 
2994 
2995 
2996 /* replaces the refs to AUTO NIC hdls with the assigned one */
2997 
2998 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
     /* [<][>][^][v][top][bottom][index][help] */
2999 
3000   char * auto_nic = NULL;
3001   GString* temp_string; 
3002   char * to_be_returned = NULL, * tempstr = NULL;
3003   char ** temp = NULL;
3004   int i, pos;
3005 
3006   if(tracing){
3007     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is running: changed_obj:[%s], arg:[%s]\n",
3008               changed_obj ? changed_obj : "NULL", arg ? arg : "NULL");
3009   }
3010 
3011 
3012   temp = g_strsplit(arg, "\n", 0);
3013 
3014   for(i = 0; temp[i] != NULL; i++){
3015     if(   strstr(temp[i], "admin-c:") == temp[i]    /*    if it starts with admin-c */
3016        || strstr(temp[i], "tech-c:" ) == temp[i]    /* or if it starts with tech-c */
3017        || strstr(temp[i], "zone-c:" ) == temp[i]    /* or if it starts with zone-c */
3018        || strstr(temp[i], "author:" ) == temp[i]){  /* or if it starts with author */
3019       temp_string = g_string_new(temp[i]);
3020       temp_string = g_string_down(temp_string);
3021       if(strstr(temp_string->str, "auto-") != NULL){
3022         auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")  + 1);
3023         auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"), 
3024             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
3025         auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0'; 
3026         g_strstrip(auto_nic);
3027         if(tracing){
3028           printf("TRACING: replace_refs_to_AUTO_NIC_hdl: auto_nic is [%s]\n", auto_nic);
3029         }
3030         pos = strstr(temp_string->str, "auto-") - temp_string->str;
3031         temp_string = g_string_erase(temp_string,
3032             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
3033         
3034         /* if we have this AUTO NIC hdl in the hash, put it. */
3035         if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
3036           temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
3037         }else{/* else, return 0 immediately */
3038           g_strfreev (temp);
3039           return NULL;
3040         }
3041         
3042         if(to_be_returned == NULL){
3043           to_be_returned = strdup(temp_string->str);
3044           g_string_free(temp_string, TRUE);
3045         }else{
3046           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
3047           to_be_returned = strcat(to_be_returned, "\n");
3048           to_be_returned = strcat(to_be_returned, temp_string->str);
3049           g_string_free(temp_string, TRUE);
3050         }
3051       }else{
3052         if(to_be_returned == NULL){
3053           to_be_returned = strdup(temp[i]);
3054         }else{
3055           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
3056           to_be_returned = strcat(to_be_returned, "\n");
3057           to_be_returned = strcat(to_be_returned, temp[i]);
3058         }
3059       }
3060     }else{/* if it doesn't begin with ac,tc,ac or author */
3061         if(to_be_returned == NULL){
3062           to_be_returned = strdup(temp[i]);
3063         }else{
3064           to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
3065           strcat(to_be_returned, "\n");
3066           strcat(to_be_returned, temp[i]);
3067         }
3068 
3069     }
3070 
3071   }
3072   g_strfreev (temp);
3073 
3074   /* now, if we don't have a '\n' at the end of the to_be_returned  string, we will
3075      add one, since RAToolSet parser cannot deal with objects without a '\n' at the end */
3076   if(to_be_returned[strlen(to_be_returned) - 1] != '\n'){
3077     /* so, add a '\n' */
3078     tempstr = (char *)malloc(strlen(to_be_returned) + 2);
3079     sprintf(tempstr, "%s\n", to_be_returned);
3080     free(to_be_returned);
3081     to_be_returned = tempstr;
3082   }
3083    
3084   if(tracing){
3085     printf("TRACING: replace_refs_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
3086   }
3087   return to_be_returned;
3088 }
3089 
3090 
3091 
3092 
3093 /* UP_put_assigned_NIC will replace the auto NIC handle of the object with its
3094    assigned NIC handle */
3095 char * UP_put_assigned_NIC(char * arg, const char * assigned_NIC){
     /* [<][>][^][v][top][bottom][index][help] */
3096 
3097   Object * o = new Object();
3098   char * object;
3099   bool code;
3100   GSList * attribute_list;
3101   GSList * next;
3102   external_syntax_struct *result;
3103   int pos;
3104   char * auto_nic = NULL;
3105   char * temp = NULL;
3106   GString* temp_string; 
3107 
3108 
3109 
3110   object = strdup(arg);
3111   /* if the object does not have a '\n' at the end, add it. */
3112   if(object[strlen(object) - 1] != '\n'){
3113     object = (char *)realloc(object, strlen(object) + 2);
3114     object = strcat(object, "\n");
3115   }
3116       
3117   result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
3118 
3119   /* initialize the struct */
3120   result->result = 0;              /* we won't use this in this function in fact */
3121   result->error_str = strdup("");  /* we won't use this in this function in fact */
3122   result->warning_str = strdup("");/* we won't use this in this function in fact */
3123   
3124   code = o->scan_silent(object, strlen(object));
3125   attribute_list = up_get_attribute_list(o, object);
3126 
3127 
3128   /* loop through the attributes */    
3129   for( next = attribute_list; next != NULL ; next = g_slist_next(next) ){
3130     /* is this a 'nic-hdl' attribute? */
3131     if(strcmp((char *)(((attribute_struct *)(next->data))->type), "nic-hdl") == 0){
3132       /* then, we will replace the AUTO-NIC hdl in it with the assigned one  */
3133       /* save the attribute value to a temp char *   */
3134       temp = strdup((char *)(((attribute_struct *)(next->data))->content));
3135       temp_string = g_string_new(temp);
3136       temp_string = g_string_down(temp_string);
3137       if(strstr(temp_string->str, "auto-") != NULL){
3138         auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")  + 1);
3139         auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"), 
3140             temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
3141         auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0'; 
3142         g_strstrip(auto_nic);
3143         if(tracing){
3144           printf("TRACING: UP_put_assigned_NIC: auto_nic is [%s]\n", auto_nic);
3145         }
3146         pos = strstr(temp_string->str, "auto-") - temp_string->str;
3147         temp_string = g_string_erase(temp_string,
3148             strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
3149         
3150         /* insert the assigned NIC handle */
3151         temp_string = g_string_insert(temp_string, pos, assigned_NIC
3152              /*(char *)g_hash_table_lookup(auto_nic_hash, auto_nic)*/);
3153        
3154         /* and assign the new value of GList member */ 
3155         ((attribute_struct *)(next->data))->content = temp_string->str;
3156         
3157         //if(to_be_returned == NULL){
3158         //  to_be_returned = strdup(temp_string->str);
3159         //  g_string_free(temp_string, TRUE);
3160         //}else{
3161         //  to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
3162         //  to_be_returned = strcat(to_be_returned, "\n");
3163         //  to_be_returned = strcat(to_be_returned, temp_string->str);
3164         //  g_string_free(temp_string, TRUE);
3165         //}
3166       }
3167     }
3168   }
3169   /* OK, now we must reconstruct the object as a char *   */ 
3170   up_reconstruct_object(attribute_list, result);
3171   
3172   /* free the o */
3173   delete(o);
3174 
3175   /* and return the reconstructed object */
3176   return result->new_obj;
3177 }
3178 
3179 
3180 
3181 
3182 
3183 /* Takes an object in a char * , and returns 1 if this object has 
3184    an AUTO NIC handle. Otherwise, returns 0 */
3185 int has_AUTO_NIC_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
3186 
3187   Object * o = new Object();
3188   GSList * attributes = NULL;
3189   bool code;
3190 
3191   code = o->scan_silent(object, strlen(object));
3192 
3193   if(code && !(o->isDeleted)){
3194     attributes = get_attributes(o, "nic-hdl", object);
3195     if(attributes != NULL){
3196       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
3197         g_slist_free(attributes);
3198         delete(o);
3199         return 1;
3200       }
3201     }
3202     /* if control reaches here, then we will return 0 */
3203     g_slist_free(attributes);
3204     delete(o);
3205     return 0; 
3206   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
3207            it contains refs to AUTO NIC hdls. */
3208     delete(o); 
3209     return 0;        
3210   }
3211     
3212 }
3213 
3214 
3215 /* Takes an object in a char * , and returns 1 if this object contains
3216    a reference to an AUTO NIC handle. Otherwise, returns 0 */
3217 int has_ref_to_AUTO_nic_hdl(const char * object){
     /* [<][>][^][v][top][bottom][index][help] */
3218 
3219   Object * o = new Object();
3220   GSList * attributes = NULL;
3221   bool code;
3222 
3223   code = o->scan_silent(object, strlen(object));
3224 
3225   if(code && !(o->isDeleted)){
3226     attributes = get_attributes(o, "admin-c", object);
3227     if(attributes != NULL){
3228       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
3229         g_slist_free(attributes);
3230         delete(o);
3231         return 1;
3232       }
3233     }
3234     g_slist_free(attributes);
3235     attributes = get_attributes(o, "tech-c", object);
3236     if(attributes != NULL){
3237       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
3238         g_slist_free(attributes);
3239         delete(o);
3240         return 1;
3241       }
3242     }
3243 
3244     g_slist_free(attributes);
3245     attributes = get_attributes(o, "zone-c", object);
3246     if(attributes != NULL){
3247       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
3248         g_slist_free(attributes);
3249         delete(o);
3250         return 1;
3251       }
3252     }
3253     g_slist_free(attributes);
3254     attributes = get_attributes(o, "author", object);
3255     if(attributes != NULL){
3256       if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
3257         g_slist_free(attributes);
3258         delete(o);
3259         return 1;
3260       }
3261     }
3262     /* if control reaches here, then we will return 0 */
3263     delete(o);
3264     return 0; 
3265   }else{/* it doesn't pass syntax check. So, it doesn't matter if 
3266            it contains refs to AUTO NIC hdls. */
3267     delete(o); 
3268     return 0;        
3269   }
3270     
3271 }
3272 
3273 
3274 
3275 
3276 
3277 
3278 
3279 
3280 
3281 /* Gets the "From" line of the incoming mail message and finds out an 
3282    address to send the acknowledgement */
3283 char * find_email_address(const char * from_line){
     /* [<][>][^][v][top][bottom][index][help] */
3284   char * pos1 = NULL, * pos2 = NULL, * pos = NULL;
3285   char * temp = NULL;
3286   char * part1 = NULL, * part2 = NULL;
3287   
3288   if(from_line == NULL){
3289     return NULL;
3290   }
3291   if(strstr(from_line, "From:") != from_line){
3292     temp = strdup(from_line);
3293   }else{
3294     temp = strdup(from_line + strlen("From:"));
3295   }
3296   g_strstrip(temp);
3297   if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
3298     pos1 = index(temp, '<');
3299     pos2 = index(temp, '>');
3300     temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
3301     temp[pos2 - pos1 - 1] = '\0';
3302     if(tracing) {
3303      printf("TRACING: find_email_address temp=[%s]\n", temp);
3304     }
3305 
3306   }
3307 
3308   
3309    
3310 
3311   /* and now, we have to remove the parts in parantheses */ 
3312   while(   index(temp, '(') != NULL && index(temp, ')') != NULL
3313         && index(temp, '(') < index(temp, ')')){
3314 
3315     part1 = strdup(temp);
3316     /* terminate the string */
3317     pos = index(part1, '(');
3318     *pos = '\0';
3319 
3320     part2 = strdup(index(temp, ')') + 1);
3321     strcat(part1, part2);
3322     free(temp);
3323     temp = strdup(part1);
3324     free(part1);
3325     free(part2);
3326 
3327   }
3328   
3329   g_strstrip(temp); 
3330   return temp;
3331   
3332 }  
3333 
3334 
3335 
3336 
3337 
3338 
3339 /* removes the '\n's and '\r's at the end of the arg, and returns it  */
3340 char * UP_remove_EOLs(char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
3341 
3342   while(strlen(arg) > 0 &&
3343         (arg[strlen(arg) - 1] == '\n' || 
3344          arg[strlen(arg) - 1] == '\r')){
3345     arg[strlen(arg) - 1] = '\0';
3346   }
3347  
3348   return arg;
3349 }
3350 
3351 
3352 
3353 
3354 
3355 
3356 
3357 
3358 
3359 
3360 /* Duplicates the given arg, and replaces 
3361     $FROM,
3362     $SUBJECT,
3363     $MDATE,
3364     $MSGID,
3365     $CC,
3366     $HUMAILBOX
3367     $AUTOBOX
3368     $FROMHOST
3369 
3370     and $TIME & $DATE
3371     
3372     strings with the corresponding variables.
3373     
3374 */
3375 char * UP_replace_globals(const char * arg){
     /* [<][>][^][v][top][bottom][index][help] */
3376 
3377   GString * g_str;
3378   int pos; 
3379   char * to_be_returned;
3380   time_t cur_time;
3381   char * temp, * time_str, * date_str;
3382 
3383 
3384   /* get time */
3385   cur_time = time(NULL);
3386   temp = strdup(ctime(&cur_time));
3387   /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */ 
3388   
3389   time_str = (char *)malloc(9);  
3390   time_str = strncpy(time_str, temp + 11, 8);
3391   time_str[8] = '\0';  
3392             
3393   date_str = (char *)malloc(16);
3394   date_str = strncpy(date_str, temp, 11);
3395   date_str[11] = '\0';
3396   date_str = strncat(date_str, temp + 20, 4);
3397   
3398    
3399   free(temp);
3400                                          
3401   g_str = g_string_new(arg);
3402 
3403   g_str = UP_replace_GStrings(g_str, "$TIME", time_str);
3404 
3405   g_str = UP_replace_GStrings(g_str, "$DATE", date_str);
3406 
3407   g_str = UP_replace_GStrings(g_str, "$SUBJECT", update_mail_subject);
3408 
3409   g_str = UP_replace_GStrings(g_str, "$FROM", update_mail_sender);
3410 
3411   g_str = UP_replace_GStrings(g_str, "$MDATE", update_mail_date); 
3412 
3413   g_str = UP_replace_GStrings(g_str, "$MSGID", update_mail_ID);
3414 
3415   g_str = UP_replace_GStrings(g_str, "$CC", update_mail_cc);
3416   if(update_mail_cc == NULL){
3417     g_str = UP_replace_GStrings(g_str, "$CC", ""); 
3418   }
3419   
3420   g_str = UP_replace_GStrings(g_str, "$HUMAILBOX", humailbox);
3421 
3422   g_str = UP_replace_GStrings(g_str, "$AUTOBOX", autobox);
3423 
3424   g_str = UP_replace_GStrings(g_str, "$FROMHOST", netupdclientIP); 
3425 
3426   free(time_str);
3427   free(date_str);
3428 
3429   to_be_returned = strdup(g_str->str); 
3430   g_string_free(g_str, 1); 
3431   return to_be_returned;
3432 }
3433 
3434 
3435 
3436 
3437 /* Get the type of the object, which is represented as a char * */
3438 char * get_class_type_char(char * object){
     /* [<][>][^][v][top][bottom][index][help] */
3439   bool code;
3440   Object * o;
3441   char * type; 
3442   char * temp; 
3443 
3444   /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it. 
3445    (no harm in having more than one) */
3446   temp = (char *)malloc(strlen(object) + 2);
3447   sprintf(temp, "%s\n", object);
3448 
3449   if(tracing) {
3450     printf("TRACING: get_class_type_char is running, object is \n[%s]\n", object);
3451   }
3452   o = new Object;
3453   code = o->scan_silent(temp,strlen(temp));
3454   
3455   type = get_class_type(o);
3456 
3457   free(temp);
3458   delete(o);
3459   return type; 
3460 
3461 }
3462 
3463 
3464 
3465 
3466 
3467 /* Adds the given file to the update log */
3468 void UP_add_to_upd_log(const char * filename){
     /* [<][>][^][v][top][bottom][index][help] */
3469 
3470   time_t now;
3471   struct tm * tmstr;
3472   time_t cur_time;
3473   char * time_str;
3474   char datestr[10]; 
3475   char * updlogfile;
3476   FILE * infile, * log_file;
3477   char * buf;
3478 
3479 
3480   /* We need to get the a date string to construct the updlog file name */
3481   time(&now);
3482   tmstr = localtime(&now);
3483   strftime(datestr, 10, "%Y%m%d", tmstr);
3484 
3485   /* now that we have the date string, we can construct updlog file name */
3486   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
3487   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
3488            "%s.%s", updlog, datestr);
3489   
3490  
3491   if(( infile = fopen(filename, "r")) == NULL){
3492     fprintf(stderr, "UP_add_to_upd_log: Can't open upd file, %s\n", filename);
3493     return;
3494   }
3495   
3496   if(( log_file = fopen(updlogfile, "a")) == NULL){
3497     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", log_file);
3498     return;
3499   }
3500    
3501   /* get time */
3502   cur_time = time(NULL);
3503   time_str = strdup(ctime(&cur_time));
3504   /* cut the '\n' at the end */
3505   time_str[strlen(time_str) - 1] = '\0';
3506 
3507   if(reading_from_mail){
3508     fprintf(log_file, ">>> time: %s MAIL UPDATE <<<\n\n", time_str);
3509   }else if(networkupdate){
3510     fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE <<<\n\n", time_str);
3511   }else{
3512     fprintf(log_file, ">>> time: %s UPDATE <<<\n\n", time_str);
3513   }
3514 
3515   free(time_str);
3516 
3517   buf = (char *)malloc(1024);
3518   while((buf=fgets(buf, 1023, infile)) > 0){
3519     fprintf(log_file, "%s", buf);
3520   }
3521   free(buf);
3522 
3523   fclose(infile);
3524   fclose(log_file);
3525 
3526 }
3527 
3528 
3529 
3530 /* Logs the object to the update log */
3531 void UP_log_networkupdate(const char * object, const char * host){
     /* [<][>][^][v][top][bottom][index][help] */
3532 
3533   time_t now;
3534   struct tm * tmstr;
3535   time_t cur_time;
3536   char * time_str;
3537   char datestr[10]; 
3538   char * updlogfile;
3539   FILE * log_file;
3540   char * buf;
3541 
3542 
3543   /* We need to get the a date string to construct the updlog file name */
3544   time(&now);
3545   tmstr = localtime(&now);
3546   strftime(datestr, 10, "%Y%m%d", tmstr);
3547 
3548   /* now that we have the date string, we can construct updlog file name */
3549   updlogfile = (char *)malloc(strlen(updlog) + strlen(datestr) + 2);
3550   snprintf(updlogfile, strlen(updlog) + strlen(datestr) + 2,
3551            "%s.%s", updlog, datestr);
3552   
3553  
3554   if(( log_file = fopen(updlogfile, "a")) == NULL){
3555     fprintf(stderr, "UP_add_to_upd_log: Can't open upd log file, %s\n", log_file);
3556     return;
3557   }
3558    
3559   /* get time */
3560   cur_time = time(NULL);
3561   time_str = strdup(ctime(&cur_time));
3562   /* cut the '\n' at the end */
3563   time_str[strlen(time_str) - 1] = '\0';
3564 
3565   fprintf(log_file, ">>> time: %s NETWORKUPDATE UPDATE (%s) <<<\n\n", time_str, host);
3566 
3567   free(time_str);
3568 
3569   fprintf(log_file, "%s\n", object);
3570 
3571   fclose(log_file);
3572 
3573   
3574 }

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